aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/programs/Xserver/hw/nxagent/X
diff options
context:
space:
mode:
Diffstat (limited to 'nx-X11/programs/Xserver/hw/nxagent/X')
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c2073
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.NX.original2073
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.X.original1966
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c4670
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original4670
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.X.original4035
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c2797
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original2797
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.X.original2143
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c4827
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original4827
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.X.original4670
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c508
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.NX.original508
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.X.original474
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c575
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.NX.original575
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.X.original505
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c566
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original566
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.X.original478
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c241
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original241
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.X.original194
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h174
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.NX.original174
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.X.original148
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c979
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.NX.original979
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.X.original905
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c318
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.NX.original318
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.X.original243
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c233
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.NX.original233
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.X.original190
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c1222
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.NX.original1222
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.X.original1184
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c2220
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original2220
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.X.original1864
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h678
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.NX.original678
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.X.original654
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c904
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original904
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.X.original729
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c1344
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original1344
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.X.original1319
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c3799
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original3799
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.X.original3306
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c1173
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original1173
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.X.original954
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c1455
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original1455
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.X.original1267
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c4174
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original4174
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.X.original3853
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c2286
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.NX.original2286
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.X.original2217
66 files changed, 107730 insertions, 0 deletions
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c
new file mode 100644
index 000000000..c49f1587f
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c
@@ -0,0 +1,2073 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/*
+ * $Id: damage.c,v 1.19 2005/10/06 21:55:41 anholt Exp $
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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 <X11/X.h>
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include <X11/fonts/font.h>
+#include "dixfontstr.h"
+#include <X11/fonts/fontstruct.h>
+#include "mi.h"
+#include "regionstr.h"
+#include "globals.h"
+#include "gcstruct.h"
+#include "damage.h"
+#include "damagestr.h"
+#ifdef COMPOSITE
+#include "cw.h"
+#endif
+
+#define wrap(priv, real, mem, func) {\
+ priv->mem = real->mem; \
+ real->mem = func; \
+}
+
+#define unwrap(priv, real, mem) {\
+ real->mem = priv->mem; \
+}
+
+#define BOX_SAME(a,b) \
+ ((a)->x1 == (b)->x1 && \
+ (a)->y1 == (b)->y1 && \
+ (a)->x2 == (b)->x2 && \
+ (a)->y2 == (b)->y2)
+
+#define DAMAGE_VALIDATE_ENABLE 0
+#define DAMAGE_DEBUG_ENABLE 0
+#if DAMAGE_DEBUG_ENABLE
+#define DAMAGE_DEBUG(x) ErrorF x
+#else
+#define DAMAGE_DEBUG(x)
+#endif
+
+#define getPixmapDamageRef(pPixmap) \
+ ((DamagePtr *) &(pPixmap->devPrivates[damagePixPrivateIndex].ptr))
+
+#define pixmapDamage(pPixmap) damagePixPriv(pPixmap)
+
+static DamagePtr *
+getDrawableDamageRef (DrawablePtr pDrawable)
+{
+ PixmapPtr pPixmap;
+
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ ScreenPtr pScreen = pDrawable->pScreen;
+
+ pPixmap = 0;
+ if (pScreen->GetWindowPixmap
+#ifdef ROOTLESS_WORKAROUND
+ && ((WindowPtr)pDrawable)->viewable
+#endif
+ )
+ pPixmap = (*pScreen->GetWindowPixmap) ((WindowPtr)pDrawable);
+
+ if (!pPixmap)
+ {
+ damageScrPriv(pScreen);
+
+ return &pScrPriv->pScreenDamage;
+ }
+ }
+ else
+ pPixmap = (PixmapPtr) pDrawable;
+ return getPixmapDamageRef (pPixmap);
+}
+
+#define getDrawableDamage(pDrawable) (*getDrawableDamageRef (pDrawable))
+#define getWindowDamage(pWin) getDrawableDamage(&(pWin)->drawable)
+
+#define drawableDamage(pDrawable) \
+ DamagePtr pDamage = getDrawableDamage(pDrawable)
+
+#define windowDamage(pWin) drawableDamage(&(pWin)->drawable)
+
+#define winDamageRef(pWindow) \
+ DamagePtr *pPrev = (DamagePtr *) \
+ &(pWindow->devPrivates[damageWinPrivateIndex].ptr)
+
+#if DAMAGE_DEBUG_ENABLE
+static void
+_damageDamageRegion (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip, int subWindowMode, const char *where)
+#define damageDamageRegion(d,r,c,m) _damageDamageRegion(d,r,c,m,__FUNCTION__)
+#else
+static void
+damageDamageRegion (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip,
+ int subWindowMode)
+#endif
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ damageScrPriv(pScreen);
+ drawableDamage(pDrawable);
+ DamagePtr pNext;
+ RegionRec clippedRec;
+ RegionPtr pDamageRegion;
+ RegionRec pixClip;
+ Bool was_empty;
+ RegionRec tmpRegion;
+ BoxRec tmpBox;
+ int draw_x, draw_y;
+#ifdef COMPOSITE
+ int screen_x = 0, screen_y = 0;
+#endif
+
+ /* short circuit for empty regions */
+ if (!REGION_NOTEMPTY(pScreen, pRegion))
+ return;
+
+#ifdef COMPOSITE
+ /*
+ * When drawing to a pixmap which is storing window contents,
+ * the region presented is in pixmap relative coordinates which
+ * need to be converted to screen relative coordinates
+ */
+ if (pDrawable->type != DRAWABLE_WINDOW)
+ {
+ screen_x = ((PixmapPtr) pDrawable)->screen_x - pDrawable->x;
+ screen_y = ((PixmapPtr) pDrawable)->screen_y - pDrawable->y;
+ }
+ if (screen_x || screen_y)
+ REGION_TRANSLATE (pScreen, pRegion, screen_x, screen_y);
+#endif
+
+ if (pDrawable->type == DRAWABLE_WINDOW &&
+ ((WindowPtr)(pDrawable))->backingStore == NotUseful)
+ {
+ if (subWindowMode == ClipByChildren)
+ {
+ REGION_INTERSECT(pScreen, pRegion, pRegion,
+ &((WindowPtr)(pDrawable))->clipList);
+ }
+ else if (subWindowMode == IncludeInferiors)
+ {
+ RegionPtr pTempRegion =
+ NotClippedByChildren((WindowPtr)(pDrawable));
+ REGION_INTERSECT(pScreen, pRegion, pRegion, pTempRegion);
+ REGION_DESTROY(pScreen, pTempRegion);
+ }
+ /* If subWindowMode is set to an invalid value, don't perform
+ * any drawable-based clipping. */
+ }
+
+
+ REGION_NULL (pScreen, &clippedRec);
+ for (; pDamage; pDamage = pNext)
+ {
+ pNext = pDamage->pNext;
+ /*
+ * Check for internal damage and don't send events
+ */
+ if (pScrPriv->internalLevel > 0 && !pDamage->isInternal)
+ {
+ DAMAGE_DEBUG (("non internal damage, skipping at %d\n",
+ pScrPriv->internalLevel));
+ continue;
+ }
+ /*
+ * Check for unrealized windows
+ */
+ if (pDamage->pDrawable->type == DRAWABLE_WINDOW &&
+ !((WindowPtr) (pDamage->pDrawable))->realized)
+ {
+#if 0
+ DAMAGE_DEBUG (("damage while window unrealized\n"));
+#endif
+ continue;
+ }
+
+ draw_x = pDamage->pDrawable->x;
+ draw_y = pDamage->pDrawable->y;
+#ifdef COMPOSITE
+ /*
+ * Need to move everyone to screen coordinates
+ * XXX what about off-screen pixmaps with non-zero x/y?
+ */
+ if (pDamage->pDrawable->type != DRAWABLE_WINDOW)
+ {
+ draw_x += ((PixmapPtr) pDamage->pDrawable)->screen_x;
+ draw_y += ((PixmapPtr) pDamage->pDrawable)->screen_y;
+ }
+#endif
+
+ /*
+ * Clip against border or pixmap bounds
+ */
+
+ pDamageRegion = pRegion;
+ if (clip || pDamage->pDrawable != pDrawable)
+ {
+ pDamageRegion = &clippedRec;
+ if (pDamage->pDrawable->type == DRAWABLE_WINDOW) {
+ REGION_INTERSECT (pScreen, pDamageRegion, pRegion,
+ &((WindowPtr)(pDamage->pDrawable))->borderClip);
+ } else {
+ BoxRec box;
+ box.x1 = draw_x;
+ box.y1 = draw_y;
+ box.x2 = draw_x + pDamage->pDrawable->width;
+ box.y2 = draw_y + pDamage->pDrawable->height;
+ REGION_INIT(pScreen, &pixClip, &box, 1);
+ REGION_INTERSECT (pScreen, pDamageRegion, pRegion, &pixClip);
+ REGION_UNINIT(pScreen, &pixClip);
+ }
+ /*
+ * Short circuit empty results
+ */
+ if (!REGION_NOTEMPTY(pScreen, pDamageRegion))
+ continue;
+ }
+
+ DAMAGE_DEBUG (("%s %d x %d +%d +%d (target 0x%lx monitor 0x%lx)\n",
+ where,
+ pDamageRegion->extents.x2 - pDamageRegion->extents.x1,
+ pDamageRegion->extents.y2 - pDamageRegion->extents.y1,
+ pDamageRegion->extents.x1, pDamageRegion->extents.y1,
+ pDrawable->id, pDamage->pDrawable->id));
+
+ /*
+ * Move region to target coordinate space
+ */
+ if (draw_x || draw_y)
+ REGION_TRANSLATE (pScreen, pDamageRegion, -draw_x, -draw_y);
+
+ switch (pDamage->damageLevel) {
+ case DamageReportRawRegion:
+ (*pDamage->damageReport) (pDamage, pDamageRegion, pDamage->closure);
+ break;
+ case DamageReportDeltaRegion:
+ REGION_NULL (pScreen, &tmpRegion);
+ REGION_SUBTRACT (pScreen, &tmpRegion, pDamageRegion, &pDamage->damage);
+ if (REGION_NOTEMPTY (pScreen, &tmpRegion))
+ {
+ REGION_UNION(pScreen, &pDamage->damage,
+ &pDamage->damage, pDamageRegion);
+ (*pDamage->damageReport) (pDamage, &tmpRegion, pDamage->closure);
+ }
+ REGION_UNINIT(pScreen, &tmpRegion);
+ break;
+ case DamageReportBoundingBox:
+ tmpBox = *REGION_EXTENTS (pScreen, &pDamage->damage);
+ REGION_UNION(pScreen, &pDamage->damage,
+ &pDamage->damage, pDamageRegion);
+ if (!BOX_SAME (&tmpBox, REGION_EXTENTS (pScreen, &pDamage->damage)))
+ (*pDamage->damageReport) (pDamage, &pDamage->damage, pDamage->closure);
+ break;
+ case DamageReportNonEmpty:
+ was_empty = !REGION_NOTEMPTY(pScreen, &pDamage->damage);
+ REGION_UNION(pScreen, &pDamage->damage, &pDamage->damage,
+ pDamageRegion);
+ if (was_empty && REGION_NOTEMPTY(pScreen, &pDamage->damage))
+ (*pDamage->damageReport) (pDamage, &pDamage->damage, pDamage->closure);
+ break;
+ case DamageReportNone:
+ REGION_UNION(pScreen, &pDamage->damage, &pDamage->damage,
+ pDamageRegion);
+ break;
+ }
+ /*
+ * translate original region back
+ */
+ if (pDamageRegion == pRegion && (draw_x || draw_y))
+ REGION_TRANSLATE (pScreen, pDamageRegion, draw_x, draw_y);
+ }
+#ifdef COMPOSITE
+ if (screen_x || screen_y)
+ REGION_TRANSLATE (pScreen, pRegion, -screen_x, -screen_y);
+#endif
+
+ REGION_UNINIT (pScreen, &clippedRec);
+}
+
+#if DAMAGE_DEBUG_ENABLE
+#define damageDamageBox(d,b,m) _damageDamageBox(d,b,m,__FUNCTION__)
+static void
+_damageDamageBox (DrawablePtr pDrawable, BoxPtr pBox, int subWindowMode, const char *where)
+#else
+static void
+damageDamageBox (DrawablePtr pDrawable, BoxPtr pBox, int subWindowMode)
+#endif
+{
+ RegionRec region;
+
+ REGION_INIT (pDrawable->pScreen, &region, pBox, 1);
+#if DAMAGE_DEBUG_ENABLE
+ _damageDamageRegion (pDrawable, &region, TRUE, subWindowMode, where);
+#else
+ damageDamageRegion (pDrawable, &region, TRUE, subWindowMode);
+#endif
+ REGION_UNINIT (pDrawable->pScreen, &region);
+}
+
+static void damageValidateGC(GCPtr, unsigned long, DrawablePtr);
+static void damageChangeGC(GCPtr, unsigned long);
+static void damageCopyGC(GCPtr, unsigned long, GCPtr);
+static void damageDestroyGC(GCPtr);
+static void damageChangeClip(GCPtr, int, pointer, int);
+static void damageDestroyClip(GCPtr);
+static void damageCopyClip(GCPtr, GCPtr);
+
+GCFuncs damageGCFuncs = {
+ damageValidateGC, damageChangeGC, damageCopyGC, damageDestroyGC,
+ damageChangeClip, damageDestroyClip, damageCopyClip
+};
+
+extern GCOps damageGCOps;
+
+static Bool
+damageCreateGC(GCPtr pGC)
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ damageScrPriv(pScreen);
+ damageGCPriv(pGC);
+ Bool ret;
+
+ pGC->pCompositeClip = 0;
+ unwrap (pScrPriv, pScreen, CreateGC);
+ if((ret = (*pScreen->CreateGC) (pGC))) {
+ pGCPriv->ops = NULL;
+ pGCPriv->funcs = pGC->funcs;
+ pGC->funcs = &damageGCFuncs;
+ }
+ wrap (pScrPriv, pScreen, CreateGC, damageCreateGC);
+
+ return ret;
+}
+
+#ifdef NOTUSED
+static void
+damageWrapGC (GCPtr pGC)
+{
+ damageGCPriv(pGC);
+
+ pGCPriv->ops = NULL;
+ pGCPriv->funcs = pGC->funcs;
+ pGC->funcs = &damageGCFuncs;
+}
+
+static void
+damageUnwrapGC (GCPtr pGC)
+{
+ damageGCPriv(pGC);
+
+ pGC->funcs = pGCPriv->funcs;
+ if (pGCPriv->ops)
+ pGC->ops = pGCPriv->ops;
+}
+#endif
+
+#define DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable) \
+ damageGCPriv(pGC); \
+ GCFuncs *oldFuncs = pGC->funcs; \
+ unwrap(pGCPriv, pGC, funcs); \
+ unwrap(pGCPriv, pGC, ops); \
+
+#define DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable) \
+ wrap(pGCPriv, pGC, funcs, oldFuncs); \
+ wrap(pGCPriv, pGC, ops, &damageGCOps)
+
+#define DAMAGE_GC_FUNC_PROLOGUE(pGC) \
+ damageGCPriv(pGC); \
+ unwrap(pGCPriv, pGC, funcs); \
+ if (pGCPriv->ops) unwrap(pGCPriv, pGC, ops)
+
+#define DAMAGE_GC_FUNC_EPILOGUE(pGC) \
+ wrap(pGCPriv, pGC, funcs, &damageGCFuncs); \
+ if (pGCPriv->ops) wrap(pGCPriv, pGC, ops, &damageGCOps)
+
+static void
+damageValidateGC(GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDrawable)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ValidateGC)(pGC, changes, pDrawable);
+ pGCPriv->ops = pGC->ops; /* just so it's not NULL */
+ DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+damageDestroyGC(GCPtr pGC)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->DestroyGC)(pGC);
+ DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+damageChangeGC (GCPtr pGC,
+ unsigned long mask)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ChangeGC) (pGC, mask);
+ DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+damageCopyGC (GCPtr pGCSrc,
+ unsigned long mask,
+ GCPtr pGCDst)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pGCDst);
+ (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
+ DAMAGE_GC_FUNC_EPILOGUE (pGCDst);
+}
+
+static void
+damageChangeClip (GCPtr pGC,
+ int type,
+ pointer pvalue,
+ int nrects)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
+ DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+damageCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pgcDst);
+ (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+ DAMAGE_GC_FUNC_EPILOGUE (pgcDst);
+}
+
+static void
+damageDestroyClip(GCPtr pGC)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pGC);
+ (* pGC->funcs->DestroyClip)(pGC);
+ DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+#define TRIM_BOX(box, pGC) if (pGC->pCompositeClip) { \
+ BoxPtr extents = &pGC->pCompositeClip->extents;\
+ if(box.x1 < extents->x1) box.x1 = extents->x1; \
+ if(box.x2 > extents->x2) box.x2 = extents->x2; \
+ if(box.y1 < extents->y1) box.y1 = extents->y1; \
+ if(box.y2 > extents->y2) box.y2 = extents->y2; \
+ }
+
+#define TRANSLATE_BOX(box, pDrawable) { \
+ box.x1 += pDrawable->x; \
+ box.x2 += pDrawable->x; \
+ box.y1 += pDrawable->y; \
+ box.y2 += pDrawable->y; \
+ }
+
+#define TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC) { \
+ TRANSLATE_BOX(box, pDrawable); \
+ TRIM_BOX(box, pGC); \
+ }
+
+#define BOX_NOT_EMPTY(box) \
+ (((box.x2 - box.x1) > 0) && ((box.y2 - box.y1) > 0))
+
+#define checkGCDamage(d,g) (getDrawableDamage(d) && \
+ (!g->pCompositeClip ||\
+ REGION_NOTEMPTY(d->pScreen, \
+ g->pCompositeClip)))
+
+#ifdef RENDER
+
+#define TRIM_PICTURE_BOX(box, pDst) { \
+ BoxPtr extents = &pDst->pCompositeClip->extents;\
+ if(box.x1 < extents->x1) box.x1 = extents->x1; \
+ if(box.x2 > extents->x2) box.x2 = extents->x2; \
+ if(box.y1 < extents->y1) box.y1 = extents->y1; \
+ if(box.y2 > extents->y2) box.y2 = extents->y2; \
+ }
+
+#define checkPictureDamage(p) (getDrawableDamage(p->pDrawable) && \
+ REGION_NOTEMPTY(pScreen, p->pCompositeClip))
+
+static void
+damageComposite (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ damageScrPriv(pScreen);
+
+ if (checkPictureDamage (pDst))
+ {
+ BoxRec box;
+
+ box.x1 = xDst + pDst->pDrawable->x;
+ box.y1 = yDst + pDst->pDrawable->y;
+ box.x2 = box.x1 + width;
+ box.y2 = box.y1 + height;
+ TRIM_PICTURE_BOX(box, pDst);
+ if (BOX_NOT_EMPTY(box))
+ damageDamageBox (pDst->pDrawable, &box, pDst->subWindowMode);
+ }
+ unwrap (pScrPriv, ps, Composite);
+ (*ps->Composite) (op,
+ pSrc,
+ pMask,
+ pDst,
+ xSrc,
+ ySrc,
+ xMask,
+ yMask,
+ xDst,
+ yDst,
+ width,
+ height);
+ wrap (pScrPriv, ps, Composite, damageComposite);
+}
+
+static void
+damageGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ damageScrPriv(pScreen);
+
+ if (checkPictureDamage (pDst))
+ {
+ int nlistTmp = nlist;
+ GlyphListPtr listTmp = list;
+ GlyphPtr *glyphsTmp = glyphs;
+ int x, y;
+ int n;
+ GlyphPtr glyph;
+ BoxRec box;
+ int x1, y1, x2, y2;
+
+ box.x1 = 32767;
+ box.y1 = 32767;
+ box.x2 = -32767;
+ box.y2 = -32767;
+ x = pDst->pDrawable->x;
+ y = pDst->pDrawable->y;
+ while (nlistTmp--)
+ {
+ x += listTmp->xOff;
+ y += listTmp->yOff;
+ n = listTmp->len;
+ while (n--)
+ {
+ glyph = *glyphsTmp++;
+ x1 = x - glyph->info.x;
+ y1 = y - glyph->info.y;
+ x2 = x1 + glyph->info.width;
+ y2 = y1 + glyph->info.height;
+ if (x1 < box.x1)
+ box.x1 = x1;
+ if (y1 < box.y1)
+ box.y1 = y1;
+ if (x2 > box.x2)
+ box.x2 = x2;
+ if (y2 > box.y2)
+ box.y2 = y2;
+ x += glyph->info.xOff;
+ y += glyph->info.yOff;
+ }
+ listTmp++;
+ }
+ TRIM_PICTURE_BOX (box, pDst);
+ if (BOX_NOT_EMPTY(box))
+ damageDamageBox (pDst->pDrawable, &box, pDst->subWindowMode);
+ }
+ unwrap (pScrPriv, ps, Glyphs);
+ (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
+ wrap (pScrPriv, ps, Glyphs, damageGlyphs);
+}
+#endif
+
+/**********************************************************/
+
+
+static void
+damageFillSpans(DrawablePtr pDrawable,
+ GC *pGC,
+ int npt,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (npt && checkGCDamage (pDrawable, pGC))
+ {
+ int nptTmp = npt;
+ DDXPointPtr pptTmp = ppt;
+ int *pwidthTmp = pwidth;
+ BoxRec box;
+
+ box.x1 = pptTmp->x;
+ box.x2 = box.x1 + *pwidthTmp;
+ box.y2 = box.y1 = pptTmp->y;
+
+ while(--nptTmp)
+ {
+ pptTmp++;
+ pwidthTmp++;
+ if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+ if(box.x2 < (pptTmp->x + *pwidthTmp))
+ box.x2 = pptTmp->x + *pwidthTmp;
+ if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+ else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+ }
+
+ box.y2++;
+
+ if(!pGC->miTranslate) {
+ TRANSLATE_BOX(box, pDrawable);
+ }
+ TRIM_BOX(box, pGC);
+
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+
+ (*pGC->ops->FillSpans)(pDrawable, pGC, npt, ppt, pwidth, fSorted);
+
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageSetSpans(DrawablePtr pDrawable,
+ GCPtr pGC,
+ char *pcharsrc,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int npt,
+ int fSorted)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (npt && checkGCDamage (pDrawable, pGC))
+ {
+ DDXPointPtr pptTmp = ppt;
+ int *pwidthTmp = pwidth;
+ int nptTmp = npt;
+ BoxRec box;
+
+ box.x1 = pptTmp->x;
+ box.x2 = box.x1 + *pwidthTmp;
+ box.y2 = box.y1 = pptTmp->y;
+
+ while(--nptTmp)
+ {
+ pptTmp++;
+ pwidthTmp++;
+ if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+ if(box.x2 < (pptTmp->x + *pwidthTmp))
+ box.x2 = pptTmp->x + *pwidthTmp;
+ if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+ else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+ }
+
+ box.y2++;
+
+ if(!pGC->miTranslate) {
+ TRANSLATE_BOX(box, pDrawable);
+ }
+ TRIM_BOX(box, pGC);
+
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->SetSpans)(pDrawable, pGC, pcharsrc, ppt, pwidth, npt, fSorted);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePutImage(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int depth,
+ int x,
+ int y,
+ int w,
+ int h,
+ int leftPad,
+ int format,
+ char *pImage)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+ if (checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+
+ box.x1 = x + pDrawable->x;
+ box.x2 = box.x1 + w;
+ box.y1 = y + pDrawable->y;
+ box.y2 = box.y1 + h;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PutImage)(pDrawable, pGC, depth, x, y, w, h,
+ leftPad, format, pImage);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static RegionPtr
+damageCopyArea(DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ int srcx,
+ int srcy,
+ int width,
+ int height,
+ int dstx,
+ int dsty)
+{
+ RegionPtr ret;
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDst);
+
+ /* The driver will only call SourceValidate() when pSrc != pDst,
+ * but the software sprite (misprite.c) always need to know when a
+ * drawable is copied so it can remove the sprite. See #1030. */
+ if ((pSrc == pDst) && pSrc->pScreen->SourceValidate &&
+ pSrc->type == DRAWABLE_WINDOW &&
+ ((WindowPtr)pSrc)->viewable)
+ {
+ (*pSrc->pScreen->SourceValidate) (pSrc, srcx, srcy, width, height);
+ }
+
+ if (checkGCDamage (pDst, pGC))
+ {
+ BoxRec box;
+
+ box.x1 = dstx + pDst->x;
+ box.x2 = box.x1 + width;
+ box.y1 = dsty + pDst->y;
+ box.y2 = box.y1 + height;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDst, &box, pGC->subWindowMode);
+ }
+
+ ret = (*pGC->ops->CopyArea)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDst);
+ return ret;
+}
+
+static RegionPtr
+damageCopyPlane(DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx,
+ int srcy,
+ int width,
+ int height,
+ int dstx,
+ int dsty,
+ unsigned long bitPlane)
+{
+ RegionPtr ret;
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDst);
+
+ /* The driver will only call SourceValidate() when pSrc != pDst,
+ * but the software sprite (misprite.c) always need to know when a
+ * drawable is copied so it can remove the sprite. See #1030. */
+ if ((pSrc == pDst) && pSrc->pScreen->SourceValidate &&
+ pSrc->type == DRAWABLE_WINDOW &&
+ ((WindowPtr)pSrc)->viewable)
+ {
+ (*pSrc->pScreen->SourceValidate) (pSrc, srcx, srcy, width, height);
+ }
+
+ if (checkGCDamage (pDst, pGC))
+ {
+ BoxRec box;
+
+ box.x1 = dstx + pDst->x;
+ box.x2 = box.x1 + width;
+ box.y1 = dsty + pDst->y;
+ box.y2 = box.y1 + height;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDst, &box, pGC->subWindowMode);
+ }
+
+ ret = (*pGC->ops->CopyPlane)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDst);
+ return ret;
+}
+
+static void
+damagePolyPoint(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ xPoint *ppt)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (npt && checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+ int nptTmp = npt;
+ xPoint *pptTmp = ppt;
+
+ box.x2 = box.x1 = pptTmp->x;
+ box.y2 = box.y1 = pptTmp->y;
+
+ /* this could be slow if the points were spread out */
+
+ while(--nptTmp)
+ {
+ pptTmp++;
+ if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+ else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x;
+ if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+ else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+ }
+
+ box.x2++;
+ box.y2++;
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PolyPoint)(pDrawable, pGC, mode, npt, ppt);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolylines(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr ppt)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (npt && checkGCDamage (pDrawable, pGC))
+ {
+ int nptTmp = npt;
+ DDXPointPtr pptTmp = ppt;
+ BoxRec box;
+ int extra = pGC->lineWidth >> 1;
+
+ box.x2 = box.x1 = pptTmp->x;
+ box.y2 = box.y1 = pptTmp->y;
+
+ if(nptTmp > 1)
+ {
+ if(pGC->joinStyle == JoinMiter)
+ extra = 6 * pGC->lineWidth;
+ else if(pGC->capStyle == CapProjecting)
+ extra = pGC->lineWidth;
+ }
+
+ if(mode == CoordModePrevious)
+ {
+ int x = box.x1;
+ int y = box.y1;
+ while(--nptTmp)
+ {
+ pptTmp++;
+ x += pptTmp->x;
+ y += pptTmp->y;
+ if(box.x1 > x) box.x1 = x;
+ else if(box.x2 < x) box.x2 = x;
+ if(box.y1 > y) box.y1 = y;
+ else if(box.y2 < y) box.y2 = y;
+ }
+ }
+ else
+ {
+ while(--nptTmp)
+ {
+ pptTmp++;
+ if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+ else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x;
+ if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+ else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+ }
+ }
+
+ box.x2++;
+ box.y2++;
+
+ if(extra)
+ {
+ box.x1 -= extra;
+ box.x2 += extra;
+ box.y1 -= extra;
+ box.y2 += extra;
+ }
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->Polylines)(pDrawable, pGC, mode, npt, ppt);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolySegment(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nSeg,
+ xSegment *pSeg)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (nSeg && checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+ int extra = pGC->lineWidth;
+ int nsegTmp = nSeg;
+ xSegment *pSegTmp = pSeg;
+
+ if(pGC->capStyle != CapProjecting)
+ extra >>= 1;
+
+ if(pSegTmp->x2 > pSegTmp->x1) {
+ box.x1 = pSegTmp->x1;
+ box.x2 = pSegTmp->x2;
+ } else {
+ box.x2 = pSegTmp->x1;
+ box.x1 = pSegTmp->x2;
+ }
+
+ if(pSegTmp->y2 > pSegTmp->y1) {
+ box.y1 = pSegTmp->y1;
+ box.y2 = pSegTmp->y2;
+ } else {
+ box.y2 = pSegTmp->y1;
+ box.y1 = pSegTmp->y2;
+ }
+
+ while(--nsegTmp)
+ {
+ pSegTmp++;
+ if(pSegTmp->x2 > pSegTmp->x1)
+ {
+ if(pSegTmp->x1 < box.x1) box.x1 = pSegTmp->x1;
+ if(pSegTmp->x2 > box.x2) box.x2 = pSegTmp->x2;
+ }
+ else
+ {
+ if(pSegTmp->x2 < box.x1) box.x1 = pSegTmp->x2;
+ if(pSegTmp->x1 > box.x2) box.x2 = pSegTmp->x1;
+ }
+ if(pSegTmp->y2 > pSegTmp->y1)
+ {
+ if(pSegTmp->y1 < box.y1) box.y1 = pSegTmp->y1;
+ if(pSegTmp->y2 > box.y2) box.y2 = pSegTmp->y2;
+ }
+ else
+ {
+ if(pSegTmp->y2 < box.y1) box.y1 = pSegTmp->y2;
+ if(pSegTmp->y1 > box.y2) box.y2 = pSegTmp->y1;
+ }
+ }
+
+ box.x2++;
+ box.y2++;
+
+ if(extra)
+ {
+ box.x1 -= extra;
+ box.x2 += extra;
+ box.y1 -= extra;
+ box.y2 += extra;
+ }
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PolySegment)(pDrawable, pGC, nSeg, pSeg);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolyRectangle(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nRects,
+ xRectangle *pRects)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (nRects && checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+ int offset1, offset2, offset3;
+ int nRectsTmp = nRects;
+ xRectangle *pRectsTmp = pRects;
+
+ offset2 = pGC->lineWidth;
+ if(!offset2) offset2 = 1;
+ offset1 = offset2 >> 1;
+ offset3 = offset2 - offset1;
+
+ while(nRectsTmp--)
+ {
+ box.x1 = pRectsTmp->x - offset1;
+ box.y1 = pRectsTmp->y - offset1;
+ box.x2 = box.x1 + pRectsTmp->width + offset2;
+ box.y2 = box.y1 + offset2;
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+ box.x1 = pRectsTmp->x - offset1;
+ box.y1 = pRectsTmp->y + offset3;
+ box.x2 = box.x1 + offset2;
+ box.y2 = box.y1 + pRectsTmp->height - offset2;
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+ box.x1 = pRectsTmp->x + pRectsTmp->width - offset1;
+ box.y1 = pRectsTmp->y + offset3;
+ box.x2 = box.x1 + offset2;
+ box.y2 = box.y1 + pRectsTmp->height - offset2;
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+ box.x1 = pRectsTmp->x - offset1;
+ box.y1 = pRectsTmp->y + pRectsTmp->height - offset1;
+ box.x2 = box.x1 + pRectsTmp->width + offset2;
+ box.y2 = box.y1 + offset2;
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+ pRectsTmp++;
+ }
+ }
+ (*pGC->ops->PolyRectangle)(pDrawable, pGC, nRects, pRects);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolyArc(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nArcs,
+ xArc *pArcs)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (nArcs && checkGCDamage (pDrawable, pGC))
+ {
+ int extra = pGC->lineWidth >> 1;
+ BoxRec box;
+ int nArcsTmp = nArcs;
+ xArc *pArcsTmp = pArcs;
+
+ box.x1 = pArcsTmp->x;
+ box.x2 = box.x1 + pArcsTmp->width;
+ box.y1 = pArcsTmp->y;
+ box.y2 = box.y1 + pArcsTmp->height;
+
+ while(--nArcsTmp)
+ {
+ pArcsTmp++;
+ if(box.x1 > pArcsTmp->x)
+ box.x1 = pArcsTmp->x;
+ if(box.x2 < (pArcsTmp->x + pArcsTmp->width))
+ box.x2 = pArcsTmp->x + pArcsTmp->width;
+ if(box.y1 > pArcsTmp->y)
+ box.y1 = pArcsTmp->y;
+ if(box.y2 < (pArcsTmp->y + pArcsTmp->height))
+ box.y2 = pArcsTmp->y + pArcsTmp->height;
+ }
+
+ if(extra)
+ {
+ box.x1 -= extra;
+ box.x2 += extra;
+ box.y1 -= extra;
+ box.y2 += extra;
+ }
+
+ box.x2++;
+ box.y2++;
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PolyArc)(pDrawable, pGC, nArcs, pArcs);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageFillPolygon(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int npt,
+ DDXPointPtr ppt)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (npt > 2 && checkGCDamage (pDrawable, pGC))
+ {
+ DDXPointPtr pptTmp = ppt;
+ int nptTmp = npt;
+ BoxRec box;
+
+ box.x2 = box.x1 = pptTmp->x;
+ box.y2 = box.y1 = pptTmp->y;
+
+ if(mode != CoordModeOrigin)
+ {
+ int x = box.x1;
+ int y = box.y1;
+ while(--nptTmp)
+ {
+ pptTmp++;
+ x += pptTmp->x;
+ y += pptTmp->y;
+ if(box.x1 > x) box.x1 = x;
+ else if(box.x2 < x) box.x2 = x;
+ if(box.y1 > y) box.y1 = y;
+ else if(box.y2 < y) box.y2 = y;
+ }
+ }
+ else
+ {
+ while(--nptTmp)
+ {
+ pptTmp++;
+ if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+ else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x;
+ if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+ else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+ }
+ }
+
+ box.x2++;
+ box.y2++;
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+
+ (*pGC->ops->FillPolygon)(pDrawable, pGC, shape, mode, npt, ppt);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+
+static void
+damagePolyFillRect(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nRects,
+ xRectangle *pRects)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+ if (nRects && checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+ xRectangle *pRectsTmp = pRects;
+ int nRectsTmp = nRects;
+
+ box.x1 = pRectsTmp->x;
+ box.x2 = box.x1 + pRectsTmp->width;
+ box.y1 = pRectsTmp->y;
+ box.y2 = box.y1 + pRectsTmp->height;
+
+ while(--nRectsTmp)
+ {
+ pRectsTmp++;
+ if(box.x1 > pRectsTmp->x) box.x1 = pRectsTmp->x;
+ if(box.x2 < (pRectsTmp->x + pRectsTmp->width))
+ box.x2 = pRectsTmp->x + pRectsTmp->width;
+ if(box.y1 > pRectsTmp->y) box.y1 = pRectsTmp->y;
+ if(box.y2 < (pRectsTmp->y + pRectsTmp->height))
+ box.y2 = pRectsTmp->y + pRectsTmp->height;
+ }
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PolyFillRect)(pDrawable, pGC, nRects, pRects);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+
+static void
+damagePolyFillArc(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nArcs,
+ xArc *pArcs)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (nArcs && checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+ int nArcsTmp = nArcs;
+ xArc *pArcsTmp = pArcs;
+
+ box.x1 = pArcsTmp->x;
+ box.x2 = box.x1 + pArcsTmp->width;
+ box.y1 = pArcsTmp->y;
+ box.y2 = box.y1 + pArcsTmp->height;
+
+ while(--nArcsTmp)
+ {
+ pArcsTmp++;
+ if(box.x1 > pArcsTmp->x)
+ box.x1 = pArcsTmp->x;
+ if(box.x2 < (pArcsTmp->x + pArcsTmp->width))
+ box.x2 = pArcsTmp->x + pArcsTmp->width;
+ if(box.y1 > pArcsTmp->y)
+ box.y1 = pArcsTmp->y;
+ if(box.y2 < (pArcsTmp->y + pArcsTmp->height))
+ box.y2 = pArcsTmp->y + pArcsTmp->height;
+ }
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PolyFillArc)(pDrawable, pGC, nArcs, pArcs);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+/*
+ * general Poly/Image text function. Extract glyph information,
+ * compute bounding box and remove cursor if it is overlapped.
+ */
+
+static void
+damageDamageChars (DrawablePtr pDrawable,
+ FontPtr font,
+ int x,
+ int y,
+ unsigned int n,
+ CharInfoPtr *charinfo,
+ Bool imageblt,
+ int subWindowMode)
+{
+ ExtentInfoRec extents;
+ BoxRec box;
+
+ QueryGlyphExtents(font, charinfo, n, &extents);
+ if (imageblt)
+ {
+ if (extents.overallWidth > extents.overallRight)
+ extents.overallRight = extents.overallWidth;
+ if (extents.overallWidth < extents.overallLeft)
+ extents.overallLeft = extents.overallWidth;
+ if (extents.overallLeft > 0)
+ extents.overallLeft = 0;
+ if (extents.fontAscent > extents.overallAscent)
+ extents.overallAscent = extents.fontAscent;
+ if (extents.fontDescent > extents.overallDescent)
+ extents.overallDescent = extents.fontDescent;
+ }
+ box.x1 = x + extents.overallLeft;
+ box.y1 = y - extents.overallAscent;
+ box.x2 = x + extents.overallRight;
+ box.y2 = y + extents.overallDescent;
+ damageDamageBox (pDrawable, &box, subWindowMode);
+}
+
+/*
+ * values for textType:
+ */
+#define TT_POLY8 0
+#define TT_IMAGE8 1
+#define TT_POLY16 2
+#define TT_IMAGE16 3
+
+static int
+damageText (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned long count,
+ char *chars,
+ FontEncoding fontEncoding,
+ Bool textType)
+{
+ CharInfoPtr *charinfo;
+ CharInfoPtr *info;
+ unsigned long i;
+ unsigned int n;
+ int w;
+ Bool imageblt;
+
+ imageblt = (textType == TT_IMAGE8) || (textType == TT_IMAGE16);
+
+ charinfo = (CharInfoPtr *) ALLOCATE_LOCAL(count * sizeof(CharInfoPtr));
+ if (!charinfo)
+ return x;
+
+ GetGlyphs(pGC->font, count, (unsigned char *)chars,
+ fontEncoding, &i, charinfo);
+ n = (unsigned int)i;
+ w = 0;
+ if (!imageblt)
+ for (info = charinfo; i--; info++)
+ w += (*info)->metrics.characterWidth;
+
+ if (n != 0) {
+ damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y, n,
+ charinfo, imageblt, pGC->subWindowMode);
+
+#ifndef NXAGENT_SERVER
+
+ if (imageblt)
+ (*pGC->ops->ImageGlyphBlt)(pDrawable, pGC, x, y, n, charinfo,
+ FONTGLYPHS(pGC->font));
+ else
+ (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, n, charinfo,
+ FONTGLYPHS(pGC->font));
+#endif
+
+ }
+ DEALLOCATE_LOCAL(charinfo);
+ return x + w;
+}
+
+#ifndef NXAGENT_SERVER
+
+static int
+damagePolyText8(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ x = damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
+ Linear8Bit, TT_POLY8);
+ else
+ x = (*pGC->ops->PolyText8)(pDrawable, pGC, x, y, count, chars);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+ return x;
+}
+
+static int
+damagePolyText16(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ x = damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
+ FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
+ TT_POLY16);
+ else
+ x = (*pGC->ops->PolyText16)(pDrawable, pGC, x, y, count, chars);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+ return x;
+}
+
+static void
+damageImageText8(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
+ Linear8Bit, TT_IMAGE8);
+ else
+ (*pGC->ops->ImageText8)(pDrawable, pGC, x, y, count, chars);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageImageText16(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
+ FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
+ TT_IMAGE16);
+ else
+ (*pGC->ops->ImageText16)(pDrawable, pGC, x, y, count, chars);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+#else /* #ifndef NXAGENT_SERVER */
+
+static int
+damagePolyText8(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
+ Linear8Bit, TT_POLY8);
+
+ x = (*pGC->ops->PolyText8)(pDrawable, pGC, x, y, count, chars);
+
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+ return x;
+}
+
+static int
+damagePolyText16(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
+ FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
+ TT_POLY16);
+
+ x = (*pGC->ops->PolyText16)(pDrawable, pGC, x, y, count, chars);
+
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+ return x;
+}
+
+static void
+damageImageText8(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
+ Linear8Bit, TT_IMAGE8);
+
+ (*pGC->ops->ImageText8)(pDrawable, pGC, x, y, count, chars);
+
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageImageText16(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
+ FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
+ TT_IMAGE16);
+
+ (*pGC->ops->ImageText16)(pDrawable, pGC, x, y, count, chars);
+
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+#endif /* #ifndef NXAGENT_SERVER */
+
+static void
+damageImageGlyphBlt(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+ damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y,
+ nglyph, ppci, TRUE, pGC->subWindowMode);
+ (*pGC->ops->ImageGlyphBlt)(pDrawable, pGC, x, y, nglyph,
+ ppci, pglyphBase);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolyGlyphBlt(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+ damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y,
+ nglyph, ppci, FALSE, pGC->subWindowMode);
+ (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, nglyph,
+ ppci, pglyphBase);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePushPixels(GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDrawable,
+ int dx,
+ int dy,
+ int xOrg,
+ int yOrg)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+ if(checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+
+ box.x1 = xOrg;
+ box.y1 = yOrg;
+
+ if(!pGC->miTranslate) {
+ box.x1 += pDrawable->x;
+ box.y1 += pDrawable->y;
+ }
+
+ box.x2 = box.x1 + dx;
+ box.y2 = box.y1 + dy;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PushPixels)(pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageRemoveDamage (DamagePtr *pPrev, DamagePtr pDamage)
+{
+ while (*pPrev)
+ {
+ if (*pPrev == pDamage)
+ {
+ *pPrev = pDamage->pNext;
+ return;
+ }
+ pPrev = &(*pPrev)->pNext;
+ }
+#if DAMAGE_VALIDATE_ENABLE
+ ErrorF ("Damage not on list\n");
+ abort ();
+#endif
+}
+
+static void
+damageInsertDamage (DamagePtr *pPrev, DamagePtr pDamage)
+{
+#if DAMAGE_VALIDATE_ENABLE
+ DamagePtr pOld;
+
+ for (pOld = *pPrev; pOld; pOld = pOld->pNext)
+ if (pOld == pDamage) {
+ ErrorF ("Damage already on list\n");
+ abort ();
+ }
+#endif
+ pDamage->pNext = *pPrev;
+ *pPrev = pDamage;
+}
+
+static Bool
+damageDestroyPixmap (PixmapPtr pPixmap)
+{
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ damageScrPriv(pScreen);
+
+ if (pPixmap->refcnt == 1)
+ {
+ DamagePtr *pPrev = getPixmapDamageRef (pPixmap);
+ DamagePtr pDamage;
+
+ while ((pDamage = *pPrev))
+ {
+ damageRemoveDamage (pPrev, pDamage);
+ if (!pDamage->isWindow)
+ DamageDestroy (pDamage);
+ }
+ }
+ unwrap (pScrPriv, pScreen, DestroyPixmap);
+ (*pScreen->DestroyPixmap) (pPixmap);
+ wrap (pScrPriv, pScreen, DestroyPixmap, damageDestroyPixmap);
+ return TRUE;
+}
+
+static void
+damagePaintWindow(WindowPtr pWindow,
+ RegionPtr prgn,
+ int what)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ damageScrPriv(pScreen);
+
+ /*
+ * Painting background none doesn't actually *do* anything, so
+ * no damage is recorded
+ */
+ if ((what != PW_BACKGROUND || pWindow->backgroundState != None) &&
+ getWindowDamage (pWindow))
+ damageDamageRegion (&pWindow->drawable, prgn, FALSE, -1);
+ if(what == PW_BACKGROUND) {
+ unwrap (pScrPriv, pScreen, PaintWindowBackground);
+ (*pScreen->PaintWindowBackground) (pWindow, prgn, what);
+ wrap (pScrPriv, pScreen, PaintWindowBackground, damagePaintWindow);
+ } else {
+ unwrap (pScrPriv, pScreen, PaintWindowBorder);
+ (*pScreen->PaintWindowBorder) (pWindow, prgn, what);
+ wrap (pScrPriv, pScreen, PaintWindowBorder, damagePaintWindow);
+ }
+}
+
+
+static void
+damageCopyWindow(WindowPtr pWindow,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ damageScrPriv(pScreen);
+
+ if (getWindowDamage (pWindow))
+ {
+ int dx = pWindow->drawable.x - ptOldOrg.x;
+ int dy = pWindow->drawable.y - ptOldOrg.y;
+
+ /*
+ * The region comes in source relative, but the damage occurs
+ * at the destination location. Translate back and forth.
+ */
+ REGION_TRANSLATE (pScreen, prgnSrc, dx, dy);
+ damageDamageRegion (&pWindow->drawable, prgnSrc, FALSE, -1);
+ REGION_TRANSLATE (pScreen, prgnSrc, -dx, -dy);
+ }
+ unwrap (pScrPriv, pScreen, CopyWindow);
+ (*pScreen->CopyWindow) (pWindow, ptOldOrg, prgnSrc);
+ wrap (pScrPriv, pScreen, CopyWindow, damageCopyWindow);
+}
+
+GCOps damageGCOps = {
+ damageFillSpans, damageSetSpans,
+ damagePutImage, damageCopyArea,
+ damageCopyPlane, damagePolyPoint,
+ damagePolylines, damagePolySegment,
+ damagePolyRectangle, damagePolyArc,
+ damageFillPolygon, damagePolyFillRect,
+ damagePolyFillArc, damagePolyText8,
+ damagePolyText16, damageImageText8,
+ damageImageText16, damageImageGlyphBlt,
+ damagePolyGlyphBlt, damagePushPixels,
+#ifdef NEED_LINEHELPER
+ NULL,
+#endif
+ {NULL} /* devPrivate */
+};
+
+static void
+damageRestoreAreas (PixmapPtr pPixmap,
+ RegionPtr prgn,
+ int xorg,
+ int yorg,
+ WindowPtr pWindow)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ damageScrPriv(pScreen);
+
+ damageDamageRegion (&pWindow->drawable, prgn, FALSE, -1);
+ unwrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas);
+ (*pScreen->BackingStoreFuncs.RestoreAreas) (pPixmap, prgn,
+ xorg, yorg, pWindow);
+ wrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas,
+ damageRestoreAreas);
+}
+
+static void
+damageSetWindowPixmap (WindowPtr pWindow, PixmapPtr pPixmap)
+{
+ DamagePtr pDamage;
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ damageScrPriv(pScreen);
+
+ if ((pDamage = damageGetWinPriv(pWindow)))
+ {
+ PixmapPtr pOldPixmap = (*pScreen->GetWindowPixmap) (pWindow);
+ DamagePtr *pPrev = getPixmapDamageRef(pOldPixmap);
+
+ while (pDamage)
+ {
+ damageRemoveDamage (pPrev, pDamage);
+ pDamage = pDamage->pNextWin;
+ }
+ }
+ unwrap (pScrPriv, pScreen, SetWindowPixmap);
+ (*pScreen->SetWindowPixmap) (pWindow, pPixmap);
+ wrap (pScrPriv, pScreen, SetWindowPixmap, damageSetWindowPixmap);
+ if ((pDamage = damageGetWinPriv(pWindow)))
+ {
+ DamagePtr *pPrev = getPixmapDamageRef(pPixmap);
+
+ while (pDamage)
+ {
+ damageInsertDamage (pPrev, pDamage);
+ pDamage = pDamage->pNextWin;
+ }
+ }
+}
+
+static Bool
+damageDestroyWindow (WindowPtr pWindow)
+{
+ DamagePtr pDamage;
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ Bool ret;
+ damageScrPriv(pScreen);
+
+ while ((pDamage = damageGetWinPriv(pWindow)))
+ {
+ DamageUnregister (&pWindow->drawable, pDamage);
+ DamageDestroy (pDamage);
+ }
+ unwrap (pScrPriv, pScreen, DestroyWindow);
+ ret = (*pScreen->DestroyWindow) (pWindow);
+ wrap (pScrPriv, pScreen, DestroyWindow, damageDestroyWindow);
+ return ret;
+}
+
+static Bool
+damageCloseScreen (int i, ScreenPtr pScreen)
+{
+ damageScrPriv(pScreen);
+
+ unwrap (pScrPriv, pScreen, DestroyPixmap);
+ unwrap (pScrPriv, pScreen, CreateGC);
+ unwrap (pScrPriv, pScreen, PaintWindowBackground);
+ unwrap (pScrPriv, pScreen, PaintWindowBorder);
+ unwrap (pScrPriv, pScreen, CopyWindow);
+ unwrap (pScrPriv, pScreen, CloseScreen);
+ unwrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas);
+ xfree (pScrPriv);
+ return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+int damageScrPrivateIndex;
+int damagePixPrivateIndex;
+int damageGCPrivateIndex;
+int damageWinPrivateIndex;
+int damageGeneration;
+
+Bool
+DamageSetup (ScreenPtr pScreen)
+{
+ DamageScrPrivPtr pScrPriv;
+#ifdef RENDER
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+#endif
+
+ if (damageGeneration != serverGeneration)
+ {
+ damageScrPrivateIndex = AllocateScreenPrivateIndex ();
+ if (damageScrPrivateIndex == -1)
+ return FALSE;
+ damageGCPrivateIndex = AllocateGCPrivateIndex ();
+ if (damageGCPrivateIndex == -1)
+ return FALSE;
+ damagePixPrivateIndex = AllocatePixmapPrivateIndex ();
+ if (damagePixPrivateIndex == -1)
+ return FALSE;
+ damageWinPrivateIndex = AllocateWindowPrivateIndex ();
+ if (damageWinPrivateIndex == -1)
+ return FALSE;
+ damageGeneration = serverGeneration;
+ }
+ if (pScreen->devPrivates[damageScrPrivateIndex].ptr)
+ return TRUE;
+
+ if (!AllocateGCPrivate (pScreen, damageGCPrivateIndex, sizeof (DamageGCPrivRec)))
+ return FALSE;
+ if (!AllocatePixmapPrivate (pScreen, damagePixPrivateIndex, 0))
+ return FALSE;
+ if (!AllocateWindowPrivate (pScreen, damageWinPrivateIndex, 0))
+ return FALSE;
+
+ pScrPriv = (DamageScrPrivPtr) xalloc (sizeof (DamageScrPrivRec));
+ if (!pScrPriv)
+ return FALSE;
+
+#ifdef COMPOSITE
+ /* This is a kludge to ensure wrapping order with the composite wrapper.
+ * If it's done from compinit.c, then DamageSetup may be called before the
+ * extension init phase, so that cw will be higher in the wrapping chain and
+ * rewrite drawables before damage gets to it, causing confusion.
+ */
+ if (!noCompositeExtension)
+ miInitializeCompositeWrapper (pScreen);
+#endif
+
+ pScrPriv->internalLevel = 0;
+ pScrPriv->pScreenDamage = 0;
+
+ wrap (pScrPriv, pScreen, DestroyPixmap, damageDestroyPixmap);
+ wrap (pScrPriv, pScreen, CreateGC, damageCreateGC);
+ wrap (pScrPriv, pScreen, PaintWindowBackground, damagePaintWindow);
+ wrap (pScrPriv, pScreen, PaintWindowBorder, damagePaintWindow);
+ wrap (pScrPriv, pScreen, DestroyWindow, damageDestroyWindow);
+ wrap (pScrPriv, pScreen, SetWindowPixmap, damageSetWindowPixmap);
+ wrap (pScrPriv, pScreen, CopyWindow, damageCopyWindow);
+ wrap (pScrPriv, pScreen, CloseScreen, damageCloseScreen);
+ wrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas,
+ damageRestoreAreas);
+#ifdef RENDER
+ if (ps) {
+ wrap (pScrPriv, ps, Glyphs, damageGlyphs);
+ wrap (pScrPriv, ps, Composite, damageComposite);
+ }
+#endif
+
+ pScreen->devPrivates[damageScrPrivateIndex].ptr = (pointer) pScrPriv;
+ return TRUE;
+}
+
+DamagePtr
+DamageCreate (DamageReportFunc damageReport,
+ DamageDestroyFunc damageDestroy,
+ DamageReportLevel damageLevel,
+ Bool isInternal,
+ ScreenPtr pScreen,
+ void *closure)
+{
+ DamagePtr pDamage;
+
+ pDamage = xalloc (sizeof (DamageRec));
+ if (!pDamage)
+ return 0;
+ pDamage->pNext = 0;
+ pDamage->pNextWin = 0;
+ REGION_NULL(pScreen, &pDamage->damage);
+
+ pDamage->damageLevel = damageLevel;
+ pDamage->isInternal = isInternal;
+ pDamage->closure = closure;
+ pDamage->isWindow = FALSE;
+ pDamage->pDrawable = 0;
+
+ pDamage->damageReport = damageReport;
+ pDamage->damageDestroy = damageDestroy;
+ return pDamage;
+}
+
+void
+DamageRegister (DrawablePtr pDrawable,
+ DamagePtr pDamage)
+{
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ WindowPtr pWindow = (WindowPtr) pDrawable;
+ winDamageRef(pWindow);
+
+#if DAMAGE_VALIDATE_ENABLE
+ DamagePtr pOld;
+
+ for (pOld = *pPrev; pOld; pOld = pOld->pNextWin)
+ if (pOld == pDamage) {
+ ErrorF ("Damage already on window list\n");
+ abort ();
+ }
+#endif
+ pDamage->pNextWin = *pPrev;
+ *pPrev = pDamage;
+ pDamage->isWindow = TRUE;
+ }
+ else
+ pDamage->isWindow = FALSE;
+ pDamage->pDrawable = pDrawable;
+ damageInsertDamage (getDrawableDamageRef (pDrawable), pDamage);
+}
+
+void
+DamageDrawInternal (ScreenPtr pScreen, Bool enable)
+{
+ damageScrPriv (pScreen);
+
+ pScrPriv->internalLevel += enable ? 1 : -1;
+}
+
+void
+DamageUnregister (DrawablePtr pDrawable,
+ DamagePtr pDamage)
+{
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ WindowPtr pWindow = (WindowPtr) pDrawable;
+ winDamageRef (pWindow);
+#if DAMAGE_VALIDATE_ENABLE
+ int found = 0;
+#endif
+
+ while (*pPrev)
+ {
+ if (*pPrev == pDamage)
+ {
+ *pPrev = pDamage->pNextWin;
+#if DAMAGE_VALIDATE_ENABLE
+ found = 1;
+#endif
+ break;
+ }
+ pPrev = &(*pPrev)->pNextWin;
+ }
+#if DAMAGE_VALIDATE_ENABLE
+ if (!found) {
+ ErrorF ("Damage not on window list\n");
+ abort ();
+ }
+#endif
+ }
+ pDamage->pDrawable = 0;
+ damageRemoveDamage (getDrawableDamageRef (pDrawable), pDamage);
+}
+
+void
+DamageDestroy (DamagePtr pDamage)
+{
+ if (pDamage->damageDestroy)
+ (*pDamage->damageDestroy) (pDamage, pDamage->closure);
+ REGION_UNINIT (pDamage->pDrawable->pScreen, &pDamage->damage);
+ xfree (pDamage);
+}
+
+Bool
+DamageSubtract (DamagePtr pDamage,
+ const RegionPtr pRegion)
+{
+ RegionPtr pClip;
+ RegionRec pixmapClip;
+ DrawablePtr pDrawable = pDamage->pDrawable;
+
+ REGION_SUBTRACT (pDrawable->pScreen, &pDamage->damage, &pDamage->damage, pRegion);
+ if (pDrawable)
+ {
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ pClip = &((WindowPtr) pDrawable)->borderClip;
+ else
+ {
+ BoxRec box;
+
+ box.x1 = pDrawable->x;
+ box.y1 = pDrawable->y;
+ box.x2 = pDrawable->x + pDrawable->width;
+ box.y2 = pDrawable->y + pDrawable->height;
+ REGION_INIT (pDrawable->pScreen, &pixmapClip, &box, 1);
+ pClip = &pixmapClip;
+ }
+ REGION_TRANSLATE (pDrawable->pScreen, &pDamage->damage, pDrawable->x, pDrawable->y);
+ REGION_INTERSECT (pDrawable->pScreen, &pDamage->damage, &pDamage->damage, pClip);
+ REGION_TRANSLATE (pDrawable->pScreen, &pDamage->damage, -pDrawable->x, -pDrawable->y);
+ if (pDrawable->type != DRAWABLE_WINDOW)
+ REGION_UNINIT(pDrawable->pScreen, &pixmapClip);
+ }
+ return REGION_NOTEMPTY (pDrawable->pScreen, &pDamage->damage);
+}
+
+void
+DamageEmpty (DamagePtr pDamage)
+{
+ REGION_EMPTY (pDamage->pDrawable->pScreen, &pDamage->damage);
+}
+
+RegionPtr
+DamageRegion (DamagePtr pDamage)
+{
+ return &pDamage->damage;
+}
+
+void
+DamageDamageRegion (DrawablePtr pDrawable,
+ RegionPtr pRegion)
+{
+ damageDamageRegion (pDrawable, pRegion, FALSE, -1);
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.NX.original
new file mode 100644
index 000000000..c49f1587f
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.NX.original
@@ -0,0 +1,2073 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/*
+ * $Id: damage.c,v 1.19 2005/10/06 21:55:41 anholt Exp $
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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 <X11/X.h>
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include <X11/fonts/font.h>
+#include "dixfontstr.h"
+#include <X11/fonts/fontstruct.h>
+#include "mi.h"
+#include "regionstr.h"
+#include "globals.h"
+#include "gcstruct.h"
+#include "damage.h"
+#include "damagestr.h"
+#ifdef COMPOSITE
+#include "cw.h"
+#endif
+
+#define wrap(priv, real, mem, func) {\
+ priv->mem = real->mem; \
+ real->mem = func; \
+}
+
+#define unwrap(priv, real, mem) {\
+ real->mem = priv->mem; \
+}
+
+#define BOX_SAME(a,b) \
+ ((a)->x1 == (b)->x1 && \
+ (a)->y1 == (b)->y1 && \
+ (a)->x2 == (b)->x2 && \
+ (a)->y2 == (b)->y2)
+
+#define DAMAGE_VALIDATE_ENABLE 0
+#define DAMAGE_DEBUG_ENABLE 0
+#if DAMAGE_DEBUG_ENABLE
+#define DAMAGE_DEBUG(x) ErrorF x
+#else
+#define DAMAGE_DEBUG(x)
+#endif
+
+#define getPixmapDamageRef(pPixmap) \
+ ((DamagePtr *) &(pPixmap->devPrivates[damagePixPrivateIndex].ptr))
+
+#define pixmapDamage(pPixmap) damagePixPriv(pPixmap)
+
+static DamagePtr *
+getDrawableDamageRef (DrawablePtr pDrawable)
+{
+ PixmapPtr pPixmap;
+
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ ScreenPtr pScreen = pDrawable->pScreen;
+
+ pPixmap = 0;
+ if (pScreen->GetWindowPixmap
+#ifdef ROOTLESS_WORKAROUND
+ && ((WindowPtr)pDrawable)->viewable
+#endif
+ )
+ pPixmap = (*pScreen->GetWindowPixmap) ((WindowPtr)pDrawable);
+
+ if (!pPixmap)
+ {
+ damageScrPriv(pScreen);
+
+ return &pScrPriv->pScreenDamage;
+ }
+ }
+ else
+ pPixmap = (PixmapPtr) pDrawable;
+ return getPixmapDamageRef (pPixmap);
+}
+
+#define getDrawableDamage(pDrawable) (*getDrawableDamageRef (pDrawable))
+#define getWindowDamage(pWin) getDrawableDamage(&(pWin)->drawable)
+
+#define drawableDamage(pDrawable) \
+ DamagePtr pDamage = getDrawableDamage(pDrawable)
+
+#define windowDamage(pWin) drawableDamage(&(pWin)->drawable)
+
+#define winDamageRef(pWindow) \
+ DamagePtr *pPrev = (DamagePtr *) \
+ &(pWindow->devPrivates[damageWinPrivateIndex].ptr)
+
+#if DAMAGE_DEBUG_ENABLE
+static void
+_damageDamageRegion (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip, int subWindowMode, const char *where)
+#define damageDamageRegion(d,r,c,m) _damageDamageRegion(d,r,c,m,__FUNCTION__)
+#else
+static void
+damageDamageRegion (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip,
+ int subWindowMode)
+#endif
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ damageScrPriv(pScreen);
+ drawableDamage(pDrawable);
+ DamagePtr pNext;
+ RegionRec clippedRec;
+ RegionPtr pDamageRegion;
+ RegionRec pixClip;
+ Bool was_empty;
+ RegionRec tmpRegion;
+ BoxRec tmpBox;
+ int draw_x, draw_y;
+#ifdef COMPOSITE
+ int screen_x = 0, screen_y = 0;
+#endif
+
+ /* short circuit for empty regions */
+ if (!REGION_NOTEMPTY(pScreen, pRegion))
+ return;
+
+#ifdef COMPOSITE
+ /*
+ * When drawing to a pixmap which is storing window contents,
+ * the region presented is in pixmap relative coordinates which
+ * need to be converted to screen relative coordinates
+ */
+ if (pDrawable->type != DRAWABLE_WINDOW)
+ {
+ screen_x = ((PixmapPtr) pDrawable)->screen_x - pDrawable->x;
+ screen_y = ((PixmapPtr) pDrawable)->screen_y - pDrawable->y;
+ }
+ if (screen_x || screen_y)
+ REGION_TRANSLATE (pScreen, pRegion, screen_x, screen_y);
+#endif
+
+ if (pDrawable->type == DRAWABLE_WINDOW &&
+ ((WindowPtr)(pDrawable))->backingStore == NotUseful)
+ {
+ if (subWindowMode == ClipByChildren)
+ {
+ REGION_INTERSECT(pScreen, pRegion, pRegion,
+ &((WindowPtr)(pDrawable))->clipList);
+ }
+ else if (subWindowMode == IncludeInferiors)
+ {
+ RegionPtr pTempRegion =
+ NotClippedByChildren((WindowPtr)(pDrawable));
+ REGION_INTERSECT(pScreen, pRegion, pRegion, pTempRegion);
+ REGION_DESTROY(pScreen, pTempRegion);
+ }
+ /* If subWindowMode is set to an invalid value, don't perform
+ * any drawable-based clipping. */
+ }
+
+
+ REGION_NULL (pScreen, &clippedRec);
+ for (; pDamage; pDamage = pNext)
+ {
+ pNext = pDamage->pNext;
+ /*
+ * Check for internal damage and don't send events
+ */
+ if (pScrPriv->internalLevel > 0 && !pDamage->isInternal)
+ {
+ DAMAGE_DEBUG (("non internal damage, skipping at %d\n",
+ pScrPriv->internalLevel));
+ continue;
+ }
+ /*
+ * Check for unrealized windows
+ */
+ if (pDamage->pDrawable->type == DRAWABLE_WINDOW &&
+ !((WindowPtr) (pDamage->pDrawable))->realized)
+ {
+#if 0
+ DAMAGE_DEBUG (("damage while window unrealized\n"));
+#endif
+ continue;
+ }
+
+ draw_x = pDamage->pDrawable->x;
+ draw_y = pDamage->pDrawable->y;
+#ifdef COMPOSITE
+ /*
+ * Need to move everyone to screen coordinates
+ * XXX what about off-screen pixmaps with non-zero x/y?
+ */
+ if (pDamage->pDrawable->type != DRAWABLE_WINDOW)
+ {
+ draw_x += ((PixmapPtr) pDamage->pDrawable)->screen_x;
+ draw_y += ((PixmapPtr) pDamage->pDrawable)->screen_y;
+ }
+#endif
+
+ /*
+ * Clip against border or pixmap bounds
+ */
+
+ pDamageRegion = pRegion;
+ if (clip || pDamage->pDrawable != pDrawable)
+ {
+ pDamageRegion = &clippedRec;
+ if (pDamage->pDrawable->type == DRAWABLE_WINDOW) {
+ REGION_INTERSECT (pScreen, pDamageRegion, pRegion,
+ &((WindowPtr)(pDamage->pDrawable))->borderClip);
+ } else {
+ BoxRec box;
+ box.x1 = draw_x;
+ box.y1 = draw_y;
+ box.x2 = draw_x + pDamage->pDrawable->width;
+ box.y2 = draw_y + pDamage->pDrawable->height;
+ REGION_INIT(pScreen, &pixClip, &box, 1);
+ REGION_INTERSECT (pScreen, pDamageRegion, pRegion, &pixClip);
+ REGION_UNINIT(pScreen, &pixClip);
+ }
+ /*
+ * Short circuit empty results
+ */
+ if (!REGION_NOTEMPTY(pScreen, pDamageRegion))
+ continue;
+ }
+
+ DAMAGE_DEBUG (("%s %d x %d +%d +%d (target 0x%lx monitor 0x%lx)\n",
+ where,
+ pDamageRegion->extents.x2 - pDamageRegion->extents.x1,
+ pDamageRegion->extents.y2 - pDamageRegion->extents.y1,
+ pDamageRegion->extents.x1, pDamageRegion->extents.y1,
+ pDrawable->id, pDamage->pDrawable->id));
+
+ /*
+ * Move region to target coordinate space
+ */
+ if (draw_x || draw_y)
+ REGION_TRANSLATE (pScreen, pDamageRegion, -draw_x, -draw_y);
+
+ switch (pDamage->damageLevel) {
+ case DamageReportRawRegion:
+ (*pDamage->damageReport) (pDamage, pDamageRegion, pDamage->closure);
+ break;
+ case DamageReportDeltaRegion:
+ REGION_NULL (pScreen, &tmpRegion);
+ REGION_SUBTRACT (pScreen, &tmpRegion, pDamageRegion, &pDamage->damage);
+ if (REGION_NOTEMPTY (pScreen, &tmpRegion))
+ {
+ REGION_UNION(pScreen, &pDamage->damage,
+ &pDamage->damage, pDamageRegion);
+ (*pDamage->damageReport) (pDamage, &tmpRegion, pDamage->closure);
+ }
+ REGION_UNINIT(pScreen, &tmpRegion);
+ break;
+ case DamageReportBoundingBox:
+ tmpBox = *REGION_EXTENTS (pScreen, &pDamage->damage);
+ REGION_UNION(pScreen, &pDamage->damage,
+ &pDamage->damage, pDamageRegion);
+ if (!BOX_SAME (&tmpBox, REGION_EXTENTS (pScreen, &pDamage->damage)))
+ (*pDamage->damageReport) (pDamage, &pDamage->damage, pDamage->closure);
+ break;
+ case DamageReportNonEmpty:
+ was_empty = !REGION_NOTEMPTY(pScreen, &pDamage->damage);
+ REGION_UNION(pScreen, &pDamage->damage, &pDamage->damage,
+ pDamageRegion);
+ if (was_empty && REGION_NOTEMPTY(pScreen, &pDamage->damage))
+ (*pDamage->damageReport) (pDamage, &pDamage->damage, pDamage->closure);
+ break;
+ case DamageReportNone:
+ REGION_UNION(pScreen, &pDamage->damage, &pDamage->damage,
+ pDamageRegion);
+ break;
+ }
+ /*
+ * translate original region back
+ */
+ if (pDamageRegion == pRegion && (draw_x || draw_y))
+ REGION_TRANSLATE (pScreen, pDamageRegion, draw_x, draw_y);
+ }
+#ifdef COMPOSITE
+ if (screen_x || screen_y)
+ REGION_TRANSLATE (pScreen, pRegion, -screen_x, -screen_y);
+#endif
+
+ REGION_UNINIT (pScreen, &clippedRec);
+}
+
+#if DAMAGE_DEBUG_ENABLE
+#define damageDamageBox(d,b,m) _damageDamageBox(d,b,m,__FUNCTION__)
+static void
+_damageDamageBox (DrawablePtr pDrawable, BoxPtr pBox, int subWindowMode, const char *where)
+#else
+static void
+damageDamageBox (DrawablePtr pDrawable, BoxPtr pBox, int subWindowMode)
+#endif
+{
+ RegionRec region;
+
+ REGION_INIT (pDrawable->pScreen, &region, pBox, 1);
+#if DAMAGE_DEBUG_ENABLE
+ _damageDamageRegion (pDrawable, &region, TRUE, subWindowMode, where);
+#else
+ damageDamageRegion (pDrawable, &region, TRUE, subWindowMode);
+#endif
+ REGION_UNINIT (pDrawable->pScreen, &region);
+}
+
+static void damageValidateGC(GCPtr, unsigned long, DrawablePtr);
+static void damageChangeGC(GCPtr, unsigned long);
+static void damageCopyGC(GCPtr, unsigned long, GCPtr);
+static void damageDestroyGC(GCPtr);
+static void damageChangeClip(GCPtr, int, pointer, int);
+static void damageDestroyClip(GCPtr);
+static void damageCopyClip(GCPtr, GCPtr);
+
+GCFuncs damageGCFuncs = {
+ damageValidateGC, damageChangeGC, damageCopyGC, damageDestroyGC,
+ damageChangeClip, damageDestroyClip, damageCopyClip
+};
+
+extern GCOps damageGCOps;
+
+static Bool
+damageCreateGC(GCPtr pGC)
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ damageScrPriv(pScreen);
+ damageGCPriv(pGC);
+ Bool ret;
+
+ pGC->pCompositeClip = 0;
+ unwrap (pScrPriv, pScreen, CreateGC);
+ if((ret = (*pScreen->CreateGC) (pGC))) {
+ pGCPriv->ops = NULL;
+ pGCPriv->funcs = pGC->funcs;
+ pGC->funcs = &damageGCFuncs;
+ }
+ wrap (pScrPriv, pScreen, CreateGC, damageCreateGC);
+
+ return ret;
+}
+
+#ifdef NOTUSED
+static void
+damageWrapGC (GCPtr pGC)
+{
+ damageGCPriv(pGC);
+
+ pGCPriv->ops = NULL;
+ pGCPriv->funcs = pGC->funcs;
+ pGC->funcs = &damageGCFuncs;
+}
+
+static void
+damageUnwrapGC (GCPtr pGC)
+{
+ damageGCPriv(pGC);
+
+ pGC->funcs = pGCPriv->funcs;
+ if (pGCPriv->ops)
+ pGC->ops = pGCPriv->ops;
+}
+#endif
+
+#define DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable) \
+ damageGCPriv(pGC); \
+ GCFuncs *oldFuncs = pGC->funcs; \
+ unwrap(pGCPriv, pGC, funcs); \
+ unwrap(pGCPriv, pGC, ops); \
+
+#define DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable) \
+ wrap(pGCPriv, pGC, funcs, oldFuncs); \
+ wrap(pGCPriv, pGC, ops, &damageGCOps)
+
+#define DAMAGE_GC_FUNC_PROLOGUE(pGC) \
+ damageGCPriv(pGC); \
+ unwrap(pGCPriv, pGC, funcs); \
+ if (pGCPriv->ops) unwrap(pGCPriv, pGC, ops)
+
+#define DAMAGE_GC_FUNC_EPILOGUE(pGC) \
+ wrap(pGCPriv, pGC, funcs, &damageGCFuncs); \
+ if (pGCPriv->ops) wrap(pGCPriv, pGC, ops, &damageGCOps)
+
+static void
+damageValidateGC(GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDrawable)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ValidateGC)(pGC, changes, pDrawable);
+ pGCPriv->ops = pGC->ops; /* just so it's not NULL */
+ DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+damageDestroyGC(GCPtr pGC)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->DestroyGC)(pGC);
+ DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+damageChangeGC (GCPtr pGC,
+ unsigned long mask)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ChangeGC) (pGC, mask);
+ DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+damageCopyGC (GCPtr pGCSrc,
+ unsigned long mask,
+ GCPtr pGCDst)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pGCDst);
+ (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
+ DAMAGE_GC_FUNC_EPILOGUE (pGCDst);
+}
+
+static void
+damageChangeClip (GCPtr pGC,
+ int type,
+ pointer pvalue,
+ int nrects)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
+ DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+damageCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pgcDst);
+ (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+ DAMAGE_GC_FUNC_EPILOGUE (pgcDst);
+}
+
+static void
+damageDestroyClip(GCPtr pGC)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pGC);
+ (* pGC->funcs->DestroyClip)(pGC);
+ DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+#define TRIM_BOX(box, pGC) if (pGC->pCompositeClip) { \
+ BoxPtr extents = &pGC->pCompositeClip->extents;\
+ if(box.x1 < extents->x1) box.x1 = extents->x1; \
+ if(box.x2 > extents->x2) box.x2 = extents->x2; \
+ if(box.y1 < extents->y1) box.y1 = extents->y1; \
+ if(box.y2 > extents->y2) box.y2 = extents->y2; \
+ }
+
+#define TRANSLATE_BOX(box, pDrawable) { \
+ box.x1 += pDrawable->x; \
+ box.x2 += pDrawable->x; \
+ box.y1 += pDrawable->y; \
+ box.y2 += pDrawable->y; \
+ }
+
+#define TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC) { \
+ TRANSLATE_BOX(box, pDrawable); \
+ TRIM_BOX(box, pGC); \
+ }
+
+#define BOX_NOT_EMPTY(box) \
+ (((box.x2 - box.x1) > 0) && ((box.y2 - box.y1) > 0))
+
+#define checkGCDamage(d,g) (getDrawableDamage(d) && \
+ (!g->pCompositeClip ||\
+ REGION_NOTEMPTY(d->pScreen, \
+ g->pCompositeClip)))
+
+#ifdef RENDER
+
+#define TRIM_PICTURE_BOX(box, pDst) { \
+ BoxPtr extents = &pDst->pCompositeClip->extents;\
+ if(box.x1 < extents->x1) box.x1 = extents->x1; \
+ if(box.x2 > extents->x2) box.x2 = extents->x2; \
+ if(box.y1 < extents->y1) box.y1 = extents->y1; \
+ if(box.y2 > extents->y2) box.y2 = extents->y2; \
+ }
+
+#define checkPictureDamage(p) (getDrawableDamage(p->pDrawable) && \
+ REGION_NOTEMPTY(pScreen, p->pCompositeClip))
+
+static void
+damageComposite (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ damageScrPriv(pScreen);
+
+ if (checkPictureDamage (pDst))
+ {
+ BoxRec box;
+
+ box.x1 = xDst + pDst->pDrawable->x;
+ box.y1 = yDst + pDst->pDrawable->y;
+ box.x2 = box.x1 + width;
+ box.y2 = box.y1 + height;
+ TRIM_PICTURE_BOX(box, pDst);
+ if (BOX_NOT_EMPTY(box))
+ damageDamageBox (pDst->pDrawable, &box, pDst->subWindowMode);
+ }
+ unwrap (pScrPriv, ps, Composite);
+ (*ps->Composite) (op,
+ pSrc,
+ pMask,
+ pDst,
+ xSrc,
+ ySrc,
+ xMask,
+ yMask,
+ xDst,
+ yDst,
+ width,
+ height);
+ wrap (pScrPriv, ps, Composite, damageComposite);
+}
+
+static void
+damageGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ damageScrPriv(pScreen);
+
+ if (checkPictureDamage (pDst))
+ {
+ int nlistTmp = nlist;
+ GlyphListPtr listTmp = list;
+ GlyphPtr *glyphsTmp = glyphs;
+ int x, y;
+ int n;
+ GlyphPtr glyph;
+ BoxRec box;
+ int x1, y1, x2, y2;
+
+ box.x1 = 32767;
+ box.y1 = 32767;
+ box.x2 = -32767;
+ box.y2 = -32767;
+ x = pDst->pDrawable->x;
+ y = pDst->pDrawable->y;
+ while (nlistTmp--)
+ {
+ x += listTmp->xOff;
+ y += listTmp->yOff;
+ n = listTmp->len;
+ while (n--)
+ {
+ glyph = *glyphsTmp++;
+ x1 = x - glyph->info.x;
+ y1 = y - glyph->info.y;
+ x2 = x1 + glyph->info.width;
+ y2 = y1 + glyph->info.height;
+ if (x1 < box.x1)
+ box.x1 = x1;
+ if (y1 < box.y1)
+ box.y1 = y1;
+ if (x2 > box.x2)
+ box.x2 = x2;
+ if (y2 > box.y2)
+ box.y2 = y2;
+ x += glyph->info.xOff;
+ y += glyph->info.yOff;
+ }
+ listTmp++;
+ }
+ TRIM_PICTURE_BOX (box, pDst);
+ if (BOX_NOT_EMPTY(box))
+ damageDamageBox (pDst->pDrawable, &box, pDst->subWindowMode);
+ }
+ unwrap (pScrPriv, ps, Glyphs);
+ (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
+ wrap (pScrPriv, ps, Glyphs, damageGlyphs);
+}
+#endif
+
+/**********************************************************/
+
+
+static void
+damageFillSpans(DrawablePtr pDrawable,
+ GC *pGC,
+ int npt,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (npt && checkGCDamage (pDrawable, pGC))
+ {
+ int nptTmp = npt;
+ DDXPointPtr pptTmp = ppt;
+ int *pwidthTmp = pwidth;
+ BoxRec box;
+
+ box.x1 = pptTmp->x;
+ box.x2 = box.x1 + *pwidthTmp;
+ box.y2 = box.y1 = pptTmp->y;
+
+ while(--nptTmp)
+ {
+ pptTmp++;
+ pwidthTmp++;
+ if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+ if(box.x2 < (pptTmp->x + *pwidthTmp))
+ box.x2 = pptTmp->x + *pwidthTmp;
+ if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+ else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+ }
+
+ box.y2++;
+
+ if(!pGC->miTranslate) {
+ TRANSLATE_BOX(box, pDrawable);
+ }
+ TRIM_BOX(box, pGC);
+
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+
+ (*pGC->ops->FillSpans)(pDrawable, pGC, npt, ppt, pwidth, fSorted);
+
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageSetSpans(DrawablePtr pDrawable,
+ GCPtr pGC,
+ char *pcharsrc,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int npt,
+ int fSorted)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (npt && checkGCDamage (pDrawable, pGC))
+ {
+ DDXPointPtr pptTmp = ppt;
+ int *pwidthTmp = pwidth;
+ int nptTmp = npt;
+ BoxRec box;
+
+ box.x1 = pptTmp->x;
+ box.x2 = box.x1 + *pwidthTmp;
+ box.y2 = box.y1 = pptTmp->y;
+
+ while(--nptTmp)
+ {
+ pptTmp++;
+ pwidthTmp++;
+ if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+ if(box.x2 < (pptTmp->x + *pwidthTmp))
+ box.x2 = pptTmp->x + *pwidthTmp;
+ if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+ else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+ }
+
+ box.y2++;
+
+ if(!pGC->miTranslate) {
+ TRANSLATE_BOX(box, pDrawable);
+ }
+ TRIM_BOX(box, pGC);
+
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->SetSpans)(pDrawable, pGC, pcharsrc, ppt, pwidth, npt, fSorted);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePutImage(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int depth,
+ int x,
+ int y,
+ int w,
+ int h,
+ int leftPad,
+ int format,
+ char *pImage)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+ if (checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+
+ box.x1 = x + pDrawable->x;
+ box.x2 = box.x1 + w;
+ box.y1 = y + pDrawable->y;
+ box.y2 = box.y1 + h;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PutImage)(pDrawable, pGC, depth, x, y, w, h,
+ leftPad, format, pImage);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static RegionPtr
+damageCopyArea(DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ int srcx,
+ int srcy,
+ int width,
+ int height,
+ int dstx,
+ int dsty)
+{
+ RegionPtr ret;
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDst);
+
+ /* The driver will only call SourceValidate() when pSrc != pDst,
+ * but the software sprite (misprite.c) always need to know when a
+ * drawable is copied so it can remove the sprite. See #1030. */
+ if ((pSrc == pDst) && pSrc->pScreen->SourceValidate &&
+ pSrc->type == DRAWABLE_WINDOW &&
+ ((WindowPtr)pSrc)->viewable)
+ {
+ (*pSrc->pScreen->SourceValidate) (pSrc, srcx, srcy, width, height);
+ }
+
+ if (checkGCDamage (pDst, pGC))
+ {
+ BoxRec box;
+
+ box.x1 = dstx + pDst->x;
+ box.x2 = box.x1 + width;
+ box.y1 = dsty + pDst->y;
+ box.y2 = box.y1 + height;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDst, &box, pGC->subWindowMode);
+ }
+
+ ret = (*pGC->ops->CopyArea)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDst);
+ return ret;
+}
+
+static RegionPtr
+damageCopyPlane(DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx,
+ int srcy,
+ int width,
+ int height,
+ int dstx,
+ int dsty,
+ unsigned long bitPlane)
+{
+ RegionPtr ret;
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDst);
+
+ /* The driver will only call SourceValidate() when pSrc != pDst,
+ * but the software sprite (misprite.c) always need to know when a
+ * drawable is copied so it can remove the sprite. See #1030. */
+ if ((pSrc == pDst) && pSrc->pScreen->SourceValidate &&
+ pSrc->type == DRAWABLE_WINDOW &&
+ ((WindowPtr)pSrc)->viewable)
+ {
+ (*pSrc->pScreen->SourceValidate) (pSrc, srcx, srcy, width, height);
+ }
+
+ if (checkGCDamage (pDst, pGC))
+ {
+ BoxRec box;
+
+ box.x1 = dstx + pDst->x;
+ box.x2 = box.x1 + width;
+ box.y1 = dsty + pDst->y;
+ box.y2 = box.y1 + height;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDst, &box, pGC->subWindowMode);
+ }
+
+ ret = (*pGC->ops->CopyPlane)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDst);
+ return ret;
+}
+
+static void
+damagePolyPoint(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ xPoint *ppt)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (npt && checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+ int nptTmp = npt;
+ xPoint *pptTmp = ppt;
+
+ box.x2 = box.x1 = pptTmp->x;
+ box.y2 = box.y1 = pptTmp->y;
+
+ /* this could be slow if the points were spread out */
+
+ while(--nptTmp)
+ {
+ pptTmp++;
+ if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+ else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x;
+ if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+ else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+ }
+
+ box.x2++;
+ box.y2++;
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PolyPoint)(pDrawable, pGC, mode, npt, ppt);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolylines(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr ppt)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (npt && checkGCDamage (pDrawable, pGC))
+ {
+ int nptTmp = npt;
+ DDXPointPtr pptTmp = ppt;
+ BoxRec box;
+ int extra = pGC->lineWidth >> 1;
+
+ box.x2 = box.x1 = pptTmp->x;
+ box.y2 = box.y1 = pptTmp->y;
+
+ if(nptTmp > 1)
+ {
+ if(pGC->joinStyle == JoinMiter)
+ extra = 6 * pGC->lineWidth;
+ else if(pGC->capStyle == CapProjecting)
+ extra = pGC->lineWidth;
+ }
+
+ if(mode == CoordModePrevious)
+ {
+ int x = box.x1;
+ int y = box.y1;
+ while(--nptTmp)
+ {
+ pptTmp++;
+ x += pptTmp->x;
+ y += pptTmp->y;
+ if(box.x1 > x) box.x1 = x;
+ else if(box.x2 < x) box.x2 = x;
+ if(box.y1 > y) box.y1 = y;
+ else if(box.y2 < y) box.y2 = y;
+ }
+ }
+ else
+ {
+ while(--nptTmp)
+ {
+ pptTmp++;
+ if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+ else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x;
+ if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+ else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+ }
+ }
+
+ box.x2++;
+ box.y2++;
+
+ if(extra)
+ {
+ box.x1 -= extra;
+ box.x2 += extra;
+ box.y1 -= extra;
+ box.y2 += extra;
+ }
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->Polylines)(pDrawable, pGC, mode, npt, ppt);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolySegment(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nSeg,
+ xSegment *pSeg)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (nSeg && checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+ int extra = pGC->lineWidth;
+ int nsegTmp = nSeg;
+ xSegment *pSegTmp = pSeg;
+
+ if(pGC->capStyle != CapProjecting)
+ extra >>= 1;
+
+ if(pSegTmp->x2 > pSegTmp->x1) {
+ box.x1 = pSegTmp->x1;
+ box.x2 = pSegTmp->x2;
+ } else {
+ box.x2 = pSegTmp->x1;
+ box.x1 = pSegTmp->x2;
+ }
+
+ if(pSegTmp->y2 > pSegTmp->y1) {
+ box.y1 = pSegTmp->y1;
+ box.y2 = pSegTmp->y2;
+ } else {
+ box.y2 = pSegTmp->y1;
+ box.y1 = pSegTmp->y2;
+ }
+
+ while(--nsegTmp)
+ {
+ pSegTmp++;
+ if(pSegTmp->x2 > pSegTmp->x1)
+ {
+ if(pSegTmp->x1 < box.x1) box.x1 = pSegTmp->x1;
+ if(pSegTmp->x2 > box.x2) box.x2 = pSegTmp->x2;
+ }
+ else
+ {
+ if(pSegTmp->x2 < box.x1) box.x1 = pSegTmp->x2;
+ if(pSegTmp->x1 > box.x2) box.x2 = pSegTmp->x1;
+ }
+ if(pSegTmp->y2 > pSegTmp->y1)
+ {
+ if(pSegTmp->y1 < box.y1) box.y1 = pSegTmp->y1;
+ if(pSegTmp->y2 > box.y2) box.y2 = pSegTmp->y2;
+ }
+ else
+ {
+ if(pSegTmp->y2 < box.y1) box.y1 = pSegTmp->y2;
+ if(pSegTmp->y1 > box.y2) box.y2 = pSegTmp->y1;
+ }
+ }
+
+ box.x2++;
+ box.y2++;
+
+ if(extra)
+ {
+ box.x1 -= extra;
+ box.x2 += extra;
+ box.y1 -= extra;
+ box.y2 += extra;
+ }
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PolySegment)(pDrawable, pGC, nSeg, pSeg);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolyRectangle(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nRects,
+ xRectangle *pRects)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (nRects && checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+ int offset1, offset2, offset3;
+ int nRectsTmp = nRects;
+ xRectangle *pRectsTmp = pRects;
+
+ offset2 = pGC->lineWidth;
+ if(!offset2) offset2 = 1;
+ offset1 = offset2 >> 1;
+ offset3 = offset2 - offset1;
+
+ while(nRectsTmp--)
+ {
+ box.x1 = pRectsTmp->x - offset1;
+ box.y1 = pRectsTmp->y - offset1;
+ box.x2 = box.x1 + pRectsTmp->width + offset2;
+ box.y2 = box.y1 + offset2;
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+ box.x1 = pRectsTmp->x - offset1;
+ box.y1 = pRectsTmp->y + offset3;
+ box.x2 = box.x1 + offset2;
+ box.y2 = box.y1 + pRectsTmp->height - offset2;
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+ box.x1 = pRectsTmp->x + pRectsTmp->width - offset1;
+ box.y1 = pRectsTmp->y + offset3;
+ box.x2 = box.x1 + offset2;
+ box.y2 = box.y1 + pRectsTmp->height - offset2;
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+ box.x1 = pRectsTmp->x - offset1;
+ box.y1 = pRectsTmp->y + pRectsTmp->height - offset1;
+ box.x2 = box.x1 + pRectsTmp->width + offset2;
+ box.y2 = box.y1 + offset2;
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+ pRectsTmp++;
+ }
+ }
+ (*pGC->ops->PolyRectangle)(pDrawable, pGC, nRects, pRects);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolyArc(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nArcs,
+ xArc *pArcs)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (nArcs && checkGCDamage (pDrawable, pGC))
+ {
+ int extra = pGC->lineWidth >> 1;
+ BoxRec box;
+ int nArcsTmp = nArcs;
+ xArc *pArcsTmp = pArcs;
+
+ box.x1 = pArcsTmp->x;
+ box.x2 = box.x1 + pArcsTmp->width;
+ box.y1 = pArcsTmp->y;
+ box.y2 = box.y1 + pArcsTmp->height;
+
+ while(--nArcsTmp)
+ {
+ pArcsTmp++;
+ if(box.x1 > pArcsTmp->x)
+ box.x1 = pArcsTmp->x;
+ if(box.x2 < (pArcsTmp->x + pArcsTmp->width))
+ box.x2 = pArcsTmp->x + pArcsTmp->width;
+ if(box.y1 > pArcsTmp->y)
+ box.y1 = pArcsTmp->y;
+ if(box.y2 < (pArcsTmp->y + pArcsTmp->height))
+ box.y2 = pArcsTmp->y + pArcsTmp->height;
+ }
+
+ if(extra)
+ {
+ box.x1 -= extra;
+ box.x2 += extra;
+ box.y1 -= extra;
+ box.y2 += extra;
+ }
+
+ box.x2++;
+ box.y2++;
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PolyArc)(pDrawable, pGC, nArcs, pArcs);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageFillPolygon(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int npt,
+ DDXPointPtr ppt)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (npt > 2 && checkGCDamage (pDrawable, pGC))
+ {
+ DDXPointPtr pptTmp = ppt;
+ int nptTmp = npt;
+ BoxRec box;
+
+ box.x2 = box.x1 = pptTmp->x;
+ box.y2 = box.y1 = pptTmp->y;
+
+ if(mode != CoordModeOrigin)
+ {
+ int x = box.x1;
+ int y = box.y1;
+ while(--nptTmp)
+ {
+ pptTmp++;
+ x += pptTmp->x;
+ y += pptTmp->y;
+ if(box.x1 > x) box.x1 = x;
+ else if(box.x2 < x) box.x2 = x;
+ if(box.y1 > y) box.y1 = y;
+ else if(box.y2 < y) box.y2 = y;
+ }
+ }
+ else
+ {
+ while(--nptTmp)
+ {
+ pptTmp++;
+ if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+ else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x;
+ if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+ else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+ }
+ }
+
+ box.x2++;
+ box.y2++;
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+
+ (*pGC->ops->FillPolygon)(pDrawable, pGC, shape, mode, npt, ppt);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+
+static void
+damagePolyFillRect(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nRects,
+ xRectangle *pRects)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+ if (nRects && checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+ xRectangle *pRectsTmp = pRects;
+ int nRectsTmp = nRects;
+
+ box.x1 = pRectsTmp->x;
+ box.x2 = box.x1 + pRectsTmp->width;
+ box.y1 = pRectsTmp->y;
+ box.y2 = box.y1 + pRectsTmp->height;
+
+ while(--nRectsTmp)
+ {
+ pRectsTmp++;
+ if(box.x1 > pRectsTmp->x) box.x1 = pRectsTmp->x;
+ if(box.x2 < (pRectsTmp->x + pRectsTmp->width))
+ box.x2 = pRectsTmp->x + pRectsTmp->width;
+ if(box.y1 > pRectsTmp->y) box.y1 = pRectsTmp->y;
+ if(box.y2 < (pRectsTmp->y + pRectsTmp->height))
+ box.y2 = pRectsTmp->y + pRectsTmp->height;
+ }
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PolyFillRect)(pDrawable, pGC, nRects, pRects);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+
+static void
+damagePolyFillArc(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nArcs,
+ xArc *pArcs)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (nArcs && checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+ int nArcsTmp = nArcs;
+ xArc *pArcsTmp = pArcs;
+
+ box.x1 = pArcsTmp->x;
+ box.x2 = box.x1 + pArcsTmp->width;
+ box.y1 = pArcsTmp->y;
+ box.y2 = box.y1 + pArcsTmp->height;
+
+ while(--nArcsTmp)
+ {
+ pArcsTmp++;
+ if(box.x1 > pArcsTmp->x)
+ box.x1 = pArcsTmp->x;
+ if(box.x2 < (pArcsTmp->x + pArcsTmp->width))
+ box.x2 = pArcsTmp->x + pArcsTmp->width;
+ if(box.y1 > pArcsTmp->y)
+ box.y1 = pArcsTmp->y;
+ if(box.y2 < (pArcsTmp->y + pArcsTmp->height))
+ box.y2 = pArcsTmp->y + pArcsTmp->height;
+ }
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PolyFillArc)(pDrawable, pGC, nArcs, pArcs);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+/*
+ * general Poly/Image text function. Extract glyph information,
+ * compute bounding box and remove cursor if it is overlapped.
+ */
+
+static void
+damageDamageChars (DrawablePtr pDrawable,
+ FontPtr font,
+ int x,
+ int y,
+ unsigned int n,
+ CharInfoPtr *charinfo,
+ Bool imageblt,
+ int subWindowMode)
+{
+ ExtentInfoRec extents;
+ BoxRec box;
+
+ QueryGlyphExtents(font, charinfo, n, &extents);
+ if (imageblt)
+ {
+ if (extents.overallWidth > extents.overallRight)
+ extents.overallRight = extents.overallWidth;
+ if (extents.overallWidth < extents.overallLeft)
+ extents.overallLeft = extents.overallWidth;
+ if (extents.overallLeft > 0)
+ extents.overallLeft = 0;
+ if (extents.fontAscent > extents.overallAscent)
+ extents.overallAscent = extents.fontAscent;
+ if (extents.fontDescent > extents.overallDescent)
+ extents.overallDescent = extents.fontDescent;
+ }
+ box.x1 = x + extents.overallLeft;
+ box.y1 = y - extents.overallAscent;
+ box.x2 = x + extents.overallRight;
+ box.y2 = y + extents.overallDescent;
+ damageDamageBox (pDrawable, &box, subWindowMode);
+}
+
+/*
+ * values for textType:
+ */
+#define TT_POLY8 0
+#define TT_IMAGE8 1
+#define TT_POLY16 2
+#define TT_IMAGE16 3
+
+static int
+damageText (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned long count,
+ char *chars,
+ FontEncoding fontEncoding,
+ Bool textType)
+{
+ CharInfoPtr *charinfo;
+ CharInfoPtr *info;
+ unsigned long i;
+ unsigned int n;
+ int w;
+ Bool imageblt;
+
+ imageblt = (textType == TT_IMAGE8) || (textType == TT_IMAGE16);
+
+ charinfo = (CharInfoPtr *) ALLOCATE_LOCAL(count * sizeof(CharInfoPtr));
+ if (!charinfo)
+ return x;
+
+ GetGlyphs(pGC->font, count, (unsigned char *)chars,
+ fontEncoding, &i, charinfo);
+ n = (unsigned int)i;
+ w = 0;
+ if (!imageblt)
+ for (info = charinfo; i--; info++)
+ w += (*info)->metrics.characterWidth;
+
+ if (n != 0) {
+ damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y, n,
+ charinfo, imageblt, pGC->subWindowMode);
+
+#ifndef NXAGENT_SERVER
+
+ if (imageblt)
+ (*pGC->ops->ImageGlyphBlt)(pDrawable, pGC, x, y, n, charinfo,
+ FONTGLYPHS(pGC->font));
+ else
+ (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, n, charinfo,
+ FONTGLYPHS(pGC->font));
+#endif
+
+ }
+ DEALLOCATE_LOCAL(charinfo);
+ return x + w;
+}
+
+#ifndef NXAGENT_SERVER
+
+static int
+damagePolyText8(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ x = damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
+ Linear8Bit, TT_POLY8);
+ else
+ x = (*pGC->ops->PolyText8)(pDrawable, pGC, x, y, count, chars);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+ return x;
+}
+
+static int
+damagePolyText16(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ x = damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
+ FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
+ TT_POLY16);
+ else
+ x = (*pGC->ops->PolyText16)(pDrawable, pGC, x, y, count, chars);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+ return x;
+}
+
+static void
+damageImageText8(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
+ Linear8Bit, TT_IMAGE8);
+ else
+ (*pGC->ops->ImageText8)(pDrawable, pGC, x, y, count, chars);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageImageText16(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
+ FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
+ TT_IMAGE16);
+ else
+ (*pGC->ops->ImageText16)(pDrawable, pGC, x, y, count, chars);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+#else /* #ifndef NXAGENT_SERVER */
+
+static int
+damagePolyText8(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
+ Linear8Bit, TT_POLY8);
+
+ x = (*pGC->ops->PolyText8)(pDrawable, pGC, x, y, count, chars);
+
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+ return x;
+}
+
+static int
+damagePolyText16(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
+ FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
+ TT_POLY16);
+
+ x = (*pGC->ops->PolyText16)(pDrawable, pGC, x, y, count, chars);
+
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+ return x;
+}
+
+static void
+damageImageText8(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
+ Linear8Bit, TT_IMAGE8);
+
+ (*pGC->ops->ImageText8)(pDrawable, pGC, x, y, count, chars);
+
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageImageText16(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
+ FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
+ TT_IMAGE16);
+
+ (*pGC->ops->ImageText16)(pDrawable, pGC, x, y, count, chars);
+
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+#endif /* #ifndef NXAGENT_SERVER */
+
+static void
+damageImageGlyphBlt(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+ damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y,
+ nglyph, ppci, TRUE, pGC->subWindowMode);
+ (*pGC->ops->ImageGlyphBlt)(pDrawable, pGC, x, y, nglyph,
+ ppci, pglyphBase);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolyGlyphBlt(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+ damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y,
+ nglyph, ppci, FALSE, pGC->subWindowMode);
+ (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, nglyph,
+ ppci, pglyphBase);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePushPixels(GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDrawable,
+ int dx,
+ int dy,
+ int xOrg,
+ int yOrg)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+ if(checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+
+ box.x1 = xOrg;
+ box.y1 = yOrg;
+
+ if(!pGC->miTranslate) {
+ box.x1 += pDrawable->x;
+ box.y1 += pDrawable->y;
+ }
+
+ box.x2 = box.x1 + dx;
+ box.y2 = box.y1 + dy;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PushPixels)(pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageRemoveDamage (DamagePtr *pPrev, DamagePtr pDamage)
+{
+ while (*pPrev)
+ {
+ if (*pPrev == pDamage)
+ {
+ *pPrev = pDamage->pNext;
+ return;
+ }
+ pPrev = &(*pPrev)->pNext;
+ }
+#if DAMAGE_VALIDATE_ENABLE
+ ErrorF ("Damage not on list\n");
+ abort ();
+#endif
+}
+
+static void
+damageInsertDamage (DamagePtr *pPrev, DamagePtr pDamage)
+{
+#if DAMAGE_VALIDATE_ENABLE
+ DamagePtr pOld;
+
+ for (pOld = *pPrev; pOld; pOld = pOld->pNext)
+ if (pOld == pDamage) {
+ ErrorF ("Damage already on list\n");
+ abort ();
+ }
+#endif
+ pDamage->pNext = *pPrev;
+ *pPrev = pDamage;
+}
+
+static Bool
+damageDestroyPixmap (PixmapPtr pPixmap)
+{
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ damageScrPriv(pScreen);
+
+ if (pPixmap->refcnt == 1)
+ {
+ DamagePtr *pPrev = getPixmapDamageRef (pPixmap);
+ DamagePtr pDamage;
+
+ while ((pDamage = *pPrev))
+ {
+ damageRemoveDamage (pPrev, pDamage);
+ if (!pDamage->isWindow)
+ DamageDestroy (pDamage);
+ }
+ }
+ unwrap (pScrPriv, pScreen, DestroyPixmap);
+ (*pScreen->DestroyPixmap) (pPixmap);
+ wrap (pScrPriv, pScreen, DestroyPixmap, damageDestroyPixmap);
+ return TRUE;
+}
+
+static void
+damagePaintWindow(WindowPtr pWindow,
+ RegionPtr prgn,
+ int what)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ damageScrPriv(pScreen);
+
+ /*
+ * Painting background none doesn't actually *do* anything, so
+ * no damage is recorded
+ */
+ if ((what != PW_BACKGROUND || pWindow->backgroundState != None) &&
+ getWindowDamage (pWindow))
+ damageDamageRegion (&pWindow->drawable, prgn, FALSE, -1);
+ if(what == PW_BACKGROUND) {
+ unwrap (pScrPriv, pScreen, PaintWindowBackground);
+ (*pScreen->PaintWindowBackground) (pWindow, prgn, what);
+ wrap (pScrPriv, pScreen, PaintWindowBackground, damagePaintWindow);
+ } else {
+ unwrap (pScrPriv, pScreen, PaintWindowBorder);
+ (*pScreen->PaintWindowBorder) (pWindow, prgn, what);
+ wrap (pScrPriv, pScreen, PaintWindowBorder, damagePaintWindow);
+ }
+}
+
+
+static void
+damageCopyWindow(WindowPtr pWindow,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ damageScrPriv(pScreen);
+
+ if (getWindowDamage (pWindow))
+ {
+ int dx = pWindow->drawable.x - ptOldOrg.x;
+ int dy = pWindow->drawable.y - ptOldOrg.y;
+
+ /*
+ * The region comes in source relative, but the damage occurs
+ * at the destination location. Translate back and forth.
+ */
+ REGION_TRANSLATE (pScreen, prgnSrc, dx, dy);
+ damageDamageRegion (&pWindow->drawable, prgnSrc, FALSE, -1);
+ REGION_TRANSLATE (pScreen, prgnSrc, -dx, -dy);
+ }
+ unwrap (pScrPriv, pScreen, CopyWindow);
+ (*pScreen->CopyWindow) (pWindow, ptOldOrg, prgnSrc);
+ wrap (pScrPriv, pScreen, CopyWindow, damageCopyWindow);
+}
+
+GCOps damageGCOps = {
+ damageFillSpans, damageSetSpans,
+ damagePutImage, damageCopyArea,
+ damageCopyPlane, damagePolyPoint,
+ damagePolylines, damagePolySegment,
+ damagePolyRectangle, damagePolyArc,
+ damageFillPolygon, damagePolyFillRect,
+ damagePolyFillArc, damagePolyText8,
+ damagePolyText16, damageImageText8,
+ damageImageText16, damageImageGlyphBlt,
+ damagePolyGlyphBlt, damagePushPixels,
+#ifdef NEED_LINEHELPER
+ NULL,
+#endif
+ {NULL} /* devPrivate */
+};
+
+static void
+damageRestoreAreas (PixmapPtr pPixmap,
+ RegionPtr prgn,
+ int xorg,
+ int yorg,
+ WindowPtr pWindow)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ damageScrPriv(pScreen);
+
+ damageDamageRegion (&pWindow->drawable, prgn, FALSE, -1);
+ unwrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas);
+ (*pScreen->BackingStoreFuncs.RestoreAreas) (pPixmap, prgn,
+ xorg, yorg, pWindow);
+ wrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas,
+ damageRestoreAreas);
+}
+
+static void
+damageSetWindowPixmap (WindowPtr pWindow, PixmapPtr pPixmap)
+{
+ DamagePtr pDamage;
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ damageScrPriv(pScreen);
+
+ if ((pDamage = damageGetWinPriv(pWindow)))
+ {
+ PixmapPtr pOldPixmap = (*pScreen->GetWindowPixmap) (pWindow);
+ DamagePtr *pPrev = getPixmapDamageRef(pOldPixmap);
+
+ while (pDamage)
+ {
+ damageRemoveDamage (pPrev, pDamage);
+ pDamage = pDamage->pNextWin;
+ }
+ }
+ unwrap (pScrPriv, pScreen, SetWindowPixmap);
+ (*pScreen->SetWindowPixmap) (pWindow, pPixmap);
+ wrap (pScrPriv, pScreen, SetWindowPixmap, damageSetWindowPixmap);
+ if ((pDamage = damageGetWinPriv(pWindow)))
+ {
+ DamagePtr *pPrev = getPixmapDamageRef(pPixmap);
+
+ while (pDamage)
+ {
+ damageInsertDamage (pPrev, pDamage);
+ pDamage = pDamage->pNextWin;
+ }
+ }
+}
+
+static Bool
+damageDestroyWindow (WindowPtr pWindow)
+{
+ DamagePtr pDamage;
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ Bool ret;
+ damageScrPriv(pScreen);
+
+ while ((pDamage = damageGetWinPriv(pWindow)))
+ {
+ DamageUnregister (&pWindow->drawable, pDamage);
+ DamageDestroy (pDamage);
+ }
+ unwrap (pScrPriv, pScreen, DestroyWindow);
+ ret = (*pScreen->DestroyWindow) (pWindow);
+ wrap (pScrPriv, pScreen, DestroyWindow, damageDestroyWindow);
+ return ret;
+}
+
+static Bool
+damageCloseScreen (int i, ScreenPtr pScreen)
+{
+ damageScrPriv(pScreen);
+
+ unwrap (pScrPriv, pScreen, DestroyPixmap);
+ unwrap (pScrPriv, pScreen, CreateGC);
+ unwrap (pScrPriv, pScreen, PaintWindowBackground);
+ unwrap (pScrPriv, pScreen, PaintWindowBorder);
+ unwrap (pScrPriv, pScreen, CopyWindow);
+ unwrap (pScrPriv, pScreen, CloseScreen);
+ unwrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas);
+ xfree (pScrPriv);
+ return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+int damageScrPrivateIndex;
+int damagePixPrivateIndex;
+int damageGCPrivateIndex;
+int damageWinPrivateIndex;
+int damageGeneration;
+
+Bool
+DamageSetup (ScreenPtr pScreen)
+{
+ DamageScrPrivPtr pScrPriv;
+#ifdef RENDER
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+#endif
+
+ if (damageGeneration != serverGeneration)
+ {
+ damageScrPrivateIndex = AllocateScreenPrivateIndex ();
+ if (damageScrPrivateIndex == -1)
+ return FALSE;
+ damageGCPrivateIndex = AllocateGCPrivateIndex ();
+ if (damageGCPrivateIndex == -1)
+ return FALSE;
+ damagePixPrivateIndex = AllocatePixmapPrivateIndex ();
+ if (damagePixPrivateIndex == -1)
+ return FALSE;
+ damageWinPrivateIndex = AllocateWindowPrivateIndex ();
+ if (damageWinPrivateIndex == -1)
+ return FALSE;
+ damageGeneration = serverGeneration;
+ }
+ if (pScreen->devPrivates[damageScrPrivateIndex].ptr)
+ return TRUE;
+
+ if (!AllocateGCPrivate (pScreen, damageGCPrivateIndex, sizeof (DamageGCPrivRec)))
+ return FALSE;
+ if (!AllocatePixmapPrivate (pScreen, damagePixPrivateIndex, 0))
+ return FALSE;
+ if (!AllocateWindowPrivate (pScreen, damageWinPrivateIndex, 0))
+ return FALSE;
+
+ pScrPriv = (DamageScrPrivPtr) xalloc (sizeof (DamageScrPrivRec));
+ if (!pScrPriv)
+ return FALSE;
+
+#ifdef COMPOSITE
+ /* This is a kludge to ensure wrapping order with the composite wrapper.
+ * If it's done from compinit.c, then DamageSetup may be called before the
+ * extension init phase, so that cw will be higher in the wrapping chain and
+ * rewrite drawables before damage gets to it, causing confusion.
+ */
+ if (!noCompositeExtension)
+ miInitializeCompositeWrapper (pScreen);
+#endif
+
+ pScrPriv->internalLevel = 0;
+ pScrPriv->pScreenDamage = 0;
+
+ wrap (pScrPriv, pScreen, DestroyPixmap, damageDestroyPixmap);
+ wrap (pScrPriv, pScreen, CreateGC, damageCreateGC);
+ wrap (pScrPriv, pScreen, PaintWindowBackground, damagePaintWindow);
+ wrap (pScrPriv, pScreen, PaintWindowBorder, damagePaintWindow);
+ wrap (pScrPriv, pScreen, DestroyWindow, damageDestroyWindow);
+ wrap (pScrPriv, pScreen, SetWindowPixmap, damageSetWindowPixmap);
+ wrap (pScrPriv, pScreen, CopyWindow, damageCopyWindow);
+ wrap (pScrPriv, pScreen, CloseScreen, damageCloseScreen);
+ wrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas,
+ damageRestoreAreas);
+#ifdef RENDER
+ if (ps) {
+ wrap (pScrPriv, ps, Glyphs, damageGlyphs);
+ wrap (pScrPriv, ps, Composite, damageComposite);
+ }
+#endif
+
+ pScreen->devPrivates[damageScrPrivateIndex].ptr = (pointer) pScrPriv;
+ return TRUE;
+}
+
+DamagePtr
+DamageCreate (DamageReportFunc damageReport,
+ DamageDestroyFunc damageDestroy,
+ DamageReportLevel damageLevel,
+ Bool isInternal,
+ ScreenPtr pScreen,
+ void *closure)
+{
+ DamagePtr pDamage;
+
+ pDamage = xalloc (sizeof (DamageRec));
+ if (!pDamage)
+ return 0;
+ pDamage->pNext = 0;
+ pDamage->pNextWin = 0;
+ REGION_NULL(pScreen, &pDamage->damage);
+
+ pDamage->damageLevel = damageLevel;
+ pDamage->isInternal = isInternal;
+ pDamage->closure = closure;
+ pDamage->isWindow = FALSE;
+ pDamage->pDrawable = 0;
+
+ pDamage->damageReport = damageReport;
+ pDamage->damageDestroy = damageDestroy;
+ return pDamage;
+}
+
+void
+DamageRegister (DrawablePtr pDrawable,
+ DamagePtr pDamage)
+{
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ WindowPtr pWindow = (WindowPtr) pDrawable;
+ winDamageRef(pWindow);
+
+#if DAMAGE_VALIDATE_ENABLE
+ DamagePtr pOld;
+
+ for (pOld = *pPrev; pOld; pOld = pOld->pNextWin)
+ if (pOld == pDamage) {
+ ErrorF ("Damage already on window list\n");
+ abort ();
+ }
+#endif
+ pDamage->pNextWin = *pPrev;
+ *pPrev = pDamage;
+ pDamage->isWindow = TRUE;
+ }
+ else
+ pDamage->isWindow = FALSE;
+ pDamage->pDrawable = pDrawable;
+ damageInsertDamage (getDrawableDamageRef (pDrawable), pDamage);
+}
+
+void
+DamageDrawInternal (ScreenPtr pScreen, Bool enable)
+{
+ damageScrPriv (pScreen);
+
+ pScrPriv->internalLevel += enable ? 1 : -1;
+}
+
+void
+DamageUnregister (DrawablePtr pDrawable,
+ DamagePtr pDamage)
+{
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ WindowPtr pWindow = (WindowPtr) pDrawable;
+ winDamageRef (pWindow);
+#if DAMAGE_VALIDATE_ENABLE
+ int found = 0;
+#endif
+
+ while (*pPrev)
+ {
+ if (*pPrev == pDamage)
+ {
+ *pPrev = pDamage->pNextWin;
+#if DAMAGE_VALIDATE_ENABLE
+ found = 1;
+#endif
+ break;
+ }
+ pPrev = &(*pPrev)->pNextWin;
+ }
+#if DAMAGE_VALIDATE_ENABLE
+ if (!found) {
+ ErrorF ("Damage not on window list\n");
+ abort ();
+ }
+#endif
+ }
+ pDamage->pDrawable = 0;
+ damageRemoveDamage (getDrawableDamageRef (pDrawable), pDamage);
+}
+
+void
+DamageDestroy (DamagePtr pDamage)
+{
+ if (pDamage->damageDestroy)
+ (*pDamage->damageDestroy) (pDamage, pDamage->closure);
+ REGION_UNINIT (pDamage->pDrawable->pScreen, &pDamage->damage);
+ xfree (pDamage);
+}
+
+Bool
+DamageSubtract (DamagePtr pDamage,
+ const RegionPtr pRegion)
+{
+ RegionPtr pClip;
+ RegionRec pixmapClip;
+ DrawablePtr pDrawable = pDamage->pDrawable;
+
+ REGION_SUBTRACT (pDrawable->pScreen, &pDamage->damage, &pDamage->damage, pRegion);
+ if (pDrawable)
+ {
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ pClip = &((WindowPtr) pDrawable)->borderClip;
+ else
+ {
+ BoxRec box;
+
+ box.x1 = pDrawable->x;
+ box.y1 = pDrawable->y;
+ box.x2 = pDrawable->x + pDrawable->width;
+ box.y2 = pDrawable->y + pDrawable->height;
+ REGION_INIT (pDrawable->pScreen, &pixmapClip, &box, 1);
+ pClip = &pixmapClip;
+ }
+ REGION_TRANSLATE (pDrawable->pScreen, &pDamage->damage, pDrawable->x, pDrawable->y);
+ REGION_INTERSECT (pDrawable->pScreen, &pDamage->damage, &pDamage->damage, pClip);
+ REGION_TRANSLATE (pDrawable->pScreen, &pDamage->damage, -pDrawable->x, -pDrawable->y);
+ if (pDrawable->type != DRAWABLE_WINDOW)
+ REGION_UNINIT(pDrawable->pScreen, &pixmapClip);
+ }
+ return REGION_NOTEMPTY (pDrawable->pScreen, &pDamage->damage);
+}
+
+void
+DamageEmpty (DamagePtr pDamage)
+{
+ REGION_EMPTY (pDamage->pDrawable->pScreen, &pDamage->damage);
+}
+
+RegionPtr
+DamageRegion (DamagePtr pDamage)
+{
+ return &pDamage->damage;
+}
+
+void
+DamageDamageRegion (DrawablePtr pDrawable,
+ RegionPtr pRegion)
+{
+ damageDamageRegion (pDrawable, pRegion, FALSE, -1);
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.X.original
new file mode 100644
index 000000000..286728cd1
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.X.original
@@ -0,0 +1,1966 @@
+/*
+ * $Id: damage.c,v 1.19 2005/10/06 21:55:41 anholt Exp $
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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 <X11/X.h>
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include <X11/fonts/font.h>
+#include "dixfontstr.h"
+#include <X11/fonts/fontstruct.h>
+#include "mi.h"
+#include "regionstr.h"
+#include "globals.h"
+#include "gcstruct.h"
+#include "damage.h"
+#include "damagestr.h"
+#ifdef COMPOSITE
+#include "cw.h"
+#endif
+
+#define wrap(priv, real, mem, func) {\
+ priv->mem = real->mem; \
+ real->mem = func; \
+}
+
+#define unwrap(priv, real, mem) {\
+ real->mem = priv->mem; \
+}
+
+#define BOX_SAME(a,b) \
+ ((a)->x1 == (b)->x1 && \
+ (a)->y1 == (b)->y1 && \
+ (a)->x2 == (b)->x2 && \
+ (a)->y2 == (b)->y2)
+
+#define DAMAGE_VALIDATE_ENABLE 0
+#define DAMAGE_DEBUG_ENABLE 0
+#if DAMAGE_DEBUG_ENABLE
+#define DAMAGE_DEBUG(x) ErrorF x
+#else
+#define DAMAGE_DEBUG(x)
+#endif
+
+#define getPixmapDamageRef(pPixmap) \
+ ((DamagePtr *) &(pPixmap->devPrivates[damagePixPrivateIndex].ptr))
+
+#define pixmapDamage(pPixmap) damagePixPriv(pPixmap)
+
+static DamagePtr *
+getDrawableDamageRef (DrawablePtr pDrawable)
+{
+ PixmapPtr pPixmap;
+
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ ScreenPtr pScreen = pDrawable->pScreen;
+
+ pPixmap = 0;
+ if (pScreen->GetWindowPixmap
+#ifdef ROOTLESS_WORKAROUND
+ && ((WindowPtr)pDrawable)->viewable
+#endif
+ )
+ pPixmap = (*pScreen->GetWindowPixmap) ((WindowPtr)pDrawable);
+
+ if (!pPixmap)
+ {
+ damageScrPriv(pScreen);
+
+ return &pScrPriv->pScreenDamage;
+ }
+ }
+ else
+ pPixmap = (PixmapPtr) pDrawable;
+ return getPixmapDamageRef (pPixmap);
+}
+
+#define getDrawableDamage(pDrawable) (*getDrawableDamageRef (pDrawable))
+#define getWindowDamage(pWin) getDrawableDamage(&(pWin)->drawable)
+
+#define drawableDamage(pDrawable) \
+ DamagePtr pDamage = getDrawableDamage(pDrawable)
+
+#define windowDamage(pWin) drawableDamage(&(pWin)->drawable)
+
+#define winDamageRef(pWindow) \
+ DamagePtr *pPrev = (DamagePtr *) \
+ &(pWindow->devPrivates[damageWinPrivateIndex].ptr)
+
+#if DAMAGE_DEBUG_ENABLE
+static void
+_damageDamageRegion (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip, int subWindowMode, const char *where)
+#define damageDamageRegion(d,r,c,m) _damageDamageRegion(d,r,c,m,__FUNCTION__)
+#else
+static void
+damageDamageRegion (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip,
+ int subWindowMode)
+#endif
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ damageScrPriv(pScreen);
+ drawableDamage(pDrawable);
+ DamagePtr pNext;
+ RegionRec clippedRec;
+ RegionPtr pDamageRegion;
+ RegionRec pixClip;
+ Bool was_empty;
+ RegionRec tmpRegion;
+ BoxRec tmpBox;
+ int draw_x, draw_y;
+#ifdef COMPOSITE
+ int screen_x = 0, screen_y = 0;
+#endif
+
+ /* short circuit for empty regions */
+ if (!REGION_NOTEMPTY(pScreen, pRegion))
+ return;
+
+#ifdef COMPOSITE
+ /*
+ * When drawing to a pixmap which is storing window contents,
+ * the region presented is in pixmap relative coordinates which
+ * need to be converted to screen relative coordinates
+ */
+ if (pDrawable->type != DRAWABLE_WINDOW)
+ {
+ screen_x = ((PixmapPtr) pDrawable)->screen_x - pDrawable->x;
+ screen_y = ((PixmapPtr) pDrawable)->screen_y - pDrawable->y;
+ }
+ if (screen_x || screen_y)
+ REGION_TRANSLATE (pScreen, pRegion, screen_x, screen_y);
+#endif
+
+ if (pDrawable->type == DRAWABLE_WINDOW &&
+ ((WindowPtr)(pDrawable))->backingStore == NotUseful)
+ {
+ if (subWindowMode == ClipByChildren)
+ {
+ REGION_INTERSECT(pScreen, pRegion, pRegion,
+ &((WindowPtr)(pDrawable))->clipList);
+ }
+ else if (subWindowMode == IncludeInferiors)
+ {
+ RegionPtr pTempRegion =
+ NotClippedByChildren((WindowPtr)(pDrawable));
+ REGION_INTERSECT(pScreen, pRegion, pRegion, pTempRegion);
+ REGION_DESTROY(pScreen, pTempRegion);
+ }
+ /* If subWindowMode is set to an invalid value, don't perform
+ * any drawable-based clipping. */
+ }
+
+
+ REGION_NULL (pScreen, &clippedRec);
+ for (; pDamage; pDamage = pNext)
+ {
+ pNext = pDamage->pNext;
+ /*
+ * Check for internal damage and don't send events
+ */
+ if (pScrPriv->internalLevel > 0 && !pDamage->isInternal)
+ {
+ DAMAGE_DEBUG (("non internal damage, skipping at %d\n",
+ pScrPriv->internalLevel));
+ continue;
+ }
+ /*
+ * Check for unrealized windows
+ */
+ if (pDamage->pDrawable->type == DRAWABLE_WINDOW &&
+ !((WindowPtr) (pDamage->pDrawable))->realized)
+ {
+#if 0
+ DAMAGE_DEBUG (("damage while window unrealized\n"));
+#endif
+ continue;
+ }
+
+ draw_x = pDamage->pDrawable->x;
+ draw_y = pDamage->pDrawable->y;
+#ifdef COMPOSITE
+ /*
+ * Need to move everyone to screen coordinates
+ * XXX what about off-screen pixmaps with non-zero x/y?
+ */
+ if (pDamage->pDrawable->type != DRAWABLE_WINDOW)
+ {
+ draw_x += ((PixmapPtr) pDamage->pDrawable)->screen_x;
+ draw_y += ((PixmapPtr) pDamage->pDrawable)->screen_y;
+ }
+#endif
+
+ /*
+ * Clip against border or pixmap bounds
+ */
+
+ pDamageRegion = pRegion;
+ if (clip || pDamage->pDrawable != pDrawable)
+ {
+ pDamageRegion = &clippedRec;
+ if (pDamage->pDrawable->type == DRAWABLE_WINDOW) {
+ REGION_INTERSECT (pScreen, pDamageRegion, pRegion,
+ &((WindowPtr)(pDamage->pDrawable))->borderClip);
+ } else {
+ BoxRec box;
+ box.x1 = draw_x;
+ box.y1 = draw_y;
+ box.x2 = draw_x + pDamage->pDrawable->width;
+ box.y2 = draw_y + pDamage->pDrawable->height;
+ REGION_INIT(pScreen, &pixClip, &box, 1);
+ REGION_INTERSECT (pScreen, pDamageRegion, pRegion, &pixClip);
+ REGION_UNINIT(pScreen, &pixClip);
+ }
+ /*
+ * Short circuit empty results
+ */
+ if (!REGION_NOTEMPTY(pScreen, pDamageRegion))
+ continue;
+ }
+
+ DAMAGE_DEBUG (("%s %d x %d +%d +%d (target 0x%lx monitor 0x%lx)\n",
+ where,
+ pDamageRegion->extents.x2 - pDamageRegion->extents.x1,
+ pDamageRegion->extents.y2 - pDamageRegion->extents.y1,
+ pDamageRegion->extents.x1, pDamageRegion->extents.y1,
+ pDrawable->id, pDamage->pDrawable->id));
+
+ /*
+ * Move region to target coordinate space
+ */
+ if (draw_x || draw_y)
+ REGION_TRANSLATE (pScreen, pDamageRegion, -draw_x, -draw_y);
+
+ switch (pDamage->damageLevel) {
+ case DamageReportRawRegion:
+ (*pDamage->damageReport) (pDamage, pDamageRegion, pDamage->closure);
+ break;
+ case DamageReportDeltaRegion:
+ REGION_NULL (pScreen, &tmpRegion);
+ REGION_SUBTRACT (pScreen, &tmpRegion, pDamageRegion, &pDamage->damage);
+ if (REGION_NOTEMPTY (pScreen, &tmpRegion))
+ {
+ REGION_UNION(pScreen, &pDamage->damage,
+ &pDamage->damage, pDamageRegion);
+ (*pDamage->damageReport) (pDamage, &tmpRegion, pDamage->closure);
+ }
+ REGION_UNINIT(pScreen, &tmpRegion);
+ break;
+ case DamageReportBoundingBox:
+ tmpBox = *REGION_EXTENTS (pScreen, &pDamage->damage);
+ REGION_UNION(pScreen, &pDamage->damage,
+ &pDamage->damage, pDamageRegion);
+ if (!BOX_SAME (&tmpBox, REGION_EXTENTS (pScreen, &pDamage->damage)))
+ (*pDamage->damageReport) (pDamage, &pDamage->damage, pDamage->closure);
+ break;
+ case DamageReportNonEmpty:
+ was_empty = !REGION_NOTEMPTY(pScreen, &pDamage->damage);
+ REGION_UNION(pScreen, &pDamage->damage, &pDamage->damage,
+ pDamageRegion);
+ if (was_empty && REGION_NOTEMPTY(pScreen, &pDamage->damage))
+ (*pDamage->damageReport) (pDamage, &pDamage->damage, pDamage->closure);
+ break;
+ case DamageReportNone:
+ REGION_UNION(pScreen, &pDamage->damage, &pDamage->damage,
+ pDamageRegion);
+ break;
+ }
+ /*
+ * translate original region back
+ */
+ if (pDamageRegion == pRegion && (draw_x || draw_y))
+ REGION_TRANSLATE (pScreen, pDamageRegion, draw_x, draw_y);
+ }
+#ifdef COMPOSITE
+ if (screen_x || screen_y)
+ REGION_TRANSLATE (pScreen, pRegion, -screen_x, -screen_y);
+#endif
+
+ REGION_UNINIT (pScreen, &clippedRec);
+}
+
+#if DAMAGE_DEBUG_ENABLE
+#define damageDamageBox(d,b,m) _damageDamageBox(d,b,m,__FUNCTION__)
+static void
+_damageDamageBox (DrawablePtr pDrawable, BoxPtr pBox, int subWindowMode, const char *where)
+#else
+static void
+damageDamageBox (DrawablePtr pDrawable, BoxPtr pBox, int subWindowMode)
+#endif
+{
+ RegionRec region;
+
+ REGION_INIT (pDrawable->pScreen, &region, pBox, 1);
+#if DAMAGE_DEBUG_ENABLE
+ _damageDamageRegion (pDrawable, &region, TRUE, subWindowMode, where);
+#else
+ damageDamageRegion (pDrawable, &region, TRUE, subWindowMode);
+#endif
+ REGION_UNINIT (pDrawable->pScreen, &region);
+}
+
+static void damageValidateGC(GCPtr, unsigned long, DrawablePtr);
+static void damageChangeGC(GCPtr, unsigned long);
+static void damageCopyGC(GCPtr, unsigned long, GCPtr);
+static void damageDestroyGC(GCPtr);
+static void damageChangeClip(GCPtr, int, pointer, int);
+static void damageDestroyClip(GCPtr);
+static void damageCopyClip(GCPtr, GCPtr);
+
+GCFuncs damageGCFuncs = {
+ damageValidateGC, damageChangeGC, damageCopyGC, damageDestroyGC,
+ damageChangeClip, damageDestroyClip, damageCopyClip
+};
+
+extern GCOps damageGCOps;
+
+static Bool
+damageCreateGC(GCPtr pGC)
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ damageScrPriv(pScreen);
+ damageGCPriv(pGC);
+ Bool ret;
+
+ pGC->pCompositeClip = 0;
+ unwrap (pScrPriv, pScreen, CreateGC);
+ if((ret = (*pScreen->CreateGC) (pGC))) {
+ pGCPriv->ops = NULL;
+ pGCPriv->funcs = pGC->funcs;
+ pGC->funcs = &damageGCFuncs;
+ }
+ wrap (pScrPriv, pScreen, CreateGC, damageCreateGC);
+
+ return ret;
+}
+
+#ifdef NOTUSED
+static void
+damageWrapGC (GCPtr pGC)
+{
+ damageGCPriv(pGC);
+
+ pGCPriv->ops = NULL;
+ pGCPriv->funcs = pGC->funcs;
+ pGC->funcs = &damageGCFuncs;
+}
+
+static void
+damageUnwrapGC (GCPtr pGC)
+{
+ damageGCPriv(pGC);
+
+ pGC->funcs = pGCPriv->funcs;
+ if (pGCPriv->ops)
+ pGC->ops = pGCPriv->ops;
+}
+#endif
+
+#define DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable) \
+ damageGCPriv(pGC); \
+ GCFuncs *oldFuncs = pGC->funcs; \
+ unwrap(pGCPriv, pGC, funcs); \
+ unwrap(pGCPriv, pGC, ops); \
+
+#define DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable) \
+ wrap(pGCPriv, pGC, funcs, oldFuncs); \
+ wrap(pGCPriv, pGC, ops, &damageGCOps)
+
+#define DAMAGE_GC_FUNC_PROLOGUE(pGC) \
+ damageGCPriv(pGC); \
+ unwrap(pGCPriv, pGC, funcs); \
+ if (pGCPriv->ops) unwrap(pGCPriv, pGC, ops)
+
+#define DAMAGE_GC_FUNC_EPILOGUE(pGC) \
+ wrap(pGCPriv, pGC, funcs, &damageGCFuncs); \
+ if (pGCPriv->ops) wrap(pGCPriv, pGC, ops, &damageGCOps)
+
+static void
+damageValidateGC(GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDrawable)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ValidateGC)(pGC, changes, pDrawable);
+ pGCPriv->ops = pGC->ops; /* just so it's not NULL */
+ DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+damageDestroyGC(GCPtr pGC)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->DestroyGC)(pGC);
+ DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+damageChangeGC (GCPtr pGC,
+ unsigned long mask)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ChangeGC) (pGC, mask);
+ DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+damageCopyGC (GCPtr pGCSrc,
+ unsigned long mask,
+ GCPtr pGCDst)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pGCDst);
+ (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
+ DAMAGE_GC_FUNC_EPILOGUE (pGCDst);
+}
+
+static void
+damageChangeClip (GCPtr pGC,
+ int type,
+ pointer pvalue,
+ int nrects)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
+ DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+damageCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pgcDst);
+ (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+ DAMAGE_GC_FUNC_EPILOGUE (pgcDst);
+}
+
+static void
+damageDestroyClip(GCPtr pGC)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pGC);
+ (* pGC->funcs->DestroyClip)(pGC);
+ DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+#define TRIM_BOX(box, pGC) if (pGC->pCompositeClip) { \
+ BoxPtr extents = &pGC->pCompositeClip->extents;\
+ if(box.x1 < extents->x1) box.x1 = extents->x1; \
+ if(box.x2 > extents->x2) box.x2 = extents->x2; \
+ if(box.y1 < extents->y1) box.y1 = extents->y1; \
+ if(box.y2 > extents->y2) box.y2 = extents->y2; \
+ }
+
+#define TRANSLATE_BOX(box, pDrawable) { \
+ box.x1 += pDrawable->x; \
+ box.x2 += pDrawable->x; \
+ box.y1 += pDrawable->y; \
+ box.y2 += pDrawable->y; \
+ }
+
+#define TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC) { \
+ TRANSLATE_BOX(box, pDrawable); \
+ TRIM_BOX(box, pGC); \
+ }
+
+#define BOX_NOT_EMPTY(box) \
+ (((box.x2 - box.x1) > 0) && ((box.y2 - box.y1) > 0))
+
+#define checkGCDamage(d,g) (getDrawableDamage(d) && \
+ (!g->pCompositeClip ||\
+ REGION_NOTEMPTY(d->pScreen, \
+ g->pCompositeClip)))
+
+#ifdef RENDER
+
+#define TRIM_PICTURE_BOX(box, pDst) { \
+ BoxPtr extents = &pDst->pCompositeClip->extents;\
+ if(box.x1 < extents->x1) box.x1 = extents->x1; \
+ if(box.x2 > extents->x2) box.x2 = extents->x2; \
+ if(box.y1 < extents->y1) box.y1 = extents->y1; \
+ if(box.y2 > extents->y2) box.y2 = extents->y2; \
+ }
+
+#define checkPictureDamage(p) (getDrawableDamage(p->pDrawable) && \
+ REGION_NOTEMPTY(pScreen, p->pCompositeClip))
+
+static void
+damageComposite (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ damageScrPriv(pScreen);
+
+ if (checkPictureDamage (pDst))
+ {
+ BoxRec box;
+
+ box.x1 = xDst + pDst->pDrawable->x;
+ box.y1 = yDst + pDst->pDrawable->y;
+ box.x2 = box.x1 + width;
+ box.y2 = box.y1 + height;
+ TRIM_PICTURE_BOX(box, pDst);
+ if (BOX_NOT_EMPTY(box))
+ damageDamageBox (pDst->pDrawable, &box, pDst->subWindowMode);
+ }
+ unwrap (pScrPriv, ps, Composite);
+ (*ps->Composite) (op,
+ pSrc,
+ pMask,
+ pDst,
+ xSrc,
+ ySrc,
+ xMask,
+ yMask,
+ xDst,
+ yDst,
+ width,
+ height);
+ wrap (pScrPriv, ps, Composite, damageComposite);
+}
+
+static void
+damageGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ damageScrPriv(pScreen);
+
+ if (checkPictureDamage (pDst))
+ {
+ int nlistTmp = nlist;
+ GlyphListPtr listTmp = list;
+ GlyphPtr *glyphsTmp = glyphs;
+ int x, y;
+ int n;
+ GlyphPtr glyph;
+ BoxRec box;
+ int x1, y1, x2, y2;
+
+ box.x1 = 32767;
+ box.y1 = 32767;
+ box.x2 = -32767;
+ box.y2 = -32767;
+ x = pDst->pDrawable->x;
+ y = pDst->pDrawable->y;
+ while (nlistTmp--)
+ {
+ x += listTmp->xOff;
+ y += listTmp->yOff;
+ n = listTmp->len;
+ while (n--)
+ {
+ glyph = *glyphsTmp++;
+ x1 = x - glyph->info.x;
+ y1 = y - glyph->info.y;
+ x2 = x1 + glyph->info.width;
+ y2 = y1 + glyph->info.height;
+ if (x1 < box.x1)
+ box.x1 = x1;
+ if (y1 < box.y1)
+ box.y1 = y1;
+ if (x2 > box.x2)
+ box.x2 = x2;
+ if (y2 > box.y2)
+ box.y2 = y2;
+ x += glyph->info.xOff;
+ y += glyph->info.yOff;
+ }
+ listTmp++;
+ }
+ TRIM_PICTURE_BOX (box, pDst);
+ if (BOX_NOT_EMPTY(box))
+ damageDamageBox (pDst->pDrawable, &box, pDst->subWindowMode);
+ }
+ unwrap (pScrPriv, ps, Glyphs);
+ (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
+ wrap (pScrPriv, ps, Glyphs, damageGlyphs);
+}
+#endif
+
+/**********************************************************/
+
+
+static void
+damageFillSpans(DrawablePtr pDrawable,
+ GC *pGC,
+ int npt,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (npt && checkGCDamage (pDrawable, pGC))
+ {
+ int nptTmp = npt;
+ DDXPointPtr pptTmp = ppt;
+ int *pwidthTmp = pwidth;
+ BoxRec box;
+
+ box.x1 = pptTmp->x;
+ box.x2 = box.x1 + *pwidthTmp;
+ box.y2 = box.y1 = pptTmp->y;
+
+ while(--nptTmp)
+ {
+ pptTmp++;
+ pwidthTmp++;
+ if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+ if(box.x2 < (pptTmp->x + *pwidthTmp))
+ box.x2 = pptTmp->x + *pwidthTmp;
+ if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+ else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+ }
+
+ box.y2++;
+
+ if(!pGC->miTranslate) {
+ TRANSLATE_BOX(box, pDrawable);
+ }
+ TRIM_BOX(box, pGC);
+
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+
+ (*pGC->ops->FillSpans)(pDrawable, pGC, npt, ppt, pwidth, fSorted);
+
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageSetSpans(DrawablePtr pDrawable,
+ GCPtr pGC,
+ char *pcharsrc,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int npt,
+ int fSorted)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (npt && checkGCDamage (pDrawable, pGC))
+ {
+ DDXPointPtr pptTmp = ppt;
+ int *pwidthTmp = pwidth;
+ int nptTmp = npt;
+ BoxRec box;
+
+ box.x1 = pptTmp->x;
+ box.x2 = box.x1 + *pwidthTmp;
+ box.y2 = box.y1 = pptTmp->y;
+
+ while(--nptTmp)
+ {
+ pptTmp++;
+ pwidthTmp++;
+ if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+ if(box.x2 < (pptTmp->x + *pwidthTmp))
+ box.x2 = pptTmp->x + *pwidthTmp;
+ if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+ else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+ }
+
+ box.y2++;
+
+ if(!pGC->miTranslate) {
+ TRANSLATE_BOX(box, pDrawable);
+ }
+ TRIM_BOX(box, pGC);
+
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->SetSpans)(pDrawable, pGC, pcharsrc, ppt, pwidth, npt, fSorted);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePutImage(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int depth,
+ int x,
+ int y,
+ int w,
+ int h,
+ int leftPad,
+ int format,
+ char *pImage)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+ if (checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+
+ box.x1 = x + pDrawable->x;
+ box.x2 = box.x1 + w;
+ box.y1 = y + pDrawable->y;
+ box.y2 = box.y1 + h;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PutImage)(pDrawable, pGC, depth, x, y, w, h,
+ leftPad, format, pImage);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static RegionPtr
+damageCopyArea(DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ int srcx,
+ int srcy,
+ int width,
+ int height,
+ int dstx,
+ int dsty)
+{
+ RegionPtr ret;
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDst);
+
+ /* The driver will only call SourceValidate() when pSrc != pDst,
+ * but the software sprite (misprite.c) always need to know when a
+ * drawable is copied so it can remove the sprite. See #1030. */
+ if ((pSrc == pDst) && pSrc->pScreen->SourceValidate &&
+ pSrc->type == DRAWABLE_WINDOW &&
+ ((WindowPtr)pSrc)->viewable)
+ {
+ (*pSrc->pScreen->SourceValidate) (pSrc, srcx, srcy, width, height);
+ }
+
+ if (checkGCDamage (pDst, pGC))
+ {
+ BoxRec box;
+
+ box.x1 = dstx + pDst->x;
+ box.x2 = box.x1 + width;
+ box.y1 = dsty + pDst->y;
+ box.y2 = box.y1 + height;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDst, &box, pGC->subWindowMode);
+ }
+
+ ret = (*pGC->ops->CopyArea)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDst);
+ return ret;
+}
+
+static RegionPtr
+damageCopyPlane(DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx,
+ int srcy,
+ int width,
+ int height,
+ int dstx,
+ int dsty,
+ unsigned long bitPlane)
+{
+ RegionPtr ret;
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDst);
+
+ /* The driver will only call SourceValidate() when pSrc != pDst,
+ * but the software sprite (misprite.c) always need to know when a
+ * drawable is copied so it can remove the sprite. See #1030. */
+ if ((pSrc == pDst) && pSrc->pScreen->SourceValidate &&
+ pSrc->type == DRAWABLE_WINDOW &&
+ ((WindowPtr)pSrc)->viewable)
+ {
+ (*pSrc->pScreen->SourceValidate) (pSrc, srcx, srcy, width, height);
+ }
+
+ if (checkGCDamage (pDst, pGC))
+ {
+ BoxRec box;
+
+ box.x1 = dstx + pDst->x;
+ box.x2 = box.x1 + width;
+ box.y1 = dsty + pDst->y;
+ box.y2 = box.y1 + height;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDst, &box, pGC->subWindowMode);
+ }
+
+ ret = (*pGC->ops->CopyPlane)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDst);
+ return ret;
+}
+
+static void
+damagePolyPoint(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ xPoint *ppt)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (npt && checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+ int nptTmp = npt;
+ xPoint *pptTmp = ppt;
+
+ box.x2 = box.x1 = pptTmp->x;
+ box.y2 = box.y1 = pptTmp->y;
+
+ /* this could be slow if the points were spread out */
+
+ while(--nptTmp)
+ {
+ pptTmp++;
+ if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+ else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x;
+ if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+ else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+ }
+
+ box.x2++;
+ box.y2++;
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PolyPoint)(pDrawable, pGC, mode, npt, ppt);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolylines(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr ppt)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (npt && checkGCDamage (pDrawable, pGC))
+ {
+ int nptTmp = npt;
+ DDXPointPtr pptTmp = ppt;
+ BoxRec box;
+ int extra = pGC->lineWidth >> 1;
+
+ box.x2 = box.x1 = pptTmp->x;
+ box.y2 = box.y1 = pptTmp->y;
+
+ if(nptTmp > 1)
+ {
+ if(pGC->joinStyle == JoinMiter)
+ extra = 6 * pGC->lineWidth;
+ else if(pGC->capStyle == CapProjecting)
+ extra = pGC->lineWidth;
+ }
+
+ if(mode == CoordModePrevious)
+ {
+ int x = box.x1;
+ int y = box.y1;
+ while(--nptTmp)
+ {
+ pptTmp++;
+ x += pptTmp->x;
+ y += pptTmp->y;
+ if(box.x1 > x) box.x1 = x;
+ else if(box.x2 < x) box.x2 = x;
+ if(box.y1 > y) box.y1 = y;
+ else if(box.y2 < y) box.y2 = y;
+ }
+ }
+ else
+ {
+ while(--nptTmp)
+ {
+ pptTmp++;
+ if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+ else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x;
+ if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+ else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+ }
+ }
+
+ box.x2++;
+ box.y2++;
+
+ if(extra)
+ {
+ box.x1 -= extra;
+ box.x2 += extra;
+ box.y1 -= extra;
+ box.y2 += extra;
+ }
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->Polylines)(pDrawable, pGC, mode, npt, ppt);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolySegment(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nSeg,
+ xSegment *pSeg)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (nSeg && checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+ int extra = pGC->lineWidth;
+ int nsegTmp = nSeg;
+ xSegment *pSegTmp = pSeg;
+
+ if(pGC->capStyle != CapProjecting)
+ extra >>= 1;
+
+ if(pSegTmp->x2 > pSegTmp->x1) {
+ box.x1 = pSegTmp->x1;
+ box.x2 = pSegTmp->x2;
+ } else {
+ box.x2 = pSegTmp->x1;
+ box.x1 = pSegTmp->x2;
+ }
+
+ if(pSegTmp->y2 > pSegTmp->y1) {
+ box.y1 = pSegTmp->y1;
+ box.y2 = pSegTmp->y2;
+ } else {
+ box.y2 = pSegTmp->y1;
+ box.y1 = pSegTmp->y2;
+ }
+
+ while(--nsegTmp)
+ {
+ pSegTmp++;
+ if(pSegTmp->x2 > pSegTmp->x1)
+ {
+ if(pSegTmp->x1 < box.x1) box.x1 = pSegTmp->x1;
+ if(pSegTmp->x2 > box.x2) box.x2 = pSegTmp->x2;
+ }
+ else
+ {
+ if(pSegTmp->x2 < box.x1) box.x1 = pSegTmp->x2;
+ if(pSegTmp->x1 > box.x2) box.x2 = pSegTmp->x1;
+ }
+ if(pSegTmp->y2 > pSegTmp->y1)
+ {
+ if(pSegTmp->y1 < box.y1) box.y1 = pSegTmp->y1;
+ if(pSegTmp->y2 > box.y2) box.y2 = pSegTmp->y2;
+ }
+ else
+ {
+ if(pSegTmp->y2 < box.y1) box.y1 = pSegTmp->y2;
+ if(pSegTmp->y1 > box.y2) box.y2 = pSegTmp->y1;
+ }
+ }
+
+ box.x2++;
+ box.y2++;
+
+ if(extra)
+ {
+ box.x1 -= extra;
+ box.x2 += extra;
+ box.y1 -= extra;
+ box.y2 += extra;
+ }
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PolySegment)(pDrawable, pGC, nSeg, pSeg);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolyRectangle(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nRects,
+ xRectangle *pRects)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (nRects && checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+ int offset1, offset2, offset3;
+ int nRectsTmp = nRects;
+ xRectangle *pRectsTmp = pRects;
+
+ offset2 = pGC->lineWidth;
+ if(!offset2) offset2 = 1;
+ offset1 = offset2 >> 1;
+ offset3 = offset2 - offset1;
+
+ while(nRectsTmp--)
+ {
+ box.x1 = pRectsTmp->x - offset1;
+ box.y1 = pRectsTmp->y - offset1;
+ box.x2 = box.x1 + pRectsTmp->width + offset2;
+ box.y2 = box.y1 + offset2;
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+ box.x1 = pRectsTmp->x - offset1;
+ box.y1 = pRectsTmp->y + offset3;
+ box.x2 = box.x1 + offset2;
+ box.y2 = box.y1 + pRectsTmp->height - offset2;
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+ box.x1 = pRectsTmp->x + pRectsTmp->width - offset1;
+ box.y1 = pRectsTmp->y + offset3;
+ box.x2 = box.x1 + offset2;
+ box.y2 = box.y1 + pRectsTmp->height - offset2;
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+ box.x1 = pRectsTmp->x - offset1;
+ box.y1 = pRectsTmp->y + pRectsTmp->height - offset1;
+ box.x2 = box.x1 + pRectsTmp->width + offset2;
+ box.y2 = box.y1 + offset2;
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+ pRectsTmp++;
+ }
+ }
+ (*pGC->ops->PolyRectangle)(pDrawable, pGC, nRects, pRects);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolyArc(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nArcs,
+ xArc *pArcs)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (nArcs && checkGCDamage (pDrawable, pGC))
+ {
+ int extra = pGC->lineWidth >> 1;
+ BoxRec box;
+ int nArcsTmp = nArcs;
+ xArc *pArcsTmp = pArcs;
+
+ box.x1 = pArcsTmp->x;
+ box.x2 = box.x1 + pArcsTmp->width;
+ box.y1 = pArcsTmp->y;
+ box.y2 = box.y1 + pArcsTmp->height;
+
+ while(--nArcsTmp)
+ {
+ pArcsTmp++;
+ if(box.x1 > pArcsTmp->x)
+ box.x1 = pArcsTmp->x;
+ if(box.x2 < (pArcsTmp->x + pArcsTmp->width))
+ box.x2 = pArcsTmp->x + pArcsTmp->width;
+ if(box.y1 > pArcsTmp->y)
+ box.y1 = pArcsTmp->y;
+ if(box.y2 < (pArcsTmp->y + pArcsTmp->height))
+ box.y2 = pArcsTmp->y + pArcsTmp->height;
+ }
+
+ if(extra)
+ {
+ box.x1 -= extra;
+ box.x2 += extra;
+ box.y1 -= extra;
+ box.y2 += extra;
+ }
+
+ box.x2++;
+ box.y2++;
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PolyArc)(pDrawable, pGC, nArcs, pArcs);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageFillPolygon(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int npt,
+ DDXPointPtr ppt)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (npt > 2 && checkGCDamage (pDrawable, pGC))
+ {
+ DDXPointPtr pptTmp = ppt;
+ int nptTmp = npt;
+ BoxRec box;
+
+ box.x2 = box.x1 = pptTmp->x;
+ box.y2 = box.y1 = pptTmp->y;
+
+ if(mode != CoordModeOrigin)
+ {
+ int x = box.x1;
+ int y = box.y1;
+ while(--nptTmp)
+ {
+ pptTmp++;
+ x += pptTmp->x;
+ y += pptTmp->y;
+ if(box.x1 > x) box.x1 = x;
+ else if(box.x2 < x) box.x2 = x;
+ if(box.y1 > y) box.y1 = y;
+ else if(box.y2 < y) box.y2 = y;
+ }
+ }
+ else
+ {
+ while(--nptTmp)
+ {
+ pptTmp++;
+ if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+ else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x;
+ if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+ else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+ }
+ }
+
+ box.x2++;
+ box.y2++;
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+
+ (*pGC->ops->FillPolygon)(pDrawable, pGC, shape, mode, npt, ppt);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+
+static void
+damagePolyFillRect(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nRects,
+ xRectangle *pRects)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+ if (nRects && checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+ xRectangle *pRectsTmp = pRects;
+ int nRectsTmp = nRects;
+
+ box.x1 = pRectsTmp->x;
+ box.x2 = box.x1 + pRectsTmp->width;
+ box.y1 = pRectsTmp->y;
+ box.y2 = box.y1 + pRectsTmp->height;
+
+ while(--nRectsTmp)
+ {
+ pRectsTmp++;
+ if(box.x1 > pRectsTmp->x) box.x1 = pRectsTmp->x;
+ if(box.x2 < (pRectsTmp->x + pRectsTmp->width))
+ box.x2 = pRectsTmp->x + pRectsTmp->width;
+ if(box.y1 > pRectsTmp->y) box.y1 = pRectsTmp->y;
+ if(box.y2 < (pRectsTmp->y + pRectsTmp->height))
+ box.y2 = pRectsTmp->y + pRectsTmp->height;
+ }
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PolyFillRect)(pDrawable, pGC, nRects, pRects);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+
+static void
+damagePolyFillArc(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nArcs,
+ xArc *pArcs)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (nArcs && checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+ int nArcsTmp = nArcs;
+ xArc *pArcsTmp = pArcs;
+
+ box.x1 = pArcsTmp->x;
+ box.x2 = box.x1 + pArcsTmp->width;
+ box.y1 = pArcsTmp->y;
+ box.y2 = box.y1 + pArcsTmp->height;
+
+ while(--nArcsTmp)
+ {
+ pArcsTmp++;
+ if(box.x1 > pArcsTmp->x)
+ box.x1 = pArcsTmp->x;
+ if(box.x2 < (pArcsTmp->x + pArcsTmp->width))
+ box.x2 = pArcsTmp->x + pArcsTmp->width;
+ if(box.y1 > pArcsTmp->y)
+ box.y1 = pArcsTmp->y;
+ if(box.y2 < (pArcsTmp->y + pArcsTmp->height))
+ box.y2 = pArcsTmp->y + pArcsTmp->height;
+ }
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PolyFillArc)(pDrawable, pGC, nArcs, pArcs);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+/*
+ * general Poly/Image text function. Extract glyph information,
+ * compute bounding box and remove cursor if it is overlapped.
+ */
+
+static void
+damageDamageChars (DrawablePtr pDrawable,
+ FontPtr font,
+ int x,
+ int y,
+ unsigned int n,
+ CharInfoPtr *charinfo,
+ Bool imageblt,
+ int subWindowMode)
+{
+ ExtentInfoRec extents;
+ BoxRec box;
+
+ QueryGlyphExtents(font, charinfo, n, &extents);
+ if (imageblt)
+ {
+ if (extents.overallWidth > extents.overallRight)
+ extents.overallRight = extents.overallWidth;
+ if (extents.overallWidth < extents.overallLeft)
+ extents.overallLeft = extents.overallWidth;
+ if (extents.overallLeft > 0)
+ extents.overallLeft = 0;
+ if (extents.fontAscent > extents.overallAscent)
+ extents.overallAscent = extents.fontAscent;
+ if (extents.fontDescent > extents.overallDescent)
+ extents.overallDescent = extents.fontDescent;
+ }
+ box.x1 = x + extents.overallLeft;
+ box.y1 = y - extents.overallAscent;
+ box.x2 = x + extents.overallRight;
+ box.y2 = y + extents.overallDescent;
+ damageDamageBox (pDrawable, &box, subWindowMode);
+}
+
+/*
+ * values for textType:
+ */
+#define TT_POLY8 0
+#define TT_IMAGE8 1
+#define TT_POLY16 2
+#define TT_IMAGE16 3
+
+static int
+damageText (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned long count,
+ char *chars,
+ FontEncoding fontEncoding,
+ Bool textType)
+{
+ CharInfoPtr *charinfo;
+ CharInfoPtr *info;
+ unsigned long i;
+ unsigned int n;
+ int w;
+ Bool imageblt;
+
+ imageblt = (textType == TT_IMAGE8) || (textType == TT_IMAGE16);
+
+ charinfo = (CharInfoPtr *) ALLOCATE_LOCAL(count * sizeof(CharInfoPtr));
+ if (!charinfo)
+ return x;
+
+ GetGlyphs(pGC->font, count, (unsigned char *)chars,
+ fontEncoding, &i, charinfo);
+ n = (unsigned int)i;
+ w = 0;
+ if (!imageblt)
+ for (info = charinfo; i--; info++)
+ w += (*info)->metrics.characterWidth;
+
+ if (n != 0) {
+ damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y, n,
+ charinfo, imageblt, pGC->subWindowMode);
+ if (imageblt)
+ (*pGC->ops->ImageGlyphBlt)(pDrawable, pGC, x, y, n, charinfo,
+ FONTGLYPHS(pGC->font));
+ else
+ (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, n, charinfo,
+ FONTGLYPHS(pGC->font));
+ }
+ DEALLOCATE_LOCAL(charinfo);
+ return x + w;
+}
+
+static int
+damagePolyText8(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ x = damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
+ Linear8Bit, TT_POLY8);
+ else
+ x = (*pGC->ops->PolyText8)(pDrawable, pGC, x, y, count, chars);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+ return x;
+}
+
+static int
+damagePolyText16(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ x = damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
+ FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
+ TT_POLY16);
+ else
+ x = (*pGC->ops->PolyText16)(pDrawable, pGC, x, y, count, chars);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+ return x;
+}
+
+static void
+damageImageText8(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
+ Linear8Bit, TT_IMAGE8);
+ else
+ (*pGC->ops->ImageText8)(pDrawable, pGC, x, y, count, chars);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageImageText16(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
+ FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
+ TT_IMAGE16);
+ else
+ (*pGC->ops->ImageText16)(pDrawable, pGC, x, y, count, chars);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+
+static void
+damageImageGlyphBlt(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+ damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y,
+ nglyph, ppci, TRUE, pGC->subWindowMode);
+ (*pGC->ops->ImageGlyphBlt)(pDrawable, pGC, x, y, nglyph,
+ ppci, pglyphBase);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolyGlyphBlt(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+ damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y,
+ nglyph, ppci, FALSE, pGC->subWindowMode);
+ (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, nglyph,
+ ppci, pglyphBase);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePushPixels(GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDrawable,
+ int dx,
+ int dy,
+ int xOrg,
+ int yOrg)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+ if(checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+
+ box.x1 = xOrg;
+ box.y1 = yOrg;
+
+ if(!pGC->miTranslate) {
+ box.x1 += pDrawable->x;
+ box.y1 += pDrawable->y;
+ }
+
+ box.x2 = box.x1 + dx;
+ box.y2 = box.y1 + dy;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PushPixels)(pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageRemoveDamage (DamagePtr *pPrev, DamagePtr pDamage)
+{
+ while (*pPrev)
+ {
+ if (*pPrev == pDamage)
+ {
+ *pPrev = pDamage->pNext;
+ return;
+ }
+ pPrev = &(*pPrev)->pNext;
+ }
+#if DAMAGE_VALIDATE_ENABLE
+ ErrorF ("Damage not on list\n");
+ abort ();
+#endif
+}
+
+static void
+damageInsertDamage (DamagePtr *pPrev, DamagePtr pDamage)
+{
+#if DAMAGE_VALIDATE_ENABLE
+ DamagePtr pOld;
+
+ for (pOld = *pPrev; pOld; pOld = pOld->pNext)
+ if (pOld == pDamage) {
+ ErrorF ("Damage already on list\n");
+ abort ();
+ }
+#endif
+ pDamage->pNext = *pPrev;
+ *pPrev = pDamage;
+}
+
+static Bool
+damageDestroyPixmap (PixmapPtr pPixmap)
+{
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ damageScrPriv(pScreen);
+
+ if (pPixmap->refcnt == 1)
+ {
+ DamagePtr *pPrev = getPixmapDamageRef (pPixmap);
+ DamagePtr pDamage;
+
+ while ((pDamage = *pPrev))
+ {
+ damageRemoveDamage (pPrev, pDamage);
+ if (!pDamage->isWindow)
+ DamageDestroy (pDamage);
+ }
+ }
+ unwrap (pScrPriv, pScreen, DestroyPixmap);
+ (*pScreen->DestroyPixmap) (pPixmap);
+ wrap (pScrPriv, pScreen, DestroyPixmap, damageDestroyPixmap);
+ return TRUE;
+}
+
+static void
+damagePaintWindow(WindowPtr pWindow,
+ RegionPtr prgn,
+ int what)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ damageScrPriv(pScreen);
+
+ /*
+ * Painting background none doesn't actually *do* anything, so
+ * no damage is recorded
+ */
+ if ((what != PW_BACKGROUND || pWindow->backgroundState != None) &&
+ getWindowDamage (pWindow))
+ damageDamageRegion (&pWindow->drawable, prgn, FALSE, -1);
+ if(what == PW_BACKGROUND) {
+ unwrap (pScrPriv, pScreen, PaintWindowBackground);
+ (*pScreen->PaintWindowBackground) (pWindow, prgn, what);
+ wrap (pScrPriv, pScreen, PaintWindowBackground, damagePaintWindow);
+ } else {
+ unwrap (pScrPriv, pScreen, PaintWindowBorder);
+ (*pScreen->PaintWindowBorder) (pWindow, prgn, what);
+ wrap (pScrPriv, pScreen, PaintWindowBorder, damagePaintWindow);
+ }
+}
+
+
+static void
+damageCopyWindow(WindowPtr pWindow,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ damageScrPriv(pScreen);
+
+ if (getWindowDamage (pWindow))
+ {
+ int dx = pWindow->drawable.x - ptOldOrg.x;
+ int dy = pWindow->drawable.y - ptOldOrg.y;
+
+ /*
+ * The region comes in source relative, but the damage occurs
+ * at the destination location. Translate back and forth.
+ */
+ REGION_TRANSLATE (pScreen, prgnSrc, dx, dy);
+ damageDamageRegion (&pWindow->drawable, prgnSrc, FALSE, -1);
+ REGION_TRANSLATE (pScreen, prgnSrc, -dx, -dy);
+ }
+ unwrap (pScrPriv, pScreen, CopyWindow);
+ (*pScreen->CopyWindow) (pWindow, ptOldOrg, prgnSrc);
+ wrap (pScrPriv, pScreen, CopyWindow, damageCopyWindow);
+}
+
+GCOps damageGCOps = {
+ damageFillSpans, damageSetSpans,
+ damagePutImage, damageCopyArea,
+ damageCopyPlane, damagePolyPoint,
+ damagePolylines, damagePolySegment,
+ damagePolyRectangle, damagePolyArc,
+ damageFillPolygon, damagePolyFillRect,
+ damagePolyFillArc, damagePolyText8,
+ damagePolyText16, damageImageText8,
+ damageImageText16, damageImageGlyphBlt,
+ damagePolyGlyphBlt, damagePushPixels,
+#ifdef NEED_LINEHELPER
+ NULL,
+#endif
+ {NULL} /* devPrivate */
+};
+
+static void
+damageRestoreAreas (PixmapPtr pPixmap,
+ RegionPtr prgn,
+ int xorg,
+ int yorg,
+ WindowPtr pWindow)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ damageScrPriv(pScreen);
+
+ damageDamageRegion (&pWindow->drawable, prgn, FALSE, -1);
+ unwrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas);
+ (*pScreen->BackingStoreFuncs.RestoreAreas) (pPixmap, prgn,
+ xorg, yorg, pWindow);
+ wrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas,
+ damageRestoreAreas);
+}
+
+static void
+damageSetWindowPixmap (WindowPtr pWindow, PixmapPtr pPixmap)
+{
+ DamagePtr pDamage;
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ damageScrPriv(pScreen);
+
+ if ((pDamage = damageGetWinPriv(pWindow)))
+ {
+ PixmapPtr pOldPixmap = (*pScreen->GetWindowPixmap) (pWindow);
+ DamagePtr *pPrev = getPixmapDamageRef(pOldPixmap);
+
+ while (pDamage)
+ {
+ damageRemoveDamage (pPrev, pDamage);
+ pDamage = pDamage->pNextWin;
+ }
+ }
+ unwrap (pScrPriv, pScreen, SetWindowPixmap);
+ (*pScreen->SetWindowPixmap) (pWindow, pPixmap);
+ wrap (pScrPriv, pScreen, SetWindowPixmap, damageSetWindowPixmap);
+ if ((pDamage = damageGetWinPriv(pWindow)))
+ {
+ DamagePtr *pPrev = getPixmapDamageRef(pPixmap);
+
+ while (pDamage)
+ {
+ damageInsertDamage (pPrev, pDamage);
+ pDamage = pDamage->pNextWin;
+ }
+ }
+}
+
+static Bool
+damageDestroyWindow (WindowPtr pWindow)
+{
+ DamagePtr pDamage;
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ Bool ret;
+ damageScrPriv(pScreen);
+
+ while ((pDamage = damageGetWinPriv(pWindow)))
+ {
+ DamageUnregister (&pWindow->drawable, pDamage);
+ DamageDestroy (pDamage);
+ }
+ unwrap (pScrPriv, pScreen, DestroyWindow);
+ ret = (*pScreen->DestroyWindow) (pWindow);
+ wrap (pScrPriv, pScreen, DestroyWindow, damageDestroyWindow);
+ return ret;
+}
+
+static Bool
+damageCloseScreen (int i, ScreenPtr pScreen)
+{
+ damageScrPriv(pScreen);
+
+ unwrap (pScrPriv, pScreen, DestroyPixmap);
+ unwrap (pScrPriv, pScreen, CreateGC);
+ unwrap (pScrPriv, pScreen, PaintWindowBackground);
+ unwrap (pScrPriv, pScreen, PaintWindowBorder);
+ unwrap (pScrPriv, pScreen, CopyWindow);
+ unwrap (pScrPriv, pScreen, CloseScreen);
+ unwrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas);
+ xfree (pScrPriv);
+ return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+int damageScrPrivateIndex;
+int damagePixPrivateIndex;
+int damageGCPrivateIndex;
+int damageWinPrivateIndex;
+int damageGeneration;
+
+Bool
+DamageSetup (ScreenPtr pScreen)
+{
+ DamageScrPrivPtr pScrPriv;
+#ifdef RENDER
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+#endif
+
+ if (damageGeneration != serverGeneration)
+ {
+ damageScrPrivateIndex = AllocateScreenPrivateIndex ();
+ if (damageScrPrivateIndex == -1)
+ return FALSE;
+ damageGCPrivateIndex = AllocateGCPrivateIndex ();
+ if (damageGCPrivateIndex == -1)
+ return FALSE;
+ damagePixPrivateIndex = AllocatePixmapPrivateIndex ();
+ if (damagePixPrivateIndex == -1)
+ return FALSE;
+ damageWinPrivateIndex = AllocateWindowPrivateIndex ();
+ if (damageWinPrivateIndex == -1)
+ return FALSE;
+ damageGeneration = serverGeneration;
+ }
+ if (pScreen->devPrivates[damageScrPrivateIndex].ptr)
+ return TRUE;
+
+ if (!AllocateGCPrivate (pScreen, damageGCPrivateIndex, sizeof (DamageGCPrivRec)))
+ return FALSE;
+ if (!AllocatePixmapPrivate (pScreen, damagePixPrivateIndex, 0))
+ return FALSE;
+ if (!AllocateWindowPrivate (pScreen, damageWinPrivateIndex, 0))
+ return FALSE;
+
+ pScrPriv = (DamageScrPrivPtr) xalloc (sizeof (DamageScrPrivRec));
+ if (!pScrPriv)
+ return FALSE;
+
+#ifdef COMPOSITE
+ /* This is a kludge to ensure wrapping order with the composite wrapper.
+ * If it's done from compinit.c, then DamageSetup may be called before the
+ * extension init phase, so that cw will be higher in the wrapping chain and
+ * rewrite drawables before damage gets to it, causing confusion.
+ */
+ if (!noCompositeExtension)
+ miInitializeCompositeWrapper (pScreen);
+#endif
+
+ pScrPriv->internalLevel = 0;
+ pScrPriv->pScreenDamage = 0;
+
+ wrap (pScrPriv, pScreen, DestroyPixmap, damageDestroyPixmap);
+ wrap (pScrPriv, pScreen, CreateGC, damageCreateGC);
+ wrap (pScrPriv, pScreen, PaintWindowBackground, damagePaintWindow);
+ wrap (pScrPriv, pScreen, PaintWindowBorder, damagePaintWindow);
+ wrap (pScrPriv, pScreen, DestroyWindow, damageDestroyWindow);
+ wrap (pScrPriv, pScreen, SetWindowPixmap, damageSetWindowPixmap);
+ wrap (pScrPriv, pScreen, CopyWindow, damageCopyWindow);
+ wrap (pScrPriv, pScreen, CloseScreen, damageCloseScreen);
+ wrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas,
+ damageRestoreAreas);
+#ifdef RENDER
+ if (ps) {
+ wrap (pScrPriv, ps, Glyphs, damageGlyphs);
+ wrap (pScrPriv, ps, Composite, damageComposite);
+ }
+#endif
+
+ pScreen->devPrivates[damageScrPrivateIndex].ptr = (pointer) pScrPriv;
+ return TRUE;
+}
+
+DamagePtr
+DamageCreate (DamageReportFunc damageReport,
+ DamageDestroyFunc damageDestroy,
+ DamageReportLevel damageLevel,
+ Bool isInternal,
+ ScreenPtr pScreen,
+ void *closure)
+{
+ DamagePtr pDamage;
+
+ pDamage = xalloc (sizeof (DamageRec));
+ if (!pDamage)
+ return 0;
+ pDamage->pNext = 0;
+ pDamage->pNextWin = 0;
+ REGION_NULL(pScreen, &pDamage->damage);
+
+ pDamage->damageLevel = damageLevel;
+ pDamage->isInternal = isInternal;
+ pDamage->closure = closure;
+ pDamage->isWindow = FALSE;
+ pDamage->pDrawable = 0;
+
+ pDamage->damageReport = damageReport;
+ pDamage->damageDestroy = damageDestroy;
+ return pDamage;
+}
+
+void
+DamageRegister (DrawablePtr pDrawable,
+ DamagePtr pDamage)
+{
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ WindowPtr pWindow = (WindowPtr) pDrawable;
+ winDamageRef(pWindow);
+
+#if DAMAGE_VALIDATE_ENABLE
+ DamagePtr pOld;
+
+ for (pOld = *pPrev; pOld; pOld = pOld->pNextWin)
+ if (pOld == pDamage) {
+ ErrorF ("Damage already on window list\n");
+ abort ();
+ }
+#endif
+ pDamage->pNextWin = *pPrev;
+ *pPrev = pDamage;
+ pDamage->isWindow = TRUE;
+ }
+ else
+ pDamage->isWindow = FALSE;
+ pDamage->pDrawable = pDrawable;
+ damageInsertDamage (getDrawableDamageRef (pDrawable), pDamage);
+}
+
+void
+DamageDrawInternal (ScreenPtr pScreen, Bool enable)
+{
+ damageScrPriv (pScreen);
+
+ pScrPriv->internalLevel += enable ? 1 : -1;
+}
+
+void
+DamageUnregister (DrawablePtr pDrawable,
+ DamagePtr pDamage)
+{
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ WindowPtr pWindow = (WindowPtr) pDrawable;
+ winDamageRef (pWindow);
+#if DAMAGE_VALIDATE_ENABLE
+ int found = 0;
+#endif
+
+ while (*pPrev)
+ {
+ if (*pPrev == pDamage)
+ {
+ *pPrev = pDamage->pNextWin;
+#if DAMAGE_VALIDATE_ENABLE
+ found = 1;
+#endif
+ break;
+ }
+ pPrev = &(*pPrev)->pNextWin;
+ }
+#if DAMAGE_VALIDATE_ENABLE
+ if (!found) {
+ ErrorF ("Damage not on window list\n");
+ abort ();
+ }
+#endif
+ }
+ pDamage->pDrawable = 0;
+ damageRemoveDamage (getDrawableDamageRef (pDrawable), pDamage);
+}
+
+void
+DamageDestroy (DamagePtr pDamage)
+{
+ if (pDamage->damageDestroy)
+ (*pDamage->damageDestroy) (pDamage, pDamage->closure);
+ REGION_UNINIT (pDamage->pDrawable->pScreen, &pDamage->damage);
+ xfree (pDamage);
+}
+
+Bool
+DamageSubtract (DamagePtr pDamage,
+ const RegionPtr pRegion)
+{
+ RegionPtr pClip;
+ RegionRec pixmapClip;
+ DrawablePtr pDrawable = pDamage->pDrawable;
+
+ REGION_SUBTRACT (pDrawable->pScreen, &pDamage->damage, &pDamage->damage, pRegion);
+ if (pDrawable)
+ {
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ pClip = &((WindowPtr) pDrawable)->borderClip;
+ else
+ {
+ BoxRec box;
+
+ box.x1 = pDrawable->x;
+ box.y1 = pDrawable->y;
+ box.x2 = pDrawable->x + pDrawable->width;
+ box.y2 = pDrawable->y + pDrawable->height;
+ REGION_INIT (pDrawable->pScreen, &pixmapClip, &box, 1);
+ pClip = &pixmapClip;
+ }
+ REGION_TRANSLATE (pDrawable->pScreen, &pDamage->damage, pDrawable->x, pDrawable->y);
+ REGION_INTERSECT (pDrawable->pScreen, &pDamage->damage, &pDamage->damage, pClip);
+ REGION_TRANSLATE (pDrawable->pScreen, &pDamage->damage, -pDrawable->x, -pDrawable->y);
+ if (pDrawable->type != DRAWABLE_WINDOW)
+ REGION_UNINIT(pDrawable->pScreen, &pixmapClip);
+ }
+ return REGION_NOTEMPTY (pDrawable->pScreen, &pDamage->damage);
+}
+
+void
+DamageEmpty (DamagePtr pDamage)
+{
+ REGION_EMPTY (pDamage->pDrawable->pScreen, &pDamage->damage);
+}
+
+RegionPtr
+DamageRegion (DamagePtr pDamage)
+{
+ return &pDamage->damage;
+}
+
+void
+DamageDamageRegion (DrawablePtr pDrawable,
+ RegionPtr pRegion)
+{
+ damageDamageRegion (pDrawable, pRegion, FALSE, -1);
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
new file mode 100644
index 000000000..845c6cfb9
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
@@ -0,0 +1,4670 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/* $XdotOrg: xc/programs/Xserver/dix/dispatch.c,v 1.13 2005/09/13 01:33:19 daniels Exp $ */
+/* $Xorg: dispatch.c,v 1.5 2001/02/09 02:04:40 xorgcvs Exp $ */
+/************************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+********************************************************/
+
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/dispatch.c,v 3.32 2003/11/10 18:21:45 tsi Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifdef PANORAMIX_DEBUG
+#include <stdio.h>
+int ProcInitialConnection();
+#endif
+
+#ifdef __sun
+#define False 0
+#define True 1
+#endif
+
+#define GC XlibGC
+#include <X11/Xlib.h>
+#undef GC
+
+#include "windowstr.h"
+#include <X11/fonts/fontstruct.h>
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "selection.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "opaque.h"
+#include "input.h"
+#include "servermd.h"
+#include "extnsionst.h"
+#include "dixfont.h"
+#include "../../dix/dispatch.h"
+#include "swaprep.h"
+#include "swapreq.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+#ifdef XAPPGROUP
+#include <X11/extensions/Xagsrv.h>
+#endif
+#ifdef XKB
+#define XKB_IN_SERVER
+#include "inputstr.h"
+#include <X11/extensions/XKBsrv.h>
+#endif
+
+#include "Atoms.h"
+#include "Splash.h"
+#include "Client.h"
+#include "Clipboard.h"
+#include "Reconnect.h"
+#include "Millis.h"
+#include "Font.h"
+#include "Shadow.h"
+#include "Handlers.h"
+#include "Keyboard.h"
+
+const int nxagentMaxFontNames = 10000;
+
+char dispatchExceptionAtReset = DE_RESET;
+
+/*
+ * This allows the agent to exit if no
+ * client is connected within a timeout.
+ */
+
+int nxagentClients = 0;
+
+void nxagentWaitDisplay(void);
+
+void nxagentListRemoteFonts(const char *, int);
+
+unsigned int nxagentWMtimeout = 0;
+Bool nxagentWMPassed = 0;
+
+/*
+ * Timeouts based on screen saver time.
+ */
+
+int nxagentAutoDisconnectTimeout = 0;
+
+#ifdef LBX
+#include "../../lbx/lbxserve.h"
+#endif
+
+#include "Xatom.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef WATCH
+
+/*
+ * Log begin and end of the important handlers.
+ */
+
+#undef BLOCKS
+
+#ifdef WATCH
+#include "unistd.h"
+#endif
+
+#ifdef TEST
+#include "Literals.h"
+#endif
+
+#define mskcnt ((MAXCLIENTS + 31) / 32)
+#define BITMASK(i) (1U << ((i) & 31))
+#define MASKIDX(i) ((i) >> 5)
+#define MASKWORD(buf, i) buf[MASKIDX(i)]
+#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
+#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
+#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
+
+extern xConnSetupPrefix connSetupPrefix;
+extern char *ConnectionInfo;
+
+Selection *CurrentSelections;
+int NumCurrentSelections;
+CallbackListPtr SelectionCallback = NULL;
+
+#ifdef VIEWPORT_FRAME
+
+extern WindowPtr nxagentViewportFrameLeft;
+extern WindowPtr nxagentViewportFrameRight;
+extern WindowPtr nxagentViewportFrameAbove;
+extern WindowPtr nxagentViewportFrameBelow;
+
+#define IsViewportFrame(pWin) ((pWin) == nxagentViewportFrameLeft || \
+ (pWin) == nxagentViewportFrameRight || \
+ (pWin) == nxagentViewportFrameAbove || \
+ (pWin) == nxagentViewportFrameBelow)
+
+#else
+
+#define IsViewportFrame(pWin) (0)
+
+#endif /* #ifdef VIEWPORT_FRAME */
+
+extern int nxagentMaxAllowedResets;
+
+extern int nxagentFindClientResource(int, RESTYPE, pointer);
+
+static ClientPtr grabClient;
+#define GrabNone 0
+#define GrabActive 1
+#define GrabKickout 2
+static int grabState = GrabNone;
+static long grabWaiters[mskcnt];
+CallbackListPtr ServerGrabCallback = NULL;
+HWEventQueuePtr checkForInput[2];
+extern int connBlockScreenStart;
+
+static void KillAllClients(void);
+
+static void DeleteClientFromAnySelections(ClientPtr client);
+
+static int nextFreeClientID; /* always MIN free client ID */
+
+static int nClients; /* number of authorized clients */
+
+CallbackListPtr ClientStateCallback;
+
+/* dispatchException & isItTimeToYield must be declared volatile since they
+ * are modified by signal handlers - otherwise optimizer may assume it doesn't
+ * need to actually check value in memory when used and may miss changes from
+ * signal handlers.
+ */
+volatile char dispatchException = 0;
+volatile char isItTimeToYield;
+
+/* Various of the DIX function interfaces were not designed to allow
+ * the client->errorValue to be set on BadValue and other errors.
+ * Rather than changing interfaces and breaking untold code we introduce
+ * a new global that dispatch can use.
+ */
+XID clientErrorValue; /* XXX this is a kludge */
+
+#define SAME_SCREENS(a, b) (\
+ (a.pScreen == b.pScreen))
+
+void
+SetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1)
+{
+ checkForInput[0] = c0;
+ checkForInput[1] = c1;
+}
+
+void
+UpdateCurrentTime()
+{
+ TimeStamp systime;
+
+ /* To avoid time running backwards, we must call GetTimeInMillis before
+ * calling ProcessInputEvents.
+ */
+ systime.months = currentTime.months;
+ systime.milliseconds = GetTimeInMillis();
+ if (systime.milliseconds < currentTime.milliseconds)
+ systime.months++;
+ if (*checkForInput[0] != *checkForInput[1])
+ ProcessInputEvents();
+ if (CompareTimeStamps(systime, currentTime) == LATER)
+ currentTime = systime;
+}
+
+/* Like UpdateCurrentTime, but can't call ProcessInputEvents */
+void
+UpdateCurrentTimeIf()
+{
+ TimeStamp systime;
+
+ systime.months = currentTime.months;
+ systime.milliseconds = GetTimeInMillis();
+ if (systime.milliseconds < currentTime.milliseconds)
+ systime.months++;
+ if (*checkForInput[0] == *checkForInput[1])
+ currentTime = systime;
+}
+
+void
+InitSelections()
+{
+ if (CurrentSelections)
+ xfree(CurrentSelections);
+ CurrentSelections = (Selection *)NULL;
+ NumCurrentSelections = 0;
+
+#ifdef NXAGENT_CLIPBOARD
+ {
+ Selection *newsels;
+ newsels = (Selection *)xalloc(2 * sizeof(Selection));
+ if (!newsels)
+ return;
+ NumCurrentSelections += 2;
+ CurrentSelections = newsels;
+
+ CurrentSelections[0].selection = XA_PRIMARY;
+ CurrentSelections[0].lastTimeChanged = ClientTimeToServerTime(0);
+ CurrentSelections[0].window = WindowTable[0]->drawable.id;
+ CurrentSelections[0].pWin = NULL;
+ CurrentSelections[0].client = NullClient;
+
+ CurrentSelections[1].selection = MakeAtom("CLIPBOARD", 9, 1);
+ CurrentSelections[1].lastTimeChanged = ClientTimeToServerTime(0);
+ CurrentSelections[1].window = WindowTable[0]->drawable.id;
+ CurrentSelections[1].pWin = NULL;
+ CurrentSelections[1].client = NullClient;
+ }
+#endif
+
+}
+
+void
+FlushClientCaches(XID id)
+{
+ int i;
+ register ClientPtr client;
+
+ client = clients[CLIENT_ID(id)];
+ if (client == NullClient)
+ return ;
+ for (i=0; i<currentMaxClients; i++)
+ {
+ client = clients[i];
+ if (client != NullClient)
+ {
+ if (client->lastDrawableID == id)
+ {
+ client->lastDrawableID = WindowTable[0]->drawable.id;
+ client->lastDrawable = (DrawablePtr)WindowTable[0];
+ }
+ else if (client->lastGCID == id)
+ {
+ client->lastGCID = INVALID;
+ client->lastGC = (GCPtr)NULL;
+ }
+ }
+ }
+}
+#ifdef SMART_SCHEDULE
+
+#undef SMART_DEBUG
+
+#define SMART_SCHEDULE_DEFAULT_INTERVAL 20 /* ms */
+#define SMART_SCHEDULE_MAX_SLICE 200 /* ms */
+
+Bool SmartScheduleDisable = FALSE;
+long SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
+long SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
+long SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
+long SmartScheduleTime;
+ClientPtr SmartLastClient;
+int SmartLastIndex[SMART_MAX_PRIORITY-SMART_MIN_PRIORITY+1];
+int SmartScheduleClient(int *clientReady, int nready);
+
+#ifdef SMART_DEBUG
+long SmartLastPrint;
+#endif
+
+void Dispatch(void);
+void InitProcVectors(void);
+
+int
+SmartScheduleClient (int *clientReady, int nready)
+{
+ ClientPtr pClient;
+ int i;
+ int client;
+ int bestPrio, best = 0;
+ int bestRobin, robin;
+ long now = SmartScheduleTime;
+ long idle;
+
+ bestPrio = -0x7fffffff;
+ bestRobin = 0;
+ idle = 2 * SmartScheduleSlice;
+ for (i = 0; i < nready; i++)
+ {
+ client = clientReady[i];
+ pClient = clients[client];
+ /* Praise clients which are idle */
+ if ((now - pClient->smart_check_tick) >= idle)
+ {
+ if (pClient->smart_priority < 0)
+ pClient->smart_priority++;
+ }
+ pClient->smart_check_tick = now;
+
+ /* check priority to select best client */
+ robin = (pClient->index - SmartLastIndex[pClient->smart_priority-SMART_MIN_PRIORITY]) & 0xff;
+ if (pClient->smart_priority > bestPrio ||
+ (pClient->smart_priority == bestPrio && robin > bestRobin))
+ {
+ bestPrio = pClient->smart_priority;
+ bestRobin = robin;
+ best = client;
+ }
+#ifdef SMART_DEBUG
+ if ((now - SmartLastPrint) >= 5000)
+ fprintf (stderr, " %2d: %3d", client, pClient->smart_priority);
+#endif
+ }
+#ifdef SMART_DEBUG
+ if ((now - SmartLastPrint) >= 5000)
+ {
+ fprintf (stderr, " use %2d\n", best);
+ SmartLastPrint = now;
+ }
+#endif
+ pClient = clients[best];
+ SmartLastIndex[bestPrio-SMART_MIN_PRIORITY] = pClient->index;
+ /*
+ * Set current client pointer
+ */
+ if (SmartLastClient != pClient)
+ {
+ pClient->smart_start_tick = now;
+ SmartLastClient = pClient;
+ }
+ /*
+ * Adjust slice
+ */
+ if (nready == 1)
+ {
+ /*
+ * If it's been a long time since another client
+ * has run, bump the slice up to get maximal
+ * performance from a single client
+ */
+ if ((now - pClient->smart_start_tick) > 1000 &&
+ SmartScheduleSlice < SmartScheduleMaxSlice)
+ {
+ SmartScheduleSlice += SmartScheduleInterval;
+ }
+ }
+ else
+ {
+ SmartScheduleSlice = SmartScheduleInterval;
+ }
+ return best;
+}
+#endif
+
+#define MAJOROP ((xReq *)client->requestBuffer)->reqType
+
+void
+Dispatch(void)
+{
+ register int *clientReady; /* array of request ready clients */
+ register int result;
+ register ClientPtr client;
+ register int nready;
+ register HWEventQueuePtr* icheck = checkForInput;
+#ifdef SMART_SCHEDULE
+ long start_tick;
+#endif
+
+ unsigned long currentDispatch = 0;
+
+ nextFreeClientID = 1;
+ InitSelections();
+ nClients = 0;
+
+ /*
+ * The agent initialization was successfully
+ * completed. We can now handle our clients.
+ */
+
+ if (serverGeneration > nxagentMaxAllowedResets)
+ {
+ fprintf(stderr, "Session: Session started at '%s'.\n", GetTimeAsString());
+
+ nxagentSessionState = SESSION_UP;
+ }
+
+ #ifdef XKB
+
+ nxagentInitXkbWrapper();
+
+ nxagentTuneXkbWrapper();
+
+ #endif
+
+ #ifdef NXAGENT_ONSTART
+
+ /*
+ * Set NX_WM property (used by NX client to identify
+ * the agent's window) three seconds since the first
+ * client connects.
+ */
+
+ nxagentWMtimeout = GetTimeInMillis() + 3000;
+
+ #endif
+
+ clientReady = (int *) ALLOCATE_LOCAL(sizeof(int) * MaxClients);
+ if (!clientReady)
+ return;
+
+ #ifdef WATCH
+
+ fprintf(stderr, "Dispatch: Watchpoint 12.\n");
+
+/*
+Reply Total Cached Bits In Bits Out Bits/Reply Ratio
+------- ----- ------ ------- -------- ---------- -----
+#3 1 352 bits (0 KB) -> 236 bits (0 KB) -> 352/1 -> 236/1 = 1.492:1
+#14 1 256 bits (0 KB) -> 101 bits (0 KB) -> 256/1 -> 101/1 = 2.535:1
+#16 1 256 bits (0 KB) -> 26 bits (0 KB) -> 256/1 -> 26/1 = 9.846:1
+#20 2 2 12256 bits (1 KB) -> 56 bits (0 KB) -> 6128/1 -> 28/1 = 218.857:1
+#43 1 256 bits (0 KB) -> 45 bits (0 KB) -> 256/1 -> 45/1 = 5.689:1
+#47 2 2 42304 bits (5 KB) -> 49 bits (0 KB) -> 21152/1 -> 24/1 = 863.347:1
+#98 1 256 bits (0 KB) -> 34 bits (0 KB) -> 256/1 -> 34/1 = 7.529:1
+*/
+
+ sleep(30);
+
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "Dispatch: Value of dispatchException is [%x].\n",
+ dispatchException);
+
+ fprintf(stderr, "Dispatch: Value of dispatchExceptionAtReset is [%x].\n",
+ dispatchExceptionAtReset);
+ #endif
+
+ if (!(dispatchException & DE_TERMINATE))
+ dispatchException = 0;
+
+ while (!dispatchException)
+ {
+ if (*icheck[0] != *icheck[1])
+ {
+ ProcessInputEvents();
+ FlushIfCriticalOutputPending();
+ }
+
+ /*
+ * Ensure we remove the splash after the timeout.
+ * Initializing clientReady[0] to -1 will tell
+ * WaitForSomething() to yield control after the
+ * timeout set in clientReady[1].
+ */
+
+ clientReady[0] = 0;
+
+ if (nxagentSplashWindow != None || (nxagentOption(Xdmcp) == 1 && nxagentXdmcpUp == 0))
+ {
+ #ifdef TEST
+ fprintf(stderr, "******Dispatch: Requesting a timeout of [%d] Ms.\n",
+ NXAGENT_WAKEUP);
+ #endif
+
+ clientReady[0] = -1;
+ clientReady[1] = NXAGENT_WAKEUP;
+ }
+
+ #ifdef BLOCKS
+ fprintf(stderr, "[End dispatch]\n");
+ #endif
+
+ nready = WaitForSomething(clientReady);
+
+ #ifdef BLOCKS
+ fprintf(stderr, "[Begin dispatch]\n");
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "******Dispatch: Running with [%d] clients ready.\n",
+ nready);
+ #endif
+
+ #ifdef NXAGENT_ONSTART
+
+ currentDispatch = GetTimeInMillis();
+
+ /*
+ * If the timeout is expired set the
+ * selection informing the NX client
+ * that the agent is ready.
+ */
+
+ if (!nxagentWMPassed && (nxagentWMtimeout < currentDispatch))
+ {
+ nxagentRemoveSplashWindow(NULL);
+ }
+
+ nxagentClients = nClients;
+
+ #endif
+
+#ifdef SMART_SCHEDULE
+ if (nready && !SmartScheduleDisable)
+ {
+ clientReady[0] = SmartScheduleClient (clientReady, nready);
+ nready = 1;
+ }
+#endif
+ /*****************
+ * Handle events in round robin fashion, doing input between
+ * each round
+ *****************/
+
+ while (!dispatchException && (--nready >= 0))
+ {
+ client = clients[clientReady[nready]];
+ if (! client)
+ {
+ /* KillClient can cause this to happen */
+ continue;
+ }
+ /* GrabServer activation can cause this to be true */
+ if (grabState == GrabKickout)
+ {
+ grabState = GrabActive;
+ break;
+ }
+ isItTimeToYield = FALSE;
+
+ requestingClient = client;
+#ifdef SMART_SCHEDULE
+ start_tick = SmartScheduleTime;
+#endif
+ while (!isItTimeToYield)
+ {
+ if (*icheck[0] != *icheck[1])
+ {
+ ProcessInputEvents();
+ FlushIfCriticalOutputPending();
+ }
+#ifdef SMART_SCHEDULE
+ if (!SmartScheduleDisable &&
+ (SmartScheduleTime - start_tick) >= SmartScheduleSlice)
+ {
+ /* Penalize clients which consume ticks */
+ if (client->smart_priority > SMART_MIN_PRIORITY)
+ client->smart_priority--;
+ break;
+ }
+#endif
+ /* now, finally, deal with client requests */
+
+ #ifdef TEST
+ fprintf(stderr, "******Dispatch: Reading request from client [%d].\n",
+ client->index);
+ #endif
+
+ result = ReadRequestFromClient(client);
+ if (result <= 0)
+ {
+ if (result < 0)
+ CloseDownClient(client);
+ break;
+ }
+#ifdef NXAGENT_SERVER
+
+ #ifdef TEST
+
+ else
+ {
+
+ if (MAJOROP > 127)
+ {
+ fprintf(stderr, "******Dispatch: Read [Extension] request OPCODE#%d MINOR#%d "
+ "size [%d] client [%d].\n", MAJOROP, *((char *) client->requestBuffer + 1),
+ client->req_len << 2, client->index);
+ }
+ else
+ {
+ fprintf(stderr, "******Dispatch: Read [%s] request OPCODE#%d size [%d] client [%d].\n",
+ nxagentRequestLiteral[MAJOROP], MAJOROP, client->req_len << 2,
+ client->index);
+ }
+ }
+
+ #endif
+#endif
+
+ client->sequence++;
+#ifdef DEBUG
+ if (client->requestLogIndex == MAX_REQUEST_LOG)
+ client->requestLogIndex = 0;
+ client->requestLog[client->requestLogIndex] = MAJOROP;
+ client->requestLogIndex++;
+#endif
+ if (result > (maxBigRequestSize << 2))
+ result = BadLength;
+ else
+#ifdef NXAGENT_SERVER
+ {
+ result = (* client->requestVector[MAJOROP])(client);
+
+ #ifdef TEST
+
+ if (MAJOROP > 127)
+ {
+ fprintf(stderr, "******Dispatch: Handled [Extension] request OPCODE#%d MINOR#%d "
+ "size [%d] client [%d] result [%d].\n", MAJOROP,
+ *((char *) client->requestBuffer + 1), client->req_len << 2,
+ client->index, result);
+ }
+ else
+ {
+ fprintf(stderr, "******Dispatch: Handled [%s] request OPCODE#%d size [%d] client [%d] "
+ "result [%d].\n", nxagentRequestLiteral[MAJOROP], MAJOROP,
+ client->req_len << 2, client->index, result);
+ }
+
+ #endif
+
+ /*
+ * Can set isItTimeToYield to force
+ * the dispatcher to pay attention
+ * to another client.
+ */
+
+ nxagentDispatchHandler(client, client->req_len << 2, 0);
+ }
+#else
+ result = (* client->requestVector[MAJOROP])(client);
+#endif
+
+ if (result != Success)
+ {
+ if (client->noClientException != Success)
+ CloseDownClient(client);
+ else
+ SendErrorToClient(client, MAJOROP,
+ MinorOpcodeOfRequest(client),
+ client->errorValue, result);
+ break;
+ }
+#ifdef DAMAGEEXT
+ FlushIfCriticalOutputPending ();
+#endif
+ }
+ FlushAllOutput();
+#ifdef SMART_SCHEDULE
+ client = clients[clientReady[nready]];
+ if (client)
+ client->smart_stop_tick = SmartScheduleTime;
+#endif
+ requestingClient = NULL;
+ }
+ dispatchException &= ~DE_PRIORITYCHANGE;
+ }
+#if defined(DDXBEFORERESET)
+ ddxBeforeReset ();
+#endif
+ if ((dispatchException & DE_RESET) &&
+ (serverGeneration > nxagentMaxAllowedResets))
+ {
+ dispatchException &= ~DE_RESET;
+ dispatchException |= DE_TERMINATE;
+
+ fprintf(stderr, "Info: Reached threshold of maximum allowed resets.\n");
+ }
+
+ nxagentResetAtomMap();
+
+ if (serverGeneration > nxagentMaxAllowedResets)
+ {
+ /*
+ * The session is terminating. Force an I/O
+ * error on the display and wait until the
+ * NX transport is gone.
+ */
+
+ fprintf(stderr, "Session: Terminating session at '%s'.\n", GetTimeAsString());
+
+ nxagentWaitDisplay();
+
+ fprintf(stderr, "Session: Session terminated at '%s'.\n", GetTimeAsString());
+ }
+
+ if (nxagentOption(Shadow) == 1)
+ {
+ NXShadowDestroy();
+ }
+
+ KillAllClients();
+ DEALLOCATE_LOCAL(clientReady);
+ dispatchException &= ~DE_RESET;
+}
+
+#undef MAJOROP
+
+int
+ProcBadRequest(ClientPtr client)
+{
+ return (BadRequest);
+}
+
+int
+ProcCreateWindow(ClientPtr client)
+{
+ register WindowPtr pParent, pWin;
+ REQUEST(xCreateWindowReq);
+ int result;
+ int len;
+
+ REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
+
+ LEGAL_NEW_RESOURCE(stuff->wid, client);
+ if (!(pParent = (WindowPtr)SecurityLookupWindow(stuff->parent, client,
+ SecurityWriteAccess)))
+ return BadWindow;
+ len = client->req_len - (sizeof(xCreateWindowReq) >> 2);
+ if (Ones(stuff->mask) != len)
+ return BadLength;
+ if (!stuff->width || !stuff->height)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ pWin = CreateWindow(stuff->wid, pParent, stuff->x,
+ stuff->y, stuff->width, stuff->height,
+ stuff->borderWidth, stuff->class,
+ stuff->mask, (XID *) &stuff[1],
+ (int)stuff->depth,
+ client, stuff->visual, &result);
+ if (pWin)
+ {
+ Mask mask = pWin->eventMask;
+
+ pWin->eventMask = 0; /* subterfuge in case AddResource fails */
+ if (!AddResource(stuff->wid, RT_WINDOW, (pointer)pWin))
+ return BadAlloc;
+ pWin->eventMask = mask;
+ }
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+int
+ProcChangeWindowAttributes(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xChangeWindowAttributesReq);
+ register int result;
+ int len;
+
+ REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ len = client->req_len - (sizeof(xChangeWindowAttributesReq) >> 2);
+ if (len != Ones(stuff->valueMask))
+ return BadLength;
+ result = ChangeWindowAttributes(pWin,
+ stuff->valueMask,
+ (XID *) &stuff[1],
+ client);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+int
+ProcGetWindowAttributes(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+ xGetWindowAttributesReply wa;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ GetWindowAttributes(pWin, client, &wa);
+ WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa);
+ return(client->noClientException);
+}
+
+int
+ProcDestroyWindow(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityDestroyAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (pWin->parent)
+ FreeResource(stuff->id, RT_NONE);
+ return(client->noClientException);
+}
+
+int
+ProcDestroySubwindows(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityDestroyAccess);
+ if (!pWin)
+ return(BadWindow);
+ DestroySubwindows(pWin, client);
+ return(client->noClientException);
+}
+
+int
+ProcChangeSaveSet(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xChangeSaveSetReq);
+ register int result;
+
+ REQUEST_SIZE_MATCH(xChangeSaveSetReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id)))
+ return BadMatch;
+ if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete))
+ {
+ result = AlterSaveSetForClient(client, pWin, stuff->mode, FALSE, TRUE);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+ }
+ else
+ {
+ client->errorValue = stuff->mode;
+ return( BadValue );
+ }
+}
+
+int
+ProcReparentWindow(register ClientPtr client)
+{
+ register WindowPtr pWin, pParent;
+ REQUEST(xReparentWindowReq);
+ register int result;
+
+ REQUEST_SIZE_MATCH(xReparentWindowReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+
+ if (!nxagentWMPassed)
+ {
+ nxagentRemoveSplashWindow(pWin);
+ }
+
+ pParent = (WindowPtr)SecurityLookupWindow(stuff->parent, client,
+ SecurityWriteAccess);
+ if (!pParent)
+ return(BadWindow);
+ if (SAME_SCREENS(pWin->drawable, pParent->drawable))
+ {
+ if ((pWin->backgroundState == ParentRelative) &&
+ (pParent->drawable.depth != pWin->drawable.depth))
+ return BadMatch;
+ if ((pWin->drawable.class != InputOnly) &&
+ (pParent->drawable.class == InputOnly))
+ return BadMatch;
+ result = ReparentWindow(pWin, pParent,
+ (short)stuff->x, (short)stuff->y, client);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+ }
+ else
+ return (BadMatch);
+}
+
+int
+ProcMapWindow(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ MapWindow(pWin, client);
+ /* update cache to say it is mapped */
+ return(client->noClientException);
+}
+
+int
+ProcMapSubwindows(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ MapSubwindows(pWin, client);
+ /* update cache to say it is mapped */
+ return(client->noClientException);
+}
+
+int
+ProcUnmapWindow(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ UnmapWindow(pWin, FALSE);
+ /* update cache to say it is mapped */
+
+ return(client->noClientException);
+}
+
+int
+ProcUnmapSubwindows(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ UnmapSubwindows(pWin);
+ return(client->noClientException);
+}
+
+int
+ProcConfigureWindow(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xConfigureWindowReq);
+ register int result;
+ int len;
+
+ REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
+ pWin = (WindowPtr)SecurityLookupWindow( stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ len = client->req_len - (sizeof(xConfigureWindowReq) >> 2);
+ if (Ones((Mask)stuff->mask) != len)
+ return BadLength;
+ result = ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1],
+ client);
+
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+int
+ProcCirculateWindow(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xCirculateWindowReq);
+
+ REQUEST_SIZE_MATCH(xCirculateWindowReq);
+ if ((stuff->direction != RaiseLowest) &&
+ (stuff->direction != LowerHighest))
+ {
+ client->errorValue = stuff->direction;
+ return BadValue;
+ }
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ CirculateWindow(pWin, (int)stuff->direction, client);
+ return(client->noClientException);
+}
+
+int
+GetGeometry(register ClientPtr client, xGetGeometryReply *rep)
+{
+ register DrawablePtr pDraw;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->id, client, SecurityReadAccess);
+ rep->type = X_Reply;
+ rep->length = 0;
+ rep->sequenceNumber = client->sequence;
+ rep->root = WindowTable[pDraw->pScreen->myNum]->drawable.id;
+ rep->depth = pDraw->depth;
+ rep->width = pDraw->width;
+ rep->height = pDraw->height;
+
+ /* XXX - Because the pixmap-implementation of the multibuffer extension
+ * may have the buffer-id's drawable resource value be a pointer
+ * to the buffer's window instead of the buffer itself
+ * (this happens if the buffer is the displayed buffer),
+ * we also have to check that the id matches before we can
+ * truly say that it is a DRAWABLE_WINDOW.
+ */
+
+ if ((pDraw->type == UNDRAWABLE_WINDOW) ||
+ ((pDraw->type == DRAWABLE_WINDOW) && (stuff->id == pDraw->id)))
+ {
+ register WindowPtr pWin = (WindowPtr)pDraw;
+ rep->x = pWin->origin.x - wBorderWidth (pWin);
+ rep->y = pWin->origin.y - wBorderWidth (pWin);
+ rep->borderWidth = pWin->borderWidth;
+ }
+ else /* DRAWABLE_PIXMAP or DRAWABLE_BUFFER */
+ {
+ rep->x = rep->y = rep->borderWidth = 0;
+ }
+
+ return Success;
+}
+
+
+int
+ProcGetGeometry(register ClientPtr client)
+{
+ xGetGeometryReply rep;
+ int status;
+
+ if ((status = GetGeometry(client, &rep)) != Success)
+ return status;
+
+ WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
+ return(client->noClientException);
+}
+
+
+int
+ProcQueryTree(register ClientPtr client)
+{
+ xQueryTreeReply reply;
+ int numChildren = 0;
+ register WindowPtr pChild, pWin, pHead;
+ Window *childIDs = (Window *)NULL;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ reply.type = X_Reply;
+ reply.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
+ reply.sequenceNumber = client->sequence;
+ if (pWin->parent)
+ reply.parent = pWin->parent->drawable.id;
+ else
+ reply.parent = (Window)None;
+ pHead = RealChildHead(pWin);
+ for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+ {
+ if (!IsViewportFrame(pChild))
+ {
+ numChildren++;
+ }
+ }
+ if (numChildren)
+ {
+ int curChild = 0;
+
+ childIDs = (Window *) ALLOCATE_LOCAL(numChildren * sizeof(Window));
+ if (!childIDs)
+ return BadAlloc;
+ for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+ {
+ if (!IsViewportFrame(pChild))
+ {
+ childIDs[curChild++] = pChild->drawable.id;
+ }
+ }
+ }
+
+ reply.nChildren = numChildren;
+ reply.length = (numChildren * sizeof(Window)) >> 2;
+
+ WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply);
+ if (numChildren)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, numChildren * sizeof(Window), childIDs);
+ DEALLOCATE_LOCAL(childIDs);
+ }
+
+ return(client->noClientException);
+}
+
+int
+ProcInternAtom(register ClientPtr client)
+{
+ Atom atom;
+ char *tchar;
+ REQUEST(xInternAtomReq);
+
+ REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes);
+ if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse))
+ {
+ client->errorValue = stuff->onlyIfExists;
+ return(BadValue);
+ }
+ tchar = (char *) &stuff[1];
+ atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists);
+ if (atom != BAD_RESOURCE)
+ {
+ xInternAtomReply reply;
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ reply.atom = atom;
+ WriteReplyToClient(client, sizeof(xInternAtomReply), &reply);
+ return(client->noClientException);
+ }
+ else
+ return (BadAlloc);
+}
+
+int
+ProcGetAtomName(register ClientPtr client)
+{
+ char *str;
+ xGetAtomNameReply reply;
+ int len;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ if ( (str = NameForAtom(stuff->id)) )
+ {
+ len = strlen(str);
+ reply.type = X_Reply;
+ reply.length = (len + 3) >> 2;
+ reply.sequenceNumber = client->sequence;
+ reply.nameLength = len;
+ WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply);
+ (void)WriteToClient(client, len, str);
+ return(client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadAtom);
+ }
+}
+
+#ifdef K5AUTH
+extern int k5_bad();
+#endif
+
+int
+ProcSetSelectionOwner(register ClientPtr client)
+{
+ WindowPtr pWin;
+ TimeStamp time;
+ REQUEST(xSetSelectionOwnerReq);
+
+ REQUEST_SIZE_MATCH(xSetSelectionOwnerReq);
+ UpdateCurrentTime();
+ time = ClientTimeToServerTime(stuff->time);
+
+ /* If the client's time stamp is in the future relative to the server's
+ time stamp, do not set the selection, just return success. */
+ if (CompareTimeStamps(time, currentTime) == LATER)
+ return Success;
+ if (stuff->window != None)
+ {
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ }
+ else
+ pWin = (WindowPtr)None;
+ if (ValidAtom(stuff->selection))
+ {
+ int i = 0;
+
+ /*
+ * First, see if the selection is already set...
+ */
+ while ((i < NumCurrentSelections) &&
+ CurrentSelections[i].selection != stuff->selection)
+ i++;
+ if (i < NumCurrentSelections)
+ {
+ xEvent event;
+
+ /* If the timestamp in client's request is in the past relative
+ to the time stamp indicating the last time the owner of the
+ selection was set, do not set the selection, just return
+ success. */
+ if (CompareTimeStamps(time, CurrentSelections[i].lastTimeChanged)
+ == EARLIER)
+ return Success;
+ if (CurrentSelections[i].client &&
+ (!pWin || (CurrentSelections[i].client != client)))
+ {
+ event.u.u.type = SelectionClear;
+ event.u.selectionClear.time = time.milliseconds;
+ event.u.selectionClear.window = CurrentSelections[i].window;
+ event.u.selectionClear.atom = CurrentSelections[i].selection;
+ (void) TryClientEvents (CurrentSelections[i].client, &event, 1,
+ NoEventMask, NoEventMask /* CantBeFiltered */,
+ NullGrab);
+ }
+ }
+ else
+ {
+ /*
+ * It doesn't exist, so add it...
+ */
+ Selection *newsels;
+
+ if (i == 0)
+ newsels = (Selection *)xalloc(sizeof(Selection));
+ else
+ newsels = (Selection *)xrealloc(CurrentSelections,
+ (NumCurrentSelections + 1) * sizeof(Selection));
+ if (!newsels)
+ return BadAlloc;
+ NumCurrentSelections++;
+ CurrentSelections = newsels;
+ CurrentSelections[i].selection = stuff->selection;
+ }
+ CurrentSelections[i].lastTimeChanged = time;
+ CurrentSelections[i].window = stuff->window;
+ CurrentSelections[i].pWin = pWin;
+ CurrentSelections[i].client = (pWin ? client : NullClient);
+ if (SelectionCallback)
+ {
+ SelectionInfoRec info;
+
+ info.selection = &CurrentSelections[i];
+ info.kind= SelectionSetOwner;
+ CallCallbacks(&SelectionCallback, &info);
+ }
+
+#ifdef NXAGENT_CLIPBOARD
+ if ((CurrentSelections[i].pWin != NULL) &&
+ (nxagentOption(Clipboard) != ClipboardNone) &&
+ ((CurrentSelections[i].selection == XA_PRIMARY) ||
+ (CurrentSelections[i].selection == MakeAtom("CLIPBOARD", 9, 0))))
+ {
+ nxagentSetSelectionOwner(&CurrentSelections[i]);
+ }
+#endif
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->selection;
+ return (BadAtom);
+ }
+}
+
+int
+ProcGetSelectionOwner(register ClientPtr client)
+{
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ if (ValidAtom(stuff->id))
+ {
+ int i;
+ xGetSelectionOwnerReply reply;
+
+ i = 0;
+ while ((i < NumCurrentSelections) &&
+ CurrentSelections[i].selection != stuff->id) i++;
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ if (i < NumCurrentSelections)
+ reply.owner = CurrentSelections[i].window;
+ else
+ reply.owner = None;
+ WriteReplyToClient(client, sizeof(xGetSelectionOwnerReply), &reply);
+ return(client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadAtom);
+ }
+}
+
+int
+ProcConvertSelection(register ClientPtr client)
+{
+ Bool paramsOkay;
+ xEvent event;
+ WindowPtr pWin;
+ REQUEST(xConvertSelectionReq);
+
+ REQUEST_SIZE_MATCH(xConvertSelectionReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->requestor, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+
+#ifdef NXAGENT_CLIPBOARD
+ if (((stuff->selection == XA_PRIMARY) ||
+ (stuff->selection == MakeAtom("CLIPBOARD", 9, 0))) &&
+ nxagentOption(Clipboard) != ClipboardNone)
+ {
+ int i = 0;
+
+ while ((i < NumCurrentSelections) &&
+ CurrentSelections[i].selection != stuff->selection) i++;
+
+ if ((i < NumCurrentSelections) && (CurrentSelections[i].window != None))
+ {
+ if (nxagentConvertSelection(client, pWin, stuff->selection, stuff->requestor,
+ stuff->property, stuff->target, stuff->time))
+ {
+ return (client->noClientException);
+ }
+ }
+ }
+#endif
+
+ paramsOkay = (ValidAtom(stuff->selection) && ValidAtom(stuff->target));
+ if (stuff->property != None)
+ paramsOkay &= ValidAtom(stuff->property);
+ if (paramsOkay)
+ {
+ int i;
+
+ i = 0;
+ while ((i < NumCurrentSelections) &&
+ CurrentSelections[i].selection != stuff->selection) i++;
+ if ((i < NumCurrentSelections) &&
+ (CurrentSelections[i].window != None) && (CurrentSelections[i].client != NullClient)
+#ifdef XCSECURITY
+ && (!client->CheckAccess ||
+ (* client->CheckAccess)(client, CurrentSelections[i].window,
+ RT_WINDOW, SecurityReadAccess,
+ CurrentSelections[i].pWin))
+#endif
+ )
+ {
+ event.u.u.type = SelectionRequest;
+ event.u.selectionRequest.time = stuff->time;
+ event.u.selectionRequest.owner =
+ CurrentSelections[i].window;
+ event.u.selectionRequest.requestor = stuff->requestor;
+ event.u.selectionRequest.selection = stuff->selection;
+ event.u.selectionRequest.target = stuff->target;
+ event.u.selectionRequest.property = stuff->property;
+ if (TryClientEvents(
+ CurrentSelections[i].client, &event, 1, NoEventMask,
+ NoEventMask /* CantBeFiltered */, NullGrab))
+ return (client->noClientException);
+ }
+ event.u.u.type = SelectionNotify;
+ event.u.selectionNotify.time = stuff->time;
+ event.u.selectionNotify.requestor = stuff->requestor;
+ event.u.selectionNotify.selection = stuff->selection;
+ event.u.selectionNotify.target = stuff->target;
+ event.u.selectionNotify.property = None;
+ (void) TryClientEvents(client, &event, 1, NoEventMask,
+ NoEventMask /* CantBeFiltered */, NullGrab);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->property;
+ return (BadAtom);
+ }
+}
+
+int
+ProcGrabServer(register ClientPtr client)
+{
+ REQUEST_SIZE_MATCH(xReq);
+ if (grabState != GrabNone && client != grabClient)
+ {
+ ResetCurrentRequest(client);
+ client->sequence--;
+ BITSET(grabWaiters, client->index);
+ IgnoreClient(client);
+ return(client->noClientException);
+ }
+ OnlyListenToOneClient(client);
+ grabState = GrabKickout;
+ grabClient = client;
+
+ if (ServerGrabCallback)
+ {
+ ServerGrabInfoRec grabinfo;
+ grabinfo.client = client;
+ grabinfo.grabstate = SERVER_GRABBED;
+ CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
+ }
+
+ return(client->noClientException);
+}
+
+static void
+UngrabServer(ClientPtr client)
+{
+ int i;
+
+ grabState = GrabNone;
+ ListenToAllClients();
+ for (i = mskcnt; --i >= 0 && !grabWaiters[i]; )
+ ;
+ if (i >= 0)
+ {
+ i <<= 5;
+ while (!GETBIT(grabWaiters, i))
+ i++;
+ BITCLEAR(grabWaiters, i);
+ AttendClient(clients[i]);
+ }
+
+ if (ServerGrabCallback)
+ {
+ ServerGrabInfoRec grabinfo;
+ grabinfo.client = client;
+ grabinfo.grabstate = SERVER_UNGRABBED;
+ CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
+ }
+}
+
+int
+ProcUngrabServer(register ClientPtr client)
+{
+ REQUEST_SIZE_MATCH(xReq);
+ UngrabServer(client);
+ return(client->noClientException);
+}
+
+int
+ProcTranslateCoords(register ClientPtr client)
+{
+ REQUEST(xTranslateCoordsReq);
+
+ register WindowPtr pWin, pDst;
+ xTranslateCoordsReply rep;
+
+ REQUEST_SIZE_MATCH(xTranslateCoordsReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->srcWid, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ pDst = (WindowPtr)SecurityLookupWindow(stuff->dstWid, client,
+ SecurityReadAccess);
+ if (!pDst)
+ return(BadWindow);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ if (!SAME_SCREENS(pWin->drawable, pDst->drawable))
+ {
+ rep.sameScreen = xFalse;
+ rep.child = None;
+ rep.dstX = rep.dstY = 0;
+ }
+ else
+ {
+ INT16 x, y;
+ rep.sameScreen = xTrue;
+ rep.child = None;
+ /* computing absolute coordinates -- adjust to destination later */
+ x = pWin->drawable.x + stuff->srcX;
+ y = pWin->drawable.y + stuff->srcY;
+ pWin = pDst->firstChild;
+ while (pWin)
+ {
+#ifdef SHAPE
+ BoxRec box;
+#endif
+ 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))
+#ifdef SHAPE
+ /* When a window is shaped, a further check
+ * is made to see if the point is inside
+ * borderSize
+ */
+ && (!wBoundingShape(pWin) ||
+ POINT_IN_REGION(pWin->drawable.pScreen,
+ &pWin->borderSize, x, y, &box))
+
+ && (!wInputShape(pWin) ||
+ POINT_IN_REGION(pWin->drawable.pScreen,
+ wInputShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box))
+#endif
+ )
+ {
+ rep.child = pWin->drawable.id;
+ pWin = (WindowPtr) NULL;
+ }
+ else
+ pWin = pWin->nextSib;
+ }
+ /* adjust to destination coordinates */
+ rep.dstX = x - pDst->drawable.x;
+ rep.dstY = y - pDst->drawable.y;
+ }
+ WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep);
+ return(client->noClientException);
+}
+
+int
+ProcOpenFont(register ClientPtr client)
+{
+ int err;
+ char fontReq[256];
+ REQUEST(xOpenFontReq);
+
+ REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes);
+ client->errorValue = stuff->fid;
+ LEGAL_NEW_RESOURCE(stuff->fid, client);
+
+ memcpy(fontReq,(char *)&stuff[1],(stuff->nbytes<256)?stuff->nbytes:255);
+ fontReq[stuff->nbytes]=0;
+ if (strchr(fontReq,'*') || strchr(fontReq,'?'))
+ {
+ extern int nxOpenFont(ClientPtr, XID, Mask, unsigned, char*);
+#ifdef NXAGENT_FONTMATCH_DEBUG
+ fprintf(stderr, "Dispatch: ProcOpenFont try to find a common font with font pattern=%s\n",fontReq);
+#endif
+ nxagentListRemoteFonts(fontReq, nxagentMaxFontNames);
+ err = nxOpenFont(client, stuff->fid, (Mask) 0,
+ stuff->nbytes, (char *)&stuff[1]);
+ }
+ else
+ err = OpenFont(client, stuff->fid, (Mask) 0,
+ stuff->nbytes, (char *)&stuff[1]);
+ if (err == Success)
+ {
+ return(client->noClientException);
+ }
+ else
+ return err;
+}
+
+int
+ProcCloseFont(register ClientPtr client)
+{
+ FontPtr pFont;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
+ SecurityDestroyAccess);
+ if (pFont != (FontPtr)NULL)
+ {
+ #ifdef NXAGENT_SERVER
+
+ /*
+ * When a client closes a font the resource
+ * should not be lost if the reference counter
+ * is not 0, otherwise the server will not be
+ * able to find this font looping through the
+ * resources.
+ */
+
+ if (pFont -> refcnt > 0)
+ {
+ if (nxagentFindClientResource(serverClient -> index, RT_NX_FONT, pFont) == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "ProcCloseFont: Switching resource for font at [%p].\n",
+ (void *) pFont);
+ #endif
+
+ nxagentFontPriv(pFont) -> mirrorID = FakeClientID(serverClient -> index);
+
+ AddResource(nxagentFontPriv(pFont) -> mirrorID, RT_NX_FONT, pFont);
+
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "ProcCloseFont: Found duplicated font at [%p], "
+ "resource switching skipped.\n", (void *) pFont);
+ }
+ #endif
+ }
+
+ #endif
+
+ FreeResource(stuff->id, RT_NONE);
+ return(client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadFont);
+ }
+}
+
+int
+ProcQueryFont(register ClientPtr client)
+{
+ xQueryFontReply *reply;
+ FontPtr pFont;
+ register GC *pGC;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ client->errorValue = stuff->id; /* EITHER font or gc */
+
+ pFont = NULL;
+ pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
+ SecurityReadAccess);
+ if (!pFont)
+ {
+ /* can't use VERIFY_GC because it might return BadGC */
+ pGC = (GC *) SecurityLookupIDByType(client, stuff->id, RT_GC,
+ SecurityReadAccess);
+ if (!pGC)
+ {
+ client->errorValue = stuff->id;
+ return(BadFont); /* procotol spec says only error is BadFont */
+ }
+ pFont = pGC->font;
+ }
+
+/* test
+{
+ Atom name_atom, value_atom;
+ int nprops;
+ FontPropPtr props;
+ int i;
+ char *name;
+
+ name_atom = MakeAtom("FONT", 4, True);
+ value_atom = 0L;
+
+ nprops = pFont->info.nprops;
+ props = pFont->info.props;
+
+ for (i = 0; i < nprops; i++)
+ if (props[i].name == name_atom) {
+ value_atom = props[i].value;
+ break;
+ }
+
+ if (!value_atom) return (BadFont);
+
+ name = (char *)NameForAtom(value_atom);
+ fprintf(stderr, "QueryFont: font name [%s]\n",name);
+}
+ end test */
+
+ {
+ xCharInfo *pmax = FONTINKMAX(pFont);
+ xCharInfo *pmin = FONTINKMIN(pFont);
+ int nprotoxcistructs;
+ int rlength;
+
+ nprotoxcistructs = (
+ pmax->rightSideBearing == pmin->rightSideBearing &&
+ pmax->leftSideBearing == pmin->leftSideBearing &&
+ pmax->descent == pmin->descent &&
+ pmax->ascent == pmin->ascent &&
+ pmax->characterWidth == pmin->characterWidth) ?
+ 0 : N2dChars(pFont);
+
+ rlength = sizeof(xQueryFontReply) +
+ FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp) +
+ nprotoxcistructs * sizeof(xCharInfo);
+ reply = NULL;
+ reply = (xQueryFontReply *)ALLOCATE_LOCAL(rlength);
+ if(!reply)
+ {
+ return(BadAlloc);
+ }
+
+ reply->type = X_Reply;
+ reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+ reply->sequenceNumber = client->sequence;
+ QueryFont( pFont, reply, nprotoxcistructs);
+
+ WriteReplyToClient(client, rlength, reply);
+ DEALLOCATE_LOCAL(reply);
+ return(client->noClientException);
+ }
+}
+
+int
+ProcQueryTextExtents(register ClientPtr client)
+{
+ REQUEST(xQueryTextExtentsReq);
+ xQueryTextExtentsReply reply;
+ FontPtr pFont;
+ GC *pGC;
+ ExtentInfoRec info;
+ unsigned long length;
+
+ REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq);
+
+ pFont = (FontPtr)SecurityLookupIDByType(client, stuff->fid, RT_FONT,
+ SecurityReadAccess);
+ if (!pFont)
+ {
+ pGC = (GC *)SecurityLookupIDByType(client, stuff->fid, RT_GC,
+ SecurityReadAccess);
+ if (!pGC)
+ {
+ client->errorValue = stuff->fid;
+ return(BadFont);
+ }
+ pFont = pGC->font;
+ }
+ length = client->req_len - (sizeof(xQueryTextExtentsReq) >> 2);
+ length = length << 1;
+ if (stuff->oddLength)
+ {
+ if (length == 0)
+ return(BadLength);
+ length--;
+ }
+ if (!QueryTextExtents(pFont, length, (unsigned char *)&stuff[1], &info))
+ return(BadAlloc);
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ reply.drawDirection = info.drawDirection;
+ reply.fontAscent = info.fontAscent;
+ reply.fontDescent = info.fontDescent;
+ reply.overallAscent = info.overallAscent;
+ reply.overallDescent = info.overallDescent;
+ reply.overallWidth = info.overallWidth;
+ reply.overallLeft = info.overallLeft;
+ reply.overallRight = info.overallRight;
+ WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply);
+ return(client->noClientException);
+}
+
+int
+ProcListFonts(register ClientPtr client)
+{
+ char tmp[256];
+
+ REQUEST(xListFontsReq);
+
+ REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes);
+ memcpy(tmp,(unsigned char *) &stuff[1],(stuff->nbytes<256)?stuff->nbytes:255);
+ tmp[stuff->nbytes]=0;
+
+#ifdef NXAGENT_FONTMATCH_DEBUG
+ fprintf(stderr, "Dispatch: ListFont request with pattern %s max_names=%d\n",tmp,stuff->maxNames);
+#endif
+ nxagentListRemoteFonts(tmp, stuff -> maxNames < nxagentMaxFontNames ? nxagentMaxFontNames : stuff->maxNames);
+ return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes,
+ stuff->maxNames);
+}
+
+int
+ProcListFontsWithInfo(register ClientPtr client)
+{
+ char tmp[256];
+ REQUEST(xListFontsWithInfoReq);
+
+ REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes);
+
+ memcpy(tmp,(unsigned char *) &stuff[1],(stuff->nbytes<256)?stuff->nbytes:255);
+ tmp[stuff->nbytes]=0;
+#ifdef NXAGENT_FONTMATCH_DEBUG
+ fprintf(stderr, "Dispatch: ListFont with info request with pattern %s max_names=%d\n",tmp,stuff->maxNames);
+#endif
+ nxagentListRemoteFonts(tmp, stuff -> maxNames < nxagentMaxFontNames ? nxagentMaxFontNames :stuff->maxNames);
+
+ return StartListFontsWithInfo(client, stuff->nbytes,
+ (unsigned char *) &stuff[1], stuff->maxNames);
+}
+
+/**
+ *
+ * \param value must conform to DeleteType
+ */
+int
+dixDestroyPixmap(pointer value, XID pid)
+{
+ PixmapPtr pPixmap = (PixmapPtr)value;
+ return (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
+}
+
+int
+ProcCreatePixmap(register ClientPtr client)
+{
+ PixmapPtr pMap;
+ register DrawablePtr pDraw;
+ REQUEST(xCreatePixmapReq);
+ DepthPtr pDepth;
+ register int i;
+
+ REQUEST_SIZE_MATCH(xCreatePixmapReq);
+ client->errorValue = stuff->pid;
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+ SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->drawable, client,
+ SecurityReadAccess);
+ if (!stuff->width || !stuff->height)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ if (stuff->width > 32767 || stuff->height > 32767)
+ {
+ /* It is allowed to try and allocate a pixmap which is larger than
+ * 32767 in either dimension. However, all of the framebuffer code
+ * is buggy and does not reliably draw to such big pixmaps, basically
+ * because the Region data structure operates with signed shorts
+ * for the rectangles in it.
+ *
+ * Furthermore, several places in the X server computes the
+ * size in bytes of the pixmap and tries to store it in an
+ * integer. This integer can overflow and cause the allocated size
+ * to be much smaller.
+ *
+ * So, such big pixmaps are rejected here with a BadAlloc
+ */
+ 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:
+ pMap = (PixmapPtr)(*pDraw->pScreen->CreatePixmap)
+ (pDraw->pScreen, stuff->width,
+ stuff->height, stuff->depth);
+ if (pMap)
+ {
+ pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pMap->drawable.id = stuff->pid;
+ if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
+ return(client->noClientException);
+ }
+ return (BadAlloc);
+}
+
+int
+ProcFreePixmap(register ClientPtr client)
+{
+ PixmapPtr pMap;
+
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pMap = (PixmapPtr)SecurityLookupIDByType(client, stuff->id, RT_PIXMAP,
+ SecurityDestroyAccess);
+ if (pMap)
+ {
+ #ifdef NXAGENT_SERVER
+
+ /*
+ * When a client releases a pixmap the resource
+ * should not be lost if the reference counter
+ * is not 0, otherwise the server will not be
+ * able to find this pixmap looping through the
+ * resources.
+ */
+
+ if (pMap -> refcnt > 0)
+ {
+ if (nxagentFindClientResource(serverClient -> index, RT_NX_PIXMAP, pMap) == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "ProcFreePixmap: Switching resource for pixmap at [%p].\n",
+ (void *) pMap);
+ #endif
+
+ nxagentPixmapPriv(pMap) -> mid = FakeClientID(serverClient -> index);
+
+ AddResource(nxagentPixmapPriv(pMap) -> mid, RT_NX_PIXMAP, pMap);
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "ProcFreePixmap: Found duplicated pixmap at [%p], "
+ "resource switching skipped.\n", (void *) pMap);
+ }
+ #endif
+ }
+
+ #endif
+
+ FreeResource(stuff->id, RT_NONE);
+ return(client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadPixmap);
+ }
+}
+
+int
+ProcCreateGC(register ClientPtr client)
+{
+ int error;
+ GC *pGC;
+ register DrawablePtr pDraw;
+ unsigned len;
+ REQUEST(xCreateGCReq);
+
+ REQUEST_AT_LEAST_SIZE(xCreateGCReq);
+ client->errorValue = stuff->gc;
+ LEGAL_NEW_RESOURCE(stuff->gc, client);
+ SECURITY_VERIFY_DRAWABLE (pDraw, stuff->drawable, client,
+ SecurityReadAccess);
+ len = client->req_len - (sizeof(xCreateGCReq) >> 2);
+ if (len != Ones(stuff->mask))
+ return BadLength;
+ pGC = (GC *)CreateGC(pDraw, stuff->mask,
+ (XID *) &stuff[1], &error);
+ if (error != Success)
+ return error;
+ if (!AddResource(stuff->gc, RT_GC, (pointer)pGC))
+ return (BadAlloc);
+ return(client->noClientException);
+}
+
+int
+ProcChangeGC(register ClientPtr client)
+{
+ GC *pGC;
+ REQUEST(xChangeGCReq);
+ int result;
+ unsigned len;
+
+ REQUEST_AT_LEAST_SIZE(xChangeGCReq);
+ SECURITY_VERIFY_GC(pGC, stuff->gc, client, SecurityWriteAccess);
+ len = client->req_len - (sizeof(xChangeGCReq) >> 2);
+ if (len != Ones(stuff->mask))
+ return BadLength;
+
+ result = dixChangeGC(client, pGC, stuff->mask, (CARD32 *) &stuff[1], 0);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return(result);
+ }
+}
+
+int
+ProcCopyGC(register ClientPtr client)
+{
+ register GC *dstGC;
+ register GC *pGC;
+ int result;
+ REQUEST(xCopyGCReq);
+
+ REQUEST_SIZE_MATCH(xCopyGCReq);
+ SECURITY_VERIFY_GC( pGC, stuff->srcGC, client, SecurityReadAccess);
+ SECURITY_VERIFY_GC( dstGC, stuff->dstGC, client, SecurityWriteAccess);
+ if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth))
+ return (BadMatch);
+ result = CopyGC(pGC, dstGC, stuff->mask);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return(result);
+ }
+}
+
+int
+ProcSetDashes(register ClientPtr client)
+{
+ register GC *pGC;
+ int result;
+ REQUEST(xSetDashesReq);
+
+ REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
+ if (stuff->nDashes == 0)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+
+ SECURITY_VERIFY_GC(pGC,stuff->gc, client, SecurityWriteAccess);
+
+ result = SetDashes(pGC, stuff->dashOffset, stuff->nDashes,
+ (unsigned char *)&stuff[1]);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return(result);
+ }
+}
+
+int
+ProcSetClipRectangles(register ClientPtr client)
+{
+ int nr;
+ int result;
+ register GC *pGC;
+ REQUEST(xSetClipRectanglesReq);
+
+ REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
+ if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
+ (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded))
+ {
+ client->errorValue = stuff->ordering;
+ return BadValue;
+ }
+ SECURITY_VERIFY_GC(pGC,stuff->gc, client, SecurityWriteAccess);
+
+ nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq);
+ if (nr & 4)
+ return(BadLength);
+ nr >>= 3;
+ result = SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin,
+ nr, (xRectangle *)&stuff[1], (int)stuff->ordering);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+int
+ProcFreeGC(register ClientPtr client)
+{
+ register GC *pGC;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ SECURITY_VERIFY_GC(pGC, stuff->id, client, SecurityDestroyAccess);
+ FreeResource(stuff->id, RT_NONE);
+ return(client->noClientException);
+}
+
+int
+ProcClearToBackground(register ClientPtr client)
+{
+ REQUEST(xClearAreaReq);
+ register WindowPtr pWin;
+
+ REQUEST_SIZE_MATCH(xClearAreaReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (pWin->drawable.class == InputOnly)
+ {
+ client->errorValue = stuff->window;
+ return (BadMatch);
+ }
+ if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse))
+ {
+ client->errorValue = stuff->exposures;
+ return(BadValue);
+ }
+ (*pWin->drawable.pScreen->ClearToBackground)(pWin, stuff->x, stuff->y,
+ stuff->width, stuff->height,
+ (Bool)stuff->exposures);
+ return(client->noClientException);
+}
+
+int
+ProcCopyArea(register ClientPtr client)
+{
+ register DrawablePtr pDst;
+ register DrawablePtr pSrc;
+ register GC *pGC;
+ REQUEST(xCopyAreaReq);
+ RegionPtr pRgn;
+
+ REQUEST_SIZE_MATCH(xCopyAreaReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, pGC, client);
+ if (stuff->dstDrawable != stuff->srcDrawable)
+ {
+ SECURITY_VERIFY_DRAWABLE(pSrc, stuff->srcDrawable, client,
+ SecurityReadAccess);
+ if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth))
+ {
+ client->errorValue = stuff->dstDrawable;
+ return (BadMatch);
+ }
+ }
+ else
+ pSrc = pDst;
+
+ SET_DBE_SRCBUF(pSrc, stuff->srcDrawable);
+
+ pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, stuff->srcX, stuff->srcY,
+ stuff->width, stuff->height,
+ stuff->dstX, stuff->dstY);
+ if (pGC->graphicsExposures)
+ {
+ (*pDst->pScreen->SendGraphicsExpose)
+ (client, pRgn, stuff->dstDrawable, X_CopyArea, 0);
+ if (pRgn)
+ REGION_DESTROY(pDst->pScreen, pRgn);
+ }
+
+ return(client->noClientException);
+}
+
+int
+ProcCopyPlane(register ClientPtr client)
+{
+ register DrawablePtr psrcDraw, pdstDraw;
+ register GC *pGC;
+ REQUEST(xCopyPlaneReq);
+ RegionPtr pRgn;
+
+ REQUEST_SIZE_MATCH(xCopyPlaneReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, pGC, client);
+ if (stuff->dstDrawable != stuff->srcDrawable)
+ {
+ SECURITY_VERIFY_DRAWABLE(psrcDraw, stuff->srcDrawable, client,
+ SecurityReadAccess);
+ if (pdstDraw->pScreen != psrcDraw->pScreen)
+ {
+ client->errorValue = stuff->dstDrawable;
+ return (BadMatch);
+ }
+ }
+ else
+ psrcDraw = pdstDraw;
+
+ SET_DBE_SRCBUF(psrcDraw, stuff->srcDrawable);
+
+ /* Check to see if stuff->bitPlane has exactly ONE good bit set */
+ 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)
+ {
+ (*pdstDraw->pScreen->SendGraphicsExpose)
+ (client, pRgn, stuff->dstDrawable, X_CopyPlane, 0);
+ if (pRgn)
+ REGION_DESTROY(pdstDraw->pScreen, pRgn);
+ }
+ return(client->noClientException);
+}
+
+int
+ProcPolyPoint(register ClientPtr client)
+{
+ int npoint;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyPointReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyPointReq);
+ if ((stuff->coordMode != CoordModeOrigin) &&
+ (stuff->coordMode != CoordModePrevious))
+ {
+ client->errorValue = stuff->coordMode;
+ return BadValue;
+ }
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ npoint = ((client->req_len << 2) - sizeof(xPolyPointReq)) >> 2;
+ if (npoint)
+ {
+ (*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint,
+ (xPoint *) &stuff[1]);
+ }
+ return (client->noClientException);
+}
+
+int
+ProcPolyLine(register ClientPtr client)
+{
+ int npoint;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyLineReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyLineReq);
+ if ((stuff->coordMode != CoordModeOrigin) &&
+ (stuff->coordMode != CoordModePrevious))
+ {
+ client->errorValue = stuff->coordMode;
+ return BadValue;
+ }
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ npoint = ((client->req_len << 2) - sizeof(xPolyLineReq)) >> 2;
+ if (npoint > 1)
+ {
+ (*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint,
+ (DDXPointPtr) &stuff[1]);
+ }
+ return(client->noClientException);
+}
+
+int
+ProcPolySegment(register ClientPtr client)
+{
+ int nsegs;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolySegmentReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
+ if (nsegs & 4)
+ return(BadLength);
+ nsegs >>= 3;
+ if (nsegs)
+ {
+ (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]);
+ }
+ return (client->noClientException);
+}
+
+int
+ProcPolyRectangle (register ClientPtr client)
+{
+ int nrects;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyRectangleReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
+ if (nrects & 4)
+ return(BadLength);
+ nrects >>= 3;
+ if (nrects)
+ {
+ (*pGC->ops->PolyRectangle)(pDraw, pGC,
+ nrects, (xRectangle *) &stuff[1]);
+ }
+ return(client->noClientException);
+}
+
+int
+ProcPolyArc(register ClientPtr client)
+{
+ int narcs;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyArcReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyArcReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
+ if (narcs % sizeof(xArc))
+ return(BadLength);
+ narcs /= sizeof(xArc);
+ if (narcs)
+ {
+ (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]);
+ }
+ return (client->noClientException);
+}
+
+int
+ProcFillPoly(register ClientPtr client)
+{
+ int things;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xFillPolyReq);
+
+ REQUEST_AT_LEAST_SIZE(xFillPolyReq);
+ if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) &&
+ (stuff->shape != Convex))
+ {
+ client->errorValue = stuff->shape;
+ return BadValue;
+ }
+ if ((stuff->coordMode != CoordModeOrigin) &&
+ (stuff->coordMode != CoordModePrevious))
+ {
+ client->errorValue = stuff->coordMode;
+ return BadValue;
+ }
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ things = ((client->req_len << 2) - sizeof(xFillPolyReq)) >> 2;
+ if (things)
+ {
+ (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape,
+ stuff->coordMode, things,
+ (DDXPointPtr) &stuff[1]);
+ }
+ return(client->noClientException);
+}
+
+int
+ProcPolyFillRectangle(register ClientPtr client)
+{
+ int things;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyFillRectangleReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
+ if (things & 4)
+ return(BadLength);
+ things >>= 3;
+
+ if (things)
+ {
+ (*pGC->ops->PolyFillRect) (pDraw, pGC, things,
+ (xRectangle *) &stuff[1]);
+ }
+ return (client->noClientException);
+}
+
+int
+ProcPolyFillArc(register ClientPtr client)
+{
+ int narcs;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyFillArcReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
+ if (narcs % sizeof(xArc))
+ return(BadLength);
+ narcs /= sizeof(xArc);
+ if (narcs)
+ {
+ (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
+ }
+ return (client->noClientException);
+}
+
+#ifdef MATCH_CLIENT_ENDIAN
+
+int
+ServerOrder (void)
+{
+ int whichbyte = 1;
+
+ if (*((char *) &whichbyte))
+ return LSBFirst;
+ return MSBFirst;
+}
+
+#define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder())
+
+void
+ReformatImage (char *base, int nbytes, int bpp, int order)
+{
+ switch (bpp) {
+ case 1: /* yuck */
+ if (BITMAP_BIT_ORDER != order)
+ BitOrderInvert ((unsigned char *) base, nbytes);
+#if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8
+ ReformatImage (base, nbytes, BITMAP_SCANLINE_UNIT, order);
+#endif
+ break;
+ case 4:
+ break; /* yuck */
+ case 8:
+ break;
+ case 16:
+ if (IMAGE_BYTE_ORDER != order)
+ TwoByteSwap ((unsigned char *) base, nbytes);
+ break;
+ case 32:
+ if (IMAGE_BYTE_ORDER != order)
+ FourByteSwap ((unsigned char *) base, nbytes);
+ break;
+ }
+}
+#else
+#define ReformatImage(b,n,bpp,o)
+#endif
+
+/* 64-bit server notes: the protocol restricts padding of images to
+ * 8-, 16-, or 32-bits. We would like to have 64-bits for the server
+ * to use internally. Removes need for internal alignment checking.
+ * All of the PutImage functions could be changed individually, but
+ * as currently written, they call other routines which require things
+ * to be 64-bit padded on scanlines, so we changed things here.
+ * If an image would be padded differently for 64- versus 32-, then
+ * copy each scanline to a 64-bit padded scanline.
+ * Also, we need to make sure that the image is aligned on a 64-bit
+ * boundary, even if the scanlines are padded to our satisfaction.
+ */
+int
+ProcPutImage(register ClientPtr client)
+{
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ long length; /* length of scanline server padded */
+ long lengthProto; /* length of scanline protocol padded */
+ char *tmpImage;
+ REQUEST(xPutImageReq);
+
+ REQUEST_AT_LEAST_SIZE(xPutImageReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ if (stuff->format == XYBitmap)
+ {
+ if ((stuff->depth != 1) ||
+ (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
+ return BadMatch;
+ length = BitmapBytePad(stuff->width + stuff->leftPad);
+ }
+ else if (stuff->format == XYPixmap)
+ {
+ if ((pDraw->depth != stuff->depth) ||
+ (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
+ return BadMatch;
+ length = BitmapBytePad(stuff->width + stuff->leftPad);
+ length *= stuff->depth;
+ }
+ else if (stuff->format == ZPixmap)
+ {
+ if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0))
+ return BadMatch;
+ length = PixmapBytePad(stuff->width, stuff->depth);
+ }
+ else
+ {
+ client->errorValue = stuff->format;
+ return BadValue;
+ }
+
+ tmpImage = (char *)&stuff[1];
+ lengthProto = length;
+
+ if (((((lengthProto * stuff->height) + (unsigned)3) >> 2) +
+ (sizeof(xPutImageReq) >> 2)) != client->req_len)
+ return BadLength;
+
+ ReformatImage (tmpImage, lengthProto * stuff->height,
+ stuff->format == ZPixmap ? BitsPerPixel (stuff->depth) : 1,
+ ClientOrder(client));
+
+ (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY,
+ stuff->width, stuff->height,
+ stuff->leftPad, stuff->format, tmpImage);
+
+ return (client->noClientException);
+}
+
+
+int
+DoGetImage(register ClientPtr client, int format, Drawable drawable,
+ int x, int y, int width, int height,
+ Mask planemask, xGetImageReply **im_return)
+{
+ register DrawablePtr pDraw;
+ int nlines, linesPerBuf;
+ register int linesDone;
+ long widthBytesLine, length;
+ Mask plane = 0;
+ char *pBuf;
+ xGetImageReply xgi;
+#ifdef XCSECURITY
+ RegionPtr pVisibleRegion = NULL;
+#endif
+
+ if ((format != XYPixmap) && (format != ZPixmap))
+ {
+ client->errorValue = format;
+ return(BadValue);
+ }
+ SECURITY_VERIFY_DRAWABLE(pDraw, drawable, client, SecurityReadAccess);
+ if(pDraw->type == DRAWABLE_WINDOW)
+ {
+ if( /* check for being viewable */
+ !((WindowPtr) pDraw)->realized ||
+ /* check for being on screen */
+ pDraw->x + x < 0 ||
+ pDraw->x + x + width > pDraw->pScreen->width ||
+ pDraw->y + y < 0 ||
+ pDraw->y + y + height > pDraw->pScreen->height ||
+ /* check for being inside of border */
+ x < - wBorderWidth((WindowPtr)pDraw) ||
+ x + width > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+ y < -wBorderWidth((WindowPtr)pDraw) ||
+ y + height > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height
+ )
+ return(BadMatch);
+ xgi.visual = wVisual (((WindowPtr) pDraw));
+ }
+ else
+ {
+ if(x < 0 ||
+ x+width > (int)pDraw->width ||
+ y < 0 ||
+ y+height > (int)pDraw->height
+ )
+ return(BadMatch);
+ xgi.visual = None;
+ }
+
+ SET_DBE_SRCBUF(pDraw, drawable);
+
+ xgi.type = X_Reply;
+ xgi.sequenceNumber = client->sequence;
+ xgi.depth = pDraw->depth;
+ if(format == ZPixmap)
+ {
+ widthBytesLine = PixmapBytePad(width, pDraw->depth);
+ length = widthBytesLine * height;
+
+ }
+ else
+ {
+ widthBytesLine = BitmapBytePad(width);
+ plane = ((Mask)1) << (pDraw->depth - 1);
+ /* only planes asked for */
+ length = widthBytesLine * height *
+ Ones(planemask & (plane | (plane - 1)));
+
+ }
+
+ xgi.length = length;
+
+ if (im_return) {
+ pBuf = (char *)xalloc(sz_xGetImageReply + length);
+ if (!pBuf)
+ return (BadAlloc);
+ if (widthBytesLine == 0)
+ linesPerBuf = 0;
+ else
+ linesPerBuf = height;
+ *im_return = (xGetImageReply *)pBuf;
+ *(xGetImageReply *)pBuf = xgi;
+ pBuf += sz_xGetImageReply;
+ } else {
+ xgi.length = (xgi.length + 3) >> 2;
+ if (widthBytesLine == 0 || height == 0)
+ linesPerBuf = 0;
+ else if (widthBytesLine >= IMAGE_BUFSIZE)
+ linesPerBuf = 1;
+ else
+ {
+ linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
+ if (linesPerBuf > height)
+ linesPerBuf = height;
+ }
+ length = linesPerBuf * widthBytesLine;
+ if (linesPerBuf < height)
+ {
+ /* we have to make sure intermediate buffers don't need padding */
+ while ((linesPerBuf > 1) &&
+ (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1)))
+ {
+ linesPerBuf--;
+ length -= widthBytesLine;
+ }
+ while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))
+ {
+ linesPerBuf++;
+ length += widthBytesLine;
+ }
+ }
+ if(!(pBuf = (char *) ALLOCATE_LOCAL(length)))
+ return (BadAlloc);
+ WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
+ }
+
+#ifdef XCSECURITY
+ if (client->trustLevel != XSecurityClientTrusted &&
+ pDraw->type == DRAWABLE_WINDOW)
+ {
+ pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw);
+ if (pVisibleRegion)
+ {
+ REGION_TRANSLATE(pDraw->pScreen, pVisibleRegion, -pDraw->x, -pDraw->y);
+ }
+ }
+#endif
+
+ if (linesPerBuf == 0)
+ {
+ /* nothing to do */
+ }
+ else if (format == ZPixmap)
+ {
+ linesDone = 0;
+ while (height - linesDone > 0)
+ {
+ nlines = min(linesPerBuf, height - linesDone);
+ (*pDraw->pScreen->GetImage) (pDraw,
+ x,
+ y + linesDone,
+ width,
+ nlines,
+ format,
+ planemask,
+ (pointer) pBuf);
+#ifdef XCSECURITY
+ if (pVisibleRegion)
+ SecurityCensorImage(client, pVisibleRegion, widthBytesLine,
+ pDraw, x, y + linesDone, width,
+ nlines, format, pBuf);
+#endif
+
+ /* Note that this is NOT a call to WriteSwappedDataToClient,
+ as we do NOT byte swap */
+ if (!im_return)
+ {
+ ReformatImage (pBuf, (int)(nlines * widthBytesLine),
+ BitsPerPixel (pDraw->depth),
+ ClientOrder(client));
+
+/* Don't split me, gcc pukes when you do */
+ (void)WriteToClient(client,
+ (int)(nlines * widthBytesLine),
+ pBuf);
+ }
+ linesDone += nlines;
+ }
+ }
+ else /* XYPixmap */
+ {
+ for (; plane; plane >>= 1)
+ {
+ if (planemask & plane)
+ {
+ linesDone = 0;
+ while (height - linesDone > 0)
+ {
+ nlines = min(linesPerBuf, height - linesDone);
+ (*pDraw->pScreen->GetImage) (pDraw,
+ x,
+ y + linesDone,
+ width,
+ nlines,
+ format,
+ plane,
+ (pointer)pBuf);
+#ifdef XCSECURITY
+ if (pVisibleRegion)
+ SecurityCensorImage(client, pVisibleRegion,
+ widthBytesLine,
+ pDraw, x, y + linesDone, width,
+ nlines, format, pBuf);
+#endif
+
+ /* Note: NOT a call to WriteSwappedDataToClient,
+ as we do NOT byte swap */
+ if (im_return) {
+ pBuf += nlines * widthBytesLine;
+ } else {
+ ReformatImage (pBuf,
+ (int)(nlines * widthBytesLine),
+ 1,
+ ClientOrder (client));
+
+/* Don't split me, gcc pukes when you do */
+ (void)WriteToClient(client,
+ (int)(nlines * widthBytesLine),
+ pBuf);
+ }
+ linesDone += nlines;
+ }
+ }
+ }
+ }
+#ifdef XCSECURITY
+ if (pVisibleRegion)
+ REGION_DESTROY(pDraw->pScreen, pVisibleRegion);
+#endif
+ if (!im_return)
+ DEALLOCATE_LOCAL(pBuf);
+ return (client->noClientException);
+}
+
+int
+ProcGetImage(register ClientPtr client)
+{
+ REQUEST(xGetImageReq);
+
+ REQUEST_SIZE_MATCH(xGetImageReq);
+
+ return DoGetImage(client, stuff->format, stuff->drawable,
+ stuff->x, stuff->y,
+ (int)stuff->width, (int)stuff->height,
+ stuff->planeMask, (xGetImageReply **)NULL);
+}
+
+int
+ProcPolyText(register ClientPtr client)
+{
+ int err;
+ REQUEST(xPolyTextReq);
+ DrawablePtr pDraw;
+ GC *pGC;
+
+ REQUEST_AT_LEAST_SIZE(xPolyTextReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ err = PolyText(client,
+ pDraw,
+ pGC,
+ (unsigned char *)&stuff[1],
+ ((unsigned char *) stuff) + (client->req_len << 2),
+ stuff->x,
+ stuff->y,
+ stuff->reqType,
+ stuff->drawable);
+
+ if (err == Success)
+ {
+ return(client->noClientException);
+ }
+ else
+ return err;
+}
+
+int
+ProcImageText8(register ClientPtr client)
+{
+ int err;
+ register DrawablePtr pDraw;
+ register GC *pGC;
+
+ REQUEST(xImageTextReq);
+
+ REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ err = ImageText(client,
+ pDraw,
+ pGC,
+ stuff->nChars,
+ (unsigned char *)&stuff[1],
+ stuff->x,
+ stuff->y,
+ stuff->reqType,
+ stuff->drawable);
+
+ if (err == Success)
+ {
+ return(client->noClientException);
+ }
+ else
+ return err;
+}
+
+int
+ProcImageText16(register ClientPtr client)
+{
+ int err;
+ register DrawablePtr pDraw;
+ register GC *pGC;
+
+ REQUEST(xImageTextReq);
+
+ REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ err = ImageText(client,
+ pDraw,
+ pGC,
+ stuff->nChars,
+ (unsigned char *)&stuff[1],
+ stuff->x,
+ stuff->y,
+ stuff->reqType,
+ stuff->drawable);
+
+ if (err == Success)
+ {
+ return(client->noClientException);
+ }
+ else
+ return err;
+}
+
+
+int
+ProcCreateColormap(register ClientPtr client)
+{
+ VisualPtr pVisual;
+ ColormapPtr pmap;
+ Colormap mid;
+ register WindowPtr pWin;
+ ScreenPtr pScreen;
+ REQUEST(xCreateColormapReq);
+ int i, result;
+
+ REQUEST_SIZE_MATCH(xCreateColormapReq);
+
+ if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll))
+ {
+ client->errorValue = stuff->alloc;
+ return(BadValue);
+ }
+ mid = stuff->mid;
+ LEGAL_NEW_RESOURCE(mid, client);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+
+ pScreen = pWin->drawable.pScreen;
+ for (i = 0, pVisual = pScreen->visuals;
+ i < pScreen->numVisuals;
+ i++, pVisual++)
+ {
+ if (pVisual->vid != stuff->visual)
+ continue;
+ result = CreateColormap(mid, pScreen, pVisual, &pmap,
+ (int)stuff->alloc, client->index);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+ }
+ client->errorValue = stuff->visual;
+ return(BadValue);
+}
+
+int
+ProcFreeColormap(register ClientPtr client)
+{
+ ColormapPtr pmap;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pmap = (ColormapPtr )SecurityLookupIDByType(client, stuff->id, RT_COLORMAP,
+ SecurityDestroyAccess);
+ if (pmap)
+ {
+ /* Freeing a default colormap is a no-op */
+ if (!(pmap->flags & IsDefault))
+ FreeResource(stuff->id, RT_NONE);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadColor);
+ }
+}
+
+
+int
+ProcCopyColormapAndFree(register ClientPtr client)
+{
+ Colormap mid;
+ ColormapPtr pSrcMap;
+ REQUEST(xCopyColormapAndFreeReq);
+ int result;
+
+ REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
+ mid = stuff->mid;
+ LEGAL_NEW_RESOURCE(mid, client);
+ if( (pSrcMap = (ColormapPtr )SecurityLookupIDByType(client, stuff->srcCmap,
+ RT_COLORMAP, SecurityReadAccess|SecurityWriteAccess)) )
+ {
+ result = CopyColormapAndFree(mid, pSrcMap, client->index);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+ }
+ else
+ {
+ client->errorValue = stuff->srcCmap;
+ return(BadColor);
+ }
+}
+
+int
+ProcInstallColormap(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
+ RT_COLORMAP, SecurityReadAccess);
+ if (pcmp)
+ {
+ (*(pcmp->pScreen->InstallColormap)) (pcmp);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadColor);
+ }
+}
+
+int
+ProcUninstallColormap(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
+ RT_COLORMAP, SecurityReadAccess);
+ if (pcmp)
+ {
+ if(pcmp->mid != pcmp->pScreen->defColormap)
+ (*(pcmp->pScreen->UninstallColormap)) (pcmp);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadColor);
+ }
+}
+
+int
+ProcListInstalledColormaps(register ClientPtr client)
+{
+ xListInstalledColormapsReply *preply;
+ int nummaps;
+ WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityReadAccess);
+
+ if (!pWin)
+ return(BadWindow);
+
+ preply = (xListInstalledColormapsReply *)
+ ALLOCATE_LOCAL(sizeof(xListInstalledColormapsReply) +
+ pWin->drawable.pScreen->maxInstalledCmaps *
+ sizeof(Colormap));
+ if(!preply)
+ return(BadAlloc);
+
+ preply->type = X_Reply;
+ preply->sequenceNumber = client->sequence;
+ nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
+ (pWin->drawable.pScreen, (Colormap *)&preply[1]);
+ preply->nColormaps = nummaps;
+ preply->length = nummaps;
+ WriteReplyToClient(client, sizeof (xListInstalledColormapsReply), preply);
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]);
+ DEALLOCATE_LOCAL(preply);
+ return(client->noClientException);
+}
+
+int
+ProcAllocColor (register ClientPtr client)
+{
+ ColormapPtr pmap;
+ int retval;
+ xAllocColorReply acr;
+ REQUEST(xAllocColorReq);
+
+ REQUEST_SIZE_MATCH(xAllocColorReq);
+ pmap = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityWriteAccess);
+ if (pmap)
+ {
+#ifdef LBX
+ /*
+ * If the colormap is grabbed by a proxy, the server will have
+ * to regain control over the colormap. This AllocColor request
+ * will be handled after the server gets back the colormap control.
+ */
+ if (LbxCheckColorRequest (client, pmap, (xReq *) stuff))
+ return Success;
+#endif
+ acr.type = X_Reply;
+ acr.length = 0;
+ acr.sequenceNumber = client->sequence;
+ acr.red = stuff->red;
+ acr.green = stuff->green;
+ acr.blue = stuff->blue;
+ acr.pixel = 0;
+ if( (retval = AllocColor(pmap, &acr.red, &acr.green, &acr.blue,
+ &acr.pixel, client->index)) )
+ {
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return (retval);
+ }
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !pmap->pScreen->myNum)
+#endif
+ WriteReplyToClient(client, sizeof(xAllocColorReply), &acr);
+ return (client->noClientException);
+
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcAllocNamedColor (register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xAllocNamedColorReq);
+
+ REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityWriteAccess);
+ if (pcmp)
+ {
+ int retval;
+
+ xAllocNamedColorReply ancr;
+
+#ifdef LBX
+ /*
+ * If the colormap is grabbed by a proxy, the server will have
+ * to regain control over the colormap. This AllocNamedColor request
+ * will be handled after the server gets back the colormap control.
+ */
+ if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
+ return Success;
+#endif
+ ancr.type = X_Reply;
+ ancr.length = 0;
+ ancr.sequenceNumber = client->sequence;
+
+ if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
+ &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue))
+ {
+ ancr.screenRed = ancr.exactRed;
+ ancr.screenGreen = ancr.exactGreen;
+ ancr.screenBlue = ancr.exactBlue;
+ ancr.pixel = 0;
+ if( (retval = AllocColor(pcmp,
+ &ancr.screenRed, &ancr.screenGreen, &ancr.screenBlue,
+ &ancr.pixel, client->index)) )
+ {
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(retval);
+ }
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+ WriteReplyToClient(client, sizeof (xAllocNamedColorReply), &ancr);
+ return (client->noClientException);
+ }
+ else
+ return(BadName);
+
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcAllocColorCells (register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xAllocColorCellsReq);
+
+ REQUEST_SIZE_MATCH(xAllocColorCellsReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityWriteAccess);
+ if (pcmp)
+ {
+ xAllocColorCellsReply accr;
+ int npixels, nmasks, retval;
+ long length;
+ Pixel *ppixels, *pmasks;
+
+#ifdef LBX
+ /*
+ * If the colormap is grabbed by a proxy, the server will have
+ * to regain control over the colormap. This AllocColorCells request
+ * will be handled after the server gets back the colormap control.
+ */
+ if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
+ return Success;
+#endif
+ npixels = stuff->colors;
+ if (!npixels)
+ {
+ client->errorValue = npixels;
+ return (BadValue);
+ }
+ if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
+ {
+ client->errorValue = stuff->contiguous;
+ return (BadValue);
+ }
+ nmasks = stuff->planes;
+ length = ((long)npixels + (long)nmasks) * sizeof(Pixel);
+ ppixels = (Pixel *)ALLOCATE_LOCAL(length);
+ if(!ppixels)
+ return(BadAlloc);
+ pmasks = ppixels + npixels;
+
+ if( (retval = AllocColorCells(client->index, pcmp, npixels, nmasks,
+ (Bool)stuff->contiguous, ppixels, pmasks)) )
+ {
+ DEALLOCATE_LOCAL(ppixels);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(retval);
+ }
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+ {
+ accr.type = X_Reply;
+ accr.length = length >> 2;
+ accr.sequenceNumber = client->sequence;
+ accr.nPixels = npixels;
+ accr.nMasks = nmasks;
+ WriteReplyToClient(client, sizeof (xAllocColorCellsReply), &accr);
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, length, ppixels);
+ }
+ DEALLOCATE_LOCAL(ppixels);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcAllocColorPlanes(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xAllocColorPlanesReq);
+
+ REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityWriteAccess);
+ if (pcmp)
+ {
+ xAllocColorPlanesReply acpr;
+ int npixels, retval;
+ long length;
+ Pixel *ppixels;
+
+#ifdef LBX
+ /*
+ * If the colormap is grabbed by a proxy, the server will have
+ * to regain control over the colormap. This AllocColorPlanes request
+ * will be handled after the server gets back the colormap control.
+ */
+ if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
+ return Success;
+#endif
+ npixels = stuff->colors;
+ if (!npixels)
+ {
+ client->errorValue = npixels;
+ return (BadValue);
+ }
+ if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
+ {
+ client->errorValue = stuff->contiguous;
+ return (BadValue);
+ }
+ acpr.type = X_Reply;
+ acpr.sequenceNumber = client->sequence;
+ acpr.nPixels = npixels;
+ length = (long)npixels * sizeof(Pixel);
+ ppixels = (Pixel *)ALLOCATE_LOCAL(length);
+ if(!ppixels)
+ return(BadAlloc);
+ if( (retval = AllocColorPlanes(client->index, pcmp, npixels,
+ (int)stuff->red, (int)stuff->green, (int)stuff->blue,
+ (Bool)stuff->contiguous, ppixels,
+ &acpr.redMask, &acpr.greenMask, &acpr.blueMask)) )
+ {
+ DEALLOCATE_LOCAL(ppixels);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(retval);
+ }
+ acpr.length = length >> 2;
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+ {
+ WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr);
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, length, ppixels);
+ }
+ DEALLOCATE_LOCAL(ppixels);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcFreeColors(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xFreeColorsReq);
+
+ REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityWriteAccess);
+ if (pcmp)
+ {
+ int count;
+ int retval;
+
+ if(pcmp->flags & AllAllocated)
+ return(BadAccess);
+ count = ((client->req_len << 2)- sizeof(xFreeColorsReq)) >> 2;
+ retval = FreeColors(pcmp, client->index, count,
+ (Pixel *)&stuff[1], (Pixel)stuff->planeMask);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return(retval);
+ }
+
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcStoreColors (ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xStoreColorsReq);
+
+ REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityWriteAccess);
+ if (pcmp)
+ {
+ int count;
+ int retval;
+
+ count = (client->req_len << 2) - sizeof(xStoreColorsReq);
+ if (count % sizeof(xColorItem))
+ return(BadLength);
+ count /= sizeof(xColorItem);
+ retval = StoreColors(pcmp, count, (xColorItem *)&stuff[1]);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return(retval);
+ }
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcStoreNamedColor (register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xStoreNamedColorReq);
+
+ REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityWriteAccess);
+ if (pcmp)
+ {
+ xColorItem def;
+ int retval;
+
+ if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1],
+ stuff->nbytes, &def.red, &def.green, &def.blue))
+ {
+ def.flags = stuff->flags;
+ def.pixel = stuff->pixel;
+ retval = StoreColors(pcmp, 1, &def);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(retval);
+ }
+ return (BadName);
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcQueryColors(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xQueryColorsReq);
+
+ REQUEST_AT_LEAST_SIZE(xQueryColorsReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityReadAccess);
+ if (pcmp)
+ {
+ int count, retval;
+ xrgb *prgbs;
+ xQueryColorsReply qcr;
+
+ count = ((client->req_len << 2) - sizeof(xQueryColorsReq)) >> 2;
+ prgbs = (xrgb *)ALLOCATE_LOCAL(count * sizeof(xrgb));
+ if(!prgbs && count)
+ return(BadAlloc);
+ if( (retval = QueryColors(pcmp, count, (Pixel *)&stuff[1], prgbs)) )
+ {
+ if (prgbs) DEALLOCATE_LOCAL(prgbs);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return (retval);
+ }
+ }
+ qcr.type = X_Reply;
+ qcr.length = (count * sizeof(xrgb)) >> 2;
+ qcr.sequenceNumber = client->sequence;
+ qcr.nColors = count;
+ WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr);
+ if (count)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend;
+ WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs);
+ }
+ if (prgbs) DEALLOCATE_LOCAL(prgbs);
+ return(client->noClientException);
+
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcLookupColor(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xLookupColorReq);
+
+ REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityReadAccess);
+ if (pcmp)
+ {
+ xLookupColorReply lcr;
+
+ if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
+ &lcr.exactRed, &lcr.exactGreen, &lcr.exactBlue))
+ {
+ lcr.type = X_Reply;
+ lcr.length = 0;
+ lcr.sequenceNumber = client->sequence;
+ lcr.screenRed = lcr.exactRed;
+ lcr.screenGreen = lcr.exactGreen;
+ lcr.screenBlue = lcr.exactBlue;
+ (*pcmp->pScreen->ResolveColor)(&lcr.screenRed,
+ &lcr.screenGreen,
+ &lcr.screenBlue,
+ pcmp->pVisual);
+ WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr);
+ return(client->noClientException);
+ }
+ return (BadName);
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcCreateCursor (register ClientPtr client)
+{
+ CursorPtr pCursor;
+
+ register PixmapPtr src;
+ register PixmapPtr msk;
+ unsigned char * srcbits;
+ unsigned char * mskbits;
+ unsigned short width, height;
+ long n;
+ CursorMetricRec cm;
+
+
+ REQUEST(xCreateCursorReq);
+
+ REQUEST_SIZE_MATCH(xCreateCursorReq);
+ LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+ src = (PixmapPtr)SecurityLookupIDByType(client, stuff->source,
+ RT_PIXMAP, SecurityReadAccess);
+ msk = (PixmapPtr)SecurityLookupIDByType(client, stuff->mask,
+ RT_PIXMAP, SecurityReadAccess);
+ if ( src == (PixmapPtr)NULL)
+ {
+ client->errorValue = stuff->source;
+ return (BadPixmap);
+ }
+ if ( msk == (PixmapPtr)NULL)
+ {
+ if (stuff->mask != None)
+ {
+ client->errorValue = stuff->mask;
+ return (BadPixmap);
+ }
+ }
+ else if ( src->drawable.width != msk->drawable.width
+ || src->drawable.height != msk->drawable.height
+ || src->drawable.depth != 1
+ || msk->drawable.depth != 1)
+ return (BadMatch);
+
+ width = src->drawable.width;
+ height = src->drawable.height;
+
+ if ( stuff->x > width
+ || stuff->y > height )
+ return (BadMatch);
+
+ n = BitmapBytePad(width)*height;
+ srcbits = (unsigned char *)xalloc(n);
+ if (!srcbits)
+ return (BadAlloc);
+ mskbits = (unsigned char *)xalloc(n);
+ if (!mskbits)
+ {
+ xfree(srcbits);
+ return (BadAlloc);
+ }
+
+ /* zeroing the (pad) bits helps some ddx cursor handling */
+ bzero((char *)srcbits, n);
+ (* src->drawable.pScreen->GetImage)( (DrawablePtr)src, 0, 0, width, height,
+ XYPixmap, 1, (pointer)srcbits);
+ if ( msk == (PixmapPtr)NULL)
+ {
+ register unsigned char *bits = mskbits;
+ while (--n >= 0)
+ *bits++ = ~0;
+ }
+ else
+ {
+ /* zeroing the (pad) bits helps some ddx cursor handling */
+ bzero((char *)mskbits, n);
+ (* msk->drawable.pScreen->GetImage)( (DrawablePtr)msk, 0, 0, width,
+ height, XYPixmap, 1, (pointer)mskbits);
+ }
+ cm.width = width;
+ cm.height = height;
+ cm.xhot = stuff->x;
+ cm.yhot = stuff->y;
+ pCursor = AllocCursor( srcbits, mskbits, &cm,
+ stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
+ stuff->backRed, stuff->backGreen, stuff->backBlue);
+
+ if (pCursor && AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+ {
+ #ifdef TEST
+ fprintf(stderr, "ProcCreateCursor: Created cursor at [%p].\n", (void *) pCursor);
+ #endif
+
+ return (client->noClientException);
+ }
+
+ return BadAlloc;
+}
+
+int
+ProcCreateGlyphCursor (register ClientPtr client)
+{
+ CursorPtr pCursor;
+ int res;
+
+ REQUEST(xCreateGlyphCursorReq);
+
+ REQUEST_SIZE_MATCH(xCreateGlyphCursorReq);
+ LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+ res = AllocGlyphCursor(stuff->source, stuff->sourceChar,
+ stuff->mask, stuff->maskChar,
+ stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
+ stuff->backRed, stuff->backGreen, stuff->backBlue,
+ &pCursor, client);
+ if (res != Success)
+ return res;
+ if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+ return client->noClientException;
+ return BadAlloc;
+}
+
+
+int
+ProcFreeCursor (register ClientPtr client)
+{
+ CursorPtr pCursor;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->id,
+ RT_CURSOR, SecurityDestroyAccess);
+ if (pCursor)
+ {
+ FreeResource(stuff->id, RT_NONE);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadCursor);
+ }
+}
+
+int
+ProcQueryBestSize (register ClientPtr client)
+{
+ xQueryBestSizeReply reply;
+ register DrawablePtr pDraw;
+ ScreenPtr pScreen;
+ REQUEST(xQueryBestSizeReq);
+
+ REQUEST_SIZE_MATCH(xQueryBestSizeReq);
+ if ((stuff->class != CursorShape) &&
+ (stuff->class != TileShape) &&
+ (stuff->class != StippleShape))
+ {
+ client->errorValue = stuff->class;
+ return(BadValue);
+ }
+ SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->drawable, client,
+ SecurityReadAccess);
+ if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW)
+ return (BadMatch);
+ pScreen = pDraw->pScreen;
+ (* pScreen->QueryBestSize)(stuff->class, &stuff->width,
+ &stuff->height, pScreen);
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ reply.width = stuff->width;
+ reply.height = stuff->height;
+ WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply);
+ return (client->noClientException);
+}
+
+
+int
+ProcSetScreenSaver (register ClientPtr client)
+{
+ int blankingOption, exposureOption;
+ REQUEST(xSetScreenSaverReq);
+
+ REQUEST_SIZE_MATCH(xSetScreenSaverReq);
+ blankingOption = stuff->preferBlank;
+ if ((blankingOption != DontPreferBlanking) &&
+ (blankingOption != PreferBlanking) &&
+ (blankingOption != DefaultBlanking))
+ {
+ client->errorValue = blankingOption;
+ return BadValue;
+ }
+ exposureOption = stuff->allowExpose;
+ if ((exposureOption != DontAllowExposures) &&
+ (exposureOption != AllowExposures) &&
+ (exposureOption != DefaultExposures))
+ {
+ client->errorValue = exposureOption;
+ return BadValue;
+ }
+ if (stuff->timeout < -1)
+ {
+ client->errorValue = stuff->timeout;
+ return BadValue;
+ }
+ if (stuff->interval < -1)
+ {
+ client->errorValue = stuff->interval;
+ return BadValue;
+ }
+
+ /*
+ * The NX agent uses the screen saver procedure
+ * to monitor the user activities and launch its
+ * handlers (like timeout feature), so we can't
+ * always allow the clients to change our values.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "ProcSetScreenSaver: Called with timeout [%d] interval [%d] Blanking [%d] Exposure [%d].\n",
+ stuff -> timeout, stuff -> interval, blankingOption, exposureOption);
+ #endif
+
+ if (nxagentOption(Timeout) == 0)
+ {
+ if (blankingOption == DefaultBlanking)
+ {
+ ScreenSaverBlanking = defaultScreenSaverBlanking;
+ }
+ else
+ {
+ ScreenSaverBlanking = blankingOption;
+ }
+
+ if (exposureOption == DefaultExposures)
+ {
+ ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
+ }
+ else
+ {
+ ScreenSaverAllowExposures = exposureOption;
+ }
+
+ if (stuff->timeout >= 0)
+ {
+ ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND;
+ }
+ else
+ {
+ ScreenSaverTime = defaultScreenSaverTime;
+ }
+
+ if (stuff->interval >= 0)
+ {
+ ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND;
+ }
+ else
+ {
+ ScreenSaverInterval = defaultScreenSaverInterval;
+ }
+ }
+ #ifdef TEST
+
+ else
+ {
+ fprintf(stderr, "ProcSetScreenSaver: Keeping auto-disconnect timeout set to [%d] seconds.\n",
+ nxagentOption(Timeout));
+ }
+
+ #endif
+
+ SetScreenSaverTimer();
+ return (client->noClientException);
+}
+
+int
+ProcGetScreenSaver(register ClientPtr client)
+{
+ xGetScreenSaverReply rep;
+
+ REQUEST_SIZE_MATCH(xReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.timeout = ScreenSaverTime / MILLI_PER_SECOND;
+ rep.interval = ScreenSaverInterval / MILLI_PER_SECOND;
+ rep.preferBlanking = ScreenSaverBlanking;
+ rep.allowExposures = ScreenSaverAllowExposures;
+ WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep);
+ return (client->noClientException);
+}
+
+int
+ProcChangeHosts(register ClientPtr client)
+{
+ REQUEST(xChangeHostsReq);
+ int result;
+
+ REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength);
+
+ if(stuff->mode == HostInsert)
+ result = AddHost(client, (int)stuff->hostFamily,
+ stuff->hostLength, (pointer)&stuff[1]);
+ else if (stuff->mode == HostDelete)
+ result = RemoveHost(client, (int)stuff->hostFamily,
+ stuff->hostLength, (pointer)&stuff[1]);
+ else
+ {
+ client->errorValue = stuff->mode;
+ return BadValue;
+ }
+ if (!result)
+ result = client->noClientException;
+ return (result);
+}
+
+int
+ProcListHosts(register ClientPtr client)
+{
+ xListHostsReply reply;
+ int len, nHosts, result;
+ pointer pdata;
+ /* REQUEST(xListHostsReq); */
+
+ REQUEST_SIZE_MATCH(xListHostsReq);
+#ifdef XCSECURITY
+ /* untrusted clients can't list hosts */
+ if (client->trustLevel != XSecurityClientTrusted)
+ {
+ SecurityAudit("client %d attempted to list hosts\n", client->index);
+ return BadAccess;
+ }
+#endif
+ result = GetHosts(&pdata, &nHosts, &len, &reply.enabled);
+ if (result != Success)
+ return(result);
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.nHosts = nHosts;
+ reply.length = len >> 2;
+ WriteReplyToClient(client, sizeof(xListHostsReply), &reply);
+ if (nHosts)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend;
+ WriteSwappedDataToClient(client, len, pdata);
+ }
+ xfree(pdata);
+ return (client->noClientException);
+}
+
+int
+ProcChangeAccessControl(register ClientPtr client)
+{
+ int result;
+ REQUEST(xSetAccessControlReq);
+
+ REQUEST_SIZE_MATCH(xSetAccessControlReq);
+ if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess))
+ {
+ client->errorValue = stuff->mode;
+ return BadValue;
+ }
+ result = ChangeAccessControl(client, stuff->mode == EnableAccess);
+ if (!result)
+ result = client->noClientException;
+ return (result);
+}
+
+int
+ProcKillClient(register ClientPtr client)
+{
+ REQUEST(xResourceReq);
+ ClientPtr killclient;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ if (stuff->id == AllTemporary)
+ {
+ CloseDownRetainedResources();
+ return (client->noClientException);
+ }
+
+ if ((killclient = LookupClient(stuff->id, client)))
+ {
+ CloseDownClient(killclient);
+ /* if an LBX proxy gets killed, isItTimeToYield will be set */
+ if (isItTimeToYield || (client == killclient))
+ {
+ /* force yield and return Success, so that Dispatch()
+ * doesn't try to touch client
+ */
+ isItTimeToYield = TRUE;
+ return (Success);
+ }
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadValue);
+ }
+}
+
+int
+ProcSetFontPath(register ClientPtr client)
+{
+ unsigned char *ptr;
+ unsigned long nbytes, total;
+ long nfonts;
+ int n, result;
+ int error;
+ REQUEST(xSetFontPathReq);
+
+ REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
+
+ nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq);
+ total = nbytes;
+ ptr = (unsigned char *)&stuff[1];
+ nfonts = stuff->nFonts;
+ while (--nfonts >= 0)
+ {
+ if ((total == 0) || (total < (n = (*ptr + 1))))
+ return(BadLength);
+ total -= n;
+ ptr += n;
+ }
+ if (total >= 4)
+ return(BadLength);
+ result = SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1],
+ &error);
+ if (!result)
+ {
+ result = client->noClientException;
+ client->errorValue = error;
+ }
+ return (result);
+}
+
+int
+ProcGetFontPath(register ClientPtr client)
+{
+ xGetFontPathReply reply;
+ int stringLens, numpaths;
+ unsigned char *bufferStart;
+ /* REQUEST (xReq); */
+
+ REQUEST_SIZE_MATCH(xReq);
+ bufferStart = GetFontPath(&numpaths, &stringLens);
+
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.length = (stringLens + numpaths + 3) >> 2;
+ reply.nPaths = numpaths;
+
+ WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply);
+ if (stringLens || numpaths)
+ (void)WriteToClient(client, stringLens + numpaths, (char *)bufferStart);
+ return(client->noClientException);
+}
+
+int
+ProcChangeCloseDownMode(register ClientPtr client)
+{
+ REQUEST(xSetCloseDownModeReq);
+
+ REQUEST_SIZE_MATCH(xSetCloseDownModeReq);
+ if ((stuff->mode == AllTemporary) ||
+ (stuff->mode == RetainPermanent) ||
+ (stuff->mode == RetainTemporary))
+ {
+ client->closeDownMode = stuff->mode;
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->mode;
+ return (BadValue);
+ }
+}
+
+int ProcForceScreenSaver(register ClientPtr client)
+{
+ REQUEST(xForceScreenSaverReq);
+
+ REQUEST_SIZE_MATCH(xForceScreenSaverReq);
+
+ if ((stuff->mode != ScreenSaverReset) &&
+ (stuff->mode != ScreenSaverActive))
+ {
+ client->errorValue = stuff->mode;
+ return BadValue;
+ }
+
+ /*
+ * The NX agent uses the screen saver procedure
+ * to monitor the user activities and launch its
+ * handlers (like timeout feature), so we can't
+ * always allow the clients to force the screen
+ * saver handler execution.
+ */
+
+ if (nxagentOption(Timeout) == 0)
+ {
+ SaveScreens(SCREEN_SAVER_FORCER, (int)stuff->mode);
+ }
+
+ #ifdef TEST
+
+ else
+ {
+ fprintf(stderr, "ProcForceScreenSaver: Ignoring the client request with mode [%d].\n",
+ stuff -> mode);
+ }
+
+ #endif
+
+ return client->noClientException;
+}
+
+int ProcNoOperation(register ClientPtr client)
+{
+ REQUEST_AT_LEAST_SIZE(xReq);
+
+ /* noop -- don't do anything */
+ return(client->noClientException);
+}
+
+void
+InitProcVectors(void)
+{
+ int i;
+ for (i = 0; i<256; i++)
+ {
+ if(!ProcVector[i])
+ {
+ ProcVector[i] = SwappedProcVector[i] = ProcBadRequest;
+ ReplySwapVector[i] = ReplyNotSwappd;
+ }
+#ifdef K5AUTH
+ if (!k5_Vector[i])
+ {
+ k5_Vector[i] = k5_bad;
+ }
+#endif
+ }
+ for(i = LASTEvent; i < 128; i++)
+ {
+ EventSwapVector[i] = NotImplemented;
+ }
+
+}
+
+/**********************
+ * CloseDownClient
+ *
+ * Client can either mark his resources destroy or retain. If retained and
+ * then killed again, the client is really destroyed.
+ *********************/
+
+void
+CloseDownClient(register ClientPtr client)
+{
+ Bool really_close_down = client->clientGone ||
+ client->closeDownMode == DestroyAll;
+
+ /*
+ * There must be a better way to hook a
+ * call-back function to be called any
+ * time a client is going to be closed.
+ */
+
+ nxagentClearClipboard(client, NULL);
+
+ /*
+ * Need to reset the karma counter and
+ * get rid of the pending sync replies.
+ */
+
+ nxagentWakeupByReset(client);
+
+ /*
+ * Check if the client
+ * is a shadow nxagent.
+ */
+
+ nxagentCheckIfShadowAgent(client);
+
+ if (!client->clientGone)
+ {
+ /* ungrab server if grabbing client dies */
+ if (grabState != GrabNone && grabClient == client)
+ {
+ UngrabServer(client);
+ }
+ BITCLEAR(grabWaiters, client->index);
+ DeleteClientFromAnySelections(client);
+ ReleaseActiveGrabs(client);
+ DeleteClientFontStuff(client);
+ if (!really_close_down)
+ {
+ /* This frees resources that should never be retained
+ * no matter what the close down mode is. Actually we
+ * could do this unconditionally, but it's probably
+ * better not to traverse all the client's resources
+ * twice (once here, once a few lines down in
+ * FreeClientResources) in the common case of
+ * really_close_down == TRUE.
+ */
+ FreeClientNeverRetainResources(client);
+ client->clientState = ClientStateRetained;
+ if (ClientStateCallback)
+ {
+ NewClientInfoRec clientinfo;
+
+ clientinfo.client = client;
+ clientinfo.prefix = (xConnSetupPrefix *)NULL;
+ clientinfo.setup = (xConnSetup *) NULL;
+ CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+ }
+ }
+ client->clientGone = TRUE; /* so events aren't sent to client */
+ if (ClientIsAsleep(client))
+ ClientSignal (client);
+ ProcessWorkQueueZombies();
+#ifdef LBX
+ ProcessQTagZombies();
+#endif
+ CloseDownConnection(client);
+
+ /* If the client made it to the Running stage, nClients has
+ * been incremented on its behalf, so we need to decrement it
+ * now. If it hasn't gotten to Running, nClients has *not*
+ * been incremented, so *don't* decrement it.
+ */
+ if (client->clientState != ClientStateInitial &&
+ client->clientState != ClientStateAuthenticating )
+ {
+ --nClients;
+ }
+ }
+
+ if (really_close_down)
+ {
+ if (client->clientState == ClientStateRunning && nClients == 0)
+ dispatchException |= dispatchExceptionAtReset;
+
+ client->clientState = ClientStateGone;
+ if (ClientStateCallback)
+ {
+ NewClientInfoRec clientinfo;
+
+ clientinfo.client = client;
+ clientinfo.prefix = (xConnSetupPrefix *)NULL;
+ clientinfo.setup = (xConnSetup *) NULL;
+ CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+ }
+ FreeClientResources(client);
+ if (client->index < nextFreeClientID)
+ nextFreeClientID = client->index;
+ clients[client->index] = NullClient;
+#ifdef SMART_SCHEDULE
+ SmartLastClient = NullClient;
+#endif
+ xfree(client);
+
+ while (!clients[currentMaxClients-1])
+ currentMaxClients--;
+ }
+}
+
+static void
+KillAllClients()
+{
+ int i;
+ for (i=1; i<currentMaxClients; i++)
+ if (clients[i]) {
+ /* Make sure Retained clients are released. */
+ clients[i]->closeDownMode = DestroyAll;
+ CloseDownClient(clients[i]);
+ }
+}
+
+/*********************
+ * CloseDownRetainedResources
+ *
+ * Find all clients that are gone and have terminated in RetainTemporary
+ * and destroy their resources.
+ *********************/
+
+void
+CloseDownRetainedResources()
+{
+ register int i;
+ register ClientPtr client;
+
+ for (i=1; i<currentMaxClients; i++)
+ {
+ client = clients[i];
+ if (client && (client->closeDownMode == RetainTemporary)
+ && (client->clientGone))
+ CloseDownClient(client);
+ }
+}
+
+void InitClient(ClientPtr client, int i, pointer ospriv)
+{
+ client->index = i;
+ client->sequence = 0;
+ client->clientAsMask = ((Mask)i) << CLIENTOFFSET;
+ client->clientGone = FALSE;
+ if (i)
+ {
+ client->closeDownMode = DestroyAll;
+ client->lastDrawable = (DrawablePtr)WindowTable[0];
+ client->lastDrawableID = WindowTable[0]->drawable.id;
+ }
+ else
+ {
+ client->closeDownMode = RetainPermanent;
+ client->lastDrawable = (DrawablePtr)NULL;
+ client->lastDrawableID = INVALID;
+ }
+ client->lastGC = (GCPtr) NULL;
+ client->lastGCID = INVALID;
+ client->numSaved = 0;
+ client->saveSet = (SaveSetElt *)NULL;
+ client->noClientException = Success;
+#ifdef LOG_DEBUG
+ client->requestLogIndex = 0;
+#endif
+ client->requestVector = InitialVector;
+ client->osPrivate = ospriv;
+ client->swapped = FALSE;
+ client->big_requests = FALSE;
+ client->priority = 0;
+ client->clientState = ClientStateInitial;
+#ifdef XKB
+ if (!noXkbExtension) {
+ client->xkbClientFlags = 0;
+ client->mapNotifyMask = 0;
+ QueryMinMaxKeyCodes(&client->minKC,&client->maxKC);
+ }
+#endif
+ client->replyBytesRemaining = 0;
+#ifdef LBX
+ client->readRequest = StandardReadRequestFromClient;
+#endif
+#ifdef XCSECURITY
+ client->trustLevel = XSecurityClientTrusted;
+ client->CheckAccess = NULL;
+ client->authId = 0;
+#endif
+#ifdef XAPPGROUP
+ client->appgroup = NULL;
+#endif
+ client->fontResFunc = NULL;
+#ifdef SMART_SCHEDULE
+ client->smart_priority = 0;
+ client->smart_start_tick = SmartScheduleTime;
+ client->smart_stop_tick = SmartScheduleTime;
+ client->smart_check_tick = SmartScheduleTime;
+#endif
+}
+
+extern int clientPrivateLen;
+extern unsigned *clientPrivateSizes;
+extern unsigned totalClientSize;
+
+int
+InitClientPrivates(ClientPtr client)
+{
+ register char *ptr;
+ DevUnion *ppriv;
+ register unsigned *sizes;
+ register unsigned size;
+ register int i;
+
+ if (totalClientSize == sizeof(ClientRec))
+ ppriv = (DevUnion *)NULL;
+ else if (client->index)
+ ppriv = (DevUnion *)(client + 1);
+ else
+ {
+ ppriv = (DevUnion *)xalloc(totalClientSize - sizeof(ClientRec));
+ if (!ppriv)
+ return 0;
+ }
+ client->devPrivates = ppriv;
+ sizes = clientPrivateSizes;
+ ptr = (char *)(ppriv + clientPrivateLen);
+ for (i = clientPrivateLen; --i >= 0; ppriv++, sizes++)
+ {
+ if ( (size = *sizes) )
+ {
+ ppriv->ptr = (pointer)ptr;
+ ptr += size;
+ }
+ else
+ ppriv->ptr = (pointer)NULL;
+ }
+
+ /*
+ * Initialize the private members.
+ */
+
+ nxagentInitClientPrivates(client);
+
+ return 1;
+}
+
+/************************
+ * int NextAvailableClient(ospriv)
+ *
+ * OS dependent portion can't assign client id's because of CloseDownModes.
+ * Returns NULL if there are no free clients.
+ *************************/
+
+ClientPtr NextAvailableClient(pointer ospriv)
+{
+ register int i;
+ register ClientPtr client;
+ xReq data;
+
+ i = nextFreeClientID;
+ if (i == MAXCLIENTS)
+ return (ClientPtr)NULL;
+ clients[i] = client = (ClientPtr)xalloc(totalClientSize);
+ if (!client)
+ return (ClientPtr)NULL;
+ InitClient(client, i, ospriv);
+ InitClientPrivates(client);
+ if (!InitClientResources(client))
+ {
+ xfree(client);
+ return (ClientPtr)NULL;
+ }
+ data.reqType = 1;
+ data.length = (sz_xReq + sz_xConnClientPrefix) >> 2;
+ if (!InsertFakeRequest(client, (char *)&data, sz_xReq))
+ {
+ FreeClientResources(client);
+ xfree(client);
+ return (ClientPtr)NULL;
+ }
+ if (i == currentMaxClients)
+ currentMaxClients++;
+ while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID])
+ nextFreeClientID++;
+ if (ClientStateCallback)
+ {
+ NewClientInfoRec clientinfo;
+
+ clientinfo.client = client;
+ clientinfo.prefix = (xConnSetupPrefix *)NULL;
+ clientinfo.setup = (xConnSetup *) NULL;
+ CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+ }
+ return(client);
+}
+
+int
+ProcInitialConnection(register ClientPtr client)
+{
+ REQUEST(xReq);
+ register xConnClientPrefix *prefix;
+ int whichbyte = 1;
+
+ prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
+ if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B'))
+ return (client->noClientException = -1);
+ if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) ||
+ (!(*(char *) &whichbyte) && (prefix->byteOrder == 'l')))
+ {
+ client->swapped = TRUE;
+ SwapConnClientPrefix(prefix);
+ }
+ stuff->reqType = 2;
+ stuff->length += ((prefix->nbytesAuthProto + (unsigned)3) >> 2) +
+ ((prefix->nbytesAuthString + (unsigned)3) >> 2);
+ if (client->swapped)
+ {
+ swaps(&stuff->length, whichbyte);
+ }
+ ResetCurrentRequest(client);
+ return (client->noClientException);
+}
+
+#ifdef LBX
+void
+IncrementClientCount()
+{
+ nClients++;
+}
+#endif
+
+int
+SendConnSetup(register ClientPtr client, char *reason)
+{
+ register xWindowRoot *root;
+ register int i;
+ int numScreens;
+ char* lConnectionInfo;
+ xConnSetupPrefix* lconnSetupPrefix;
+
+ if (reason)
+ {
+ xConnSetupPrefix csp;
+
+ csp.success = xFalse;
+ csp.lengthReason = strlen(reason);
+ csp.length = (csp.lengthReason + (unsigned)3) >> 2;
+ csp.majorVersion = X_PROTOCOL;
+ csp.minorVersion = X_PROTOCOL_REVISION;
+ if (client->swapped)
+ WriteSConnSetupPrefix(client, &csp);
+ else
+ (void)WriteToClient(client, sz_xConnSetupPrefix, (char *) &csp);
+ (void)WriteToClient(client, (int)csp.lengthReason, reason);
+ return (client->noClientException = -1);
+ }
+
+ numScreens = screenInfo.numScreens;
+ lConnectionInfo = ConnectionInfo;
+ lconnSetupPrefix = &connSetupPrefix;
+
+ /* We're about to start speaking X protocol back to the client by
+ * sending the connection setup info. This means the authorization
+ * step is complete, and we can count the client as an
+ * authorized one.
+ */
+ nClients++;
+
+ client->requestVector = client->swapped ? SwappedProcVector : ProcVector;
+ client->sequence = 0;
+#ifdef XAPPGROUP
+ XagConnectionInfo (client, &lconnSetupPrefix, &lConnectionInfo, &numScreens);
+#endif
+ ((xConnSetup *)lConnectionInfo)->ridBase = client->clientAsMask;
+ ((xConnSetup *)lConnectionInfo)->ridMask = RESOURCE_ID_MASK;
+#ifdef MATCH_CLIENT_ENDIAN
+ ((xConnSetup *)lConnectionInfo)->imageByteOrder = ClientOrder (client);
+ ((xConnSetup *)lConnectionInfo)->bitmapBitOrder = ClientOrder (client);
+#endif
+ /* fill in the "currentInputMask" */
+ root = (xWindowRoot *)(lConnectionInfo + connBlockScreenStart);
+#ifdef PANORAMIX
+ if (noPanoramiXExtension)
+ numScreens = screenInfo.numScreens;
+ else
+ numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
+#endif
+
+ for (i=0; i<numScreens; i++)
+ {
+ register unsigned int j;
+ register xDepth *pDepth;
+
+ root->currentInputMask = WindowTable[i]->eventMask |
+ wOtherEventMasks (WindowTable[i]);
+ pDepth = (xDepth *)(root + 1);
+ for (j = 0; j < root->nDepths; j++)
+ {
+ pDepth = (xDepth *)(((char *)(pDepth + 1)) +
+ pDepth->nVisuals * sizeof(xVisualType));
+ }
+ root = (xWindowRoot *)pDepth;
+ }
+
+ if (client->swapped)
+ {
+ WriteSConnSetupPrefix(client, lconnSetupPrefix);
+ WriteSConnectionInfo(client,
+ (unsigned long)(lconnSetupPrefix->length << 2),
+ lConnectionInfo);
+ }
+ else
+ {
+ (void)WriteToClient(client, sizeof(xConnSetupPrefix),
+ (char *) lconnSetupPrefix);
+ (void)WriteToClient(client, (int)(lconnSetupPrefix->length << 2),
+ lConnectionInfo);
+ }
+ client->clientState = ClientStateRunning;
+ if (ClientStateCallback)
+ {
+ NewClientInfoRec clientinfo;
+
+ clientinfo.client = client;
+ clientinfo.prefix = lconnSetupPrefix;
+ clientinfo.setup = (xConnSetup *)lConnectionInfo;
+ CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+ }
+ return (client->noClientException);
+}
+
+int
+ProcEstablishConnection(register ClientPtr client)
+{
+ char *reason, *auth_proto, *auth_string;
+ register xConnClientPrefix *prefix;
+ REQUEST(xReq);
+
+ prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
+ auth_proto = (char *)prefix + sz_xConnClientPrefix;
+ auth_string = auth_proto + ((prefix->nbytesAuthProto + 3) & ~3);
+ if ((prefix->majorVersion != X_PROTOCOL) ||
+ (prefix->minorVersion != X_PROTOCOL_REVISION))
+ reason = "Protocol version mismatch";
+ else
+ reason = ClientAuthorized(client,
+ (unsigned short)prefix->nbytesAuthProto,
+ auth_proto,
+ (unsigned short)prefix->nbytesAuthString,
+ auth_string);
+ /*
+ * If Kerberos is being used for this client, the clientState
+ * will be set to ClientStateAuthenticating at this point.
+ * More messages need to be exchanged among the X server, Kerberos
+ * server, and client to figure out if everyone is authorized.
+ * So we don't want to send the connection setup info yet, since
+ * the auth step isn't really done.
+ */
+ if (client->clientState == ClientStateCheckingSecurity)
+ client->clientState = ClientStateCheckedSecurity;
+ else if (client->clientState != ClientStateAuthenticating)
+ return(SendConnSetup(client, reason));
+ return(client->noClientException);
+}
+
+void
+SendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode,
+ XID resId, int errorCode)
+{
+ xError rep;
+
+ rep.type = X_Error;
+ rep.sequenceNumber = client->sequence;
+ rep.errorCode = errorCode;
+ rep.majorCode = majorCode;
+ rep.minorCode = minorCode;
+ rep.resourceID = resId;
+
+ WriteEventsToClient (client, 1, (xEvent *)&rep);
+}
+
+void
+DeleteWindowFromAnySelections(WindowPtr pWin)
+{
+ register int i;
+
+ for (i = 0; i< NumCurrentSelections; i++)
+ if (CurrentSelections[i].pWin == pWin)
+ {
+ if (SelectionCallback)
+ {
+ SelectionInfoRec info;
+
+ info.selection = &CurrentSelections[i];
+ info.kind = SelectionWindowDestroy;
+ CallCallbacks(&SelectionCallback, &info);
+ }
+ CurrentSelections[i].pWin = (WindowPtr)NULL;
+ CurrentSelections[i].window = None;
+ CurrentSelections[i].client = NullClient;
+ }
+}
+
+static void
+DeleteClientFromAnySelections(ClientPtr client)
+{
+ register int i;
+
+ for (i = 0; i< NumCurrentSelections; i++)
+ if (CurrentSelections[i].client == client)
+ {
+ if (SelectionCallback)
+ {
+ SelectionInfoRec info;
+
+ info.selection = &CurrentSelections[i];
+ info.kind = SelectionWindowDestroy;
+ CallCallbacks(&SelectionCallback, &info);
+ }
+ CurrentSelections[i].pWin = (WindowPtr)NULL;
+ CurrentSelections[i].window = None;
+ CurrentSelections[i].client = NullClient;
+ }
+}
+
+void
+MarkClientException(ClientPtr client)
+{
+ client->noClientException = -1;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original
new file mode 100644
index 000000000..845c6cfb9
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original
@@ -0,0 +1,4670 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/* $XdotOrg: xc/programs/Xserver/dix/dispatch.c,v 1.13 2005/09/13 01:33:19 daniels Exp $ */
+/* $Xorg: dispatch.c,v 1.5 2001/02/09 02:04:40 xorgcvs Exp $ */
+/************************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+********************************************************/
+
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/dispatch.c,v 3.32 2003/11/10 18:21:45 tsi Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifdef PANORAMIX_DEBUG
+#include <stdio.h>
+int ProcInitialConnection();
+#endif
+
+#ifdef __sun
+#define False 0
+#define True 1
+#endif
+
+#define GC XlibGC
+#include <X11/Xlib.h>
+#undef GC
+
+#include "windowstr.h"
+#include <X11/fonts/fontstruct.h>
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "selection.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "opaque.h"
+#include "input.h"
+#include "servermd.h"
+#include "extnsionst.h"
+#include "dixfont.h"
+#include "../../dix/dispatch.h"
+#include "swaprep.h"
+#include "swapreq.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+#ifdef XAPPGROUP
+#include <X11/extensions/Xagsrv.h>
+#endif
+#ifdef XKB
+#define XKB_IN_SERVER
+#include "inputstr.h"
+#include <X11/extensions/XKBsrv.h>
+#endif
+
+#include "Atoms.h"
+#include "Splash.h"
+#include "Client.h"
+#include "Clipboard.h"
+#include "Reconnect.h"
+#include "Millis.h"
+#include "Font.h"
+#include "Shadow.h"
+#include "Handlers.h"
+#include "Keyboard.h"
+
+const int nxagentMaxFontNames = 10000;
+
+char dispatchExceptionAtReset = DE_RESET;
+
+/*
+ * This allows the agent to exit if no
+ * client is connected within a timeout.
+ */
+
+int nxagentClients = 0;
+
+void nxagentWaitDisplay(void);
+
+void nxagentListRemoteFonts(const char *, int);
+
+unsigned int nxagentWMtimeout = 0;
+Bool nxagentWMPassed = 0;
+
+/*
+ * Timeouts based on screen saver time.
+ */
+
+int nxagentAutoDisconnectTimeout = 0;
+
+#ifdef LBX
+#include "../../lbx/lbxserve.h"
+#endif
+
+#include "Xatom.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef WATCH
+
+/*
+ * Log begin and end of the important handlers.
+ */
+
+#undef BLOCKS
+
+#ifdef WATCH
+#include "unistd.h"
+#endif
+
+#ifdef TEST
+#include "Literals.h"
+#endif
+
+#define mskcnt ((MAXCLIENTS + 31) / 32)
+#define BITMASK(i) (1U << ((i) & 31))
+#define MASKIDX(i) ((i) >> 5)
+#define MASKWORD(buf, i) buf[MASKIDX(i)]
+#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
+#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
+#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
+
+extern xConnSetupPrefix connSetupPrefix;
+extern char *ConnectionInfo;
+
+Selection *CurrentSelections;
+int NumCurrentSelections;
+CallbackListPtr SelectionCallback = NULL;
+
+#ifdef VIEWPORT_FRAME
+
+extern WindowPtr nxagentViewportFrameLeft;
+extern WindowPtr nxagentViewportFrameRight;
+extern WindowPtr nxagentViewportFrameAbove;
+extern WindowPtr nxagentViewportFrameBelow;
+
+#define IsViewportFrame(pWin) ((pWin) == nxagentViewportFrameLeft || \
+ (pWin) == nxagentViewportFrameRight || \
+ (pWin) == nxagentViewportFrameAbove || \
+ (pWin) == nxagentViewportFrameBelow)
+
+#else
+
+#define IsViewportFrame(pWin) (0)
+
+#endif /* #ifdef VIEWPORT_FRAME */
+
+extern int nxagentMaxAllowedResets;
+
+extern int nxagentFindClientResource(int, RESTYPE, pointer);
+
+static ClientPtr grabClient;
+#define GrabNone 0
+#define GrabActive 1
+#define GrabKickout 2
+static int grabState = GrabNone;
+static long grabWaiters[mskcnt];
+CallbackListPtr ServerGrabCallback = NULL;
+HWEventQueuePtr checkForInput[2];
+extern int connBlockScreenStart;
+
+static void KillAllClients(void);
+
+static void DeleteClientFromAnySelections(ClientPtr client);
+
+static int nextFreeClientID; /* always MIN free client ID */
+
+static int nClients; /* number of authorized clients */
+
+CallbackListPtr ClientStateCallback;
+
+/* dispatchException & isItTimeToYield must be declared volatile since they
+ * are modified by signal handlers - otherwise optimizer may assume it doesn't
+ * need to actually check value in memory when used and may miss changes from
+ * signal handlers.
+ */
+volatile char dispatchException = 0;
+volatile char isItTimeToYield;
+
+/* Various of the DIX function interfaces were not designed to allow
+ * the client->errorValue to be set on BadValue and other errors.
+ * Rather than changing interfaces and breaking untold code we introduce
+ * a new global that dispatch can use.
+ */
+XID clientErrorValue; /* XXX this is a kludge */
+
+#define SAME_SCREENS(a, b) (\
+ (a.pScreen == b.pScreen))
+
+void
+SetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1)
+{
+ checkForInput[0] = c0;
+ checkForInput[1] = c1;
+}
+
+void
+UpdateCurrentTime()
+{
+ TimeStamp systime;
+
+ /* To avoid time running backwards, we must call GetTimeInMillis before
+ * calling ProcessInputEvents.
+ */
+ systime.months = currentTime.months;
+ systime.milliseconds = GetTimeInMillis();
+ if (systime.milliseconds < currentTime.milliseconds)
+ systime.months++;
+ if (*checkForInput[0] != *checkForInput[1])
+ ProcessInputEvents();
+ if (CompareTimeStamps(systime, currentTime) == LATER)
+ currentTime = systime;
+}
+
+/* Like UpdateCurrentTime, but can't call ProcessInputEvents */
+void
+UpdateCurrentTimeIf()
+{
+ TimeStamp systime;
+
+ systime.months = currentTime.months;
+ systime.milliseconds = GetTimeInMillis();
+ if (systime.milliseconds < currentTime.milliseconds)
+ systime.months++;
+ if (*checkForInput[0] == *checkForInput[1])
+ currentTime = systime;
+}
+
+void
+InitSelections()
+{
+ if (CurrentSelections)
+ xfree(CurrentSelections);
+ CurrentSelections = (Selection *)NULL;
+ NumCurrentSelections = 0;
+
+#ifdef NXAGENT_CLIPBOARD
+ {
+ Selection *newsels;
+ newsels = (Selection *)xalloc(2 * sizeof(Selection));
+ if (!newsels)
+ return;
+ NumCurrentSelections += 2;
+ CurrentSelections = newsels;
+
+ CurrentSelections[0].selection = XA_PRIMARY;
+ CurrentSelections[0].lastTimeChanged = ClientTimeToServerTime(0);
+ CurrentSelections[0].window = WindowTable[0]->drawable.id;
+ CurrentSelections[0].pWin = NULL;
+ CurrentSelections[0].client = NullClient;
+
+ CurrentSelections[1].selection = MakeAtom("CLIPBOARD", 9, 1);
+ CurrentSelections[1].lastTimeChanged = ClientTimeToServerTime(0);
+ CurrentSelections[1].window = WindowTable[0]->drawable.id;
+ CurrentSelections[1].pWin = NULL;
+ CurrentSelections[1].client = NullClient;
+ }
+#endif
+
+}
+
+void
+FlushClientCaches(XID id)
+{
+ int i;
+ register ClientPtr client;
+
+ client = clients[CLIENT_ID(id)];
+ if (client == NullClient)
+ return ;
+ for (i=0; i<currentMaxClients; i++)
+ {
+ client = clients[i];
+ if (client != NullClient)
+ {
+ if (client->lastDrawableID == id)
+ {
+ client->lastDrawableID = WindowTable[0]->drawable.id;
+ client->lastDrawable = (DrawablePtr)WindowTable[0];
+ }
+ else if (client->lastGCID == id)
+ {
+ client->lastGCID = INVALID;
+ client->lastGC = (GCPtr)NULL;
+ }
+ }
+ }
+}
+#ifdef SMART_SCHEDULE
+
+#undef SMART_DEBUG
+
+#define SMART_SCHEDULE_DEFAULT_INTERVAL 20 /* ms */
+#define SMART_SCHEDULE_MAX_SLICE 200 /* ms */
+
+Bool SmartScheduleDisable = FALSE;
+long SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
+long SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
+long SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
+long SmartScheduleTime;
+ClientPtr SmartLastClient;
+int SmartLastIndex[SMART_MAX_PRIORITY-SMART_MIN_PRIORITY+1];
+int SmartScheduleClient(int *clientReady, int nready);
+
+#ifdef SMART_DEBUG
+long SmartLastPrint;
+#endif
+
+void Dispatch(void);
+void InitProcVectors(void);
+
+int
+SmartScheduleClient (int *clientReady, int nready)
+{
+ ClientPtr pClient;
+ int i;
+ int client;
+ int bestPrio, best = 0;
+ int bestRobin, robin;
+ long now = SmartScheduleTime;
+ long idle;
+
+ bestPrio = -0x7fffffff;
+ bestRobin = 0;
+ idle = 2 * SmartScheduleSlice;
+ for (i = 0; i < nready; i++)
+ {
+ client = clientReady[i];
+ pClient = clients[client];
+ /* Praise clients which are idle */
+ if ((now - pClient->smart_check_tick) >= idle)
+ {
+ if (pClient->smart_priority < 0)
+ pClient->smart_priority++;
+ }
+ pClient->smart_check_tick = now;
+
+ /* check priority to select best client */
+ robin = (pClient->index - SmartLastIndex[pClient->smart_priority-SMART_MIN_PRIORITY]) & 0xff;
+ if (pClient->smart_priority > bestPrio ||
+ (pClient->smart_priority == bestPrio && robin > bestRobin))
+ {
+ bestPrio = pClient->smart_priority;
+ bestRobin = robin;
+ best = client;
+ }
+#ifdef SMART_DEBUG
+ if ((now - SmartLastPrint) >= 5000)
+ fprintf (stderr, " %2d: %3d", client, pClient->smart_priority);
+#endif
+ }
+#ifdef SMART_DEBUG
+ if ((now - SmartLastPrint) >= 5000)
+ {
+ fprintf (stderr, " use %2d\n", best);
+ SmartLastPrint = now;
+ }
+#endif
+ pClient = clients[best];
+ SmartLastIndex[bestPrio-SMART_MIN_PRIORITY] = pClient->index;
+ /*
+ * Set current client pointer
+ */
+ if (SmartLastClient != pClient)
+ {
+ pClient->smart_start_tick = now;
+ SmartLastClient = pClient;
+ }
+ /*
+ * Adjust slice
+ */
+ if (nready == 1)
+ {
+ /*
+ * If it's been a long time since another client
+ * has run, bump the slice up to get maximal
+ * performance from a single client
+ */
+ if ((now - pClient->smart_start_tick) > 1000 &&
+ SmartScheduleSlice < SmartScheduleMaxSlice)
+ {
+ SmartScheduleSlice += SmartScheduleInterval;
+ }
+ }
+ else
+ {
+ SmartScheduleSlice = SmartScheduleInterval;
+ }
+ return best;
+}
+#endif
+
+#define MAJOROP ((xReq *)client->requestBuffer)->reqType
+
+void
+Dispatch(void)
+{
+ register int *clientReady; /* array of request ready clients */
+ register int result;
+ register ClientPtr client;
+ register int nready;
+ register HWEventQueuePtr* icheck = checkForInput;
+#ifdef SMART_SCHEDULE
+ long start_tick;
+#endif
+
+ unsigned long currentDispatch = 0;
+
+ nextFreeClientID = 1;
+ InitSelections();
+ nClients = 0;
+
+ /*
+ * The agent initialization was successfully
+ * completed. We can now handle our clients.
+ */
+
+ if (serverGeneration > nxagentMaxAllowedResets)
+ {
+ fprintf(stderr, "Session: Session started at '%s'.\n", GetTimeAsString());
+
+ nxagentSessionState = SESSION_UP;
+ }
+
+ #ifdef XKB
+
+ nxagentInitXkbWrapper();
+
+ nxagentTuneXkbWrapper();
+
+ #endif
+
+ #ifdef NXAGENT_ONSTART
+
+ /*
+ * Set NX_WM property (used by NX client to identify
+ * the agent's window) three seconds since the first
+ * client connects.
+ */
+
+ nxagentWMtimeout = GetTimeInMillis() + 3000;
+
+ #endif
+
+ clientReady = (int *) ALLOCATE_LOCAL(sizeof(int) * MaxClients);
+ if (!clientReady)
+ return;
+
+ #ifdef WATCH
+
+ fprintf(stderr, "Dispatch: Watchpoint 12.\n");
+
+/*
+Reply Total Cached Bits In Bits Out Bits/Reply Ratio
+------- ----- ------ ------- -------- ---------- -----
+#3 1 352 bits (0 KB) -> 236 bits (0 KB) -> 352/1 -> 236/1 = 1.492:1
+#14 1 256 bits (0 KB) -> 101 bits (0 KB) -> 256/1 -> 101/1 = 2.535:1
+#16 1 256 bits (0 KB) -> 26 bits (0 KB) -> 256/1 -> 26/1 = 9.846:1
+#20 2 2 12256 bits (1 KB) -> 56 bits (0 KB) -> 6128/1 -> 28/1 = 218.857:1
+#43 1 256 bits (0 KB) -> 45 bits (0 KB) -> 256/1 -> 45/1 = 5.689:1
+#47 2 2 42304 bits (5 KB) -> 49 bits (0 KB) -> 21152/1 -> 24/1 = 863.347:1
+#98 1 256 bits (0 KB) -> 34 bits (0 KB) -> 256/1 -> 34/1 = 7.529:1
+*/
+
+ sleep(30);
+
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "Dispatch: Value of dispatchException is [%x].\n",
+ dispatchException);
+
+ fprintf(stderr, "Dispatch: Value of dispatchExceptionAtReset is [%x].\n",
+ dispatchExceptionAtReset);
+ #endif
+
+ if (!(dispatchException & DE_TERMINATE))
+ dispatchException = 0;
+
+ while (!dispatchException)
+ {
+ if (*icheck[0] != *icheck[1])
+ {
+ ProcessInputEvents();
+ FlushIfCriticalOutputPending();
+ }
+
+ /*
+ * Ensure we remove the splash after the timeout.
+ * Initializing clientReady[0] to -1 will tell
+ * WaitForSomething() to yield control after the
+ * timeout set in clientReady[1].
+ */
+
+ clientReady[0] = 0;
+
+ if (nxagentSplashWindow != None || (nxagentOption(Xdmcp) == 1 && nxagentXdmcpUp == 0))
+ {
+ #ifdef TEST
+ fprintf(stderr, "******Dispatch: Requesting a timeout of [%d] Ms.\n",
+ NXAGENT_WAKEUP);
+ #endif
+
+ clientReady[0] = -1;
+ clientReady[1] = NXAGENT_WAKEUP;
+ }
+
+ #ifdef BLOCKS
+ fprintf(stderr, "[End dispatch]\n");
+ #endif
+
+ nready = WaitForSomething(clientReady);
+
+ #ifdef BLOCKS
+ fprintf(stderr, "[Begin dispatch]\n");
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "******Dispatch: Running with [%d] clients ready.\n",
+ nready);
+ #endif
+
+ #ifdef NXAGENT_ONSTART
+
+ currentDispatch = GetTimeInMillis();
+
+ /*
+ * If the timeout is expired set the
+ * selection informing the NX client
+ * that the agent is ready.
+ */
+
+ if (!nxagentWMPassed && (nxagentWMtimeout < currentDispatch))
+ {
+ nxagentRemoveSplashWindow(NULL);
+ }
+
+ nxagentClients = nClients;
+
+ #endif
+
+#ifdef SMART_SCHEDULE
+ if (nready && !SmartScheduleDisable)
+ {
+ clientReady[0] = SmartScheduleClient (clientReady, nready);
+ nready = 1;
+ }
+#endif
+ /*****************
+ * Handle events in round robin fashion, doing input between
+ * each round
+ *****************/
+
+ while (!dispatchException && (--nready >= 0))
+ {
+ client = clients[clientReady[nready]];
+ if (! client)
+ {
+ /* KillClient can cause this to happen */
+ continue;
+ }
+ /* GrabServer activation can cause this to be true */
+ if (grabState == GrabKickout)
+ {
+ grabState = GrabActive;
+ break;
+ }
+ isItTimeToYield = FALSE;
+
+ requestingClient = client;
+#ifdef SMART_SCHEDULE
+ start_tick = SmartScheduleTime;
+#endif
+ while (!isItTimeToYield)
+ {
+ if (*icheck[0] != *icheck[1])
+ {
+ ProcessInputEvents();
+ FlushIfCriticalOutputPending();
+ }
+#ifdef SMART_SCHEDULE
+ if (!SmartScheduleDisable &&
+ (SmartScheduleTime - start_tick) >= SmartScheduleSlice)
+ {
+ /* Penalize clients which consume ticks */
+ if (client->smart_priority > SMART_MIN_PRIORITY)
+ client->smart_priority--;
+ break;
+ }
+#endif
+ /* now, finally, deal with client requests */
+
+ #ifdef TEST
+ fprintf(stderr, "******Dispatch: Reading request from client [%d].\n",
+ client->index);
+ #endif
+
+ result = ReadRequestFromClient(client);
+ if (result <= 0)
+ {
+ if (result < 0)
+ CloseDownClient(client);
+ break;
+ }
+#ifdef NXAGENT_SERVER
+
+ #ifdef TEST
+
+ else
+ {
+
+ if (MAJOROP > 127)
+ {
+ fprintf(stderr, "******Dispatch: Read [Extension] request OPCODE#%d MINOR#%d "
+ "size [%d] client [%d].\n", MAJOROP, *((char *) client->requestBuffer + 1),
+ client->req_len << 2, client->index);
+ }
+ else
+ {
+ fprintf(stderr, "******Dispatch: Read [%s] request OPCODE#%d size [%d] client [%d].\n",
+ nxagentRequestLiteral[MAJOROP], MAJOROP, client->req_len << 2,
+ client->index);
+ }
+ }
+
+ #endif
+#endif
+
+ client->sequence++;
+#ifdef DEBUG
+ if (client->requestLogIndex == MAX_REQUEST_LOG)
+ client->requestLogIndex = 0;
+ client->requestLog[client->requestLogIndex] = MAJOROP;
+ client->requestLogIndex++;
+#endif
+ if (result > (maxBigRequestSize << 2))
+ result = BadLength;
+ else
+#ifdef NXAGENT_SERVER
+ {
+ result = (* client->requestVector[MAJOROP])(client);
+
+ #ifdef TEST
+
+ if (MAJOROP > 127)
+ {
+ fprintf(stderr, "******Dispatch: Handled [Extension] request OPCODE#%d MINOR#%d "
+ "size [%d] client [%d] result [%d].\n", MAJOROP,
+ *((char *) client->requestBuffer + 1), client->req_len << 2,
+ client->index, result);
+ }
+ else
+ {
+ fprintf(stderr, "******Dispatch: Handled [%s] request OPCODE#%d size [%d] client [%d] "
+ "result [%d].\n", nxagentRequestLiteral[MAJOROP], MAJOROP,
+ client->req_len << 2, client->index, result);
+ }
+
+ #endif
+
+ /*
+ * Can set isItTimeToYield to force
+ * the dispatcher to pay attention
+ * to another client.
+ */
+
+ nxagentDispatchHandler(client, client->req_len << 2, 0);
+ }
+#else
+ result = (* client->requestVector[MAJOROP])(client);
+#endif
+
+ if (result != Success)
+ {
+ if (client->noClientException != Success)
+ CloseDownClient(client);
+ else
+ SendErrorToClient(client, MAJOROP,
+ MinorOpcodeOfRequest(client),
+ client->errorValue, result);
+ break;
+ }
+#ifdef DAMAGEEXT
+ FlushIfCriticalOutputPending ();
+#endif
+ }
+ FlushAllOutput();
+#ifdef SMART_SCHEDULE
+ client = clients[clientReady[nready]];
+ if (client)
+ client->smart_stop_tick = SmartScheduleTime;
+#endif
+ requestingClient = NULL;
+ }
+ dispatchException &= ~DE_PRIORITYCHANGE;
+ }
+#if defined(DDXBEFORERESET)
+ ddxBeforeReset ();
+#endif
+ if ((dispatchException & DE_RESET) &&
+ (serverGeneration > nxagentMaxAllowedResets))
+ {
+ dispatchException &= ~DE_RESET;
+ dispatchException |= DE_TERMINATE;
+
+ fprintf(stderr, "Info: Reached threshold of maximum allowed resets.\n");
+ }
+
+ nxagentResetAtomMap();
+
+ if (serverGeneration > nxagentMaxAllowedResets)
+ {
+ /*
+ * The session is terminating. Force an I/O
+ * error on the display and wait until the
+ * NX transport is gone.
+ */
+
+ fprintf(stderr, "Session: Terminating session at '%s'.\n", GetTimeAsString());
+
+ nxagentWaitDisplay();
+
+ fprintf(stderr, "Session: Session terminated at '%s'.\n", GetTimeAsString());
+ }
+
+ if (nxagentOption(Shadow) == 1)
+ {
+ NXShadowDestroy();
+ }
+
+ KillAllClients();
+ DEALLOCATE_LOCAL(clientReady);
+ dispatchException &= ~DE_RESET;
+}
+
+#undef MAJOROP
+
+int
+ProcBadRequest(ClientPtr client)
+{
+ return (BadRequest);
+}
+
+int
+ProcCreateWindow(ClientPtr client)
+{
+ register WindowPtr pParent, pWin;
+ REQUEST(xCreateWindowReq);
+ int result;
+ int len;
+
+ REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
+
+ LEGAL_NEW_RESOURCE(stuff->wid, client);
+ if (!(pParent = (WindowPtr)SecurityLookupWindow(stuff->parent, client,
+ SecurityWriteAccess)))
+ return BadWindow;
+ len = client->req_len - (sizeof(xCreateWindowReq) >> 2);
+ if (Ones(stuff->mask) != len)
+ return BadLength;
+ if (!stuff->width || !stuff->height)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ pWin = CreateWindow(stuff->wid, pParent, stuff->x,
+ stuff->y, stuff->width, stuff->height,
+ stuff->borderWidth, stuff->class,
+ stuff->mask, (XID *) &stuff[1],
+ (int)stuff->depth,
+ client, stuff->visual, &result);
+ if (pWin)
+ {
+ Mask mask = pWin->eventMask;
+
+ pWin->eventMask = 0; /* subterfuge in case AddResource fails */
+ if (!AddResource(stuff->wid, RT_WINDOW, (pointer)pWin))
+ return BadAlloc;
+ pWin->eventMask = mask;
+ }
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+int
+ProcChangeWindowAttributes(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xChangeWindowAttributesReq);
+ register int result;
+ int len;
+
+ REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ len = client->req_len - (sizeof(xChangeWindowAttributesReq) >> 2);
+ if (len != Ones(stuff->valueMask))
+ return BadLength;
+ result = ChangeWindowAttributes(pWin,
+ stuff->valueMask,
+ (XID *) &stuff[1],
+ client);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+int
+ProcGetWindowAttributes(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+ xGetWindowAttributesReply wa;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ GetWindowAttributes(pWin, client, &wa);
+ WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa);
+ return(client->noClientException);
+}
+
+int
+ProcDestroyWindow(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityDestroyAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (pWin->parent)
+ FreeResource(stuff->id, RT_NONE);
+ return(client->noClientException);
+}
+
+int
+ProcDestroySubwindows(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityDestroyAccess);
+ if (!pWin)
+ return(BadWindow);
+ DestroySubwindows(pWin, client);
+ return(client->noClientException);
+}
+
+int
+ProcChangeSaveSet(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xChangeSaveSetReq);
+ register int result;
+
+ REQUEST_SIZE_MATCH(xChangeSaveSetReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id)))
+ return BadMatch;
+ if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete))
+ {
+ result = AlterSaveSetForClient(client, pWin, stuff->mode, FALSE, TRUE);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+ }
+ else
+ {
+ client->errorValue = stuff->mode;
+ return( BadValue );
+ }
+}
+
+int
+ProcReparentWindow(register ClientPtr client)
+{
+ register WindowPtr pWin, pParent;
+ REQUEST(xReparentWindowReq);
+ register int result;
+
+ REQUEST_SIZE_MATCH(xReparentWindowReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+
+ if (!nxagentWMPassed)
+ {
+ nxagentRemoveSplashWindow(pWin);
+ }
+
+ pParent = (WindowPtr)SecurityLookupWindow(stuff->parent, client,
+ SecurityWriteAccess);
+ if (!pParent)
+ return(BadWindow);
+ if (SAME_SCREENS(pWin->drawable, pParent->drawable))
+ {
+ if ((pWin->backgroundState == ParentRelative) &&
+ (pParent->drawable.depth != pWin->drawable.depth))
+ return BadMatch;
+ if ((pWin->drawable.class != InputOnly) &&
+ (pParent->drawable.class == InputOnly))
+ return BadMatch;
+ result = ReparentWindow(pWin, pParent,
+ (short)stuff->x, (short)stuff->y, client);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+ }
+ else
+ return (BadMatch);
+}
+
+int
+ProcMapWindow(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ MapWindow(pWin, client);
+ /* update cache to say it is mapped */
+ return(client->noClientException);
+}
+
+int
+ProcMapSubwindows(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ MapSubwindows(pWin, client);
+ /* update cache to say it is mapped */
+ return(client->noClientException);
+}
+
+int
+ProcUnmapWindow(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ UnmapWindow(pWin, FALSE);
+ /* update cache to say it is mapped */
+
+ return(client->noClientException);
+}
+
+int
+ProcUnmapSubwindows(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ UnmapSubwindows(pWin);
+ return(client->noClientException);
+}
+
+int
+ProcConfigureWindow(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xConfigureWindowReq);
+ register int result;
+ int len;
+
+ REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
+ pWin = (WindowPtr)SecurityLookupWindow( stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ len = client->req_len - (sizeof(xConfigureWindowReq) >> 2);
+ if (Ones((Mask)stuff->mask) != len)
+ return BadLength;
+ result = ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1],
+ client);
+
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+int
+ProcCirculateWindow(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xCirculateWindowReq);
+
+ REQUEST_SIZE_MATCH(xCirculateWindowReq);
+ if ((stuff->direction != RaiseLowest) &&
+ (stuff->direction != LowerHighest))
+ {
+ client->errorValue = stuff->direction;
+ return BadValue;
+ }
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ CirculateWindow(pWin, (int)stuff->direction, client);
+ return(client->noClientException);
+}
+
+int
+GetGeometry(register ClientPtr client, xGetGeometryReply *rep)
+{
+ register DrawablePtr pDraw;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->id, client, SecurityReadAccess);
+ rep->type = X_Reply;
+ rep->length = 0;
+ rep->sequenceNumber = client->sequence;
+ rep->root = WindowTable[pDraw->pScreen->myNum]->drawable.id;
+ rep->depth = pDraw->depth;
+ rep->width = pDraw->width;
+ rep->height = pDraw->height;
+
+ /* XXX - Because the pixmap-implementation of the multibuffer extension
+ * may have the buffer-id's drawable resource value be a pointer
+ * to the buffer's window instead of the buffer itself
+ * (this happens if the buffer is the displayed buffer),
+ * we also have to check that the id matches before we can
+ * truly say that it is a DRAWABLE_WINDOW.
+ */
+
+ if ((pDraw->type == UNDRAWABLE_WINDOW) ||
+ ((pDraw->type == DRAWABLE_WINDOW) && (stuff->id == pDraw->id)))
+ {
+ register WindowPtr pWin = (WindowPtr)pDraw;
+ rep->x = pWin->origin.x - wBorderWidth (pWin);
+ rep->y = pWin->origin.y - wBorderWidth (pWin);
+ rep->borderWidth = pWin->borderWidth;
+ }
+ else /* DRAWABLE_PIXMAP or DRAWABLE_BUFFER */
+ {
+ rep->x = rep->y = rep->borderWidth = 0;
+ }
+
+ return Success;
+}
+
+
+int
+ProcGetGeometry(register ClientPtr client)
+{
+ xGetGeometryReply rep;
+ int status;
+
+ if ((status = GetGeometry(client, &rep)) != Success)
+ return status;
+
+ WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
+ return(client->noClientException);
+}
+
+
+int
+ProcQueryTree(register ClientPtr client)
+{
+ xQueryTreeReply reply;
+ int numChildren = 0;
+ register WindowPtr pChild, pWin, pHead;
+ Window *childIDs = (Window *)NULL;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ reply.type = X_Reply;
+ reply.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
+ reply.sequenceNumber = client->sequence;
+ if (pWin->parent)
+ reply.parent = pWin->parent->drawable.id;
+ else
+ reply.parent = (Window)None;
+ pHead = RealChildHead(pWin);
+ for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+ {
+ if (!IsViewportFrame(pChild))
+ {
+ numChildren++;
+ }
+ }
+ if (numChildren)
+ {
+ int curChild = 0;
+
+ childIDs = (Window *) ALLOCATE_LOCAL(numChildren * sizeof(Window));
+ if (!childIDs)
+ return BadAlloc;
+ for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+ {
+ if (!IsViewportFrame(pChild))
+ {
+ childIDs[curChild++] = pChild->drawable.id;
+ }
+ }
+ }
+
+ reply.nChildren = numChildren;
+ reply.length = (numChildren * sizeof(Window)) >> 2;
+
+ WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply);
+ if (numChildren)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, numChildren * sizeof(Window), childIDs);
+ DEALLOCATE_LOCAL(childIDs);
+ }
+
+ return(client->noClientException);
+}
+
+int
+ProcInternAtom(register ClientPtr client)
+{
+ Atom atom;
+ char *tchar;
+ REQUEST(xInternAtomReq);
+
+ REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes);
+ if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse))
+ {
+ client->errorValue = stuff->onlyIfExists;
+ return(BadValue);
+ }
+ tchar = (char *) &stuff[1];
+ atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists);
+ if (atom != BAD_RESOURCE)
+ {
+ xInternAtomReply reply;
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ reply.atom = atom;
+ WriteReplyToClient(client, sizeof(xInternAtomReply), &reply);
+ return(client->noClientException);
+ }
+ else
+ return (BadAlloc);
+}
+
+int
+ProcGetAtomName(register ClientPtr client)
+{
+ char *str;
+ xGetAtomNameReply reply;
+ int len;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ if ( (str = NameForAtom(stuff->id)) )
+ {
+ len = strlen(str);
+ reply.type = X_Reply;
+ reply.length = (len + 3) >> 2;
+ reply.sequenceNumber = client->sequence;
+ reply.nameLength = len;
+ WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply);
+ (void)WriteToClient(client, len, str);
+ return(client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadAtom);
+ }
+}
+
+#ifdef K5AUTH
+extern int k5_bad();
+#endif
+
+int
+ProcSetSelectionOwner(register ClientPtr client)
+{
+ WindowPtr pWin;
+ TimeStamp time;
+ REQUEST(xSetSelectionOwnerReq);
+
+ REQUEST_SIZE_MATCH(xSetSelectionOwnerReq);
+ UpdateCurrentTime();
+ time = ClientTimeToServerTime(stuff->time);
+
+ /* If the client's time stamp is in the future relative to the server's
+ time stamp, do not set the selection, just return success. */
+ if (CompareTimeStamps(time, currentTime) == LATER)
+ return Success;
+ if (stuff->window != None)
+ {
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ }
+ else
+ pWin = (WindowPtr)None;
+ if (ValidAtom(stuff->selection))
+ {
+ int i = 0;
+
+ /*
+ * First, see if the selection is already set...
+ */
+ while ((i < NumCurrentSelections) &&
+ CurrentSelections[i].selection != stuff->selection)
+ i++;
+ if (i < NumCurrentSelections)
+ {
+ xEvent event;
+
+ /* If the timestamp in client's request is in the past relative
+ to the time stamp indicating the last time the owner of the
+ selection was set, do not set the selection, just return
+ success. */
+ if (CompareTimeStamps(time, CurrentSelections[i].lastTimeChanged)
+ == EARLIER)
+ return Success;
+ if (CurrentSelections[i].client &&
+ (!pWin || (CurrentSelections[i].client != client)))
+ {
+ event.u.u.type = SelectionClear;
+ event.u.selectionClear.time = time.milliseconds;
+ event.u.selectionClear.window = CurrentSelections[i].window;
+ event.u.selectionClear.atom = CurrentSelections[i].selection;
+ (void) TryClientEvents (CurrentSelections[i].client, &event, 1,
+ NoEventMask, NoEventMask /* CantBeFiltered */,
+ NullGrab);
+ }
+ }
+ else
+ {
+ /*
+ * It doesn't exist, so add it...
+ */
+ Selection *newsels;
+
+ if (i == 0)
+ newsels = (Selection *)xalloc(sizeof(Selection));
+ else
+ newsels = (Selection *)xrealloc(CurrentSelections,
+ (NumCurrentSelections + 1) * sizeof(Selection));
+ if (!newsels)
+ return BadAlloc;
+ NumCurrentSelections++;
+ CurrentSelections = newsels;
+ CurrentSelections[i].selection = stuff->selection;
+ }
+ CurrentSelections[i].lastTimeChanged = time;
+ CurrentSelections[i].window = stuff->window;
+ CurrentSelections[i].pWin = pWin;
+ CurrentSelections[i].client = (pWin ? client : NullClient);
+ if (SelectionCallback)
+ {
+ SelectionInfoRec info;
+
+ info.selection = &CurrentSelections[i];
+ info.kind= SelectionSetOwner;
+ CallCallbacks(&SelectionCallback, &info);
+ }
+
+#ifdef NXAGENT_CLIPBOARD
+ if ((CurrentSelections[i].pWin != NULL) &&
+ (nxagentOption(Clipboard) != ClipboardNone) &&
+ ((CurrentSelections[i].selection == XA_PRIMARY) ||
+ (CurrentSelections[i].selection == MakeAtom("CLIPBOARD", 9, 0))))
+ {
+ nxagentSetSelectionOwner(&CurrentSelections[i]);
+ }
+#endif
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->selection;
+ return (BadAtom);
+ }
+}
+
+int
+ProcGetSelectionOwner(register ClientPtr client)
+{
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ if (ValidAtom(stuff->id))
+ {
+ int i;
+ xGetSelectionOwnerReply reply;
+
+ i = 0;
+ while ((i < NumCurrentSelections) &&
+ CurrentSelections[i].selection != stuff->id) i++;
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ if (i < NumCurrentSelections)
+ reply.owner = CurrentSelections[i].window;
+ else
+ reply.owner = None;
+ WriteReplyToClient(client, sizeof(xGetSelectionOwnerReply), &reply);
+ return(client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadAtom);
+ }
+}
+
+int
+ProcConvertSelection(register ClientPtr client)
+{
+ Bool paramsOkay;
+ xEvent event;
+ WindowPtr pWin;
+ REQUEST(xConvertSelectionReq);
+
+ REQUEST_SIZE_MATCH(xConvertSelectionReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->requestor, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+
+#ifdef NXAGENT_CLIPBOARD
+ if (((stuff->selection == XA_PRIMARY) ||
+ (stuff->selection == MakeAtom("CLIPBOARD", 9, 0))) &&
+ nxagentOption(Clipboard) != ClipboardNone)
+ {
+ int i = 0;
+
+ while ((i < NumCurrentSelections) &&
+ CurrentSelections[i].selection != stuff->selection) i++;
+
+ if ((i < NumCurrentSelections) && (CurrentSelections[i].window != None))
+ {
+ if (nxagentConvertSelection(client, pWin, stuff->selection, stuff->requestor,
+ stuff->property, stuff->target, stuff->time))
+ {
+ return (client->noClientException);
+ }
+ }
+ }
+#endif
+
+ paramsOkay = (ValidAtom(stuff->selection) && ValidAtom(stuff->target));
+ if (stuff->property != None)
+ paramsOkay &= ValidAtom(stuff->property);
+ if (paramsOkay)
+ {
+ int i;
+
+ i = 0;
+ while ((i < NumCurrentSelections) &&
+ CurrentSelections[i].selection != stuff->selection) i++;
+ if ((i < NumCurrentSelections) &&
+ (CurrentSelections[i].window != None) && (CurrentSelections[i].client != NullClient)
+#ifdef XCSECURITY
+ && (!client->CheckAccess ||
+ (* client->CheckAccess)(client, CurrentSelections[i].window,
+ RT_WINDOW, SecurityReadAccess,
+ CurrentSelections[i].pWin))
+#endif
+ )
+ {
+ event.u.u.type = SelectionRequest;
+ event.u.selectionRequest.time = stuff->time;
+ event.u.selectionRequest.owner =
+ CurrentSelections[i].window;
+ event.u.selectionRequest.requestor = stuff->requestor;
+ event.u.selectionRequest.selection = stuff->selection;
+ event.u.selectionRequest.target = stuff->target;
+ event.u.selectionRequest.property = stuff->property;
+ if (TryClientEvents(
+ CurrentSelections[i].client, &event, 1, NoEventMask,
+ NoEventMask /* CantBeFiltered */, NullGrab))
+ return (client->noClientException);
+ }
+ event.u.u.type = SelectionNotify;
+ event.u.selectionNotify.time = stuff->time;
+ event.u.selectionNotify.requestor = stuff->requestor;
+ event.u.selectionNotify.selection = stuff->selection;
+ event.u.selectionNotify.target = stuff->target;
+ event.u.selectionNotify.property = None;
+ (void) TryClientEvents(client, &event, 1, NoEventMask,
+ NoEventMask /* CantBeFiltered */, NullGrab);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->property;
+ return (BadAtom);
+ }
+}
+
+int
+ProcGrabServer(register ClientPtr client)
+{
+ REQUEST_SIZE_MATCH(xReq);
+ if (grabState != GrabNone && client != grabClient)
+ {
+ ResetCurrentRequest(client);
+ client->sequence--;
+ BITSET(grabWaiters, client->index);
+ IgnoreClient(client);
+ return(client->noClientException);
+ }
+ OnlyListenToOneClient(client);
+ grabState = GrabKickout;
+ grabClient = client;
+
+ if (ServerGrabCallback)
+ {
+ ServerGrabInfoRec grabinfo;
+ grabinfo.client = client;
+ grabinfo.grabstate = SERVER_GRABBED;
+ CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
+ }
+
+ return(client->noClientException);
+}
+
+static void
+UngrabServer(ClientPtr client)
+{
+ int i;
+
+ grabState = GrabNone;
+ ListenToAllClients();
+ for (i = mskcnt; --i >= 0 && !grabWaiters[i]; )
+ ;
+ if (i >= 0)
+ {
+ i <<= 5;
+ while (!GETBIT(grabWaiters, i))
+ i++;
+ BITCLEAR(grabWaiters, i);
+ AttendClient(clients[i]);
+ }
+
+ if (ServerGrabCallback)
+ {
+ ServerGrabInfoRec grabinfo;
+ grabinfo.client = client;
+ grabinfo.grabstate = SERVER_UNGRABBED;
+ CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
+ }
+}
+
+int
+ProcUngrabServer(register ClientPtr client)
+{
+ REQUEST_SIZE_MATCH(xReq);
+ UngrabServer(client);
+ return(client->noClientException);
+}
+
+int
+ProcTranslateCoords(register ClientPtr client)
+{
+ REQUEST(xTranslateCoordsReq);
+
+ register WindowPtr pWin, pDst;
+ xTranslateCoordsReply rep;
+
+ REQUEST_SIZE_MATCH(xTranslateCoordsReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->srcWid, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ pDst = (WindowPtr)SecurityLookupWindow(stuff->dstWid, client,
+ SecurityReadAccess);
+ if (!pDst)
+ return(BadWindow);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ if (!SAME_SCREENS(pWin->drawable, pDst->drawable))
+ {
+ rep.sameScreen = xFalse;
+ rep.child = None;
+ rep.dstX = rep.dstY = 0;
+ }
+ else
+ {
+ INT16 x, y;
+ rep.sameScreen = xTrue;
+ rep.child = None;
+ /* computing absolute coordinates -- adjust to destination later */
+ x = pWin->drawable.x + stuff->srcX;
+ y = pWin->drawable.y + stuff->srcY;
+ pWin = pDst->firstChild;
+ while (pWin)
+ {
+#ifdef SHAPE
+ BoxRec box;
+#endif
+ 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))
+#ifdef SHAPE
+ /* When a window is shaped, a further check
+ * is made to see if the point is inside
+ * borderSize
+ */
+ && (!wBoundingShape(pWin) ||
+ POINT_IN_REGION(pWin->drawable.pScreen,
+ &pWin->borderSize, x, y, &box))
+
+ && (!wInputShape(pWin) ||
+ POINT_IN_REGION(pWin->drawable.pScreen,
+ wInputShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box))
+#endif
+ )
+ {
+ rep.child = pWin->drawable.id;
+ pWin = (WindowPtr) NULL;
+ }
+ else
+ pWin = pWin->nextSib;
+ }
+ /* adjust to destination coordinates */
+ rep.dstX = x - pDst->drawable.x;
+ rep.dstY = y - pDst->drawable.y;
+ }
+ WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep);
+ return(client->noClientException);
+}
+
+int
+ProcOpenFont(register ClientPtr client)
+{
+ int err;
+ char fontReq[256];
+ REQUEST(xOpenFontReq);
+
+ REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes);
+ client->errorValue = stuff->fid;
+ LEGAL_NEW_RESOURCE(stuff->fid, client);
+
+ memcpy(fontReq,(char *)&stuff[1],(stuff->nbytes<256)?stuff->nbytes:255);
+ fontReq[stuff->nbytes]=0;
+ if (strchr(fontReq,'*') || strchr(fontReq,'?'))
+ {
+ extern int nxOpenFont(ClientPtr, XID, Mask, unsigned, char*);
+#ifdef NXAGENT_FONTMATCH_DEBUG
+ fprintf(stderr, "Dispatch: ProcOpenFont try to find a common font with font pattern=%s\n",fontReq);
+#endif
+ nxagentListRemoteFonts(fontReq, nxagentMaxFontNames);
+ err = nxOpenFont(client, stuff->fid, (Mask) 0,
+ stuff->nbytes, (char *)&stuff[1]);
+ }
+ else
+ err = OpenFont(client, stuff->fid, (Mask) 0,
+ stuff->nbytes, (char *)&stuff[1]);
+ if (err == Success)
+ {
+ return(client->noClientException);
+ }
+ else
+ return err;
+}
+
+int
+ProcCloseFont(register ClientPtr client)
+{
+ FontPtr pFont;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
+ SecurityDestroyAccess);
+ if (pFont != (FontPtr)NULL)
+ {
+ #ifdef NXAGENT_SERVER
+
+ /*
+ * When a client closes a font the resource
+ * should not be lost if the reference counter
+ * is not 0, otherwise the server will not be
+ * able to find this font looping through the
+ * resources.
+ */
+
+ if (pFont -> refcnt > 0)
+ {
+ if (nxagentFindClientResource(serverClient -> index, RT_NX_FONT, pFont) == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "ProcCloseFont: Switching resource for font at [%p].\n",
+ (void *) pFont);
+ #endif
+
+ nxagentFontPriv(pFont) -> mirrorID = FakeClientID(serverClient -> index);
+
+ AddResource(nxagentFontPriv(pFont) -> mirrorID, RT_NX_FONT, pFont);
+
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "ProcCloseFont: Found duplicated font at [%p], "
+ "resource switching skipped.\n", (void *) pFont);
+ }
+ #endif
+ }
+
+ #endif
+
+ FreeResource(stuff->id, RT_NONE);
+ return(client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadFont);
+ }
+}
+
+int
+ProcQueryFont(register ClientPtr client)
+{
+ xQueryFontReply *reply;
+ FontPtr pFont;
+ register GC *pGC;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ client->errorValue = stuff->id; /* EITHER font or gc */
+
+ pFont = NULL;
+ pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
+ SecurityReadAccess);
+ if (!pFont)
+ {
+ /* can't use VERIFY_GC because it might return BadGC */
+ pGC = (GC *) SecurityLookupIDByType(client, stuff->id, RT_GC,
+ SecurityReadAccess);
+ if (!pGC)
+ {
+ client->errorValue = stuff->id;
+ return(BadFont); /* procotol spec says only error is BadFont */
+ }
+ pFont = pGC->font;
+ }
+
+/* test
+{
+ Atom name_atom, value_atom;
+ int nprops;
+ FontPropPtr props;
+ int i;
+ char *name;
+
+ name_atom = MakeAtom("FONT", 4, True);
+ value_atom = 0L;
+
+ nprops = pFont->info.nprops;
+ props = pFont->info.props;
+
+ for (i = 0; i < nprops; i++)
+ if (props[i].name == name_atom) {
+ value_atom = props[i].value;
+ break;
+ }
+
+ if (!value_atom) return (BadFont);
+
+ name = (char *)NameForAtom(value_atom);
+ fprintf(stderr, "QueryFont: font name [%s]\n",name);
+}
+ end test */
+
+ {
+ xCharInfo *pmax = FONTINKMAX(pFont);
+ xCharInfo *pmin = FONTINKMIN(pFont);
+ int nprotoxcistructs;
+ int rlength;
+
+ nprotoxcistructs = (
+ pmax->rightSideBearing == pmin->rightSideBearing &&
+ pmax->leftSideBearing == pmin->leftSideBearing &&
+ pmax->descent == pmin->descent &&
+ pmax->ascent == pmin->ascent &&
+ pmax->characterWidth == pmin->characterWidth) ?
+ 0 : N2dChars(pFont);
+
+ rlength = sizeof(xQueryFontReply) +
+ FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp) +
+ nprotoxcistructs * sizeof(xCharInfo);
+ reply = NULL;
+ reply = (xQueryFontReply *)ALLOCATE_LOCAL(rlength);
+ if(!reply)
+ {
+ return(BadAlloc);
+ }
+
+ reply->type = X_Reply;
+ reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+ reply->sequenceNumber = client->sequence;
+ QueryFont( pFont, reply, nprotoxcistructs);
+
+ WriteReplyToClient(client, rlength, reply);
+ DEALLOCATE_LOCAL(reply);
+ return(client->noClientException);
+ }
+}
+
+int
+ProcQueryTextExtents(register ClientPtr client)
+{
+ REQUEST(xQueryTextExtentsReq);
+ xQueryTextExtentsReply reply;
+ FontPtr pFont;
+ GC *pGC;
+ ExtentInfoRec info;
+ unsigned long length;
+
+ REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq);
+
+ pFont = (FontPtr)SecurityLookupIDByType(client, stuff->fid, RT_FONT,
+ SecurityReadAccess);
+ if (!pFont)
+ {
+ pGC = (GC *)SecurityLookupIDByType(client, stuff->fid, RT_GC,
+ SecurityReadAccess);
+ if (!pGC)
+ {
+ client->errorValue = stuff->fid;
+ return(BadFont);
+ }
+ pFont = pGC->font;
+ }
+ length = client->req_len - (sizeof(xQueryTextExtentsReq) >> 2);
+ length = length << 1;
+ if (stuff->oddLength)
+ {
+ if (length == 0)
+ return(BadLength);
+ length--;
+ }
+ if (!QueryTextExtents(pFont, length, (unsigned char *)&stuff[1], &info))
+ return(BadAlloc);
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ reply.drawDirection = info.drawDirection;
+ reply.fontAscent = info.fontAscent;
+ reply.fontDescent = info.fontDescent;
+ reply.overallAscent = info.overallAscent;
+ reply.overallDescent = info.overallDescent;
+ reply.overallWidth = info.overallWidth;
+ reply.overallLeft = info.overallLeft;
+ reply.overallRight = info.overallRight;
+ WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply);
+ return(client->noClientException);
+}
+
+int
+ProcListFonts(register ClientPtr client)
+{
+ char tmp[256];
+
+ REQUEST(xListFontsReq);
+
+ REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes);
+ memcpy(tmp,(unsigned char *) &stuff[1],(stuff->nbytes<256)?stuff->nbytes:255);
+ tmp[stuff->nbytes]=0;
+
+#ifdef NXAGENT_FONTMATCH_DEBUG
+ fprintf(stderr, "Dispatch: ListFont request with pattern %s max_names=%d\n",tmp,stuff->maxNames);
+#endif
+ nxagentListRemoteFonts(tmp, stuff -> maxNames < nxagentMaxFontNames ? nxagentMaxFontNames : stuff->maxNames);
+ return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes,
+ stuff->maxNames);
+}
+
+int
+ProcListFontsWithInfo(register ClientPtr client)
+{
+ char tmp[256];
+ REQUEST(xListFontsWithInfoReq);
+
+ REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes);
+
+ memcpy(tmp,(unsigned char *) &stuff[1],(stuff->nbytes<256)?stuff->nbytes:255);
+ tmp[stuff->nbytes]=0;
+#ifdef NXAGENT_FONTMATCH_DEBUG
+ fprintf(stderr, "Dispatch: ListFont with info request with pattern %s max_names=%d\n",tmp,stuff->maxNames);
+#endif
+ nxagentListRemoteFonts(tmp, stuff -> maxNames < nxagentMaxFontNames ? nxagentMaxFontNames :stuff->maxNames);
+
+ return StartListFontsWithInfo(client, stuff->nbytes,
+ (unsigned char *) &stuff[1], stuff->maxNames);
+}
+
+/**
+ *
+ * \param value must conform to DeleteType
+ */
+int
+dixDestroyPixmap(pointer value, XID pid)
+{
+ PixmapPtr pPixmap = (PixmapPtr)value;
+ return (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
+}
+
+int
+ProcCreatePixmap(register ClientPtr client)
+{
+ PixmapPtr pMap;
+ register DrawablePtr pDraw;
+ REQUEST(xCreatePixmapReq);
+ DepthPtr pDepth;
+ register int i;
+
+ REQUEST_SIZE_MATCH(xCreatePixmapReq);
+ client->errorValue = stuff->pid;
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+ SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->drawable, client,
+ SecurityReadAccess);
+ if (!stuff->width || !stuff->height)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ if (stuff->width > 32767 || stuff->height > 32767)
+ {
+ /* It is allowed to try and allocate a pixmap which is larger than
+ * 32767 in either dimension. However, all of the framebuffer code
+ * is buggy and does not reliably draw to such big pixmaps, basically
+ * because the Region data structure operates with signed shorts
+ * for the rectangles in it.
+ *
+ * Furthermore, several places in the X server computes the
+ * size in bytes of the pixmap and tries to store it in an
+ * integer. This integer can overflow and cause the allocated size
+ * to be much smaller.
+ *
+ * So, such big pixmaps are rejected here with a BadAlloc
+ */
+ 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:
+ pMap = (PixmapPtr)(*pDraw->pScreen->CreatePixmap)
+ (pDraw->pScreen, stuff->width,
+ stuff->height, stuff->depth);
+ if (pMap)
+ {
+ pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pMap->drawable.id = stuff->pid;
+ if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
+ return(client->noClientException);
+ }
+ return (BadAlloc);
+}
+
+int
+ProcFreePixmap(register ClientPtr client)
+{
+ PixmapPtr pMap;
+
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pMap = (PixmapPtr)SecurityLookupIDByType(client, stuff->id, RT_PIXMAP,
+ SecurityDestroyAccess);
+ if (pMap)
+ {
+ #ifdef NXAGENT_SERVER
+
+ /*
+ * When a client releases a pixmap the resource
+ * should not be lost if the reference counter
+ * is not 0, otherwise the server will not be
+ * able to find this pixmap looping through the
+ * resources.
+ */
+
+ if (pMap -> refcnt > 0)
+ {
+ if (nxagentFindClientResource(serverClient -> index, RT_NX_PIXMAP, pMap) == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "ProcFreePixmap: Switching resource for pixmap at [%p].\n",
+ (void *) pMap);
+ #endif
+
+ nxagentPixmapPriv(pMap) -> mid = FakeClientID(serverClient -> index);
+
+ AddResource(nxagentPixmapPriv(pMap) -> mid, RT_NX_PIXMAP, pMap);
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "ProcFreePixmap: Found duplicated pixmap at [%p], "
+ "resource switching skipped.\n", (void *) pMap);
+ }
+ #endif
+ }
+
+ #endif
+
+ FreeResource(stuff->id, RT_NONE);
+ return(client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadPixmap);
+ }
+}
+
+int
+ProcCreateGC(register ClientPtr client)
+{
+ int error;
+ GC *pGC;
+ register DrawablePtr pDraw;
+ unsigned len;
+ REQUEST(xCreateGCReq);
+
+ REQUEST_AT_LEAST_SIZE(xCreateGCReq);
+ client->errorValue = stuff->gc;
+ LEGAL_NEW_RESOURCE(stuff->gc, client);
+ SECURITY_VERIFY_DRAWABLE (pDraw, stuff->drawable, client,
+ SecurityReadAccess);
+ len = client->req_len - (sizeof(xCreateGCReq) >> 2);
+ if (len != Ones(stuff->mask))
+ return BadLength;
+ pGC = (GC *)CreateGC(pDraw, stuff->mask,
+ (XID *) &stuff[1], &error);
+ if (error != Success)
+ return error;
+ if (!AddResource(stuff->gc, RT_GC, (pointer)pGC))
+ return (BadAlloc);
+ return(client->noClientException);
+}
+
+int
+ProcChangeGC(register ClientPtr client)
+{
+ GC *pGC;
+ REQUEST(xChangeGCReq);
+ int result;
+ unsigned len;
+
+ REQUEST_AT_LEAST_SIZE(xChangeGCReq);
+ SECURITY_VERIFY_GC(pGC, stuff->gc, client, SecurityWriteAccess);
+ len = client->req_len - (sizeof(xChangeGCReq) >> 2);
+ if (len != Ones(stuff->mask))
+ return BadLength;
+
+ result = dixChangeGC(client, pGC, stuff->mask, (CARD32 *) &stuff[1], 0);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return(result);
+ }
+}
+
+int
+ProcCopyGC(register ClientPtr client)
+{
+ register GC *dstGC;
+ register GC *pGC;
+ int result;
+ REQUEST(xCopyGCReq);
+
+ REQUEST_SIZE_MATCH(xCopyGCReq);
+ SECURITY_VERIFY_GC( pGC, stuff->srcGC, client, SecurityReadAccess);
+ SECURITY_VERIFY_GC( dstGC, stuff->dstGC, client, SecurityWriteAccess);
+ if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth))
+ return (BadMatch);
+ result = CopyGC(pGC, dstGC, stuff->mask);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return(result);
+ }
+}
+
+int
+ProcSetDashes(register ClientPtr client)
+{
+ register GC *pGC;
+ int result;
+ REQUEST(xSetDashesReq);
+
+ REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
+ if (stuff->nDashes == 0)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+
+ SECURITY_VERIFY_GC(pGC,stuff->gc, client, SecurityWriteAccess);
+
+ result = SetDashes(pGC, stuff->dashOffset, stuff->nDashes,
+ (unsigned char *)&stuff[1]);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return(result);
+ }
+}
+
+int
+ProcSetClipRectangles(register ClientPtr client)
+{
+ int nr;
+ int result;
+ register GC *pGC;
+ REQUEST(xSetClipRectanglesReq);
+
+ REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
+ if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
+ (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded))
+ {
+ client->errorValue = stuff->ordering;
+ return BadValue;
+ }
+ SECURITY_VERIFY_GC(pGC,stuff->gc, client, SecurityWriteAccess);
+
+ nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq);
+ if (nr & 4)
+ return(BadLength);
+ nr >>= 3;
+ result = SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin,
+ nr, (xRectangle *)&stuff[1], (int)stuff->ordering);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+int
+ProcFreeGC(register ClientPtr client)
+{
+ register GC *pGC;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ SECURITY_VERIFY_GC(pGC, stuff->id, client, SecurityDestroyAccess);
+ FreeResource(stuff->id, RT_NONE);
+ return(client->noClientException);
+}
+
+int
+ProcClearToBackground(register ClientPtr client)
+{
+ REQUEST(xClearAreaReq);
+ register WindowPtr pWin;
+
+ REQUEST_SIZE_MATCH(xClearAreaReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (pWin->drawable.class == InputOnly)
+ {
+ client->errorValue = stuff->window;
+ return (BadMatch);
+ }
+ if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse))
+ {
+ client->errorValue = stuff->exposures;
+ return(BadValue);
+ }
+ (*pWin->drawable.pScreen->ClearToBackground)(pWin, stuff->x, stuff->y,
+ stuff->width, stuff->height,
+ (Bool)stuff->exposures);
+ return(client->noClientException);
+}
+
+int
+ProcCopyArea(register ClientPtr client)
+{
+ register DrawablePtr pDst;
+ register DrawablePtr pSrc;
+ register GC *pGC;
+ REQUEST(xCopyAreaReq);
+ RegionPtr pRgn;
+
+ REQUEST_SIZE_MATCH(xCopyAreaReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, pGC, client);
+ if (stuff->dstDrawable != stuff->srcDrawable)
+ {
+ SECURITY_VERIFY_DRAWABLE(pSrc, stuff->srcDrawable, client,
+ SecurityReadAccess);
+ if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth))
+ {
+ client->errorValue = stuff->dstDrawable;
+ return (BadMatch);
+ }
+ }
+ else
+ pSrc = pDst;
+
+ SET_DBE_SRCBUF(pSrc, stuff->srcDrawable);
+
+ pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, stuff->srcX, stuff->srcY,
+ stuff->width, stuff->height,
+ stuff->dstX, stuff->dstY);
+ if (pGC->graphicsExposures)
+ {
+ (*pDst->pScreen->SendGraphicsExpose)
+ (client, pRgn, stuff->dstDrawable, X_CopyArea, 0);
+ if (pRgn)
+ REGION_DESTROY(pDst->pScreen, pRgn);
+ }
+
+ return(client->noClientException);
+}
+
+int
+ProcCopyPlane(register ClientPtr client)
+{
+ register DrawablePtr psrcDraw, pdstDraw;
+ register GC *pGC;
+ REQUEST(xCopyPlaneReq);
+ RegionPtr pRgn;
+
+ REQUEST_SIZE_MATCH(xCopyPlaneReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, pGC, client);
+ if (stuff->dstDrawable != stuff->srcDrawable)
+ {
+ SECURITY_VERIFY_DRAWABLE(psrcDraw, stuff->srcDrawable, client,
+ SecurityReadAccess);
+ if (pdstDraw->pScreen != psrcDraw->pScreen)
+ {
+ client->errorValue = stuff->dstDrawable;
+ return (BadMatch);
+ }
+ }
+ else
+ psrcDraw = pdstDraw;
+
+ SET_DBE_SRCBUF(psrcDraw, stuff->srcDrawable);
+
+ /* Check to see if stuff->bitPlane has exactly ONE good bit set */
+ 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)
+ {
+ (*pdstDraw->pScreen->SendGraphicsExpose)
+ (client, pRgn, stuff->dstDrawable, X_CopyPlane, 0);
+ if (pRgn)
+ REGION_DESTROY(pdstDraw->pScreen, pRgn);
+ }
+ return(client->noClientException);
+}
+
+int
+ProcPolyPoint(register ClientPtr client)
+{
+ int npoint;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyPointReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyPointReq);
+ if ((stuff->coordMode != CoordModeOrigin) &&
+ (stuff->coordMode != CoordModePrevious))
+ {
+ client->errorValue = stuff->coordMode;
+ return BadValue;
+ }
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ npoint = ((client->req_len << 2) - sizeof(xPolyPointReq)) >> 2;
+ if (npoint)
+ {
+ (*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint,
+ (xPoint *) &stuff[1]);
+ }
+ return (client->noClientException);
+}
+
+int
+ProcPolyLine(register ClientPtr client)
+{
+ int npoint;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyLineReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyLineReq);
+ if ((stuff->coordMode != CoordModeOrigin) &&
+ (stuff->coordMode != CoordModePrevious))
+ {
+ client->errorValue = stuff->coordMode;
+ return BadValue;
+ }
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ npoint = ((client->req_len << 2) - sizeof(xPolyLineReq)) >> 2;
+ if (npoint > 1)
+ {
+ (*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint,
+ (DDXPointPtr) &stuff[1]);
+ }
+ return(client->noClientException);
+}
+
+int
+ProcPolySegment(register ClientPtr client)
+{
+ int nsegs;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolySegmentReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
+ if (nsegs & 4)
+ return(BadLength);
+ nsegs >>= 3;
+ if (nsegs)
+ {
+ (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]);
+ }
+ return (client->noClientException);
+}
+
+int
+ProcPolyRectangle (register ClientPtr client)
+{
+ int nrects;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyRectangleReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
+ if (nrects & 4)
+ return(BadLength);
+ nrects >>= 3;
+ if (nrects)
+ {
+ (*pGC->ops->PolyRectangle)(pDraw, pGC,
+ nrects, (xRectangle *) &stuff[1]);
+ }
+ return(client->noClientException);
+}
+
+int
+ProcPolyArc(register ClientPtr client)
+{
+ int narcs;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyArcReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyArcReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
+ if (narcs % sizeof(xArc))
+ return(BadLength);
+ narcs /= sizeof(xArc);
+ if (narcs)
+ {
+ (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]);
+ }
+ return (client->noClientException);
+}
+
+int
+ProcFillPoly(register ClientPtr client)
+{
+ int things;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xFillPolyReq);
+
+ REQUEST_AT_LEAST_SIZE(xFillPolyReq);
+ if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) &&
+ (stuff->shape != Convex))
+ {
+ client->errorValue = stuff->shape;
+ return BadValue;
+ }
+ if ((stuff->coordMode != CoordModeOrigin) &&
+ (stuff->coordMode != CoordModePrevious))
+ {
+ client->errorValue = stuff->coordMode;
+ return BadValue;
+ }
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ things = ((client->req_len << 2) - sizeof(xFillPolyReq)) >> 2;
+ if (things)
+ {
+ (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape,
+ stuff->coordMode, things,
+ (DDXPointPtr) &stuff[1]);
+ }
+ return(client->noClientException);
+}
+
+int
+ProcPolyFillRectangle(register ClientPtr client)
+{
+ int things;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyFillRectangleReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
+ if (things & 4)
+ return(BadLength);
+ things >>= 3;
+
+ if (things)
+ {
+ (*pGC->ops->PolyFillRect) (pDraw, pGC, things,
+ (xRectangle *) &stuff[1]);
+ }
+ return (client->noClientException);
+}
+
+int
+ProcPolyFillArc(register ClientPtr client)
+{
+ int narcs;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyFillArcReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
+ if (narcs % sizeof(xArc))
+ return(BadLength);
+ narcs /= sizeof(xArc);
+ if (narcs)
+ {
+ (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
+ }
+ return (client->noClientException);
+}
+
+#ifdef MATCH_CLIENT_ENDIAN
+
+int
+ServerOrder (void)
+{
+ int whichbyte = 1;
+
+ if (*((char *) &whichbyte))
+ return LSBFirst;
+ return MSBFirst;
+}
+
+#define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder())
+
+void
+ReformatImage (char *base, int nbytes, int bpp, int order)
+{
+ switch (bpp) {
+ case 1: /* yuck */
+ if (BITMAP_BIT_ORDER != order)
+ BitOrderInvert ((unsigned char *) base, nbytes);
+#if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8
+ ReformatImage (base, nbytes, BITMAP_SCANLINE_UNIT, order);
+#endif
+ break;
+ case 4:
+ break; /* yuck */
+ case 8:
+ break;
+ case 16:
+ if (IMAGE_BYTE_ORDER != order)
+ TwoByteSwap ((unsigned char *) base, nbytes);
+ break;
+ case 32:
+ if (IMAGE_BYTE_ORDER != order)
+ FourByteSwap ((unsigned char *) base, nbytes);
+ break;
+ }
+}
+#else
+#define ReformatImage(b,n,bpp,o)
+#endif
+
+/* 64-bit server notes: the protocol restricts padding of images to
+ * 8-, 16-, or 32-bits. We would like to have 64-bits for the server
+ * to use internally. Removes need for internal alignment checking.
+ * All of the PutImage functions could be changed individually, but
+ * as currently written, they call other routines which require things
+ * to be 64-bit padded on scanlines, so we changed things here.
+ * If an image would be padded differently for 64- versus 32-, then
+ * copy each scanline to a 64-bit padded scanline.
+ * Also, we need to make sure that the image is aligned on a 64-bit
+ * boundary, even if the scanlines are padded to our satisfaction.
+ */
+int
+ProcPutImage(register ClientPtr client)
+{
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ long length; /* length of scanline server padded */
+ long lengthProto; /* length of scanline protocol padded */
+ char *tmpImage;
+ REQUEST(xPutImageReq);
+
+ REQUEST_AT_LEAST_SIZE(xPutImageReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ if (stuff->format == XYBitmap)
+ {
+ if ((stuff->depth != 1) ||
+ (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
+ return BadMatch;
+ length = BitmapBytePad(stuff->width + stuff->leftPad);
+ }
+ else if (stuff->format == XYPixmap)
+ {
+ if ((pDraw->depth != stuff->depth) ||
+ (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
+ return BadMatch;
+ length = BitmapBytePad(stuff->width + stuff->leftPad);
+ length *= stuff->depth;
+ }
+ else if (stuff->format == ZPixmap)
+ {
+ if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0))
+ return BadMatch;
+ length = PixmapBytePad(stuff->width, stuff->depth);
+ }
+ else
+ {
+ client->errorValue = stuff->format;
+ return BadValue;
+ }
+
+ tmpImage = (char *)&stuff[1];
+ lengthProto = length;
+
+ if (((((lengthProto * stuff->height) + (unsigned)3) >> 2) +
+ (sizeof(xPutImageReq) >> 2)) != client->req_len)
+ return BadLength;
+
+ ReformatImage (tmpImage, lengthProto * stuff->height,
+ stuff->format == ZPixmap ? BitsPerPixel (stuff->depth) : 1,
+ ClientOrder(client));
+
+ (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY,
+ stuff->width, stuff->height,
+ stuff->leftPad, stuff->format, tmpImage);
+
+ return (client->noClientException);
+}
+
+
+int
+DoGetImage(register ClientPtr client, int format, Drawable drawable,
+ int x, int y, int width, int height,
+ Mask planemask, xGetImageReply **im_return)
+{
+ register DrawablePtr pDraw;
+ int nlines, linesPerBuf;
+ register int linesDone;
+ long widthBytesLine, length;
+ Mask plane = 0;
+ char *pBuf;
+ xGetImageReply xgi;
+#ifdef XCSECURITY
+ RegionPtr pVisibleRegion = NULL;
+#endif
+
+ if ((format != XYPixmap) && (format != ZPixmap))
+ {
+ client->errorValue = format;
+ return(BadValue);
+ }
+ SECURITY_VERIFY_DRAWABLE(pDraw, drawable, client, SecurityReadAccess);
+ if(pDraw->type == DRAWABLE_WINDOW)
+ {
+ if( /* check for being viewable */
+ !((WindowPtr) pDraw)->realized ||
+ /* check for being on screen */
+ pDraw->x + x < 0 ||
+ pDraw->x + x + width > pDraw->pScreen->width ||
+ pDraw->y + y < 0 ||
+ pDraw->y + y + height > pDraw->pScreen->height ||
+ /* check for being inside of border */
+ x < - wBorderWidth((WindowPtr)pDraw) ||
+ x + width > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+ y < -wBorderWidth((WindowPtr)pDraw) ||
+ y + height > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height
+ )
+ return(BadMatch);
+ xgi.visual = wVisual (((WindowPtr) pDraw));
+ }
+ else
+ {
+ if(x < 0 ||
+ x+width > (int)pDraw->width ||
+ y < 0 ||
+ y+height > (int)pDraw->height
+ )
+ return(BadMatch);
+ xgi.visual = None;
+ }
+
+ SET_DBE_SRCBUF(pDraw, drawable);
+
+ xgi.type = X_Reply;
+ xgi.sequenceNumber = client->sequence;
+ xgi.depth = pDraw->depth;
+ if(format == ZPixmap)
+ {
+ widthBytesLine = PixmapBytePad(width, pDraw->depth);
+ length = widthBytesLine * height;
+
+ }
+ else
+ {
+ widthBytesLine = BitmapBytePad(width);
+ plane = ((Mask)1) << (pDraw->depth - 1);
+ /* only planes asked for */
+ length = widthBytesLine * height *
+ Ones(planemask & (plane | (plane - 1)));
+
+ }
+
+ xgi.length = length;
+
+ if (im_return) {
+ pBuf = (char *)xalloc(sz_xGetImageReply + length);
+ if (!pBuf)
+ return (BadAlloc);
+ if (widthBytesLine == 0)
+ linesPerBuf = 0;
+ else
+ linesPerBuf = height;
+ *im_return = (xGetImageReply *)pBuf;
+ *(xGetImageReply *)pBuf = xgi;
+ pBuf += sz_xGetImageReply;
+ } else {
+ xgi.length = (xgi.length + 3) >> 2;
+ if (widthBytesLine == 0 || height == 0)
+ linesPerBuf = 0;
+ else if (widthBytesLine >= IMAGE_BUFSIZE)
+ linesPerBuf = 1;
+ else
+ {
+ linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
+ if (linesPerBuf > height)
+ linesPerBuf = height;
+ }
+ length = linesPerBuf * widthBytesLine;
+ if (linesPerBuf < height)
+ {
+ /* we have to make sure intermediate buffers don't need padding */
+ while ((linesPerBuf > 1) &&
+ (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1)))
+ {
+ linesPerBuf--;
+ length -= widthBytesLine;
+ }
+ while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))
+ {
+ linesPerBuf++;
+ length += widthBytesLine;
+ }
+ }
+ if(!(pBuf = (char *) ALLOCATE_LOCAL(length)))
+ return (BadAlloc);
+ WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
+ }
+
+#ifdef XCSECURITY
+ if (client->trustLevel != XSecurityClientTrusted &&
+ pDraw->type == DRAWABLE_WINDOW)
+ {
+ pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw);
+ if (pVisibleRegion)
+ {
+ REGION_TRANSLATE(pDraw->pScreen, pVisibleRegion, -pDraw->x, -pDraw->y);
+ }
+ }
+#endif
+
+ if (linesPerBuf == 0)
+ {
+ /* nothing to do */
+ }
+ else if (format == ZPixmap)
+ {
+ linesDone = 0;
+ while (height - linesDone > 0)
+ {
+ nlines = min(linesPerBuf, height - linesDone);
+ (*pDraw->pScreen->GetImage) (pDraw,
+ x,
+ y + linesDone,
+ width,
+ nlines,
+ format,
+ planemask,
+ (pointer) pBuf);
+#ifdef XCSECURITY
+ if (pVisibleRegion)
+ SecurityCensorImage(client, pVisibleRegion, widthBytesLine,
+ pDraw, x, y + linesDone, width,
+ nlines, format, pBuf);
+#endif
+
+ /* Note that this is NOT a call to WriteSwappedDataToClient,
+ as we do NOT byte swap */
+ if (!im_return)
+ {
+ ReformatImage (pBuf, (int)(nlines * widthBytesLine),
+ BitsPerPixel (pDraw->depth),
+ ClientOrder(client));
+
+/* Don't split me, gcc pukes when you do */
+ (void)WriteToClient(client,
+ (int)(nlines * widthBytesLine),
+ pBuf);
+ }
+ linesDone += nlines;
+ }
+ }
+ else /* XYPixmap */
+ {
+ for (; plane; plane >>= 1)
+ {
+ if (planemask & plane)
+ {
+ linesDone = 0;
+ while (height - linesDone > 0)
+ {
+ nlines = min(linesPerBuf, height - linesDone);
+ (*pDraw->pScreen->GetImage) (pDraw,
+ x,
+ y + linesDone,
+ width,
+ nlines,
+ format,
+ plane,
+ (pointer)pBuf);
+#ifdef XCSECURITY
+ if (pVisibleRegion)
+ SecurityCensorImage(client, pVisibleRegion,
+ widthBytesLine,
+ pDraw, x, y + linesDone, width,
+ nlines, format, pBuf);
+#endif
+
+ /* Note: NOT a call to WriteSwappedDataToClient,
+ as we do NOT byte swap */
+ if (im_return) {
+ pBuf += nlines * widthBytesLine;
+ } else {
+ ReformatImage (pBuf,
+ (int)(nlines * widthBytesLine),
+ 1,
+ ClientOrder (client));
+
+/* Don't split me, gcc pukes when you do */
+ (void)WriteToClient(client,
+ (int)(nlines * widthBytesLine),
+ pBuf);
+ }
+ linesDone += nlines;
+ }
+ }
+ }
+ }
+#ifdef XCSECURITY
+ if (pVisibleRegion)
+ REGION_DESTROY(pDraw->pScreen, pVisibleRegion);
+#endif
+ if (!im_return)
+ DEALLOCATE_LOCAL(pBuf);
+ return (client->noClientException);
+}
+
+int
+ProcGetImage(register ClientPtr client)
+{
+ REQUEST(xGetImageReq);
+
+ REQUEST_SIZE_MATCH(xGetImageReq);
+
+ return DoGetImage(client, stuff->format, stuff->drawable,
+ stuff->x, stuff->y,
+ (int)stuff->width, (int)stuff->height,
+ stuff->planeMask, (xGetImageReply **)NULL);
+}
+
+int
+ProcPolyText(register ClientPtr client)
+{
+ int err;
+ REQUEST(xPolyTextReq);
+ DrawablePtr pDraw;
+ GC *pGC;
+
+ REQUEST_AT_LEAST_SIZE(xPolyTextReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ err = PolyText(client,
+ pDraw,
+ pGC,
+ (unsigned char *)&stuff[1],
+ ((unsigned char *) stuff) + (client->req_len << 2),
+ stuff->x,
+ stuff->y,
+ stuff->reqType,
+ stuff->drawable);
+
+ if (err == Success)
+ {
+ return(client->noClientException);
+ }
+ else
+ return err;
+}
+
+int
+ProcImageText8(register ClientPtr client)
+{
+ int err;
+ register DrawablePtr pDraw;
+ register GC *pGC;
+
+ REQUEST(xImageTextReq);
+
+ REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ err = ImageText(client,
+ pDraw,
+ pGC,
+ stuff->nChars,
+ (unsigned char *)&stuff[1],
+ stuff->x,
+ stuff->y,
+ stuff->reqType,
+ stuff->drawable);
+
+ if (err == Success)
+ {
+ return(client->noClientException);
+ }
+ else
+ return err;
+}
+
+int
+ProcImageText16(register ClientPtr client)
+{
+ int err;
+ register DrawablePtr pDraw;
+ register GC *pGC;
+
+ REQUEST(xImageTextReq);
+
+ REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ err = ImageText(client,
+ pDraw,
+ pGC,
+ stuff->nChars,
+ (unsigned char *)&stuff[1],
+ stuff->x,
+ stuff->y,
+ stuff->reqType,
+ stuff->drawable);
+
+ if (err == Success)
+ {
+ return(client->noClientException);
+ }
+ else
+ return err;
+}
+
+
+int
+ProcCreateColormap(register ClientPtr client)
+{
+ VisualPtr pVisual;
+ ColormapPtr pmap;
+ Colormap mid;
+ register WindowPtr pWin;
+ ScreenPtr pScreen;
+ REQUEST(xCreateColormapReq);
+ int i, result;
+
+ REQUEST_SIZE_MATCH(xCreateColormapReq);
+
+ if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll))
+ {
+ client->errorValue = stuff->alloc;
+ return(BadValue);
+ }
+ mid = stuff->mid;
+ LEGAL_NEW_RESOURCE(mid, client);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+
+ pScreen = pWin->drawable.pScreen;
+ for (i = 0, pVisual = pScreen->visuals;
+ i < pScreen->numVisuals;
+ i++, pVisual++)
+ {
+ if (pVisual->vid != stuff->visual)
+ continue;
+ result = CreateColormap(mid, pScreen, pVisual, &pmap,
+ (int)stuff->alloc, client->index);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+ }
+ client->errorValue = stuff->visual;
+ return(BadValue);
+}
+
+int
+ProcFreeColormap(register ClientPtr client)
+{
+ ColormapPtr pmap;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pmap = (ColormapPtr )SecurityLookupIDByType(client, stuff->id, RT_COLORMAP,
+ SecurityDestroyAccess);
+ if (pmap)
+ {
+ /* Freeing a default colormap is a no-op */
+ if (!(pmap->flags & IsDefault))
+ FreeResource(stuff->id, RT_NONE);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadColor);
+ }
+}
+
+
+int
+ProcCopyColormapAndFree(register ClientPtr client)
+{
+ Colormap mid;
+ ColormapPtr pSrcMap;
+ REQUEST(xCopyColormapAndFreeReq);
+ int result;
+
+ REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
+ mid = stuff->mid;
+ LEGAL_NEW_RESOURCE(mid, client);
+ if( (pSrcMap = (ColormapPtr )SecurityLookupIDByType(client, stuff->srcCmap,
+ RT_COLORMAP, SecurityReadAccess|SecurityWriteAccess)) )
+ {
+ result = CopyColormapAndFree(mid, pSrcMap, client->index);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+ }
+ else
+ {
+ client->errorValue = stuff->srcCmap;
+ return(BadColor);
+ }
+}
+
+int
+ProcInstallColormap(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
+ RT_COLORMAP, SecurityReadAccess);
+ if (pcmp)
+ {
+ (*(pcmp->pScreen->InstallColormap)) (pcmp);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadColor);
+ }
+}
+
+int
+ProcUninstallColormap(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
+ RT_COLORMAP, SecurityReadAccess);
+ if (pcmp)
+ {
+ if(pcmp->mid != pcmp->pScreen->defColormap)
+ (*(pcmp->pScreen->UninstallColormap)) (pcmp);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadColor);
+ }
+}
+
+int
+ProcListInstalledColormaps(register ClientPtr client)
+{
+ xListInstalledColormapsReply *preply;
+ int nummaps;
+ WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityReadAccess);
+
+ if (!pWin)
+ return(BadWindow);
+
+ preply = (xListInstalledColormapsReply *)
+ ALLOCATE_LOCAL(sizeof(xListInstalledColormapsReply) +
+ pWin->drawable.pScreen->maxInstalledCmaps *
+ sizeof(Colormap));
+ if(!preply)
+ return(BadAlloc);
+
+ preply->type = X_Reply;
+ preply->sequenceNumber = client->sequence;
+ nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
+ (pWin->drawable.pScreen, (Colormap *)&preply[1]);
+ preply->nColormaps = nummaps;
+ preply->length = nummaps;
+ WriteReplyToClient(client, sizeof (xListInstalledColormapsReply), preply);
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]);
+ DEALLOCATE_LOCAL(preply);
+ return(client->noClientException);
+}
+
+int
+ProcAllocColor (register ClientPtr client)
+{
+ ColormapPtr pmap;
+ int retval;
+ xAllocColorReply acr;
+ REQUEST(xAllocColorReq);
+
+ REQUEST_SIZE_MATCH(xAllocColorReq);
+ pmap = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityWriteAccess);
+ if (pmap)
+ {
+#ifdef LBX
+ /*
+ * If the colormap is grabbed by a proxy, the server will have
+ * to regain control over the colormap. This AllocColor request
+ * will be handled after the server gets back the colormap control.
+ */
+ if (LbxCheckColorRequest (client, pmap, (xReq *) stuff))
+ return Success;
+#endif
+ acr.type = X_Reply;
+ acr.length = 0;
+ acr.sequenceNumber = client->sequence;
+ acr.red = stuff->red;
+ acr.green = stuff->green;
+ acr.blue = stuff->blue;
+ acr.pixel = 0;
+ if( (retval = AllocColor(pmap, &acr.red, &acr.green, &acr.blue,
+ &acr.pixel, client->index)) )
+ {
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return (retval);
+ }
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !pmap->pScreen->myNum)
+#endif
+ WriteReplyToClient(client, sizeof(xAllocColorReply), &acr);
+ return (client->noClientException);
+
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcAllocNamedColor (register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xAllocNamedColorReq);
+
+ REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityWriteAccess);
+ if (pcmp)
+ {
+ int retval;
+
+ xAllocNamedColorReply ancr;
+
+#ifdef LBX
+ /*
+ * If the colormap is grabbed by a proxy, the server will have
+ * to regain control over the colormap. This AllocNamedColor request
+ * will be handled after the server gets back the colormap control.
+ */
+ if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
+ return Success;
+#endif
+ ancr.type = X_Reply;
+ ancr.length = 0;
+ ancr.sequenceNumber = client->sequence;
+
+ if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
+ &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue))
+ {
+ ancr.screenRed = ancr.exactRed;
+ ancr.screenGreen = ancr.exactGreen;
+ ancr.screenBlue = ancr.exactBlue;
+ ancr.pixel = 0;
+ if( (retval = AllocColor(pcmp,
+ &ancr.screenRed, &ancr.screenGreen, &ancr.screenBlue,
+ &ancr.pixel, client->index)) )
+ {
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(retval);
+ }
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+ WriteReplyToClient(client, sizeof (xAllocNamedColorReply), &ancr);
+ return (client->noClientException);
+ }
+ else
+ return(BadName);
+
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcAllocColorCells (register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xAllocColorCellsReq);
+
+ REQUEST_SIZE_MATCH(xAllocColorCellsReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityWriteAccess);
+ if (pcmp)
+ {
+ xAllocColorCellsReply accr;
+ int npixels, nmasks, retval;
+ long length;
+ Pixel *ppixels, *pmasks;
+
+#ifdef LBX
+ /*
+ * If the colormap is grabbed by a proxy, the server will have
+ * to regain control over the colormap. This AllocColorCells request
+ * will be handled after the server gets back the colormap control.
+ */
+ if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
+ return Success;
+#endif
+ npixels = stuff->colors;
+ if (!npixels)
+ {
+ client->errorValue = npixels;
+ return (BadValue);
+ }
+ if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
+ {
+ client->errorValue = stuff->contiguous;
+ return (BadValue);
+ }
+ nmasks = stuff->planes;
+ length = ((long)npixels + (long)nmasks) * sizeof(Pixel);
+ ppixels = (Pixel *)ALLOCATE_LOCAL(length);
+ if(!ppixels)
+ return(BadAlloc);
+ pmasks = ppixels + npixels;
+
+ if( (retval = AllocColorCells(client->index, pcmp, npixels, nmasks,
+ (Bool)stuff->contiguous, ppixels, pmasks)) )
+ {
+ DEALLOCATE_LOCAL(ppixels);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(retval);
+ }
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+ {
+ accr.type = X_Reply;
+ accr.length = length >> 2;
+ accr.sequenceNumber = client->sequence;
+ accr.nPixels = npixels;
+ accr.nMasks = nmasks;
+ WriteReplyToClient(client, sizeof (xAllocColorCellsReply), &accr);
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, length, ppixels);
+ }
+ DEALLOCATE_LOCAL(ppixels);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcAllocColorPlanes(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xAllocColorPlanesReq);
+
+ REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityWriteAccess);
+ if (pcmp)
+ {
+ xAllocColorPlanesReply acpr;
+ int npixels, retval;
+ long length;
+ Pixel *ppixels;
+
+#ifdef LBX
+ /*
+ * If the colormap is grabbed by a proxy, the server will have
+ * to regain control over the colormap. This AllocColorPlanes request
+ * will be handled after the server gets back the colormap control.
+ */
+ if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
+ return Success;
+#endif
+ npixels = stuff->colors;
+ if (!npixels)
+ {
+ client->errorValue = npixels;
+ return (BadValue);
+ }
+ if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
+ {
+ client->errorValue = stuff->contiguous;
+ return (BadValue);
+ }
+ acpr.type = X_Reply;
+ acpr.sequenceNumber = client->sequence;
+ acpr.nPixels = npixels;
+ length = (long)npixels * sizeof(Pixel);
+ ppixels = (Pixel *)ALLOCATE_LOCAL(length);
+ if(!ppixels)
+ return(BadAlloc);
+ if( (retval = AllocColorPlanes(client->index, pcmp, npixels,
+ (int)stuff->red, (int)stuff->green, (int)stuff->blue,
+ (Bool)stuff->contiguous, ppixels,
+ &acpr.redMask, &acpr.greenMask, &acpr.blueMask)) )
+ {
+ DEALLOCATE_LOCAL(ppixels);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(retval);
+ }
+ acpr.length = length >> 2;
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+ {
+ WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr);
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, length, ppixels);
+ }
+ DEALLOCATE_LOCAL(ppixels);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcFreeColors(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xFreeColorsReq);
+
+ REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityWriteAccess);
+ if (pcmp)
+ {
+ int count;
+ int retval;
+
+ if(pcmp->flags & AllAllocated)
+ return(BadAccess);
+ count = ((client->req_len << 2)- sizeof(xFreeColorsReq)) >> 2;
+ retval = FreeColors(pcmp, client->index, count,
+ (Pixel *)&stuff[1], (Pixel)stuff->planeMask);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return(retval);
+ }
+
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcStoreColors (ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xStoreColorsReq);
+
+ REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityWriteAccess);
+ if (pcmp)
+ {
+ int count;
+ int retval;
+
+ count = (client->req_len << 2) - sizeof(xStoreColorsReq);
+ if (count % sizeof(xColorItem))
+ return(BadLength);
+ count /= sizeof(xColorItem);
+ retval = StoreColors(pcmp, count, (xColorItem *)&stuff[1]);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return(retval);
+ }
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcStoreNamedColor (register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xStoreNamedColorReq);
+
+ REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityWriteAccess);
+ if (pcmp)
+ {
+ xColorItem def;
+ int retval;
+
+ if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1],
+ stuff->nbytes, &def.red, &def.green, &def.blue))
+ {
+ def.flags = stuff->flags;
+ def.pixel = stuff->pixel;
+ retval = StoreColors(pcmp, 1, &def);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(retval);
+ }
+ return (BadName);
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcQueryColors(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xQueryColorsReq);
+
+ REQUEST_AT_LEAST_SIZE(xQueryColorsReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityReadAccess);
+ if (pcmp)
+ {
+ int count, retval;
+ xrgb *prgbs;
+ xQueryColorsReply qcr;
+
+ count = ((client->req_len << 2) - sizeof(xQueryColorsReq)) >> 2;
+ prgbs = (xrgb *)ALLOCATE_LOCAL(count * sizeof(xrgb));
+ if(!prgbs && count)
+ return(BadAlloc);
+ if( (retval = QueryColors(pcmp, count, (Pixel *)&stuff[1], prgbs)) )
+ {
+ if (prgbs) DEALLOCATE_LOCAL(prgbs);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return (retval);
+ }
+ }
+ qcr.type = X_Reply;
+ qcr.length = (count * sizeof(xrgb)) >> 2;
+ qcr.sequenceNumber = client->sequence;
+ qcr.nColors = count;
+ WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr);
+ if (count)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend;
+ WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs);
+ }
+ if (prgbs) DEALLOCATE_LOCAL(prgbs);
+ return(client->noClientException);
+
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcLookupColor(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xLookupColorReq);
+
+ REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityReadAccess);
+ if (pcmp)
+ {
+ xLookupColorReply lcr;
+
+ if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
+ &lcr.exactRed, &lcr.exactGreen, &lcr.exactBlue))
+ {
+ lcr.type = X_Reply;
+ lcr.length = 0;
+ lcr.sequenceNumber = client->sequence;
+ lcr.screenRed = lcr.exactRed;
+ lcr.screenGreen = lcr.exactGreen;
+ lcr.screenBlue = lcr.exactBlue;
+ (*pcmp->pScreen->ResolveColor)(&lcr.screenRed,
+ &lcr.screenGreen,
+ &lcr.screenBlue,
+ pcmp->pVisual);
+ WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr);
+ return(client->noClientException);
+ }
+ return (BadName);
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcCreateCursor (register ClientPtr client)
+{
+ CursorPtr pCursor;
+
+ register PixmapPtr src;
+ register PixmapPtr msk;
+ unsigned char * srcbits;
+ unsigned char * mskbits;
+ unsigned short width, height;
+ long n;
+ CursorMetricRec cm;
+
+
+ REQUEST(xCreateCursorReq);
+
+ REQUEST_SIZE_MATCH(xCreateCursorReq);
+ LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+ src = (PixmapPtr)SecurityLookupIDByType(client, stuff->source,
+ RT_PIXMAP, SecurityReadAccess);
+ msk = (PixmapPtr)SecurityLookupIDByType(client, stuff->mask,
+ RT_PIXMAP, SecurityReadAccess);
+ if ( src == (PixmapPtr)NULL)
+ {
+ client->errorValue = stuff->source;
+ return (BadPixmap);
+ }
+ if ( msk == (PixmapPtr)NULL)
+ {
+ if (stuff->mask != None)
+ {
+ client->errorValue = stuff->mask;
+ return (BadPixmap);
+ }
+ }
+ else if ( src->drawable.width != msk->drawable.width
+ || src->drawable.height != msk->drawable.height
+ || src->drawable.depth != 1
+ || msk->drawable.depth != 1)
+ return (BadMatch);
+
+ width = src->drawable.width;
+ height = src->drawable.height;
+
+ if ( stuff->x > width
+ || stuff->y > height )
+ return (BadMatch);
+
+ n = BitmapBytePad(width)*height;
+ srcbits = (unsigned char *)xalloc(n);
+ if (!srcbits)
+ return (BadAlloc);
+ mskbits = (unsigned char *)xalloc(n);
+ if (!mskbits)
+ {
+ xfree(srcbits);
+ return (BadAlloc);
+ }
+
+ /* zeroing the (pad) bits helps some ddx cursor handling */
+ bzero((char *)srcbits, n);
+ (* src->drawable.pScreen->GetImage)( (DrawablePtr)src, 0, 0, width, height,
+ XYPixmap, 1, (pointer)srcbits);
+ if ( msk == (PixmapPtr)NULL)
+ {
+ register unsigned char *bits = mskbits;
+ while (--n >= 0)
+ *bits++ = ~0;
+ }
+ else
+ {
+ /* zeroing the (pad) bits helps some ddx cursor handling */
+ bzero((char *)mskbits, n);
+ (* msk->drawable.pScreen->GetImage)( (DrawablePtr)msk, 0, 0, width,
+ height, XYPixmap, 1, (pointer)mskbits);
+ }
+ cm.width = width;
+ cm.height = height;
+ cm.xhot = stuff->x;
+ cm.yhot = stuff->y;
+ pCursor = AllocCursor( srcbits, mskbits, &cm,
+ stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
+ stuff->backRed, stuff->backGreen, stuff->backBlue);
+
+ if (pCursor && AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+ {
+ #ifdef TEST
+ fprintf(stderr, "ProcCreateCursor: Created cursor at [%p].\n", (void *) pCursor);
+ #endif
+
+ return (client->noClientException);
+ }
+
+ return BadAlloc;
+}
+
+int
+ProcCreateGlyphCursor (register ClientPtr client)
+{
+ CursorPtr pCursor;
+ int res;
+
+ REQUEST(xCreateGlyphCursorReq);
+
+ REQUEST_SIZE_MATCH(xCreateGlyphCursorReq);
+ LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+ res = AllocGlyphCursor(stuff->source, stuff->sourceChar,
+ stuff->mask, stuff->maskChar,
+ stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
+ stuff->backRed, stuff->backGreen, stuff->backBlue,
+ &pCursor, client);
+ if (res != Success)
+ return res;
+ if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+ return client->noClientException;
+ return BadAlloc;
+}
+
+
+int
+ProcFreeCursor (register ClientPtr client)
+{
+ CursorPtr pCursor;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->id,
+ RT_CURSOR, SecurityDestroyAccess);
+ if (pCursor)
+ {
+ FreeResource(stuff->id, RT_NONE);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadCursor);
+ }
+}
+
+int
+ProcQueryBestSize (register ClientPtr client)
+{
+ xQueryBestSizeReply reply;
+ register DrawablePtr pDraw;
+ ScreenPtr pScreen;
+ REQUEST(xQueryBestSizeReq);
+
+ REQUEST_SIZE_MATCH(xQueryBestSizeReq);
+ if ((stuff->class != CursorShape) &&
+ (stuff->class != TileShape) &&
+ (stuff->class != StippleShape))
+ {
+ client->errorValue = stuff->class;
+ return(BadValue);
+ }
+ SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->drawable, client,
+ SecurityReadAccess);
+ if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW)
+ return (BadMatch);
+ pScreen = pDraw->pScreen;
+ (* pScreen->QueryBestSize)(stuff->class, &stuff->width,
+ &stuff->height, pScreen);
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ reply.width = stuff->width;
+ reply.height = stuff->height;
+ WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply);
+ return (client->noClientException);
+}
+
+
+int
+ProcSetScreenSaver (register ClientPtr client)
+{
+ int blankingOption, exposureOption;
+ REQUEST(xSetScreenSaverReq);
+
+ REQUEST_SIZE_MATCH(xSetScreenSaverReq);
+ blankingOption = stuff->preferBlank;
+ if ((blankingOption != DontPreferBlanking) &&
+ (blankingOption != PreferBlanking) &&
+ (blankingOption != DefaultBlanking))
+ {
+ client->errorValue = blankingOption;
+ return BadValue;
+ }
+ exposureOption = stuff->allowExpose;
+ if ((exposureOption != DontAllowExposures) &&
+ (exposureOption != AllowExposures) &&
+ (exposureOption != DefaultExposures))
+ {
+ client->errorValue = exposureOption;
+ return BadValue;
+ }
+ if (stuff->timeout < -1)
+ {
+ client->errorValue = stuff->timeout;
+ return BadValue;
+ }
+ if (stuff->interval < -1)
+ {
+ client->errorValue = stuff->interval;
+ return BadValue;
+ }
+
+ /*
+ * The NX agent uses the screen saver procedure
+ * to monitor the user activities and launch its
+ * handlers (like timeout feature), so we can't
+ * always allow the clients to change our values.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "ProcSetScreenSaver: Called with timeout [%d] interval [%d] Blanking [%d] Exposure [%d].\n",
+ stuff -> timeout, stuff -> interval, blankingOption, exposureOption);
+ #endif
+
+ if (nxagentOption(Timeout) == 0)
+ {
+ if (blankingOption == DefaultBlanking)
+ {
+ ScreenSaverBlanking = defaultScreenSaverBlanking;
+ }
+ else
+ {
+ ScreenSaverBlanking = blankingOption;
+ }
+
+ if (exposureOption == DefaultExposures)
+ {
+ ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
+ }
+ else
+ {
+ ScreenSaverAllowExposures = exposureOption;
+ }
+
+ if (stuff->timeout >= 0)
+ {
+ ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND;
+ }
+ else
+ {
+ ScreenSaverTime = defaultScreenSaverTime;
+ }
+
+ if (stuff->interval >= 0)
+ {
+ ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND;
+ }
+ else
+ {
+ ScreenSaverInterval = defaultScreenSaverInterval;
+ }
+ }
+ #ifdef TEST
+
+ else
+ {
+ fprintf(stderr, "ProcSetScreenSaver: Keeping auto-disconnect timeout set to [%d] seconds.\n",
+ nxagentOption(Timeout));
+ }
+
+ #endif
+
+ SetScreenSaverTimer();
+ return (client->noClientException);
+}
+
+int
+ProcGetScreenSaver(register ClientPtr client)
+{
+ xGetScreenSaverReply rep;
+
+ REQUEST_SIZE_MATCH(xReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.timeout = ScreenSaverTime / MILLI_PER_SECOND;
+ rep.interval = ScreenSaverInterval / MILLI_PER_SECOND;
+ rep.preferBlanking = ScreenSaverBlanking;
+ rep.allowExposures = ScreenSaverAllowExposures;
+ WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep);
+ return (client->noClientException);
+}
+
+int
+ProcChangeHosts(register ClientPtr client)
+{
+ REQUEST(xChangeHostsReq);
+ int result;
+
+ REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength);
+
+ if(stuff->mode == HostInsert)
+ result = AddHost(client, (int)stuff->hostFamily,
+ stuff->hostLength, (pointer)&stuff[1]);
+ else if (stuff->mode == HostDelete)
+ result = RemoveHost(client, (int)stuff->hostFamily,
+ stuff->hostLength, (pointer)&stuff[1]);
+ else
+ {
+ client->errorValue = stuff->mode;
+ return BadValue;
+ }
+ if (!result)
+ result = client->noClientException;
+ return (result);
+}
+
+int
+ProcListHosts(register ClientPtr client)
+{
+ xListHostsReply reply;
+ int len, nHosts, result;
+ pointer pdata;
+ /* REQUEST(xListHostsReq); */
+
+ REQUEST_SIZE_MATCH(xListHostsReq);
+#ifdef XCSECURITY
+ /* untrusted clients can't list hosts */
+ if (client->trustLevel != XSecurityClientTrusted)
+ {
+ SecurityAudit("client %d attempted to list hosts\n", client->index);
+ return BadAccess;
+ }
+#endif
+ result = GetHosts(&pdata, &nHosts, &len, &reply.enabled);
+ if (result != Success)
+ return(result);
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.nHosts = nHosts;
+ reply.length = len >> 2;
+ WriteReplyToClient(client, sizeof(xListHostsReply), &reply);
+ if (nHosts)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend;
+ WriteSwappedDataToClient(client, len, pdata);
+ }
+ xfree(pdata);
+ return (client->noClientException);
+}
+
+int
+ProcChangeAccessControl(register ClientPtr client)
+{
+ int result;
+ REQUEST(xSetAccessControlReq);
+
+ REQUEST_SIZE_MATCH(xSetAccessControlReq);
+ if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess))
+ {
+ client->errorValue = stuff->mode;
+ return BadValue;
+ }
+ result = ChangeAccessControl(client, stuff->mode == EnableAccess);
+ if (!result)
+ result = client->noClientException;
+ return (result);
+}
+
+int
+ProcKillClient(register ClientPtr client)
+{
+ REQUEST(xResourceReq);
+ ClientPtr killclient;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ if (stuff->id == AllTemporary)
+ {
+ CloseDownRetainedResources();
+ return (client->noClientException);
+ }
+
+ if ((killclient = LookupClient(stuff->id, client)))
+ {
+ CloseDownClient(killclient);
+ /* if an LBX proxy gets killed, isItTimeToYield will be set */
+ if (isItTimeToYield || (client == killclient))
+ {
+ /* force yield and return Success, so that Dispatch()
+ * doesn't try to touch client
+ */
+ isItTimeToYield = TRUE;
+ return (Success);
+ }
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadValue);
+ }
+}
+
+int
+ProcSetFontPath(register ClientPtr client)
+{
+ unsigned char *ptr;
+ unsigned long nbytes, total;
+ long nfonts;
+ int n, result;
+ int error;
+ REQUEST(xSetFontPathReq);
+
+ REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
+
+ nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq);
+ total = nbytes;
+ ptr = (unsigned char *)&stuff[1];
+ nfonts = stuff->nFonts;
+ while (--nfonts >= 0)
+ {
+ if ((total == 0) || (total < (n = (*ptr + 1))))
+ return(BadLength);
+ total -= n;
+ ptr += n;
+ }
+ if (total >= 4)
+ return(BadLength);
+ result = SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1],
+ &error);
+ if (!result)
+ {
+ result = client->noClientException;
+ client->errorValue = error;
+ }
+ return (result);
+}
+
+int
+ProcGetFontPath(register ClientPtr client)
+{
+ xGetFontPathReply reply;
+ int stringLens, numpaths;
+ unsigned char *bufferStart;
+ /* REQUEST (xReq); */
+
+ REQUEST_SIZE_MATCH(xReq);
+ bufferStart = GetFontPath(&numpaths, &stringLens);
+
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.length = (stringLens + numpaths + 3) >> 2;
+ reply.nPaths = numpaths;
+
+ WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply);
+ if (stringLens || numpaths)
+ (void)WriteToClient(client, stringLens + numpaths, (char *)bufferStart);
+ return(client->noClientException);
+}
+
+int
+ProcChangeCloseDownMode(register ClientPtr client)
+{
+ REQUEST(xSetCloseDownModeReq);
+
+ REQUEST_SIZE_MATCH(xSetCloseDownModeReq);
+ if ((stuff->mode == AllTemporary) ||
+ (stuff->mode == RetainPermanent) ||
+ (stuff->mode == RetainTemporary))
+ {
+ client->closeDownMode = stuff->mode;
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->mode;
+ return (BadValue);
+ }
+}
+
+int ProcForceScreenSaver(register ClientPtr client)
+{
+ REQUEST(xForceScreenSaverReq);
+
+ REQUEST_SIZE_MATCH(xForceScreenSaverReq);
+
+ if ((stuff->mode != ScreenSaverReset) &&
+ (stuff->mode != ScreenSaverActive))
+ {
+ client->errorValue = stuff->mode;
+ return BadValue;
+ }
+
+ /*
+ * The NX agent uses the screen saver procedure
+ * to monitor the user activities and launch its
+ * handlers (like timeout feature), so we can't
+ * always allow the clients to force the screen
+ * saver handler execution.
+ */
+
+ if (nxagentOption(Timeout) == 0)
+ {
+ SaveScreens(SCREEN_SAVER_FORCER, (int)stuff->mode);
+ }
+
+ #ifdef TEST
+
+ else
+ {
+ fprintf(stderr, "ProcForceScreenSaver: Ignoring the client request with mode [%d].\n",
+ stuff -> mode);
+ }
+
+ #endif
+
+ return client->noClientException;
+}
+
+int ProcNoOperation(register ClientPtr client)
+{
+ REQUEST_AT_LEAST_SIZE(xReq);
+
+ /* noop -- don't do anything */
+ return(client->noClientException);
+}
+
+void
+InitProcVectors(void)
+{
+ int i;
+ for (i = 0; i<256; i++)
+ {
+ if(!ProcVector[i])
+ {
+ ProcVector[i] = SwappedProcVector[i] = ProcBadRequest;
+ ReplySwapVector[i] = ReplyNotSwappd;
+ }
+#ifdef K5AUTH
+ if (!k5_Vector[i])
+ {
+ k5_Vector[i] = k5_bad;
+ }
+#endif
+ }
+ for(i = LASTEvent; i < 128; i++)
+ {
+ EventSwapVector[i] = NotImplemented;
+ }
+
+}
+
+/**********************
+ * CloseDownClient
+ *
+ * Client can either mark his resources destroy or retain. If retained and
+ * then killed again, the client is really destroyed.
+ *********************/
+
+void
+CloseDownClient(register ClientPtr client)
+{
+ Bool really_close_down = client->clientGone ||
+ client->closeDownMode == DestroyAll;
+
+ /*
+ * There must be a better way to hook a
+ * call-back function to be called any
+ * time a client is going to be closed.
+ */
+
+ nxagentClearClipboard(client, NULL);
+
+ /*
+ * Need to reset the karma counter and
+ * get rid of the pending sync replies.
+ */
+
+ nxagentWakeupByReset(client);
+
+ /*
+ * Check if the client
+ * is a shadow nxagent.
+ */
+
+ nxagentCheckIfShadowAgent(client);
+
+ if (!client->clientGone)
+ {
+ /* ungrab server if grabbing client dies */
+ if (grabState != GrabNone && grabClient == client)
+ {
+ UngrabServer(client);
+ }
+ BITCLEAR(grabWaiters, client->index);
+ DeleteClientFromAnySelections(client);
+ ReleaseActiveGrabs(client);
+ DeleteClientFontStuff(client);
+ if (!really_close_down)
+ {
+ /* This frees resources that should never be retained
+ * no matter what the close down mode is. Actually we
+ * could do this unconditionally, but it's probably
+ * better not to traverse all the client's resources
+ * twice (once here, once a few lines down in
+ * FreeClientResources) in the common case of
+ * really_close_down == TRUE.
+ */
+ FreeClientNeverRetainResources(client);
+ client->clientState = ClientStateRetained;
+ if (ClientStateCallback)
+ {
+ NewClientInfoRec clientinfo;
+
+ clientinfo.client = client;
+ clientinfo.prefix = (xConnSetupPrefix *)NULL;
+ clientinfo.setup = (xConnSetup *) NULL;
+ CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+ }
+ }
+ client->clientGone = TRUE; /* so events aren't sent to client */
+ if (ClientIsAsleep(client))
+ ClientSignal (client);
+ ProcessWorkQueueZombies();
+#ifdef LBX
+ ProcessQTagZombies();
+#endif
+ CloseDownConnection(client);
+
+ /* If the client made it to the Running stage, nClients has
+ * been incremented on its behalf, so we need to decrement it
+ * now. If it hasn't gotten to Running, nClients has *not*
+ * been incremented, so *don't* decrement it.
+ */
+ if (client->clientState != ClientStateInitial &&
+ client->clientState != ClientStateAuthenticating )
+ {
+ --nClients;
+ }
+ }
+
+ if (really_close_down)
+ {
+ if (client->clientState == ClientStateRunning && nClients == 0)
+ dispatchException |= dispatchExceptionAtReset;
+
+ client->clientState = ClientStateGone;
+ if (ClientStateCallback)
+ {
+ NewClientInfoRec clientinfo;
+
+ clientinfo.client = client;
+ clientinfo.prefix = (xConnSetupPrefix *)NULL;
+ clientinfo.setup = (xConnSetup *) NULL;
+ CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+ }
+ FreeClientResources(client);
+ if (client->index < nextFreeClientID)
+ nextFreeClientID = client->index;
+ clients[client->index] = NullClient;
+#ifdef SMART_SCHEDULE
+ SmartLastClient = NullClient;
+#endif
+ xfree(client);
+
+ while (!clients[currentMaxClients-1])
+ currentMaxClients--;
+ }
+}
+
+static void
+KillAllClients()
+{
+ int i;
+ for (i=1; i<currentMaxClients; i++)
+ if (clients[i]) {
+ /* Make sure Retained clients are released. */
+ clients[i]->closeDownMode = DestroyAll;
+ CloseDownClient(clients[i]);
+ }
+}
+
+/*********************
+ * CloseDownRetainedResources
+ *
+ * Find all clients that are gone and have terminated in RetainTemporary
+ * and destroy their resources.
+ *********************/
+
+void
+CloseDownRetainedResources()
+{
+ register int i;
+ register ClientPtr client;
+
+ for (i=1; i<currentMaxClients; i++)
+ {
+ client = clients[i];
+ if (client && (client->closeDownMode == RetainTemporary)
+ && (client->clientGone))
+ CloseDownClient(client);
+ }
+}
+
+void InitClient(ClientPtr client, int i, pointer ospriv)
+{
+ client->index = i;
+ client->sequence = 0;
+ client->clientAsMask = ((Mask)i) << CLIENTOFFSET;
+ client->clientGone = FALSE;
+ if (i)
+ {
+ client->closeDownMode = DestroyAll;
+ client->lastDrawable = (DrawablePtr)WindowTable[0];
+ client->lastDrawableID = WindowTable[0]->drawable.id;
+ }
+ else
+ {
+ client->closeDownMode = RetainPermanent;
+ client->lastDrawable = (DrawablePtr)NULL;
+ client->lastDrawableID = INVALID;
+ }
+ client->lastGC = (GCPtr) NULL;
+ client->lastGCID = INVALID;
+ client->numSaved = 0;
+ client->saveSet = (SaveSetElt *)NULL;
+ client->noClientException = Success;
+#ifdef LOG_DEBUG
+ client->requestLogIndex = 0;
+#endif
+ client->requestVector = InitialVector;
+ client->osPrivate = ospriv;
+ client->swapped = FALSE;
+ client->big_requests = FALSE;
+ client->priority = 0;
+ client->clientState = ClientStateInitial;
+#ifdef XKB
+ if (!noXkbExtension) {
+ client->xkbClientFlags = 0;
+ client->mapNotifyMask = 0;
+ QueryMinMaxKeyCodes(&client->minKC,&client->maxKC);
+ }
+#endif
+ client->replyBytesRemaining = 0;
+#ifdef LBX
+ client->readRequest = StandardReadRequestFromClient;
+#endif
+#ifdef XCSECURITY
+ client->trustLevel = XSecurityClientTrusted;
+ client->CheckAccess = NULL;
+ client->authId = 0;
+#endif
+#ifdef XAPPGROUP
+ client->appgroup = NULL;
+#endif
+ client->fontResFunc = NULL;
+#ifdef SMART_SCHEDULE
+ client->smart_priority = 0;
+ client->smart_start_tick = SmartScheduleTime;
+ client->smart_stop_tick = SmartScheduleTime;
+ client->smart_check_tick = SmartScheduleTime;
+#endif
+}
+
+extern int clientPrivateLen;
+extern unsigned *clientPrivateSizes;
+extern unsigned totalClientSize;
+
+int
+InitClientPrivates(ClientPtr client)
+{
+ register char *ptr;
+ DevUnion *ppriv;
+ register unsigned *sizes;
+ register unsigned size;
+ register int i;
+
+ if (totalClientSize == sizeof(ClientRec))
+ ppriv = (DevUnion *)NULL;
+ else if (client->index)
+ ppriv = (DevUnion *)(client + 1);
+ else
+ {
+ ppriv = (DevUnion *)xalloc(totalClientSize - sizeof(ClientRec));
+ if (!ppriv)
+ return 0;
+ }
+ client->devPrivates = ppriv;
+ sizes = clientPrivateSizes;
+ ptr = (char *)(ppriv + clientPrivateLen);
+ for (i = clientPrivateLen; --i >= 0; ppriv++, sizes++)
+ {
+ if ( (size = *sizes) )
+ {
+ ppriv->ptr = (pointer)ptr;
+ ptr += size;
+ }
+ else
+ ppriv->ptr = (pointer)NULL;
+ }
+
+ /*
+ * Initialize the private members.
+ */
+
+ nxagentInitClientPrivates(client);
+
+ return 1;
+}
+
+/************************
+ * int NextAvailableClient(ospriv)
+ *
+ * OS dependent portion can't assign client id's because of CloseDownModes.
+ * Returns NULL if there are no free clients.
+ *************************/
+
+ClientPtr NextAvailableClient(pointer ospriv)
+{
+ register int i;
+ register ClientPtr client;
+ xReq data;
+
+ i = nextFreeClientID;
+ if (i == MAXCLIENTS)
+ return (ClientPtr)NULL;
+ clients[i] = client = (ClientPtr)xalloc(totalClientSize);
+ if (!client)
+ return (ClientPtr)NULL;
+ InitClient(client, i, ospriv);
+ InitClientPrivates(client);
+ if (!InitClientResources(client))
+ {
+ xfree(client);
+ return (ClientPtr)NULL;
+ }
+ data.reqType = 1;
+ data.length = (sz_xReq + sz_xConnClientPrefix) >> 2;
+ if (!InsertFakeRequest(client, (char *)&data, sz_xReq))
+ {
+ FreeClientResources(client);
+ xfree(client);
+ return (ClientPtr)NULL;
+ }
+ if (i == currentMaxClients)
+ currentMaxClients++;
+ while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID])
+ nextFreeClientID++;
+ if (ClientStateCallback)
+ {
+ NewClientInfoRec clientinfo;
+
+ clientinfo.client = client;
+ clientinfo.prefix = (xConnSetupPrefix *)NULL;
+ clientinfo.setup = (xConnSetup *) NULL;
+ CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+ }
+ return(client);
+}
+
+int
+ProcInitialConnection(register ClientPtr client)
+{
+ REQUEST(xReq);
+ register xConnClientPrefix *prefix;
+ int whichbyte = 1;
+
+ prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
+ if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B'))
+ return (client->noClientException = -1);
+ if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) ||
+ (!(*(char *) &whichbyte) && (prefix->byteOrder == 'l')))
+ {
+ client->swapped = TRUE;
+ SwapConnClientPrefix(prefix);
+ }
+ stuff->reqType = 2;
+ stuff->length += ((prefix->nbytesAuthProto + (unsigned)3) >> 2) +
+ ((prefix->nbytesAuthString + (unsigned)3) >> 2);
+ if (client->swapped)
+ {
+ swaps(&stuff->length, whichbyte);
+ }
+ ResetCurrentRequest(client);
+ return (client->noClientException);
+}
+
+#ifdef LBX
+void
+IncrementClientCount()
+{
+ nClients++;
+}
+#endif
+
+int
+SendConnSetup(register ClientPtr client, char *reason)
+{
+ register xWindowRoot *root;
+ register int i;
+ int numScreens;
+ char* lConnectionInfo;
+ xConnSetupPrefix* lconnSetupPrefix;
+
+ if (reason)
+ {
+ xConnSetupPrefix csp;
+
+ csp.success = xFalse;
+ csp.lengthReason = strlen(reason);
+ csp.length = (csp.lengthReason + (unsigned)3) >> 2;
+ csp.majorVersion = X_PROTOCOL;
+ csp.minorVersion = X_PROTOCOL_REVISION;
+ if (client->swapped)
+ WriteSConnSetupPrefix(client, &csp);
+ else
+ (void)WriteToClient(client, sz_xConnSetupPrefix, (char *) &csp);
+ (void)WriteToClient(client, (int)csp.lengthReason, reason);
+ return (client->noClientException = -1);
+ }
+
+ numScreens = screenInfo.numScreens;
+ lConnectionInfo = ConnectionInfo;
+ lconnSetupPrefix = &connSetupPrefix;
+
+ /* We're about to start speaking X protocol back to the client by
+ * sending the connection setup info. This means the authorization
+ * step is complete, and we can count the client as an
+ * authorized one.
+ */
+ nClients++;
+
+ client->requestVector = client->swapped ? SwappedProcVector : ProcVector;
+ client->sequence = 0;
+#ifdef XAPPGROUP
+ XagConnectionInfo (client, &lconnSetupPrefix, &lConnectionInfo, &numScreens);
+#endif
+ ((xConnSetup *)lConnectionInfo)->ridBase = client->clientAsMask;
+ ((xConnSetup *)lConnectionInfo)->ridMask = RESOURCE_ID_MASK;
+#ifdef MATCH_CLIENT_ENDIAN
+ ((xConnSetup *)lConnectionInfo)->imageByteOrder = ClientOrder (client);
+ ((xConnSetup *)lConnectionInfo)->bitmapBitOrder = ClientOrder (client);
+#endif
+ /* fill in the "currentInputMask" */
+ root = (xWindowRoot *)(lConnectionInfo + connBlockScreenStart);
+#ifdef PANORAMIX
+ if (noPanoramiXExtension)
+ numScreens = screenInfo.numScreens;
+ else
+ numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
+#endif
+
+ for (i=0; i<numScreens; i++)
+ {
+ register unsigned int j;
+ register xDepth *pDepth;
+
+ root->currentInputMask = WindowTable[i]->eventMask |
+ wOtherEventMasks (WindowTable[i]);
+ pDepth = (xDepth *)(root + 1);
+ for (j = 0; j < root->nDepths; j++)
+ {
+ pDepth = (xDepth *)(((char *)(pDepth + 1)) +
+ pDepth->nVisuals * sizeof(xVisualType));
+ }
+ root = (xWindowRoot *)pDepth;
+ }
+
+ if (client->swapped)
+ {
+ WriteSConnSetupPrefix(client, lconnSetupPrefix);
+ WriteSConnectionInfo(client,
+ (unsigned long)(lconnSetupPrefix->length << 2),
+ lConnectionInfo);
+ }
+ else
+ {
+ (void)WriteToClient(client, sizeof(xConnSetupPrefix),
+ (char *) lconnSetupPrefix);
+ (void)WriteToClient(client, (int)(lconnSetupPrefix->length << 2),
+ lConnectionInfo);
+ }
+ client->clientState = ClientStateRunning;
+ if (ClientStateCallback)
+ {
+ NewClientInfoRec clientinfo;
+
+ clientinfo.client = client;
+ clientinfo.prefix = lconnSetupPrefix;
+ clientinfo.setup = (xConnSetup *)lConnectionInfo;
+ CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+ }
+ return (client->noClientException);
+}
+
+int
+ProcEstablishConnection(register ClientPtr client)
+{
+ char *reason, *auth_proto, *auth_string;
+ register xConnClientPrefix *prefix;
+ REQUEST(xReq);
+
+ prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
+ auth_proto = (char *)prefix + sz_xConnClientPrefix;
+ auth_string = auth_proto + ((prefix->nbytesAuthProto + 3) & ~3);
+ if ((prefix->majorVersion != X_PROTOCOL) ||
+ (prefix->minorVersion != X_PROTOCOL_REVISION))
+ reason = "Protocol version mismatch";
+ else
+ reason = ClientAuthorized(client,
+ (unsigned short)prefix->nbytesAuthProto,
+ auth_proto,
+ (unsigned short)prefix->nbytesAuthString,
+ auth_string);
+ /*
+ * If Kerberos is being used for this client, the clientState
+ * will be set to ClientStateAuthenticating at this point.
+ * More messages need to be exchanged among the X server, Kerberos
+ * server, and client to figure out if everyone is authorized.
+ * So we don't want to send the connection setup info yet, since
+ * the auth step isn't really done.
+ */
+ if (client->clientState == ClientStateCheckingSecurity)
+ client->clientState = ClientStateCheckedSecurity;
+ else if (client->clientState != ClientStateAuthenticating)
+ return(SendConnSetup(client, reason));
+ return(client->noClientException);
+}
+
+void
+SendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode,
+ XID resId, int errorCode)
+{
+ xError rep;
+
+ rep.type = X_Error;
+ rep.sequenceNumber = client->sequence;
+ rep.errorCode = errorCode;
+ rep.majorCode = majorCode;
+ rep.minorCode = minorCode;
+ rep.resourceID = resId;
+
+ WriteEventsToClient (client, 1, (xEvent *)&rep);
+}
+
+void
+DeleteWindowFromAnySelections(WindowPtr pWin)
+{
+ register int i;
+
+ for (i = 0; i< NumCurrentSelections; i++)
+ if (CurrentSelections[i].pWin == pWin)
+ {
+ if (SelectionCallback)
+ {
+ SelectionInfoRec info;
+
+ info.selection = &CurrentSelections[i];
+ info.kind = SelectionWindowDestroy;
+ CallCallbacks(&SelectionCallback, &info);
+ }
+ CurrentSelections[i].pWin = (WindowPtr)NULL;
+ CurrentSelections[i].window = None;
+ CurrentSelections[i].client = NullClient;
+ }
+}
+
+static void
+DeleteClientFromAnySelections(ClientPtr client)
+{
+ register int i;
+
+ for (i = 0; i< NumCurrentSelections; i++)
+ if (CurrentSelections[i].client == client)
+ {
+ if (SelectionCallback)
+ {
+ SelectionInfoRec info;
+
+ info.selection = &CurrentSelections[i];
+ info.kind = SelectionWindowDestroy;
+ CallCallbacks(&SelectionCallback, &info);
+ }
+ CurrentSelections[i].pWin = (WindowPtr)NULL;
+ CurrentSelections[i].window = None;
+ CurrentSelections[i].client = NullClient;
+ }
+}
+
+void
+MarkClientException(ClientPtr client)
+{
+ client->noClientException = -1;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.X.original
new file mode 100644
index 000000000..6941456de
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.X.original
@@ -0,0 +1,4035 @@
+/* $XdotOrg: xc/programs/Xserver/dix/dispatch.c,v 1.13 2005/09/13 01:33:19 daniels Exp $ */
+/* $Xorg: dispatch.c,v 1.5 2001/02/09 02:04:40 xorgcvs Exp $ */
+/************************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+********************************************************/
+
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/dispatch.c,v 3.32 2003/11/10 18:21:45 tsi Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifdef PANORAMIX_DEBUG
+#include <stdio.h>
+int ProcInitialConnection();
+#endif
+
+#include "windowstr.h"
+#include <X11/fonts/fontstruct.h>
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "selection.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "opaque.h"
+#include "input.h"
+#include "servermd.h"
+#include "extnsionst.h"
+#include "dixfont.h"
+#include "dispatch.h"
+#include "swaprep.h"
+#include "swapreq.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+#ifdef XAPPGROUP
+#include <X11/extensions/Xagsrv.h>
+#endif
+#ifdef XKB
+#define XKB_IN_SERVER
+#include "inputstr.h"
+#include <X11/extensions/XKBsrv.h>
+#endif
+#ifdef LBX
+#include "lbxserve.h"
+#endif
+
+#define mskcnt ((MAXCLIENTS + 31) / 32)
+#define BITMASK(i) (1U << ((i) & 31))
+#define MASKIDX(i) ((i) >> 5)
+#define MASKWORD(buf, i) buf[MASKIDX(i)]
+#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
+#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
+#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
+
+extern xConnSetupPrefix connSetupPrefix;
+extern char *ConnectionInfo;
+
+Selection *CurrentSelections;
+int NumCurrentSelections;
+CallbackListPtr SelectionCallback = NULL;
+
+static ClientPtr grabClient;
+#define GrabNone 0
+#define GrabActive 1
+#define GrabKickout 2
+static int grabState = GrabNone;
+static long grabWaiters[mskcnt];
+CallbackListPtr ServerGrabCallback = NULL;
+HWEventQueuePtr checkForInput[2];
+extern int connBlockScreenStart;
+
+static void KillAllClients(void);
+
+static void DeleteClientFromAnySelections(ClientPtr client);
+
+static int nextFreeClientID; /* always MIN free client ID */
+
+static int nClients; /* number of authorized clients */
+
+CallbackListPtr ClientStateCallback;
+
+/* dispatchException & isItTimeToYield must be declared volatile since they
+ * are modified by signal handlers - otherwise optimizer may assume it doesn't
+ * need to actually check value in memory when used and may miss changes from
+ * signal handlers.
+ */
+volatile char dispatchException = 0;
+volatile char isItTimeToYield;
+
+/* Various of the DIX function interfaces were not designed to allow
+ * the client->errorValue to be set on BadValue and other errors.
+ * Rather than changing interfaces and breaking untold code we introduce
+ * a new global that dispatch can use.
+ */
+XID clientErrorValue; /* XXX this is a kludge */
+
+#define SAME_SCREENS(a, b) (\
+ (a.pScreen == b.pScreen))
+
+void
+SetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1)
+{
+ checkForInput[0] = c0;
+ checkForInput[1] = c1;
+}
+
+void
+UpdateCurrentTime()
+{
+ TimeStamp systime;
+
+ /* To avoid time running backwards, we must call GetTimeInMillis before
+ * calling ProcessInputEvents.
+ */
+ systime.months = currentTime.months;
+ systime.milliseconds = GetTimeInMillis();
+ if (systime.milliseconds < currentTime.milliseconds)
+ systime.months++;
+ if (*checkForInput[0] != *checkForInput[1])
+ ProcessInputEvents();
+ if (CompareTimeStamps(systime, currentTime) == LATER)
+ currentTime = systime;
+}
+
+/* Like UpdateCurrentTime, but can't call ProcessInputEvents */
+void
+UpdateCurrentTimeIf()
+{
+ TimeStamp systime;
+
+ systime.months = currentTime.months;
+ systime.milliseconds = GetTimeInMillis();
+ if (systime.milliseconds < currentTime.milliseconds)
+ systime.months++;
+ if (*checkForInput[0] == *checkForInput[1])
+ currentTime = systime;
+}
+
+void
+InitSelections()
+{
+ if (CurrentSelections)
+ xfree(CurrentSelections);
+ CurrentSelections = (Selection *)NULL;
+ NumCurrentSelections = 0;
+}
+
+void
+FlushClientCaches(XID id)
+{
+ int i;
+ register ClientPtr client;
+
+ client = clients[CLIENT_ID(id)];
+ if (client == NullClient)
+ return ;
+ for (i=0; i<currentMaxClients; i++)
+ {
+ client = clients[i];
+ if (client != NullClient)
+ {
+ if (client->lastDrawableID == id)
+ {
+ client->lastDrawableID = WindowTable[0]->drawable.id;
+ client->lastDrawable = (DrawablePtr)WindowTable[0];
+ }
+ else if (client->lastGCID == id)
+ {
+ client->lastGCID = INVALID;
+ client->lastGC = (GCPtr)NULL;
+ }
+ }
+ }
+}
+#ifdef SMART_SCHEDULE
+
+#undef SMART_DEBUG
+
+#define SMART_SCHEDULE_DEFAULT_INTERVAL 20 /* ms */
+#define SMART_SCHEDULE_MAX_SLICE 200 /* ms */
+
+Bool SmartScheduleDisable = FALSE;
+long SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
+long SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
+long SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
+long SmartScheduleTime;
+ClientPtr SmartLastClient;
+int SmartLastIndex[SMART_MAX_PRIORITY-SMART_MIN_PRIORITY+1];
+int SmartScheduleClient(int *clientReady, int nready);
+
+#ifdef SMART_DEBUG
+long SmartLastPrint;
+#endif
+
+void Dispatch(void);
+void InitProcVectors(void);
+
+int
+SmartScheduleClient (int *clientReady, int nready)
+{
+ ClientPtr pClient;
+ int i;
+ int client;
+ int bestPrio, best = 0;
+ int bestRobin, robin;
+ long now = SmartScheduleTime;
+ long idle;
+
+ bestPrio = -0x7fffffff;
+ bestRobin = 0;
+ idle = 2 * SmartScheduleSlice;
+ for (i = 0; i < nready; i++)
+ {
+ client = clientReady[i];
+ pClient = clients[client];
+ /* Praise clients which are idle */
+ if ((now - pClient->smart_check_tick) >= idle)
+ {
+ if (pClient->smart_priority < 0)
+ pClient->smart_priority++;
+ }
+ pClient->smart_check_tick = now;
+
+ /* check priority to select best client */
+ robin = (pClient->index - SmartLastIndex[pClient->smart_priority-SMART_MIN_PRIORITY]) & 0xff;
+ if (pClient->smart_priority > bestPrio ||
+ (pClient->smart_priority == bestPrio && robin > bestRobin))
+ {
+ bestPrio = pClient->smart_priority;
+ bestRobin = robin;
+ best = client;
+ }
+#ifdef SMART_DEBUG
+ if ((now - SmartLastPrint) >= 5000)
+ fprintf (stderr, " %2d: %3d", client, pClient->smart_priority);
+#endif
+ }
+#ifdef SMART_DEBUG
+ if ((now - SmartLastPrint) >= 5000)
+ {
+ fprintf (stderr, " use %2d\n", best);
+ SmartLastPrint = now;
+ }
+#endif
+ pClient = clients[best];
+ SmartLastIndex[bestPrio-SMART_MIN_PRIORITY] = pClient->index;
+ /*
+ * Set current client pointer
+ */
+ if (SmartLastClient != pClient)
+ {
+ pClient->smart_start_tick = now;
+ SmartLastClient = pClient;
+ }
+ /*
+ * Adjust slice
+ */
+ if (nready == 1)
+ {
+ /*
+ * If it's been a long time since another client
+ * has run, bump the slice up to get maximal
+ * performance from a single client
+ */
+ if ((now - pClient->smart_start_tick) > 1000 &&
+ SmartScheduleSlice < SmartScheduleMaxSlice)
+ {
+ SmartScheduleSlice += SmartScheduleInterval;
+ }
+ }
+ else
+ {
+ SmartScheduleSlice = SmartScheduleInterval;
+ }
+ return best;
+}
+#endif
+
+#define MAJOROP ((xReq *)client->requestBuffer)->reqType
+
+void
+Dispatch(void)
+{
+ register int *clientReady; /* array of request ready clients */
+ register int result;
+ register ClientPtr client;
+ register int nready;
+ register HWEventQueuePtr* icheck = checkForInput;
+#ifdef SMART_SCHEDULE
+ long start_tick;
+#endif
+
+ nextFreeClientID = 1;
+ InitSelections();
+ nClients = 0;
+
+ clientReady = (int *) ALLOCATE_LOCAL(sizeof(int) * MaxClients);
+ if (!clientReady)
+ return;
+
+ while (!dispatchException)
+ {
+ if (*icheck[0] != *icheck[1])
+ {
+ ProcessInputEvents();
+ FlushIfCriticalOutputPending();
+ }
+
+ nready = WaitForSomething(clientReady);
+
+#ifdef SMART_SCHEDULE
+ if (nready && !SmartScheduleDisable)
+ {
+ clientReady[0] = SmartScheduleClient (clientReady, nready);
+ nready = 1;
+ }
+#endif
+ /*****************
+ * Handle events in round robin fashion, doing input between
+ * each round
+ *****************/
+
+ while (!dispatchException && (--nready >= 0))
+ {
+ client = clients[clientReady[nready]];
+ if (! client)
+ {
+ /* KillClient can cause this to happen */
+ continue;
+ }
+ /* GrabServer activation can cause this to be true */
+ if (grabState == GrabKickout)
+ {
+ grabState = GrabActive;
+ break;
+ }
+ isItTimeToYield = FALSE;
+
+ requestingClient = client;
+#ifdef SMART_SCHEDULE
+ start_tick = SmartScheduleTime;
+#endif
+ while (!isItTimeToYield)
+ {
+ if (*icheck[0] != *icheck[1])
+ {
+ ProcessInputEvents();
+ FlushIfCriticalOutputPending();
+ }
+#ifdef SMART_SCHEDULE
+ if (!SmartScheduleDisable &&
+ (SmartScheduleTime - start_tick) >= SmartScheduleSlice)
+ {
+ /* Penalize clients which consume ticks */
+ if (client->smart_priority > SMART_MIN_PRIORITY)
+ client->smart_priority--;
+ break;
+ }
+#endif
+ /* now, finally, deal with client requests */
+
+ result = ReadRequestFromClient(client);
+ if (result <= 0)
+ {
+ if (result < 0)
+ CloseDownClient(client);
+ break;
+ }
+
+ client->sequence++;
+#ifdef DEBUG
+ if (client->requestLogIndex == MAX_REQUEST_LOG)
+ client->requestLogIndex = 0;
+ client->requestLog[client->requestLogIndex] = MAJOROP;
+ client->requestLogIndex++;
+#endif
+ if (result > (maxBigRequestSize << 2))
+ result = BadLength;
+ else
+ result = (* client->requestVector[MAJOROP])(client);
+
+ if (result != Success)
+ {
+ if (client->noClientException != Success)
+ CloseDownClient(client);
+ else
+ SendErrorToClient(client, MAJOROP,
+ MinorOpcodeOfRequest(client),
+ client->errorValue, result);
+ break;
+ }
+#ifdef DAMAGEEXT
+ FlushIfCriticalOutputPending ();
+#endif
+ }
+ FlushAllOutput();
+#ifdef SMART_SCHEDULE
+ client = clients[clientReady[nready]];
+ if (client)
+ client->smart_stop_tick = SmartScheduleTime;
+#endif
+ requestingClient = NULL;
+ }
+ dispatchException &= ~DE_PRIORITYCHANGE;
+ }
+#if defined(DDXBEFORERESET)
+ ddxBeforeReset ();
+#endif
+ KillAllClients();
+ DEALLOCATE_LOCAL(clientReady);
+ dispatchException &= ~DE_RESET;
+}
+
+#undef MAJOROP
+
+int
+ProcBadRequest(ClientPtr client)
+{
+ return (BadRequest);
+}
+
+int
+ProcCreateWindow(ClientPtr client)
+{
+ register WindowPtr pParent, pWin;
+ REQUEST(xCreateWindowReq);
+ int result;
+ int len;
+
+ REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
+
+ LEGAL_NEW_RESOURCE(stuff->wid, client);
+ if (!(pParent = (WindowPtr)SecurityLookupWindow(stuff->parent, client,
+ SecurityWriteAccess)))
+ return BadWindow;
+ len = client->req_len - (sizeof(xCreateWindowReq) >> 2);
+ if (Ones(stuff->mask) != len)
+ return BadLength;
+ if (!stuff->width || !stuff->height)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ pWin = CreateWindow(stuff->wid, pParent, stuff->x,
+ stuff->y, stuff->width, stuff->height,
+ stuff->borderWidth, stuff->class,
+ stuff->mask, (XID *) &stuff[1],
+ (int)stuff->depth,
+ client, stuff->visual, &result);
+ if (pWin)
+ {
+ Mask mask = pWin->eventMask;
+
+ pWin->eventMask = 0; /* subterfuge in case AddResource fails */
+ if (!AddResource(stuff->wid, RT_WINDOW, (pointer)pWin))
+ return BadAlloc;
+ pWin->eventMask = mask;
+ }
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+int
+ProcChangeWindowAttributes(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xChangeWindowAttributesReq);
+ register int result;
+ int len;
+
+ REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ len = client->req_len - (sizeof(xChangeWindowAttributesReq) >> 2);
+ if (len != Ones(stuff->valueMask))
+ return BadLength;
+ result = ChangeWindowAttributes(pWin,
+ stuff->valueMask,
+ (XID *) &stuff[1],
+ client);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+int
+ProcGetWindowAttributes(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+ xGetWindowAttributesReply wa;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ GetWindowAttributes(pWin, client, &wa);
+ WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa);
+ return(client->noClientException);
+}
+
+int
+ProcDestroyWindow(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityDestroyAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (pWin->parent)
+ FreeResource(stuff->id, RT_NONE);
+ return(client->noClientException);
+}
+
+int
+ProcDestroySubwindows(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityDestroyAccess);
+ if (!pWin)
+ return(BadWindow);
+ DestroySubwindows(pWin, client);
+ return(client->noClientException);
+}
+
+int
+ProcChangeSaveSet(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xChangeSaveSetReq);
+ register int result;
+
+ REQUEST_SIZE_MATCH(xChangeSaveSetReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id)))
+ return BadMatch;
+ if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete))
+ {
+ result = AlterSaveSetForClient(client, pWin, stuff->mode, FALSE, TRUE);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+ }
+ else
+ {
+ client->errorValue = stuff->mode;
+ return( BadValue );
+ }
+}
+
+int
+ProcReparentWindow(register ClientPtr client)
+{
+ register WindowPtr pWin, pParent;
+ REQUEST(xReparentWindowReq);
+ register int result;
+
+ REQUEST_SIZE_MATCH(xReparentWindowReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ pParent = (WindowPtr)SecurityLookupWindow(stuff->parent, client,
+ SecurityWriteAccess);
+ if (!pParent)
+ return(BadWindow);
+ if (SAME_SCREENS(pWin->drawable, pParent->drawable))
+ {
+ if ((pWin->backgroundState == ParentRelative) &&
+ (pParent->drawable.depth != pWin->drawable.depth))
+ return BadMatch;
+ if ((pWin->drawable.class != InputOnly) &&
+ (pParent->drawable.class == InputOnly))
+ return BadMatch;
+ result = ReparentWindow(pWin, pParent,
+ (short)stuff->x, (short)stuff->y, client);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+ }
+ else
+ return (BadMatch);
+}
+
+int
+ProcMapWindow(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ MapWindow(pWin, client);
+ /* update cache to say it is mapped */
+ return(client->noClientException);
+}
+
+int
+ProcMapSubwindows(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ MapSubwindows(pWin, client);
+ /* update cache to say it is mapped */
+ return(client->noClientException);
+}
+
+int
+ProcUnmapWindow(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ UnmapWindow(pWin, FALSE);
+ /* update cache to say it is mapped */
+ return(client->noClientException);
+}
+
+int
+ProcUnmapSubwindows(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ UnmapSubwindows(pWin);
+ return(client->noClientException);
+}
+
+int
+ProcConfigureWindow(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xConfigureWindowReq);
+ register int result;
+ int len;
+
+ REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
+ pWin = (WindowPtr)SecurityLookupWindow( stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ len = client->req_len - (sizeof(xConfigureWindowReq) >> 2);
+ if (Ones((Mask)stuff->mask) != len)
+ return BadLength;
+ result = ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1],
+ client);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+int
+ProcCirculateWindow(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xCirculateWindowReq);
+
+ REQUEST_SIZE_MATCH(xCirculateWindowReq);
+ if ((stuff->direction != RaiseLowest) &&
+ (stuff->direction != LowerHighest))
+ {
+ client->errorValue = stuff->direction;
+ return BadValue;
+ }
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ CirculateWindow(pWin, (int)stuff->direction, client);
+ return(client->noClientException);
+}
+
+int
+GetGeometry(register ClientPtr client, xGetGeometryReply *rep)
+{
+ register DrawablePtr pDraw;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->id, client, SecurityReadAccess);
+ rep->type = X_Reply;
+ rep->length = 0;
+ rep->sequenceNumber = client->sequence;
+ rep->root = WindowTable[pDraw->pScreen->myNum]->drawable.id;
+ rep->depth = pDraw->depth;
+ rep->width = pDraw->width;
+ rep->height = pDraw->height;
+
+ /* XXX - Because the pixmap-implementation of the multibuffer extension
+ * may have the buffer-id's drawable resource value be a pointer
+ * to the buffer's window instead of the buffer itself
+ * (this happens if the buffer is the displayed buffer),
+ * we also have to check that the id matches before we can
+ * truly say that it is a DRAWABLE_WINDOW.
+ */
+
+ if ((pDraw->type == UNDRAWABLE_WINDOW) ||
+ ((pDraw->type == DRAWABLE_WINDOW) && (stuff->id == pDraw->id)))
+ {
+ register WindowPtr pWin = (WindowPtr)pDraw;
+ rep->x = pWin->origin.x - wBorderWidth (pWin);
+ rep->y = pWin->origin.y - wBorderWidth (pWin);
+ rep->borderWidth = pWin->borderWidth;
+ }
+ else /* DRAWABLE_PIXMAP or DRAWABLE_BUFFER */
+ {
+ rep->x = rep->y = rep->borderWidth = 0;
+ }
+
+ return Success;
+}
+
+
+int
+ProcGetGeometry(register ClientPtr client)
+{
+ xGetGeometryReply rep;
+ int status;
+
+ if ((status = GetGeometry(client, &rep)) != Success)
+ return status;
+
+ WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
+ return(client->noClientException);
+}
+
+
+int
+ProcQueryTree(register ClientPtr client)
+{
+ xQueryTreeReply reply;
+ int numChildren = 0;
+ register WindowPtr pChild, pWin, pHead;
+ Window *childIDs = (Window *)NULL;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ reply.type = X_Reply;
+ reply.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
+ reply.sequenceNumber = client->sequence;
+ if (pWin->parent)
+ reply.parent = pWin->parent->drawable.id;
+ else
+ reply.parent = (Window)None;
+ pHead = RealChildHead(pWin);
+ for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+ numChildren++;
+ if (numChildren)
+ {
+ int curChild = 0;
+
+ childIDs = (Window *) ALLOCATE_LOCAL(numChildren * sizeof(Window));
+ if (!childIDs)
+ return BadAlloc;
+ for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+ childIDs[curChild++] = pChild->drawable.id;
+ }
+
+ reply.nChildren = numChildren;
+ reply.length = (numChildren * sizeof(Window)) >> 2;
+
+ WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply);
+ if (numChildren)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, numChildren * sizeof(Window), childIDs);
+ DEALLOCATE_LOCAL(childIDs);
+ }
+
+ return(client->noClientException);
+}
+
+int
+ProcInternAtom(register ClientPtr client)
+{
+ Atom atom;
+ char *tchar;
+ REQUEST(xInternAtomReq);
+
+ REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes);
+ if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse))
+ {
+ client->errorValue = stuff->onlyIfExists;
+ return(BadValue);
+ }
+ tchar = (char *) &stuff[1];
+ atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists);
+ if (atom != BAD_RESOURCE)
+ {
+ xInternAtomReply reply;
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ reply.atom = atom;
+ WriteReplyToClient(client, sizeof(xInternAtomReply), &reply);
+ return(client->noClientException);
+ }
+ else
+ return (BadAlloc);
+}
+
+int
+ProcGetAtomName(register ClientPtr client)
+{
+ char *str;
+ xGetAtomNameReply reply;
+ int len;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ if ( (str = NameForAtom(stuff->id)) )
+ {
+ len = strlen(str);
+ reply.type = X_Reply;
+ reply.length = (len + 3) >> 2;
+ reply.sequenceNumber = client->sequence;
+ reply.nameLength = len;
+ WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply);
+ (void)WriteToClient(client, len, str);
+ return(client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadAtom);
+ }
+}
+
+#ifdef K5AUTH
+extern int k5_bad();
+#endif
+
+int
+ProcSetSelectionOwner(register ClientPtr client)
+{
+ WindowPtr pWin;
+ TimeStamp time;
+ REQUEST(xSetSelectionOwnerReq);
+
+ REQUEST_SIZE_MATCH(xSetSelectionOwnerReq);
+ UpdateCurrentTime();
+ time = ClientTimeToServerTime(stuff->time);
+
+ /* If the client's time stamp is in the future relative to the server's
+ time stamp, do not set the selection, just return success. */
+ if (CompareTimeStamps(time, currentTime) == LATER)
+ return Success;
+ if (stuff->window != None)
+ {
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ }
+ else
+ pWin = (WindowPtr)None;
+ if (ValidAtom(stuff->selection))
+ {
+ int i = 0;
+
+ /*
+ * First, see if the selection is already set...
+ */
+ while ((i < NumCurrentSelections) &&
+ CurrentSelections[i].selection != stuff->selection)
+ i++;
+ if (i < NumCurrentSelections)
+ {
+ xEvent event;
+
+ /* If the timestamp in client's request is in the past relative
+ to the time stamp indicating the last time the owner of the
+ selection was set, do not set the selection, just return
+ success. */
+ if (CompareTimeStamps(time, CurrentSelections[i].lastTimeChanged)
+ == EARLIER)
+ return Success;
+ if (CurrentSelections[i].client &&
+ (!pWin || (CurrentSelections[i].client != client)))
+ {
+ event.u.u.type = SelectionClear;
+ event.u.selectionClear.time = time.milliseconds;
+ event.u.selectionClear.window = CurrentSelections[i].window;
+ event.u.selectionClear.atom = CurrentSelections[i].selection;
+ (void) TryClientEvents (CurrentSelections[i].client, &event, 1,
+ NoEventMask, NoEventMask /* CantBeFiltered */,
+ NullGrab);
+ }
+ }
+ else
+ {
+ /*
+ * It doesn't exist, so add it...
+ */
+ Selection *newsels;
+
+ if (i == 0)
+ newsels = (Selection *)xalloc(sizeof(Selection));
+ else
+ newsels = (Selection *)xrealloc(CurrentSelections,
+ (NumCurrentSelections + 1) * sizeof(Selection));
+ if (!newsels)
+ return BadAlloc;
+ NumCurrentSelections++;
+ CurrentSelections = newsels;
+ CurrentSelections[i].selection = stuff->selection;
+ }
+ CurrentSelections[i].lastTimeChanged = time;
+ CurrentSelections[i].window = stuff->window;
+ CurrentSelections[i].pWin = pWin;
+ CurrentSelections[i].client = (pWin ? client : NullClient);
+ if (SelectionCallback)
+ {
+ SelectionInfoRec info;
+
+ info.selection = &CurrentSelections[i];
+ info.kind= SelectionSetOwner;
+ CallCallbacks(&SelectionCallback, &info);
+ }
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->selection;
+ return (BadAtom);
+ }
+}
+
+int
+ProcGetSelectionOwner(register ClientPtr client)
+{
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ if (ValidAtom(stuff->id))
+ {
+ int i;
+ xGetSelectionOwnerReply reply;
+
+ i = 0;
+ while ((i < NumCurrentSelections) &&
+ CurrentSelections[i].selection != stuff->id) i++;
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ if (i < NumCurrentSelections)
+ reply.owner = CurrentSelections[i].window;
+ else
+ reply.owner = None;
+ WriteReplyToClient(client, sizeof(xGetSelectionOwnerReply), &reply);
+ return(client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadAtom);
+ }
+}
+
+int
+ProcConvertSelection(register ClientPtr client)
+{
+ Bool paramsOkay;
+ xEvent event;
+ WindowPtr pWin;
+ REQUEST(xConvertSelectionReq);
+
+ REQUEST_SIZE_MATCH(xConvertSelectionReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->requestor, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+
+ paramsOkay = (ValidAtom(stuff->selection) && ValidAtom(stuff->target));
+ if (stuff->property != None)
+ paramsOkay &= ValidAtom(stuff->property);
+ if (paramsOkay)
+ {
+ int i;
+
+ i = 0;
+ while ((i < NumCurrentSelections) &&
+ CurrentSelections[i].selection != stuff->selection) i++;
+ if ((i < NumCurrentSelections) &&
+ (CurrentSelections[i].window != None)
+#ifdef XCSECURITY
+ && (!client->CheckAccess ||
+ (* client->CheckAccess)(client, CurrentSelections[i].window,
+ RT_WINDOW, SecurityReadAccess,
+ CurrentSelections[i].pWin))
+#endif
+ )
+ {
+ event.u.u.type = SelectionRequest;
+ event.u.selectionRequest.time = stuff->time;
+ event.u.selectionRequest.owner =
+ CurrentSelections[i].window;
+ event.u.selectionRequest.requestor = stuff->requestor;
+ event.u.selectionRequest.selection = stuff->selection;
+ event.u.selectionRequest.target = stuff->target;
+ event.u.selectionRequest.property = stuff->property;
+ if (TryClientEvents(
+ CurrentSelections[i].client, &event, 1, NoEventMask,
+ NoEventMask /* CantBeFiltered */, NullGrab))
+ return (client->noClientException);
+ }
+ event.u.u.type = SelectionNotify;
+ event.u.selectionNotify.time = stuff->time;
+ event.u.selectionNotify.requestor = stuff->requestor;
+ event.u.selectionNotify.selection = stuff->selection;
+ event.u.selectionNotify.target = stuff->target;
+ event.u.selectionNotify.property = None;
+ (void) TryClientEvents(client, &event, 1, NoEventMask,
+ NoEventMask /* CantBeFiltered */, NullGrab);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->property;
+ return (BadAtom);
+ }
+}
+
+int
+ProcGrabServer(register ClientPtr client)
+{
+ REQUEST_SIZE_MATCH(xReq);
+ if (grabState != GrabNone && client != grabClient)
+ {
+ ResetCurrentRequest(client);
+ client->sequence--;
+ BITSET(grabWaiters, client->index);
+ IgnoreClient(client);
+ return(client->noClientException);
+ }
+ OnlyListenToOneClient(client);
+ grabState = GrabKickout;
+ grabClient = client;
+
+ if (ServerGrabCallback)
+ {
+ ServerGrabInfoRec grabinfo;
+ grabinfo.client = client;
+ grabinfo.grabstate = SERVER_GRABBED;
+ CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
+ }
+
+ return(client->noClientException);
+}
+
+static void
+UngrabServer(ClientPtr client)
+{
+ int i;
+
+ grabState = GrabNone;
+ ListenToAllClients();
+ for (i = mskcnt; --i >= 0 && !grabWaiters[i]; )
+ ;
+ if (i >= 0)
+ {
+ i <<= 5;
+ while (!GETBIT(grabWaiters, i))
+ i++;
+ BITCLEAR(grabWaiters, i);
+ AttendClient(clients[i]);
+ }
+
+ if (ServerGrabCallback)
+ {
+ ServerGrabInfoRec grabinfo;
+ grabinfo.client = client;
+ grabinfo.grabstate = SERVER_UNGRABBED;
+ CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
+ }
+}
+
+int
+ProcUngrabServer(register ClientPtr client)
+{
+ REQUEST_SIZE_MATCH(xReq);
+ UngrabServer(client);
+ return(client->noClientException);
+}
+
+int
+ProcTranslateCoords(register ClientPtr client)
+{
+ REQUEST(xTranslateCoordsReq);
+
+ register WindowPtr pWin, pDst;
+ xTranslateCoordsReply rep;
+
+ REQUEST_SIZE_MATCH(xTranslateCoordsReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->srcWid, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ pDst = (WindowPtr)SecurityLookupWindow(stuff->dstWid, client,
+ SecurityReadAccess);
+ if (!pDst)
+ return(BadWindow);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ if (!SAME_SCREENS(pWin->drawable, pDst->drawable))
+ {
+ rep.sameScreen = xFalse;
+ rep.child = None;
+ rep.dstX = rep.dstY = 0;
+ }
+ else
+ {
+ INT16 x, y;
+ rep.sameScreen = xTrue;
+ rep.child = None;
+ /* computing absolute coordinates -- adjust to destination later */
+ x = pWin->drawable.x + stuff->srcX;
+ y = pWin->drawable.y + stuff->srcY;
+ pWin = pDst->firstChild;
+ while (pWin)
+ {
+#ifdef SHAPE
+ BoxRec box;
+#endif
+ 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))
+#ifdef SHAPE
+ /* When a window is shaped, a further check
+ * is made to see if the point is inside
+ * borderSize
+ */
+ && (!wBoundingShape(pWin) ||
+ POINT_IN_REGION(pWin->drawable.pScreen,
+ &pWin->borderSize, x, y, &box))
+
+ && (!wInputShape(pWin) ||
+ POINT_IN_REGION(pWin->drawable.pScreen,
+ wInputShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box))
+#endif
+ )
+ {
+ rep.child = pWin->drawable.id;
+ pWin = (WindowPtr) NULL;
+ }
+ else
+ pWin = pWin->nextSib;
+ }
+ /* adjust to destination coordinates */
+ rep.dstX = x - pDst->drawable.x;
+ rep.dstY = y - pDst->drawable.y;
+ }
+ WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep);
+ return(client->noClientException);
+}
+
+int
+ProcOpenFont(register ClientPtr client)
+{
+ int err;
+ REQUEST(xOpenFontReq);
+
+ REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes);
+ client->errorValue = stuff->fid;
+ LEGAL_NEW_RESOURCE(stuff->fid, client);
+ err = OpenFont(client, stuff->fid, (Mask) 0,
+ stuff->nbytes, (char *)&stuff[1]);
+ if (err == Success)
+ {
+ return(client->noClientException);
+ }
+ else
+ return err;
+}
+
+int
+ProcCloseFont(register ClientPtr client)
+{
+ FontPtr pFont;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
+ SecurityDestroyAccess);
+ if ( pFont != (FontPtr)NULL) /* id was valid */
+ {
+ FreeResource(stuff->id, RT_NONE);
+ return(client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadFont);
+ }
+}
+
+int
+ProcQueryFont(register ClientPtr client)
+{
+ xQueryFontReply *reply;
+ FontPtr pFont;
+ register GC *pGC;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ client->errorValue = stuff->id; /* EITHER font or gc */
+ pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
+ SecurityReadAccess);
+ if (!pFont)
+ {
+ /* can't use VERIFY_GC because it might return BadGC */
+ pGC = (GC *) SecurityLookupIDByType(client, stuff->id, RT_GC,
+ SecurityReadAccess);
+ if (!pGC)
+ {
+ client->errorValue = stuff->id;
+ return(BadFont); /* procotol spec says only error is BadFont */
+ }
+ pFont = pGC->font;
+ }
+
+ {
+ xCharInfo *pmax = FONTINKMAX(pFont);
+ xCharInfo *pmin = FONTINKMIN(pFont);
+ int nprotoxcistructs;
+ int rlength;
+
+ nprotoxcistructs = (
+ pmax->rightSideBearing == pmin->rightSideBearing &&
+ pmax->leftSideBearing == pmin->leftSideBearing &&
+ pmax->descent == pmin->descent &&
+ pmax->ascent == pmin->ascent &&
+ pmax->characterWidth == pmin->characterWidth) ?
+ 0 : N2dChars(pFont);
+
+ rlength = sizeof(xQueryFontReply) +
+ FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp) +
+ nprotoxcistructs * sizeof(xCharInfo);
+ reply = (xQueryFontReply *)ALLOCATE_LOCAL(rlength);
+ if(!reply)
+ {
+ return(BadAlloc);
+ }
+
+ reply->type = X_Reply;
+ reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+ reply->sequenceNumber = client->sequence;
+ QueryFont( pFont, reply, nprotoxcistructs);
+
+ WriteReplyToClient(client, rlength, reply);
+ DEALLOCATE_LOCAL(reply);
+ return(client->noClientException);
+ }
+}
+
+int
+ProcQueryTextExtents(register ClientPtr client)
+{
+ REQUEST(xQueryTextExtentsReq);
+ xQueryTextExtentsReply reply;
+ FontPtr pFont;
+ GC *pGC;
+ ExtentInfoRec info;
+ unsigned long length;
+
+ REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq);
+
+ pFont = (FontPtr)SecurityLookupIDByType(client, stuff->fid, RT_FONT,
+ SecurityReadAccess);
+ if (!pFont)
+ {
+ pGC = (GC *)SecurityLookupIDByType(client, stuff->fid, RT_GC,
+ SecurityReadAccess);
+ if (!pGC)
+ {
+ client->errorValue = stuff->fid;
+ return(BadFont);
+ }
+ pFont = pGC->font;
+ }
+ length = client->req_len - (sizeof(xQueryTextExtentsReq) >> 2);
+ length = length << 1;
+ if (stuff->oddLength)
+ {
+ if (length == 0)
+ return(BadLength);
+ length--;
+ }
+ if (!QueryTextExtents(pFont, length, (unsigned char *)&stuff[1], &info))
+ return(BadAlloc);
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ reply.drawDirection = info.drawDirection;
+ reply.fontAscent = info.fontAscent;
+ reply.fontDescent = info.fontDescent;
+ reply.overallAscent = info.overallAscent;
+ reply.overallDescent = info.overallDescent;
+ reply.overallWidth = info.overallWidth;
+ reply.overallLeft = info.overallLeft;
+ reply.overallRight = info.overallRight;
+ WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply);
+ return(client->noClientException);
+}
+
+int
+ProcListFonts(register ClientPtr client)
+{
+ REQUEST(xListFontsReq);
+
+ REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes);
+
+ return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes,
+ stuff->maxNames);
+}
+
+int
+ProcListFontsWithInfo(register ClientPtr client)
+{
+ REQUEST(xListFontsWithInfoReq);
+
+ REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes);
+
+ return StartListFontsWithInfo(client, stuff->nbytes,
+ (unsigned char *) &stuff[1], stuff->maxNames);
+}
+
+/**
+ *
+ * \param value must conform to DeleteType
+ */
+int
+dixDestroyPixmap(pointer value, XID pid)
+{
+ PixmapPtr pPixmap = (PixmapPtr)value;
+ return (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
+}
+
+int
+ProcCreatePixmap(register ClientPtr client)
+{
+ PixmapPtr pMap;
+ register DrawablePtr pDraw;
+ REQUEST(xCreatePixmapReq);
+ DepthPtr pDepth;
+ register int i;
+
+ REQUEST_SIZE_MATCH(xCreatePixmapReq);
+ client->errorValue = stuff->pid;
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+ SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->drawable, client,
+ SecurityReadAccess);
+ if (!stuff->width || !stuff->height)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ if (stuff->width > 32767 || stuff->height > 32767)
+ {
+ /* It is allowed to try and allocate a pixmap which is larger than
+ * 32767 in either dimension. However, all of the framebuffer code
+ * is buggy and does not reliably draw to such big pixmaps, basically
+ * because the Region data structure operates with signed shorts
+ * for the rectangles in it.
+ *
+ * Furthermore, several places in the X server computes the
+ * size in bytes of the pixmap and tries to store it in an
+ * integer. This integer can overflow and cause the allocated size
+ * to be much smaller.
+ *
+ * So, such big pixmaps are rejected here with a BadAlloc
+ */
+ 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:
+ pMap = (PixmapPtr)(*pDraw->pScreen->CreatePixmap)
+ (pDraw->pScreen, stuff->width,
+ stuff->height, stuff->depth);
+ if (pMap)
+ {
+ pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pMap->drawable.id = stuff->pid;
+ if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
+ return(client->noClientException);
+ }
+ return (BadAlloc);
+}
+
+int
+ProcFreePixmap(register ClientPtr client)
+{
+ PixmapPtr pMap;
+
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pMap = (PixmapPtr)SecurityLookupIDByType(client, stuff->id, RT_PIXMAP,
+ SecurityDestroyAccess);
+ if (pMap)
+ {
+ FreeResource(stuff->id, RT_NONE);
+ return(client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadPixmap);
+ }
+}
+
+int
+ProcCreateGC(register ClientPtr client)
+{
+ int error;
+ GC *pGC;
+ register DrawablePtr pDraw;
+ unsigned len;
+ REQUEST(xCreateGCReq);
+
+ REQUEST_AT_LEAST_SIZE(xCreateGCReq);
+ client->errorValue = stuff->gc;
+ LEGAL_NEW_RESOURCE(stuff->gc, client);
+ SECURITY_VERIFY_DRAWABLE (pDraw, stuff->drawable, client,
+ SecurityReadAccess);
+ len = client->req_len - (sizeof(xCreateGCReq) >> 2);
+ if (len != Ones(stuff->mask))
+ return BadLength;
+ pGC = (GC *)CreateGC(pDraw, stuff->mask,
+ (XID *) &stuff[1], &error);
+ if (error != Success)
+ return error;
+ if (!AddResource(stuff->gc, RT_GC, (pointer)pGC))
+ return (BadAlloc);
+ return(client->noClientException);
+}
+
+int
+ProcChangeGC(register ClientPtr client)
+{
+ GC *pGC;
+ REQUEST(xChangeGCReq);
+ int result;
+ unsigned len;
+
+ REQUEST_AT_LEAST_SIZE(xChangeGCReq);
+ SECURITY_VERIFY_GC(pGC, stuff->gc, client, SecurityWriteAccess);
+ len = client->req_len - (sizeof(xChangeGCReq) >> 2);
+ if (len != Ones(stuff->mask))
+ return BadLength;
+
+ result = dixChangeGC(client, pGC, stuff->mask, (CARD32 *) &stuff[1], 0);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return(result);
+ }
+}
+
+int
+ProcCopyGC(register ClientPtr client)
+{
+ register GC *dstGC;
+ register GC *pGC;
+ int result;
+ REQUEST(xCopyGCReq);
+
+ REQUEST_SIZE_MATCH(xCopyGCReq);
+ SECURITY_VERIFY_GC( pGC, stuff->srcGC, client, SecurityReadAccess);
+ SECURITY_VERIFY_GC( dstGC, stuff->dstGC, client, SecurityWriteAccess);
+ if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth))
+ return (BadMatch);
+ result = CopyGC(pGC, dstGC, stuff->mask);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return(result);
+ }
+}
+
+int
+ProcSetDashes(register ClientPtr client)
+{
+ register GC *pGC;
+ int result;
+ REQUEST(xSetDashesReq);
+
+ REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
+ if (stuff->nDashes == 0)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+
+ SECURITY_VERIFY_GC(pGC,stuff->gc, client, SecurityWriteAccess);
+
+ result = SetDashes(pGC, stuff->dashOffset, stuff->nDashes,
+ (unsigned char *)&stuff[1]);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return(result);
+ }
+}
+
+int
+ProcSetClipRectangles(register ClientPtr client)
+{
+ int nr;
+ int result;
+ register GC *pGC;
+ REQUEST(xSetClipRectanglesReq);
+
+ REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
+ if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
+ (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded))
+ {
+ client->errorValue = stuff->ordering;
+ return BadValue;
+ }
+ SECURITY_VERIFY_GC(pGC,stuff->gc, client, SecurityWriteAccess);
+
+ nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq);
+ if (nr & 4)
+ return(BadLength);
+ nr >>= 3;
+ result = SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin,
+ nr, (xRectangle *)&stuff[1], (int)stuff->ordering);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+int
+ProcFreeGC(register ClientPtr client)
+{
+ register GC *pGC;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ SECURITY_VERIFY_GC(pGC, stuff->id, client, SecurityDestroyAccess);
+ FreeResource(stuff->id, RT_NONE);
+ return(client->noClientException);
+}
+
+int
+ProcClearToBackground(register ClientPtr client)
+{
+ REQUEST(xClearAreaReq);
+ register WindowPtr pWin;
+
+ REQUEST_SIZE_MATCH(xClearAreaReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (pWin->drawable.class == InputOnly)
+ {
+ client->errorValue = stuff->window;
+ return (BadMatch);
+ }
+ if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse))
+ {
+ client->errorValue = stuff->exposures;
+ return(BadValue);
+ }
+ (*pWin->drawable.pScreen->ClearToBackground)(pWin, stuff->x, stuff->y,
+ stuff->width, stuff->height,
+ (Bool)stuff->exposures);
+ return(client->noClientException);
+}
+
+int
+ProcCopyArea(register ClientPtr client)
+{
+ register DrawablePtr pDst;
+ register DrawablePtr pSrc;
+ register GC *pGC;
+ REQUEST(xCopyAreaReq);
+ RegionPtr pRgn;
+
+ REQUEST_SIZE_MATCH(xCopyAreaReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, pGC, client);
+ if (stuff->dstDrawable != stuff->srcDrawable)
+ {
+ SECURITY_VERIFY_DRAWABLE(pSrc, stuff->srcDrawable, client,
+ SecurityReadAccess);
+ if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth))
+ {
+ client->errorValue = stuff->dstDrawable;
+ return (BadMatch);
+ }
+ }
+ else
+ pSrc = pDst;
+
+ SET_DBE_SRCBUF(pSrc, stuff->srcDrawable);
+
+ pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, stuff->srcX, stuff->srcY,
+ stuff->width, stuff->height,
+ stuff->dstX, stuff->dstY);
+ if (pGC->graphicsExposures)
+ {
+ (*pDst->pScreen->SendGraphicsExpose)
+ (client, pRgn, stuff->dstDrawable, X_CopyArea, 0);
+ if (pRgn)
+ REGION_DESTROY(pDst->pScreen, pRgn);
+ }
+
+ return(client->noClientException);
+}
+
+int
+ProcCopyPlane(register ClientPtr client)
+{
+ register DrawablePtr psrcDraw, pdstDraw;
+ register GC *pGC;
+ REQUEST(xCopyPlaneReq);
+ RegionPtr pRgn;
+
+ REQUEST_SIZE_MATCH(xCopyPlaneReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, pGC, client);
+ if (stuff->dstDrawable != stuff->srcDrawable)
+ {
+ SECURITY_VERIFY_DRAWABLE(psrcDraw, stuff->srcDrawable, client,
+ SecurityReadAccess);
+ if (pdstDraw->pScreen != psrcDraw->pScreen)
+ {
+ client->errorValue = stuff->dstDrawable;
+ return (BadMatch);
+ }
+ }
+ else
+ psrcDraw = pdstDraw;
+
+ SET_DBE_SRCBUF(psrcDraw, stuff->srcDrawable);
+
+ /* Check to see if stuff->bitPlane has exactly ONE good bit set */
+ 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)
+ {
+ (*pdstDraw->pScreen->SendGraphicsExpose)
+ (client, pRgn, stuff->dstDrawable, X_CopyPlane, 0);
+ if (pRgn)
+ REGION_DESTROY(pdstDraw->pScreen, pRgn);
+ }
+ return(client->noClientException);
+}
+
+int
+ProcPolyPoint(register ClientPtr client)
+{
+ int npoint;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyPointReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyPointReq);
+ if ((stuff->coordMode != CoordModeOrigin) &&
+ (stuff->coordMode != CoordModePrevious))
+ {
+ client->errorValue = stuff->coordMode;
+ return BadValue;
+ }
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ npoint = ((client->req_len << 2) - sizeof(xPolyPointReq)) >> 2;
+ if (npoint)
+ (*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint,
+ (xPoint *) &stuff[1]);
+ return (client->noClientException);
+}
+
+int
+ProcPolyLine(register ClientPtr client)
+{
+ int npoint;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyLineReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyLineReq);
+ if ((stuff->coordMode != CoordModeOrigin) &&
+ (stuff->coordMode != CoordModePrevious))
+ {
+ client->errorValue = stuff->coordMode;
+ return BadValue;
+ }
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ npoint = ((client->req_len << 2) - sizeof(xPolyLineReq)) >> 2;
+ if (npoint > 1)
+ (*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint,
+ (DDXPointPtr) &stuff[1]);
+ return(client->noClientException);
+}
+
+int
+ProcPolySegment(register ClientPtr client)
+{
+ int nsegs;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolySegmentReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
+ if (nsegs & 4)
+ return(BadLength);
+ nsegs >>= 3;
+ if (nsegs)
+ (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]);
+ return (client->noClientException);
+}
+
+int
+ProcPolyRectangle (register ClientPtr client)
+{
+ int nrects;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyRectangleReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
+ if (nrects & 4)
+ return(BadLength);
+ nrects >>= 3;
+ if (nrects)
+ (*pGC->ops->PolyRectangle)(pDraw, pGC,
+ nrects, (xRectangle *) &stuff[1]);
+ return(client->noClientException);
+}
+
+int
+ProcPolyArc(register ClientPtr client)
+{
+ int narcs;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyArcReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyArcReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
+ if (narcs % sizeof(xArc))
+ return(BadLength);
+ narcs /= sizeof(xArc);
+ if (narcs)
+ (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]);
+ return (client->noClientException);
+}
+
+int
+ProcFillPoly(register ClientPtr client)
+{
+ int things;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xFillPolyReq);
+
+ REQUEST_AT_LEAST_SIZE(xFillPolyReq);
+ if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) &&
+ (stuff->shape != Convex))
+ {
+ client->errorValue = stuff->shape;
+ return BadValue;
+ }
+ if ((stuff->coordMode != CoordModeOrigin) &&
+ (stuff->coordMode != CoordModePrevious))
+ {
+ client->errorValue = stuff->coordMode;
+ return BadValue;
+ }
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ things = ((client->req_len << 2) - sizeof(xFillPolyReq)) >> 2;
+ if (things)
+ (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape,
+ stuff->coordMode, things,
+ (DDXPointPtr) &stuff[1]);
+ return(client->noClientException);
+}
+
+int
+ProcPolyFillRectangle(register ClientPtr client)
+{
+ int things;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyFillRectangleReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
+ if (things & 4)
+ return(BadLength);
+ things >>= 3;
+
+ if (things)
+ (*pGC->ops->PolyFillRect) (pDraw, pGC, things,
+ (xRectangle *) &stuff[1]);
+ return (client->noClientException);
+}
+
+int
+ProcPolyFillArc(register ClientPtr client)
+{
+ int narcs;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyFillArcReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
+ if (narcs % sizeof(xArc))
+ return(BadLength);
+ narcs /= sizeof(xArc);
+ if (narcs)
+ (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
+ return (client->noClientException);
+}
+
+#ifdef MATCH_CLIENT_ENDIAN
+
+int
+ServerOrder (void)
+{
+ int whichbyte = 1;
+
+ if (*((char *) &whichbyte))
+ return LSBFirst;
+ return MSBFirst;
+}
+
+#define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder())
+
+void
+ReformatImage (char *base, int nbytes, int bpp, int order)
+{
+ switch (bpp) {
+ case 1: /* yuck */
+ if (BITMAP_BIT_ORDER != order)
+ BitOrderInvert ((unsigned char *) base, nbytes);
+#if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8
+ ReformatImage (base, nbytes, BITMAP_SCANLINE_UNIT, order);
+#endif
+ break;
+ case 4:
+ break; /* yuck */
+ case 8:
+ break;
+ case 16:
+ if (IMAGE_BYTE_ORDER != order)
+ TwoByteSwap ((unsigned char *) base, nbytes);
+ break;
+ case 32:
+ if (IMAGE_BYTE_ORDER != order)
+ FourByteSwap ((unsigned char *) base, nbytes);
+ break;
+ }
+}
+#else
+#define ReformatImage(b,n,bpp,o)
+#endif
+
+/* 64-bit server notes: the protocol restricts padding of images to
+ * 8-, 16-, or 32-bits. We would like to have 64-bits for the server
+ * to use internally. Removes need for internal alignment checking.
+ * All of the PutImage functions could be changed individually, but
+ * as currently written, they call other routines which require things
+ * to be 64-bit padded on scanlines, so we changed things here.
+ * If an image would be padded differently for 64- versus 32-, then
+ * copy each scanline to a 64-bit padded scanline.
+ * Also, we need to make sure that the image is aligned on a 64-bit
+ * boundary, even if the scanlines are padded to our satisfaction.
+ */
+int
+ProcPutImage(register ClientPtr client)
+{
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ long length; /* length of scanline server padded */
+ long lengthProto; /* length of scanline protocol padded */
+ char *tmpImage;
+ REQUEST(xPutImageReq);
+
+ REQUEST_AT_LEAST_SIZE(xPutImageReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ if (stuff->format == XYBitmap)
+ {
+ if ((stuff->depth != 1) ||
+ (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
+ return BadMatch;
+ length = BitmapBytePad(stuff->width + stuff->leftPad);
+ }
+ else if (stuff->format == XYPixmap)
+ {
+ if ((pDraw->depth != stuff->depth) ||
+ (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
+ return BadMatch;
+ length = BitmapBytePad(stuff->width + stuff->leftPad);
+ length *= stuff->depth;
+ }
+ else if (stuff->format == ZPixmap)
+ {
+ if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0))
+ return BadMatch;
+ length = PixmapBytePad(stuff->width, stuff->depth);
+ }
+ else
+ {
+ client->errorValue = stuff->format;
+ return BadValue;
+ }
+
+ tmpImage = (char *)&stuff[1];
+ lengthProto = length;
+
+ if (((((lengthProto * stuff->height) + (unsigned)3) >> 2) +
+ (sizeof(xPutImageReq) >> 2)) != client->req_len)
+ return BadLength;
+
+ ReformatImage (tmpImage, lengthProto * stuff->height,
+ stuff->format == ZPixmap ? BitsPerPixel (stuff->depth) : 1,
+ ClientOrder(client));
+
+ (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY,
+ stuff->width, stuff->height,
+ stuff->leftPad, stuff->format, tmpImage);
+
+ return (client->noClientException);
+}
+
+
+int
+DoGetImage(register ClientPtr client, int format, Drawable drawable,
+ int x, int y, int width, int height,
+ Mask planemask, xGetImageReply **im_return)
+{
+ register DrawablePtr pDraw;
+ int nlines, linesPerBuf;
+ register int linesDone;
+ long widthBytesLine, length;
+ Mask plane = 0;
+ char *pBuf;
+ xGetImageReply xgi;
+#ifdef XCSECURITY
+ RegionPtr pVisibleRegion = NULL;
+#endif
+
+ if ((format != XYPixmap) && (format != ZPixmap))
+ {
+ client->errorValue = format;
+ return(BadValue);
+ }
+ SECURITY_VERIFY_DRAWABLE(pDraw, drawable, client, SecurityReadAccess);
+ if(pDraw->type == DRAWABLE_WINDOW)
+ {
+ if( /* check for being viewable */
+ !((WindowPtr) pDraw)->realized ||
+ /* check for being on screen */
+ pDraw->x + x < 0 ||
+ pDraw->x + x + width > pDraw->pScreen->width ||
+ pDraw->y + y < 0 ||
+ pDraw->y + y + height > pDraw->pScreen->height ||
+ /* check for being inside of border */
+ x < - wBorderWidth((WindowPtr)pDraw) ||
+ x + width > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+ y < -wBorderWidth((WindowPtr)pDraw) ||
+ y + height > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height
+ )
+ return(BadMatch);
+ xgi.visual = wVisual (((WindowPtr) pDraw));
+ }
+ else
+ {
+ if(x < 0 ||
+ x+width > (int)pDraw->width ||
+ y < 0 ||
+ y+height > (int)pDraw->height
+ )
+ return(BadMatch);
+ xgi.visual = None;
+ }
+
+ SET_DBE_SRCBUF(pDraw, drawable);
+
+ xgi.type = X_Reply;
+ xgi.sequenceNumber = client->sequence;
+ xgi.depth = pDraw->depth;
+ if(format == ZPixmap)
+ {
+ widthBytesLine = PixmapBytePad(width, pDraw->depth);
+ length = widthBytesLine * height;
+
+ }
+ else
+ {
+ widthBytesLine = BitmapBytePad(width);
+ plane = ((Mask)1) << (pDraw->depth - 1);
+ /* only planes asked for */
+ length = widthBytesLine * height *
+ Ones(planemask & (plane | (plane - 1)));
+
+ }
+
+ xgi.length = length;
+
+ if (im_return) {
+ pBuf = (char *)xalloc(sz_xGetImageReply + length);
+ if (!pBuf)
+ return (BadAlloc);
+ if (widthBytesLine == 0)
+ linesPerBuf = 0;
+ else
+ linesPerBuf = height;
+ *im_return = (xGetImageReply *)pBuf;
+ *(xGetImageReply *)pBuf = xgi;
+ pBuf += sz_xGetImageReply;
+ } else {
+ xgi.length = (xgi.length + 3) >> 2;
+ if (widthBytesLine == 0 || height == 0)
+ linesPerBuf = 0;
+ else if (widthBytesLine >= IMAGE_BUFSIZE)
+ linesPerBuf = 1;
+ else
+ {
+ linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
+ if (linesPerBuf > height)
+ linesPerBuf = height;
+ }
+ length = linesPerBuf * widthBytesLine;
+ if (linesPerBuf < height)
+ {
+ /* we have to make sure intermediate buffers don't need padding */
+ while ((linesPerBuf > 1) &&
+ (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1)))
+ {
+ linesPerBuf--;
+ length -= widthBytesLine;
+ }
+ while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))
+ {
+ linesPerBuf++;
+ length += widthBytesLine;
+ }
+ }
+ if(!(pBuf = (char *) ALLOCATE_LOCAL(length)))
+ return (BadAlloc);
+ WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
+ }
+
+#ifdef XCSECURITY
+ if (client->trustLevel != XSecurityClientTrusted &&
+ pDraw->type == DRAWABLE_WINDOW)
+ {
+ pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw);
+ if (pVisibleRegion)
+ {
+ REGION_TRANSLATE(pDraw->pScreen, pVisibleRegion, -pDraw->x, -pDraw->y);
+ }
+ }
+#endif
+
+ if (linesPerBuf == 0)
+ {
+ /* nothing to do */
+ }
+ else if (format == ZPixmap)
+ {
+ linesDone = 0;
+ while (height - linesDone > 0)
+ {
+ nlines = min(linesPerBuf, height - linesDone);
+ (*pDraw->pScreen->GetImage) (pDraw,
+ x,
+ y + linesDone,
+ width,
+ nlines,
+ format,
+ planemask,
+ (pointer) pBuf);
+#ifdef XCSECURITY
+ if (pVisibleRegion)
+ SecurityCensorImage(client, pVisibleRegion, widthBytesLine,
+ pDraw, x, y + linesDone, width,
+ nlines, format, pBuf);
+#endif
+
+ /* Note that this is NOT a call to WriteSwappedDataToClient,
+ as we do NOT byte swap */
+ if (!im_return)
+ {
+ ReformatImage (pBuf, (int)(nlines * widthBytesLine),
+ BitsPerPixel (pDraw->depth),
+ ClientOrder(client));
+
+/* Don't split me, gcc pukes when you do */
+ (void)WriteToClient(client,
+ (int)(nlines * widthBytesLine),
+ pBuf);
+ }
+ linesDone += nlines;
+ }
+ }
+ else /* XYPixmap */
+ {
+ for (; plane; plane >>= 1)
+ {
+ if (planemask & plane)
+ {
+ linesDone = 0;
+ while (height - linesDone > 0)
+ {
+ nlines = min(linesPerBuf, height - linesDone);
+ (*pDraw->pScreen->GetImage) (pDraw,
+ x,
+ y + linesDone,
+ width,
+ nlines,
+ format,
+ plane,
+ (pointer)pBuf);
+#ifdef XCSECURITY
+ if (pVisibleRegion)
+ SecurityCensorImage(client, pVisibleRegion,
+ widthBytesLine,
+ pDraw, x, y + linesDone, width,
+ nlines, format, pBuf);
+#endif
+
+ /* Note: NOT a call to WriteSwappedDataToClient,
+ as we do NOT byte swap */
+ if (im_return) {
+ pBuf += nlines * widthBytesLine;
+ } else {
+ ReformatImage (pBuf,
+ (int)(nlines * widthBytesLine),
+ 1,
+ ClientOrder (client));
+
+/* Don't split me, gcc pukes when you do */
+ (void)WriteToClient(client,
+ (int)(nlines * widthBytesLine),
+ pBuf);
+ }
+ linesDone += nlines;
+ }
+ }
+ }
+ }
+#ifdef XCSECURITY
+ if (pVisibleRegion)
+ REGION_DESTROY(pDraw->pScreen, pVisibleRegion);
+#endif
+ if (!im_return)
+ DEALLOCATE_LOCAL(pBuf);
+ return (client->noClientException);
+}
+
+int
+ProcGetImage(register ClientPtr client)
+{
+ REQUEST(xGetImageReq);
+
+ REQUEST_SIZE_MATCH(xGetImageReq);
+
+ return DoGetImage(client, stuff->format, stuff->drawable,
+ stuff->x, stuff->y,
+ (int)stuff->width, (int)stuff->height,
+ stuff->planeMask, (xGetImageReply **)NULL);
+}
+
+int
+ProcPolyText(register ClientPtr client)
+{
+ int err;
+ REQUEST(xPolyTextReq);
+ DrawablePtr pDraw;
+ GC *pGC;
+
+ REQUEST_AT_LEAST_SIZE(xPolyTextReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ err = PolyText(client,
+ pDraw,
+ pGC,
+ (unsigned char *)&stuff[1],
+ ((unsigned char *) stuff) + (client->req_len << 2),
+ stuff->x,
+ stuff->y,
+ stuff->reqType,
+ stuff->drawable);
+
+ if (err == Success)
+ {
+ return(client->noClientException);
+ }
+ else
+ return err;
+}
+
+int
+ProcImageText8(register ClientPtr client)
+{
+ int err;
+ register DrawablePtr pDraw;
+ register GC *pGC;
+
+ REQUEST(xImageTextReq);
+
+ REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ err = ImageText(client,
+ pDraw,
+ pGC,
+ stuff->nChars,
+ (unsigned char *)&stuff[1],
+ stuff->x,
+ stuff->y,
+ stuff->reqType,
+ stuff->drawable);
+
+ if (err == Success)
+ {
+ return(client->noClientException);
+ }
+ else
+ return err;
+}
+
+int
+ProcImageText16(register ClientPtr client)
+{
+ int err;
+ register DrawablePtr pDraw;
+ register GC *pGC;
+
+ REQUEST(xImageTextReq);
+
+ REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ err = ImageText(client,
+ pDraw,
+ pGC,
+ stuff->nChars,
+ (unsigned char *)&stuff[1],
+ stuff->x,
+ stuff->y,
+ stuff->reqType,
+ stuff->drawable);
+
+ if (err == Success)
+ {
+ return(client->noClientException);
+ }
+ else
+ return err;
+}
+
+
+int
+ProcCreateColormap(register ClientPtr client)
+{
+ VisualPtr pVisual;
+ ColormapPtr pmap;
+ Colormap mid;
+ register WindowPtr pWin;
+ ScreenPtr pScreen;
+ REQUEST(xCreateColormapReq);
+ int i, result;
+
+ REQUEST_SIZE_MATCH(xCreateColormapReq);
+
+ if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll))
+ {
+ client->errorValue = stuff->alloc;
+ return(BadValue);
+ }
+ mid = stuff->mid;
+ LEGAL_NEW_RESOURCE(mid, client);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+
+ pScreen = pWin->drawable.pScreen;
+ for (i = 0, pVisual = pScreen->visuals;
+ i < pScreen->numVisuals;
+ i++, pVisual++)
+ {
+ if (pVisual->vid != stuff->visual)
+ continue;
+ result = CreateColormap(mid, pScreen, pVisual, &pmap,
+ (int)stuff->alloc, client->index);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+ }
+ client->errorValue = stuff->visual;
+ return(BadValue);
+}
+
+int
+ProcFreeColormap(register ClientPtr client)
+{
+ ColormapPtr pmap;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pmap = (ColormapPtr )SecurityLookupIDByType(client, stuff->id, RT_COLORMAP,
+ SecurityDestroyAccess);
+ if (pmap)
+ {
+ /* Freeing a default colormap is a no-op */
+ if (!(pmap->flags & IsDefault))
+ FreeResource(stuff->id, RT_NONE);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadColor);
+ }
+}
+
+
+int
+ProcCopyColormapAndFree(register ClientPtr client)
+{
+ Colormap mid;
+ ColormapPtr pSrcMap;
+ REQUEST(xCopyColormapAndFreeReq);
+ int result;
+
+ REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
+ mid = stuff->mid;
+ LEGAL_NEW_RESOURCE(mid, client);
+ if( (pSrcMap = (ColormapPtr )SecurityLookupIDByType(client, stuff->srcCmap,
+ RT_COLORMAP, SecurityReadAccess|SecurityWriteAccess)) )
+ {
+ result = CopyColormapAndFree(mid, pSrcMap, client->index);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+ }
+ else
+ {
+ client->errorValue = stuff->srcCmap;
+ return(BadColor);
+ }
+}
+
+int
+ProcInstallColormap(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
+ RT_COLORMAP, SecurityReadAccess);
+ if (pcmp)
+ {
+ (*(pcmp->pScreen->InstallColormap)) (pcmp);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadColor);
+ }
+}
+
+int
+ProcUninstallColormap(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
+ RT_COLORMAP, SecurityReadAccess);
+ if (pcmp)
+ {
+ if(pcmp->mid != pcmp->pScreen->defColormap)
+ (*(pcmp->pScreen->UninstallColormap)) (pcmp);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadColor);
+ }
+}
+
+int
+ProcListInstalledColormaps(register ClientPtr client)
+{
+ xListInstalledColormapsReply *preply;
+ int nummaps;
+ WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityReadAccess);
+
+ if (!pWin)
+ return(BadWindow);
+
+ preply = (xListInstalledColormapsReply *)
+ ALLOCATE_LOCAL(sizeof(xListInstalledColormapsReply) +
+ pWin->drawable.pScreen->maxInstalledCmaps *
+ sizeof(Colormap));
+ if(!preply)
+ return(BadAlloc);
+
+ preply->type = X_Reply;
+ preply->sequenceNumber = client->sequence;
+ nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
+ (pWin->drawable.pScreen, (Colormap *)&preply[1]);
+ preply->nColormaps = nummaps;
+ preply->length = nummaps;
+ WriteReplyToClient(client, sizeof (xListInstalledColormapsReply), preply);
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]);
+ DEALLOCATE_LOCAL(preply);
+ return(client->noClientException);
+}
+
+int
+ProcAllocColor (register ClientPtr client)
+{
+ ColormapPtr pmap;
+ int retval;
+ xAllocColorReply acr;
+ REQUEST(xAllocColorReq);
+
+ REQUEST_SIZE_MATCH(xAllocColorReq);
+ pmap = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityWriteAccess);
+ if (pmap)
+ {
+#ifdef LBX
+ /*
+ * If the colormap is grabbed by a proxy, the server will have
+ * to regain control over the colormap. This AllocColor request
+ * will be handled after the server gets back the colormap control.
+ */
+ if (LbxCheckColorRequest (client, pmap, (xReq *) stuff))
+ return Success;
+#endif
+ acr.type = X_Reply;
+ acr.length = 0;
+ acr.sequenceNumber = client->sequence;
+ acr.red = stuff->red;
+ acr.green = stuff->green;
+ acr.blue = stuff->blue;
+ acr.pixel = 0;
+ if( (retval = AllocColor(pmap, &acr.red, &acr.green, &acr.blue,
+ &acr.pixel, client->index)) )
+ {
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return (retval);
+ }
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !pmap->pScreen->myNum)
+#endif
+ WriteReplyToClient(client, sizeof(xAllocColorReply), &acr);
+ return (client->noClientException);
+
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcAllocNamedColor (register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xAllocNamedColorReq);
+
+ REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityWriteAccess);
+ if (pcmp)
+ {
+ int retval;
+
+ xAllocNamedColorReply ancr;
+
+#ifdef LBX
+ /*
+ * If the colormap is grabbed by a proxy, the server will have
+ * to regain control over the colormap. This AllocNamedColor request
+ * will be handled after the server gets back the colormap control.
+ */
+ if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
+ return Success;
+#endif
+ ancr.type = X_Reply;
+ ancr.length = 0;
+ ancr.sequenceNumber = client->sequence;
+
+ if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
+ &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue))
+ {
+ ancr.screenRed = ancr.exactRed;
+ ancr.screenGreen = ancr.exactGreen;
+ ancr.screenBlue = ancr.exactBlue;
+ ancr.pixel = 0;
+ if( (retval = AllocColor(pcmp,
+ &ancr.screenRed, &ancr.screenGreen, &ancr.screenBlue,
+ &ancr.pixel, client->index)) )
+ {
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(retval);
+ }
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+ WriteReplyToClient(client, sizeof (xAllocNamedColorReply), &ancr);
+ return (client->noClientException);
+ }
+ else
+ return(BadName);
+
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcAllocColorCells (register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xAllocColorCellsReq);
+
+ REQUEST_SIZE_MATCH(xAllocColorCellsReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityWriteAccess);
+ if (pcmp)
+ {
+ xAllocColorCellsReply accr;
+ int npixels, nmasks, retval;
+ long length;
+ Pixel *ppixels, *pmasks;
+
+#ifdef LBX
+ /*
+ * If the colormap is grabbed by a proxy, the server will have
+ * to regain control over the colormap. This AllocColorCells request
+ * will be handled after the server gets back the colormap control.
+ */
+ if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
+ return Success;
+#endif
+ npixels = stuff->colors;
+ if (!npixels)
+ {
+ client->errorValue = npixels;
+ return (BadValue);
+ }
+ if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
+ {
+ client->errorValue = stuff->contiguous;
+ return (BadValue);
+ }
+ nmasks = stuff->planes;
+ length = ((long)npixels + (long)nmasks) * sizeof(Pixel);
+ ppixels = (Pixel *)ALLOCATE_LOCAL(length);
+ if(!ppixels)
+ return(BadAlloc);
+ pmasks = ppixels + npixels;
+
+ if( (retval = AllocColorCells(client->index, pcmp, npixels, nmasks,
+ (Bool)stuff->contiguous, ppixels, pmasks)) )
+ {
+ DEALLOCATE_LOCAL(ppixels);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(retval);
+ }
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+ {
+ accr.type = X_Reply;
+ accr.length = length >> 2;
+ accr.sequenceNumber = client->sequence;
+ accr.nPixels = npixels;
+ accr.nMasks = nmasks;
+ WriteReplyToClient(client, sizeof (xAllocColorCellsReply), &accr);
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, length, ppixels);
+ }
+ DEALLOCATE_LOCAL(ppixels);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcAllocColorPlanes(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xAllocColorPlanesReq);
+
+ REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityWriteAccess);
+ if (pcmp)
+ {
+ xAllocColorPlanesReply acpr;
+ int npixels, retval;
+ long length;
+ Pixel *ppixels;
+
+#ifdef LBX
+ /*
+ * If the colormap is grabbed by a proxy, the server will have
+ * to regain control over the colormap. This AllocColorPlanes request
+ * will be handled after the server gets back the colormap control.
+ */
+ if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
+ return Success;
+#endif
+ npixels = stuff->colors;
+ if (!npixels)
+ {
+ client->errorValue = npixels;
+ return (BadValue);
+ }
+ if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
+ {
+ client->errorValue = stuff->contiguous;
+ return (BadValue);
+ }
+ acpr.type = X_Reply;
+ acpr.sequenceNumber = client->sequence;
+ acpr.nPixels = npixels;
+ length = (long)npixels * sizeof(Pixel);
+ ppixels = (Pixel *)ALLOCATE_LOCAL(length);
+ if(!ppixels)
+ return(BadAlloc);
+ if( (retval = AllocColorPlanes(client->index, pcmp, npixels,
+ (int)stuff->red, (int)stuff->green, (int)stuff->blue,
+ (Bool)stuff->contiguous, ppixels,
+ &acpr.redMask, &acpr.greenMask, &acpr.blueMask)) )
+ {
+ DEALLOCATE_LOCAL(ppixels);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(retval);
+ }
+ acpr.length = length >> 2;
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+ {
+ WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr);
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, length, ppixels);
+ }
+ DEALLOCATE_LOCAL(ppixels);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcFreeColors(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xFreeColorsReq);
+
+ REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityWriteAccess);
+ if (pcmp)
+ {
+ int count;
+ int retval;
+
+ if(pcmp->flags & AllAllocated)
+ return(BadAccess);
+ count = ((client->req_len << 2)- sizeof(xFreeColorsReq)) >> 2;
+ retval = FreeColors(pcmp, client->index, count,
+ (Pixel *)&stuff[1], (Pixel)stuff->planeMask);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return(retval);
+ }
+
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcStoreColors (ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xStoreColorsReq);
+
+ REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityWriteAccess);
+ if (pcmp)
+ {
+ int count;
+ int retval;
+
+ count = (client->req_len << 2) - sizeof(xStoreColorsReq);
+ if (count % sizeof(xColorItem))
+ return(BadLength);
+ count /= sizeof(xColorItem);
+ retval = StoreColors(pcmp, count, (xColorItem *)&stuff[1]);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return(retval);
+ }
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcStoreNamedColor (register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xStoreNamedColorReq);
+
+ REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityWriteAccess);
+ if (pcmp)
+ {
+ xColorItem def;
+ int retval;
+
+ if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1],
+ stuff->nbytes, &def.red, &def.green, &def.blue))
+ {
+ def.flags = stuff->flags;
+ def.pixel = stuff->pixel;
+ retval = StoreColors(pcmp, 1, &def);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(retval);
+ }
+ return (BadName);
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcQueryColors(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xQueryColorsReq);
+
+ REQUEST_AT_LEAST_SIZE(xQueryColorsReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityReadAccess);
+ if (pcmp)
+ {
+ int count, retval;
+ xrgb *prgbs;
+ xQueryColorsReply qcr;
+
+ count = ((client->req_len << 2) - sizeof(xQueryColorsReq)) >> 2;
+ prgbs = (xrgb *)ALLOCATE_LOCAL(count * sizeof(xrgb));
+ if(!prgbs && count)
+ return(BadAlloc);
+ if( (retval = QueryColors(pcmp, count, (Pixel *)&stuff[1], prgbs)) )
+ {
+ if (prgbs) DEALLOCATE_LOCAL(prgbs);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return (retval);
+ }
+ }
+ qcr.type = X_Reply;
+ qcr.length = (count * sizeof(xrgb)) >> 2;
+ qcr.sequenceNumber = client->sequence;
+ qcr.nColors = count;
+ WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr);
+ if (count)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend;
+ WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs);
+ }
+ if (prgbs) DEALLOCATE_LOCAL(prgbs);
+ return(client->noClientException);
+
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcLookupColor(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xLookupColorReq);
+
+ REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, SecurityReadAccess);
+ if (pcmp)
+ {
+ xLookupColorReply lcr;
+
+ if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
+ &lcr.exactRed, &lcr.exactGreen, &lcr.exactBlue))
+ {
+ lcr.type = X_Reply;
+ lcr.length = 0;
+ lcr.sequenceNumber = client->sequence;
+ lcr.screenRed = lcr.exactRed;
+ lcr.screenGreen = lcr.exactGreen;
+ lcr.screenBlue = lcr.exactBlue;
+ (*pcmp->pScreen->ResolveColor)(&lcr.screenRed,
+ &lcr.screenGreen,
+ &lcr.screenBlue,
+ pcmp->pVisual);
+ WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr);
+ return(client->noClientException);
+ }
+ return (BadName);
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcCreateCursor (register ClientPtr client)
+{
+ CursorPtr pCursor;
+
+ register PixmapPtr src;
+ register PixmapPtr msk;
+ unsigned char * srcbits;
+ unsigned char * mskbits;
+ unsigned short width, height;
+ long n;
+ CursorMetricRec cm;
+
+
+ REQUEST(xCreateCursorReq);
+
+ REQUEST_SIZE_MATCH(xCreateCursorReq);
+ LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+ src = (PixmapPtr)SecurityLookupIDByType(client, stuff->source,
+ RT_PIXMAP, SecurityReadAccess);
+ msk = (PixmapPtr)SecurityLookupIDByType(client, stuff->mask,
+ RT_PIXMAP, SecurityReadAccess);
+ if ( src == (PixmapPtr)NULL)
+ {
+ client->errorValue = stuff->source;
+ return (BadPixmap);
+ }
+ if ( msk == (PixmapPtr)NULL)
+ {
+ if (stuff->mask != None)
+ {
+ client->errorValue = stuff->mask;
+ return (BadPixmap);
+ }
+ }
+ else if ( src->drawable.width != msk->drawable.width
+ || src->drawable.height != msk->drawable.height
+ || src->drawable.depth != 1
+ || msk->drawable.depth != 1)
+ return (BadMatch);
+
+ width = src->drawable.width;
+ height = src->drawable.height;
+
+ if ( stuff->x > width
+ || stuff->y > height )
+ return (BadMatch);
+
+ n = BitmapBytePad(width)*height;
+ srcbits = (unsigned char *)xalloc(n);
+ if (!srcbits)
+ return (BadAlloc);
+ mskbits = (unsigned char *)xalloc(n);
+ if (!mskbits)
+ {
+ xfree(srcbits);
+ return (BadAlloc);
+ }
+
+ /* zeroing the (pad) bits helps some ddx cursor handling */
+ bzero((char *)srcbits, n);
+ (* src->drawable.pScreen->GetImage)( (DrawablePtr)src, 0, 0, width, height,
+ XYPixmap, 1, (pointer)srcbits);
+ if ( msk == (PixmapPtr)NULL)
+ {
+ register unsigned char *bits = mskbits;
+ while (--n >= 0)
+ *bits++ = ~0;
+ }
+ else
+ {
+ /* zeroing the (pad) bits helps some ddx cursor handling */
+ bzero((char *)mskbits, n);
+ (* msk->drawable.pScreen->GetImage)( (DrawablePtr)msk, 0, 0, width,
+ height, XYPixmap, 1, (pointer)mskbits);
+ }
+ cm.width = width;
+ cm.height = height;
+ cm.xhot = stuff->x;
+ cm.yhot = stuff->y;
+ pCursor = AllocCursor( srcbits, mskbits, &cm,
+ stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
+ stuff->backRed, stuff->backGreen, stuff->backBlue);
+
+ if (pCursor && AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+ return (client->noClientException);
+ return BadAlloc;
+}
+
+int
+ProcCreateGlyphCursor (register ClientPtr client)
+{
+ CursorPtr pCursor;
+ int res;
+
+ REQUEST(xCreateGlyphCursorReq);
+
+ REQUEST_SIZE_MATCH(xCreateGlyphCursorReq);
+ LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+ res = AllocGlyphCursor(stuff->source, stuff->sourceChar,
+ stuff->mask, stuff->maskChar,
+ stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
+ stuff->backRed, stuff->backGreen, stuff->backBlue,
+ &pCursor, client);
+ if (res != Success)
+ return res;
+ if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+ return client->noClientException;
+ return BadAlloc;
+}
+
+
+int
+ProcFreeCursor (register ClientPtr client)
+{
+ CursorPtr pCursor;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->id,
+ RT_CURSOR, SecurityDestroyAccess);
+ if (pCursor)
+ {
+ FreeResource(stuff->id, RT_NONE);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadCursor);
+ }
+}
+
+int
+ProcQueryBestSize (register ClientPtr client)
+{
+ xQueryBestSizeReply reply;
+ register DrawablePtr pDraw;
+ ScreenPtr pScreen;
+ REQUEST(xQueryBestSizeReq);
+
+ REQUEST_SIZE_MATCH(xQueryBestSizeReq);
+ if ((stuff->class != CursorShape) &&
+ (stuff->class != TileShape) &&
+ (stuff->class != StippleShape))
+ {
+ client->errorValue = stuff->class;
+ return(BadValue);
+ }
+ SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->drawable, client,
+ SecurityReadAccess);
+ if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW)
+ return (BadMatch);
+ pScreen = pDraw->pScreen;
+ (* pScreen->QueryBestSize)(stuff->class, &stuff->width,
+ &stuff->height, pScreen);
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ reply.width = stuff->width;
+ reply.height = stuff->height;
+ WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply);
+ return (client->noClientException);
+}
+
+
+int
+ProcSetScreenSaver (register ClientPtr client)
+{
+ int blankingOption, exposureOption;
+ REQUEST(xSetScreenSaverReq);
+
+ REQUEST_SIZE_MATCH(xSetScreenSaverReq);
+ blankingOption = stuff->preferBlank;
+ if ((blankingOption != DontPreferBlanking) &&
+ (blankingOption != PreferBlanking) &&
+ (blankingOption != DefaultBlanking))
+ {
+ client->errorValue = blankingOption;
+ return BadValue;
+ }
+ exposureOption = stuff->allowExpose;
+ if ((exposureOption != DontAllowExposures) &&
+ (exposureOption != AllowExposures) &&
+ (exposureOption != DefaultExposures))
+ {
+ client->errorValue = exposureOption;
+ return BadValue;
+ }
+ if (stuff->timeout < -1)
+ {
+ client->errorValue = stuff->timeout;
+ return BadValue;
+ }
+ if (stuff->interval < -1)
+ {
+ client->errorValue = stuff->interval;
+ return BadValue;
+ }
+
+ if (blankingOption == DefaultBlanking)
+ ScreenSaverBlanking = defaultScreenSaverBlanking;
+ else
+ ScreenSaverBlanking = blankingOption;
+ if (exposureOption == DefaultExposures)
+ ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
+ else
+ ScreenSaverAllowExposures = exposureOption;
+
+ if (stuff->timeout >= 0)
+ ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND;
+ else
+ ScreenSaverTime = defaultScreenSaverTime;
+ if (stuff->interval >= 0)
+ ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND;
+ else
+ ScreenSaverInterval = defaultScreenSaverInterval;
+
+ SetScreenSaverTimer();
+ return (client->noClientException);
+}
+
+int
+ProcGetScreenSaver(register ClientPtr client)
+{
+ xGetScreenSaverReply rep;
+
+ REQUEST_SIZE_MATCH(xReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.timeout = ScreenSaverTime / MILLI_PER_SECOND;
+ rep.interval = ScreenSaverInterval / MILLI_PER_SECOND;
+ rep.preferBlanking = ScreenSaverBlanking;
+ rep.allowExposures = ScreenSaverAllowExposures;
+ WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep);
+ return (client->noClientException);
+}
+
+int
+ProcChangeHosts(register ClientPtr client)
+{
+ REQUEST(xChangeHostsReq);
+ int result;
+
+ REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength);
+
+ if(stuff->mode == HostInsert)
+ result = AddHost(client, (int)stuff->hostFamily,
+ stuff->hostLength, (pointer)&stuff[1]);
+ else if (stuff->mode == HostDelete)
+ result = RemoveHost(client, (int)stuff->hostFamily,
+ stuff->hostLength, (pointer)&stuff[1]);
+ else
+ {
+ client->errorValue = stuff->mode;
+ return BadValue;
+ }
+ if (!result)
+ result = client->noClientException;
+ return (result);
+}
+
+int
+ProcListHosts(register ClientPtr client)
+{
+ xListHostsReply reply;
+ int len, nHosts, result;
+ pointer pdata;
+ /* REQUEST(xListHostsReq); */
+
+ REQUEST_SIZE_MATCH(xListHostsReq);
+#ifdef XCSECURITY
+ /* untrusted clients can't list hosts */
+ if (client->trustLevel != XSecurityClientTrusted)
+ {
+ SecurityAudit("client %d attempted to list hosts\n", client->index);
+ return BadAccess;
+ }
+#endif
+ result = GetHosts(&pdata, &nHosts, &len, &reply.enabled);
+ if (result != Success)
+ return(result);
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.nHosts = nHosts;
+ reply.length = len >> 2;
+ WriteReplyToClient(client, sizeof(xListHostsReply), &reply);
+ if (nHosts)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend;
+ WriteSwappedDataToClient(client, len, pdata);
+ }
+ xfree(pdata);
+ return (client->noClientException);
+}
+
+int
+ProcChangeAccessControl(register ClientPtr client)
+{
+ int result;
+ REQUEST(xSetAccessControlReq);
+
+ REQUEST_SIZE_MATCH(xSetAccessControlReq);
+ if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess))
+ {
+ client->errorValue = stuff->mode;
+ return BadValue;
+ }
+ result = ChangeAccessControl(client, stuff->mode == EnableAccess);
+ if (!result)
+ result = client->noClientException;
+ return (result);
+}
+
+int
+ProcKillClient(register ClientPtr client)
+{
+ REQUEST(xResourceReq);
+ ClientPtr killclient;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ if (stuff->id == AllTemporary)
+ {
+ CloseDownRetainedResources();
+ return (client->noClientException);
+ }
+
+ if ((killclient = LookupClient(stuff->id, client)))
+ {
+ CloseDownClient(killclient);
+ /* if an LBX proxy gets killed, isItTimeToYield will be set */
+ if (isItTimeToYield || (client == killclient))
+ {
+ /* force yield and return Success, so that Dispatch()
+ * doesn't try to touch client
+ */
+ isItTimeToYield = TRUE;
+ return (Success);
+ }
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadValue);
+ }
+}
+
+int
+ProcSetFontPath(register ClientPtr client)
+{
+ unsigned char *ptr;
+ unsigned long nbytes, total;
+ long nfonts;
+ int n, result;
+ int error;
+ REQUEST(xSetFontPathReq);
+
+ REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
+
+ nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq);
+ total = nbytes;
+ ptr = (unsigned char *)&stuff[1];
+ nfonts = stuff->nFonts;
+ while (--nfonts >= 0)
+ {
+ if ((total == 0) || (total < (n = (*ptr + 1))))
+ return(BadLength);
+ total -= n;
+ ptr += n;
+ }
+ if (total >= 4)
+ return(BadLength);
+ result = SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1],
+ &error);
+ if (!result)
+ {
+ result = client->noClientException;
+ client->errorValue = error;
+ }
+ return (result);
+}
+
+int
+ProcGetFontPath(register ClientPtr client)
+{
+ xGetFontPathReply reply;
+ int stringLens, numpaths;
+ unsigned char *bufferStart;
+ /* REQUEST (xReq); */
+
+ REQUEST_SIZE_MATCH(xReq);
+ bufferStart = GetFontPath(&numpaths, &stringLens);
+
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.length = (stringLens + numpaths + 3) >> 2;
+ reply.nPaths = numpaths;
+
+ WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply);
+ if (stringLens || numpaths)
+ (void)WriteToClient(client, stringLens + numpaths, (char *)bufferStart);
+ return(client->noClientException);
+}
+
+int
+ProcChangeCloseDownMode(register ClientPtr client)
+{
+ REQUEST(xSetCloseDownModeReq);
+
+ REQUEST_SIZE_MATCH(xSetCloseDownModeReq);
+ if ((stuff->mode == AllTemporary) ||
+ (stuff->mode == RetainPermanent) ||
+ (stuff->mode == RetainTemporary))
+ {
+ client->closeDownMode = stuff->mode;
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->mode;
+ return (BadValue);
+ }
+}
+
+int ProcForceScreenSaver(register ClientPtr client)
+{
+ REQUEST(xForceScreenSaverReq);
+
+ REQUEST_SIZE_MATCH(xForceScreenSaverReq);
+
+ if ((stuff->mode != ScreenSaverReset) &&
+ (stuff->mode != ScreenSaverActive))
+ {
+ client->errorValue = stuff->mode;
+ return BadValue;
+ }
+ SaveScreens(SCREEN_SAVER_FORCER, (int)stuff->mode);
+ return client->noClientException;
+}
+
+int ProcNoOperation(register ClientPtr client)
+{
+ REQUEST_AT_LEAST_SIZE(xReq);
+
+ /* noop -- don't do anything */
+ return(client->noClientException);
+}
+
+void
+InitProcVectors(void)
+{
+ int i;
+ for (i = 0; i<256; i++)
+ {
+ if(!ProcVector[i])
+ {
+ ProcVector[i] = SwappedProcVector[i] = ProcBadRequest;
+ ReplySwapVector[i] = ReplyNotSwappd;
+ }
+#ifdef K5AUTH
+ if (!k5_Vector[i])
+ {
+ k5_Vector[i] = k5_bad;
+ }
+#endif
+ }
+ for(i = LASTEvent; i < 128; i++)
+ {
+ EventSwapVector[i] = NotImplemented;
+ }
+
+}
+
+/**********************
+ * CloseDownClient
+ *
+ * Client can either mark his resources destroy or retain. If retained and
+ * then killed again, the client is really destroyed.
+ *********************/
+
+char dispatchExceptionAtReset = DE_RESET;
+
+void
+CloseDownClient(register ClientPtr client)
+{
+ Bool really_close_down = client->clientGone ||
+ client->closeDownMode == DestroyAll;
+
+ if (!client->clientGone)
+ {
+ /* ungrab server if grabbing client dies */
+ if (grabState != GrabNone && grabClient == client)
+ {
+ UngrabServer(client);
+ }
+ BITCLEAR(grabWaiters, client->index);
+ DeleteClientFromAnySelections(client);
+ ReleaseActiveGrabs(client);
+ DeleteClientFontStuff(client);
+ if (!really_close_down)
+ {
+ /* This frees resources that should never be retained
+ * no matter what the close down mode is. Actually we
+ * could do this unconditionally, but it's probably
+ * better not to traverse all the client's resources
+ * twice (once here, once a few lines down in
+ * FreeClientResources) in the common case of
+ * really_close_down == TRUE.
+ */
+ FreeClientNeverRetainResources(client);
+ client->clientState = ClientStateRetained;
+ if (ClientStateCallback)
+ {
+ NewClientInfoRec clientinfo;
+
+ clientinfo.client = client;
+ clientinfo.prefix = (xConnSetupPrefix *)NULL;
+ clientinfo.setup = (xConnSetup *) NULL;
+ CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+ }
+ }
+ client->clientGone = TRUE; /* so events aren't sent to client */
+ if (ClientIsAsleep(client))
+ ClientSignal (client);
+ ProcessWorkQueueZombies();
+#ifdef LBX
+ ProcessQTagZombies();
+#endif
+ CloseDownConnection(client);
+
+ /* If the client made it to the Running stage, nClients has
+ * been incremented on its behalf, so we need to decrement it
+ * now. If it hasn't gotten to Running, nClients has *not*
+ * been incremented, so *don't* decrement it.
+ */
+ if (client->clientState != ClientStateInitial &&
+ client->clientState != ClientStateAuthenticating )
+ {
+ --nClients;
+ }
+ }
+
+ if (really_close_down)
+ {
+ if (client->clientState == ClientStateRunning && nClients == 0)
+ dispatchException |= dispatchExceptionAtReset;
+
+ client->clientState = ClientStateGone;
+ if (ClientStateCallback)
+ {
+ NewClientInfoRec clientinfo;
+
+ clientinfo.client = client;
+ clientinfo.prefix = (xConnSetupPrefix *)NULL;
+ clientinfo.setup = (xConnSetup *) NULL;
+ CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+ }
+ FreeClientResources(client);
+ if (client->index < nextFreeClientID)
+ nextFreeClientID = client->index;
+ clients[client->index] = NullClient;
+#ifdef SMART_SCHEDULE
+ SmartLastClient = NullClient;
+#endif
+ xfree(client);
+
+ while (!clients[currentMaxClients-1])
+ currentMaxClients--;
+ }
+}
+
+static void
+KillAllClients()
+{
+ int i;
+ for (i=1; i<currentMaxClients; i++)
+ if (clients[i]) {
+ /* Make sure Retained clients are released. */
+ clients[i]->closeDownMode = DestroyAll;
+ CloseDownClient(clients[i]);
+ }
+}
+
+/*********************
+ * CloseDownRetainedResources
+ *
+ * Find all clients that are gone and have terminated in RetainTemporary
+ * and destroy their resources.
+ *********************/
+
+void
+CloseDownRetainedResources()
+{
+ register int i;
+ register ClientPtr client;
+
+ for (i=1; i<currentMaxClients; i++)
+ {
+ client = clients[i];
+ if (client && (client->closeDownMode == RetainTemporary)
+ && (client->clientGone))
+ CloseDownClient(client);
+ }
+}
+
+void InitClient(ClientPtr client, int i, pointer ospriv)
+{
+ client->index = i;
+ client->sequence = 0;
+ client->clientAsMask = ((Mask)i) << CLIENTOFFSET;
+ client->clientGone = FALSE;
+ if (i)
+ {
+ client->closeDownMode = DestroyAll;
+ client->lastDrawable = (DrawablePtr)WindowTable[0];
+ client->lastDrawableID = WindowTable[0]->drawable.id;
+ }
+ else
+ {
+ client->closeDownMode = RetainPermanent;
+ client->lastDrawable = (DrawablePtr)NULL;
+ client->lastDrawableID = INVALID;
+ }
+ client->lastGC = (GCPtr) NULL;
+ client->lastGCID = INVALID;
+ client->numSaved = 0;
+ client->saveSet = (SaveSetElt *)NULL;
+ client->noClientException = Success;
+#ifdef DEBUG
+ client->requestLogIndex = 0;
+#endif
+ client->requestVector = InitialVector;
+ client->osPrivate = ospriv;
+ client->swapped = FALSE;
+ client->big_requests = FALSE;
+ client->priority = 0;
+ client->clientState = ClientStateInitial;
+#ifdef XKB
+ if (!noXkbExtension) {
+ client->xkbClientFlags = 0;
+ client->mapNotifyMask = 0;
+ QueryMinMaxKeyCodes(&client->minKC,&client->maxKC);
+ }
+#endif
+ client->replyBytesRemaining = 0;
+#ifdef LBX
+ client->readRequest = StandardReadRequestFromClient;
+#endif
+#ifdef XCSECURITY
+ client->trustLevel = XSecurityClientTrusted;
+ client->CheckAccess = NULL;
+ client->authId = 0;
+#endif
+#ifdef XAPPGROUP
+ client->appgroup = NULL;
+#endif
+ client->fontResFunc = NULL;
+#ifdef SMART_SCHEDULE
+ client->smart_priority = 0;
+ client->smart_start_tick = SmartScheduleTime;
+ client->smart_stop_tick = SmartScheduleTime;
+ client->smart_check_tick = SmartScheduleTime;
+#endif
+}
+
+extern int clientPrivateLen;
+extern unsigned *clientPrivateSizes;
+extern unsigned totalClientSize;
+
+int
+InitClientPrivates(ClientPtr client)
+{
+ register char *ptr;
+ DevUnion *ppriv;
+ register unsigned *sizes;
+ register unsigned size;
+ register int i;
+
+ if (totalClientSize == sizeof(ClientRec))
+ ppriv = (DevUnion *)NULL;
+ else if (client->index)
+ ppriv = (DevUnion *)(client + 1);
+ else
+ {
+ ppriv = (DevUnion *)xalloc(totalClientSize - sizeof(ClientRec));
+ if (!ppriv)
+ return 0;
+ }
+ client->devPrivates = ppriv;
+ sizes = clientPrivateSizes;
+ ptr = (char *)(ppriv + clientPrivateLen);
+ for (i = clientPrivateLen; --i >= 0; ppriv++, sizes++)
+ {
+ if ( (size = *sizes) )
+ {
+ ppriv->ptr = (pointer)ptr;
+ ptr += size;
+ }
+ else
+ ppriv->ptr = (pointer)NULL;
+ }
+ return 1;
+}
+
+/************************
+ * int NextAvailableClient(ospriv)
+ *
+ * OS dependent portion can't assign client id's because of CloseDownModes.
+ * Returns NULL if there are no free clients.
+ *************************/
+
+ClientPtr NextAvailableClient(pointer ospriv)
+{
+ register int i;
+ register ClientPtr client;
+ xReq data;
+
+ i = nextFreeClientID;
+ if (i == MAXCLIENTS)
+ return (ClientPtr)NULL;
+ clients[i] = client = (ClientPtr)xalloc(totalClientSize);
+ if (!client)
+ return (ClientPtr)NULL;
+ InitClient(client, i, ospriv);
+ InitClientPrivates(client);
+ if (!InitClientResources(client))
+ {
+ xfree(client);
+ return (ClientPtr)NULL;
+ }
+ data.reqType = 1;
+ data.length = (sz_xReq + sz_xConnClientPrefix) >> 2;
+ if (!InsertFakeRequest(client, (char *)&data, sz_xReq))
+ {
+ FreeClientResources(client);
+ xfree(client);
+ return (ClientPtr)NULL;
+ }
+ if (i == currentMaxClients)
+ currentMaxClients++;
+ while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID])
+ nextFreeClientID++;
+ if (ClientStateCallback)
+ {
+ NewClientInfoRec clientinfo;
+
+ clientinfo.client = client;
+ clientinfo.prefix = (xConnSetupPrefix *)NULL;
+ clientinfo.setup = (xConnSetup *) NULL;
+ CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+ }
+ return(client);
+}
+
+int
+ProcInitialConnection(register ClientPtr client)
+{
+ REQUEST(xReq);
+ register xConnClientPrefix *prefix;
+ int whichbyte = 1;
+
+ prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
+ if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B'))
+ return (client->noClientException = -1);
+ if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) ||
+ (!(*(char *) &whichbyte) && (prefix->byteOrder == 'l')))
+ {
+ client->swapped = TRUE;
+ SwapConnClientPrefix(prefix);
+ }
+ stuff->reqType = 2;
+ stuff->length += ((prefix->nbytesAuthProto + (unsigned)3) >> 2) +
+ ((prefix->nbytesAuthString + (unsigned)3) >> 2);
+ if (client->swapped)
+ {
+ swaps(&stuff->length, whichbyte);
+ }
+ ResetCurrentRequest(client);
+ return (client->noClientException);
+}
+
+#ifdef LBX
+void
+IncrementClientCount()
+{
+ nClients++;
+}
+#endif
+
+int
+SendConnSetup(register ClientPtr client, char *reason)
+{
+ register xWindowRoot *root;
+ register int i;
+ int numScreens;
+ char* lConnectionInfo;
+ xConnSetupPrefix* lconnSetupPrefix;
+
+ if (reason)
+ {
+ xConnSetupPrefix csp;
+
+ csp.success = xFalse;
+ csp.lengthReason = strlen(reason);
+ csp.length = (csp.lengthReason + (unsigned)3) >> 2;
+ csp.majorVersion = X_PROTOCOL;
+ csp.minorVersion = X_PROTOCOL_REVISION;
+ if (client->swapped)
+ WriteSConnSetupPrefix(client, &csp);
+ else
+ (void)WriteToClient(client, sz_xConnSetupPrefix, (char *) &csp);
+ (void)WriteToClient(client, (int)csp.lengthReason, reason);
+ return (client->noClientException = -1);
+ }
+
+ numScreens = screenInfo.numScreens;
+ lConnectionInfo = ConnectionInfo;
+ lconnSetupPrefix = &connSetupPrefix;
+
+ /* We're about to start speaking X protocol back to the client by
+ * sending the connection setup info. This means the authorization
+ * step is complete, and we can count the client as an
+ * authorized one.
+ */
+ nClients++;
+
+ client->requestVector = client->swapped ? SwappedProcVector : ProcVector;
+ client->sequence = 0;
+#ifdef XAPPGROUP
+ XagConnectionInfo (client, &lconnSetupPrefix, &lConnectionInfo, &numScreens);
+#endif
+ ((xConnSetup *)lConnectionInfo)->ridBase = client->clientAsMask;
+ ((xConnSetup *)lConnectionInfo)->ridMask = RESOURCE_ID_MASK;
+#ifdef MATCH_CLIENT_ENDIAN
+ ((xConnSetup *)lConnectionInfo)->imageByteOrder = ClientOrder (client);
+ ((xConnSetup *)lConnectionInfo)->bitmapBitOrder = ClientOrder (client);
+#endif
+ /* fill in the "currentInputMask" */
+ root = (xWindowRoot *)(lConnectionInfo + connBlockScreenStart);
+#ifdef PANORAMIX
+ if (noPanoramiXExtension)
+ numScreens = screenInfo.numScreens;
+ else
+ numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
+#endif
+
+ for (i=0; i<numScreens; i++)
+ {
+ register unsigned int j;
+ register xDepth *pDepth;
+
+ root->currentInputMask = WindowTable[i]->eventMask |
+ wOtherEventMasks (WindowTable[i]);
+ pDepth = (xDepth *)(root + 1);
+ for (j = 0; j < root->nDepths; j++)
+ {
+ pDepth = (xDepth *)(((char *)(pDepth + 1)) +
+ pDepth->nVisuals * sizeof(xVisualType));
+ }
+ root = (xWindowRoot *)pDepth;
+ }
+
+ if (client->swapped)
+ {
+ WriteSConnSetupPrefix(client, lconnSetupPrefix);
+ WriteSConnectionInfo(client,
+ (unsigned long)(lconnSetupPrefix->length << 2),
+ lConnectionInfo);
+ }
+ else
+ {
+ (void)WriteToClient(client, sizeof(xConnSetupPrefix),
+ (char *) lconnSetupPrefix);
+ (void)WriteToClient(client, (int)(lconnSetupPrefix->length << 2),
+ lConnectionInfo);
+ }
+ client->clientState = ClientStateRunning;
+ if (ClientStateCallback)
+ {
+ NewClientInfoRec clientinfo;
+
+ clientinfo.client = client;
+ clientinfo.prefix = lconnSetupPrefix;
+ clientinfo.setup = (xConnSetup *)lConnectionInfo;
+ CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+ }
+ return (client->noClientException);
+}
+
+int
+ProcEstablishConnection(register ClientPtr client)
+{
+ char *reason, *auth_proto, *auth_string;
+ register xConnClientPrefix *prefix;
+ REQUEST(xReq);
+
+ prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
+ auth_proto = (char *)prefix + sz_xConnClientPrefix;
+ auth_string = auth_proto + ((prefix->nbytesAuthProto + 3) & ~3);
+ if ((prefix->majorVersion != X_PROTOCOL) ||
+ (prefix->minorVersion != X_PROTOCOL_REVISION))
+ reason = "Protocol version mismatch";
+ else
+ reason = ClientAuthorized(client,
+ (unsigned short)prefix->nbytesAuthProto,
+ auth_proto,
+ (unsigned short)prefix->nbytesAuthString,
+ auth_string);
+ /*
+ * If Kerberos is being used for this client, the clientState
+ * will be set to ClientStateAuthenticating at this point.
+ * More messages need to be exchanged among the X server, Kerberos
+ * server, and client to figure out if everyone is authorized.
+ * So we don't want to send the connection setup info yet, since
+ * the auth step isn't really done.
+ */
+ if (client->clientState == ClientStateCheckingSecurity)
+ client->clientState = ClientStateCheckedSecurity;
+ else if (client->clientState != ClientStateAuthenticating)
+ return(SendConnSetup(client, reason));
+ return(client->noClientException);
+}
+
+void
+SendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode,
+ XID resId, int errorCode)
+{
+ xError rep;
+
+ rep.type = X_Error;
+ rep.sequenceNumber = client->sequence;
+ rep.errorCode = errorCode;
+ rep.majorCode = majorCode;
+ rep.minorCode = minorCode;
+ rep.resourceID = resId;
+
+ WriteEventsToClient (client, 1, (xEvent *)&rep);
+}
+
+void
+DeleteWindowFromAnySelections(WindowPtr pWin)
+{
+ register int i;
+
+ for (i = 0; i< NumCurrentSelections; i++)
+ if (CurrentSelections[i].pWin == pWin)
+ {
+ if (SelectionCallback)
+ {
+ SelectionInfoRec info;
+
+ info.selection = &CurrentSelections[i];
+ info.kind = SelectionWindowDestroy;
+ CallCallbacks(&SelectionCallback, &info);
+ }
+ CurrentSelections[i].pWin = (WindowPtr)NULL;
+ CurrentSelections[i].window = None;
+ CurrentSelections[i].client = NullClient;
+ }
+}
+
+static void
+DeleteClientFromAnySelections(ClientPtr client)
+{
+ register int i;
+
+ for (i = 0; i< NumCurrentSelections; i++)
+ if (CurrentSelections[i].client == client)
+ {
+ if (SelectionCallback)
+ {
+ SelectionInfoRec info;
+
+ info.selection = &CurrentSelections[i];
+ info.kind = SelectionWindowDestroy;
+ CallCallbacks(&SelectionCallback, &info);
+ }
+ CurrentSelections[i].pWin = (WindowPtr)NULL;
+ CurrentSelections[i].window = None;
+ CurrentSelections[i].client = NullClient;
+ }
+}
+
+void
+MarkClientException(ClientPtr client)
+{
+ client->noClientException = -1;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c
new file mode 100644
index 000000000..6dfff3776
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c
@@ -0,0 +1,2797 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/* $XdotOrg: xc/programs/Xserver/dix/dixfonts.c,v 1.8 2005/07/03 08:53:38 daniels Exp $ */
+/* $XFree86: xc/programs/Xserver/dix/dixfonts.c,v 3.28 2003/11/08 02:02:03 dawes Exp $ */
+/************************************************************************
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+************************************************************************/
+/* The panoramix components contained the following notice */
+/*
+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.
+
+******************************************************************/
+/* $Xorg: dixfonts.c,v 1.4 2000/08/17 19:48:18 cpqbld Exp $ */
+
+#define NEED_REPLIES
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xmd.h>
+#include <X11/Xproto.h>
+#include "scrnintstr.h"
+#include "resource.h"
+#include "dixstruct.h"
+#include "cursorstr.h"
+#include "misc.h"
+#include "opaque.h"
+#include "dixfontstr.h"
+#include "closestr.h"
+
+/*
+#define NXAGENT_DEBUG
+*/
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#include "Agent.h"
+#include "Font.h"
+
+#ifndef NX_TRANS_SOCKET
+
+#define NX_TRANS_SOCKET
+
+#endif
+
+#ifdef NX_TRANS_SOCKET
+
+char _NXFontPath[1024];
+
+/*
+ * Override the default font path and make
+ * it configurable at run time, based on
+ * the NX_FONT environment.
+ */
+
+static const char *_NXGetFontPath(const char *path)
+{
+ const char *fontEnv;
+
+ /*
+ * Check the environment only once.
+ */
+
+ if (*_NXFontPath != '\0')
+ {
+ return _NXFontPath;
+ }
+
+ fontEnv = getenv("NX_FONT");
+
+ if (fontEnv != NULL && *fontEnv != '\0')
+ {
+ if (strlen(fontEnv) + 1 > 1024)
+ {
+#ifdef NX_TRANS_TEST
+ fprintf(stderr, "_NXGetFontPath: WARNING! Maximum length of font path exceeded.\n");
+#endif
+ goto _NXGetFontPathError;
+ }
+
+ strcpy(_NXFontPath, fontEnv);
+
+#ifdef NX_TRANS_TEST
+ fprintf(stderr, "_NXGetFontPath: Using NX font path [%s].\n", _NXFontPath);
+#endif
+
+ return _NXFontPath;
+ }
+
+_NXGetFontPathError:
+
+ strcpy(_NXFontPath, path);
+
+#ifdef NX_TRANS_TEST
+ fprintf(stderr, "_NXGetFontPath: Using default font path [%s].\n", _NXFontPath);
+#endif
+
+ return _NXFontPath;
+}
+
+#endif
+
+#ifdef PANORAMIX
+#include "../../Xext/panoramiX.h"
+#include "../../Xext/panoramiXsrv.h"
+#endif
+
+#ifdef LBX
+#include "lbxserve.h"
+#endif
+
+#ifdef XF86BIGFONT
+#define _XF86BIGFONT_SERVER_
+#include <X11/extensions/xf86bigfont.h>
+#endif
+
+#define QUERYCHARINFO(pci, pr) *(pr) = (pci)->metrics
+
+extern pointer fosNaturalParams;
+extern FontPtr defaultFont;
+
+static FontPathElementPtr *font_path_elements = (FontPathElementPtr *) 0;
+static int num_fpes = 0;
+FPEFunctions *fpe_functions = (FPEFunctions *) 0;
+static int num_fpe_types = 0;
+
+static unsigned char *font_path_string;
+
+static int num_slept_fpes = 0;
+static int size_slept_fpes = 0;
+static FontPathElementPtr *slept_fpes = (FontPathElementPtr *) 0;
+static FontPatternCachePtr patternCache;
+
+int
+FontToXError(err)
+ int err;
+{
+ switch (err) {
+ case Successful:
+ return Success;
+ case AllocError:
+ return BadAlloc;
+ case BadFontName:
+ return BadName;
+ case BadFontPath:
+ case BadFontFormat: /* is there something better? */
+ case BadCharRange:
+ return BadValue;
+ default:
+ return err;
+ }
+}
+
+
+/*
+ * adding RT_FONT prevents conflict with default cursor font
+ */
+Bool
+SetDefaultFont(char *defaultfontname)
+{
+ int err;
+ FontPtr pf;
+ XID fid;
+
+ fid = FakeClientID(0);
+ err = OpenFont(serverClient, fid, FontLoadAll | FontOpenSync,
+ (unsigned) strlen(defaultfontname), defaultfontname);
+ if (err != Success)
+ return FALSE;
+ pf = (FontPtr) LookupIDByType(fid, RT_FONT);
+ if (pf == (FontPtr) NULL)
+ return FALSE;
+ defaultFont = pf;
+ return TRUE;
+}
+
+/*
+ * note that the font wakeup queue is not refcounted. this is because
+ * an fpe needs to be added when it's inited, and removed when it's finally
+ * freed, in order to handle any data that isn't requested, like FS events.
+ *
+ * since the only thing that should call these routines is the renderer's
+ * init_fpe() and free_fpe(), there shouldn't be any problem in using
+ * freed data.
+ */
+void
+QueueFontWakeup(FontPathElementPtr fpe)
+{
+ int i;
+ FontPathElementPtr *new;
+
+ for (i = 0; i < num_slept_fpes; i++) {
+ if (slept_fpes[i] == fpe) {
+
+#ifdef DEBUG
+ fprintf(stderr, "re-queueing fpe wakeup\n");
+#endif
+
+ return;
+ }
+ }
+ if (num_slept_fpes == size_slept_fpes) {
+ new = (FontPathElementPtr *)
+ xrealloc(slept_fpes,
+ sizeof(FontPathElementPtr) * (size_slept_fpes + 4));
+ if (!new)
+ return;
+ slept_fpes = new;
+ size_slept_fpes += 4;
+ }
+ slept_fpes[num_slept_fpes] = fpe;
+ num_slept_fpes++;
+}
+
+void
+RemoveFontWakeup(FontPathElementPtr fpe)
+{
+ int i,
+ j;
+
+ for (i = 0; i < num_slept_fpes; i++) {
+ if (slept_fpes[i] == fpe) {
+ for (j = i; j < num_slept_fpes; j++) {
+ slept_fpes[j] = slept_fpes[j + 1];
+ }
+ num_slept_fpes--;
+ return;
+ }
+ }
+}
+
+void
+FontWakeup(pointer data, int count, pointer LastSelectMask)
+{
+ int i;
+ FontPathElementPtr fpe;
+
+ if (count < 0)
+ return;
+ /* wake up any fpe's that may be waiting for information */
+ for (i = 0; i < num_slept_fpes; i++) {
+ fpe = slept_fpes[i];
+ (void) (*fpe_functions[fpe->type].wakeup_fpe) (fpe, LastSelectMask);
+ }
+}
+
+/* XXX -- these two funcs may want to be broken into macros */
+static void
+UseFPE(FontPathElementPtr fpe)
+{
+ fpe->refcount++;
+}
+
+static void
+FreeFPE (FontPathElementPtr fpe)
+{
+ fpe->refcount--;
+ if (fpe->refcount == 0) {
+ (*fpe_functions[fpe->type].free_fpe) (fpe);
+ xfree(fpe->name);
+ xfree(fpe);
+ }
+}
+
+static Bool
+doOpenFont(ClientPtr client, OFclosurePtr c)
+{
+ FontPtr pfont = NullFont;
+ FontPathElementPtr fpe = NULL;
+ ScreenPtr pScr;
+ int err = Successful;
+ int i;
+ char *alias,
+ *newname;
+ int newlen;
+ int aliascount = 20;
+ char nxagentOrigFontName[256];
+ int nxagentOrigFontNameLen;
+
+ /*
+ * Decide at runtime what FontFormat to use.
+ */
+ Mask FontFormat =
+
+ ((screenInfo.imageByteOrder == LSBFirst) ?
+ BitmapFormatByteOrderLSB : BitmapFormatByteOrderMSB) |
+
+ ((screenInfo.bitmapBitOrder == LSBFirst) ?
+ BitmapFormatBitOrderLSB : BitmapFormatBitOrderMSB) |
+
+ BitmapFormatImageRectMin |
+
+#if GLYPHPADBYTES == 1
+ BitmapFormatScanlinePad8 |
+#endif
+
+#if GLYPHPADBYTES == 2
+ BitmapFormatScanlinePad16 |
+#endif
+
+#if GLYPHPADBYTES == 4
+ BitmapFormatScanlinePad32 |
+#endif
+
+#if GLYPHPADBYTES == 8
+ BitmapFormatScanlinePad64 |
+#endif
+
+ BitmapFormatScanlineUnit8;
+
+
+ nxagentOrigFontNameLen = (c -> origFontNameLen < 256) ? c -> origFontNameLen : 255;
+
+ memcpy(nxagentOrigFontName, c -> origFontName, nxagentOrigFontNameLen);
+
+ nxagentOrigFontName[nxagentOrigFontNameLen] = 0;
+
+ if (client->clientGone)
+ {
+ if (c->current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current_fpe];
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ }
+ err = Successful;
+ goto bail;
+ }
+ while (c->current_fpe < c->num_fpes) {
+ fpe = c->fpe_list[c->current_fpe];
+ err = (*fpe_functions[fpe->type].open_font)
+ ((pointer) client, fpe, c->flags,
+ c->fontname, c->fnamelen, FontFormat,
+ BitmapFormatMaskByte |
+ BitmapFormatMaskBit |
+ BitmapFormatMaskImageRectangle |
+ BitmapFormatMaskScanLinePad |
+ BitmapFormatMaskScanLineUnit,
+ c->fontid, &pfont, &alias,
+ c->non_cachable_font && c->non_cachable_font->fpe == fpe ?
+ c->non_cachable_font :
+ (FontPtr)0);
+
+ if (err == FontNameAlias && alias) {
+ newlen = strlen(alias);
+ newname = (char *) xrealloc(c->fontname, newlen);
+ if (!newname) {
+ err = AllocError;
+ break;
+ }
+ memmove(newname, alias, newlen);
+ c->fontname = newname;
+ c->fnamelen = newlen;
+ c->current_fpe = 0;
+ if (--aliascount <= 0)
+ break;
+ continue;
+ }
+ if (err == BadFontName) {
+ c->current_fpe++;
+ continue;
+ }
+ if (err == Suspended) {
+ if (!c->slept) {
+ c->slept = TRUE;
+ ClientSleep(client, (ClientSleepProcPtr)doOpenFont, (pointer) c);
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doOpenFont: client [%lx] sleeping.\n", client);
+#endif
+ }
+ return TRUE;
+ }
+ break;
+ }
+
+ if (err != Successful)
+ goto bail;
+ if (!pfont) {
+ err = BadFontName;
+ goto bail;
+ }
+ if (!pfont->fpe)
+ pfont->fpe = fpe;
+ pfont->refcnt++;
+ if (pfont->refcnt == 1) {
+ UseFPE(pfont->fpe);
+ for (i = 0; i < screenInfo.numScreens; i++) {
+ pScr = screenInfo.screens[i];
+ if (pScr->RealizeFont)
+ {
+
+ /* NXAGENT uses useless screen pointer to pass the original font name
+ * to realizeFont, could be a source of problems in the future.
+ */
+
+ if (!(*pScr->RealizeFont) ((ScreenPtr)nxagentOrigFontName, pfont))
+ {
+ CloseFont (pfont, (Font) 0);
+ err=BadFontName;
+ goto bail;
+ }
+ }
+ }
+ }
+ if (!AddResource(c->fontid, RT_FONT, (pointer) pfont)) {
+ err = AllocError;
+ goto bail;
+ }
+ if( nxagentFontPriv(pfont) -> mirrorID == 0 )
+ {
+ extern RESTYPE RT_NX_FONT;
+
+ nxagentFontPriv(pfont) -> mirrorID = FakeClientID(0);
+ if (!AddResource(nxagentFontPriv(pfont) -> mirrorID, RT_NX_FONT, (pointer) pfont)) {
+ FreeResource(c->fontid, RT_NONE);
+ err = AllocError;
+ goto bail;
+ }
+ }
+ if (patternCache && pfont != c->non_cachable_font)
+ CacheFontPattern(patternCache, nxagentOrigFontName, nxagentOrigFontNameLen,
+ pfont);
+bail:
+ if (err != Successful && c->client != serverClient) {
+ SendErrorToClient(c->client, X_OpenFont, 0,
+ c->fontid, FontToXError(err));
+ }
+ if (c->slept)
+ {
+ ClientWakeup(c->client);
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doOpenFont: client [%lx] wakeup.\n", client);
+#endif
+ }
+ for (i = 0; i < c->num_fpes; i++) {
+ FreeFPE(c->fpe_list[i]);
+ }
+ xfree(c->fpe_list);
+ xfree(c->fontname);
+ xfree(c);
+ return TRUE;
+}
+
+int
+OpenFont(ClientPtr client, XID fid, Mask flags, unsigned lenfname, char *pfontname)
+{
+ OFclosurePtr c;
+ int i;
+ FontPtr cached = (FontPtr)0;
+
+#ifdef FONTDEBUG
+ char *f;
+ f = (char *)xalloc(lenfname + 1);
+ memmove(f, pfontname, lenfname);
+ f[lenfname] = '\0';
+ ErrorF("OpenFont: fontname is \"%s\"\n", f);
+ xfree(f);
+#endif
+ if (!lenfname || lenfname > XLFDMAXFONTNAMELEN)
+ return BadName;
+ if (patternCache)
+ {
+
+ /*
+ ** Check name cache. If we find a cached version of this font that
+ ** is cachable, immediately satisfy the request with it. If we find
+ ** a cached version of this font that is non-cachable, we do not
+ ** satisfy the request with it. Instead, we pass the FontPtr to the
+ ** FPE's open_font code (the fontfile FPE in turn passes the
+ ** information to the rasterizer; the fserve FPE ignores it).
+ **
+ ** Presumably, the font is marked non-cachable because the FPE has
+ ** put some licensing restrictions on it. If the FPE, using
+ ** whatever logic it relies on, determines that it is willing to
+ ** share this existing font with the client, then it has the option
+ ** to return the FontPtr we passed it as the newly-opened font.
+ ** This allows the FPE to exercise its licensing logic without
+ ** having to create another instance of a font that already exists.
+ */
+
+ cached = FindCachedFontPattern(patternCache, pfontname, lenfname);
+ if (cached && cached->info.cachable)
+ {
+ if (!AddResource(fid, RT_FONT, (pointer) cached))
+ return BadAlloc;
+ cached->refcnt++;
+ return Success;
+ }
+ }
+ c = (OFclosurePtr) xalloc(sizeof(OFclosureRec));
+ if (!c)
+ return BadAlloc;
+ c->fontname = (char *) xalloc(lenfname);
+ c->origFontName = pfontname;
+ c->origFontNameLen = lenfname;
+ if (!c->fontname) {
+ xfree(c);
+ return BadAlloc;
+ }
+ /*
+ * copy the current FPE list, so that if it gets changed by another client
+ * while we're blocking, the request still appears atomic
+ */
+ c->fpe_list = (FontPathElementPtr *)
+ xalloc(sizeof(FontPathElementPtr) * num_fpes);
+ if (!c->fpe_list) {
+ xfree(c->fontname);
+ xfree(c);
+ return BadAlloc;
+ }
+ memmove(c->fontname, pfontname, lenfname);
+ for (i = 0; i < num_fpes; i++) {
+ c->fpe_list[i] = font_path_elements[i];
+ UseFPE(c->fpe_list[i]);
+ }
+ c->client = client;
+ c->fontid = fid;
+ c->current_fpe = 0;
+ c->num_fpes = num_fpes;
+ c->fnamelen = lenfname;
+ c->slept = FALSE;
+ c->flags = flags;
+ c->non_cachable_font = cached;
+
+ (void) doOpenFont(client, c);
+ return Success;
+}
+
+/**
+ * Decrement font's ref count, and free storage if ref count equals zero
+ *
+ * \param value must conform to DeleteType
+ */
+int
+CloseFont(pointer value, XID fid)
+{
+ int nscr;
+ ScreenPtr pscr;
+ FontPathElementPtr fpe;
+ FontPtr pfont = (FontPtr)value;
+
+ if (pfont == NullFont)
+ return (Success);
+ if (--pfont->refcnt == 0) {
+ if (patternCache)
+ RemoveCachedFontPattern (patternCache, pfont);
+ /*
+ * since the last reference is gone, ask each screen to free any
+ * storage it may have allocated locally for it.
+ */
+ for (nscr = 0; nscr < screenInfo.numScreens; nscr++) {
+ pscr = screenInfo.screens[nscr];
+ if (pscr->UnrealizeFont)
+ (*pscr->UnrealizeFont) (pscr, pfont);
+ }
+ if (pfont == defaultFont)
+ defaultFont = NULL;
+#ifdef LBX
+ LbxFreeFontTag(pfont);
+#endif
+#ifdef XF86BIGFONT
+ {
+ extern void XF86BigfontFreeFontShm(FontPtr);
+ XF86BigfontFreeFontShm(pfont);
+ }
+#endif
+ fpe = pfont->fpe;
+ (*fpe_functions[fpe->type].close_font) (fpe, pfont);
+ FreeFPE(fpe);
+ }
+ return (Success);
+}
+
+
+/***====================================================================***/
+
+/**
+ * Sets up pReply as the correct QueryFontReply for pFont with the first
+ * nProtoCCIStructs char infos.
+ *
+ * \param pReply caller must allocate this storage
+ */
+void
+QueryFont(FontPtr pFont, xQueryFontReply *pReply, int nProtoCCIStructs)
+{
+ FontPropPtr pFP;
+ int r,
+ c,
+ i;
+ xFontProp *prFP;
+ xCharInfo *prCI;
+ xCharInfo *charInfos[256];
+ unsigned char chars[512];
+ int ninfos;
+ unsigned long ncols;
+ unsigned long count;
+
+ /* pr->length set in dispatch */
+ pReply->minCharOrByte2 = pFont->info.firstCol;
+ pReply->defaultChar = pFont->info.defaultCh;
+ pReply->maxCharOrByte2 = pFont->info.lastCol;
+ pReply->drawDirection = pFont->info.drawDirection;
+ pReply->allCharsExist = pFont->info.allExist;
+ pReply->minByte1 = pFont->info.firstRow;
+ pReply->maxByte1 = pFont->info.lastRow;
+ pReply->fontAscent = pFont->info.fontAscent;
+ pReply->fontDescent = pFont->info.fontDescent;
+
+ pReply->minBounds = pFont->info.ink_minbounds;
+ pReply->maxBounds = pFont->info.ink_maxbounds;
+
+ pReply->nFontProps = pFont->info.nprops;
+ pReply->nCharInfos = nProtoCCIStructs;
+
+ for (i = 0, pFP = pFont->info.props, prFP = (xFontProp *) (&pReply[1]);
+ i < pFont->info.nprops;
+ i++, pFP++, prFP++) {
+ prFP->name = pFP->name;
+ prFP->value = pFP->value;
+ }
+
+ ninfos = 0;
+ ncols = (unsigned long) (pFont->info.lastCol - pFont->info.firstCol + 1);
+ prCI = (xCharInfo *) (prFP);
+ for (r = pFont->info.firstRow;
+ ninfos < nProtoCCIStructs && r <= (int)pFont->info.lastRow;
+ r++) {
+ i = 0;
+ for (c = pFont->info.firstCol; c <= (int)pFont->info.lastCol; c++) {
+ chars[i++] = r;
+ chars[i++] = c;
+ }
+ (*pFont->get_metrics) (pFont, ncols, chars,
+ TwoD16Bit, &count, charInfos);
+ i = 0;
+ for (i = 0; i < (int) count && ninfos < nProtoCCIStructs; i++) {
+ *prCI = *charInfos[i];
+ prCI++;
+ ninfos++;
+ }
+ }
+ return;
+}
+
+static Bool
+doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
+{
+ FontPathElementPtr fpe;
+ int err = Successful;
+ FontNamesPtr names = NULL;
+ char *name, *resolved=NULL;
+ int namelen, resolvedlen;
+ int nnames;
+ int stringLens;
+ int i;
+ xListFontsReply reply;
+ char *bufptr;
+ char *bufferStart;
+ int aliascount = 0;
+
+ if (client->clientGone)
+ {
+ if (c->current.current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current.current_fpe];
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ }
+ err = Successful;
+ goto bail;
+ }
+
+ if (!c->current.patlen)
+ goto finish;
+
+ while (c->current.current_fpe < c->num_fpes) {
+ fpe = c->fpe_list[c->current.current_fpe];
+ err = Successful;
+
+ if (!fpe_functions[fpe->type].start_list_fonts_and_aliases)
+ {
+ /* This FPE doesn't support/require list_fonts_and_aliases */
+
+ err = (*fpe_functions[fpe->type].list_fonts)
+ ((pointer) c->client, fpe, c->current.pattern,
+ c->current.patlen, c->current.max_names - c->names->nnames,
+ c->names);
+
+ if (err == Suspended) {
+ if (!c->slept) {
+ c->slept = TRUE;
+ ClientSleep(client,
+ (ClientSleepProcPtr)doListFontsAndAliases,
+ (pointer) c);
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doListFont (1): client [%lx] sleeping.\n", client);
+#endif
+ }
+ return TRUE;
+ }
+
+ err = BadFontName;
+ }
+ else
+ {
+ /* Start of list_fonts_and_aliases functionality. Modeled
+ after list_fonts_with_info in that it resolves aliases,
+ except that the information collected from FPEs is just
+ names, not font info. Each list_next_font_or_alias()
+ returns either a name into name/namelen or an alias into
+ name/namelen and its target name into resolved/resolvedlen.
+ The code at this level then resolves the alias by polling
+ the FPEs. */
+
+ if (!c->current.list_started) {
+ err = (*fpe_functions[fpe->type].start_list_fonts_and_aliases)
+ ((pointer) c->client, fpe, c->current.pattern,
+ c->current.patlen, c->current.max_names - c->names->nnames,
+ &c->current.private);
+ if (err == Suspended) {
+ if (!c->slept) {
+ ClientSleep(client,
+ (ClientSleepProcPtr)doListFontsAndAliases,
+ (pointer) c);
+ c->slept = TRUE;
+ }
+ return TRUE;
+ }
+ if (err == Successful)
+ c->current.list_started = TRUE;
+ }
+ if (err == Successful) {
+ char *tmpname;
+ name = 0;
+ err = (*fpe_functions[fpe->type].list_next_font_or_alias)
+ ((pointer) c->client, fpe, &name, &namelen, &tmpname,
+ &resolvedlen, c->current.private);
+ if (err == Suspended) {
+ if (!c->slept) {
+ ClientSleep(client,
+ (ClientSleepProcPtr)doListFontsAndAliases,
+ (pointer) c);
+ c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doListFont (2): client [%lx] sleeping.\n", client);
+#endif
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doListFont (3): client [%lx] sleeping.\n", client);
+#endif
+ }
+ return TRUE;
+ }
+ if (err == FontNameAlias) {
+ if (resolved) xfree(resolved);
+ resolved = (char *) xalloc(resolvedlen + 1);
+ if (resolved)
+ memmove(resolved, tmpname, resolvedlen + 1);
+ }
+ }
+
+ if (err == Successful)
+ {
+ if (c->haveSaved)
+ {
+ if (c->savedName)
+ (void)AddFontNamesName(c->names, c->savedName,
+ c->savedNameLen);
+ }
+ else
+ (void)AddFontNamesName(c->names, name, namelen);
+ }
+
+ /*
+ * When we get an alias back, save our state and reset back to
+ * the start of the FPE looking for the specified name. As
+ * soon as a real font is found for the alias, pop back to the
+ * old state
+ */
+ else if (err == FontNameAlias) {
+ char tmp_pattern[XLFDMAXFONTNAMELEN];
+ /*
+ * when an alias recurses, we need to give
+ * the last FPE a chance to clean up; so we call
+ * it again, and assume that the error returned
+ * is BadFontName, indicating the alias resolution
+ * is complete.
+ */
+ memmove(tmp_pattern, resolved, resolvedlen);
+ if (c->haveSaved)
+ {
+ char *tmpname;
+ int tmpnamelen;
+
+ tmpname = 0;
+ (void) (*fpe_functions[fpe->type].list_next_font_or_alias)
+ ((pointer) c->client, fpe, &tmpname, &tmpnamelen,
+ &tmpname, &tmpnamelen, c->current.private);
+ if (--aliascount <= 0)
+ {
+ err = BadFontName;
+ goto ContBadFontName;
+ }
+ }
+ else
+ {
+ c->saved = c->current;
+ c->haveSaved = TRUE;
+ if (c->savedName)
+ xfree(c->savedName);
+ c->savedName = (char *)xalloc(namelen + 1);
+ if (c->savedName)
+ memmove(c->savedName, name, namelen + 1);
+ c->savedNameLen = namelen;
+ aliascount = 20;
+ }
+ memmove(c->current.pattern, tmp_pattern, resolvedlen);
+ c->current.patlen = resolvedlen;
+ c->current.max_names = c->names->nnames + 1;
+ c->current.current_fpe = -1;
+ c->current.private = 0;
+ err = BadFontName;
+ }
+ }
+ /*
+ * At the end of this FPE, step to the next. If we've finished
+ * processing an alias, pop state back. If we've collected enough
+ * font names, quit.
+ */
+ if (err == BadFontName) {
+ ContBadFontName: ;
+ c->current.list_started = FALSE;
+ c->current.current_fpe++;
+ err = Successful;
+ if (c->haveSaved)
+ {
+ if (c->names->nnames == c->current.max_names ||
+ c->current.current_fpe == c->num_fpes) {
+ c->haveSaved = FALSE;
+ c->current = c->saved;
+ /* Give the saved namelist a chance to clean itself up */
+ continue;
+ }
+ }
+ if (c->names->nnames == c->current.max_names)
+ break;
+ }
+ }
+
+ /*
+ * send the reply
+ */
+ if (err != Successful) {
+ SendErrorToClient(client, X_ListFonts, 0, 0, FontToXError(err));
+ goto bail;
+ }
+
+finish:
+
+ names = c->names;
+ nnames = names->nnames;
+ client = c->client;
+ stringLens = 0;
+ for (i = 0; i < nnames; i++)
+ stringLens += (names->length[i] <= 255) ? names->length[i] : 0;
+
+ reply.type = X_Reply;
+ reply.length = (stringLens + nnames + 3) >> 2;
+ reply.nFonts = nnames;
+ reply.sequenceNumber = client->sequence;
+
+ bufptr = bufferStart = (char *) ALLOCATE_LOCAL(reply.length << 2);
+
+ if (!bufptr && reply.length) {
+ SendErrorToClient(client, X_ListFonts, 0, 0, BadAlloc);
+ goto bail;
+ }
+ /*
+ * since WriteToClient long word aligns things, copy to temp buffer and
+ * write all at once
+ */
+ for (i = 0; i < nnames; i++) {
+ if (names->length[i] > 255)
+ reply.nFonts--;
+ else
+ {
+ {
+ /* dirty hack: don't list to client fonts not existing on the remote side */
+ char tmp[256];
+
+ memcpy(tmp, names->names[i], names->length[i]);
+ tmp[ names->length[i] ] = 0;
+
+ if (nxagentFontLookUp(tmp) == 0)
+ {
+#ifdef NXAGENT_FONTMATCH_DEBUG
+ fprintf(stderr, "doListFontsAndAliases:\n");
+ fprintf(stderr, " removing font: %s \n", tmp);
+#endif
+ reply.nFonts--;
+ stringLens -= names->length[i];
+ continue;
+ }
+ }
+ *bufptr++ = names->length[i];
+ memmove( bufptr, names->names[i], names->length[i]);
+ bufptr += names->length[i];
+ }
+ }
+ nnames = reply.nFonts;
+ reply.length = (stringLens + nnames + 3) >> 2;
+ client->pSwapReplyFunc = ReplySwapVector[X_ListFonts];
+ WriteSwappedDataToClient(client, sizeof(xListFontsReply), &reply);
+ (void) WriteToClient(client, stringLens + nnames, bufferStart);
+ DEALLOCATE_LOCAL(bufferStart);
+
+bail:
+ if (c->slept)
+ {
+ ClientWakeup(client);
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doListFont: client [%lx] wakeup.\n", client);
+#endif
+ }
+ for (i = 0; i < c->num_fpes; i++)
+ FreeFPE(c->fpe_list[i]);
+ xfree(c->fpe_list);
+ if (c->savedName) xfree(c->savedName);
+ FreeFontNames(names);
+ xfree(c);
+ if (resolved) xfree(resolved);
+ return TRUE;
+}
+
+int
+ListFonts(ClientPtr client, unsigned char *pattern, unsigned length,
+ unsigned max_names)
+{
+ int i;
+ LFclosurePtr c;
+
+ /*
+ * The right error to return here would be BadName, however the
+ * specification does not allow for a Name error on this request.
+ * Perhaps a better solution would be to return a nil list, i.e.
+ * a list containing zero fontnames.
+ */
+ if (length > XLFDMAXFONTNAMELEN)
+ return BadAlloc;
+
+ if (!(c = (LFclosurePtr) xalloc(sizeof *c)))
+ return BadAlloc;
+ c->fpe_list = (FontPathElementPtr *)
+ xalloc(sizeof(FontPathElementPtr) * num_fpes);
+ if (!c->fpe_list) {
+ xfree(c);
+ return BadAlloc;
+ }
+ c->names = MakeFontNamesRecord(max_names < nxagentMaxFontNames ? max_names : nxagentMaxFontNames);
+ if (!c->names)
+ {
+ xfree(c->fpe_list);
+ xfree(c);
+ return BadAlloc;
+ }
+ memmove( c->current.pattern, pattern, length);
+ for (i = 0; i < num_fpes; i++) {
+ c->fpe_list[i] = font_path_elements[i];
+ UseFPE(c->fpe_list[i]);
+ }
+ c->client = client;
+ c->num_fpes = num_fpes;
+ c->current.patlen = length;
+ c->current.current_fpe = 0;
+ c->current.max_names = max_names;
+ c->current.list_started = FALSE;
+ c->current.private = 0;
+ c->haveSaved = FALSE;
+ c->slept = FALSE;
+ c->savedName = 0;
+ doListFontsAndAliases(client, c);
+ return Success;
+}
+
+int
+doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c)
+{
+ FontPathElementPtr fpe;
+ int err = Successful;
+ char *name;
+ int namelen;
+ int numFonts;
+ FontInfoRec fontInfo,
+ *pFontInfo;
+ xListFontsWithInfoReply *reply;
+ int length;
+ xFontProp *pFP;
+ int i;
+ int aliascount = 0;
+ xListFontsWithInfoReply finalReply;
+
+ if (client->clientGone)
+ {
+ if (c->current.current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current.current_fpe];
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ }
+ err = Successful;
+ goto bail;
+ }
+ client->pSwapReplyFunc = ReplySwapVector[X_ListFontsWithInfo];
+ if (!c->current.patlen)
+ goto finish;
+ while (c->current.current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current.current_fpe];
+ err = Successful;
+ if (!c->current.list_started)
+ {
+ err = (*fpe_functions[fpe->type].start_list_fonts_with_info)
+ (client, fpe, c->current.pattern, c->current.patlen,
+ c->current.max_names, &c->current.private);
+ if (err == Suspended)
+ {
+ if (!c->slept)
+ {
+ ClientSleep(client, (ClientSleepProcPtr)doListFontsWithInfo, c);
+ c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doListFontWinfo (1): client [%lx] sleeping.\n", client);
+#endif
+ }
+ return TRUE;
+ }
+ if (err == Successful)
+ c->current.list_started = TRUE;
+ }
+ if (err == Successful)
+ {
+ name = 0;
+ pFontInfo = &fontInfo;
+ err = (*fpe_functions[fpe->type].list_next_font_with_info)
+ (client, fpe, &name, &namelen, &pFontInfo,
+ &numFonts, c->current.private);
+ if (err == Suspended)
+ {
+ if (!c->slept)
+ {
+ ClientSleep(client,
+ (ClientSleepProcPtr)doListFontsWithInfo,
+ c);
+ c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doListFontWinfo (2): client [%lx] sleeping.\n", client);
+#endif
+ }
+ return TRUE;
+ }
+ }
+ /*
+ * When we get an alias back, save our state and reset back to the
+ * start of the FPE looking for the specified name. As soon as a real
+ * font is found for the alias, pop back to the old state
+ */
+ if (err == FontNameAlias)
+ {
+ /*
+ * when an alias recurses, we need to give
+ * the last FPE a chance to clean up; so we call
+ * it again, and assume that the error returned
+ * is BadFontName, indicating the alias resolution
+ * is complete.
+ */
+ if (c->haveSaved)
+ {
+ char *tmpname;
+ int tmpnamelen;
+ FontInfoPtr tmpFontInfo;
+
+ tmpname = 0;
+ tmpFontInfo = &fontInfo;
+ (void) (*fpe_functions[fpe->type].list_next_font_with_info)
+ (client, fpe, &tmpname, &tmpnamelen, &tmpFontInfo,
+ &numFonts, c->current.private);
+ if (--aliascount <= 0)
+ {
+ err = BadFontName;
+ goto ContBadFontName;
+ }
+ }
+ else
+ {
+ c->saved = c->current;
+ c->haveSaved = TRUE;
+ c->savedNumFonts = numFonts;
+ if (c->savedName)
+ xfree(c->savedName);
+ c->savedName = (char *)xalloc(namelen + 1);
+ if (c->savedName)
+ memmove(c->savedName, name, namelen + 1);
+ aliascount = 20;
+ }
+ memmove(c->current.pattern, name, namelen);
+ c->current.patlen = namelen;
+ c->current.max_names = 1;
+ c->current.current_fpe = 0;
+ c->current.private = 0;
+ c->current.list_started = FALSE;
+ }
+ /*
+ * At the end of this FPE, step to the next. If we've finished
+ * processing an alias, pop state back. If we've sent enough font
+ * names, quit. Always wait for BadFontName to let the FPE
+ * have a chance to clean up.
+ */
+ else if (err == BadFontName)
+ {
+ ContBadFontName: ;
+ c->current.list_started = FALSE;
+ c->current.current_fpe++;
+ err = Successful;
+ if (c->haveSaved)
+ {
+ if (c->current.max_names == 0 ||
+ c->current.current_fpe == c->num_fpes)
+ {
+ c->haveSaved = FALSE;
+ c->saved.max_names -= (1 - c->current.max_names);
+ c->current = c->saved;
+ }
+ }
+ else if (c->current.max_names == 0)
+ break;
+ }
+ else if (err == Successful)
+ {
+
+ if (c->haveSaved)
+ {
+ numFonts = c->savedNumFonts;
+ name = c->savedName;
+ namelen = strlen(name);
+ }
+
+ if (nxagentFontLookUp(name) == 0)
+ {
+#ifdef NXAGENT_FONTMATCH_DEBUG
+ fprintf(stderr, "doListFontsAndAliases (with info):\n");
+ fprintf(stderr, " removing font: %s \n", name);
+#endif
+ continue;
+ }
+
+ length = sizeof(*reply) + pFontInfo->nprops * sizeof(xFontProp);
+ reply = c->reply;
+ if (c->length < length)
+ {
+ reply = (xListFontsWithInfoReply *) xrealloc(c->reply, length);
+ if (!reply)
+ {
+ err = AllocError;
+ break;
+ }
+ c->reply = reply;
+ c->length = length;
+ }
+ reply->type = X_Reply;
+ reply->length = (sizeof *reply - sizeof(xGenericReply) +
+ pFontInfo->nprops * sizeof(xFontProp) +
+ namelen + 3) >> 2;
+ reply->sequenceNumber = client->sequence;
+ reply->nameLength = namelen;
+ reply->minBounds = pFontInfo->ink_minbounds;
+ reply->maxBounds = pFontInfo->ink_maxbounds;
+ reply->minCharOrByte2 = pFontInfo->firstCol;
+ reply->maxCharOrByte2 = pFontInfo->lastCol;
+ reply->defaultChar = pFontInfo->defaultCh;
+ reply->nFontProps = pFontInfo->nprops;
+ reply->drawDirection = pFontInfo->drawDirection;
+ reply->minByte1 = pFontInfo->firstRow;
+ reply->maxByte1 = pFontInfo->lastRow;
+ reply->allCharsExist = pFontInfo->allExist;
+ reply->fontAscent = pFontInfo->fontAscent;
+ reply->fontDescent = pFontInfo->fontDescent;
+ reply->nReplies = numFonts;
+ pFP = (xFontProp *) (reply + 1);
+ for (i = 0; i < pFontInfo->nprops; i++)
+ {
+ pFP->name = pFontInfo->props[i].name;
+ pFP->value = pFontInfo->props[i].value;
+ pFP++;
+ }
+ WriteSwappedDataToClient(client, length, reply);
+ (void) WriteToClient(client, namelen, name);
+ if (pFontInfo == &fontInfo)
+ {
+ xfree(fontInfo.props);
+ xfree(fontInfo.isStringProp);
+ }
+ --c->current.max_names;
+ }
+ }
+finish:
+ length = sizeof(xListFontsWithInfoReply);
+ bzero((char *) &finalReply, sizeof(xListFontsWithInfoReply));
+ finalReply.type = X_Reply;
+ finalReply.sequenceNumber = client->sequence;
+ finalReply.length = (sizeof(xListFontsWithInfoReply)
+ - sizeof(xGenericReply)) >> 2;
+ WriteSwappedDataToClient(client, length, &finalReply);
+bail:
+ if (c->slept)
+ {
+ ClientWakeup(client);
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doListFontWinfo: client [%lx] wakeup.\n", client);
+#endif
+ }
+ for (i = 0; i < c->num_fpes; i++)
+ FreeFPE(c->fpe_list[i]);
+ xfree(c->reply);
+ xfree(c->fpe_list);
+ if (c->savedName) xfree(c->savedName);
+ xfree(c);
+ return TRUE;
+}
+
+int
+StartListFontsWithInfo(ClientPtr client, int length, unsigned char *pattern,
+ int max_names)
+{
+ int i;
+ LFWIclosurePtr c;
+
+ /*
+ * The right error to return here would be BadName, however the
+ * specification does not allow for a Name error on this request.
+ * Perhaps a better solution would be to return a nil list, i.e.
+ * a list containing zero fontnames.
+ */
+ if (length > XLFDMAXFONTNAMELEN)
+ return BadAlloc;
+
+ if (!(c = (LFWIclosurePtr) xalloc(sizeof *c)))
+ goto badAlloc;
+ c->fpe_list = (FontPathElementPtr *)
+ xalloc(sizeof(FontPathElementPtr) * num_fpes);
+ if (!c->fpe_list)
+ {
+ xfree(c);
+ goto badAlloc;
+ }
+ memmove(c->current.pattern, pattern, length);
+ for (i = 0; i < num_fpes; i++)
+ {
+ c->fpe_list[i] = font_path_elements[i];
+ UseFPE(c->fpe_list[i]);
+ }
+ c->client = client;
+ c->num_fpes = num_fpes;
+ c->reply = 0;
+ c->length = 0;
+ c->current.patlen = length;
+ c->current.current_fpe = 0;
+ c->current.max_names = max_names;
+ c->current.list_started = FALSE;
+ c->current.private = 0;
+ c->savedNumFonts = 0;
+ c->haveSaved = FALSE;
+ c->slept = FALSE;
+ c->savedName = 0;
+ doListFontsWithInfo(client, c);
+ return Success;
+badAlloc:
+ return BadAlloc;
+}
+
+#define TextEltHeader 2
+#define FontShiftSize 5
+static XID clearGC[] = { CT_NONE };
+#define clearGCmask (GCClipMask)
+
+int
+doPolyText(ClientPtr client, register PTclosurePtr c)
+{
+ register FontPtr pFont = c->pGC->font, oldpFont;
+ Font fid, oldfid;
+ int err = Success, lgerr; /* err is in X error, not font error, space */
+ enum { NEVER_SLEPT, START_SLEEP, SLEEPING } client_state = NEVER_SLEPT;
+ FontPathElementPtr fpe;
+ GC *origGC = NULL;
+
+ if (client->clientGone)
+ {
+ fpe = c->pGC->font->fpe;
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+
+ if (c->slept)
+ {
+ /* Client has died, but we cannot bail out right now. We
+ need to clean up after the work we did when going to
+ sleep. Setting the drawable pointer to 0 makes this
+ happen without any attempts to render or perform other
+ unnecessary activities. */
+ c->pDraw = (DrawablePtr)0;
+ }
+ else
+ {
+ err = Success;
+ goto bail;
+ }
+ }
+
+ /* Make sure our drawable hasn't disappeared while we slept. */
+ if (c->slept &&
+ c->pDraw &&
+ c->pDraw != (DrawablePtr)SecurityLookupIDByClass(client, c->did,
+ RC_DRAWABLE, SecurityWriteAccess))
+ {
+ /* Our drawable has disappeared. Treat like client died... ask
+ the FPE code to clean up after client and avoid further
+ rendering while we clean up after ourself. */
+ fpe = c->pGC->font->fpe;
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ c->pDraw = (DrawablePtr)0;
+ }
+
+ client_state = c->slept ? SLEEPING : NEVER_SLEPT;
+
+ while (c->endReq - c->pElt > TextEltHeader)
+ {
+ if (*c->pElt == FontChange)
+ {
+ if (c->endReq - c->pElt < FontShiftSize)
+ {
+ err = BadLength;
+ goto bail;
+ }
+
+ oldpFont = pFont;
+ oldfid = fid;
+
+ fid = ((Font)*(c->pElt+4)) /* big-endian */
+ | ((Font)*(c->pElt+3)) << 8
+ | ((Font)*(c->pElt+2)) << 16
+ | ((Font)*(c->pElt+1)) << 24;
+ pFont = (FontPtr)SecurityLookupIDByType(client, fid, RT_FONT,
+ SecurityReadAccess);
+ if (!pFont)
+ {
+ client->errorValue = fid;
+ err = BadFont;
+ /* restore pFont and fid for step 4 (described below) */
+ pFont = oldpFont;
+ fid = oldfid;
+
+ /* If we're in START_SLEEP mode, the following step
+ shortens the request... in the unlikely event that
+ the fid somehow becomes valid before we come through
+ again to actually execute the polytext, which would
+ then mess up our refcounting scheme badly. */
+ c->err = err;
+ c->endReq = c->pElt;
+
+ goto bail;
+ }
+
+ /* Step 3 (described below) on our new font */
+ if (client_state == START_SLEEP)
+ pFont->refcnt++;
+ else
+ {
+ if (pFont != c->pGC->font && c->pDraw)
+ {
+ ChangeGC( c->pGC, GCFont, &fid);
+ ValidateGC(c->pDraw, c->pGC);
+ if (c->reqType == X_PolyText8)
+ c->polyText = (PolyTextPtr) c->pGC->ops->PolyText8;
+ else
+ c->polyText = (PolyTextPtr) c->pGC->ops->PolyText16;
+ }
+
+ /* Undo the refcnt++ we performed when going to sleep */
+ if (client_state == SLEEPING)
+ (void)CloseFont(c->pGC->font, (Font)0);
+ }
+ c->pElt += FontShiftSize;
+ }
+ else /* print a string */
+ {
+ unsigned char *pNextElt;
+ pNextElt = c->pElt + TextEltHeader + (*c->pElt)*c->itemSize;
+ if ( pNextElt > c->endReq)
+ {
+ err = BadLength;
+ goto bail;
+ }
+ if (client_state == START_SLEEP)
+ {
+ c->pElt = pNextElt;
+ continue;
+ }
+ if (c->pDraw)
+ {
+ lgerr = LoadGlyphs(client, c->pGC->font, *c->pElt, c->itemSize,
+ c->pElt + TextEltHeader);
+ }
+ else lgerr = Successful;
+
+ if (lgerr == Suspended)
+ {
+ if (!c->slept) {
+ int len;
+ GC *pGC;
+ PTclosurePtr new_closure;
+
+ /* We're putting the client to sleep. We need to do a few things
+ to ensure successful and atomic-appearing execution of the
+ remainder of the request. First, copy the remainder of the
+ request into a safe malloc'd area. Second, create a scratch GC
+ to use for the remainder of the request. Third, mark all fonts
+ referenced in the remainder of the request to prevent their
+ deallocation. Fourth, make the original GC look like the
+ request has completed... set its font to the final font value
+ from this request. These GC manipulations are for the unlikely
+ (but possible) event that some other client is using the GC.
+ Steps 3 and 4 are performed by running this procedure through
+ the remainder of the request in a special no-render mode
+ indicated by client_state = START_SLEEP. */
+
+ /* Step 1 */
+ /* Allocate a malloc'd closure structure to replace
+ the local one we were passed */
+ new_closure = (PTclosurePtr) xalloc(sizeof(PTclosureRec));
+ if (!new_closure)
+ {
+ err = BadAlloc;
+ goto bail;
+ }
+ *new_closure = *c;
+ c = new_closure;
+
+ len = c->endReq - c->pElt;
+ c->data = (unsigned char *)xalloc(len);
+ if (!c->data)
+ {
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+ memmove(c->data, c->pElt, len);
+ c->pElt = c->data;
+ c->endReq = c->pElt + len;
+
+ /* Step 2 */
+
+ pGC = GetScratchGC(c->pGC->depth, c->pGC->pScreen);
+ if (!pGC)
+ {
+ xfree(c->data);
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+
+ pGC->tileIsPixel = TRUE;
+ pGC->tile.pixel = 0;
+ pGC->stipple = NullPixmap;
+
+ if ((err = CopyGC(c->pGC, pGC, GCFunction |
+ GCPlaneMask | GCForeground |
+ GCBackground | GCFillStyle |
+ GCTile | GCStipple |
+ GCTileStipXOrigin |
+ GCTileStipYOrigin | GCFont |
+ GCSubwindowMode | GCClipXOrigin |
+ GCClipYOrigin | GCClipMask)) !=
+ Success)
+ {
+ FreeScratchGC(pGC);
+ xfree(c->data);
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+ origGC = c->pGC;
+ c->pGC = pGC;
+ ValidateGC(c->pDraw, c->pGC);
+
+ c->slept = TRUE;
+ ClientSleep(client,
+ (ClientSleepProcPtr)doPolyText,
+ (pointer) c);
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doPolyText (1): client [%lx] sleeping.\n", client);
+#endif
+
+ /* Set up to perform steps 3 and 4 */
+ client_state = START_SLEEP;
+ continue; /* on to steps 3 and 4 */
+ }
+ return TRUE;
+ }
+ else if (lgerr != Successful)
+ {
+ err = FontToXError(lgerr);
+ goto bail;
+ }
+ if (c->pDraw)
+ {
+ c->xorg += *((INT8 *)(c->pElt + 1)); /* must be signed */
+ c->xorg = (* c->polyText)(c->pDraw, c->pGC, c->xorg, c->yorg,
+ *c->pElt, c->pElt + TextEltHeader);
+ }
+ c->pElt = pNextElt;
+ }
+ }
+
+bail:
+
+ if (client_state == START_SLEEP)
+ {
+ /* Step 4 */
+ if (pFont != origGC->font)
+ {
+ ChangeGC(origGC, GCFont, &fid);
+ ValidateGC(c->pDraw, origGC);
+ }
+
+ /* restore pElt pointer for execution of remainder of the request */
+ c->pElt = c->data;
+ return TRUE;
+ }
+
+ if (c->err != Success) err = c->err;
+ if (err != Success && c->client != serverClient) {
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !c->pGC->pScreen->myNum)
+#endif
+ SendErrorToClient(c->client, c->reqType, 0, 0, err);
+ }
+ if (c->slept)
+ {
+ ClientWakeup(c->client);
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doPolytext: client [%lx] wakeup.\n", client);
+#endif
+ ChangeGC(c->pGC, clearGCmask, clearGC);
+
+ /* Unreference the font from the scratch GC */
+ CloseFont(c->pGC->font, (Font)0);
+ c->pGC->font = NullFont;
+
+ FreeScratchGC(c->pGC);
+ xfree(c->data);
+ xfree(c);
+ }
+ return TRUE;
+}
+
+int
+PolyText(ClientPtr client, DrawablePtr pDraw, GC *pGC, unsigned char *pElt,
+ unsigned char *endReq, int xorg, int yorg, int reqType, XID did)
+{
+ PTclosureRec local_closure;
+
+ local_closure.pElt = pElt;
+ local_closure.endReq = endReq;
+ local_closure.client = client;
+ local_closure.pDraw = pDraw;
+ local_closure.xorg = xorg;
+ local_closure.yorg = yorg;
+ if ((local_closure.reqType = reqType) == X_PolyText8)
+ {
+ local_closure.polyText = (PolyTextPtr) pGC->ops->PolyText8;
+ local_closure.itemSize = 1;
+ }
+ else
+ {
+ local_closure.polyText = (PolyTextPtr) pGC->ops->PolyText16;
+ local_closure.itemSize = 2;
+ }
+ local_closure.pGC = pGC;
+ local_closure.did = did;
+ local_closure.err = Success;
+ local_closure.slept = FALSE;
+
+ (void) doPolyText(client, &local_closure);
+ return Success;
+}
+
+
+#undef TextEltHeader
+#undef FontShiftSize
+
+int
+doImageText(ClientPtr client, register ITclosurePtr c)
+{
+ int err = Success, lgerr; /* err is in X error, not font error, space */
+ FontPathElementPtr fpe;
+
+ if (client->clientGone)
+ {
+ fpe = c->pGC->font->fpe;
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ err = Success;
+ goto bail;
+ }
+
+ /* Make sure our drawable hasn't disappeared while we slept. */
+ if (c->slept &&
+ c->pDraw &&
+ c->pDraw != (DrawablePtr)SecurityLookupIDByClass(client, c->did,
+ RC_DRAWABLE, SecurityWriteAccess))
+ {
+ /* Our drawable has disappeared. Treat like client died... ask
+ the FPE code to clean up after client. */
+ fpe = c->pGC->font->fpe;
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ err = Success;
+ goto bail;
+ }
+
+ lgerr = LoadGlyphs(client, c->pGC->font, c->nChars, c->itemSize, c->data);
+ if (lgerr == Suspended)
+ {
+ if (!c->slept) {
+ GC *pGC;
+ unsigned char *data;
+ ITclosurePtr new_closure;
+
+ /* We're putting the client to sleep. We need to
+ save some state. Similar problem to that handled
+ in doPolyText, but much simpler because the
+ request structure is much simpler. */
+
+ new_closure = (ITclosurePtr) xalloc(sizeof(ITclosureRec));
+ if (!new_closure)
+ {
+ err = BadAlloc;
+ goto bail;
+ }
+ *new_closure = *c;
+ c = new_closure;
+
+ data = (unsigned char *)xalloc(c->nChars * c->itemSize);
+ if (!data)
+ {
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+ memmove(data, c->data, c->nChars * c->itemSize);
+ c->data = data;
+
+ pGC = GetScratchGC(c->pGC->depth, c->pGC->pScreen);
+ if (!pGC)
+ {
+ xfree(c->data);
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+
+ pGC->tileIsPixel = TRUE;
+ pGC->tile.pixel = 0;
+ pGC->stipple = NullPixmap;
+
+ if ((err = CopyGC(c->pGC, pGC, GCFunction | GCPlaneMask |
+ GCForeground | GCBackground | GCFillStyle |
+ GCTile | GCStipple | GCTileStipXOrigin |
+ GCTileStipYOrigin | GCFont |
+ GCSubwindowMode | GCClipXOrigin |
+ GCClipYOrigin | GCClipMask)) != Success)
+ {
+ FreeScratchGC(pGC);
+ xfree(c->data);
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+ c->pGC = pGC;
+ ValidateGC(c->pDraw, c->pGC);
+
+ c->slept = TRUE;
+ ClientSleep(client, (ClientSleepProcPtr)doImageText, (pointer) c);
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doImageText (1): client [%lx] sleeping.\n", client);
+#endif
+
+ }
+ return TRUE;
+ }
+ else if (lgerr != Successful)
+ {
+ err = FontToXError(lgerr);
+ goto bail;
+ }
+ if (c->pDraw)
+ {
+ (* c->imageText)(c->pDraw, c->pGC, c->xorg, c->yorg,
+ c->nChars, c->data);
+ }
+
+bail:
+
+ if (err != Success && c->client != serverClient) {
+ SendErrorToClient(c->client, c->reqType, 0, 0, err);
+ }
+ if (c->slept)
+ {
+ ClientWakeup(c->client);
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doImageText: client [%lx] wakeup.\n", client);
+#endif
+ ChangeGC(c->pGC, clearGCmask, clearGC);
+
+ /* Unreference the font from the scratch GC */
+ CloseFont(c->pGC->font, (Font)0);
+ c->pGC->font = NullFont;
+
+ FreeScratchGC(c->pGC);
+ xfree(c->data);
+ xfree(c);
+ }
+ return TRUE;
+}
+
+int
+ImageText(ClientPtr client, DrawablePtr pDraw, GC *pGC, int nChars,
+ unsigned char *data, int xorg, int yorg, int reqType, XID did)
+{
+ ITclosureRec local_closure;
+
+ local_closure.client = client;
+ local_closure.pDraw = pDraw;
+ local_closure.pGC = pGC;
+ local_closure.nChars = nChars;
+ local_closure.data = data;
+ local_closure.xorg = xorg;
+ local_closure.yorg = yorg;
+ if ((local_closure.reqType = reqType) == X_ImageText8)
+ {
+ local_closure.imageText = (ImageTextPtr) pGC->ops->ImageText8;
+ local_closure.itemSize = 1;
+ }
+ else
+ {
+ local_closure.imageText = (ImageTextPtr) pGC->ops->ImageText16;
+ local_closure.itemSize = 2;
+ }
+ local_closure.did = did;
+ local_closure.slept = FALSE;
+
+ (void) doImageText(client, &local_closure);
+ return Success;
+}
+
+
+/* does the necessary magic to figure out the fpe type */
+static int
+DetermineFPEType(char *pathname)
+{
+ int i;
+
+ for (i = 0; i < num_fpe_types; i++) {
+ if ((*fpe_functions[i].name_check) (pathname))
+ return i;
+ }
+ return -1;
+}
+
+
+static void
+FreeFontPath(FontPathElementPtr *list, int n, Bool force)
+{
+ int i;
+
+ for (i = 0; i < n; i++) {
+ if (force) {
+ /* Sanity check that all refcounts will be 0 by the time
+ we get to the end of the list. */
+ int found = 1; /* the first reference is us */
+ int j;
+ for (j = i+1; j < n; j++) {
+ if (list[j] == list[i])
+ found++;
+ }
+ if (list[i]->refcount != found) {
+ ErrorF("FreeFontPath: FPE \"%.*s\" refcount is %d, should be %d; fixing.\n",
+ list[i]->name_length, list[i]->name,
+ list[i]->refcount, found);
+ list[i]->refcount = found; /* ensure it will get freed */
+ }
+ }
+ FreeFPE(list[i]);
+ }
+ xfree((char *) list);
+}
+
+static FontPathElementPtr
+find_existing_fpe(FontPathElementPtr *list, int num, unsigned char *name, int len)
+{
+ FontPathElementPtr fpe;
+ int i;
+
+ for (i = 0; i < num; i++) {
+ fpe = list[i];
+ if (fpe->name_length == len && memcmp(name, fpe->name, len) == 0)
+ return fpe;
+ }
+ return (FontPathElementPtr) 0;
+}
+
+
+static int
+SetFontPathElements(int npaths, unsigned char *paths, int *bad, Bool persist)
+{
+ int i, err = 0;
+ int valid_paths = 0;
+ unsigned int len;
+ unsigned char *cp = paths;
+ FontPathElementPtr fpe = NULL, *fplist;
+
+ fplist = (FontPathElementPtr *)
+ xalloc(sizeof(FontPathElementPtr) * npaths);
+ if (!fplist) {
+ *bad = 0;
+ return BadAlloc;
+ }
+ for (i = 0; i < num_fpe_types; i++) {
+ if (fpe_functions[i].set_path_hook)
+ (*fpe_functions[i].set_path_hook) ();
+ }
+ for (i = 0; i < npaths; i++)
+ {
+ len = (unsigned int) (*cp++);
+
+ if (len == 0)
+ {
+ if (persist)
+ ErrorF ("Removing empty element from the valid list of fontpaths\n");
+ err = BadValue;
+ }
+ else
+ {
+ /* if it's already in our active list, just reset it */
+ /*
+ * note that this can miss FPE's in limbo -- may be worth catching
+ * them, though it'd muck up refcounting
+ */
+ fpe = find_existing_fpe(font_path_elements, num_fpes, cp, len);
+ if (fpe)
+ {
+ err = (*fpe_functions[fpe->type].reset_fpe) (fpe);
+ if (err == Successful)
+ {
+ UseFPE(fpe);/* since it'll be decref'd later when freed
+ * from the old list */
+ }
+ else
+ fpe = 0;
+ }
+ /* if error or can't do it, act like it's a new one */
+ if (!fpe)
+ {
+ fpe = (FontPathElementPtr) xalloc(sizeof(FontPathElementRec));
+ if (!fpe)
+ {
+ err = BadAlloc;
+ goto bail;
+ }
+ fpe->name = (char *) xalloc(len + 1);
+ if (!fpe->name)
+ {
+ xfree(fpe);
+ err = BadAlloc;
+ goto bail;
+ }
+ fpe->refcount = 1;
+
+ strncpy(fpe->name, (char *) cp, (int) len);
+ fpe->name[len] = '\0';
+ fpe->name_length = len;
+ fpe->type = DetermineFPEType(fpe->name);
+ if (fpe->type == -1)
+ err = BadValue;
+ else
+ err = (*fpe_functions[fpe->type].init_fpe) (fpe);
+ if (err != Successful)
+ {
+ #ifndef NXAGENT_SERVER
+ if (persist)
+ {
+ ErrorF("Could not init font path element %s, removing from list!\n",
+ fpe->name);
+ }
+ #endif
+ xfree (fpe->name);
+ xfree (fpe);
+ }
+ }
+ }
+ if (err != Successful)
+ {
+ if (!persist)
+ goto bail;
+ }
+ else
+ {
+ fplist[valid_paths++] = fpe;
+ }
+ cp += len;
+ }
+
+ FreeFontPath(font_path_elements, num_fpes, FALSE);
+ font_path_elements = fplist;
+ if (patternCache)
+ EmptyFontPatternCache(patternCache);
+ num_fpes = valid_paths;
+
+ return Success;
+bail:
+ *bad = i;
+ while (--valid_paths >= 0)
+ FreeFPE(fplist[valid_paths]);
+ xfree(fplist);
+ return FontToXError(err);
+}
+
+/* XXX -- do we need to pass error down to each renderer? */
+int
+SetFontPath(ClientPtr client, int npaths, unsigned char *paths, int *error)
+{
+ int err = Success;
+
+ if (npaths == 0) {
+ if (SetDefaultFontPath(defaultFontPath) != Success)
+ return BadValue;
+ } else {
+ err = SetFontPathElements(npaths, paths, error, FALSE);
+ }
+ return err;
+}
+
+int
+SetDefaultFontPath(char *path)
+{
+ unsigned char *cp,
+ *pp,
+ *nump,
+ *newpath;
+ int num = 1,
+ len,
+ err,
+ size = 0,
+ bad;
+
+ /* get enough for string, plus values -- use up commas */
+#ifdef NX_TRANS_SOCKET
+ len = strlen(_NXGetFontPath(path)) + 1;
+#else
+ len = strlen(path) + 1;
+#endif
+ nump = cp = newpath = (unsigned char *) ALLOCATE_LOCAL(len);
+ if (!newpath)
+ return BadAlloc;
+#ifdef NX_TRANS_SOCKET
+ pp = (unsigned char *) _NXGetFontPath(path);
+#else
+ pp = (unsigned char *) path;
+#endif
+ cp++;
+ while (*pp) {
+ if (*pp == ',') {
+ *nump = (unsigned char) size;
+ nump = cp++;
+ pp++;
+ num++;
+ size = 0;
+ } else {
+ *cp++ = *pp++;
+ size++;
+ }
+ }
+ *nump = (unsigned char) size;
+
+ err = SetFontPathElements(num, newpath, &bad, TRUE);
+
+ DEALLOCATE_LOCAL(newpath);
+
+ return err;
+}
+
+unsigned char *
+GetFontPath(int *count, int *length)
+{
+ int i;
+ unsigned char *c;
+ int len;
+ FontPathElementPtr fpe;
+
+ len = 0;
+ for (i = 0; i < num_fpes; i++) {
+ fpe = font_path_elements[i];
+ len += fpe->name_length + 1;
+ }
+ font_path_string = (unsigned char *) xrealloc(font_path_string, len);
+ if (!font_path_string)
+ return NULL;
+
+ c = font_path_string;
+ *length = 0;
+ for (i = 0; i < num_fpes; i++) {
+ fpe = font_path_elements[i];
+ *c = fpe->name_length;
+ *length += *c++;
+ memmove(c, fpe->name, fpe->name_length);
+ c += fpe->name_length;
+ }
+ *count = num_fpes;
+ return font_path_string;
+}
+
+int
+LoadGlyphs(ClientPtr client, FontPtr pfont, unsigned nchars, int item_size, unsigned char *data)
+{
+ if (fpe_functions[pfont->fpe->type].load_glyphs)
+ return (*fpe_functions[pfont->fpe->type].load_glyphs)
+ (client, pfont, 0, nchars, item_size, data);
+ else
+ return Successful;
+}
+
+void
+DeleteClientFontStuff(ClientPtr client)
+{
+ int i;
+ FontPathElementPtr fpe;
+
+ for (i = 0; i < num_fpes; i++)
+ {
+ fpe = font_path_elements[i];
+ if (fpe_functions[fpe->type].client_died)
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ }
+}
+
+void
+InitFonts ()
+{
+ patternCache = MakeFontPatternCache();
+
+#ifndef KDRIVESERVER
+ if (screenInfo.numScreens > screenInfo.numVideoScreens) {
+ PrinterFontRegisterFpeFunctions();
+ FontFileCheckRegisterFpeFunctions();
+ check_fs_register_fpe_functions();
+ } else
+#endif
+ {
+#ifdef KDRIVESERVER
+ BuiltinRegisterFpeFunctions();
+#endif
+ FontFileRegisterFpeFunctions();
+#ifndef NOFONTSERVERACCESS
+ fs_register_fpe_functions();
+#endif
+ }
+}
+
+int
+GetDefaultPointSize ()
+{
+ return 120;
+}
+
+
+FontResolutionPtr
+GetClientResolutions (int *num)
+{
+ if (requestingClient && requestingClient->fontResFunc != NULL &&
+ !requestingClient->clientGone)
+ {
+ return (*requestingClient->fontResFunc)(requestingClient, num);
+ }
+ else {
+ static struct _FontResolution res;
+ ScreenPtr pScreen;
+
+ pScreen = screenInfo.screens[0];
+ res.x_resolution = (pScreen->width * 25.4) / pScreen->mmWidth;
+ /*
+ * XXX - we'll want this as long as bitmap instances are prevalent
+ so that we can match them from scalable fonts
+ */
+ if (res.x_resolution < 88)
+ res.x_resolution = 75;
+ else
+ res.x_resolution = 100;
+ res.y_resolution = (pScreen->height * 25.4) / pScreen->mmHeight;
+ if (res.y_resolution < 88)
+ res.y_resolution = 75;
+ else
+ res.y_resolution = 100;
+ res.point_size = 120;
+ *num = 1;
+ return &res;
+ }
+}
+
+/*
+ * returns the type index of the new fpe
+ *
+ * should be called (only once!) by each type of fpe when initialized
+ */
+
+int
+RegisterFPEFunctions(NameCheckFunc name_func,
+ InitFpeFunc init_func,
+ FreeFpeFunc free_func,
+ ResetFpeFunc reset_func,
+ OpenFontFunc open_func,
+ CloseFontFunc close_func,
+ ListFontsFunc list_func,
+ StartLfwiFunc start_lfwi_func,
+ NextLfwiFunc next_lfwi_func,
+ WakeupFpeFunc wakeup_func,
+ ClientDiedFunc client_died,
+ LoadGlyphsFunc load_glyphs,
+ StartLaFunc start_list_alias_func,
+ NextLaFunc next_list_alias_func,
+ SetPathFunc set_path_func)
+{
+ FPEFunctions *new;
+
+ /* grow the list */
+ new = (FPEFunctions *) xrealloc(fpe_functions,
+ (num_fpe_types + 1) * sizeof(FPEFunctions));
+ if (!new)
+ return -1;
+ fpe_functions = new;
+
+ fpe_functions[num_fpe_types].name_check = name_func;
+ fpe_functions[num_fpe_types].open_font = open_func;
+ fpe_functions[num_fpe_types].close_font = close_func;
+ fpe_functions[num_fpe_types].wakeup_fpe = wakeup_func;
+ fpe_functions[num_fpe_types].list_fonts = list_func;
+ fpe_functions[num_fpe_types].start_list_fonts_with_info =
+ start_lfwi_func;
+ fpe_functions[num_fpe_types].list_next_font_with_info =
+ next_lfwi_func;
+ fpe_functions[num_fpe_types].init_fpe = init_func;
+ fpe_functions[num_fpe_types].free_fpe = free_func;
+ fpe_functions[num_fpe_types].reset_fpe = reset_func;
+ fpe_functions[num_fpe_types].client_died = client_died;
+ fpe_functions[num_fpe_types].load_glyphs = load_glyphs;
+ fpe_functions[num_fpe_types].start_list_fonts_and_aliases =
+ start_list_alias_func;
+ fpe_functions[num_fpe_types].list_next_font_or_alias =
+ next_list_alias_func;
+ fpe_functions[num_fpe_types].set_path_hook = set_path_func;
+
+ return num_fpe_types++;
+}
+
+void
+FreeFonts()
+{
+ if (patternCache) {
+ FreeFontPatternCache(patternCache);
+ patternCache = 0;
+ }
+ FreeFontPath(font_path_elements, num_fpes, TRUE);
+ font_path_elements = 0;
+ num_fpes = 0;
+ xfree(fpe_functions);
+ num_fpe_types = 0;
+ fpe_functions = (FPEFunctions *) 0;
+}
+
+/* convenience functions for FS interface */
+
+FontPtr
+find_old_font(XID id)
+{
+ return (FontPtr) SecurityLookupIDByType(NullClient, id, RT_NONE,
+ SecurityUnknownAccess);
+}
+
+Font
+GetNewFontClientID()
+{
+ return FakeClientID(0);
+}
+
+int
+StoreFontClientFont(FontPtr pfont, Font id)
+{
+ return AddResource(id, RT_NONE, (pointer) pfont);
+}
+
+void
+DeleteFontClientID(Font id)
+{
+ FreeResource(id, RT_NONE);
+}
+
+int
+client_auth_generation(ClientPtr client)
+{
+ return 0;
+}
+
+static int fs_handlers_installed = 0;
+static unsigned int last_server_gen;
+
+int
+init_fs_handlers(FontPathElementPtr fpe, BlockHandlerProcPtr block_handler)
+{
+ /* if server has reset, make sure the b&w handlers are reinstalled */
+ if (last_server_gen < serverGeneration) {
+ last_server_gen = serverGeneration;
+ fs_handlers_installed = 0;
+ }
+ if (fs_handlers_installed == 0) {
+
+#ifdef DEBUG
+ fprintf(stderr, "adding FS b & w handlers\n");
+#endif
+
+ if (!RegisterBlockAndWakeupHandlers(block_handler,
+ FontWakeup, (pointer) 0))
+ return AllocError;
+ fs_handlers_installed++;
+ }
+ QueueFontWakeup(fpe);
+ return Successful;
+}
+
+void
+remove_fs_handlers(FontPathElementPtr fpe, BlockHandlerProcPtr block_handler, Bool all)
+{
+ if (all) {
+ /* remove the handlers if no one else is using them */
+ if (--fs_handlers_installed == 0) {
+
+#ifdef DEBUG
+ fprintf(stderr, "removing FS b & w handlers\n");
+#endif
+
+ RemoveBlockAndWakeupHandlers(block_handler, FontWakeup,
+ (pointer) 0);
+ }
+ }
+ RemoveFontWakeup(fpe);
+}
+
+#ifdef DEBUG
+#define GLWIDTHBYTESPADDED(bits,nbytes) \
+ ((nbytes) == 1 ? (((bits)+7)>>3) /* pad to 1 byte */ \
+ :(nbytes) == 2 ? ((((bits)+15)>>3)&~1) /* pad to 2 bytes */ \
+ :(nbytes) == 4 ? ((((bits)+31)>>3)&~3) /* pad to 4 bytes */ \
+ :(nbytes) == 8 ? ((((bits)+63)>>3)&~7) /* pad to 8 bytes */ \
+ : 0)
+
+#define GLYPH_SIZE(ch, nbytes) \
+ GLWIDTHBYTESPADDED((ch)->metrics.rightSideBearing - \
+ (ch)->metrics.leftSideBearing, (nbytes))
+void
+dump_char_ascii(CharInfoPtr cip)
+{
+ int r,
+ l;
+ int bpr;
+ int byte;
+ static unsigned maskTab[] = {
+ (1 << 7), (1 << 6), (1 << 5), (1 << 4),
+ (1 << 3), (1 << 2), (1 << 1), (1 << 0),
+ };
+
+ bpr = GLYPH_SIZE(cip, 4);
+ for (r = 0; r < (cip->metrics.ascent + cip->metrics.descent); r++) {
+ pointer row = (pointer) cip->bits + r * bpr;
+
+ byte = 0;
+ for (l = 0; l <= (cip->metrics.rightSideBearing -
+ cip->metrics.leftSideBearing); l++) {
+ if (maskTab[l & 7] & row[l >> 3])
+ putchar('X');
+ else
+ putchar('.');
+ }
+ putchar('\n');
+ }
+}
+
+#endif
+
+
+typedef struct
+{
+ LFclosurePtr c;
+ OFclosurePtr oc;
+} nxFs,*nxFsPtr;
+
+static Bool
+#if NeedFunctionPrototypes
+nxdoListFontsAndAliases(ClientPtr client, nxFsPtr fss)
+#else
+nxdoListFontsAndAliases(client, fss)
+ ClientPtr client;
+ nxFsPtr fss;
+#endif
+{
+ LFclosurePtr c=fss->c;
+ OFclosurePtr oc=fss->oc;
+ FontPathElementPtr fpe;
+ int err = Successful;
+ char *name, *resolved=NULL;
+ int namelen, resolvedlen;
+ int i;
+ int aliascount = 0;
+ char tmp[256];
+ tmp[0]=0;
+ if (client->clientGone)
+ {
+ if (c->current.current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current.current_fpe];
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ }
+ err = Successful;
+ goto bail;
+ }
+
+ if (!c->current.patlen)
+ goto finish;
+
+ while (c->current.current_fpe < c->num_fpes) {
+ fpe = c->fpe_list[c->current.current_fpe];
+ err = Successful;
+
+ if (!fpe_functions[fpe->type].start_list_fonts_and_aliases)
+ {
+ /* This FPE doesn't support/require list_fonts_and_aliases */
+
+ err = (*fpe_functions[fpe->type].list_fonts)
+ ((pointer) c->client, fpe, c->current.pattern,
+ c->current.patlen, c->current.max_names - c->names->nnames,
+ c->names);
+
+ if (err == Suspended) {
+ if (!c->slept) {
+ c->slept = TRUE;
+ ClientSleep(client,
+ (ClientSleepProcPtr)nxdoListFontsAndAliases,
+ (pointer) fss);
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: nxdoListFont (1): client [%lx] sleeping.\n", client);
+#endif
+ }
+ return TRUE;
+ }
+
+ err = BadFontName;
+ }
+ else
+ {
+ /* Start of list_fonts_and_aliases functionality. Modeled
+ after list_fonts_with_info in that it resolves aliases,
+ except that the information collected from FPEs is just
+ names, not font info. Each list_next_font_or_alias()
+ returns either a name into name/namelen or an alias into
+ name/namelen and its target name into resolved/resolvedlen.
+ The code at this level then resolves the alias by polling
+ the FPEs. */
+
+ if (!c->current.list_started) {
+ err = (*fpe_functions[fpe->type].start_list_fonts_and_aliases)
+ ((pointer) c->client, fpe, c->current.pattern,
+ c->current.patlen, c->current.max_names - c->names->nnames,
+ &c->current.private);
+ if (err == Suspended) {
+ if (!c->slept) {
+ ClientSleep(client,
+ (ClientSleepProcPtr)nxdoListFontsAndAliases,
+ (pointer) fss);
+ c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: nxdoListFont (2): client [%lx] sleeping.\n", client);
+#endif
+ }
+ return TRUE;
+ }
+ if (err == Successful)
+ c->current.list_started = TRUE;
+ }
+ if (err == Successful) {
+ char *tmpname;
+ name = 0;
+ err = (*fpe_functions[fpe->type].list_next_font_or_alias)
+ ((pointer) c->client, fpe, &name, &namelen, &tmpname,
+ &resolvedlen, c->current.private);
+ if (err == Suspended) {
+ if (!c->slept) {
+ ClientSleep(client,
+ (ClientSleepProcPtr)nxdoListFontsAndAliases,
+ (pointer) fss);
+ c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: nxdoListFont (3): client [%lx] sleeping.\n", client);
+#endif
+ }
+ return TRUE;
+ }
+ if (err == FontNameAlias) {
+ if (resolved) xfree(resolved);
+ resolved = (char *) xalloc(resolvedlen + 1);
+ if (resolved)
+ {
+ memmove(resolved, tmpname, resolvedlen);
+ resolved[resolvedlen] = '\0';
+ }
+ }
+ }
+
+ if (err == Successful)
+ {
+ if (c->haveSaved)
+ {
+ if (c->savedName)
+ {
+ memcpy(tmp,c->savedName,c->savedNameLen>255?255:c->savedNameLen);
+ tmp[c->savedNameLen>255?256:c->savedNameLen]=0;
+ if (nxagentFontLookUp(tmp))
+ break;
+ else tmp[0]=0;
+ }
+ }
+ else
+ {
+ memcpy(tmp,name,namelen>255?255:namelen);
+ tmp[namelen>255?256:namelen]=0;
+ if (nxagentFontLookUp(tmp))
+ break;
+ else tmp[0]=0;
+ }
+ }
+
+ /*
+ * When we get an alias back, save our state and reset back to
+ * the start of the FPE looking for the specified name. As
+ * soon as a real font is found for the alias, pop back to the
+ * old state
+ */
+ else if (err == FontNameAlias) {
+ char tmp_pattern[XLFDMAXFONTNAMELEN];
+ /*
+ * when an alias recurses, we need to give
+ * the last FPE a chance to clean up; so we call
+ * it again, and assume that the error returned
+ * is BadFontName, indicating the alias resolution
+ * is complete.
+ */
+ memmove(tmp_pattern, resolved, resolvedlen);
+ if (c->haveSaved)
+ {
+ char *tmpname;
+ int tmpnamelen;
+
+ tmpname = 0;
+ (void) (*fpe_functions[fpe->type].list_next_font_or_alias)
+ ((pointer) c->client, fpe, &tmpname, &tmpnamelen,
+ &tmpname, &tmpnamelen, c->current.private);
+ if (--aliascount <= 0)
+ {
+ err = BadFontName;
+ goto ContBadFontName;
+ }
+ }
+ else
+ {
+ c->saved = c->current;
+ c->haveSaved = TRUE;
+ if (c->savedName)
+ xfree(c->savedName);
+ c->savedName = (char *)xalloc(namelen + 1);
+ if (c->savedName)
+ {
+ memmove(c->savedName, name, namelen);
+ c->savedName[namelen] = '\0';
+ }
+ c->savedNameLen = namelen;
+ aliascount = 20;
+ }
+ memmove(c->current.pattern, tmp_pattern, resolvedlen);
+ c->current.patlen = resolvedlen;
+ c->current.max_names = c->names->nnames + 1;
+ c->current.current_fpe = -1;
+ c->current.private = 0;
+ err = BadFontName;
+ }
+ }
+ /*
+ * At the end of this FPE, step to the next. If we've finished
+ * processing an alias, pop state back. If we've collected enough
+ * font names, quit.
+ */
+ if (err == BadFontName) {
+ ContBadFontName: ;
+ c->current.list_started = FALSE;
+ c->current.current_fpe++;
+ err = Successful;
+ if (c->haveSaved)
+ {
+ if (c->names->nnames == c->current.max_names ||
+ c->current.current_fpe == c->num_fpes) {
+ c->haveSaved = FALSE;
+ c->current = c->saved;
+ /* Give the saved namelist a chance to clean itself up */
+ continue;
+ }
+ }
+ if (c->names->nnames == c->current.max_names)
+ break;
+ }
+ }
+
+ /*
+ * send the reply
+ */
+bail:
+finish:
+ if (strlen(tmp))
+ {
+#ifdef NXAGENT_FONTMATCH_DEBUG
+ fprintf(stderr, "nxListFont changed (0) font to %s\n",tmp);
+#endif
+ memcpy(oc->fontname, tmp, strlen(tmp));
+ oc->fnamelen = strlen(tmp);
+
+ oc->origFontName = oc->fontname;
+ oc->origFontNameLen = oc->fnamelen;
+
+ }
+ else
+ {
+ for (i = 0; i < c->names->nnames; i++)
+ {
+ if (c->names->length[i] > 255)
+ continue;
+ else
+ {
+ memcpy(tmp, c->names->names[i], c->names->length[i]);
+ tmp[ c->names->length[i] ] = 0;
+ if (nxagentFontLookUp(tmp) == 0)
+ continue;
+ memcpy(oc->fontname, tmp, strlen(tmp));
+ oc->fnamelen = strlen(tmp);
+
+ oc->origFontName = oc->fontname;
+ oc->origFontNameLen = oc->fnamelen;
+
+#ifdef NXAGENT_FONTMATCH_DEBUG
+ fprintf(stderr, "nxListFont changed (1) font to %s\n",tmp);
+#endif
+ break;
+ }
+ }
+ }
+
+ if (c->slept)
+ {
+ ClientWakeup(client);
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: nxdoListFont: client [%lx] wakeup.\n", client);
+#endif
+ }
+ for (i = 0; i < c->num_fpes; i++)
+ FreeFPE(c->fpe_list[i]);
+ xfree(c->fpe_list);
+ if (c->savedName) xfree(c->savedName);
+ FreeFontNames(c->names);
+ xfree(c);
+ xfree(fss);
+ if (resolved) xfree(resolved);
+
+ return doOpenFont(client, oc);
+}
+
+int
+nxOpenFont(client, fid, flags, lenfname, pfontname)
+ ClientPtr client;
+ XID fid;
+ Mask flags;
+ unsigned lenfname;
+ char *pfontname;
+{
+ nxFsPtr fss;
+ LFclosurePtr c;
+ OFclosurePtr oc;
+ int i;
+ FontPtr cached = (FontPtr)0;
+
+#ifdef FONTDEBUG
+ char *f;
+ f = (char *)xalloc(lenfname + 1);
+ memmove(f, pfontname, lenfname);
+ f[lenfname] = '\0';
+ ErrorF("OpenFont: fontname is \"%s\"\n", f);
+ xfree(f);
+#endif
+ if (!lenfname || lenfname > XLFDMAXFONTNAMELEN)
+ return BadName;
+ if (patternCache)
+ {
+
+ /*
+ ** Check name cache. If we find a cached version of this font that
+ ** is cachable, immediately satisfy the request with it. If we find
+ ** a cached version of this font that is non-cachable, we do not
+ ** satisfy the request with it. Instead, we pass the FontPtr to the
+ ** FPE's open_font code (the fontfile FPE in turn passes the
+ ** information to the rasterizer; the fserve FPE ignores it).
+ **
+ ** Presumably, the font is marked non-cachable because the FPE has
+ ** put some licensing restrictions on it. If the FPE, using
+ ** whatever logic it relies on, determines that it is willing to
+ ** share this existing font with the client, then it has the option
+ ** to return the FontPtr we passed it as the newly-opened font.
+ ** This allows the FPE to exercise its licensing logic without
+ ** having to create another instance of a font that already exists.
+ */
+
+ cached = FindCachedFontPattern(patternCache, pfontname, lenfname);
+ if (cached && cached->info.cachable)
+ {
+ if (!AddResource(fid, RT_FONT, (pointer) cached))
+ return BadAlloc;
+ cached->refcnt++;
+ return Success;
+ }
+ }
+ if (!(fss = (nxFsPtr) xalloc(sizeof(nxFs))))
+ return BadAlloc;
+
+ if (!(c = (LFclosurePtr) xalloc(sizeof *c)))
+ {
+ xfree(fss);
+ return BadAlloc;
+ }
+ c->fpe_list = (FontPathElementPtr *)
+ xalloc(sizeof(FontPathElementPtr) * num_fpes);
+ if (!c->fpe_list) {
+ xfree(c);
+ xfree(fss);
+ return BadAlloc;
+ }
+ c->names = MakeFontNamesRecord(100);
+ if (!c->names)
+ {
+ xfree(c->fpe_list);
+ xfree(c);
+ xfree(fss);
+ return BadAlloc;
+ }
+ memmove( c->current.pattern, pfontname, lenfname);
+ for (i = 0; i < num_fpes; i++) {
+ c->fpe_list[i] = font_path_elements[i];
+ UseFPE(c->fpe_list[i]);
+ }
+ c->client = client;
+ c->num_fpes = num_fpes;
+ c->current.patlen = lenfname;
+ c->current.current_fpe = 0;
+ c->current.max_names = nxagentMaxFontNames;
+ c->current.list_started = FALSE;
+ c->current.private = 0;
+ c->haveSaved = FALSE;
+ c->slept = FALSE;
+ c->savedName = 0;
+
+ oc = (OFclosurePtr) xalloc(sizeof(OFclosureRec));
+ if (!oc)
+ {
+ for (i = 0; i < c->num_fpes; i++)
+ FreeFPE(c->fpe_list[i]);
+ xfree(c->fpe_list);
+ xfree(c);
+ xfree(fss);
+ return BadAlloc;
+ }
+ oc->fontname = (char *) xalloc(256);/* I don't want to deal with future reallocs errors */
+ oc->origFontName = pfontname;
+ oc->origFontNameLen = lenfname;
+ if (!oc->fontname) {
+ for (i = 0; i < c->num_fpes; i++)
+ FreeFPE(c->fpe_list[i]);
+ xfree(c->fpe_list);
+ xfree(c);
+ xfree(oc);
+ xfree(fss);
+ return BadAlloc;
+ }
+ /*
+ * copy the current FPE list, so that if it gets changed by another client
+ * while we're blocking, the request still appears atomic
+ */
+ oc->fpe_list = (FontPathElementPtr *)
+ xalloc(sizeof(FontPathElementPtr) * num_fpes);
+ if (!oc->fpe_list) {
+ xfree(oc->fontname);
+ xfree(oc);
+ for (i = 0; i < c->num_fpes; i++)
+ FreeFPE(c->fpe_list[i]);
+ xfree(c->fpe_list);
+ xfree(c);
+ xfree(fss);
+ return BadAlloc;
+ }
+ memmove(oc->fontname, pfontname, lenfname);
+ for (i = 0; i < num_fpes; i++) {
+ oc->fpe_list[i] = font_path_elements[i];
+ UseFPE(oc->fpe_list[i]);
+ }
+ oc->client = client;
+ oc->fontid = fid;
+ oc->current_fpe = 0;
+ oc->num_fpes = num_fpes;
+ oc->fnamelen = lenfname;
+ oc->slept = FALSE;
+ oc->flags = flags;
+ oc->non_cachable_font = cached;
+ fss->c=c;
+ fss->oc=oc;
+ nxdoListFontsAndAliases(client, fss);
+ return Success;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original
new file mode 100644
index 000000000..6dfff3776
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original
@@ -0,0 +1,2797 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/* $XdotOrg: xc/programs/Xserver/dix/dixfonts.c,v 1.8 2005/07/03 08:53:38 daniels Exp $ */
+/* $XFree86: xc/programs/Xserver/dix/dixfonts.c,v 3.28 2003/11/08 02:02:03 dawes Exp $ */
+/************************************************************************
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+************************************************************************/
+/* The panoramix components contained the following notice */
+/*
+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.
+
+******************************************************************/
+/* $Xorg: dixfonts.c,v 1.4 2000/08/17 19:48:18 cpqbld Exp $ */
+
+#define NEED_REPLIES
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xmd.h>
+#include <X11/Xproto.h>
+#include "scrnintstr.h"
+#include "resource.h"
+#include "dixstruct.h"
+#include "cursorstr.h"
+#include "misc.h"
+#include "opaque.h"
+#include "dixfontstr.h"
+#include "closestr.h"
+
+/*
+#define NXAGENT_DEBUG
+*/
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#include "Agent.h"
+#include "Font.h"
+
+#ifndef NX_TRANS_SOCKET
+
+#define NX_TRANS_SOCKET
+
+#endif
+
+#ifdef NX_TRANS_SOCKET
+
+char _NXFontPath[1024];
+
+/*
+ * Override the default font path and make
+ * it configurable at run time, based on
+ * the NX_FONT environment.
+ */
+
+static const char *_NXGetFontPath(const char *path)
+{
+ const char *fontEnv;
+
+ /*
+ * Check the environment only once.
+ */
+
+ if (*_NXFontPath != '\0')
+ {
+ return _NXFontPath;
+ }
+
+ fontEnv = getenv("NX_FONT");
+
+ if (fontEnv != NULL && *fontEnv != '\0')
+ {
+ if (strlen(fontEnv) + 1 > 1024)
+ {
+#ifdef NX_TRANS_TEST
+ fprintf(stderr, "_NXGetFontPath: WARNING! Maximum length of font path exceeded.\n");
+#endif
+ goto _NXGetFontPathError;
+ }
+
+ strcpy(_NXFontPath, fontEnv);
+
+#ifdef NX_TRANS_TEST
+ fprintf(stderr, "_NXGetFontPath: Using NX font path [%s].\n", _NXFontPath);
+#endif
+
+ return _NXFontPath;
+ }
+
+_NXGetFontPathError:
+
+ strcpy(_NXFontPath, path);
+
+#ifdef NX_TRANS_TEST
+ fprintf(stderr, "_NXGetFontPath: Using default font path [%s].\n", _NXFontPath);
+#endif
+
+ return _NXFontPath;
+}
+
+#endif
+
+#ifdef PANORAMIX
+#include "../../Xext/panoramiX.h"
+#include "../../Xext/panoramiXsrv.h"
+#endif
+
+#ifdef LBX
+#include "lbxserve.h"
+#endif
+
+#ifdef XF86BIGFONT
+#define _XF86BIGFONT_SERVER_
+#include <X11/extensions/xf86bigfont.h>
+#endif
+
+#define QUERYCHARINFO(pci, pr) *(pr) = (pci)->metrics
+
+extern pointer fosNaturalParams;
+extern FontPtr defaultFont;
+
+static FontPathElementPtr *font_path_elements = (FontPathElementPtr *) 0;
+static int num_fpes = 0;
+FPEFunctions *fpe_functions = (FPEFunctions *) 0;
+static int num_fpe_types = 0;
+
+static unsigned char *font_path_string;
+
+static int num_slept_fpes = 0;
+static int size_slept_fpes = 0;
+static FontPathElementPtr *slept_fpes = (FontPathElementPtr *) 0;
+static FontPatternCachePtr patternCache;
+
+int
+FontToXError(err)
+ int err;
+{
+ switch (err) {
+ case Successful:
+ return Success;
+ case AllocError:
+ return BadAlloc;
+ case BadFontName:
+ return BadName;
+ case BadFontPath:
+ case BadFontFormat: /* is there something better? */
+ case BadCharRange:
+ return BadValue;
+ default:
+ return err;
+ }
+}
+
+
+/*
+ * adding RT_FONT prevents conflict with default cursor font
+ */
+Bool
+SetDefaultFont(char *defaultfontname)
+{
+ int err;
+ FontPtr pf;
+ XID fid;
+
+ fid = FakeClientID(0);
+ err = OpenFont(serverClient, fid, FontLoadAll | FontOpenSync,
+ (unsigned) strlen(defaultfontname), defaultfontname);
+ if (err != Success)
+ return FALSE;
+ pf = (FontPtr) LookupIDByType(fid, RT_FONT);
+ if (pf == (FontPtr) NULL)
+ return FALSE;
+ defaultFont = pf;
+ return TRUE;
+}
+
+/*
+ * note that the font wakeup queue is not refcounted. this is because
+ * an fpe needs to be added when it's inited, and removed when it's finally
+ * freed, in order to handle any data that isn't requested, like FS events.
+ *
+ * since the only thing that should call these routines is the renderer's
+ * init_fpe() and free_fpe(), there shouldn't be any problem in using
+ * freed data.
+ */
+void
+QueueFontWakeup(FontPathElementPtr fpe)
+{
+ int i;
+ FontPathElementPtr *new;
+
+ for (i = 0; i < num_slept_fpes; i++) {
+ if (slept_fpes[i] == fpe) {
+
+#ifdef DEBUG
+ fprintf(stderr, "re-queueing fpe wakeup\n");
+#endif
+
+ return;
+ }
+ }
+ if (num_slept_fpes == size_slept_fpes) {
+ new = (FontPathElementPtr *)
+ xrealloc(slept_fpes,
+ sizeof(FontPathElementPtr) * (size_slept_fpes + 4));
+ if (!new)
+ return;
+ slept_fpes = new;
+ size_slept_fpes += 4;
+ }
+ slept_fpes[num_slept_fpes] = fpe;
+ num_slept_fpes++;
+}
+
+void
+RemoveFontWakeup(FontPathElementPtr fpe)
+{
+ int i,
+ j;
+
+ for (i = 0; i < num_slept_fpes; i++) {
+ if (slept_fpes[i] == fpe) {
+ for (j = i; j < num_slept_fpes; j++) {
+ slept_fpes[j] = slept_fpes[j + 1];
+ }
+ num_slept_fpes--;
+ return;
+ }
+ }
+}
+
+void
+FontWakeup(pointer data, int count, pointer LastSelectMask)
+{
+ int i;
+ FontPathElementPtr fpe;
+
+ if (count < 0)
+ return;
+ /* wake up any fpe's that may be waiting for information */
+ for (i = 0; i < num_slept_fpes; i++) {
+ fpe = slept_fpes[i];
+ (void) (*fpe_functions[fpe->type].wakeup_fpe) (fpe, LastSelectMask);
+ }
+}
+
+/* XXX -- these two funcs may want to be broken into macros */
+static void
+UseFPE(FontPathElementPtr fpe)
+{
+ fpe->refcount++;
+}
+
+static void
+FreeFPE (FontPathElementPtr fpe)
+{
+ fpe->refcount--;
+ if (fpe->refcount == 0) {
+ (*fpe_functions[fpe->type].free_fpe) (fpe);
+ xfree(fpe->name);
+ xfree(fpe);
+ }
+}
+
+static Bool
+doOpenFont(ClientPtr client, OFclosurePtr c)
+{
+ FontPtr pfont = NullFont;
+ FontPathElementPtr fpe = NULL;
+ ScreenPtr pScr;
+ int err = Successful;
+ int i;
+ char *alias,
+ *newname;
+ int newlen;
+ int aliascount = 20;
+ char nxagentOrigFontName[256];
+ int nxagentOrigFontNameLen;
+
+ /*
+ * Decide at runtime what FontFormat to use.
+ */
+ Mask FontFormat =
+
+ ((screenInfo.imageByteOrder == LSBFirst) ?
+ BitmapFormatByteOrderLSB : BitmapFormatByteOrderMSB) |
+
+ ((screenInfo.bitmapBitOrder == LSBFirst) ?
+ BitmapFormatBitOrderLSB : BitmapFormatBitOrderMSB) |
+
+ BitmapFormatImageRectMin |
+
+#if GLYPHPADBYTES == 1
+ BitmapFormatScanlinePad8 |
+#endif
+
+#if GLYPHPADBYTES == 2
+ BitmapFormatScanlinePad16 |
+#endif
+
+#if GLYPHPADBYTES == 4
+ BitmapFormatScanlinePad32 |
+#endif
+
+#if GLYPHPADBYTES == 8
+ BitmapFormatScanlinePad64 |
+#endif
+
+ BitmapFormatScanlineUnit8;
+
+
+ nxagentOrigFontNameLen = (c -> origFontNameLen < 256) ? c -> origFontNameLen : 255;
+
+ memcpy(nxagentOrigFontName, c -> origFontName, nxagentOrigFontNameLen);
+
+ nxagentOrigFontName[nxagentOrigFontNameLen] = 0;
+
+ if (client->clientGone)
+ {
+ if (c->current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current_fpe];
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ }
+ err = Successful;
+ goto bail;
+ }
+ while (c->current_fpe < c->num_fpes) {
+ fpe = c->fpe_list[c->current_fpe];
+ err = (*fpe_functions[fpe->type].open_font)
+ ((pointer) client, fpe, c->flags,
+ c->fontname, c->fnamelen, FontFormat,
+ BitmapFormatMaskByte |
+ BitmapFormatMaskBit |
+ BitmapFormatMaskImageRectangle |
+ BitmapFormatMaskScanLinePad |
+ BitmapFormatMaskScanLineUnit,
+ c->fontid, &pfont, &alias,
+ c->non_cachable_font && c->non_cachable_font->fpe == fpe ?
+ c->non_cachable_font :
+ (FontPtr)0);
+
+ if (err == FontNameAlias && alias) {
+ newlen = strlen(alias);
+ newname = (char *) xrealloc(c->fontname, newlen);
+ if (!newname) {
+ err = AllocError;
+ break;
+ }
+ memmove(newname, alias, newlen);
+ c->fontname = newname;
+ c->fnamelen = newlen;
+ c->current_fpe = 0;
+ if (--aliascount <= 0)
+ break;
+ continue;
+ }
+ if (err == BadFontName) {
+ c->current_fpe++;
+ continue;
+ }
+ if (err == Suspended) {
+ if (!c->slept) {
+ c->slept = TRUE;
+ ClientSleep(client, (ClientSleepProcPtr)doOpenFont, (pointer) c);
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doOpenFont: client [%lx] sleeping.\n", client);
+#endif
+ }
+ return TRUE;
+ }
+ break;
+ }
+
+ if (err != Successful)
+ goto bail;
+ if (!pfont) {
+ err = BadFontName;
+ goto bail;
+ }
+ if (!pfont->fpe)
+ pfont->fpe = fpe;
+ pfont->refcnt++;
+ if (pfont->refcnt == 1) {
+ UseFPE(pfont->fpe);
+ for (i = 0; i < screenInfo.numScreens; i++) {
+ pScr = screenInfo.screens[i];
+ if (pScr->RealizeFont)
+ {
+
+ /* NXAGENT uses useless screen pointer to pass the original font name
+ * to realizeFont, could be a source of problems in the future.
+ */
+
+ if (!(*pScr->RealizeFont) ((ScreenPtr)nxagentOrigFontName, pfont))
+ {
+ CloseFont (pfont, (Font) 0);
+ err=BadFontName;
+ goto bail;
+ }
+ }
+ }
+ }
+ if (!AddResource(c->fontid, RT_FONT, (pointer) pfont)) {
+ err = AllocError;
+ goto bail;
+ }
+ if( nxagentFontPriv(pfont) -> mirrorID == 0 )
+ {
+ extern RESTYPE RT_NX_FONT;
+
+ nxagentFontPriv(pfont) -> mirrorID = FakeClientID(0);
+ if (!AddResource(nxagentFontPriv(pfont) -> mirrorID, RT_NX_FONT, (pointer) pfont)) {
+ FreeResource(c->fontid, RT_NONE);
+ err = AllocError;
+ goto bail;
+ }
+ }
+ if (patternCache && pfont != c->non_cachable_font)
+ CacheFontPattern(patternCache, nxagentOrigFontName, nxagentOrigFontNameLen,
+ pfont);
+bail:
+ if (err != Successful && c->client != serverClient) {
+ SendErrorToClient(c->client, X_OpenFont, 0,
+ c->fontid, FontToXError(err));
+ }
+ if (c->slept)
+ {
+ ClientWakeup(c->client);
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doOpenFont: client [%lx] wakeup.\n", client);
+#endif
+ }
+ for (i = 0; i < c->num_fpes; i++) {
+ FreeFPE(c->fpe_list[i]);
+ }
+ xfree(c->fpe_list);
+ xfree(c->fontname);
+ xfree(c);
+ return TRUE;
+}
+
+int
+OpenFont(ClientPtr client, XID fid, Mask flags, unsigned lenfname, char *pfontname)
+{
+ OFclosurePtr c;
+ int i;
+ FontPtr cached = (FontPtr)0;
+
+#ifdef FONTDEBUG
+ char *f;
+ f = (char *)xalloc(lenfname + 1);
+ memmove(f, pfontname, lenfname);
+ f[lenfname] = '\0';
+ ErrorF("OpenFont: fontname is \"%s\"\n", f);
+ xfree(f);
+#endif
+ if (!lenfname || lenfname > XLFDMAXFONTNAMELEN)
+ return BadName;
+ if (patternCache)
+ {
+
+ /*
+ ** Check name cache. If we find a cached version of this font that
+ ** is cachable, immediately satisfy the request with it. If we find
+ ** a cached version of this font that is non-cachable, we do not
+ ** satisfy the request with it. Instead, we pass the FontPtr to the
+ ** FPE's open_font code (the fontfile FPE in turn passes the
+ ** information to the rasterizer; the fserve FPE ignores it).
+ **
+ ** Presumably, the font is marked non-cachable because the FPE has
+ ** put some licensing restrictions on it. If the FPE, using
+ ** whatever logic it relies on, determines that it is willing to
+ ** share this existing font with the client, then it has the option
+ ** to return the FontPtr we passed it as the newly-opened font.
+ ** This allows the FPE to exercise its licensing logic without
+ ** having to create another instance of a font that already exists.
+ */
+
+ cached = FindCachedFontPattern(patternCache, pfontname, lenfname);
+ if (cached && cached->info.cachable)
+ {
+ if (!AddResource(fid, RT_FONT, (pointer) cached))
+ return BadAlloc;
+ cached->refcnt++;
+ return Success;
+ }
+ }
+ c = (OFclosurePtr) xalloc(sizeof(OFclosureRec));
+ if (!c)
+ return BadAlloc;
+ c->fontname = (char *) xalloc(lenfname);
+ c->origFontName = pfontname;
+ c->origFontNameLen = lenfname;
+ if (!c->fontname) {
+ xfree(c);
+ return BadAlloc;
+ }
+ /*
+ * copy the current FPE list, so that if it gets changed by another client
+ * while we're blocking, the request still appears atomic
+ */
+ c->fpe_list = (FontPathElementPtr *)
+ xalloc(sizeof(FontPathElementPtr) * num_fpes);
+ if (!c->fpe_list) {
+ xfree(c->fontname);
+ xfree(c);
+ return BadAlloc;
+ }
+ memmove(c->fontname, pfontname, lenfname);
+ for (i = 0; i < num_fpes; i++) {
+ c->fpe_list[i] = font_path_elements[i];
+ UseFPE(c->fpe_list[i]);
+ }
+ c->client = client;
+ c->fontid = fid;
+ c->current_fpe = 0;
+ c->num_fpes = num_fpes;
+ c->fnamelen = lenfname;
+ c->slept = FALSE;
+ c->flags = flags;
+ c->non_cachable_font = cached;
+
+ (void) doOpenFont(client, c);
+ return Success;
+}
+
+/**
+ * Decrement font's ref count, and free storage if ref count equals zero
+ *
+ * \param value must conform to DeleteType
+ */
+int
+CloseFont(pointer value, XID fid)
+{
+ int nscr;
+ ScreenPtr pscr;
+ FontPathElementPtr fpe;
+ FontPtr pfont = (FontPtr)value;
+
+ if (pfont == NullFont)
+ return (Success);
+ if (--pfont->refcnt == 0) {
+ if (patternCache)
+ RemoveCachedFontPattern (patternCache, pfont);
+ /*
+ * since the last reference is gone, ask each screen to free any
+ * storage it may have allocated locally for it.
+ */
+ for (nscr = 0; nscr < screenInfo.numScreens; nscr++) {
+ pscr = screenInfo.screens[nscr];
+ if (pscr->UnrealizeFont)
+ (*pscr->UnrealizeFont) (pscr, pfont);
+ }
+ if (pfont == defaultFont)
+ defaultFont = NULL;
+#ifdef LBX
+ LbxFreeFontTag(pfont);
+#endif
+#ifdef XF86BIGFONT
+ {
+ extern void XF86BigfontFreeFontShm(FontPtr);
+ XF86BigfontFreeFontShm(pfont);
+ }
+#endif
+ fpe = pfont->fpe;
+ (*fpe_functions[fpe->type].close_font) (fpe, pfont);
+ FreeFPE(fpe);
+ }
+ return (Success);
+}
+
+
+/***====================================================================***/
+
+/**
+ * Sets up pReply as the correct QueryFontReply for pFont with the first
+ * nProtoCCIStructs char infos.
+ *
+ * \param pReply caller must allocate this storage
+ */
+void
+QueryFont(FontPtr pFont, xQueryFontReply *pReply, int nProtoCCIStructs)
+{
+ FontPropPtr pFP;
+ int r,
+ c,
+ i;
+ xFontProp *prFP;
+ xCharInfo *prCI;
+ xCharInfo *charInfos[256];
+ unsigned char chars[512];
+ int ninfos;
+ unsigned long ncols;
+ unsigned long count;
+
+ /* pr->length set in dispatch */
+ pReply->minCharOrByte2 = pFont->info.firstCol;
+ pReply->defaultChar = pFont->info.defaultCh;
+ pReply->maxCharOrByte2 = pFont->info.lastCol;
+ pReply->drawDirection = pFont->info.drawDirection;
+ pReply->allCharsExist = pFont->info.allExist;
+ pReply->minByte1 = pFont->info.firstRow;
+ pReply->maxByte1 = pFont->info.lastRow;
+ pReply->fontAscent = pFont->info.fontAscent;
+ pReply->fontDescent = pFont->info.fontDescent;
+
+ pReply->minBounds = pFont->info.ink_minbounds;
+ pReply->maxBounds = pFont->info.ink_maxbounds;
+
+ pReply->nFontProps = pFont->info.nprops;
+ pReply->nCharInfos = nProtoCCIStructs;
+
+ for (i = 0, pFP = pFont->info.props, prFP = (xFontProp *) (&pReply[1]);
+ i < pFont->info.nprops;
+ i++, pFP++, prFP++) {
+ prFP->name = pFP->name;
+ prFP->value = pFP->value;
+ }
+
+ ninfos = 0;
+ ncols = (unsigned long) (pFont->info.lastCol - pFont->info.firstCol + 1);
+ prCI = (xCharInfo *) (prFP);
+ for (r = pFont->info.firstRow;
+ ninfos < nProtoCCIStructs && r <= (int)pFont->info.lastRow;
+ r++) {
+ i = 0;
+ for (c = pFont->info.firstCol; c <= (int)pFont->info.lastCol; c++) {
+ chars[i++] = r;
+ chars[i++] = c;
+ }
+ (*pFont->get_metrics) (pFont, ncols, chars,
+ TwoD16Bit, &count, charInfos);
+ i = 0;
+ for (i = 0; i < (int) count && ninfos < nProtoCCIStructs; i++) {
+ *prCI = *charInfos[i];
+ prCI++;
+ ninfos++;
+ }
+ }
+ return;
+}
+
+static Bool
+doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
+{
+ FontPathElementPtr fpe;
+ int err = Successful;
+ FontNamesPtr names = NULL;
+ char *name, *resolved=NULL;
+ int namelen, resolvedlen;
+ int nnames;
+ int stringLens;
+ int i;
+ xListFontsReply reply;
+ char *bufptr;
+ char *bufferStart;
+ int aliascount = 0;
+
+ if (client->clientGone)
+ {
+ if (c->current.current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current.current_fpe];
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ }
+ err = Successful;
+ goto bail;
+ }
+
+ if (!c->current.patlen)
+ goto finish;
+
+ while (c->current.current_fpe < c->num_fpes) {
+ fpe = c->fpe_list[c->current.current_fpe];
+ err = Successful;
+
+ if (!fpe_functions[fpe->type].start_list_fonts_and_aliases)
+ {
+ /* This FPE doesn't support/require list_fonts_and_aliases */
+
+ err = (*fpe_functions[fpe->type].list_fonts)
+ ((pointer) c->client, fpe, c->current.pattern,
+ c->current.patlen, c->current.max_names - c->names->nnames,
+ c->names);
+
+ if (err == Suspended) {
+ if (!c->slept) {
+ c->slept = TRUE;
+ ClientSleep(client,
+ (ClientSleepProcPtr)doListFontsAndAliases,
+ (pointer) c);
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doListFont (1): client [%lx] sleeping.\n", client);
+#endif
+ }
+ return TRUE;
+ }
+
+ err = BadFontName;
+ }
+ else
+ {
+ /* Start of list_fonts_and_aliases functionality. Modeled
+ after list_fonts_with_info in that it resolves aliases,
+ except that the information collected from FPEs is just
+ names, not font info. Each list_next_font_or_alias()
+ returns either a name into name/namelen or an alias into
+ name/namelen and its target name into resolved/resolvedlen.
+ The code at this level then resolves the alias by polling
+ the FPEs. */
+
+ if (!c->current.list_started) {
+ err = (*fpe_functions[fpe->type].start_list_fonts_and_aliases)
+ ((pointer) c->client, fpe, c->current.pattern,
+ c->current.patlen, c->current.max_names - c->names->nnames,
+ &c->current.private);
+ if (err == Suspended) {
+ if (!c->slept) {
+ ClientSleep(client,
+ (ClientSleepProcPtr)doListFontsAndAliases,
+ (pointer) c);
+ c->slept = TRUE;
+ }
+ return TRUE;
+ }
+ if (err == Successful)
+ c->current.list_started = TRUE;
+ }
+ if (err == Successful) {
+ char *tmpname;
+ name = 0;
+ err = (*fpe_functions[fpe->type].list_next_font_or_alias)
+ ((pointer) c->client, fpe, &name, &namelen, &tmpname,
+ &resolvedlen, c->current.private);
+ if (err == Suspended) {
+ if (!c->slept) {
+ ClientSleep(client,
+ (ClientSleepProcPtr)doListFontsAndAliases,
+ (pointer) c);
+ c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doListFont (2): client [%lx] sleeping.\n", client);
+#endif
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doListFont (3): client [%lx] sleeping.\n", client);
+#endif
+ }
+ return TRUE;
+ }
+ if (err == FontNameAlias) {
+ if (resolved) xfree(resolved);
+ resolved = (char *) xalloc(resolvedlen + 1);
+ if (resolved)
+ memmove(resolved, tmpname, resolvedlen + 1);
+ }
+ }
+
+ if (err == Successful)
+ {
+ if (c->haveSaved)
+ {
+ if (c->savedName)
+ (void)AddFontNamesName(c->names, c->savedName,
+ c->savedNameLen);
+ }
+ else
+ (void)AddFontNamesName(c->names, name, namelen);
+ }
+
+ /*
+ * When we get an alias back, save our state and reset back to
+ * the start of the FPE looking for the specified name. As
+ * soon as a real font is found for the alias, pop back to the
+ * old state
+ */
+ else if (err == FontNameAlias) {
+ char tmp_pattern[XLFDMAXFONTNAMELEN];
+ /*
+ * when an alias recurses, we need to give
+ * the last FPE a chance to clean up; so we call
+ * it again, and assume that the error returned
+ * is BadFontName, indicating the alias resolution
+ * is complete.
+ */
+ memmove(tmp_pattern, resolved, resolvedlen);
+ if (c->haveSaved)
+ {
+ char *tmpname;
+ int tmpnamelen;
+
+ tmpname = 0;
+ (void) (*fpe_functions[fpe->type].list_next_font_or_alias)
+ ((pointer) c->client, fpe, &tmpname, &tmpnamelen,
+ &tmpname, &tmpnamelen, c->current.private);
+ if (--aliascount <= 0)
+ {
+ err = BadFontName;
+ goto ContBadFontName;
+ }
+ }
+ else
+ {
+ c->saved = c->current;
+ c->haveSaved = TRUE;
+ if (c->savedName)
+ xfree(c->savedName);
+ c->savedName = (char *)xalloc(namelen + 1);
+ if (c->savedName)
+ memmove(c->savedName, name, namelen + 1);
+ c->savedNameLen = namelen;
+ aliascount = 20;
+ }
+ memmove(c->current.pattern, tmp_pattern, resolvedlen);
+ c->current.patlen = resolvedlen;
+ c->current.max_names = c->names->nnames + 1;
+ c->current.current_fpe = -1;
+ c->current.private = 0;
+ err = BadFontName;
+ }
+ }
+ /*
+ * At the end of this FPE, step to the next. If we've finished
+ * processing an alias, pop state back. If we've collected enough
+ * font names, quit.
+ */
+ if (err == BadFontName) {
+ ContBadFontName: ;
+ c->current.list_started = FALSE;
+ c->current.current_fpe++;
+ err = Successful;
+ if (c->haveSaved)
+ {
+ if (c->names->nnames == c->current.max_names ||
+ c->current.current_fpe == c->num_fpes) {
+ c->haveSaved = FALSE;
+ c->current = c->saved;
+ /* Give the saved namelist a chance to clean itself up */
+ continue;
+ }
+ }
+ if (c->names->nnames == c->current.max_names)
+ break;
+ }
+ }
+
+ /*
+ * send the reply
+ */
+ if (err != Successful) {
+ SendErrorToClient(client, X_ListFonts, 0, 0, FontToXError(err));
+ goto bail;
+ }
+
+finish:
+
+ names = c->names;
+ nnames = names->nnames;
+ client = c->client;
+ stringLens = 0;
+ for (i = 0; i < nnames; i++)
+ stringLens += (names->length[i] <= 255) ? names->length[i] : 0;
+
+ reply.type = X_Reply;
+ reply.length = (stringLens + nnames + 3) >> 2;
+ reply.nFonts = nnames;
+ reply.sequenceNumber = client->sequence;
+
+ bufptr = bufferStart = (char *) ALLOCATE_LOCAL(reply.length << 2);
+
+ if (!bufptr && reply.length) {
+ SendErrorToClient(client, X_ListFonts, 0, 0, BadAlloc);
+ goto bail;
+ }
+ /*
+ * since WriteToClient long word aligns things, copy to temp buffer and
+ * write all at once
+ */
+ for (i = 0; i < nnames; i++) {
+ if (names->length[i] > 255)
+ reply.nFonts--;
+ else
+ {
+ {
+ /* dirty hack: don't list to client fonts not existing on the remote side */
+ char tmp[256];
+
+ memcpy(tmp, names->names[i], names->length[i]);
+ tmp[ names->length[i] ] = 0;
+
+ if (nxagentFontLookUp(tmp) == 0)
+ {
+#ifdef NXAGENT_FONTMATCH_DEBUG
+ fprintf(stderr, "doListFontsAndAliases:\n");
+ fprintf(stderr, " removing font: %s \n", tmp);
+#endif
+ reply.nFonts--;
+ stringLens -= names->length[i];
+ continue;
+ }
+ }
+ *bufptr++ = names->length[i];
+ memmove( bufptr, names->names[i], names->length[i]);
+ bufptr += names->length[i];
+ }
+ }
+ nnames = reply.nFonts;
+ reply.length = (stringLens + nnames + 3) >> 2;
+ client->pSwapReplyFunc = ReplySwapVector[X_ListFonts];
+ WriteSwappedDataToClient(client, sizeof(xListFontsReply), &reply);
+ (void) WriteToClient(client, stringLens + nnames, bufferStart);
+ DEALLOCATE_LOCAL(bufferStart);
+
+bail:
+ if (c->slept)
+ {
+ ClientWakeup(client);
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doListFont: client [%lx] wakeup.\n", client);
+#endif
+ }
+ for (i = 0; i < c->num_fpes; i++)
+ FreeFPE(c->fpe_list[i]);
+ xfree(c->fpe_list);
+ if (c->savedName) xfree(c->savedName);
+ FreeFontNames(names);
+ xfree(c);
+ if (resolved) xfree(resolved);
+ return TRUE;
+}
+
+int
+ListFonts(ClientPtr client, unsigned char *pattern, unsigned length,
+ unsigned max_names)
+{
+ int i;
+ LFclosurePtr c;
+
+ /*
+ * The right error to return here would be BadName, however the
+ * specification does not allow for a Name error on this request.
+ * Perhaps a better solution would be to return a nil list, i.e.
+ * a list containing zero fontnames.
+ */
+ if (length > XLFDMAXFONTNAMELEN)
+ return BadAlloc;
+
+ if (!(c = (LFclosurePtr) xalloc(sizeof *c)))
+ return BadAlloc;
+ c->fpe_list = (FontPathElementPtr *)
+ xalloc(sizeof(FontPathElementPtr) * num_fpes);
+ if (!c->fpe_list) {
+ xfree(c);
+ return BadAlloc;
+ }
+ c->names = MakeFontNamesRecord(max_names < nxagentMaxFontNames ? max_names : nxagentMaxFontNames);
+ if (!c->names)
+ {
+ xfree(c->fpe_list);
+ xfree(c);
+ return BadAlloc;
+ }
+ memmove( c->current.pattern, pattern, length);
+ for (i = 0; i < num_fpes; i++) {
+ c->fpe_list[i] = font_path_elements[i];
+ UseFPE(c->fpe_list[i]);
+ }
+ c->client = client;
+ c->num_fpes = num_fpes;
+ c->current.patlen = length;
+ c->current.current_fpe = 0;
+ c->current.max_names = max_names;
+ c->current.list_started = FALSE;
+ c->current.private = 0;
+ c->haveSaved = FALSE;
+ c->slept = FALSE;
+ c->savedName = 0;
+ doListFontsAndAliases(client, c);
+ return Success;
+}
+
+int
+doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c)
+{
+ FontPathElementPtr fpe;
+ int err = Successful;
+ char *name;
+ int namelen;
+ int numFonts;
+ FontInfoRec fontInfo,
+ *pFontInfo;
+ xListFontsWithInfoReply *reply;
+ int length;
+ xFontProp *pFP;
+ int i;
+ int aliascount = 0;
+ xListFontsWithInfoReply finalReply;
+
+ if (client->clientGone)
+ {
+ if (c->current.current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current.current_fpe];
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ }
+ err = Successful;
+ goto bail;
+ }
+ client->pSwapReplyFunc = ReplySwapVector[X_ListFontsWithInfo];
+ if (!c->current.patlen)
+ goto finish;
+ while (c->current.current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current.current_fpe];
+ err = Successful;
+ if (!c->current.list_started)
+ {
+ err = (*fpe_functions[fpe->type].start_list_fonts_with_info)
+ (client, fpe, c->current.pattern, c->current.patlen,
+ c->current.max_names, &c->current.private);
+ if (err == Suspended)
+ {
+ if (!c->slept)
+ {
+ ClientSleep(client, (ClientSleepProcPtr)doListFontsWithInfo, c);
+ c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doListFontWinfo (1): client [%lx] sleeping.\n", client);
+#endif
+ }
+ return TRUE;
+ }
+ if (err == Successful)
+ c->current.list_started = TRUE;
+ }
+ if (err == Successful)
+ {
+ name = 0;
+ pFontInfo = &fontInfo;
+ err = (*fpe_functions[fpe->type].list_next_font_with_info)
+ (client, fpe, &name, &namelen, &pFontInfo,
+ &numFonts, c->current.private);
+ if (err == Suspended)
+ {
+ if (!c->slept)
+ {
+ ClientSleep(client,
+ (ClientSleepProcPtr)doListFontsWithInfo,
+ c);
+ c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doListFontWinfo (2): client [%lx] sleeping.\n", client);
+#endif
+ }
+ return TRUE;
+ }
+ }
+ /*
+ * When we get an alias back, save our state and reset back to the
+ * start of the FPE looking for the specified name. As soon as a real
+ * font is found for the alias, pop back to the old state
+ */
+ if (err == FontNameAlias)
+ {
+ /*
+ * when an alias recurses, we need to give
+ * the last FPE a chance to clean up; so we call
+ * it again, and assume that the error returned
+ * is BadFontName, indicating the alias resolution
+ * is complete.
+ */
+ if (c->haveSaved)
+ {
+ char *tmpname;
+ int tmpnamelen;
+ FontInfoPtr tmpFontInfo;
+
+ tmpname = 0;
+ tmpFontInfo = &fontInfo;
+ (void) (*fpe_functions[fpe->type].list_next_font_with_info)
+ (client, fpe, &tmpname, &tmpnamelen, &tmpFontInfo,
+ &numFonts, c->current.private);
+ if (--aliascount <= 0)
+ {
+ err = BadFontName;
+ goto ContBadFontName;
+ }
+ }
+ else
+ {
+ c->saved = c->current;
+ c->haveSaved = TRUE;
+ c->savedNumFonts = numFonts;
+ if (c->savedName)
+ xfree(c->savedName);
+ c->savedName = (char *)xalloc(namelen + 1);
+ if (c->savedName)
+ memmove(c->savedName, name, namelen + 1);
+ aliascount = 20;
+ }
+ memmove(c->current.pattern, name, namelen);
+ c->current.patlen = namelen;
+ c->current.max_names = 1;
+ c->current.current_fpe = 0;
+ c->current.private = 0;
+ c->current.list_started = FALSE;
+ }
+ /*
+ * At the end of this FPE, step to the next. If we've finished
+ * processing an alias, pop state back. If we've sent enough font
+ * names, quit. Always wait for BadFontName to let the FPE
+ * have a chance to clean up.
+ */
+ else if (err == BadFontName)
+ {
+ ContBadFontName: ;
+ c->current.list_started = FALSE;
+ c->current.current_fpe++;
+ err = Successful;
+ if (c->haveSaved)
+ {
+ if (c->current.max_names == 0 ||
+ c->current.current_fpe == c->num_fpes)
+ {
+ c->haveSaved = FALSE;
+ c->saved.max_names -= (1 - c->current.max_names);
+ c->current = c->saved;
+ }
+ }
+ else if (c->current.max_names == 0)
+ break;
+ }
+ else if (err == Successful)
+ {
+
+ if (c->haveSaved)
+ {
+ numFonts = c->savedNumFonts;
+ name = c->savedName;
+ namelen = strlen(name);
+ }
+
+ if (nxagentFontLookUp(name) == 0)
+ {
+#ifdef NXAGENT_FONTMATCH_DEBUG
+ fprintf(stderr, "doListFontsAndAliases (with info):\n");
+ fprintf(stderr, " removing font: %s \n", name);
+#endif
+ continue;
+ }
+
+ length = sizeof(*reply) + pFontInfo->nprops * sizeof(xFontProp);
+ reply = c->reply;
+ if (c->length < length)
+ {
+ reply = (xListFontsWithInfoReply *) xrealloc(c->reply, length);
+ if (!reply)
+ {
+ err = AllocError;
+ break;
+ }
+ c->reply = reply;
+ c->length = length;
+ }
+ reply->type = X_Reply;
+ reply->length = (sizeof *reply - sizeof(xGenericReply) +
+ pFontInfo->nprops * sizeof(xFontProp) +
+ namelen + 3) >> 2;
+ reply->sequenceNumber = client->sequence;
+ reply->nameLength = namelen;
+ reply->minBounds = pFontInfo->ink_minbounds;
+ reply->maxBounds = pFontInfo->ink_maxbounds;
+ reply->minCharOrByte2 = pFontInfo->firstCol;
+ reply->maxCharOrByte2 = pFontInfo->lastCol;
+ reply->defaultChar = pFontInfo->defaultCh;
+ reply->nFontProps = pFontInfo->nprops;
+ reply->drawDirection = pFontInfo->drawDirection;
+ reply->minByte1 = pFontInfo->firstRow;
+ reply->maxByte1 = pFontInfo->lastRow;
+ reply->allCharsExist = pFontInfo->allExist;
+ reply->fontAscent = pFontInfo->fontAscent;
+ reply->fontDescent = pFontInfo->fontDescent;
+ reply->nReplies = numFonts;
+ pFP = (xFontProp *) (reply + 1);
+ for (i = 0; i < pFontInfo->nprops; i++)
+ {
+ pFP->name = pFontInfo->props[i].name;
+ pFP->value = pFontInfo->props[i].value;
+ pFP++;
+ }
+ WriteSwappedDataToClient(client, length, reply);
+ (void) WriteToClient(client, namelen, name);
+ if (pFontInfo == &fontInfo)
+ {
+ xfree(fontInfo.props);
+ xfree(fontInfo.isStringProp);
+ }
+ --c->current.max_names;
+ }
+ }
+finish:
+ length = sizeof(xListFontsWithInfoReply);
+ bzero((char *) &finalReply, sizeof(xListFontsWithInfoReply));
+ finalReply.type = X_Reply;
+ finalReply.sequenceNumber = client->sequence;
+ finalReply.length = (sizeof(xListFontsWithInfoReply)
+ - sizeof(xGenericReply)) >> 2;
+ WriteSwappedDataToClient(client, length, &finalReply);
+bail:
+ if (c->slept)
+ {
+ ClientWakeup(client);
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doListFontWinfo: client [%lx] wakeup.\n", client);
+#endif
+ }
+ for (i = 0; i < c->num_fpes; i++)
+ FreeFPE(c->fpe_list[i]);
+ xfree(c->reply);
+ xfree(c->fpe_list);
+ if (c->savedName) xfree(c->savedName);
+ xfree(c);
+ return TRUE;
+}
+
+int
+StartListFontsWithInfo(ClientPtr client, int length, unsigned char *pattern,
+ int max_names)
+{
+ int i;
+ LFWIclosurePtr c;
+
+ /*
+ * The right error to return here would be BadName, however the
+ * specification does not allow for a Name error on this request.
+ * Perhaps a better solution would be to return a nil list, i.e.
+ * a list containing zero fontnames.
+ */
+ if (length > XLFDMAXFONTNAMELEN)
+ return BadAlloc;
+
+ if (!(c = (LFWIclosurePtr) xalloc(sizeof *c)))
+ goto badAlloc;
+ c->fpe_list = (FontPathElementPtr *)
+ xalloc(sizeof(FontPathElementPtr) * num_fpes);
+ if (!c->fpe_list)
+ {
+ xfree(c);
+ goto badAlloc;
+ }
+ memmove(c->current.pattern, pattern, length);
+ for (i = 0; i < num_fpes; i++)
+ {
+ c->fpe_list[i] = font_path_elements[i];
+ UseFPE(c->fpe_list[i]);
+ }
+ c->client = client;
+ c->num_fpes = num_fpes;
+ c->reply = 0;
+ c->length = 0;
+ c->current.patlen = length;
+ c->current.current_fpe = 0;
+ c->current.max_names = max_names;
+ c->current.list_started = FALSE;
+ c->current.private = 0;
+ c->savedNumFonts = 0;
+ c->haveSaved = FALSE;
+ c->slept = FALSE;
+ c->savedName = 0;
+ doListFontsWithInfo(client, c);
+ return Success;
+badAlloc:
+ return BadAlloc;
+}
+
+#define TextEltHeader 2
+#define FontShiftSize 5
+static XID clearGC[] = { CT_NONE };
+#define clearGCmask (GCClipMask)
+
+int
+doPolyText(ClientPtr client, register PTclosurePtr c)
+{
+ register FontPtr pFont = c->pGC->font, oldpFont;
+ Font fid, oldfid;
+ int err = Success, lgerr; /* err is in X error, not font error, space */
+ enum { NEVER_SLEPT, START_SLEEP, SLEEPING } client_state = NEVER_SLEPT;
+ FontPathElementPtr fpe;
+ GC *origGC = NULL;
+
+ if (client->clientGone)
+ {
+ fpe = c->pGC->font->fpe;
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+
+ if (c->slept)
+ {
+ /* Client has died, but we cannot bail out right now. We
+ need to clean up after the work we did when going to
+ sleep. Setting the drawable pointer to 0 makes this
+ happen without any attempts to render or perform other
+ unnecessary activities. */
+ c->pDraw = (DrawablePtr)0;
+ }
+ else
+ {
+ err = Success;
+ goto bail;
+ }
+ }
+
+ /* Make sure our drawable hasn't disappeared while we slept. */
+ if (c->slept &&
+ c->pDraw &&
+ c->pDraw != (DrawablePtr)SecurityLookupIDByClass(client, c->did,
+ RC_DRAWABLE, SecurityWriteAccess))
+ {
+ /* Our drawable has disappeared. Treat like client died... ask
+ the FPE code to clean up after client and avoid further
+ rendering while we clean up after ourself. */
+ fpe = c->pGC->font->fpe;
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ c->pDraw = (DrawablePtr)0;
+ }
+
+ client_state = c->slept ? SLEEPING : NEVER_SLEPT;
+
+ while (c->endReq - c->pElt > TextEltHeader)
+ {
+ if (*c->pElt == FontChange)
+ {
+ if (c->endReq - c->pElt < FontShiftSize)
+ {
+ err = BadLength;
+ goto bail;
+ }
+
+ oldpFont = pFont;
+ oldfid = fid;
+
+ fid = ((Font)*(c->pElt+4)) /* big-endian */
+ | ((Font)*(c->pElt+3)) << 8
+ | ((Font)*(c->pElt+2)) << 16
+ | ((Font)*(c->pElt+1)) << 24;
+ pFont = (FontPtr)SecurityLookupIDByType(client, fid, RT_FONT,
+ SecurityReadAccess);
+ if (!pFont)
+ {
+ client->errorValue = fid;
+ err = BadFont;
+ /* restore pFont and fid for step 4 (described below) */
+ pFont = oldpFont;
+ fid = oldfid;
+
+ /* If we're in START_SLEEP mode, the following step
+ shortens the request... in the unlikely event that
+ the fid somehow becomes valid before we come through
+ again to actually execute the polytext, which would
+ then mess up our refcounting scheme badly. */
+ c->err = err;
+ c->endReq = c->pElt;
+
+ goto bail;
+ }
+
+ /* Step 3 (described below) on our new font */
+ if (client_state == START_SLEEP)
+ pFont->refcnt++;
+ else
+ {
+ if (pFont != c->pGC->font && c->pDraw)
+ {
+ ChangeGC( c->pGC, GCFont, &fid);
+ ValidateGC(c->pDraw, c->pGC);
+ if (c->reqType == X_PolyText8)
+ c->polyText = (PolyTextPtr) c->pGC->ops->PolyText8;
+ else
+ c->polyText = (PolyTextPtr) c->pGC->ops->PolyText16;
+ }
+
+ /* Undo the refcnt++ we performed when going to sleep */
+ if (client_state == SLEEPING)
+ (void)CloseFont(c->pGC->font, (Font)0);
+ }
+ c->pElt += FontShiftSize;
+ }
+ else /* print a string */
+ {
+ unsigned char *pNextElt;
+ pNextElt = c->pElt + TextEltHeader + (*c->pElt)*c->itemSize;
+ if ( pNextElt > c->endReq)
+ {
+ err = BadLength;
+ goto bail;
+ }
+ if (client_state == START_SLEEP)
+ {
+ c->pElt = pNextElt;
+ continue;
+ }
+ if (c->pDraw)
+ {
+ lgerr = LoadGlyphs(client, c->pGC->font, *c->pElt, c->itemSize,
+ c->pElt + TextEltHeader);
+ }
+ else lgerr = Successful;
+
+ if (lgerr == Suspended)
+ {
+ if (!c->slept) {
+ int len;
+ GC *pGC;
+ PTclosurePtr new_closure;
+
+ /* We're putting the client to sleep. We need to do a few things
+ to ensure successful and atomic-appearing execution of the
+ remainder of the request. First, copy the remainder of the
+ request into a safe malloc'd area. Second, create a scratch GC
+ to use for the remainder of the request. Third, mark all fonts
+ referenced in the remainder of the request to prevent their
+ deallocation. Fourth, make the original GC look like the
+ request has completed... set its font to the final font value
+ from this request. These GC manipulations are for the unlikely
+ (but possible) event that some other client is using the GC.
+ Steps 3 and 4 are performed by running this procedure through
+ the remainder of the request in a special no-render mode
+ indicated by client_state = START_SLEEP. */
+
+ /* Step 1 */
+ /* Allocate a malloc'd closure structure to replace
+ the local one we were passed */
+ new_closure = (PTclosurePtr) xalloc(sizeof(PTclosureRec));
+ if (!new_closure)
+ {
+ err = BadAlloc;
+ goto bail;
+ }
+ *new_closure = *c;
+ c = new_closure;
+
+ len = c->endReq - c->pElt;
+ c->data = (unsigned char *)xalloc(len);
+ if (!c->data)
+ {
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+ memmove(c->data, c->pElt, len);
+ c->pElt = c->data;
+ c->endReq = c->pElt + len;
+
+ /* Step 2 */
+
+ pGC = GetScratchGC(c->pGC->depth, c->pGC->pScreen);
+ if (!pGC)
+ {
+ xfree(c->data);
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+
+ pGC->tileIsPixel = TRUE;
+ pGC->tile.pixel = 0;
+ pGC->stipple = NullPixmap;
+
+ if ((err = CopyGC(c->pGC, pGC, GCFunction |
+ GCPlaneMask | GCForeground |
+ GCBackground | GCFillStyle |
+ GCTile | GCStipple |
+ GCTileStipXOrigin |
+ GCTileStipYOrigin | GCFont |
+ GCSubwindowMode | GCClipXOrigin |
+ GCClipYOrigin | GCClipMask)) !=
+ Success)
+ {
+ FreeScratchGC(pGC);
+ xfree(c->data);
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+ origGC = c->pGC;
+ c->pGC = pGC;
+ ValidateGC(c->pDraw, c->pGC);
+
+ c->slept = TRUE;
+ ClientSleep(client,
+ (ClientSleepProcPtr)doPolyText,
+ (pointer) c);
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doPolyText (1): client [%lx] sleeping.\n", client);
+#endif
+
+ /* Set up to perform steps 3 and 4 */
+ client_state = START_SLEEP;
+ continue; /* on to steps 3 and 4 */
+ }
+ return TRUE;
+ }
+ else if (lgerr != Successful)
+ {
+ err = FontToXError(lgerr);
+ goto bail;
+ }
+ if (c->pDraw)
+ {
+ c->xorg += *((INT8 *)(c->pElt + 1)); /* must be signed */
+ c->xorg = (* c->polyText)(c->pDraw, c->pGC, c->xorg, c->yorg,
+ *c->pElt, c->pElt + TextEltHeader);
+ }
+ c->pElt = pNextElt;
+ }
+ }
+
+bail:
+
+ if (client_state == START_SLEEP)
+ {
+ /* Step 4 */
+ if (pFont != origGC->font)
+ {
+ ChangeGC(origGC, GCFont, &fid);
+ ValidateGC(c->pDraw, origGC);
+ }
+
+ /* restore pElt pointer for execution of remainder of the request */
+ c->pElt = c->data;
+ return TRUE;
+ }
+
+ if (c->err != Success) err = c->err;
+ if (err != Success && c->client != serverClient) {
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !c->pGC->pScreen->myNum)
+#endif
+ SendErrorToClient(c->client, c->reqType, 0, 0, err);
+ }
+ if (c->slept)
+ {
+ ClientWakeup(c->client);
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doPolytext: client [%lx] wakeup.\n", client);
+#endif
+ ChangeGC(c->pGC, clearGCmask, clearGC);
+
+ /* Unreference the font from the scratch GC */
+ CloseFont(c->pGC->font, (Font)0);
+ c->pGC->font = NullFont;
+
+ FreeScratchGC(c->pGC);
+ xfree(c->data);
+ xfree(c);
+ }
+ return TRUE;
+}
+
+int
+PolyText(ClientPtr client, DrawablePtr pDraw, GC *pGC, unsigned char *pElt,
+ unsigned char *endReq, int xorg, int yorg, int reqType, XID did)
+{
+ PTclosureRec local_closure;
+
+ local_closure.pElt = pElt;
+ local_closure.endReq = endReq;
+ local_closure.client = client;
+ local_closure.pDraw = pDraw;
+ local_closure.xorg = xorg;
+ local_closure.yorg = yorg;
+ if ((local_closure.reqType = reqType) == X_PolyText8)
+ {
+ local_closure.polyText = (PolyTextPtr) pGC->ops->PolyText8;
+ local_closure.itemSize = 1;
+ }
+ else
+ {
+ local_closure.polyText = (PolyTextPtr) pGC->ops->PolyText16;
+ local_closure.itemSize = 2;
+ }
+ local_closure.pGC = pGC;
+ local_closure.did = did;
+ local_closure.err = Success;
+ local_closure.slept = FALSE;
+
+ (void) doPolyText(client, &local_closure);
+ return Success;
+}
+
+
+#undef TextEltHeader
+#undef FontShiftSize
+
+int
+doImageText(ClientPtr client, register ITclosurePtr c)
+{
+ int err = Success, lgerr; /* err is in X error, not font error, space */
+ FontPathElementPtr fpe;
+
+ if (client->clientGone)
+ {
+ fpe = c->pGC->font->fpe;
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ err = Success;
+ goto bail;
+ }
+
+ /* Make sure our drawable hasn't disappeared while we slept. */
+ if (c->slept &&
+ c->pDraw &&
+ c->pDraw != (DrawablePtr)SecurityLookupIDByClass(client, c->did,
+ RC_DRAWABLE, SecurityWriteAccess))
+ {
+ /* Our drawable has disappeared. Treat like client died... ask
+ the FPE code to clean up after client. */
+ fpe = c->pGC->font->fpe;
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ err = Success;
+ goto bail;
+ }
+
+ lgerr = LoadGlyphs(client, c->pGC->font, c->nChars, c->itemSize, c->data);
+ if (lgerr == Suspended)
+ {
+ if (!c->slept) {
+ GC *pGC;
+ unsigned char *data;
+ ITclosurePtr new_closure;
+
+ /* We're putting the client to sleep. We need to
+ save some state. Similar problem to that handled
+ in doPolyText, but much simpler because the
+ request structure is much simpler. */
+
+ new_closure = (ITclosurePtr) xalloc(sizeof(ITclosureRec));
+ if (!new_closure)
+ {
+ err = BadAlloc;
+ goto bail;
+ }
+ *new_closure = *c;
+ c = new_closure;
+
+ data = (unsigned char *)xalloc(c->nChars * c->itemSize);
+ if (!data)
+ {
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+ memmove(data, c->data, c->nChars * c->itemSize);
+ c->data = data;
+
+ pGC = GetScratchGC(c->pGC->depth, c->pGC->pScreen);
+ if (!pGC)
+ {
+ xfree(c->data);
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+
+ pGC->tileIsPixel = TRUE;
+ pGC->tile.pixel = 0;
+ pGC->stipple = NullPixmap;
+
+ if ((err = CopyGC(c->pGC, pGC, GCFunction | GCPlaneMask |
+ GCForeground | GCBackground | GCFillStyle |
+ GCTile | GCStipple | GCTileStipXOrigin |
+ GCTileStipYOrigin | GCFont |
+ GCSubwindowMode | GCClipXOrigin |
+ GCClipYOrigin | GCClipMask)) != Success)
+ {
+ FreeScratchGC(pGC);
+ xfree(c->data);
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+ c->pGC = pGC;
+ ValidateGC(c->pDraw, c->pGC);
+
+ c->slept = TRUE;
+ ClientSleep(client, (ClientSleepProcPtr)doImageText, (pointer) c);
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doImageText (1): client [%lx] sleeping.\n", client);
+#endif
+
+ }
+ return TRUE;
+ }
+ else if (lgerr != Successful)
+ {
+ err = FontToXError(lgerr);
+ goto bail;
+ }
+ if (c->pDraw)
+ {
+ (* c->imageText)(c->pDraw, c->pGC, c->xorg, c->yorg,
+ c->nChars, c->data);
+ }
+
+bail:
+
+ if (err != Success && c->client != serverClient) {
+ SendErrorToClient(c->client, c->reqType, 0, 0, err);
+ }
+ if (c->slept)
+ {
+ ClientWakeup(c->client);
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doImageText: client [%lx] wakeup.\n", client);
+#endif
+ ChangeGC(c->pGC, clearGCmask, clearGC);
+
+ /* Unreference the font from the scratch GC */
+ CloseFont(c->pGC->font, (Font)0);
+ c->pGC->font = NullFont;
+
+ FreeScratchGC(c->pGC);
+ xfree(c->data);
+ xfree(c);
+ }
+ return TRUE;
+}
+
+int
+ImageText(ClientPtr client, DrawablePtr pDraw, GC *pGC, int nChars,
+ unsigned char *data, int xorg, int yorg, int reqType, XID did)
+{
+ ITclosureRec local_closure;
+
+ local_closure.client = client;
+ local_closure.pDraw = pDraw;
+ local_closure.pGC = pGC;
+ local_closure.nChars = nChars;
+ local_closure.data = data;
+ local_closure.xorg = xorg;
+ local_closure.yorg = yorg;
+ if ((local_closure.reqType = reqType) == X_ImageText8)
+ {
+ local_closure.imageText = (ImageTextPtr) pGC->ops->ImageText8;
+ local_closure.itemSize = 1;
+ }
+ else
+ {
+ local_closure.imageText = (ImageTextPtr) pGC->ops->ImageText16;
+ local_closure.itemSize = 2;
+ }
+ local_closure.did = did;
+ local_closure.slept = FALSE;
+
+ (void) doImageText(client, &local_closure);
+ return Success;
+}
+
+
+/* does the necessary magic to figure out the fpe type */
+static int
+DetermineFPEType(char *pathname)
+{
+ int i;
+
+ for (i = 0; i < num_fpe_types; i++) {
+ if ((*fpe_functions[i].name_check) (pathname))
+ return i;
+ }
+ return -1;
+}
+
+
+static void
+FreeFontPath(FontPathElementPtr *list, int n, Bool force)
+{
+ int i;
+
+ for (i = 0; i < n; i++) {
+ if (force) {
+ /* Sanity check that all refcounts will be 0 by the time
+ we get to the end of the list. */
+ int found = 1; /* the first reference is us */
+ int j;
+ for (j = i+1; j < n; j++) {
+ if (list[j] == list[i])
+ found++;
+ }
+ if (list[i]->refcount != found) {
+ ErrorF("FreeFontPath: FPE \"%.*s\" refcount is %d, should be %d; fixing.\n",
+ list[i]->name_length, list[i]->name,
+ list[i]->refcount, found);
+ list[i]->refcount = found; /* ensure it will get freed */
+ }
+ }
+ FreeFPE(list[i]);
+ }
+ xfree((char *) list);
+}
+
+static FontPathElementPtr
+find_existing_fpe(FontPathElementPtr *list, int num, unsigned char *name, int len)
+{
+ FontPathElementPtr fpe;
+ int i;
+
+ for (i = 0; i < num; i++) {
+ fpe = list[i];
+ if (fpe->name_length == len && memcmp(name, fpe->name, len) == 0)
+ return fpe;
+ }
+ return (FontPathElementPtr) 0;
+}
+
+
+static int
+SetFontPathElements(int npaths, unsigned char *paths, int *bad, Bool persist)
+{
+ int i, err = 0;
+ int valid_paths = 0;
+ unsigned int len;
+ unsigned char *cp = paths;
+ FontPathElementPtr fpe = NULL, *fplist;
+
+ fplist = (FontPathElementPtr *)
+ xalloc(sizeof(FontPathElementPtr) * npaths);
+ if (!fplist) {
+ *bad = 0;
+ return BadAlloc;
+ }
+ for (i = 0; i < num_fpe_types; i++) {
+ if (fpe_functions[i].set_path_hook)
+ (*fpe_functions[i].set_path_hook) ();
+ }
+ for (i = 0; i < npaths; i++)
+ {
+ len = (unsigned int) (*cp++);
+
+ if (len == 0)
+ {
+ if (persist)
+ ErrorF ("Removing empty element from the valid list of fontpaths\n");
+ err = BadValue;
+ }
+ else
+ {
+ /* if it's already in our active list, just reset it */
+ /*
+ * note that this can miss FPE's in limbo -- may be worth catching
+ * them, though it'd muck up refcounting
+ */
+ fpe = find_existing_fpe(font_path_elements, num_fpes, cp, len);
+ if (fpe)
+ {
+ err = (*fpe_functions[fpe->type].reset_fpe) (fpe);
+ if (err == Successful)
+ {
+ UseFPE(fpe);/* since it'll be decref'd later when freed
+ * from the old list */
+ }
+ else
+ fpe = 0;
+ }
+ /* if error or can't do it, act like it's a new one */
+ if (!fpe)
+ {
+ fpe = (FontPathElementPtr) xalloc(sizeof(FontPathElementRec));
+ if (!fpe)
+ {
+ err = BadAlloc;
+ goto bail;
+ }
+ fpe->name = (char *) xalloc(len + 1);
+ if (!fpe->name)
+ {
+ xfree(fpe);
+ err = BadAlloc;
+ goto bail;
+ }
+ fpe->refcount = 1;
+
+ strncpy(fpe->name, (char *) cp, (int) len);
+ fpe->name[len] = '\0';
+ fpe->name_length = len;
+ fpe->type = DetermineFPEType(fpe->name);
+ if (fpe->type == -1)
+ err = BadValue;
+ else
+ err = (*fpe_functions[fpe->type].init_fpe) (fpe);
+ if (err != Successful)
+ {
+ #ifndef NXAGENT_SERVER
+ if (persist)
+ {
+ ErrorF("Could not init font path element %s, removing from list!\n",
+ fpe->name);
+ }
+ #endif
+ xfree (fpe->name);
+ xfree (fpe);
+ }
+ }
+ }
+ if (err != Successful)
+ {
+ if (!persist)
+ goto bail;
+ }
+ else
+ {
+ fplist[valid_paths++] = fpe;
+ }
+ cp += len;
+ }
+
+ FreeFontPath(font_path_elements, num_fpes, FALSE);
+ font_path_elements = fplist;
+ if (patternCache)
+ EmptyFontPatternCache(patternCache);
+ num_fpes = valid_paths;
+
+ return Success;
+bail:
+ *bad = i;
+ while (--valid_paths >= 0)
+ FreeFPE(fplist[valid_paths]);
+ xfree(fplist);
+ return FontToXError(err);
+}
+
+/* XXX -- do we need to pass error down to each renderer? */
+int
+SetFontPath(ClientPtr client, int npaths, unsigned char *paths, int *error)
+{
+ int err = Success;
+
+ if (npaths == 0) {
+ if (SetDefaultFontPath(defaultFontPath) != Success)
+ return BadValue;
+ } else {
+ err = SetFontPathElements(npaths, paths, error, FALSE);
+ }
+ return err;
+}
+
+int
+SetDefaultFontPath(char *path)
+{
+ unsigned char *cp,
+ *pp,
+ *nump,
+ *newpath;
+ int num = 1,
+ len,
+ err,
+ size = 0,
+ bad;
+
+ /* get enough for string, plus values -- use up commas */
+#ifdef NX_TRANS_SOCKET
+ len = strlen(_NXGetFontPath(path)) + 1;
+#else
+ len = strlen(path) + 1;
+#endif
+ nump = cp = newpath = (unsigned char *) ALLOCATE_LOCAL(len);
+ if (!newpath)
+ return BadAlloc;
+#ifdef NX_TRANS_SOCKET
+ pp = (unsigned char *) _NXGetFontPath(path);
+#else
+ pp = (unsigned char *) path;
+#endif
+ cp++;
+ while (*pp) {
+ if (*pp == ',') {
+ *nump = (unsigned char) size;
+ nump = cp++;
+ pp++;
+ num++;
+ size = 0;
+ } else {
+ *cp++ = *pp++;
+ size++;
+ }
+ }
+ *nump = (unsigned char) size;
+
+ err = SetFontPathElements(num, newpath, &bad, TRUE);
+
+ DEALLOCATE_LOCAL(newpath);
+
+ return err;
+}
+
+unsigned char *
+GetFontPath(int *count, int *length)
+{
+ int i;
+ unsigned char *c;
+ int len;
+ FontPathElementPtr fpe;
+
+ len = 0;
+ for (i = 0; i < num_fpes; i++) {
+ fpe = font_path_elements[i];
+ len += fpe->name_length + 1;
+ }
+ font_path_string = (unsigned char *) xrealloc(font_path_string, len);
+ if (!font_path_string)
+ return NULL;
+
+ c = font_path_string;
+ *length = 0;
+ for (i = 0; i < num_fpes; i++) {
+ fpe = font_path_elements[i];
+ *c = fpe->name_length;
+ *length += *c++;
+ memmove(c, fpe->name, fpe->name_length);
+ c += fpe->name_length;
+ }
+ *count = num_fpes;
+ return font_path_string;
+}
+
+int
+LoadGlyphs(ClientPtr client, FontPtr pfont, unsigned nchars, int item_size, unsigned char *data)
+{
+ if (fpe_functions[pfont->fpe->type].load_glyphs)
+ return (*fpe_functions[pfont->fpe->type].load_glyphs)
+ (client, pfont, 0, nchars, item_size, data);
+ else
+ return Successful;
+}
+
+void
+DeleteClientFontStuff(ClientPtr client)
+{
+ int i;
+ FontPathElementPtr fpe;
+
+ for (i = 0; i < num_fpes; i++)
+ {
+ fpe = font_path_elements[i];
+ if (fpe_functions[fpe->type].client_died)
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ }
+}
+
+void
+InitFonts ()
+{
+ patternCache = MakeFontPatternCache();
+
+#ifndef KDRIVESERVER
+ if (screenInfo.numScreens > screenInfo.numVideoScreens) {
+ PrinterFontRegisterFpeFunctions();
+ FontFileCheckRegisterFpeFunctions();
+ check_fs_register_fpe_functions();
+ } else
+#endif
+ {
+#ifdef KDRIVESERVER
+ BuiltinRegisterFpeFunctions();
+#endif
+ FontFileRegisterFpeFunctions();
+#ifndef NOFONTSERVERACCESS
+ fs_register_fpe_functions();
+#endif
+ }
+}
+
+int
+GetDefaultPointSize ()
+{
+ return 120;
+}
+
+
+FontResolutionPtr
+GetClientResolutions (int *num)
+{
+ if (requestingClient && requestingClient->fontResFunc != NULL &&
+ !requestingClient->clientGone)
+ {
+ return (*requestingClient->fontResFunc)(requestingClient, num);
+ }
+ else {
+ static struct _FontResolution res;
+ ScreenPtr pScreen;
+
+ pScreen = screenInfo.screens[0];
+ res.x_resolution = (pScreen->width * 25.4) / pScreen->mmWidth;
+ /*
+ * XXX - we'll want this as long as bitmap instances are prevalent
+ so that we can match them from scalable fonts
+ */
+ if (res.x_resolution < 88)
+ res.x_resolution = 75;
+ else
+ res.x_resolution = 100;
+ res.y_resolution = (pScreen->height * 25.4) / pScreen->mmHeight;
+ if (res.y_resolution < 88)
+ res.y_resolution = 75;
+ else
+ res.y_resolution = 100;
+ res.point_size = 120;
+ *num = 1;
+ return &res;
+ }
+}
+
+/*
+ * returns the type index of the new fpe
+ *
+ * should be called (only once!) by each type of fpe when initialized
+ */
+
+int
+RegisterFPEFunctions(NameCheckFunc name_func,
+ InitFpeFunc init_func,
+ FreeFpeFunc free_func,
+ ResetFpeFunc reset_func,
+ OpenFontFunc open_func,
+ CloseFontFunc close_func,
+ ListFontsFunc list_func,
+ StartLfwiFunc start_lfwi_func,
+ NextLfwiFunc next_lfwi_func,
+ WakeupFpeFunc wakeup_func,
+ ClientDiedFunc client_died,
+ LoadGlyphsFunc load_glyphs,
+ StartLaFunc start_list_alias_func,
+ NextLaFunc next_list_alias_func,
+ SetPathFunc set_path_func)
+{
+ FPEFunctions *new;
+
+ /* grow the list */
+ new = (FPEFunctions *) xrealloc(fpe_functions,
+ (num_fpe_types + 1) * sizeof(FPEFunctions));
+ if (!new)
+ return -1;
+ fpe_functions = new;
+
+ fpe_functions[num_fpe_types].name_check = name_func;
+ fpe_functions[num_fpe_types].open_font = open_func;
+ fpe_functions[num_fpe_types].close_font = close_func;
+ fpe_functions[num_fpe_types].wakeup_fpe = wakeup_func;
+ fpe_functions[num_fpe_types].list_fonts = list_func;
+ fpe_functions[num_fpe_types].start_list_fonts_with_info =
+ start_lfwi_func;
+ fpe_functions[num_fpe_types].list_next_font_with_info =
+ next_lfwi_func;
+ fpe_functions[num_fpe_types].init_fpe = init_func;
+ fpe_functions[num_fpe_types].free_fpe = free_func;
+ fpe_functions[num_fpe_types].reset_fpe = reset_func;
+ fpe_functions[num_fpe_types].client_died = client_died;
+ fpe_functions[num_fpe_types].load_glyphs = load_glyphs;
+ fpe_functions[num_fpe_types].start_list_fonts_and_aliases =
+ start_list_alias_func;
+ fpe_functions[num_fpe_types].list_next_font_or_alias =
+ next_list_alias_func;
+ fpe_functions[num_fpe_types].set_path_hook = set_path_func;
+
+ return num_fpe_types++;
+}
+
+void
+FreeFonts()
+{
+ if (patternCache) {
+ FreeFontPatternCache(patternCache);
+ patternCache = 0;
+ }
+ FreeFontPath(font_path_elements, num_fpes, TRUE);
+ font_path_elements = 0;
+ num_fpes = 0;
+ xfree(fpe_functions);
+ num_fpe_types = 0;
+ fpe_functions = (FPEFunctions *) 0;
+}
+
+/* convenience functions for FS interface */
+
+FontPtr
+find_old_font(XID id)
+{
+ return (FontPtr) SecurityLookupIDByType(NullClient, id, RT_NONE,
+ SecurityUnknownAccess);
+}
+
+Font
+GetNewFontClientID()
+{
+ return FakeClientID(0);
+}
+
+int
+StoreFontClientFont(FontPtr pfont, Font id)
+{
+ return AddResource(id, RT_NONE, (pointer) pfont);
+}
+
+void
+DeleteFontClientID(Font id)
+{
+ FreeResource(id, RT_NONE);
+}
+
+int
+client_auth_generation(ClientPtr client)
+{
+ return 0;
+}
+
+static int fs_handlers_installed = 0;
+static unsigned int last_server_gen;
+
+int
+init_fs_handlers(FontPathElementPtr fpe, BlockHandlerProcPtr block_handler)
+{
+ /* if server has reset, make sure the b&w handlers are reinstalled */
+ if (last_server_gen < serverGeneration) {
+ last_server_gen = serverGeneration;
+ fs_handlers_installed = 0;
+ }
+ if (fs_handlers_installed == 0) {
+
+#ifdef DEBUG
+ fprintf(stderr, "adding FS b & w handlers\n");
+#endif
+
+ if (!RegisterBlockAndWakeupHandlers(block_handler,
+ FontWakeup, (pointer) 0))
+ return AllocError;
+ fs_handlers_installed++;
+ }
+ QueueFontWakeup(fpe);
+ return Successful;
+}
+
+void
+remove_fs_handlers(FontPathElementPtr fpe, BlockHandlerProcPtr block_handler, Bool all)
+{
+ if (all) {
+ /* remove the handlers if no one else is using them */
+ if (--fs_handlers_installed == 0) {
+
+#ifdef DEBUG
+ fprintf(stderr, "removing FS b & w handlers\n");
+#endif
+
+ RemoveBlockAndWakeupHandlers(block_handler, FontWakeup,
+ (pointer) 0);
+ }
+ }
+ RemoveFontWakeup(fpe);
+}
+
+#ifdef DEBUG
+#define GLWIDTHBYTESPADDED(bits,nbytes) \
+ ((nbytes) == 1 ? (((bits)+7)>>3) /* pad to 1 byte */ \
+ :(nbytes) == 2 ? ((((bits)+15)>>3)&~1) /* pad to 2 bytes */ \
+ :(nbytes) == 4 ? ((((bits)+31)>>3)&~3) /* pad to 4 bytes */ \
+ :(nbytes) == 8 ? ((((bits)+63)>>3)&~7) /* pad to 8 bytes */ \
+ : 0)
+
+#define GLYPH_SIZE(ch, nbytes) \
+ GLWIDTHBYTESPADDED((ch)->metrics.rightSideBearing - \
+ (ch)->metrics.leftSideBearing, (nbytes))
+void
+dump_char_ascii(CharInfoPtr cip)
+{
+ int r,
+ l;
+ int bpr;
+ int byte;
+ static unsigned maskTab[] = {
+ (1 << 7), (1 << 6), (1 << 5), (1 << 4),
+ (1 << 3), (1 << 2), (1 << 1), (1 << 0),
+ };
+
+ bpr = GLYPH_SIZE(cip, 4);
+ for (r = 0; r < (cip->metrics.ascent + cip->metrics.descent); r++) {
+ pointer row = (pointer) cip->bits + r * bpr;
+
+ byte = 0;
+ for (l = 0; l <= (cip->metrics.rightSideBearing -
+ cip->metrics.leftSideBearing); l++) {
+ if (maskTab[l & 7] & row[l >> 3])
+ putchar('X');
+ else
+ putchar('.');
+ }
+ putchar('\n');
+ }
+}
+
+#endif
+
+
+typedef struct
+{
+ LFclosurePtr c;
+ OFclosurePtr oc;
+} nxFs,*nxFsPtr;
+
+static Bool
+#if NeedFunctionPrototypes
+nxdoListFontsAndAliases(ClientPtr client, nxFsPtr fss)
+#else
+nxdoListFontsAndAliases(client, fss)
+ ClientPtr client;
+ nxFsPtr fss;
+#endif
+{
+ LFclosurePtr c=fss->c;
+ OFclosurePtr oc=fss->oc;
+ FontPathElementPtr fpe;
+ int err = Successful;
+ char *name, *resolved=NULL;
+ int namelen, resolvedlen;
+ int i;
+ int aliascount = 0;
+ char tmp[256];
+ tmp[0]=0;
+ if (client->clientGone)
+ {
+ if (c->current.current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current.current_fpe];
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ }
+ err = Successful;
+ goto bail;
+ }
+
+ if (!c->current.patlen)
+ goto finish;
+
+ while (c->current.current_fpe < c->num_fpes) {
+ fpe = c->fpe_list[c->current.current_fpe];
+ err = Successful;
+
+ if (!fpe_functions[fpe->type].start_list_fonts_and_aliases)
+ {
+ /* This FPE doesn't support/require list_fonts_and_aliases */
+
+ err = (*fpe_functions[fpe->type].list_fonts)
+ ((pointer) c->client, fpe, c->current.pattern,
+ c->current.patlen, c->current.max_names - c->names->nnames,
+ c->names);
+
+ if (err == Suspended) {
+ if (!c->slept) {
+ c->slept = TRUE;
+ ClientSleep(client,
+ (ClientSleepProcPtr)nxdoListFontsAndAliases,
+ (pointer) fss);
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: nxdoListFont (1): client [%lx] sleeping.\n", client);
+#endif
+ }
+ return TRUE;
+ }
+
+ err = BadFontName;
+ }
+ else
+ {
+ /* Start of list_fonts_and_aliases functionality. Modeled
+ after list_fonts_with_info in that it resolves aliases,
+ except that the information collected from FPEs is just
+ names, not font info. Each list_next_font_or_alias()
+ returns either a name into name/namelen or an alias into
+ name/namelen and its target name into resolved/resolvedlen.
+ The code at this level then resolves the alias by polling
+ the FPEs. */
+
+ if (!c->current.list_started) {
+ err = (*fpe_functions[fpe->type].start_list_fonts_and_aliases)
+ ((pointer) c->client, fpe, c->current.pattern,
+ c->current.patlen, c->current.max_names - c->names->nnames,
+ &c->current.private);
+ if (err == Suspended) {
+ if (!c->slept) {
+ ClientSleep(client,
+ (ClientSleepProcPtr)nxdoListFontsAndAliases,
+ (pointer) fss);
+ c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: nxdoListFont (2): client [%lx] sleeping.\n", client);
+#endif
+ }
+ return TRUE;
+ }
+ if (err == Successful)
+ c->current.list_started = TRUE;
+ }
+ if (err == Successful) {
+ char *tmpname;
+ name = 0;
+ err = (*fpe_functions[fpe->type].list_next_font_or_alias)
+ ((pointer) c->client, fpe, &name, &namelen, &tmpname,
+ &resolvedlen, c->current.private);
+ if (err == Suspended) {
+ if (!c->slept) {
+ ClientSleep(client,
+ (ClientSleepProcPtr)nxdoListFontsAndAliases,
+ (pointer) fss);
+ c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: nxdoListFont (3): client [%lx] sleeping.\n", client);
+#endif
+ }
+ return TRUE;
+ }
+ if (err == FontNameAlias) {
+ if (resolved) xfree(resolved);
+ resolved = (char *) xalloc(resolvedlen + 1);
+ if (resolved)
+ {
+ memmove(resolved, tmpname, resolvedlen);
+ resolved[resolvedlen] = '\0';
+ }
+ }
+ }
+
+ if (err == Successful)
+ {
+ if (c->haveSaved)
+ {
+ if (c->savedName)
+ {
+ memcpy(tmp,c->savedName,c->savedNameLen>255?255:c->savedNameLen);
+ tmp[c->savedNameLen>255?256:c->savedNameLen]=0;
+ if (nxagentFontLookUp(tmp))
+ break;
+ else tmp[0]=0;
+ }
+ }
+ else
+ {
+ memcpy(tmp,name,namelen>255?255:namelen);
+ tmp[namelen>255?256:namelen]=0;
+ if (nxagentFontLookUp(tmp))
+ break;
+ else tmp[0]=0;
+ }
+ }
+
+ /*
+ * When we get an alias back, save our state and reset back to
+ * the start of the FPE looking for the specified name. As
+ * soon as a real font is found for the alias, pop back to the
+ * old state
+ */
+ else if (err == FontNameAlias) {
+ char tmp_pattern[XLFDMAXFONTNAMELEN];
+ /*
+ * when an alias recurses, we need to give
+ * the last FPE a chance to clean up; so we call
+ * it again, and assume that the error returned
+ * is BadFontName, indicating the alias resolution
+ * is complete.
+ */
+ memmove(tmp_pattern, resolved, resolvedlen);
+ if (c->haveSaved)
+ {
+ char *tmpname;
+ int tmpnamelen;
+
+ tmpname = 0;
+ (void) (*fpe_functions[fpe->type].list_next_font_or_alias)
+ ((pointer) c->client, fpe, &tmpname, &tmpnamelen,
+ &tmpname, &tmpnamelen, c->current.private);
+ if (--aliascount <= 0)
+ {
+ err = BadFontName;
+ goto ContBadFontName;
+ }
+ }
+ else
+ {
+ c->saved = c->current;
+ c->haveSaved = TRUE;
+ if (c->savedName)
+ xfree(c->savedName);
+ c->savedName = (char *)xalloc(namelen + 1);
+ if (c->savedName)
+ {
+ memmove(c->savedName, name, namelen);
+ c->savedName[namelen] = '\0';
+ }
+ c->savedNameLen = namelen;
+ aliascount = 20;
+ }
+ memmove(c->current.pattern, tmp_pattern, resolvedlen);
+ c->current.patlen = resolvedlen;
+ c->current.max_names = c->names->nnames + 1;
+ c->current.current_fpe = -1;
+ c->current.private = 0;
+ err = BadFontName;
+ }
+ }
+ /*
+ * At the end of this FPE, step to the next. If we've finished
+ * processing an alias, pop state back. If we've collected enough
+ * font names, quit.
+ */
+ if (err == BadFontName) {
+ ContBadFontName: ;
+ c->current.list_started = FALSE;
+ c->current.current_fpe++;
+ err = Successful;
+ if (c->haveSaved)
+ {
+ if (c->names->nnames == c->current.max_names ||
+ c->current.current_fpe == c->num_fpes) {
+ c->haveSaved = FALSE;
+ c->current = c->saved;
+ /* Give the saved namelist a chance to clean itself up */
+ continue;
+ }
+ }
+ if (c->names->nnames == c->current.max_names)
+ break;
+ }
+ }
+
+ /*
+ * send the reply
+ */
+bail:
+finish:
+ if (strlen(tmp))
+ {
+#ifdef NXAGENT_FONTMATCH_DEBUG
+ fprintf(stderr, "nxListFont changed (0) font to %s\n",tmp);
+#endif
+ memcpy(oc->fontname, tmp, strlen(tmp));
+ oc->fnamelen = strlen(tmp);
+
+ oc->origFontName = oc->fontname;
+ oc->origFontNameLen = oc->fnamelen;
+
+ }
+ else
+ {
+ for (i = 0; i < c->names->nnames; i++)
+ {
+ if (c->names->length[i] > 255)
+ continue;
+ else
+ {
+ memcpy(tmp, c->names->names[i], c->names->length[i]);
+ tmp[ c->names->length[i] ] = 0;
+ if (nxagentFontLookUp(tmp) == 0)
+ continue;
+ memcpy(oc->fontname, tmp, strlen(tmp));
+ oc->fnamelen = strlen(tmp);
+
+ oc->origFontName = oc->fontname;
+ oc->origFontNameLen = oc->fnamelen;
+
+#ifdef NXAGENT_FONTMATCH_DEBUG
+ fprintf(stderr, "nxListFont changed (1) font to %s\n",tmp);
+#endif
+ break;
+ }
+ }
+ }
+
+ if (c->slept)
+ {
+ ClientWakeup(client);
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: nxdoListFont: client [%lx] wakeup.\n", client);
+#endif
+ }
+ for (i = 0; i < c->num_fpes; i++)
+ FreeFPE(c->fpe_list[i]);
+ xfree(c->fpe_list);
+ if (c->savedName) xfree(c->savedName);
+ FreeFontNames(c->names);
+ xfree(c);
+ xfree(fss);
+ if (resolved) xfree(resolved);
+
+ return doOpenFont(client, oc);
+}
+
+int
+nxOpenFont(client, fid, flags, lenfname, pfontname)
+ ClientPtr client;
+ XID fid;
+ Mask flags;
+ unsigned lenfname;
+ char *pfontname;
+{
+ nxFsPtr fss;
+ LFclosurePtr c;
+ OFclosurePtr oc;
+ int i;
+ FontPtr cached = (FontPtr)0;
+
+#ifdef FONTDEBUG
+ char *f;
+ f = (char *)xalloc(lenfname + 1);
+ memmove(f, pfontname, lenfname);
+ f[lenfname] = '\0';
+ ErrorF("OpenFont: fontname is \"%s\"\n", f);
+ xfree(f);
+#endif
+ if (!lenfname || lenfname > XLFDMAXFONTNAMELEN)
+ return BadName;
+ if (patternCache)
+ {
+
+ /*
+ ** Check name cache. If we find a cached version of this font that
+ ** is cachable, immediately satisfy the request with it. If we find
+ ** a cached version of this font that is non-cachable, we do not
+ ** satisfy the request with it. Instead, we pass the FontPtr to the
+ ** FPE's open_font code (the fontfile FPE in turn passes the
+ ** information to the rasterizer; the fserve FPE ignores it).
+ **
+ ** Presumably, the font is marked non-cachable because the FPE has
+ ** put some licensing restrictions on it. If the FPE, using
+ ** whatever logic it relies on, determines that it is willing to
+ ** share this existing font with the client, then it has the option
+ ** to return the FontPtr we passed it as the newly-opened font.
+ ** This allows the FPE to exercise its licensing logic without
+ ** having to create another instance of a font that already exists.
+ */
+
+ cached = FindCachedFontPattern(patternCache, pfontname, lenfname);
+ if (cached && cached->info.cachable)
+ {
+ if (!AddResource(fid, RT_FONT, (pointer) cached))
+ return BadAlloc;
+ cached->refcnt++;
+ return Success;
+ }
+ }
+ if (!(fss = (nxFsPtr) xalloc(sizeof(nxFs))))
+ return BadAlloc;
+
+ if (!(c = (LFclosurePtr) xalloc(sizeof *c)))
+ {
+ xfree(fss);
+ return BadAlloc;
+ }
+ c->fpe_list = (FontPathElementPtr *)
+ xalloc(sizeof(FontPathElementPtr) * num_fpes);
+ if (!c->fpe_list) {
+ xfree(c);
+ xfree(fss);
+ return BadAlloc;
+ }
+ c->names = MakeFontNamesRecord(100);
+ if (!c->names)
+ {
+ xfree(c->fpe_list);
+ xfree(c);
+ xfree(fss);
+ return BadAlloc;
+ }
+ memmove( c->current.pattern, pfontname, lenfname);
+ for (i = 0; i < num_fpes; i++) {
+ c->fpe_list[i] = font_path_elements[i];
+ UseFPE(c->fpe_list[i]);
+ }
+ c->client = client;
+ c->num_fpes = num_fpes;
+ c->current.patlen = lenfname;
+ c->current.current_fpe = 0;
+ c->current.max_names = nxagentMaxFontNames;
+ c->current.list_started = FALSE;
+ c->current.private = 0;
+ c->haveSaved = FALSE;
+ c->slept = FALSE;
+ c->savedName = 0;
+
+ oc = (OFclosurePtr) xalloc(sizeof(OFclosureRec));
+ if (!oc)
+ {
+ for (i = 0; i < c->num_fpes; i++)
+ FreeFPE(c->fpe_list[i]);
+ xfree(c->fpe_list);
+ xfree(c);
+ xfree(fss);
+ return BadAlloc;
+ }
+ oc->fontname = (char *) xalloc(256);/* I don't want to deal with future reallocs errors */
+ oc->origFontName = pfontname;
+ oc->origFontNameLen = lenfname;
+ if (!oc->fontname) {
+ for (i = 0; i < c->num_fpes; i++)
+ FreeFPE(c->fpe_list[i]);
+ xfree(c->fpe_list);
+ xfree(c);
+ xfree(oc);
+ xfree(fss);
+ return BadAlloc;
+ }
+ /*
+ * copy the current FPE list, so that if it gets changed by another client
+ * while we're blocking, the request still appears atomic
+ */
+ oc->fpe_list = (FontPathElementPtr *)
+ xalloc(sizeof(FontPathElementPtr) * num_fpes);
+ if (!oc->fpe_list) {
+ xfree(oc->fontname);
+ xfree(oc);
+ for (i = 0; i < c->num_fpes; i++)
+ FreeFPE(c->fpe_list[i]);
+ xfree(c->fpe_list);
+ xfree(c);
+ xfree(fss);
+ return BadAlloc;
+ }
+ memmove(oc->fontname, pfontname, lenfname);
+ for (i = 0; i < num_fpes; i++) {
+ oc->fpe_list[i] = font_path_elements[i];
+ UseFPE(oc->fpe_list[i]);
+ }
+ oc->client = client;
+ oc->fontid = fid;
+ oc->current_fpe = 0;
+ oc->num_fpes = num_fpes;
+ oc->fnamelen = lenfname;
+ oc->slept = FALSE;
+ oc->flags = flags;
+ oc->non_cachable_font = cached;
+ fss->c=c;
+ fss->oc=oc;
+ nxdoListFontsAndAliases(client, fss);
+ return Success;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.X.original
new file mode 100644
index 000000000..9de998417
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.X.original
@@ -0,0 +1,2143 @@
+/* $XdotOrg: xc/programs/Xserver/dix/dixfonts.c,v 1.8 2005/07/03 08:53:38 daniels Exp $ */
+/* $XFree86: xc/programs/Xserver/dix/dixfonts.c,v 3.28 2003/11/08 02:02:03 dawes Exp $ */
+/************************************************************************
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+************************************************************************/
+/* The panoramix components contained the following notice */
+/*
+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.
+
+******************************************************************/
+/* $Xorg: dixfonts.c,v 1.4 2000/08/17 19:48:18 cpqbld Exp $ */
+
+#define NEED_REPLIES
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xmd.h>
+#include <X11/Xproto.h>
+#include "scrnintstr.h"
+#include "resource.h"
+#include "dixstruct.h"
+#include "cursorstr.h"
+#include "misc.h"
+#include "opaque.h"
+#include "dixfontstr.h"
+#include "closestr.h"
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#endif
+
+#ifdef LBX
+#include "lbxserve.h"
+#endif
+
+#ifdef XF86BIGFONT
+#define _XF86BIGFONT_SERVER_
+#include <X11/extensions/xf86bigfont.h>
+#endif
+
+#define QUERYCHARINFO(pci, pr) *(pr) = (pci)->metrics
+
+extern pointer fosNaturalParams;
+extern FontPtr defaultFont;
+
+static FontPathElementPtr *font_path_elements = (FontPathElementPtr *) 0;
+static int num_fpes = 0;
+FPEFunctions *fpe_functions = (FPEFunctions *) 0;
+static int num_fpe_types = 0;
+
+static unsigned char *font_path_string;
+
+static int num_slept_fpes = 0;
+static int size_slept_fpes = 0;
+static FontPathElementPtr *slept_fpes = (FontPathElementPtr *) 0;
+static FontPatternCachePtr patternCache;
+
+int
+FontToXError(err)
+ int err;
+{
+ switch (err) {
+ case Successful:
+ return Success;
+ case AllocError:
+ return BadAlloc;
+ case BadFontName:
+ return BadName;
+ case BadFontPath:
+ case BadFontFormat: /* is there something better? */
+ case BadCharRange:
+ return BadValue;
+ default:
+ return err;
+ }
+}
+
+
+/*
+ * adding RT_FONT prevents conflict with default cursor font
+ */
+Bool
+SetDefaultFont(char *defaultfontname)
+{
+ int err;
+ FontPtr pf;
+ XID fid;
+
+ fid = FakeClientID(0);
+ err = OpenFont(serverClient, fid, FontLoadAll | FontOpenSync,
+ (unsigned) strlen(defaultfontname), defaultfontname);
+ if (err != Success)
+ return FALSE;
+ pf = (FontPtr) LookupIDByType(fid, RT_FONT);
+ if (pf == (FontPtr) NULL)
+ return FALSE;
+ defaultFont = pf;
+ return TRUE;
+}
+
+/*
+ * note that the font wakeup queue is not refcounted. this is because
+ * an fpe needs to be added when it's inited, and removed when it's finally
+ * freed, in order to handle any data that isn't requested, like FS events.
+ *
+ * since the only thing that should call these routines is the renderer's
+ * init_fpe() and free_fpe(), there shouldn't be any problem in using
+ * freed data.
+ */
+void
+QueueFontWakeup(FontPathElementPtr fpe)
+{
+ int i;
+ FontPathElementPtr *new;
+
+ for (i = 0; i < num_slept_fpes; i++) {
+ if (slept_fpes[i] == fpe) {
+
+#ifdef DEBUG
+ fprintf(stderr, "re-queueing fpe wakeup\n");
+#endif
+
+ return;
+ }
+ }
+ if (num_slept_fpes == size_slept_fpes) {
+ new = (FontPathElementPtr *)
+ xrealloc(slept_fpes,
+ sizeof(FontPathElementPtr) * (size_slept_fpes + 4));
+ if (!new)
+ return;
+ slept_fpes = new;
+ size_slept_fpes += 4;
+ }
+ slept_fpes[num_slept_fpes] = fpe;
+ num_slept_fpes++;
+}
+
+void
+RemoveFontWakeup(FontPathElementPtr fpe)
+{
+ int i,
+ j;
+
+ for (i = 0; i < num_slept_fpes; i++) {
+ if (slept_fpes[i] == fpe) {
+ for (j = i; j < num_slept_fpes; j++) {
+ slept_fpes[j] = slept_fpes[j + 1];
+ }
+ num_slept_fpes--;
+ return;
+ }
+ }
+}
+
+void
+FontWakeup(pointer data, int count, pointer LastSelectMask)
+{
+ int i;
+ FontPathElementPtr fpe;
+
+ if (count < 0)
+ return;
+ /* wake up any fpe's that may be waiting for information */
+ for (i = 0; i < num_slept_fpes; i++) {
+ fpe = slept_fpes[i];
+ (void) (*fpe_functions[fpe->type].wakeup_fpe) (fpe, LastSelectMask);
+ }
+}
+
+/* XXX -- these two funcs may want to be broken into macros */
+static void
+UseFPE(FontPathElementPtr fpe)
+{
+ fpe->refcount++;
+}
+
+static void
+FreeFPE (FontPathElementPtr fpe)
+{
+ fpe->refcount--;
+ if (fpe->refcount == 0) {
+ (*fpe_functions[fpe->type].free_fpe) (fpe);
+ xfree(fpe->name);
+ xfree(fpe);
+ }
+}
+
+static Bool
+doOpenFont(ClientPtr client, OFclosurePtr c)
+{
+ FontPtr pfont = NullFont;
+ FontPathElementPtr fpe = NULL;
+ ScreenPtr pScr;
+ int err = Successful;
+ int i;
+ char *alias,
+ *newname;
+ int newlen;
+ int aliascount = 20;
+ /*
+ * Decide at runtime what FontFormat to use.
+ */
+ Mask FontFormat =
+
+ ((screenInfo.imageByteOrder == LSBFirst) ?
+ BitmapFormatByteOrderLSB : BitmapFormatByteOrderMSB) |
+
+ ((screenInfo.bitmapBitOrder == LSBFirst) ?
+ BitmapFormatBitOrderLSB : BitmapFormatBitOrderMSB) |
+
+ BitmapFormatImageRectMin |
+
+#if GLYPHPADBYTES == 1
+ BitmapFormatScanlinePad8 |
+#endif
+
+#if GLYPHPADBYTES == 2
+ BitmapFormatScanlinePad16 |
+#endif
+
+#if GLYPHPADBYTES == 4
+ BitmapFormatScanlinePad32 |
+#endif
+
+#if GLYPHPADBYTES == 8
+ BitmapFormatScanlinePad64 |
+#endif
+
+ BitmapFormatScanlineUnit8;
+
+ if (client->clientGone)
+ {
+ if (c->current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current_fpe];
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ }
+ err = Successful;
+ goto bail;
+ }
+ while (c->current_fpe < c->num_fpes) {
+ fpe = c->fpe_list[c->current_fpe];
+ err = (*fpe_functions[fpe->type].open_font)
+ ((pointer) client, fpe, c->flags,
+ c->fontname, c->fnamelen, FontFormat,
+ BitmapFormatMaskByte |
+ BitmapFormatMaskBit |
+ BitmapFormatMaskImageRectangle |
+ BitmapFormatMaskScanLinePad |
+ BitmapFormatMaskScanLineUnit,
+ c->fontid, &pfont, &alias,
+ c->non_cachable_font && c->non_cachable_font->fpe == fpe ?
+ c->non_cachable_font :
+ (FontPtr)0);
+
+ if (err == FontNameAlias && alias) {
+ newlen = strlen(alias);
+ newname = (char *) xrealloc(c->fontname, newlen);
+ if (!newname) {
+ err = AllocError;
+ break;
+ }
+ memmove(newname, alias, newlen);
+ c->fontname = newname;
+ c->fnamelen = newlen;
+ c->current_fpe = 0;
+ if (--aliascount <= 0)
+ break;
+ continue;
+ }
+ if (err == BadFontName) {
+ c->current_fpe++;
+ continue;
+ }
+ if (err == Suspended) {
+ if (!c->slept) {
+ c->slept = TRUE;
+ ClientSleep(client, (ClientSleepProcPtr)doOpenFont, (pointer) c);
+ }
+ return TRUE;
+ }
+ break;
+ }
+
+ if (err != Successful)
+ goto bail;
+ if (!pfont) {
+ err = BadFontName;
+ goto bail;
+ }
+ if (!pfont->fpe)
+ pfont->fpe = fpe;
+ pfont->refcnt++;
+ if (pfont->refcnt == 1) {
+ UseFPE(pfont->fpe);
+ for (i = 0; i < screenInfo.numScreens; i++) {
+ pScr = screenInfo.screens[i];
+ if (pScr->RealizeFont)
+ {
+ if (!(*pScr->RealizeFont) (pScr, pfont))
+ {
+ CloseFont (pfont, (Font) 0);
+ err = AllocError;
+ goto bail;
+ }
+ }
+ }
+ }
+ if (!AddResource(c->fontid, RT_FONT, (pointer) pfont)) {
+ err = AllocError;
+ goto bail;
+ }
+ if (patternCache && pfont != c->non_cachable_font)
+ CacheFontPattern(patternCache, c->origFontName, c->origFontNameLen,
+ pfont);
+bail:
+ if (err != Successful && c->client != serverClient) {
+ SendErrorToClient(c->client, X_OpenFont, 0,
+ c->fontid, FontToXError(err));
+ }
+ if (c->slept)
+ ClientWakeup(c->client);
+ for (i = 0; i < c->num_fpes; i++) {
+ FreeFPE(c->fpe_list[i]);
+ }
+ xfree(c->fpe_list);
+ xfree(c->fontname);
+ xfree(c);
+ return TRUE;
+}
+
+int
+OpenFont(ClientPtr client, XID fid, Mask flags, unsigned lenfname, char *pfontname)
+{
+ OFclosurePtr c;
+ int i;
+ FontPtr cached = (FontPtr)0;
+
+#ifdef FONTDEBUG
+ char *f;
+ f = (char *)xalloc(lenfname + 1);
+ memmove(f, pfontname, lenfname);
+ f[lenfname] = '\0';
+ ErrorF("OpenFont: fontname is \"%s\"\n", f);
+ xfree(f);
+#endif
+ if (!lenfname || lenfname > XLFDMAXFONTNAMELEN)
+ return BadName;
+ if (patternCache)
+ {
+
+ /*
+ ** Check name cache. If we find a cached version of this font that
+ ** is cachable, immediately satisfy the request with it. If we find
+ ** a cached version of this font that is non-cachable, we do not
+ ** satisfy the request with it. Instead, we pass the FontPtr to the
+ ** FPE's open_font code (the fontfile FPE in turn passes the
+ ** information to the rasterizer; the fserve FPE ignores it).
+ **
+ ** Presumably, the font is marked non-cachable because the FPE has
+ ** put some licensing restrictions on it. If the FPE, using
+ ** whatever logic it relies on, determines that it is willing to
+ ** share this existing font with the client, then it has the option
+ ** to return the FontPtr we passed it as the newly-opened font.
+ ** This allows the FPE to exercise its licensing logic without
+ ** having to create another instance of a font that already exists.
+ */
+
+ cached = FindCachedFontPattern(patternCache, pfontname, lenfname);
+ if (cached && cached->info.cachable)
+ {
+ if (!AddResource(fid, RT_FONT, (pointer) cached))
+ return BadAlloc;
+ cached->refcnt++;
+ return Success;
+ }
+ }
+ c = (OFclosurePtr) xalloc(sizeof(OFclosureRec));
+ if (!c)
+ return BadAlloc;
+ c->fontname = (char *) xalloc(lenfname);
+ c->origFontName = pfontname;
+ c->origFontNameLen = lenfname;
+ if (!c->fontname) {
+ xfree(c);
+ return BadAlloc;
+ }
+ /*
+ * copy the current FPE list, so that if it gets changed by another client
+ * while we're blocking, the request still appears atomic
+ */
+ c->fpe_list = (FontPathElementPtr *)
+ xalloc(sizeof(FontPathElementPtr) * num_fpes);
+ if (!c->fpe_list) {
+ xfree(c->fontname);
+ xfree(c);
+ return BadAlloc;
+ }
+ memmove(c->fontname, pfontname, lenfname);
+ for (i = 0; i < num_fpes; i++) {
+ c->fpe_list[i] = font_path_elements[i];
+ UseFPE(c->fpe_list[i]);
+ }
+ c->client = client;
+ c->fontid = fid;
+ c->current_fpe = 0;
+ c->num_fpes = num_fpes;
+ c->fnamelen = lenfname;
+ c->slept = FALSE;
+ c->flags = flags;
+ c->non_cachable_font = cached;
+
+ (void) doOpenFont(client, c);
+ return Success;
+}
+
+/**
+ * Decrement font's ref count, and free storage if ref count equals zero
+ *
+ * \param value must conform to DeleteType
+ */
+int
+CloseFont(pointer value, XID fid)
+{
+ int nscr;
+ ScreenPtr pscr;
+ FontPathElementPtr fpe;
+ FontPtr pfont = (FontPtr)value;
+
+ if (pfont == NullFont)
+ return (Success);
+ if (--pfont->refcnt == 0) {
+ if (patternCache)
+ RemoveCachedFontPattern (patternCache, pfont);
+ /*
+ * since the last reference is gone, ask each screen to free any
+ * storage it may have allocated locally for it.
+ */
+ for (nscr = 0; nscr < screenInfo.numScreens; nscr++) {
+ pscr = screenInfo.screens[nscr];
+ if (pscr->UnrealizeFont)
+ (*pscr->UnrealizeFont) (pscr, pfont);
+ }
+ if (pfont == defaultFont)
+ defaultFont = NULL;
+#ifdef LBX
+ LbxFreeFontTag(pfont);
+#endif
+#ifdef XF86BIGFONT
+ XF86BigfontFreeFontShm(pfont);
+#endif
+ fpe = pfont->fpe;
+ (*fpe_functions[fpe->type].close_font) (fpe, pfont);
+ FreeFPE(fpe);
+ }
+ return (Success);
+}
+
+
+/***====================================================================***/
+
+/**
+ * Sets up pReply as the correct QueryFontReply for pFont with the first
+ * nProtoCCIStructs char infos.
+ *
+ * \param pReply caller must allocate this storage
+ */
+void
+QueryFont(FontPtr pFont, xQueryFontReply *pReply, int nProtoCCIStructs)
+{
+ FontPropPtr pFP;
+ int r,
+ c,
+ i;
+ xFontProp *prFP;
+ xCharInfo *prCI;
+ xCharInfo *charInfos[256];
+ unsigned char chars[512];
+ int ninfos;
+ unsigned long ncols;
+ unsigned long count;
+
+ /* pr->length set in dispatch */
+ pReply->minCharOrByte2 = pFont->info.firstCol;
+ pReply->defaultChar = pFont->info.defaultCh;
+ pReply->maxCharOrByte2 = pFont->info.lastCol;
+ pReply->drawDirection = pFont->info.drawDirection;
+ pReply->allCharsExist = pFont->info.allExist;
+ pReply->minByte1 = pFont->info.firstRow;
+ pReply->maxByte1 = pFont->info.lastRow;
+ pReply->fontAscent = pFont->info.fontAscent;
+ pReply->fontDescent = pFont->info.fontDescent;
+
+ pReply->minBounds = pFont->info.ink_minbounds;
+ pReply->maxBounds = pFont->info.ink_maxbounds;
+
+ pReply->nFontProps = pFont->info.nprops;
+ pReply->nCharInfos = nProtoCCIStructs;
+
+ for (i = 0, pFP = pFont->info.props, prFP = (xFontProp *) (&pReply[1]);
+ i < pFont->info.nprops;
+ i++, pFP++, prFP++) {
+ prFP->name = pFP->name;
+ prFP->value = pFP->value;
+ }
+
+ ninfos = 0;
+ ncols = (unsigned long) (pFont->info.lastCol - pFont->info.firstCol + 1);
+ prCI = (xCharInfo *) (prFP);
+ for (r = pFont->info.firstRow;
+ ninfos < nProtoCCIStructs && r <= (int)pFont->info.lastRow;
+ r++) {
+ i = 0;
+ for (c = pFont->info.firstCol; c <= (int)pFont->info.lastCol; c++) {
+ chars[i++] = r;
+ chars[i++] = c;
+ }
+ (*pFont->get_metrics) (pFont, ncols, chars,
+ TwoD16Bit, &count, charInfos);
+ i = 0;
+ for (i = 0; i < (int) count && ninfos < nProtoCCIStructs; i++) {
+ *prCI = *charInfos[i];
+ prCI++;
+ ninfos++;
+ }
+ }
+ return;
+}
+
+static Bool
+doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
+{
+ FontPathElementPtr fpe;
+ int err = Successful;
+ FontNamesPtr names = NULL;
+ char *name, *resolved=NULL;
+ int namelen, resolvedlen;
+ int nnames;
+ int stringLens;
+ int i;
+ xListFontsReply reply;
+ char *bufptr;
+ char *bufferStart;
+ int aliascount = 0;
+
+ if (client->clientGone)
+ {
+ if (c->current.current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current.current_fpe];
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ }
+ err = Successful;
+ goto bail;
+ }
+
+ if (!c->current.patlen)
+ goto finish;
+
+ while (c->current.current_fpe < c->num_fpes) {
+ fpe = c->fpe_list[c->current.current_fpe];
+ err = Successful;
+
+ if (!fpe_functions[fpe->type].start_list_fonts_and_aliases)
+ {
+ /* This FPE doesn't support/require list_fonts_and_aliases */
+
+ err = (*fpe_functions[fpe->type].list_fonts)
+ ((pointer) c->client, fpe, c->current.pattern,
+ c->current.patlen, c->current.max_names - c->names->nnames,
+ c->names);
+
+ if (err == Suspended) {
+ if (!c->slept) {
+ c->slept = TRUE;
+ ClientSleep(client,
+ (ClientSleepProcPtr)doListFontsAndAliases,
+ (pointer) c);
+ }
+ return TRUE;
+ }
+
+ err = BadFontName;
+ }
+ else
+ {
+ /* Start of list_fonts_and_aliases functionality. Modeled
+ after list_fonts_with_info in that it resolves aliases,
+ except that the information collected from FPEs is just
+ names, not font info. Each list_next_font_or_alias()
+ returns either a name into name/namelen or an alias into
+ name/namelen and its target name into resolved/resolvedlen.
+ The code at this level then resolves the alias by polling
+ the FPEs. */
+
+ if (!c->current.list_started) {
+ err = (*fpe_functions[fpe->type].start_list_fonts_and_aliases)
+ ((pointer) c->client, fpe, c->current.pattern,
+ c->current.patlen, c->current.max_names - c->names->nnames,
+ &c->current.private);
+ if (err == Suspended) {
+ if (!c->slept) {
+ ClientSleep(client,
+ (ClientSleepProcPtr)doListFontsAndAliases,
+ (pointer) c);
+ c->slept = TRUE;
+ }
+ return TRUE;
+ }
+ if (err == Successful)
+ c->current.list_started = TRUE;
+ }
+ if (err == Successful) {
+ char *tmpname;
+ name = 0;
+ err = (*fpe_functions[fpe->type].list_next_font_or_alias)
+ ((pointer) c->client, fpe, &name, &namelen, &tmpname,
+ &resolvedlen, c->current.private);
+ if (err == Suspended) {
+ if (!c->slept) {
+ ClientSleep(client,
+ (ClientSleepProcPtr)doListFontsAndAliases,
+ (pointer) c);
+ c->slept = TRUE;
+ }
+ return TRUE;
+ }
+ if (err == FontNameAlias) {
+ if (resolved) xfree(resolved);
+ resolved = (char *) xalloc(resolvedlen + 1);
+ if (resolved)
+ memmove(resolved, tmpname, resolvedlen + 1);
+ }
+ }
+
+ if (err == Successful)
+ {
+ if (c->haveSaved)
+ {
+ if (c->savedName)
+ (void)AddFontNamesName(c->names, c->savedName,
+ c->savedNameLen);
+ }
+ else
+ (void)AddFontNamesName(c->names, name, namelen);
+ }
+
+ /*
+ * When we get an alias back, save our state and reset back to
+ * the start of the FPE looking for the specified name. As
+ * soon as a real font is found for the alias, pop back to the
+ * old state
+ */
+ else if (err == FontNameAlias) {
+ char tmp_pattern[XLFDMAXFONTNAMELEN];
+ /*
+ * when an alias recurses, we need to give
+ * the last FPE a chance to clean up; so we call
+ * it again, and assume that the error returned
+ * is BadFontName, indicating the alias resolution
+ * is complete.
+ */
+ memmove(tmp_pattern, resolved, resolvedlen);
+ if (c->haveSaved)
+ {
+ char *tmpname;
+ int tmpnamelen;
+
+ tmpname = 0;
+ (void) (*fpe_functions[fpe->type].list_next_font_or_alias)
+ ((pointer) c->client, fpe, &tmpname, &tmpnamelen,
+ &tmpname, &tmpnamelen, c->current.private);
+ if (--aliascount <= 0)
+ {
+ err = BadFontName;
+ goto ContBadFontName;
+ }
+ }
+ else
+ {
+ c->saved = c->current;
+ c->haveSaved = TRUE;
+ if (c->savedName)
+ xfree(c->savedName);
+ c->savedName = (char *)xalloc(namelen + 1);
+ if (c->savedName)
+ memmove(c->savedName, name, namelen + 1);
+ c->savedNameLen = namelen;
+ aliascount = 20;
+ }
+ memmove(c->current.pattern, tmp_pattern, resolvedlen);
+ c->current.patlen = resolvedlen;
+ c->current.max_names = c->names->nnames + 1;
+ c->current.current_fpe = -1;
+ c->current.private = 0;
+ err = BadFontName;
+ }
+ }
+ /*
+ * At the end of this FPE, step to the next. If we've finished
+ * processing an alias, pop state back. If we've collected enough
+ * font names, quit.
+ */
+ if (err == BadFontName) {
+ ContBadFontName: ;
+ c->current.list_started = FALSE;
+ c->current.current_fpe++;
+ err = Successful;
+ if (c->haveSaved)
+ {
+ if (c->names->nnames == c->current.max_names ||
+ c->current.current_fpe == c->num_fpes) {
+ c->haveSaved = FALSE;
+ c->current = c->saved;
+ /* Give the saved namelist a chance to clean itself up */
+ continue;
+ }
+ }
+ if (c->names->nnames == c->current.max_names)
+ break;
+ }
+ }
+
+ /*
+ * send the reply
+ */
+ if (err != Successful) {
+ SendErrorToClient(client, X_ListFonts, 0, 0, FontToXError(err));
+ goto bail;
+ }
+
+finish:
+
+ names = c->names;
+ nnames = names->nnames;
+ client = c->client;
+ stringLens = 0;
+ for (i = 0; i < nnames; i++)
+ stringLens += (names->length[i] <= 255) ? names->length[i] : 0;
+
+ reply.type = X_Reply;
+ reply.length = (stringLens + nnames + 3) >> 2;
+ reply.nFonts = nnames;
+ reply.sequenceNumber = client->sequence;
+
+ bufptr = bufferStart = (char *) ALLOCATE_LOCAL(reply.length << 2);
+
+ if (!bufptr && reply.length) {
+ SendErrorToClient(client, X_ListFonts, 0, 0, BadAlloc);
+ goto bail;
+ }
+ /*
+ * since WriteToClient long word aligns things, copy to temp buffer and
+ * write all at once
+ */
+ for (i = 0; i < nnames; i++) {
+ if (names->length[i] > 255)
+ reply.nFonts--;
+ else
+ {
+ *bufptr++ = names->length[i];
+ memmove( bufptr, names->names[i], names->length[i]);
+ bufptr += names->length[i];
+ }
+ }
+ nnames = reply.nFonts;
+ reply.length = (stringLens + nnames + 3) >> 2;
+ client->pSwapReplyFunc = ReplySwapVector[X_ListFonts];
+ WriteSwappedDataToClient(client, sizeof(xListFontsReply), &reply);
+ (void) WriteToClient(client, stringLens + nnames, bufferStart);
+ DEALLOCATE_LOCAL(bufferStart);
+
+bail:
+ if (c->slept)
+ ClientWakeup(client);
+ for (i = 0; i < c->num_fpes; i++)
+ FreeFPE(c->fpe_list[i]);
+ xfree(c->fpe_list);
+ if (c->savedName) xfree(c->savedName);
+ FreeFontNames(names);
+ xfree(c);
+ if (resolved) xfree(resolved);
+ return TRUE;
+}
+
+int
+ListFonts(ClientPtr client, unsigned char *pattern, unsigned length,
+ unsigned max_names)
+{
+ int i;
+ LFclosurePtr c;
+
+ /*
+ * The right error to return here would be BadName, however the
+ * specification does not allow for a Name error on this request.
+ * Perhaps a better solution would be to return a nil list, i.e.
+ * a list containing zero fontnames.
+ */
+ if (length > XLFDMAXFONTNAMELEN)
+ return BadAlloc;
+
+ if (!(c = (LFclosurePtr) xalloc(sizeof *c)))
+ return BadAlloc;
+ c->fpe_list = (FontPathElementPtr *)
+ xalloc(sizeof(FontPathElementPtr) * num_fpes);
+ if (!c->fpe_list) {
+ xfree(c);
+ return BadAlloc;
+ }
+ c->names = MakeFontNamesRecord(max_names < 100 ? max_names : 100);
+ if (!c->names)
+ {
+ xfree(c->fpe_list);
+ xfree(c);
+ return BadAlloc;
+ }
+ memmove( c->current.pattern, pattern, length);
+ for (i = 0; i < num_fpes; i++) {
+ c->fpe_list[i] = font_path_elements[i];
+ UseFPE(c->fpe_list[i]);
+ }
+ c->client = client;
+ c->num_fpes = num_fpes;
+ c->current.patlen = length;
+ c->current.current_fpe = 0;
+ c->current.max_names = max_names;
+ c->current.list_started = FALSE;
+ c->current.private = 0;
+ c->haveSaved = FALSE;
+ c->slept = FALSE;
+ c->savedName = 0;
+ doListFontsAndAliases(client, c);
+ return Success;
+}
+
+int
+doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c)
+{
+ FontPathElementPtr fpe;
+ int err = Successful;
+ char *name;
+ int namelen;
+ int numFonts;
+ FontInfoRec fontInfo,
+ *pFontInfo;
+ xListFontsWithInfoReply *reply;
+ int length;
+ xFontProp *pFP;
+ int i;
+ int aliascount = 0;
+ xListFontsWithInfoReply finalReply;
+
+ if (client->clientGone)
+ {
+ if (c->current.current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current.current_fpe];
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ }
+ err = Successful;
+ goto bail;
+ }
+ client->pSwapReplyFunc = ReplySwapVector[X_ListFontsWithInfo];
+ if (!c->current.patlen)
+ goto finish;
+ while (c->current.current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current.current_fpe];
+ err = Successful;
+ if (!c->current.list_started)
+ {
+ err = (*fpe_functions[fpe->type].start_list_fonts_with_info)
+ (client, fpe, c->current.pattern, c->current.patlen,
+ c->current.max_names, &c->current.private);
+ if (err == Suspended)
+ {
+ if (!c->slept)
+ {
+ ClientSleep(client, (ClientSleepProcPtr)doListFontsWithInfo, c);
+ c->slept = TRUE;
+ }
+ return TRUE;
+ }
+ if (err == Successful)
+ c->current.list_started = TRUE;
+ }
+ if (err == Successful)
+ {
+ name = 0;
+ pFontInfo = &fontInfo;
+ err = (*fpe_functions[fpe->type].list_next_font_with_info)
+ (client, fpe, &name, &namelen, &pFontInfo,
+ &numFonts, c->current.private);
+ if (err == Suspended)
+ {
+ if (!c->slept)
+ {
+ ClientSleep(client,
+ (ClientSleepProcPtr)doListFontsWithInfo,
+ c);
+ c->slept = TRUE;
+ }
+ return TRUE;
+ }
+ }
+ /*
+ * When we get an alias back, save our state and reset back to the
+ * start of the FPE looking for the specified name. As soon as a real
+ * font is found for the alias, pop back to the old state
+ */
+ if (err == FontNameAlias)
+ {
+ /*
+ * when an alias recurses, we need to give
+ * the last FPE a chance to clean up; so we call
+ * it again, and assume that the error returned
+ * is BadFontName, indicating the alias resolution
+ * is complete.
+ */
+ if (c->haveSaved)
+ {
+ char *tmpname;
+ int tmpnamelen;
+ FontInfoPtr tmpFontInfo;
+
+ tmpname = 0;
+ tmpFontInfo = &fontInfo;
+ (void) (*fpe_functions[fpe->type].list_next_font_with_info)
+ (client, fpe, &tmpname, &tmpnamelen, &tmpFontInfo,
+ &numFonts, c->current.private);
+ if (--aliascount <= 0)
+ {
+ err = BadFontName;
+ goto ContBadFontName;
+ }
+ }
+ else
+ {
+ c->saved = c->current;
+ c->haveSaved = TRUE;
+ c->savedNumFonts = numFonts;
+ if (c->savedName)
+ xfree(c->savedName);
+ c->savedName = (char *)xalloc(namelen + 1);
+ if (c->savedName)
+ memmove(c->savedName, name, namelen + 1);
+ aliascount = 20;
+ }
+ memmove(c->current.pattern, name, namelen);
+ c->current.patlen = namelen;
+ c->current.max_names = 1;
+ c->current.current_fpe = 0;
+ c->current.private = 0;
+ c->current.list_started = FALSE;
+ }
+ /*
+ * At the end of this FPE, step to the next. If we've finished
+ * processing an alias, pop state back. If we've sent enough font
+ * names, quit. Always wait for BadFontName to let the FPE
+ * have a chance to clean up.
+ */
+ else if (err == BadFontName)
+ {
+ ContBadFontName: ;
+ c->current.list_started = FALSE;
+ c->current.current_fpe++;
+ err = Successful;
+ if (c->haveSaved)
+ {
+ if (c->current.max_names == 0 ||
+ c->current.current_fpe == c->num_fpes)
+ {
+ c->haveSaved = FALSE;
+ c->saved.max_names -= (1 - c->current.max_names);
+ c->current = c->saved;
+ }
+ }
+ else if (c->current.max_names == 0)
+ break;
+ }
+ else if (err == Successful)
+ {
+ length = sizeof(*reply) + pFontInfo->nprops * sizeof(xFontProp);
+ reply = c->reply;
+ if (c->length < length)
+ {
+ reply = (xListFontsWithInfoReply *) xrealloc(c->reply, length);
+ if (!reply)
+ {
+ err = AllocError;
+ break;
+ }
+ c->reply = reply;
+ c->length = length;
+ }
+ if (c->haveSaved)
+ {
+ numFonts = c->savedNumFonts;
+ name = c->savedName;
+ namelen = strlen(name);
+ }
+ reply->type = X_Reply;
+ reply->length = (sizeof *reply - sizeof(xGenericReply) +
+ pFontInfo->nprops * sizeof(xFontProp) +
+ namelen + 3) >> 2;
+ reply->sequenceNumber = client->sequence;
+ reply->nameLength = namelen;
+ reply->minBounds = pFontInfo->ink_minbounds;
+ reply->maxBounds = pFontInfo->ink_maxbounds;
+ reply->minCharOrByte2 = pFontInfo->firstCol;
+ reply->maxCharOrByte2 = pFontInfo->lastCol;
+ reply->defaultChar = pFontInfo->defaultCh;
+ reply->nFontProps = pFontInfo->nprops;
+ reply->drawDirection = pFontInfo->drawDirection;
+ reply->minByte1 = pFontInfo->firstRow;
+ reply->maxByte1 = pFontInfo->lastRow;
+ reply->allCharsExist = pFontInfo->allExist;
+ reply->fontAscent = pFontInfo->fontAscent;
+ reply->fontDescent = pFontInfo->fontDescent;
+ reply->nReplies = numFonts;
+ pFP = (xFontProp *) (reply + 1);
+ for (i = 0; i < pFontInfo->nprops; i++)
+ {
+ pFP->name = pFontInfo->props[i].name;
+ pFP->value = pFontInfo->props[i].value;
+ pFP++;
+ }
+ WriteSwappedDataToClient(client, length, reply);
+ (void) WriteToClient(client, namelen, name);
+ if (pFontInfo == &fontInfo)
+ {
+ xfree(fontInfo.props);
+ xfree(fontInfo.isStringProp);
+ }
+ --c->current.max_names;
+ }
+ }
+finish:
+ length = sizeof(xListFontsWithInfoReply);
+ bzero((char *) &finalReply, sizeof(xListFontsWithInfoReply));
+ finalReply.type = X_Reply;
+ finalReply.sequenceNumber = client->sequence;
+ finalReply.length = (sizeof(xListFontsWithInfoReply)
+ - sizeof(xGenericReply)) >> 2;
+ WriteSwappedDataToClient(client, length, &finalReply);
+bail:
+ if (c->slept)
+ ClientWakeup(client);
+ for (i = 0; i < c->num_fpes; i++)
+ FreeFPE(c->fpe_list[i]);
+ xfree(c->reply);
+ xfree(c->fpe_list);
+ if (c->savedName) xfree(c->savedName);
+ xfree(c);
+ return TRUE;
+}
+
+int
+StartListFontsWithInfo(ClientPtr client, int length, unsigned char *pattern,
+ int max_names)
+{
+ int i;
+ LFWIclosurePtr c;
+
+ /*
+ * The right error to return here would be BadName, however the
+ * specification does not allow for a Name error on this request.
+ * Perhaps a better solution would be to return a nil list, i.e.
+ * a list containing zero fontnames.
+ */
+ if (length > XLFDMAXFONTNAMELEN)
+ return BadAlloc;
+
+ if (!(c = (LFWIclosurePtr) xalloc(sizeof *c)))
+ goto badAlloc;
+ c->fpe_list = (FontPathElementPtr *)
+ xalloc(sizeof(FontPathElementPtr) * num_fpes);
+ if (!c->fpe_list)
+ {
+ xfree(c);
+ goto badAlloc;
+ }
+ memmove(c->current.pattern, pattern, length);
+ for (i = 0; i < num_fpes; i++)
+ {
+ c->fpe_list[i] = font_path_elements[i];
+ UseFPE(c->fpe_list[i]);
+ }
+ c->client = client;
+ c->num_fpes = num_fpes;
+ c->reply = 0;
+ c->length = 0;
+ c->current.patlen = length;
+ c->current.current_fpe = 0;
+ c->current.max_names = max_names;
+ c->current.list_started = FALSE;
+ c->current.private = 0;
+ c->savedNumFonts = 0;
+ c->haveSaved = FALSE;
+ c->slept = FALSE;
+ c->savedName = 0;
+ doListFontsWithInfo(client, c);
+ return Success;
+badAlloc:
+ return BadAlloc;
+}
+
+#define TextEltHeader 2
+#define FontShiftSize 5
+static XID clearGC[] = { CT_NONE };
+#define clearGCmask (GCClipMask)
+
+int
+doPolyText(ClientPtr client, register PTclosurePtr c)
+{
+ register FontPtr pFont = c->pGC->font, oldpFont;
+ Font fid, oldfid;
+ int err = Success, lgerr; /* err is in X error, not font error, space */
+ enum { NEVER_SLEPT, START_SLEEP, SLEEPING } client_state = NEVER_SLEPT;
+ FontPathElementPtr fpe;
+ GC *origGC = NULL;
+
+ if (client->clientGone)
+ {
+ fpe = c->pGC->font->fpe;
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+
+ if (c->slept)
+ {
+ /* Client has died, but we cannot bail out right now. We
+ need to clean up after the work we did when going to
+ sleep. Setting the drawable pointer to 0 makes this
+ happen without any attempts to render or perform other
+ unnecessary activities. */
+ c->pDraw = (DrawablePtr)0;
+ }
+ else
+ {
+ err = Success;
+ goto bail;
+ }
+ }
+
+ /* Make sure our drawable hasn't disappeared while we slept. */
+ if (c->slept &&
+ c->pDraw &&
+ c->pDraw != (DrawablePtr)SecurityLookupIDByClass(client, c->did,
+ RC_DRAWABLE, SecurityWriteAccess))
+ {
+ /* Our drawable has disappeared. Treat like client died... ask
+ the FPE code to clean up after client and avoid further
+ rendering while we clean up after ourself. */
+ fpe = c->pGC->font->fpe;
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ c->pDraw = (DrawablePtr)0;
+ }
+
+ client_state = c->slept ? SLEEPING : NEVER_SLEPT;
+
+ while (c->endReq - c->pElt > TextEltHeader)
+ {
+ if (*c->pElt == FontChange)
+ {
+ if (c->endReq - c->pElt < FontShiftSize)
+ {
+ err = BadLength;
+ goto bail;
+ }
+
+ oldpFont = pFont;
+ oldfid = fid;
+
+ fid = ((Font)*(c->pElt+4)) /* big-endian */
+ | ((Font)*(c->pElt+3)) << 8
+ | ((Font)*(c->pElt+2)) << 16
+ | ((Font)*(c->pElt+1)) << 24;
+ pFont = (FontPtr)SecurityLookupIDByType(client, fid, RT_FONT,
+ SecurityReadAccess);
+ if (!pFont)
+ {
+ client->errorValue = fid;
+ err = BadFont;
+ /* restore pFont and fid for step 4 (described below) */
+ pFont = oldpFont;
+ fid = oldfid;
+
+ /* If we're in START_SLEEP mode, the following step
+ shortens the request... in the unlikely event that
+ the fid somehow becomes valid before we come through
+ again to actually execute the polytext, which would
+ then mess up our refcounting scheme badly. */
+ c->err = err;
+ c->endReq = c->pElt;
+
+ goto bail;
+ }
+
+ /* Step 3 (described below) on our new font */
+ if (client_state == START_SLEEP)
+ pFont->refcnt++;
+ else
+ {
+ if (pFont != c->pGC->font && c->pDraw)
+ {
+ ChangeGC( c->pGC, GCFont, &fid);
+ ValidateGC(c->pDraw, c->pGC);
+ if (c->reqType == X_PolyText8)
+ c->polyText = (PolyTextPtr) c->pGC->ops->PolyText8;
+ else
+ c->polyText = (PolyTextPtr) c->pGC->ops->PolyText16;
+ }
+
+ /* Undo the refcnt++ we performed when going to sleep */
+ if (client_state == SLEEPING)
+ (void)CloseFont(c->pGC->font, (Font)0);
+ }
+ c->pElt += FontShiftSize;
+ }
+ else /* print a string */
+ {
+ unsigned char *pNextElt;
+ pNextElt = c->pElt + TextEltHeader + (*c->pElt)*c->itemSize;
+ if ( pNextElt > c->endReq)
+ {
+ err = BadLength;
+ goto bail;
+ }
+ if (client_state == START_SLEEP)
+ {
+ c->pElt = pNextElt;
+ continue;
+ }
+ if (c->pDraw)
+ {
+ lgerr = LoadGlyphs(client, c->pGC->font, *c->pElt, c->itemSize,
+ c->pElt + TextEltHeader);
+ }
+ else lgerr = Successful;
+
+ if (lgerr == Suspended)
+ {
+ if (!c->slept) {
+ int len;
+ GC *pGC;
+ PTclosurePtr new_closure;
+
+ /* We're putting the client to sleep. We need to do a few things
+ to ensure successful and atomic-appearing execution of the
+ remainder of the request. First, copy the remainder of the
+ request into a safe malloc'd area. Second, create a scratch GC
+ to use for the remainder of the request. Third, mark all fonts
+ referenced in the remainder of the request to prevent their
+ deallocation. Fourth, make the original GC look like the
+ request has completed... set its font to the final font value
+ from this request. These GC manipulations are for the unlikely
+ (but possible) event that some other client is using the GC.
+ Steps 3 and 4 are performed by running this procedure through
+ the remainder of the request in a special no-render mode
+ indicated by client_state = START_SLEEP. */
+
+ /* Step 1 */
+ /* Allocate a malloc'd closure structure to replace
+ the local one we were passed */
+ new_closure = (PTclosurePtr) xalloc(sizeof(PTclosureRec));
+ if (!new_closure)
+ {
+ err = BadAlloc;
+ goto bail;
+ }
+ *new_closure = *c;
+ c = new_closure;
+
+ len = c->endReq - c->pElt;
+ c->data = (unsigned char *)xalloc(len);
+ if (!c->data)
+ {
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+ memmove(c->data, c->pElt, len);
+ c->pElt = c->data;
+ c->endReq = c->pElt + len;
+
+ /* Step 2 */
+
+ pGC = GetScratchGC(c->pGC->depth, c->pGC->pScreen);
+ if (!pGC)
+ {
+ xfree(c->data);
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+ if ((err = CopyGC(c->pGC, pGC, GCFunction |
+ GCPlaneMask | GCForeground |
+ GCBackground | GCFillStyle |
+ GCTile | GCStipple |
+ GCTileStipXOrigin |
+ GCTileStipYOrigin | GCFont |
+ GCSubwindowMode | GCClipXOrigin |
+ GCClipYOrigin | GCClipMask)) !=
+ Success)
+ {
+ FreeScratchGC(pGC);
+ xfree(c->data);
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+ origGC = c->pGC;
+ c->pGC = pGC;
+ ValidateGC(c->pDraw, c->pGC);
+
+ c->slept = TRUE;
+ ClientSleep(client,
+ (ClientSleepProcPtr)doPolyText,
+ (pointer) c);
+
+ /* Set up to perform steps 3 and 4 */
+ client_state = START_SLEEP;
+ continue; /* on to steps 3 and 4 */
+ }
+ return TRUE;
+ }
+ else if (lgerr != Successful)
+ {
+ err = FontToXError(lgerr);
+ goto bail;
+ }
+ if (c->pDraw)
+ {
+ c->xorg += *((INT8 *)(c->pElt + 1)); /* must be signed */
+ c->xorg = (* c->polyText)(c->pDraw, c->pGC, c->xorg, c->yorg,
+ *c->pElt, c->pElt + TextEltHeader);
+ }
+ c->pElt = pNextElt;
+ }
+ }
+
+bail:
+
+ if (client_state == START_SLEEP)
+ {
+ /* Step 4 */
+ if (pFont != origGC->font)
+ {
+ ChangeGC(origGC, GCFont, &fid);
+ ValidateGC(c->pDraw, origGC);
+ }
+
+ /* restore pElt pointer for execution of remainder of the request */
+ c->pElt = c->data;
+ return TRUE;
+ }
+
+ if (c->err != Success) err = c->err;
+ if (err != Success && c->client != serverClient) {
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !c->pGC->pScreen->myNum)
+#endif
+ SendErrorToClient(c->client, c->reqType, 0, 0, err);
+ }
+ if (c->slept)
+ {
+ ClientWakeup(c->client);
+ ChangeGC(c->pGC, clearGCmask, clearGC);
+
+ /* Unreference the font from the scratch GC */
+ CloseFont(c->pGC->font, (Font)0);
+ c->pGC->font = NullFont;
+
+ FreeScratchGC(c->pGC);
+ xfree(c->data);
+ xfree(c);
+ }
+ return TRUE;
+}
+
+int
+PolyText(ClientPtr client, DrawablePtr pDraw, GC *pGC, unsigned char *pElt,
+ unsigned char *endReq, int xorg, int yorg, int reqType, XID did)
+{
+ PTclosureRec local_closure;
+
+ local_closure.pElt = pElt;
+ local_closure.endReq = endReq;
+ local_closure.client = client;
+ local_closure.pDraw = pDraw;
+ local_closure.xorg = xorg;
+ local_closure.yorg = yorg;
+ if ((local_closure.reqType = reqType) == X_PolyText8)
+ {
+ local_closure.polyText = (PolyTextPtr) pGC->ops->PolyText8;
+ local_closure.itemSize = 1;
+ }
+ else
+ {
+ local_closure.polyText = (PolyTextPtr) pGC->ops->PolyText16;
+ local_closure.itemSize = 2;
+ }
+ local_closure.pGC = pGC;
+ local_closure.did = did;
+ local_closure.err = Success;
+ local_closure.slept = FALSE;
+
+ (void) doPolyText(client, &local_closure);
+ return Success;
+}
+
+
+#undef TextEltHeader
+#undef FontShiftSize
+
+int
+doImageText(ClientPtr client, register ITclosurePtr c)
+{
+ int err = Success, lgerr; /* err is in X error, not font error, space */
+ FontPathElementPtr fpe;
+
+ if (client->clientGone)
+ {
+ fpe = c->pGC->font->fpe;
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ err = Success;
+ goto bail;
+ }
+
+ /* Make sure our drawable hasn't disappeared while we slept. */
+ if (c->slept &&
+ c->pDraw &&
+ c->pDraw != (DrawablePtr)SecurityLookupIDByClass(client, c->did,
+ RC_DRAWABLE, SecurityWriteAccess))
+ {
+ /* Our drawable has disappeared. Treat like client died... ask
+ the FPE code to clean up after client. */
+ fpe = c->pGC->font->fpe;
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ err = Success;
+ goto bail;
+ }
+
+ lgerr = LoadGlyphs(client, c->pGC->font, c->nChars, c->itemSize, c->data);
+ if (lgerr == Suspended)
+ {
+ if (!c->slept) {
+ GC *pGC;
+ unsigned char *data;
+ ITclosurePtr new_closure;
+
+ /* We're putting the client to sleep. We need to
+ save some state. Similar problem to that handled
+ in doPolyText, but much simpler because the
+ request structure is much simpler. */
+
+ new_closure = (ITclosurePtr) xalloc(sizeof(ITclosureRec));
+ if (!new_closure)
+ {
+ err = BadAlloc;
+ goto bail;
+ }
+ *new_closure = *c;
+ c = new_closure;
+
+ data = (unsigned char *)xalloc(c->nChars * c->itemSize);
+ if (!data)
+ {
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+ memmove(data, c->data, c->nChars * c->itemSize);
+ c->data = data;
+
+ pGC = GetScratchGC(c->pGC->depth, c->pGC->pScreen);
+ if (!pGC)
+ {
+ xfree(c->data);
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+ if ((err = CopyGC(c->pGC, pGC, GCFunction | GCPlaneMask |
+ GCForeground | GCBackground | GCFillStyle |
+ GCTile | GCStipple | GCTileStipXOrigin |
+ GCTileStipYOrigin | GCFont |
+ GCSubwindowMode | GCClipXOrigin |
+ GCClipYOrigin | GCClipMask)) != Success)
+ {
+ FreeScratchGC(pGC);
+ xfree(c->data);
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+ c->pGC = pGC;
+ ValidateGC(c->pDraw, c->pGC);
+
+ c->slept = TRUE;
+ ClientSleep(client, (ClientSleepProcPtr)doImageText, (pointer) c);
+ }
+ return TRUE;
+ }
+ else if (lgerr != Successful)
+ {
+ err = FontToXError(lgerr);
+ goto bail;
+ }
+ if (c->pDraw)
+ {
+ (* c->imageText)(c->pDraw, c->pGC, c->xorg, c->yorg,
+ c->nChars, c->data);
+ }
+
+bail:
+
+ if (err != Success && c->client != serverClient) {
+ SendErrorToClient(c->client, c->reqType, 0, 0, err);
+ }
+ if (c->slept)
+ {
+ ClientWakeup(c->client);
+ ChangeGC(c->pGC, clearGCmask, clearGC);
+
+ /* Unreference the font from the scratch GC */
+ CloseFont(c->pGC->font, (Font)0);
+ c->pGC->font = NullFont;
+
+ FreeScratchGC(c->pGC);
+ xfree(c->data);
+ xfree(c);
+ }
+ return TRUE;
+}
+
+int
+ImageText(ClientPtr client, DrawablePtr pDraw, GC *pGC, int nChars,
+ unsigned char *data, int xorg, int yorg, int reqType, XID did)
+{
+ ITclosureRec local_closure;
+
+ local_closure.client = client;
+ local_closure.pDraw = pDraw;
+ local_closure.pGC = pGC;
+ local_closure.nChars = nChars;
+ local_closure.data = data;
+ local_closure.xorg = xorg;
+ local_closure.yorg = yorg;
+ if ((local_closure.reqType = reqType) == X_ImageText8)
+ {
+ local_closure.imageText = (ImageTextPtr) pGC->ops->ImageText8;
+ local_closure.itemSize = 1;
+ }
+ else
+ {
+ local_closure.imageText = (ImageTextPtr) pGC->ops->ImageText16;
+ local_closure.itemSize = 2;
+ }
+ local_closure.did = did;
+ local_closure.slept = FALSE;
+
+ (void) doImageText(client, &local_closure);
+ return Success;
+}
+
+
+/* does the necessary magic to figure out the fpe type */
+static int
+DetermineFPEType(char *pathname)
+{
+ int i;
+
+ for (i = 0; i < num_fpe_types; i++) {
+ if ((*fpe_functions[i].name_check) (pathname))
+ return i;
+ }
+ return -1;
+}
+
+
+static void
+FreeFontPath(FontPathElementPtr *list, int n, Bool force)
+{
+ int i;
+
+ for (i = 0; i < n; i++) {
+ if (force) {
+ /* Sanity check that all refcounts will be 0 by the time
+ we get to the end of the list. */
+ int found = 1; /* the first reference is us */
+ int j;
+ for (j = i+1; j < n; j++) {
+ if (list[j] == list[i])
+ found++;
+ }
+ if (list[i]->refcount != found) {
+ ErrorF("FreeFontPath: FPE \"%.*s\" refcount is %d, should be %d; fixing.\n",
+ list[i]->name_length, list[i]->name,
+ list[i]->refcount, found);
+ list[i]->refcount = found; /* ensure it will get freed */
+ }
+ }
+ FreeFPE(list[i]);
+ }
+ xfree((char *) list);
+}
+
+static FontPathElementPtr
+find_existing_fpe(FontPathElementPtr *list, int num, unsigned char *name, int len)
+{
+ FontPathElementPtr fpe;
+ int i;
+
+ for (i = 0; i < num; i++) {
+ fpe = list[i];
+ if (fpe->name_length == len && memcmp(name, fpe->name, len) == 0)
+ return fpe;
+ }
+ return (FontPathElementPtr) 0;
+}
+
+
+static int
+SetFontPathElements(int npaths, unsigned char *paths, int *bad, Bool persist)
+{
+ int i, err = 0;
+ int valid_paths = 0;
+ unsigned int len;
+ unsigned char *cp = paths;
+ FontPathElementPtr fpe = NULL, *fplist;
+
+ fplist = (FontPathElementPtr *)
+ xalloc(sizeof(FontPathElementPtr) * npaths);
+ if (!fplist) {
+ *bad = 0;
+ return BadAlloc;
+ }
+ for (i = 0; i < num_fpe_types; i++) {
+ if (fpe_functions[i].set_path_hook)
+ (*fpe_functions[i].set_path_hook) ();
+ }
+ for (i = 0; i < npaths; i++)
+ {
+ len = (unsigned int) (*cp++);
+
+ if (len == 0)
+ {
+ if (persist)
+ ErrorF ("Removing empty element from the valid list of fontpaths\n");
+ err = BadValue;
+ }
+ else
+ {
+ /* if it's already in our active list, just reset it */
+ /*
+ * note that this can miss FPE's in limbo -- may be worth catching
+ * them, though it'd muck up refcounting
+ */
+ fpe = find_existing_fpe(font_path_elements, num_fpes, cp, len);
+ if (fpe)
+ {
+ err = (*fpe_functions[fpe->type].reset_fpe) (fpe);
+ if (err == Successful)
+ {
+ UseFPE(fpe);/* since it'll be decref'd later when freed
+ * from the old list */
+ }
+ else
+ fpe = 0;
+ }
+ /* if error or can't do it, act like it's a new one */
+ if (!fpe)
+ {
+ fpe = (FontPathElementPtr) xalloc(sizeof(FontPathElementRec));
+ if (!fpe)
+ {
+ err = BadAlloc;
+ goto bail;
+ }
+ fpe->name = (char *) xalloc(len + 1);
+ if (!fpe->name)
+ {
+ xfree(fpe);
+ err = BadAlloc;
+ goto bail;
+ }
+ fpe->refcount = 1;
+
+ strncpy(fpe->name, (char *) cp, (int) len);
+ fpe->name[len] = '\0';
+ fpe->name_length = len;
+ fpe->type = DetermineFPEType(fpe->name);
+ if (fpe->type == -1)
+ err = BadValue;
+ else
+ err = (*fpe_functions[fpe->type].init_fpe) (fpe);
+ if (err != Successful)
+ {
+ if (persist)
+ {
+ ErrorF("Could not init font path element %s, removing from list!\n",
+ fpe->name);
+ }
+ xfree (fpe->name);
+ xfree (fpe);
+ }
+ }
+ }
+ if (err != Successful)
+ {
+ if (!persist)
+ goto bail;
+ }
+ else
+ {
+ fplist[valid_paths++] = fpe;
+ }
+ cp += len;
+ }
+
+ FreeFontPath(font_path_elements, num_fpes, FALSE);
+ font_path_elements = fplist;
+ if (patternCache)
+ EmptyFontPatternCache(patternCache);
+ num_fpes = valid_paths;
+
+ return Success;
+bail:
+ *bad = i;
+ while (--valid_paths >= 0)
+ FreeFPE(fplist[valid_paths]);
+ xfree(fplist);
+ return FontToXError(err);
+}
+
+/* XXX -- do we need to pass error down to each renderer? */
+int
+SetFontPath(ClientPtr client, int npaths, unsigned char *paths, int *error)
+{
+ int err = Success;
+
+ if (npaths == 0) {
+ if (SetDefaultFontPath(defaultFontPath) != Success)
+ return BadValue;
+ } else {
+ err = SetFontPathElements(npaths, paths, error, FALSE);
+ }
+ return err;
+}
+
+int
+SetDefaultFontPath(char *path)
+{
+ unsigned char *cp,
+ *pp,
+ *nump,
+ *newpath;
+ int num = 1,
+ len,
+ err,
+ size = 0,
+ bad;
+
+ /* get enough for string, plus values -- use up commas */
+ len = strlen(path) + 1;
+ nump = cp = newpath = (unsigned char *) ALLOCATE_LOCAL(len);
+ if (!newpath)
+ return BadAlloc;
+ pp = (unsigned char *) path;
+ cp++;
+ while (*pp) {
+ if (*pp == ',') {
+ *nump = (unsigned char) size;
+ nump = cp++;
+ pp++;
+ num++;
+ size = 0;
+ } else {
+ *cp++ = *pp++;
+ size++;
+ }
+ }
+ *nump = (unsigned char) size;
+
+ err = SetFontPathElements(num, newpath, &bad, TRUE);
+
+ DEALLOCATE_LOCAL(newpath);
+
+ return err;
+}
+
+unsigned char *
+GetFontPath(int *count, int *length)
+{
+ int i;
+ unsigned char *c;
+ int len;
+ FontPathElementPtr fpe;
+
+ len = 0;
+ for (i = 0; i < num_fpes; i++) {
+ fpe = font_path_elements[i];
+ len += fpe->name_length + 1;
+ }
+ font_path_string = (unsigned char *) xrealloc(font_path_string, len);
+ if (!font_path_string)
+ return NULL;
+
+ c = font_path_string;
+ *length = 0;
+ for (i = 0; i < num_fpes; i++) {
+ fpe = font_path_elements[i];
+ *c = fpe->name_length;
+ *length += *c++;
+ memmove(c, fpe->name, fpe->name_length);
+ c += fpe->name_length;
+ }
+ *count = num_fpes;
+ return font_path_string;
+}
+
+int
+LoadGlyphs(ClientPtr client, FontPtr pfont, unsigned nchars, int item_size, unsigned char *data)
+{
+ if (fpe_functions[pfont->fpe->type].load_glyphs)
+ return (*fpe_functions[pfont->fpe->type].load_glyphs)
+ (client, pfont, 0, nchars, item_size, data);
+ else
+ return Successful;
+}
+
+void
+DeleteClientFontStuff(ClientPtr client)
+{
+ int i;
+ FontPathElementPtr fpe;
+
+ for (i = 0; i < num_fpes; i++)
+ {
+ fpe = font_path_elements[i];
+ if (fpe_functions[fpe->type].client_died)
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ }
+}
+
+void
+InitFonts ()
+{
+ patternCache = MakeFontPatternCache();
+
+#ifndef KDRIVESERVER
+ if (screenInfo.numScreens > screenInfo.numVideoScreens) {
+ PrinterFontRegisterFpeFunctions();
+ FontFileCheckRegisterFpeFunctions();
+ check_fs_register_fpe_functions();
+ } else
+#endif
+ {
+#ifdef KDRIVESERVER
+ BuiltinRegisterFpeFunctions();
+#endif
+ FontFileRegisterFpeFunctions();
+#ifndef NOFONTSERVERACCESS
+ fs_register_fpe_functions();
+#endif
+ }
+}
+
+int
+GetDefaultPointSize ()
+{
+ return 120;
+}
+
+
+FontResolutionPtr
+GetClientResolutions (int *num)
+{
+ if (requestingClient && requestingClient->fontResFunc != NULL &&
+ !requestingClient->clientGone)
+ {
+ return (*requestingClient->fontResFunc)(requestingClient, num);
+ }
+ else {
+ static struct _FontResolution res;
+ ScreenPtr pScreen;
+
+ pScreen = screenInfo.screens[0];
+ res.x_resolution = (pScreen->width * 25.4) / pScreen->mmWidth;
+ /*
+ * XXX - we'll want this as long as bitmap instances are prevalent
+ so that we can match them from scalable fonts
+ */
+ if (res.x_resolution < 88)
+ res.x_resolution = 75;
+ else
+ res.x_resolution = 100;
+ res.y_resolution = (pScreen->height * 25.4) / pScreen->mmHeight;
+ if (res.y_resolution < 88)
+ res.y_resolution = 75;
+ else
+ res.y_resolution = 100;
+ res.point_size = 120;
+ *num = 1;
+ return &res;
+ }
+}
+
+/*
+ * returns the type index of the new fpe
+ *
+ * should be called (only once!) by each type of fpe when initialized
+ */
+
+int
+RegisterFPEFunctions(NameCheckFunc name_func,
+ InitFpeFunc init_func,
+ FreeFpeFunc free_func,
+ ResetFpeFunc reset_func,
+ OpenFontFunc open_func,
+ CloseFontFunc close_func,
+ ListFontsFunc list_func,
+ StartLfwiFunc start_lfwi_func,
+ NextLfwiFunc next_lfwi_func,
+ WakeupFpeFunc wakeup_func,
+ ClientDiedFunc client_died,
+ LoadGlyphsFunc load_glyphs,
+ StartLaFunc start_list_alias_func,
+ NextLaFunc next_list_alias_func,
+ SetPathFunc set_path_func)
+{
+ FPEFunctions *new;
+
+ /* grow the list */
+ new = (FPEFunctions *) xrealloc(fpe_functions,
+ (num_fpe_types + 1) * sizeof(FPEFunctions));
+ if (!new)
+ return -1;
+ fpe_functions = new;
+
+ fpe_functions[num_fpe_types].name_check = name_func;
+ fpe_functions[num_fpe_types].open_font = open_func;
+ fpe_functions[num_fpe_types].close_font = close_func;
+ fpe_functions[num_fpe_types].wakeup_fpe = wakeup_func;
+ fpe_functions[num_fpe_types].list_fonts = list_func;
+ fpe_functions[num_fpe_types].start_list_fonts_with_info =
+ start_lfwi_func;
+ fpe_functions[num_fpe_types].list_next_font_with_info =
+ next_lfwi_func;
+ fpe_functions[num_fpe_types].init_fpe = init_func;
+ fpe_functions[num_fpe_types].free_fpe = free_func;
+ fpe_functions[num_fpe_types].reset_fpe = reset_func;
+ fpe_functions[num_fpe_types].client_died = client_died;
+ fpe_functions[num_fpe_types].load_glyphs = load_glyphs;
+ fpe_functions[num_fpe_types].start_list_fonts_and_aliases =
+ start_list_alias_func;
+ fpe_functions[num_fpe_types].list_next_font_or_alias =
+ next_list_alias_func;
+ fpe_functions[num_fpe_types].set_path_hook = set_path_func;
+
+ return num_fpe_types++;
+}
+
+void
+FreeFonts()
+{
+ if (patternCache) {
+ FreeFontPatternCache(patternCache);
+ patternCache = 0;
+ }
+ FreeFontPath(font_path_elements, num_fpes, TRUE);
+ font_path_elements = 0;
+ num_fpes = 0;
+ xfree(fpe_functions);
+ num_fpe_types = 0;
+ fpe_functions = (FPEFunctions *) 0;
+}
+
+/* convenience functions for FS interface */
+
+FontPtr
+find_old_font(XID id)
+{
+ return (FontPtr) SecurityLookupIDByType(NullClient, id, RT_NONE,
+ SecurityUnknownAccess);
+}
+
+Font
+GetNewFontClientID()
+{
+ return FakeClientID(0);
+}
+
+int
+StoreFontClientFont(FontPtr pfont, Font id)
+{
+ return AddResource(id, RT_NONE, (pointer) pfont);
+}
+
+void
+DeleteFontClientID(Font id)
+{
+ FreeResource(id, RT_NONE);
+}
+
+int
+client_auth_generation(ClientPtr client)
+{
+ return 0;
+}
+
+static int fs_handlers_installed = 0;
+static unsigned int last_server_gen;
+
+int
+init_fs_handlers(FontPathElementPtr fpe, BlockHandlerProcPtr block_handler)
+{
+ /* if server has reset, make sure the b&w handlers are reinstalled */
+ if (last_server_gen < serverGeneration) {
+ last_server_gen = serverGeneration;
+ fs_handlers_installed = 0;
+ }
+ if (fs_handlers_installed == 0) {
+
+#ifdef DEBUG
+ fprintf(stderr, "adding FS b & w handlers\n");
+#endif
+
+ if (!RegisterBlockAndWakeupHandlers(block_handler,
+ FontWakeup, (pointer) 0))
+ return AllocError;
+ fs_handlers_installed++;
+ }
+ QueueFontWakeup(fpe);
+ return Successful;
+}
+
+void
+remove_fs_handlers(FontPathElementPtr fpe, BlockHandlerProcPtr block_handler, Bool all)
+{
+ if (all) {
+ /* remove the handlers if no one else is using them */
+ if (--fs_handlers_installed == 0) {
+
+#ifdef DEBUG
+ fprintf(stderr, "removing FS b & w handlers\n");
+#endif
+
+ RemoveBlockAndWakeupHandlers(block_handler, FontWakeup,
+ (pointer) 0);
+ }
+ }
+ RemoveFontWakeup(fpe);
+}
+
+#ifdef DEBUG
+#define GLWIDTHBYTESPADDED(bits,nbytes) \
+ ((nbytes) == 1 ? (((bits)+7)>>3) /* pad to 1 byte */ \
+ :(nbytes) == 2 ? ((((bits)+15)>>3)&~1) /* pad to 2 bytes */ \
+ :(nbytes) == 4 ? ((((bits)+31)>>3)&~3) /* pad to 4 bytes */ \
+ :(nbytes) == 8 ? ((((bits)+63)>>3)&~7) /* pad to 8 bytes */ \
+ : 0)
+
+#define GLYPH_SIZE(ch, nbytes) \
+ GLWIDTHBYTESPADDED((ch)->metrics.rightSideBearing - \
+ (ch)->metrics.leftSideBearing, (nbytes))
+void
+dump_char_ascii(CharInfoPtr cip)
+{
+ int r,
+ l;
+ int bpr;
+ int byte;
+ static unsigned maskTab[] = {
+ (1 << 7), (1 << 6), (1 << 5), (1 << 4),
+ (1 << 3), (1 << 2), (1 << 1), (1 << 0),
+ };
+
+ bpr = GLYPH_SIZE(cip, 4);
+ for (r = 0; r < (cip->metrics.ascent + cip->metrics.descent); r++) {
+ pointer row = (pointer) cip->bits + r * bpr;
+
+ byte = 0;
+ for (l = 0; l <= (cip->metrics.rightSideBearing -
+ cip->metrics.leftSideBearing); l++) {
+ if (maskTab[l & 7] & row[l >> 3])
+ putchar('X');
+ else
+ putchar('.');
+ }
+ putchar('\n');
+ }
+}
+
+#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
new file mode 100644
index 000000000..91e290996
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
@@ -0,0 +1,4827 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/* $XdotOrg: xc/programs/Xserver/dix/events.c,v 1.17 2005/08/25 22:11:04 anholt Exp $ */
+/* $XFree86: xc/programs/Xserver/dix/events.c,v 3.51 2004/01/12 17:04:52 tsi Exp $ */
+/************************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+********************************************************/
+
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+/*****************************************************************
+
+Copyright 2003-2005 Sun Microsystems, Inc.
+
+All rights reserved.
+
+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, and/or sell copies of the Software, and to permit persons
+to whom the Software is furnished to do so, provided that the above
+copyright notice(s) and this permission notice appear in all copies of
+the Software and that both the above copyright notice(s) and this
+permission notice appear in supporting documentation.
+
+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
+OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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.
+
+Except as contained in this notice, the name of a copyright holder
+shall not be used in advertising or otherwise to promote the sale, use
+or other dealings in this Software without prior written authorization
+of the copyright holder.
+
+******************************************************************/
+
+/* $Xorg: events.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "Xlib.h"
+#include "misc.h"
+#include "resource.h"
+#define NEED_EVENTS
+#define NEED_REPLIES
+#include <X11/Xproto.h>
+#include "windowstr.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "cursorstr.h"
+
+#include "dixstruct.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#include "globals.h"
+
+#ifdef XKB
+#include <X11/extensions/XKBsrv.h>
+extern Bool XkbFilterEvents(ClientPtr, int, xEvent *);
+#endif
+
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+
+#ifdef XEVIE
+extern WindowPtr *WindowTable;
+extern int xevieFlag;
+extern int xevieClientIndex;
+extern DeviceIntPtr xeviemouse;
+extern DeviceIntPtr xeviekb;
+extern Mask xevieMask;
+extern Mask xevieFilters[128];
+extern int xevieEventSent;
+extern int xevieKBEventSent;
+int xeviegrabState = 0;
+xEvent *xeviexE;
+#endif
+
+#include <X11/extensions/XIproto.h>
+#include "exevents.h"
+#include "extnsionst.h"
+
+#include "dixevents.h"
+#include "dixgrabs.h"
+#include "../../dix/dispatch.h"
+
+#include "NXlib.h"
+
+#include "Events.h"
+#include "Windows.h"
+#include "Args.h"
+
+extern Display *nxagentDisplay;
+
+extern WindowPtr nxagentLastEnteredWindow;
+
+#define EXTENSION_EVENT_BASE 64
+
+#define NoSuchEvent 0x80000000 /* so doesn't match NoEventMask */
+#define StructureAndSubMask ( StructureNotifyMask | SubstructureNotifyMask )
+#define AllButtonsMask ( \
+ Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask )
+#define MotionMask ( \
+ PointerMotionMask | Button1MotionMask | \
+ Button2MotionMask | Button3MotionMask | Button4MotionMask | \
+ Button5MotionMask | ButtonMotionMask )
+#define PropagateMask ( \
+ KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \
+ MotionMask )
+#define PointerGrabMask ( \
+ ButtonPressMask | ButtonReleaseMask | \
+ EnterWindowMask | LeaveWindowMask | \
+ PointerMotionHintMask | KeymapStateMask | \
+ MotionMask )
+#define AllModifiersMask ( \
+ ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \
+ Mod3Mask | Mod4Mask | Mod5Mask )
+#define AllEventMasks (lastEventMask|(lastEventMask-1))
+/*
+ * The following relies on the fact that the Button<n>MotionMasks are equal
+ * to the corresponding Button<n>Masks from the current modifier/button state.
+ */
+#define Motion_Filter(class) (PointerMotionMask | \
+ (class)->state | (class)->motionMask)
+
+
+#define WID(w) ((w) ? ((w)->drawable.id) : 0)
+
+#define XE_KBPTR (xE->u.keyButtonPointer)
+
+
+#define rClient(obj) (clients[CLIENT_ID((obj)->resource)])
+
+CallbackListPtr EventCallback;
+CallbackListPtr DeviceEventCallback;
+
+#define DNPMCOUNT 8
+
+Mask DontPropagateMasks[DNPMCOUNT];
+static int DontPropagateRefCnts[DNPMCOUNT];
+
+#ifdef DEBUG
+static debug_events = 0;
+#endif
+InputInfo inputInfo;
+
+static struct {
+ QdEventPtr pending, *pendtail;
+ DeviceIntPtr replayDev; /* kludgy rock to put flag for */
+ WindowPtr replayWin; /* ComputeFreezes */
+ Bool playingEvents;
+ TimeStamp time;
+} syncEvents;
+
+/*
+ * The window trace information is used to avoid having to compute all the
+ * windows between the root and the current pointer window each time a button
+ * or key goes down. The grabs on each of those windows must be checked.
+ */
+static WindowPtr *spriteTrace = (WindowPtr *)NULL;
+#define ROOT spriteTrace[0]
+static int spriteTraceSize = 0;
+static int spriteTraceGood;
+
+static struct {
+ CursorPtr current;
+ BoxRec hotLimits; /* logical constraints of hot spot */
+ Bool confined; /* confined to screen */
+#if defined(SHAPE) || defined(PANORAMIX)
+ RegionPtr hotShape; /* additional logical shape constraint */
+#endif
+ BoxRec physLimits; /* physical constraints of hot spot */
+ WindowPtr win; /* window of logical position */
+ HotSpot hot; /* logical pointer position */
+ HotSpot hotPhys; /* physical pointer position */
+#ifdef PANORAMIX
+ ScreenPtr screen; /* all others are in Screen 0 coordinates */
+ RegionRec Reg1; /* Region 1 for confining motion */
+ RegionRec Reg2; /* Region 2 for confining virtual motion */
+ WindowPtr windows[MAXSCREENS];
+ WindowPtr confineWin; /* confine window */
+#endif
+} sprite; /* info about the cursor sprite */
+
+#ifdef XEVIE
+WindowPtr xeviewin;
+HotSpot xeviehot;
+#endif
+
+static void DoEnterLeaveEvents(
+ WindowPtr fromWin,
+ WindowPtr toWin,
+ int mode
+);
+
+static WindowPtr XYToWindow(
+ int x,
+ int y
+);
+
+extern int lastEvent;
+
+static Mask lastEventMask;
+
+#ifdef XINPUT
+extern int DeviceMotionNotify;
+#endif
+
+#define CantBeFiltered NoEventMask
+static Mask filters[128] =
+{
+ NoSuchEvent, /* 0 */
+ NoSuchEvent, /* 1 */
+ KeyPressMask, /* KeyPress */
+ KeyReleaseMask, /* KeyRelease */
+ ButtonPressMask, /* ButtonPress */
+ ButtonReleaseMask, /* ButtonRelease */
+ PointerMotionMask, /* MotionNotify (initial state) */
+ EnterWindowMask, /* EnterNotify */
+ LeaveWindowMask, /* LeaveNotify */
+ FocusChangeMask, /* FocusIn */
+ FocusChangeMask, /* FocusOut */
+ KeymapStateMask, /* KeymapNotify */
+ ExposureMask, /* Expose */
+ CantBeFiltered, /* GraphicsExpose */
+ CantBeFiltered, /* NoExpose */
+ VisibilityChangeMask, /* VisibilityNotify */
+ SubstructureNotifyMask, /* CreateNotify */
+ StructureAndSubMask, /* DestroyNotify */
+ StructureAndSubMask, /* UnmapNotify */
+ StructureAndSubMask, /* MapNotify */
+ SubstructureRedirectMask, /* MapRequest */
+ StructureAndSubMask, /* ReparentNotify */
+ StructureAndSubMask, /* ConfigureNotify */
+ SubstructureRedirectMask, /* ConfigureRequest */
+ StructureAndSubMask, /* GravityNotify */
+ ResizeRedirectMask, /* ResizeRequest */
+ StructureAndSubMask, /* CirculateNotify */
+ SubstructureRedirectMask, /* CirculateRequest */
+ PropertyChangeMask, /* PropertyNotify */
+ CantBeFiltered, /* SelectionClear */
+ CantBeFiltered, /* SelectionRequest */
+ CantBeFiltered, /* SelectionNotify */
+ ColormapChangeMask, /* ColormapNotify */
+ CantBeFiltered, /* ClientMessage */
+ CantBeFiltered /* MappingNotify */
+};
+
+static CARD8 criticalEvents[32] =
+{
+ 0x7c /* key and button events */
+};
+
+#ifdef PANORAMIX
+
+static void ConfineToShape(RegionPtr shape, int *px, int *py);
+static void SyntheticMotion(int x, int y);
+static void PostNewCursor(void);
+
+static Bool
+XineramaSetCursorPosition(
+ int x,
+ int y,
+ Bool generateEvent
+){
+ ScreenPtr pScreen;
+ BoxRec box;
+ int i;
+
+ /* x,y are in Screen 0 coordinates. We need to decide what Screen
+ to send the message too and what the coordinates relative to
+ that screen are. */
+
+ pScreen = sprite.screen;
+ x += panoramiXdataPtr[0].x;
+ y += panoramiXdataPtr[0].y;
+
+ if(!POINT_IN_REGION(pScreen, &XineramaScreenRegions[pScreen->myNum],
+ x, y, &box))
+ {
+ FOR_NSCREENS(i)
+ {
+ if(i == pScreen->myNum)
+ continue;
+ if(POINT_IN_REGION(pScreen, &XineramaScreenRegions[i], x, y, &box))
+ {
+ pScreen = screenInfo.screens[i];
+ break;
+ }
+ }
+ }
+
+ sprite.screen = pScreen;
+ sprite.hotPhys.x = x - panoramiXdataPtr[0].x;
+ sprite.hotPhys.y = y - panoramiXdataPtr[0].y;
+ x -= panoramiXdataPtr[pScreen->myNum].x;
+ y -= panoramiXdataPtr[pScreen->myNum].y;
+
+ return (*pScreen->SetCursorPosition)(pScreen, x, y, generateEvent);
+}
+
+
+static void
+XineramaConstrainCursor(void)
+{
+ ScreenPtr pScreen = sprite.screen;
+ BoxRec newBox = sprite.physLimits;
+
+ /* Translate the constraining box to the screen
+ the sprite is actually on */
+ newBox.x1 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x;
+ newBox.x2 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x;
+ newBox.y1 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
+ newBox.y2 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
+
+ (* pScreen->ConstrainCursor)(pScreen, &newBox);
+}
+
+static void
+XineramaCheckPhysLimits(
+ CursorPtr cursor,
+ Bool generateEvents
+){
+ HotSpot new;
+
+ if (!cursor)
+ return;
+
+ new = sprite.hotPhys;
+
+ /* I don't care what the DDX has to say about it */
+ sprite.physLimits = sprite.hotLimits;
+
+ /* constrain the pointer to those limits */
+ if (new.x < sprite.physLimits.x1)
+ new.x = sprite.physLimits.x1;
+ else
+ if (new.x >= sprite.physLimits.x2)
+ new.x = sprite.physLimits.x2 - 1;
+ if (new.y < sprite.physLimits.y1)
+ new.y = sprite.physLimits.y1;
+ else
+ if (new.y >= sprite.physLimits.y2)
+ new.y = sprite.physLimits.y2 - 1;
+
+ if (sprite.hotShape) /* more work if the shape is a mess */
+ ConfineToShape(sprite.hotShape, &new.x, &new.y);
+
+ if((new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
+ {
+ XineramaSetCursorPosition (new.x, new.y, generateEvents);
+ if (!generateEvents)
+ SyntheticMotion(new.x, new.y);
+ }
+
+ /* Tell DDX what the limits are */
+ XineramaConstrainCursor();
+}
+
+
+static Bool
+XineramaSetWindowPntrs(WindowPtr pWin)
+{
+ if(pWin == WindowTable[0]) {
+ memcpy(sprite.windows, WindowTable,
+ PanoramiXNumScreens*sizeof(WindowPtr));
+ } else {
+ PanoramiXRes *win;
+ int i;
+
+ win = (PanoramiXRes*)LookupIDByType(pWin->drawable.id, XRT_WINDOW);
+
+ if(!win)
+ return FALSE;
+
+ for(i = 0; i < PanoramiXNumScreens; i++) {
+ sprite.windows[i] = LookupIDByType(win->info[i].id, RT_WINDOW);
+ if(!sprite.windows[i]) /* window is being unmapped */
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+static void
+XineramaCheckVirtualMotion(
+ QdEventPtr qe,
+ WindowPtr pWin
+){
+
+ if (qe)
+ {
+ sprite.hot.pScreen = qe->pScreen; /* should always be Screen 0 */
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
+ pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
+ NullWindow;
+ }
+ if (pWin)
+ {
+ int x, y, off_x, off_y, i;
+ BoxRec lims;
+
+ if(!XineramaSetWindowPntrs(pWin))
+ return;
+
+ i = PanoramiXNumScreens - 1;
+
+ REGION_COPY(sprite.screen, &sprite.Reg2,
+ &sprite.windows[i]->borderSize);
+ off_x = panoramiXdataPtr[i].x;
+ off_y = panoramiXdataPtr[i].y;
+
+ while(i--) {
+ x = off_x - panoramiXdataPtr[i].x;
+ y = off_y - panoramiXdataPtr[i].y;
+
+ if(x || y)
+ REGION_TRANSLATE(sprite.screen, &sprite.Reg2, x, y);
+
+ REGION_UNION(sprite.screen, &sprite.Reg2, &sprite.Reg2,
+ &sprite.windows[i]->borderSize);
+
+ off_x = panoramiXdataPtr[i].x;
+ off_y = panoramiXdataPtr[i].y;
+ }
+
+ lims = *REGION_EXTENTS(sprite.screen, &sprite.Reg2);
+
+ if (sprite.hot.x < lims.x1)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = lims.x1;
+ else if (sprite.hot.x >= lims.x2)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = lims.x2 - 1;
+ if (sprite.hot.y < lims.y1)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = lims.y1;
+ else if (sprite.hot.y >= lims.y2)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = lims.y2 - 1;
+
+ if (REGION_NUM_RECTS(&sprite.Reg2) > 1)
+ ConfineToShape(&sprite.Reg2, &sprite.hot.x, &sprite.hot.y);
+
+ if (qe)
+ {
+ qe->pScreen = sprite.hot.pScreen;
+ qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
+ qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
+ }
+ }
+}
+
+
+static Bool
+XineramaCheckMotion(xEvent *xE)
+{
+ WindowPtr prevSpriteWin = sprite.win;
+
+ if (xE && !syncEvents.playingEvents)
+ {
+ /* Motion events entering DIX get translated to Screen 0
+ coordinates. Replayed events have already been
+ translated since they've entered DIX before */
+ XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x -
+ panoramiXdataPtr[0].x;
+ XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y -
+ panoramiXdataPtr[0].y;
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = XE_KBPTR.rootX;
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = XE_KBPTR.rootY;
+ if (sprite.hot.x < sprite.physLimits.x1)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = sprite.physLimits.x1;
+ else if (sprite.hot.x >= sprite.physLimits.x2)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = sprite.physLimits.x2 - 1;
+ if (sprite.hot.y < sprite.physLimits.y1)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = sprite.physLimits.y1;
+ else if (sprite.hot.y >= sprite.physLimits.y2)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = sprite.physLimits.y2 - 1;
+
+ if (sprite.hotShape)
+ ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
+
+ sprite.hotPhys = sprite.hot;
+ if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
+ (sprite.hotPhys.y != XE_KBPTR.rootY))
+ {
+ XineramaSetCursorPosition(
+ sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
+ }
+ XE_KBPTR.rootX = sprite.hot.x;
+ XE_KBPTR.rootY = sprite.hot.y;
+ }
+
+#ifdef XEVIE
+ xeviewin =
+#endif
+ sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
+
+ if (sprite.win != prevSpriteWin)
+ {
+ if (prevSpriteWin != NullWindow) {
+ if (!xE)
+ UpdateCurrentTimeIf();
+ DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
+ }
+ PostNewCursor();
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+static void
+XineramaConfineCursorToWindow(WindowPtr pWin, Bool generateEvents)
+{
+
+ if (syncEvents.playingEvents)
+ {
+ XineramaCheckVirtualMotion((QdEventPtr)NULL, pWin);
+ SyntheticMotion(sprite.hot.x, sprite.hot.y);
+ }
+ else
+ {
+ int x, y, off_x, off_y, i;
+
+ if(!XineramaSetWindowPntrs(pWin))
+ return;
+
+ i = PanoramiXNumScreens - 1;
+
+ REGION_COPY(sprite.screen, &sprite.Reg1,
+ &sprite.windows[i]->borderSize);
+ off_x = panoramiXdataPtr[i].x;
+ off_y = panoramiXdataPtr[i].y;
+
+ while(i--) {
+ x = off_x - panoramiXdataPtr[i].x;
+ y = off_y - panoramiXdataPtr[i].y;
+
+ if(x || y)
+ REGION_TRANSLATE(sprite.screen, &sprite.Reg1, x, y);
+
+ REGION_UNION(sprite.screen, &sprite.Reg1, &sprite.Reg1,
+ &sprite.windows[i]->borderSize);
+
+ off_x = panoramiXdataPtr[i].x;
+ off_y = panoramiXdataPtr[i].y;
+ }
+
+ sprite.hotLimits = *REGION_EXTENTS(sprite.screen, &sprite.Reg1);
+
+ if(REGION_NUM_RECTS(&sprite.Reg1) > 1)
+ sprite.hotShape = &sprite.Reg1;
+ else
+ sprite.hotShape = NullRegion;
+
+ sprite.confined = FALSE;
+ sprite.confineWin = (pWin == WindowTable[0]) ? NullWindow : pWin;
+
+ XineramaCheckPhysLimits(sprite.current, generateEvents);
+ }
+}
+
+
+static void
+XineramaChangeToCursor(CursorPtr cursor)
+{
+ if (cursor != sprite.current)
+ {
+ if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
+ (sprite.current->bits->yhot != cursor->bits->yhot))
+ XineramaCheckPhysLimits(cursor, FALSE);
+ (*sprite.screen->DisplayCursor)(sprite.screen, cursor);
+ FreeCursor(sprite.current, (Cursor)0);
+ sprite.current = cursor;
+ sprite.current->refcnt++;
+ }
+}
+
+
+#endif /* PANORAMIX */
+
+void
+SetMaskForEvent(Mask mask, int event)
+{
+ if ((event < LASTEvent) || (event >= 128))
+ FatalError("SetMaskForEvent: bogus event number");
+ filters[event] = mask;
+}
+
+void
+SetCriticalEvent(int event)
+{
+ if (event >= 128)
+ FatalError("SetCriticalEvent: bogus event number");
+ criticalEvents[event >> 3] |= 1 << (event & 7);
+}
+
+static void
+SyntheticMotion(int x, int y)
+{
+ xEvent xE;
+
+#ifdef PANORAMIX
+ /* Translate back to the sprite screen since processInputProc
+ will translate from sprite screen to screen 0 upon reentry
+ to the DIX layer */
+ if(!noPanoramiXExtension) {
+ x += panoramiXdataPtr[0].x - panoramiXdataPtr[sprite.screen->myNum].x;
+ y += panoramiXdataPtr[0].y - panoramiXdataPtr[sprite.screen->myNum].y;
+ }
+#endif
+ xE.u.keyButtonPointer.rootX = x;
+ xE.u.keyButtonPointer.rootY = y;
+ if (syncEvents.playingEvents)
+ xE.u.keyButtonPointer.time = syncEvents.time.milliseconds;
+ else
+ xE.u.keyButtonPointer.time = currentTime.milliseconds;
+ xE.u.u.type = MotionNotify;
+ (*inputInfo.pointer->public.processInputProc)(&xE, inputInfo.pointer, 1);
+}
+
+#ifdef SHAPE
+static void
+ConfineToShape(RegionPtr shape, int *px, int *py)
+{
+ BoxRec box;
+ int x = *px, y = *py;
+ int incx = 1, incy = 1;
+
+ if (POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box))
+ return;
+ box = *REGION_EXTENTS(sprite.hot.pScreen, shape);
+ /* this is rather crude */
+ do {
+ x += incx;
+ if (x >= box.x2)
+ {
+ incx = -1;
+ x = *px - 1;
+ }
+ else if (x < box.x1)
+ {
+ incx = 1;
+ x = *px;
+ y += incy;
+ if (y >= box.y2)
+ {
+ incy = -1;
+ y = *py - 1;
+ }
+ else if (y < box.y1)
+ return; /* should never get here! */
+ }
+ } while (!POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box));
+ *px = x;
+ *py = y;
+}
+#endif
+
+static void
+CheckPhysLimits(
+ CursorPtr cursor,
+ Bool generateEvents,
+ Bool confineToScreen,
+ ScreenPtr pScreen)
+{
+ HotSpot new;
+
+ if (!cursor)
+ return;
+ new = sprite.hotPhys;
+ if (pScreen)
+ new.pScreen = pScreen;
+ else
+ pScreen = new.pScreen;
+ (*pScreen->CursorLimits) (pScreen, cursor, &sprite.hotLimits,
+ &sprite.physLimits);
+ sprite.confined = confineToScreen;
+ (* pScreen->ConstrainCursor)(pScreen, &sprite.physLimits);
+ if (new.x < sprite.physLimits.x1)
+ new.x = sprite.physLimits.x1;
+ else
+ if (new.x >= sprite.physLimits.x2)
+ new.x = sprite.physLimits.x2 - 1;
+ if (new.y < sprite.physLimits.y1)
+ new.y = sprite.physLimits.y1;
+ else
+ if (new.y >= sprite.physLimits.y2)
+ new.y = sprite.physLimits.y2 - 1;
+#ifdef SHAPE
+ if (sprite.hotShape)
+ ConfineToShape(sprite.hotShape, &new.x, &new.y);
+#endif
+ if ((pScreen != sprite.hotPhys.pScreen) ||
+ (new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
+ {
+ if (pScreen != sprite.hotPhys.pScreen)
+ sprite.hotPhys = new;
+ (*pScreen->SetCursorPosition) (pScreen, new.x, new.y, generateEvents);
+ if (!generateEvents)
+ SyntheticMotion(new.x, new.y);
+ }
+}
+
+static void
+CheckVirtualMotion(
+ register QdEventPtr qe,
+ register WindowPtr pWin)
+{
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ XineramaCheckVirtualMotion(qe, pWin);
+ return;
+ }
+#endif
+ if (qe)
+ {
+ sprite.hot.pScreen = qe->pScreen;
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
+ pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
+ NullWindow;
+ }
+ if (pWin)
+ {
+ BoxRec lims;
+
+ if (sprite.hot.pScreen != pWin->drawable.pScreen)
+ {
+ sprite.hot.pScreen = pWin->drawable.pScreen;
+#ifdef XEVIE
+ xeviehot.x = xeviehot.y = 0;
+#endif
+ sprite.hot.x = sprite.hot.y = 0;
+ }
+ lims = *REGION_EXTENTS(pWin->drawable.pScreen, &pWin->borderSize);
+ if (sprite.hot.x < lims.x1)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = lims.x1;
+ else if (sprite.hot.x >= lims.x2)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = lims.x2 - 1;
+ if (sprite.hot.y < lims.y1)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = lims.y1;
+ else if (sprite.hot.y >= lims.y2)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = lims.y2 - 1;
+#ifdef SHAPE
+ if (wBoundingShape(pWin))
+ ConfineToShape(&pWin->borderSize, &sprite.hot.x, &sprite.hot.y);
+#endif
+ if (qe)
+ {
+ qe->pScreen = sprite.hot.pScreen;
+ qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
+ qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
+ }
+ }
+ ROOT = WindowTable[sprite.hot.pScreen->myNum];
+}
+
+static void
+ConfineCursorToWindow(WindowPtr pWin, Bool generateEvents, Bool confineToScreen)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ XineramaConfineCursorToWindow(pWin, generateEvents);
+ return;
+ }
+#endif
+
+ if (syncEvents.playingEvents)
+ {
+ CheckVirtualMotion((QdEventPtr)NULL, pWin);
+ SyntheticMotion(sprite.hot.x, sprite.hot.y);
+ }
+ else
+ {
+ sprite.hotLimits = *REGION_EXTENTS( pScreen, &pWin->borderSize);
+#ifdef SHAPE
+ sprite.hotShape = wBoundingShape(pWin) ? &pWin->borderSize
+ : NullRegion;
+#endif
+ CheckPhysLimits(sprite.current, generateEvents, confineToScreen,
+ pScreen);
+ }
+}
+
+Bool
+PointerConfinedToScreen()
+{
+ return sprite.confined;
+}
+
+static void
+ChangeToCursor(CursorPtr cursor)
+{
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ XineramaChangeToCursor(cursor);
+ return;
+ }
+#endif
+
+ if (cursor != sprite.current)
+ {
+ if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
+ (sprite.current->bits->yhot != cursor->bits->yhot))
+ CheckPhysLimits(cursor, FALSE, sprite.confined,
+ (ScreenPtr)NULL);
+ (*sprite.hotPhys.pScreen->DisplayCursor) (sprite.hotPhys.pScreen,
+ cursor);
+ FreeCursor(sprite.current, (Cursor)0);
+ sprite.current = cursor;
+ sprite.current->refcnt++;
+ }
+}
+
+/* returns true if b is a descendent of a */
+Bool
+IsParent(register WindowPtr a, register WindowPtr b)
+{
+ for (b = b->parent; b; b = b->parent)
+ if (b == a) return TRUE;
+ return FALSE;
+}
+
+static void
+PostNewCursor(void)
+{
+ register WindowPtr win;
+ register GrabPtr grab = inputInfo.pointer->grab;
+
+ if (syncEvents.playingEvents)
+ return;
+ if (grab)
+ {
+ if (grab->cursor)
+ {
+ ChangeToCursor(grab->cursor);
+ return;
+ }
+ if (IsParent(grab->window, sprite.win))
+ win = sprite.win;
+ else
+ win = grab->window;
+ }
+ else
+ win = sprite.win;
+ for (; win; win = win->parent)
+ if (win->optional && win->optional->cursor != NullCursor)
+ {
+ ChangeToCursor(win->optional->cursor);
+ return;
+ }
+}
+
+WindowPtr
+GetCurrentRootWindow()
+{
+ return ROOT;
+}
+
+WindowPtr
+GetSpriteWindow()
+{
+ return sprite.win;
+}
+
+CursorPtr
+GetSpriteCursor()
+{
+ return sprite.current;
+}
+
+void
+GetSpritePosition(int *px, int *py)
+{
+ *px = sprite.hotPhys.x;
+ *py = sprite.hotPhys.y;
+}
+
+#ifdef PANORAMIX
+int
+XineramaGetCursorScreen()
+{
+ if(!noPanoramiXExtension) {
+ return sprite.screen->myNum;
+ } else {
+ return 0;
+ }
+}
+#endif /* PANORAMIX */
+
+#define TIMESLOP (5 * 60 * 1000) /* 5 minutes */
+
+static void
+MonthChangedOrBadTime(register xEvent *xE)
+{
+ /* If the ddx/OS is careless about not processing timestamped events from
+ * different sources in sorted order, then it's possible for time to go
+ * backwards when it should not. Here we ensure a decent time.
+ */
+ if ((currentTime.milliseconds - XE_KBPTR.time) > TIMESLOP)
+ currentTime.months++;
+ else
+ XE_KBPTR.time = currentTime.milliseconds;
+}
+
+#define NoticeTime(xE) { \
+ if ((xE)->u.keyButtonPointer.time < currentTime.milliseconds) \
+ MonthChangedOrBadTime(xE); \
+ currentTime.milliseconds = (xE)->u.keyButtonPointer.time; \
+ lastDeviceEventTime = currentTime; }
+
+void
+NoticeEventTime(register xEvent *xE)
+{
+ if (!syncEvents.playingEvents)
+ NoticeTime(xE);
+}
+
+/**************************************************************************
+ * The following procedures deal with synchronous events *
+ **************************************************************************/
+
+void
+EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count)
+{
+ register QdEventPtr tail = *syncEvents.pendtail;
+ register QdEventPtr qe;
+ xEvent *qxE;
+
+ NoticeTime(xE);
+
+#ifdef XKB
+ /* Fix for key repeating bug. */
+ if (device->key != NULL && device->key->xkbInfo != NULL &&
+ xE->u.u.type == KeyRelease)
+ AccessXCancelRepeatKey(device->key->xkbInfo, xE->u.u.detail);
+#endif
+
+ if (DeviceEventCallback)
+ {
+ DeviceEventInfoRec eventinfo;
+ /* The RECORD spec says that the root window field of motion events
+ * must be valid. At this point, it hasn't been filled in yet, so
+ * we do it here. The long expression below is necessary to get
+ * the current root window; the apparently reasonable alternative
+ * GetCurrentRootWindow()->drawable.id doesn't give you the right
+ * answer on the first motion event after a screen change because
+ * the data that GetCurrentRootWindow relies on hasn't been
+ * updated yet.
+ */
+ if (xE->u.u.type == MotionNotify)
+ XE_KBPTR.root =
+ WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
+ eventinfo.events = xE;
+ eventinfo.count = count;
+ CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+ }
+ if (xE->u.u.type == MotionNotify)
+ {
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x -
+ panoramiXdataPtr[0].x;
+ XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y -
+ panoramiXdataPtr[0].y;
+ }
+#endif
+ sprite.hotPhys.x = XE_KBPTR.rootX;
+ sprite.hotPhys.y = XE_KBPTR.rootY;
+ /* do motion compression */
+ if (tail &&
+ (tail->event->u.u.type == MotionNotify) &&
+ (tail->pScreen == sprite.hotPhys.pScreen))
+ {
+ tail->event->u.keyButtonPointer.rootX = sprite.hotPhys.x;
+ tail->event->u.keyButtonPointer.rootY = sprite.hotPhys.y;
+ tail->event->u.keyButtonPointer.time = XE_KBPTR.time;
+ tail->months = currentTime.months;
+ return;
+ }
+ }
+ qe = (QdEventPtr)xalloc(sizeof(QdEventRec) + (count * sizeof(xEvent)));
+ if (!qe)
+ return;
+ qe->next = (QdEventPtr)NULL;
+ qe->device = device;
+ qe->pScreen = sprite.hotPhys.pScreen;
+ qe->months = currentTime.months;
+ qe->event = (xEvent *)(qe + 1);
+ qe->evcount = count;
+ for (qxE = qe->event; --count >= 0; qxE++, xE++)
+ *qxE = *xE;
+ if (tail)
+ syncEvents.pendtail = &tail->next;
+ *syncEvents.pendtail = qe;
+}
+
+static void
+PlayReleasedEvents(void)
+{
+ register QdEventPtr *prev, qe;
+ register DeviceIntPtr dev;
+
+ prev = &syncEvents.pending;
+ while ( (qe = *prev) )
+ {
+ if (!qe->device->sync.frozen)
+ {
+ *prev = qe->next;
+ if (*syncEvents.pendtail == *prev)
+ syncEvents.pendtail = prev;
+ if (qe->event->u.u.type == MotionNotify)
+ CheckVirtualMotion(qe, NullWindow);
+ syncEvents.time.months = qe->months;
+ syncEvents.time.milliseconds = qe->event->u.keyButtonPointer.time;
+#ifdef PANORAMIX
+ /* Translate back to the sprite screen since processInputProc
+ will translate from sprite screen to screen 0 upon reentry
+ to the DIX layer */
+ if(!noPanoramiXExtension) {
+ qe->event->u.keyButtonPointer.rootX +=
+ panoramiXdataPtr[0].x -
+ panoramiXdataPtr[sprite.screen->myNum].x;
+ qe->event->u.keyButtonPointer.rootY +=
+ panoramiXdataPtr[0].y -
+ panoramiXdataPtr[sprite.screen->myNum].y;
+ }
+#endif
+ (*qe->device->public.processInputProc)(qe->event, qe->device,
+ qe->evcount);
+ xfree(qe);
+ for (dev = inputInfo.devices; dev && dev->sync.frozen; dev = dev->next)
+ ;
+ if (!dev)
+ break;
+ /* Playing the event may have unfrozen another device. */
+ /* So to play it safe, restart at the head of the queue */
+ prev = &syncEvents.pending;
+ }
+ else
+ prev = &qe->next;
+ }
+}
+
+static void
+FreezeThaw(register DeviceIntPtr dev, Bool frozen)
+{
+ dev->sync.frozen = frozen;
+ if (frozen)
+ dev->public.processInputProc = dev->public.enqueueInputProc;
+ else
+ dev->public.processInputProc = dev->public.realInputProc;
+}
+
+void
+ComputeFreezes()
+{
+ register DeviceIntPtr replayDev = syncEvents.replayDev;
+ register int i;
+ WindowPtr w;
+ register xEvent *xE;
+ int count;
+ GrabPtr grab;
+ register DeviceIntPtr dev;
+
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ FreezeThaw(dev, dev->sync.other || (dev->sync.state >= FROZEN));
+ if (syncEvents.playingEvents || (!replayDev && !syncEvents.pending))
+ return;
+ syncEvents.playingEvents = TRUE;
+ if (replayDev)
+ {
+ xE = replayDev->sync.event;
+ count = replayDev->sync.evcount;
+ syncEvents.replayDev = (DeviceIntPtr)NULL;
+
+ w = XYToWindow( XE_KBPTR.rootX, XE_KBPTR.rootY);
+ for (i = 0; i < spriteTraceGood; i++)
+ {
+ if (syncEvents.replayWin == spriteTrace[i])
+ {
+ if (!CheckDeviceGrabs(replayDev, xE, i+1, count)) {
+ if (replayDev->focus)
+ DeliverFocusedEvent(replayDev, xE, w, count);
+ else
+ DeliverDeviceEvents(w, xE, NullGrab, NullWindow,
+ replayDev, count);
+ }
+ goto playmore;
+ }
+ }
+ /* must not still be in the same stack */
+ if (replayDev->focus)
+ DeliverFocusedEvent(replayDev, xE, w, count);
+ else
+ DeliverDeviceEvents(w, xE, NullGrab, NullWindow, replayDev, count);
+ }
+playmore:
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (!dev->sync.frozen)
+ {
+ PlayReleasedEvents();
+ break;
+ }
+ }
+ syncEvents.playingEvents = FALSE;
+ /* the following may have been skipped during replay, so do it now */
+ if ((grab = inputInfo.pointer->grab) && grab->confineTo)
+ {
+ if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+ sprite.hotPhys.x = sprite.hotPhys.y = 0;
+ ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+ }
+ else
+ ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
+ TRUE, FALSE);
+ PostNewCursor();
+}
+
+#ifdef RANDR
+void
+ScreenRestructured (ScreenPtr pScreen)
+{
+ GrabPtr grab;
+
+ if ((grab = inputInfo.pointer->grab) && grab->confineTo)
+ {
+ if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+ sprite.hotPhys.x = sprite.hotPhys.y = 0;
+ ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+ }
+ else
+ ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
+ TRUE, FALSE);
+}
+#endif
+
+void
+CheckGrabForSyncs(register DeviceIntPtr thisDev, Bool thisMode, Bool otherMode)
+{
+ register GrabPtr grab = thisDev->grab;
+ register DeviceIntPtr dev;
+
+ if (thisMode == GrabModeSync)
+ thisDev->sync.state = FROZEN_NO_EVENT;
+ else
+ { /* free both if same client owns both */
+ thisDev->sync.state = THAWED;
+ if (thisDev->sync.other &&
+ (CLIENT_BITS(thisDev->sync.other->resource) ==
+ CLIENT_BITS(grab->resource)))
+ thisDev->sync.other = NullGrab;
+ }
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev != thisDev)
+ {
+ if (otherMode == GrabModeSync)
+ dev->sync.other = grab;
+ else
+ { /* free both if same client owns both */
+ if (dev->sync.other &&
+ (CLIENT_BITS(dev->sync.other->resource) ==
+ CLIENT_BITS(grab->resource)))
+ dev->sync.other = NullGrab;
+ }
+ }
+ }
+ ComputeFreezes();
+}
+
+void
+ActivatePointerGrab(register DeviceIntPtr mouse, register GrabPtr grab,
+ TimeStamp time, Bool autoGrab)
+{
+ WindowPtr oldWin = (mouse->grab) ? mouse->grab->window
+ : sprite.win;
+
+ if (grab->confineTo)
+ {
+ if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+ sprite.hotPhys.x = sprite.hotPhys.y = 0;
+ ConfineCursorToWindow(grab->confineTo, FALSE, TRUE);
+ }
+ DoEnterLeaveEvents(oldWin, grab->window, NotifyGrab);
+ mouse->valuator->motionHintWindow = NullWindow;
+ if (syncEvents.playingEvents)
+ mouse->grabTime = syncEvents.time;
+ else
+ mouse->grabTime = time;
+ if (grab->cursor)
+ grab->cursor->refcnt++;
+ mouse->activeGrab = *grab;
+ mouse->grab = &mouse->activeGrab;
+ mouse->fromPassiveGrab = autoGrab;
+ PostNewCursor();
+ CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
+
+ #ifdef NXAGENT_SERVER
+
+ /*
+ * If grab is synchronous, events are delivered to clients only if they send
+ * an AllowEvent request. If mode field in AllowEvent request is SyncPointer, the
+ * delivered event is saved in a queue and replayed later, when grab is released.
+ * We should export sync grab to X as async in order to avoid events to be
+ * queued twice, in the agent and in the X server. This solution have a drawback:
+ * replayed events are not delivered to that application that are not clients of
+ * the agent.
+ * A different solution could be to make the grab asynchronous in the agent and
+ * to export it as synchronous. But this seems to be less safe.
+ *
+ * To make internal grab asynchronous, change previous line as follows.
+ *
+ * if (nxagentOption(Rootless))
+ * {
+ * CheckGrabForSyncs(mouse, GrabModeAsync, (Bool)grab->keyboardMode);
+ * }
+ * else
+ * {
+ * CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
+ * }
+ */
+
+ if (nxagentOption(Rootless) == 1)
+ {
+ /*
+ * FIXME: We should use the correct value
+ * for the cursor. Temporarily we set it
+ * to None.
+ */
+
+ int resource = nxagentWaitForResource(NXGetCollectGrabPointerResource,
+ nxagentCollectGrabPointerPredicate);
+
+ NXCollectGrabPointer(nxagentDisplay, resource, nxagentWindow(grab -> window),
+ 1, grab -> eventMask & PointerGrabMask,
+ GrabModeAsync, GrabModeAsync, (grab -> confineTo) ?
+ nxagentWindow(grab -> confineTo) : None,
+ None, CurrentTime);
+ }
+
+ #endif
+}
+
+void
+DeactivatePointerGrab(register DeviceIntPtr mouse)
+{
+ register GrabPtr grab = mouse->grab;
+ register DeviceIntPtr dev;
+
+ mouse->valuator->motionHintWindow = NullWindow;
+ mouse->grab = NullGrab;
+ mouse->sync.state = NOT_GRABBED;
+ mouse->fromPassiveGrab = FALSE;
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->sync.other == grab)
+ dev->sync.other = NullGrab;
+ }
+ DoEnterLeaveEvents(grab->window, sprite.win, NotifyUngrab);
+ if (grab->confineTo)
+ ConfineCursorToWindow(ROOT, FALSE, FALSE);
+ PostNewCursor();
+ if (grab->cursor)
+ FreeCursor(grab->cursor, (Cursor)0);
+ ComputeFreezes();
+
+ #ifdef NXAGENT_SERVER
+
+ if (nxagentOption(Rootless) == 1)
+ {
+ XUngrabPointer(nxagentDisplay, CurrentTime);
+
+ if (sprite.win == ROOT)
+ {
+ mouse -> button -> state &=
+ ~(Button1Mask | Button2Mask | Button3Mask |
+ Button4Mask | Button5Mask);
+ }
+ }
+
+ #endif
+}
+
+void
+ActivateKeyboardGrab(register DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, Bool passive)
+{
+ WindowPtr oldWin;
+
+ if (keybd->grab)
+ oldWin = keybd->grab->window;
+ else if (keybd->focus)
+ oldWin = keybd->focus->win;
+ else
+ oldWin = sprite.win;
+ if (oldWin == FollowKeyboardWin)
+ oldWin = inputInfo.keyboard->focus->win;
+ if (keybd->valuator)
+ keybd->valuator->motionHintWindow = NullWindow;
+ DoFocusEvents(keybd, oldWin, grab->window, NotifyGrab);
+ if (syncEvents.playingEvents)
+ keybd->grabTime = syncEvents.time;
+ else
+ keybd->grabTime = time;
+ keybd->activeGrab = *grab;
+ keybd->grab = &keybd->activeGrab;
+ keybd->fromPassiveGrab = passive;
+ CheckGrabForSyncs(keybd, (Bool)grab->keyboardMode, (Bool)grab->pointerMode);
+}
+
+void
+DeactivateKeyboardGrab(register DeviceIntPtr keybd)
+{
+ register GrabPtr grab = keybd->grab;
+ register DeviceIntPtr dev;
+ register WindowPtr focusWin = keybd->focus ? keybd->focus->win
+ : sprite.win;
+
+ if (focusWin == FollowKeyboardWin)
+ focusWin = inputInfo.keyboard->focus->win;
+ if (keybd->valuator)
+ keybd->valuator->motionHintWindow = NullWindow;
+ keybd->grab = NullGrab;
+ keybd->sync.state = NOT_GRABBED;
+ keybd->fromPassiveGrab = FALSE;
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->sync.other == grab)
+ dev->sync.other = NullGrab;
+ }
+ DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab);
+ ComputeFreezes();
+}
+
+void
+AllowSome(ClientPtr client, TimeStamp time, DeviceIntPtr thisDev, int newState)
+{
+ Bool thisGrabbed, otherGrabbed, othersFrozen, thisSynced;
+ TimeStamp grabTime;
+ register DeviceIntPtr dev;
+
+ thisGrabbed = thisDev->grab && SameClient(thisDev->grab, client);
+ thisSynced = FALSE;
+ otherGrabbed = FALSE;
+ othersFrozen = TRUE;
+ grabTime = thisDev->grabTime;
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev == thisDev)
+ continue;
+ if (dev->grab && SameClient(dev->grab, client))
+ {
+ if (!(thisGrabbed || otherGrabbed) ||
+ (CompareTimeStamps(dev->grabTime, grabTime) == LATER))
+ grabTime = dev->grabTime;
+ otherGrabbed = TRUE;
+ if (thisDev->sync.other == dev->grab)
+ thisSynced = TRUE;
+ if (dev->sync.state < FROZEN)
+ othersFrozen = FALSE;
+ }
+ else if (!dev->sync.other || !SameClient(dev->sync.other, client))
+ othersFrozen = FALSE;
+ }
+ if (!((thisGrabbed && thisDev->sync.state >= FROZEN) || thisSynced))
+ return;
+ if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, grabTime) == EARLIER))
+ return;
+ switch (newState)
+ {
+ case THAWED: /* Async */
+ if (thisGrabbed)
+ thisDev->sync.state = THAWED;
+ if (thisSynced)
+ thisDev->sync.other = NullGrab;
+ ComputeFreezes();
+ break;
+ case FREEZE_NEXT_EVENT: /* Sync */
+ if (thisGrabbed)
+ {
+ thisDev->sync.state = FREEZE_NEXT_EVENT;
+ if (thisSynced)
+ thisDev->sync.other = NullGrab;
+ ComputeFreezes();
+ }
+ break;
+ case THAWED_BOTH: /* AsyncBoth */
+ if (othersFrozen)
+ {
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->grab && SameClient(dev->grab, client))
+ dev->sync.state = THAWED;
+ if (dev->sync.other && SameClient(dev->sync.other, client))
+ dev->sync.other = NullGrab;
+ }
+ ComputeFreezes();
+ }
+ break;
+ case FREEZE_BOTH_NEXT_EVENT: /* SyncBoth */
+ if (othersFrozen)
+ {
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->grab && SameClient(dev->grab, client))
+ dev->sync.state = FREEZE_BOTH_NEXT_EVENT;
+ if (dev->sync.other && SameClient(dev->sync.other, client))
+ dev->sync.other = NullGrab;
+ }
+ ComputeFreezes();
+ }
+ break;
+ case NOT_GRABBED: /* Replay */
+ if (thisGrabbed && thisDev->sync.state == FROZEN_WITH_EVENT)
+ {
+ if (thisSynced)
+ thisDev->sync.other = NullGrab;
+ syncEvents.replayDev = thisDev;
+ syncEvents.replayWin = thisDev->grab->window;
+ (*thisDev->DeactivateGrab)(thisDev);
+ syncEvents.replayDev = (DeviceIntPtr)NULL;
+ }
+ break;
+ case THAW_OTHERS: /* AsyncOthers */
+ if (othersFrozen)
+ {
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev == thisDev)
+ continue;
+ if (dev->grab && SameClient(dev->grab, client))
+ dev->sync.state = THAWED;
+ if (dev->sync.other && SameClient(dev->sync.other, client))
+ dev->sync.other = NullGrab;
+ }
+ ComputeFreezes();
+ }
+ break;
+ }
+}
+
+int
+ProcAllowEvents(register ClientPtr client)
+{
+ TimeStamp time;
+ DeviceIntPtr mouse = inputInfo.pointer;
+ DeviceIntPtr keybd = inputInfo.keyboard;
+ REQUEST(xAllowEventsReq);
+
+ REQUEST_SIZE_MATCH(xAllowEventsReq);
+ time = ClientTimeToServerTime(stuff->time);
+ switch (stuff->mode)
+ {
+ case ReplayPointer:
+ AllowSome(client, time, mouse, NOT_GRABBED);
+ break;
+ case SyncPointer:
+ AllowSome(client, time, mouse, FREEZE_NEXT_EVENT);
+ break;
+ case AsyncPointer:
+ AllowSome(client, time, mouse, THAWED);
+ break;
+ case ReplayKeyboard:
+ AllowSome(client, time, keybd, NOT_GRABBED);
+ break;
+ case SyncKeyboard:
+ AllowSome(client, time, keybd, FREEZE_NEXT_EVENT);
+ break;
+ case AsyncKeyboard:
+ AllowSome(client, time, keybd, THAWED);
+ break;
+ case SyncBoth:
+ AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT);
+ break;
+ case AsyncBoth:
+ AllowSome(client, time, keybd, THAWED_BOTH);
+ break;
+ default:
+ client->errorValue = stuff->mode;
+ return BadValue;
+ }
+
+ /*
+ * This is not necessary if we export grab to X as asynchronous.
+ *
+ * if (nxagentOption(Rootless) && stuff -> mode != ReplayKeyboard &&
+ * stuff -> mode != SyncKeyboard && stuff -> mode != AsyncKeyboard)
+ * {
+ * XAllowEvents(nxagentDisplay, stuff -> mode, CurrentTime);
+ * }
+ */
+
+ return Success;
+}
+
+void
+ReleaseActiveGrabs(ClientPtr client)
+{
+ register DeviceIntPtr dev;
+ Bool done;
+
+ /* XXX CloseDownClient should remove passive grabs before
+ * releasing active grabs.
+ */
+ do {
+ done = TRUE;
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->grab && SameClient(dev->grab, client))
+ {
+ (*dev->DeactivateGrab)(dev);
+ done = FALSE;
+ }
+ }
+ } while (!done);
+}
+
+/**************************************************************************
+ * The following procedures deal with delivering events *
+ **************************************************************************/
+
+int
+TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
+ Mask filter, GrabPtr grab)
+{
+ int i;
+ int type;
+
+#ifdef DEBUG
+ if (debug_events) ErrorF(
+ "Event([%d, %d], mask=0x%x), client=%d",
+ pEvents->u.u.type, pEvents->u.u.detail, mask, client->index);
+#endif
+ if ((client) && (client != serverClient) && (!client->clientGone) &&
+ ((filter == CantBeFiltered) || (mask & filter)))
+ {
+ if (grab && !SameClient(grab, client))
+ return -1; /* don't send, but notify caller */
+ type = pEvents->u.u.type;
+ if (type == MotionNotify)
+ {
+ if (mask & PointerMotionHintMask)
+ {
+ if (WID(inputInfo.pointer->valuator->motionHintWindow) ==
+ pEvents->u.keyButtonPointer.event)
+ {
+#ifdef DEBUG
+ if (debug_events) ErrorF("\n");
+ fprintf(stderr,"motionHintWindow == keyButtonPointer.event\n");
+#endif
+ return 1; /* don't send, but pretend we did */
+ }
+ pEvents->u.u.detail = NotifyHint;
+ }
+ else
+ {
+ pEvents->u.u.detail = NotifyNormal;
+ }
+ }
+#ifdef XINPUT
+ else
+ {
+ if ((type == DeviceMotionNotify) &&
+ MaybeSendDeviceMotionNotifyHint
+ ((deviceKeyButtonPointer*)pEvents, mask) != 0)
+ return 1;
+ }
+#endif
+ type &= 0177;
+ if (type != KeymapNotify)
+ {
+ /* all extension events must have a sequence number */
+ for (i = 0; i < count; i++)
+ pEvents[i].u.u.sequenceNumber = client->sequence;
+ }
+
+ if (BitIsOn(criticalEvents, type))
+ {
+#ifdef SMART_SCHEDULE
+ if (client->smart_priority < SMART_MAX_PRIORITY)
+ client->smart_priority++;
+#endif
+ SetCriticalOutputPending();
+ }
+
+ WriteEventsToClient(client, count, pEvents);
+#ifdef DEBUG
+ if (debug_events) ErrorF( " delivered\n");
+#endif
+ return 1;
+ }
+ else
+ {
+#ifdef DEBUG
+ if (debug_events) ErrorF("\n");
+#endif
+ return 0;
+ }
+}
+
+int
+DeliverEventsToWindow(register WindowPtr pWin, xEvent *pEvents, int count,
+ Mask filter, GrabPtr grab, int mskidx)
+{
+ int deliveries = 0, nondeliveries = 0;
+ int attempt;
+ register InputClients *other;
+ ClientPtr client = NullClient;
+ Mask deliveryMask = 0; /* If a grab occurs due to a button press, then
+ this mask is the mask of the grab. */
+ int type = pEvents->u.u.type;
+
+ /* CantBeFiltered means only window owner gets the event */
+ if ((filter == CantBeFiltered) || !(type & EXTENSION_EVENT_BASE))
+ {
+ /* if nobody ever wants to see this event, skip some work */
+ if (filter != CantBeFiltered &&
+ !((wOtherEventMasks(pWin)|pWin->eventMask) & filter))
+ return 0;
+ if ( (attempt = TryClientEvents(wClient(pWin), pEvents, count,
+ pWin->eventMask, filter, grab)) )
+ {
+ if (attempt > 0)
+ {
+ deliveries++;
+ client = wClient(pWin);
+ deliveryMask = pWin->eventMask;
+ } else
+ nondeliveries--;
+ }
+ }
+ if (filter != CantBeFiltered)
+ {
+ if (type & EXTENSION_EVENT_BASE)
+ {
+ OtherInputMasks *inputMasks;
+
+ inputMasks = wOtherInputMasks(pWin);
+ if (!inputMasks ||
+ !(inputMasks->inputEvents[mskidx] & filter))
+ return 0;
+ other = inputMasks->inputClients;
+ }
+ else
+ other = (InputClients *)wOtherClients(pWin);
+ for (; other; other = other->next)
+ {
+ if ( (attempt = TryClientEvents(rClient(other), pEvents, count,
+ other->mask[mskidx], filter, grab)) )
+ {
+ if (attempt > 0)
+ {
+ deliveries++;
+ client = rClient(other);
+ deliveryMask = other->mask[mskidx];
+ } else
+ nondeliveries--;
+ }
+ }
+ }
+ if ((type == ButtonPress) && deliveries && (!grab))
+ {
+ GrabRec tempGrab;
+
+ tempGrab.device = inputInfo.pointer;
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.window = pWin;
+ tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
+ tempGrab.eventMask = deliveryMask;
+ tempGrab.keyboardMode = GrabModeAsync;
+ tempGrab.pointerMode = GrabModeAsync;
+ tempGrab.confineTo = NullWindow;
+ tempGrab.cursor = NullCursor;
+ (*inputInfo.pointer->ActivateGrab)(inputInfo.pointer, &tempGrab,
+ currentTime, TRUE);
+ }
+ else if ((type == MotionNotify) && deliveries)
+ inputInfo.pointer->valuator->motionHintWindow = pWin;
+#ifdef XINPUT
+ else
+ {
+ if (((type == DeviceMotionNotify)
+#ifdef XKB
+ || (type == DeviceButtonPress)
+#endif
+ ) && deliveries)
+ CheckDeviceGrabAndHintWindow (pWin, type,
+ (deviceKeyButtonPointer*) pEvents,
+ grab, client, deliveryMask);
+ }
+#endif
+ if (deliveries)
+ return deliveries;
+ return nondeliveries;
+}
+
+/* If the event goes to dontClient, don't send it and return 0. if
+ send works, return 1 or if send didn't work, return 2.
+ Only works for core events.
+*/
+
+#ifdef PANORAMIX
+static int
+XineramaTryClientEventsResult(
+ ClientPtr client,
+ GrabPtr grab,
+ Mask mask,
+ Mask filter
+){
+ if ((client) && (client != serverClient) && (!client->clientGone) &&
+ ((filter == CantBeFiltered) || (mask & filter)))
+ {
+ if (grab && !SameClient(grab, client)) return -1;
+ else return 1;
+ }
+ return 0;
+}
+#endif
+
+int
+MaybeDeliverEventsToClient(register WindowPtr pWin, xEvent *pEvents,
+ int count, Mask filter, ClientPtr dontClient)
+{
+ register OtherClients *other;
+
+
+ if (pWin->eventMask & filter)
+ {
+ if (wClient(pWin) == dontClient)
+ return 0;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
+ return XineramaTryClientEventsResult(
+ wClient(pWin), NullGrab, pWin->eventMask, filter);
+#endif
+ return TryClientEvents(wClient(pWin), pEvents, count,
+ pWin->eventMask, filter, NullGrab);
+ }
+ for (other = wOtherClients(pWin); other; other = other->next)
+ {
+ if (other->mask & filter)
+ {
+ if (SameClient(other, dontClient))
+ return 0;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
+ return XineramaTryClientEventsResult(
+ rClient(other), NullGrab, other->mask, filter);
+#endif
+ return TryClientEvents(rClient(other), pEvents, count,
+ other->mask, filter, NullGrab);
+ }
+ }
+ return 2;
+}
+
+static void
+FixUpEventFromWindow(
+ xEvent *xE,
+ WindowPtr pWin,
+ Window child,
+ Bool calcChild)
+{
+ if (calcChild)
+ {
+ WindowPtr w=spriteTrace[spriteTraceGood-1];
+ /* If the search ends up past the root should the child field be
+ set to none or should the value in the argument be passed
+ through. It probably doesn't matter since everyone calls
+ this function with child == None anyway. */
+
+ while (w)
+ {
+ /* If the source window is same as event window, child should be
+ none. Don't bother going all all the way back to the root. */
+
+ if (w == pWin)
+ {
+ child = None;
+ break;
+ }
+
+ if (w->parent == pWin)
+ {
+ child = w->drawable.id;
+ break;
+ }
+ w = w->parent;
+ }
+ }
+ XE_KBPTR.root = ROOT->drawable.id;
+ XE_KBPTR.event = pWin->drawable.id;
+ if (sprite.hot.pScreen == pWin->drawable.pScreen)
+ {
+ XE_KBPTR.sameScreen = xTrue;
+ XE_KBPTR.child = child;
+ XE_KBPTR.eventX =
+ XE_KBPTR.rootX - pWin->drawable.x;
+ XE_KBPTR.eventY =
+ XE_KBPTR.rootY - pWin->drawable.y;
+ }
+ else
+ {
+ XE_KBPTR.sameScreen = xFalse;
+ XE_KBPTR.child = None;
+ XE_KBPTR.eventX = 0;
+ XE_KBPTR.eventY = 0;
+ }
+}
+
+int
+DeliverDeviceEvents(register WindowPtr pWin, register xEvent *xE, GrabPtr grab,
+ register WindowPtr stopAt, DeviceIntPtr dev, int count)
+{
+ Window child = None;
+ int type = xE->u.u.type;
+ Mask filter = filters[type];
+ int deliveries = 0;
+
+ if (type & EXTENSION_EVENT_BASE)
+ {
+ register OtherInputMasks *inputMasks;
+ int mskidx = dev->id;
+
+ inputMasks = wOtherInputMasks(pWin);
+ if (inputMasks && !(filter & inputMasks->deliverableEvents[mskidx]))
+ return 0;
+ while (pWin)
+ {
+ if (inputMasks && (inputMasks->inputEvents[mskidx] & filter))
+ {
+ FixUpEventFromWindow(xE, pWin, child, FALSE);
+ deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
+ grab, mskidx);
+ if (deliveries > 0)
+ return deliveries;
+ }
+ if ((deliveries < 0) ||
+ (pWin == stopAt) ||
+ (inputMasks &&
+ (filter & inputMasks->dontPropagateMask[mskidx])))
+ return 0;
+ child = pWin->drawable.id;
+ pWin = pWin->parent;
+ if (pWin)
+ inputMasks = wOtherInputMasks(pWin);
+ }
+ }
+ else
+ {
+ if (!(filter & pWin->deliverableEvents))
+ return 0;
+ while (pWin)
+ {
+ if ((wOtherEventMasks(pWin)|pWin->eventMask) & filter)
+ {
+ FixUpEventFromWindow(xE, pWin, child, FALSE);
+ deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
+ grab, 0);
+ if (deliveries > 0)
+ return deliveries;
+ }
+ if ((deliveries < 0) ||
+ (pWin == stopAt) ||
+ (filter & wDontPropagateMask(pWin)))
+ return 0;
+ child = pWin->drawable.id;
+ pWin = pWin->parent;
+ }
+ }
+ return 0;
+}
+
+/* not useful for events that propagate up the tree or extension events */
+int
+DeliverEvents(register WindowPtr pWin, register xEvent *xE, int count,
+ register WindowPtr otherParent)
+{
+ Mask filter;
+ int deliveries;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
+ return count;
+#endif
+
+ if (!count)
+ return 0;
+ filter = filters[xE->u.u.type];
+ if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify))
+ xE->u.destroyNotify.event = pWin->drawable.id;
+ if (filter != StructureAndSubMask)
+ return DeliverEventsToWindow(pWin, xE, count, filter, NullGrab, 0);
+ deliveries = DeliverEventsToWindow(pWin, xE, count, StructureNotifyMask,
+ NullGrab, 0);
+ if (pWin->parent)
+ {
+ xE->u.destroyNotify.event = pWin->parent->drawable.id;
+ deliveries += DeliverEventsToWindow(pWin->parent, xE, count,
+ SubstructureNotifyMask, NullGrab,
+ 0);
+ if (xE->u.u.type == ReparentNotify)
+ {
+ xE->u.destroyNotify.event = otherParent->drawable.id;
+ deliveries += DeliverEventsToWindow(otherParent, xE, count,
+ SubstructureNotifyMask,
+ NullGrab, 0);
+ }
+ }
+ return deliveries;
+}
+
+
+static Bool
+PointInBorderSize(WindowPtr pWin, int x, int y)
+{
+ BoxRec box;
+
+ if(POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderSize, x, y, &box))
+ return TRUE;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
+ int i;
+
+ for(i = 1; i < PanoramiXNumScreens; i++) {
+ if(POINT_IN_REGION(sprite.screen,
+ &sprite.windows[i]->borderSize,
+ x + panoramiXdataPtr[0].x - panoramiXdataPtr[i].x,
+ y + panoramiXdataPtr[0].y - panoramiXdataPtr[i].y,
+ &box))
+ return TRUE;
+ }
+ }
+#endif
+ return FALSE;
+}
+
+static WindowPtr
+XYToWindow(int x, int y)
+{
+ register WindowPtr pWin;
+ BoxRec box;
+
+ spriteTraceGood = 1; /* root window still there */
+
+ if (nxagentOption(Rootless))
+ {
+ if (nxagentLastEnteredWindow == NULL)
+ {
+ return ROOT;
+ }
+
+ pWin = ROOT->lastChild;
+
+ while (pWin && pWin != ROOT->firstChild && pWin != nxagentLastEnteredWindow)
+ {
+ pWin = pWin->prevSib;
+ }
+ }
+ else
+ {
+ pWin = ROOT->firstChild;
+ }
+
+ while (pWin)
+ {
+ 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))
+#ifdef SHAPE
+ /* When a window is shaped, a further check
+ * is made to see if the point is inside
+ * borderSize
+ */
+ && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
+ && (!wInputShape(pWin) ||
+ POINT_IN_REGION(pWin->drawable.pScreen,
+ wInputShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box))
+#endif
+ )
+ {
+ if (spriteTraceGood >= spriteTraceSize)
+ {
+ spriteTraceSize += 10;
+ Must_have_memory = TRUE; /* XXX */
+ spriteTrace = (WindowPtr *)xrealloc(
+ spriteTrace, spriteTraceSize*sizeof(WindowPtr));
+ Must_have_memory = FALSE; /* XXX */
+ }
+ spriteTrace[spriteTraceGood++] = pWin;
+ pWin = pWin->firstChild;
+ }
+ else
+ pWin = pWin->nextSib;
+ }
+ return spriteTrace[spriteTraceGood-1];
+}
+
+static Bool
+CheckMotion(xEvent *xE)
+{
+ WindowPtr prevSpriteWin = sprite.win;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ return XineramaCheckMotion(xE);
+#endif
+
+ if (xE && !syncEvents.playingEvents)
+ {
+ if (sprite.hot.pScreen != sprite.hotPhys.pScreen)
+ {
+ sprite.hot.pScreen = sprite.hotPhys.pScreen;
+ ROOT = WindowTable[sprite.hot.pScreen->myNum];
+ }
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = XE_KBPTR.rootX;
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = XE_KBPTR.rootY;
+ if (sprite.hot.x < sprite.physLimits.x1)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = sprite.physLimits.x1;
+ else if (sprite.hot.x >= sprite.physLimits.x2)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = sprite.physLimits.x2 - 1;
+ if (sprite.hot.y < sprite.physLimits.y1)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = sprite.physLimits.y1;
+ else if (sprite.hot.y >= sprite.physLimits.y2)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = sprite.physLimits.y2 - 1;
+#ifdef SHAPE
+ if (sprite.hotShape)
+ ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
+#endif
+ sprite.hotPhys = sprite.hot;
+
+ /*
+ * This code force cursor position to be inside the
+ * root window of the agent. We can't view a reason
+ * to do this and it interacts in an undesirable way
+ * with toggling fullscreen.
+ *
+ * if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
+ * (sprite.hotPhys.y != XE_KBPTR.rootY))
+ * {
+ * (*sprite.hotPhys.pScreen->SetCursorPosition)(
+ * sprite.hotPhys.pScreen,
+ * sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
+ * }
+ */
+
+ XE_KBPTR.rootX = sprite.hot.x;
+ XE_KBPTR.rootY = sprite.hot.y;
+ }
+
+#ifdef XEVIE
+ xeviewin =
+#endif
+ sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
+#ifdef notyet
+ if (!(sprite.win->deliverableEvents &
+ Motion_Filter(inputInfo.pointer->button))
+ !syncEvents.playingEvents)
+ {
+ /* XXX Do PointerNonInterestBox here */
+ }
+#endif
+ if (sprite.win != prevSpriteWin)
+ {
+ if (prevSpriteWin != NullWindow) {
+ if (!xE)
+ UpdateCurrentTimeIf();
+ DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
+ }
+ PostNewCursor();
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void
+WindowsRestructured()
+{
+ (void) CheckMotion((xEvent *)NULL);
+}
+
+#ifdef PANORAMIX
+/* This was added to support reconfiguration under Xdmx. The problem is
+ * that if the 0th screen (i.e., WindowTable[0]) is moved to an origin
+ * other than 0,0, the information in the private sprite structure must
+ * be updated accordingly, or XYToWindow (and other routines) will not
+ * compute correctly. */
+void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff)
+{
+ ScreenPtr pScreen = win->drawable.pScreen;
+ GrabPtr grab;
+
+ if (noPanoramiXExtension) return;
+
+ sprite.hot.x -= xoff;
+ sprite.hot.y -= yoff;
+
+ sprite.hotPhys.x -= xoff;
+ sprite.hotPhys.y -= yoff;
+
+ sprite.hotLimits.x1 -= xoff;
+ sprite.hotLimits.y1 -= yoff;
+ sprite.hotLimits.x2 -= xoff;
+ sprite.hotLimits.y2 -= yoff;
+
+ if (REGION_NOTEMPTY(sprite.screen, &sprite.Reg1))
+ REGION_TRANSLATE(sprite.screen, &sprite.Reg1, xoff, yoff);
+ if (REGION_NOTEMPTY(sprite.screen, &sprite.Reg2))
+ REGION_TRANSLATE(sprite.screen, &sprite.Reg2, xoff, yoff);
+
+ /* FIXME: if we call ConfineCursorToWindow, must we do anything else? */
+ if ((grab = inputInfo.pointer->grab) && grab->confineTo) {
+ if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+ sprite.hotPhys.x = sprite.hotPhys.y = 0;
+ ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+ } else
+ ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
+ TRUE, FALSE);
+}
+#endif
+
+void
+DefineInitialRootWindow(register WindowPtr win)
+{
+ register ScreenPtr pScreen = win->drawable.pScreen;
+ #ifdef VIEWPORT_FRAME
+ extern void nxagentInitViewportFrame(ScreenPtr, WindowPtr);
+ #endif
+ extern int nxagentShadowInit(ScreenPtr, WindowPtr);
+
+ sprite.hotPhys.pScreen = pScreen;
+ sprite.hotPhys.x = pScreen->width / 2;
+ sprite.hotPhys.y = pScreen->height / 2;
+ sprite.hot = sprite.hotPhys;
+ sprite.hotLimits.x2 = pScreen->width;
+ sprite.hotLimits.y2 = pScreen->height;
+#ifdef XEVIE
+ xeviewin =
+#endif
+ sprite.win = win;
+ sprite.current = wCursor (win);
+ sprite.current->refcnt++;
+ spriteTraceGood = 1;
+ ROOT = win;
+ (*pScreen->CursorLimits) (
+ pScreen, sprite.current, &sprite.hotLimits, &sprite.physLimits);
+ sprite.confined = FALSE;
+ (*pScreen->ConstrainCursor) (pScreen, &sprite.physLimits);
+ (*pScreen->SetCursorPosition) (pScreen, sprite.hot.x, sprite.hot.y, FALSE);
+ (*pScreen->DisplayCursor) (pScreen, sprite.current);
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ sprite.hotLimits.x1 = -panoramiXdataPtr[0].x;
+ sprite.hotLimits.y1 = -panoramiXdataPtr[0].y;
+ sprite.hotLimits.x2 = PanoramiXPixWidth - panoramiXdataPtr[0].x;
+ sprite.hotLimits.y2 = PanoramiXPixHeight - panoramiXdataPtr[0].y;
+ sprite.physLimits = sprite.hotLimits;
+ sprite.confineWin = NullWindow;
+#ifdef SHAPE
+ sprite.hotShape = NullRegion;
+#endif
+ sprite.screen = pScreen;
+ /* gotta UNINIT these someplace */
+ REGION_NULL(pScreen, &sprite.Reg1);
+ REGION_NULL(pScreen, &sprite.Reg2);
+ }
+#endif
+
+ #ifdef VIEWPORT_FRAME
+ nxagentInitViewportFrame(pScreen, win);
+ #endif
+
+ if (nxagentOption(Shadow))
+ {
+ if (nxagentShadowInit(pScreen, win) == -1)
+ {
+ FatalError("Failed to connect to display '%s'", nxagentShadowDisplayName);
+ }
+ }
+}
+
+/*
+ * This does not take any shortcuts, and even ignores its argument, since
+ * it does not happen very often, and one has to walk up the tree since
+ * this might be a newly instantiated cursor for an intermediate window
+ * between the one the pointer is in and the one that the last cursor was
+ * instantiated from.
+ */
+void
+WindowHasNewCursor(WindowPtr pWin)
+{
+ PostNewCursor();
+}
+
+void
+NewCurrentScreen(ScreenPtr newScreen, int x, int y)
+{
+ sprite.hotPhys.x = x;
+ sprite.hotPhys.y = y;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ sprite.hotPhys.x += panoramiXdataPtr[newScreen->myNum].x -
+ panoramiXdataPtr[0].x;
+ sprite.hotPhys.y += panoramiXdataPtr[newScreen->myNum].y -
+ panoramiXdataPtr[0].y;
+ if (newScreen != sprite.screen) {
+ sprite.screen = newScreen;
+ /* Make sure we tell the DDX to update its copy of the screen */
+ if(sprite.confineWin)
+ XineramaConfineCursorToWindow(sprite.confineWin, TRUE);
+ else
+ XineramaConfineCursorToWindow(WindowTable[0], TRUE);
+ /* if the pointer wasn't confined, the DDX won't get
+ told of the pointer warp so we reposition it here */
+ if(!syncEvents.playingEvents)
+ (*sprite.screen->SetCursorPosition)(sprite.screen,
+ sprite.hotPhys.x + panoramiXdataPtr[0].x -
+ panoramiXdataPtr[sprite.screen->myNum].x,
+ sprite.hotPhys.y + panoramiXdataPtr[0].y -
+ panoramiXdataPtr[sprite.screen->myNum].y, FALSE);
+ }
+ } else
+#endif
+ if (newScreen != sprite.hotPhys.pScreen)
+ ConfineCursorToWindow(WindowTable[newScreen->myNum], TRUE, FALSE);
+}
+
+#ifdef PANORAMIX
+
+static Bool
+XineramaPointInWindowIsVisible(
+ WindowPtr pWin,
+ int x,
+ int y
+)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ BoxRec box;
+ int i, xoff, yoff;
+
+ if (!pWin->realized) return FALSE;
+
+ if (POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box))
+ return TRUE;
+
+ if(!XineramaSetWindowPntrs(pWin)) return FALSE;
+
+ xoff = x + panoramiXdataPtr[0].x;
+ yoff = y + panoramiXdataPtr[0].y;
+
+ for(i = 1; i < PanoramiXNumScreens; i++) {
+ pWin = sprite.windows[i];
+ pScreen = pWin->drawable.pScreen;
+ x = xoff - panoramiXdataPtr[i].x;
+ y = yoff - panoramiXdataPtr[i].y;
+
+ if(POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box)
+ && (!wInputShape(pWin) ||
+ POINT_IN_REGION(pWin->drawable.pScreen,
+ wInputShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box)))
+ return TRUE;
+
+ }
+
+ return FALSE;
+}
+
+static int
+XineramaWarpPointer(ClientPtr client)
+{
+ WindowPtr dest = NULL;
+ int x, y;
+
+ REQUEST(xWarpPointerReq);
+
+
+ if (stuff->dstWid != None)
+ {
+ dest = SecurityLookupWindow(stuff->dstWid, client, SecurityReadAccess);
+ if (!dest)
+ return BadWindow;
+ }
+ x = sprite.hotPhys.x;
+ y = sprite.hotPhys.y;
+
+ if (stuff->srcWid != None)
+ {
+ int winX, winY;
+ XID winID = stuff->srcWid;
+ WindowPtr source;
+
+ source = SecurityLookupWindow(winID, client, SecurityReadAccess);
+ if (!source) return BadWindow;
+
+ winX = source->drawable.x;
+ winY = source->drawable.y;
+ if(source == WindowTable[0]) {
+ winX -= panoramiXdataPtr[0].x;
+ winY -= panoramiXdataPtr[0].y;
+ }
+ if (x < winX + stuff->srcX ||
+ y < winY + stuff->srcY ||
+ (stuff->srcWidth != 0 &&
+ winX + stuff->srcX + (int)stuff->srcWidth < x) ||
+ (stuff->srcHeight != 0 &&
+ winY + stuff->srcY + (int)stuff->srcHeight < y) ||
+ !XineramaPointInWindowIsVisible(source, x, y))
+ return Success;
+ }
+ if (dest) {
+ x = dest->drawable.x;
+ y = dest->drawable.y;
+ if(dest == WindowTable[0]) {
+ x -= panoramiXdataPtr[0].x;
+ y -= panoramiXdataPtr[0].y;
+ }
+ }
+
+ x += stuff->dstX;
+ y += stuff->dstY;
+
+ if (x < sprite.physLimits.x1)
+ x = sprite.physLimits.x1;
+ else if (x >= sprite.physLimits.x2)
+ x = sprite.physLimits.x2 - 1;
+ if (y < sprite.physLimits.y1)
+ y = sprite.physLimits.y1;
+ else if (y >= sprite.physLimits.y2)
+ y = sprite.physLimits.y2 - 1;
+ if (sprite.hotShape)
+ ConfineToShape(sprite.hotShape, &x, &y);
+
+ XineramaSetCursorPosition(x, y, TRUE);
+
+ return Success;
+}
+
+#endif
+
+
+int
+ProcWarpPointer(ClientPtr client)
+{
+ WindowPtr dest = NULL;
+ int x, y;
+ ScreenPtr newScreen;
+
+ REQUEST(xWarpPointerReq);
+
+ REQUEST_SIZE_MATCH(xWarpPointerReq);
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ return XineramaWarpPointer(client);
+#endif
+
+ if (stuff->dstWid != None)
+ {
+ dest = SecurityLookupWindow(stuff->dstWid, client, SecurityReadAccess);
+ if (!dest)
+ return BadWindow;
+ }
+ x = sprite.hotPhys.x;
+ y = sprite.hotPhys.y;
+
+ if (stuff->srcWid != None)
+ {
+ int winX, winY;
+ XID winID = stuff->srcWid;
+ WindowPtr source;
+
+ source = SecurityLookupWindow(winID, client, SecurityReadAccess);
+ if (!source) return BadWindow;
+
+ winX = source->drawable.x;
+ winY = source->drawable.y;
+ if (source->drawable.pScreen != sprite.hotPhys.pScreen ||
+ x < winX + stuff->srcX ||
+ y < winY + stuff->srcY ||
+ (stuff->srcWidth != 0 &&
+ winX + stuff->srcX + (int)stuff->srcWidth < x) ||
+ (stuff->srcHeight != 0 &&
+ winY + stuff->srcY + (int)stuff->srcHeight < y) ||
+ !PointInWindowIsVisible(source, x, y))
+ return Success;
+ }
+ if (dest)
+ {
+ x = dest->drawable.x;
+ y = dest->drawable.y;
+ newScreen = dest->drawable.pScreen;
+ } else
+ newScreen = sprite.hotPhys.pScreen;
+
+ x += stuff->dstX;
+ y += stuff->dstY;
+
+ if (x < 0)
+ x = 0;
+ else if (x >= newScreen->width)
+ x = newScreen->width - 1;
+ if (y < 0)
+ y = 0;
+ else if (y >= newScreen->height)
+ y = newScreen->height - 1;
+
+ if (newScreen == sprite.hotPhys.pScreen)
+ {
+ if (x < sprite.physLimits.x1)
+ x = sprite.physLimits.x1;
+ else if (x >= sprite.physLimits.x2)
+ x = sprite.physLimits.x2 - 1;
+ if (y < sprite.physLimits.y1)
+ y = sprite.physLimits.y1;
+ else if (y >= sprite.physLimits.y2)
+ y = sprite.physLimits.y2 - 1;
+#if defined(SHAPE)
+ if (sprite.hotShape)
+ ConfineToShape(sprite.hotShape, &x, &y);
+#endif
+ (*newScreen->SetCursorPosition)(newScreen, x, y, TRUE);
+ }
+ else if (!PointerConfinedToScreen())
+ {
+ NewCurrentScreen(newScreen, x, y);
+ }
+ return Success;
+}
+
+static Bool
+BorderSizeNotEmpty(WindowPtr pWin)
+{
+ if(REGION_NOTEMPTY(sprite.hotPhys.pScreen, &pWin->borderSize))
+ return TRUE;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
+ int i;
+
+ for(i = 1; i < PanoramiXNumScreens; i++) {
+ if(REGION_NOTEMPTY(sprite.screen, &sprite.windows[i]->borderSize))
+ return TRUE;
+ }
+ }
+#endif
+ return FALSE;
+}
+
+/* "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a
+ passive grab set on the window to be activated. */
+
+static Bool
+CheckPassiveGrabsOnWindow(
+ WindowPtr pWin,
+ register DeviceIntPtr device,
+ register xEvent *xE,
+ int count)
+{
+ register GrabPtr grab = wPassiveGrabs(pWin);
+ GrabRec tempGrab;
+ register xEvent *dxE;
+
+ if (!grab)
+ return FALSE;
+ tempGrab.window = pWin;
+ tempGrab.device = device;
+ tempGrab.type = xE->u.u.type;
+ tempGrab.detail.exact = xE->u.u.detail;
+ tempGrab.detail.pMask = NULL;
+ tempGrab.modifiersDetail.pMask = NULL;
+ for (; grab; grab = grab->next)
+ {
+#ifdef XKB
+ DeviceIntPtr gdev;
+ XkbSrvInfoPtr xkbi;
+
+ gdev= grab->modifierDevice;
+ xkbi= gdev->key->xkbInfo;
+#endif
+ tempGrab.modifierDevice = grab->modifierDevice;
+ if ((device == grab->modifierDevice) &&
+ ((xE->u.u.type == KeyPress)
+#if defined(XINPUT) && defined(XKB)
+ || (xE->u.u.type == DeviceKeyPress)
+#endif
+ ))
+ tempGrab.modifiersDetail.exact =
+#ifdef XKB
+ (noXkbExtension?gdev->key->prev_state:xkbi->state.grab_mods);
+#else
+ grab->modifierDevice->key->prev_state;
+#endif
+ else
+ tempGrab.modifiersDetail.exact =
+#ifdef XKB
+ (noXkbExtension ? gdev->key->state : xkbi->state.grab_mods);
+#else
+ grab->modifierDevice->key->state;
+#endif
+ if (GrabMatchesSecond(&tempGrab, grab) &&
+ (!grab->confineTo ||
+ (grab->confineTo->realized &&
+ BorderSizeNotEmpty(grab->confineTo))))
+ {
+#ifdef XCSECURITY
+ if (!SecurityCheckDeviceAccess(wClient(pWin), device, FALSE))
+ return FALSE;
+#endif
+#ifdef XKB
+ if (!noXkbExtension) {
+ XE_KBPTR.state &= 0x1f00;
+ XE_KBPTR.state |=
+ tempGrab.modifiersDetail.exact&(~0x1f00);
+ }
+#endif
+ (*device->ActivateGrab)(device, grab, currentTime, TRUE);
+
+ FixUpEventFromWindow(xE, grab->window, None, TRUE);
+
+ (void) TryClientEvents(rClient(grab), xE, count,
+ filters[xE->u.u.type],
+ filters[xE->u.u.type], grab);
+
+ if (device->sync.state == FROZEN_NO_EVENT)
+ {
+ if (device->sync.evcount < count)
+ {
+ Must_have_memory = TRUE; /* XXX */
+ device->sync.event = (xEvent *)xrealloc(device->sync.event,
+ count*
+ sizeof(xEvent));
+ Must_have_memory = FALSE; /* XXX */
+ }
+ device->sync.evcount = count;
+ for (dxE = device->sync.event; --count >= 0; dxE++, xE++)
+ *dxE = *xE;
+ device->sync.state = FROZEN_WITH_EVENT;
+ }
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/**
+"CheckDeviceGrabs" handles both keyboard and pointer events that may cause
+a passive grab to be activated. If the event is a keyboard event, the
+ancestors of the focus window are traced down and tried to see if they have
+any passive grabs to be activated. If the focus window itself is reached and
+it's descendants contain they pointer, the ancestors of the window that the
+pointer is in are then traced down starting at the focus window, otherwise no
+grabs are activated. If the event is a pointer event, the ancestors of the
+window that the pointer is in are traced down starting at the root until
+CheckPassiveGrabs causes a passive grab to activate or all the windows are
+tried. PRH
+*/
+
+Bool
+CheckDeviceGrabs(register DeviceIntPtr device, register xEvent *xE,
+ int checkFirst, int count)
+{
+ register int i;
+ register WindowPtr pWin = NULL;
+ register FocusClassPtr focus = device->focus;
+
+ if (((xE->u.u.type == ButtonPress)
+#if defined(XINPUT) && defined(XKB)
+ || (xE->u.u.type == DeviceButtonPress)
+#endif
+ ) && (device->button->buttonsDown != 1))
+ return FALSE;
+
+ i = checkFirst;
+
+ if (focus)
+ {
+ for (; i < focus->traceGood; i++)
+ {
+ pWin = focus->trace[i];
+ if (pWin->optional &&
+ CheckPassiveGrabsOnWindow(pWin, device, xE, count))
+ return TRUE;
+ }
+
+ if ((focus->win == NoneWin) ||
+ (i >= spriteTraceGood) ||
+ ((i > checkFirst) && (pWin != spriteTrace[i-1])))
+ return FALSE;
+ }
+
+ for (; i < spriteTraceGood; i++)
+ {
+ pWin = spriteTrace[i];
+ if (pWin->optional &&
+ CheckPassiveGrabsOnWindow(pWin, device, xE, count))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void
+DeliverFocusedEvent(DeviceIntPtr keybd, xEvent *xE, WindowPtr window, int count)
+{
+ WindowPtr focus = keybd->focus->win;
+ int mskidx = 0;
+
+ if (focus == FollowKeyboardWin)
+ focus = inputInfo.keyboard->focus->win;
+ if (!focus)
+ return;
+ if (focus == PointerRootWin)
+ {
+ DeliverDeviceEvents(window, xE, NullGrab, NullWindow, keybd, count);
+ return;
+ }
+ if ((focus == window) || IsParent(focus, window))
+ {
+ if (DeliverDeviceEvents(window, xE, NullGrab, focus, keybd, count))
+ return;
+ }
+ /* just deliver it to the focus window */
+ FixUpEventFromWindow(xE, focus, None, FALSE);
+ if (xE->u.u.type & EXTENSION_EVENT_BASE)
+ mskidx = keybd->id;
+ (void)DeliverEventsToWindow(focus, xE, count, filters[xE->u.u.type],
+ NullGrab, mskidx);
+}
+
+void
+DeliverGrabbedEvent(register xEvent *xE, register DeviceIntPtr thisDev,
+ Bool deactivateGrab, int count)
+{
+ register GrabPtr grab = thisDev->grab;
+ int deliveries = 0;
+ register DeviceIntPtr dev;
+ register xEvent *dxE;
+
+ if (grab->ownerEvents)
+ {
+ WindowPtr focus;
+
+ if (thisDev->focus)
+ {
+ focus = thisDev->focus->win;
+ if (focus == FollowKeyboardWin)
+ focus = inputInfo.keyboard->focus->win;
+ }
+ else
+ focus = PointerRootWin;
+ if (focus == PointerRootWin)
+ deliveries = DeliverDeviceEvents(sprite.win, xE, grab, NullWindow,
+ thisDev, count);
+ else if (focus && (focus == sprite.win || IsParent(focus, sprite.win)))
+ deliveries = DeliverDeviceEvents(sprite.win, xE, grab, focus,
+ thisDev, count);
+ else if (focus)
+ deliveries = DeliverDeviceEvents(focus, xE, grab, focus,
+ thisDev, count);
+ }
+ if (!deliveries)
+ {
+ FixUpEventFromWindow(xE, grab->window, None, TRUE);
+ deliveries = TryClientEvents(rClient(grab), xE, count,
+ (Mask)grab->eventMask,
+ filters[xE->u.u.type], grab);
+ if (deliveries && (xE->u.u.type == MotionNotify
+#ifdef XINPUT
+ || xE->u.u.type == DeviceMotionNotify
+#endif
+ ))
+ thisDev->valuator->motionHintWindow = grab->window;
+ }
+ if (deliveries && !deactivateGrab && (xE->u.u.type != MotionNotify
+#ifdef XINPUT
+ && xE->u.u.type != DeviceMotionNotify
+#endif
+ ))
+ switch (thisDev->sync.state)
+ {
+ case FREEZE_BOTH_NEXT_EVENT:
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev == thisDev)
+ continue;
+ FreezeThaw(dev, TRUE);
+ if ((dev->sync.state == FREEZE_BOTH_NEXT_EVENT) &&
+ (CLIENT_BITS(dev->grab->resource) ==
+ CLIENT_BITS(thisDev->grab->resource)))
+ dev->sync.state = FROZEN_NO_EVENT;
+ else
+ dev->sync.other = thisDev->grab;
+ }
+ /* fall through */
+ case FREEZE_NEXT_EVENT:
+ thisDev->sync.state = FROZEN_WITH_EVENT;
+ FreezeThaw(thisDev, TRUE);
+ if (thisDev->sync.evcount < count)
+ {
+ Must_have_memory = TRUE; /* XXX */
+ thisDev->sync.event = (xEvent *)xrealloc(thisDev->sync.event,
+ count*sizeof(xEvent));
+ Must_have_memory = FALSE; /* XXX */
+ }
+ thisDev->sync.evcount = count;
+ for (dxE = thisDev->sync.event; --count >= 0; dxE++, xE++)
+ *dxE = *xE;
+ break;
+ }
+}
+
+void
+#ifdef XKB
+CoreProcessKeyboardEvent (register xEvent *xE, register DeviceIntPtr keybd, int count)
+#else
+ProcessKeyboardEvent (register xEvent *xE, register DeviceIntPtr keybd, int count)
+#endif
+{
+ int key, bit;
+ register BYTE *kptr;
+ register int i;
+ register CARD8 modifiers;
+ register CARD16 mask;
+ GrabPtr grab = keybd->grab;
+ Bool deactivateGrab = FALSE;
+ register KeyClassPtr keyc = keybd->key;
+#ifdef XEVIE
+ static Window rootWin = 0;
+
+ if(!xeviegrabState && xevieFlag && clients[xevieClientIndex] &&
+ (xevieMask & xevieFilters[xE->u.u.type])) {
+ key = xE->u.u.detail;
+ kptr = &keyc->down[key >> 3];
+ bit = 1 << (key & 7);
+ if((xE->u.u.type == KeyPress && (*kptr & bit)) ||
+ (xE->u.u.type == KeyRelease && !(*kptr & bit)))
+ {} else {
+#ifdef XKB
+ if(!noXkbExtension)
+ xevieKBEventSent = 1;
+#endif
+ if(!xevieKBEventSent)
+ {
+ xeviekb = keybd;
+ if(!rootWin) {
+ rootWin = GetCurrentRootWindow()->drawable.id;
+ }
+ xE->u.keyButtonPointer.event = xeviewin->drawable.id;
+ xE->u.keyButtonPointer.root = rootWin;
+ xE->u.keyButtonPointer.child = (xeviewin->firstChild) ? xeviewin->firstChild->
+drawable.id:0;
+ xE->u.keyButtonPointer.rootX = xeviehot.x;
+ xE->u.keyButtonPointer.rootY = xeviehot.y;
+ xE->u.keyButtonPointer.state = keyc->state;
+ WriteToClient(clients[xevieClientIndex], sizeof(xEvent), (char *)xE);
+#ifdef XKB
+ if(noXkbExtension)
+#endif
+ return;
+ } else {
+ xevieKBEventSent = 0;
+ }
+ }
+ }
+#endif
+
+ if (!syncEvents.playingEvents)
+ {
+ NoticeTime(xE);
+ if (DeviceEventCallback)
+ {
+ DeviceEventInfoRec eventinfo;
+ eventinfo.events = xE;
+ eventinfo.count = count;
+ CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+ }
+ }
+#ifdef XEVIE
+ /* fix for bug5094030: don't change the state bit if the event is from XEvIE client */
+ if(!(!xeviegrabState && xevieFlag && clients[xevieClientIndex] &&
+ (xevieMask & xevieFilters[xE->u.u.type]
+#ifdef XKB
+ && !noXkbExtension
+#endif
+ )))
+#endif
+ XE_KBPTR.state = (keyc->state | inputInfo.pointer->button->state);
+ XE_KBPTR.rootX = sprite.hot.x;
+ XE_KBPTR.rootY = sprite.hot.y;
+ key = xE->u.u.detail;
+ kptr = &keyc->down[key >> 3];
+ bit = 1 << (key & 7);
+ modifiers = keyc->modifierMap[key];
+#if defined(XKB) && defined(XEVIE)
+ if(!noXkbExtension && !xeviegrabState &&
+ xevieFlag && clients[xevieClientIndex] &&
+ (xevieMask & xevieFilters[xE->u.u.type])) {
+ switch(xE->u.u.type) {
+ case KeyPress: *kptr &= ~bit; break;
+ case KeyRelease: *kptr |= bit; break;
+ }
+ }
+#endif
+
+#ifdef DEBUG
+ if ((xkbDebugFlags&0x4)&&
+ ((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))) {
+ ErrorF("CoreProcessKbdEvent: Key %d %s\n",key,
+ (xE->u.u.type==KeyPress?"down":"up"));
+ }
+#endif
+ switch (xE->u.u.type)
+ {
+ case KeyPress:
+ if (*kptr & bit) /* allow ddx to generate multiple downs */
+ {
+ if (!modifiers)
+ {
+ xE->u.u.type = KeyRelease;
+ (*keybd->public.processInputProc)(xE, keybd, count);
+ xE->u.u.type = KeyPress;
+ /* release can have side effects, don't fall through */
+ (*keybd->public.processInputProc)(xE, keybd, count);
+ }
+ return;
+ }
+ inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+ *kptr |= bit;
+ keyc->prev_state = keyc->state;
+ for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
+ {
+ if (mask & modifiers)
+ {
+ /* This key affects modifier "i" */
+ keyc->modifierKeyCount[i]++;
+ keyc->state |= mask;
+ modifiers &= ~mask;
+ }
+ }
+ if (!grab && CheckDeviceGrabs(keybd, xE, 0, count))
+ {
+ keybd->activatingKey = key;
+ return;
+ }
+ break;
+ case KeyRelease:
+ if (!(*kptr & bit)) /* guard against duplicates */
+ return;
+ inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+ *kptr &= ~bit;
+ keyc->prev_state = keyc->state;
+ for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
+ {
+ if (mask & modifiers) {
+ /* This key affects modifier "i" */
+ if (--keyc->modifierKeyCount[i] <= 0) {
+ keyc->state &= ~mask;
+ keyc->modifierKeyCount[i] = 0;
+ }
+ modifiers &= ~mask;
+ }
+ }
+ if (keybd->fromPassiveGrab && (key == keybd->activatingKey))
+ deactivateGrab = TRUE;
+ break;
+ default:
+ FatalError("Impossible keyboard event");
+ }
+ if (grab)
+ DeliverGrabbedEvent(xE, keybd, deactivateGrab, count);
+ else
+ DeliverFocusedEvent(keybd, xE, sprite.win, count);
+ if (deactivateGrab)
+ (*keybd->DeactivateGrab)(keybd);
+}
+
+#ifdef XKB
+/* This function is used to set the key pressed or key released state -
+ this is only used when the pressing of keys does not cause
+ CoreProcessKeyEvent to be called, as in for example Mouse Keys.
+*/
+void
+FixKeyState (register xEvent *xE, register DeviceIntPtr keybd)
+{
+ int key, bit;
+ register BYTE *kptr;
+ register KeyClassPtr keyc = keybd->key;
+
+ key = xE->u.u.detail;
+ kptr = &keyc->down[key >> 3];
+ bit = 1 << (key & 7);
+#ifdef DEBUG
+ if ((xkbDebugFlags&0x4)&&
+ ((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))) {
+ ErrorF("FixKeyState: Key %d %s\n",key,
+ (xE->u.u.type==KeyPress?"down":"up"));
+ }
+#endif
+ switch (xE->u.u.type)
+ {
+ case KeyPress:
+ *kptr |= bit;
+ break;
+ case KeyRelease:
+ *kptr &= ~bit;
+ break;
+ default:
+ FatalError("Impossible keyboard event");
+ }
+}
+#endif
+
+void
+#ifdef XKB
+CoreProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count)
+#else
+ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count)
+#endif
+{
+ register GrabPtr grab = mouse->grab;
+ Bool deactivateGrab = FALSE;
+ register ButtonClassPtr butc = mouse->button;
+#ifdef XKB
+ XkbSrvInfoPtr xkbi;
+
+ xkbi = inputInfo.keyboard->key->xkbInfo;
+#endif
+#ifdef XEVIE
+ if(xevieFlag && clients[xevieClientIndex] && !xeviegrabState &&
+ (xevieMask & xevieFilters[xE->u.u.type])) {
+ if(xevieEventSent)
+ xevieEventSent = 0;
+ else {
+ xeviemouse = mouse;
+ WriteToClient(clients[xevieClientIndex], sizeof(xEvent), (char *)xE);
+ return;
+ }
+ }
+#endif
+
+ if (!syncEvents.playingEvents)
+ NoticeTime(xE)
+ XE_KBPTR.state = (butc->state | (
+#ifdef XKB
+ (noXkbExtension ?
+ inputInfo.keyboard->key->state :
+ xkbi->state.grab_mods)
+#else
+ inputInfo.keyboard->key->state
+#endif
+ ));
+ {
+ NoticeTime(xE);
+ if (DeviceEventCallback)
+ {
+ DeviceEventInfoRec eventinfo;
+ /* see comment in EnqueueEvents regarding the next three lines */
+ if (xE->u.u.type == MotionNotify)
+ XE_KBPTR.root =
+ WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
+ eventinfo.events = xE;
+ eventinfo.count = count;
+ CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+ }
+ }
+ if (xE->u.u.type != MotionNotify)
+ {
+ register int key;
+ register BYTE *kptr;
+ int bit;
+
+ XE_KBPTR.rootX = sprite.hot.x;
+ XE_KBPTR.rootY = sprite.hot.y;
+
+ key = xE->u.u.detail;
+ kptr = &butc->down[key >> 3];
+ bit = 1 << (key & 7);
+ switch (xE->u.u.type)
+ {
+ case ButtonPress:
+ mouse->valuator->motionHintWindow = NullWindow;
+ if (!(*kptr & bit))
+ butc->buttonsDown++;
+ butc->motionMask = ButtonMotionMask;
+ *kptr |= bit;
+#if !defined(XFree86Server) || !defined(XINPUT)
+ xE->u.u.detail = butc->map[key];
+#endif
+ if (xE->u.u.detail == 0)
+ return;
+ if (xE->u.u.detail <= 5)
+ butc->state |= (Button1Mask >> 1) << xE->u.u.detail;
+ filters[MotionNotify] = Motion_Filter(butc);
+ if (!grab)
+ if (CheckDeviceGrabs(mouse, xE, 0, count))
+ return;
+ break;
+ case ButtonRelease:
+ mouse->valuator->motionHintWindow = NullWindow;
+ if (*kptr & bit)
+ --butc->buttonsDown;
+ if (!butc->buttonsDown)
+ butc->motionMask = 0;
+ *kptr &= ~bit;
+#if !defined(XFree86Server) || !defined(XINPUT)
+ xE->u.u.detail = butc->map[key];
+#endif
+ if (xE->u.u.detail == 0)
+ return;
+ if (xE->u.u.detail <= 5)
+ butc->state &= ~((Button1Mask >> 1) << xE->u.u.detail);
+ filters[MotionNotify] = Motion_Filter(butc);
+ if (!butc->state && mouse->fromPassiveGrab)
+ deactivateGrab = TRUE;
+ break;
+ default:
+ FatalError("bogus pointer event from ddx");
+ }
+ }
+ else if (!CheckMotion(xE))
+ return;
+ if (grab)
+ DeliverGrabbedEvent(xE, mouse, deactivateGrab, count);
+ else
+ DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
+ mouse, count);
+ if (deactivateGrab)
+ (*mouse->DeactivateGrab)(mouse);
+}
+
+#define AtMostOneClient \
+ (SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask)
+
+void
+RecalculateDeliverableEvents(pWin)
+ register WindowPtr pWin;
+{
+ register OtherClients *others;
+ register WindowPtr pChild;
+
+ pChild = pWin;
+ while (1)
+ {
+ if (pChild->optional)
+ {
+ pChild->optional->otherEventMasks = 0;
+ for (others = wOtherClients(pChild); others; others = others->next)
+ {
+ pChild->optional->otherEventMasks |= others->mask;
+ }
+ }
+ pChild->deliverableEvents = pChild->eventMask|
+ wOtherEventMasks(pChild);
+ if (pChild->parent)
+ pChild->deliverableEvents |=
+ (pChild->parent->deliverableEvents &
+ ~wDontPropagateMask(pChild) & PropagateMask);
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ break;
+ pChild = pChild->nextSib;
+ }
+}
+
+/**
+ *
+ * \param value must conform to DeleteType
+ */
+int
+OtherClientGone(pointer value, XID id)
+{
+ register OtherClientsPtr other, prev;
+ register WindowPtr pWin = (WindowPtr)value;
+
+ prev = 0;
+ for (other = wOtherClients(pWin); other; other = other->next)
+ {
+ if (other->resource == id)
+ {
+ if (prev)
+ prev->next = other->next;
+ else
+ {
+ if (!(pWin->optional->otherClients = other->next))
+ CheckWindowOptionalNeed (pWin);
+ }
+ xfree(other);
+ RecalculateDeliverableEvents(pWin);
+ return(Success);
+ }
+ prev = other;
+ }
+ FatalError("client not on event list");
+ /*NOTREACHED*/
+ return -1; /* make compiler happy */
+}
+
+int
+EventSelectForWindow(register WindowPtr pWin, register ClientPtr client, Mask mask)
+{
+ Mask check;
+ OtherClients * others;
+
+ if (mask & ~AllEventMasks)
+ {
+ client->errorValue = mask;
+ return BadValue;
+ }
+ check = (mask & AtMostOneClient);
+ if (check & (pWin->eventMask|wOtherEventMasks(pWin)))
+ { /* It is illegal for two different
+ clients to select on any of the
+ events for AtMostOneClient. However,
+ it is OK, for some client to
+ continue selecting on one of those
+ events. */
+ if ((wClient(pWin) != client) && (check & pWin->eventMask))
+ return BadAccess;
+ for (others = wOtherClients (pWin); others; others = others->next)
+ {
+ if (!SameClient(others, client) && (check & others->mask))
+ return BadAccess;
+ }
+ }
+ if (wClient (pWin) == client)
+ {
+ check = pWin->eventMask;
+#ifdef SGIMISC
+ pWin->eventMask =
+ (mask & ~SGIMiscSpecialDestroyMask) | (pWin->eventMask & SGIMiscSpecialDestroyMask);
+#else
+ pWin->eventMask = mask;
+#endif
+ }
+ else
+ {
+ for (others = wOtherClients (pWin); others; others = others->next)
+ {
+ if (SameClient(others, client))
+ {
+ check = others->mask;
+#ifdef SGIMISC
+ mask = (mask & ~SGIMiscSpecialDestroyMask) | (others->mask & SGIMiscSpecialDestroyMask);
+#endif
+ if (mask == 0)
+ {
+ FreeResource(others->resource, RT_NONE);
+ return Success;
+ }
+ else
+ others->mask = mask;
+ goto maskSet;
+ }
+ }
+ check = 0;
+ if (!pWin->optional && !MakeWindowOptional (pWin))
+ return BadAlloc;
+ others = (OtherClients *) xalloc(sizeof(OtherClients));
+ if (!others)
+ return BadAlloc;
+ others->mask = mask;
+ others->resource = FakeClientID(client->index);
+ others->next = pWin->optional->otherClients;
+ pWin->optional->otherClients = others;
+ if (!AddResource(others->resource, RT_OTHERCLIENT, (pointer)pWin))
+ return BadAlloc;
+ }
+maskSet:
+ if ((inputInfo.pointer->valuator->motionHintWindow == pWin) &&
+ (mask & PointerMotionHintMask) &&
+ !(check & PointerMotionHintMask) &&
+ !inputInfo.pointer->grab)
+ inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+ RecalculateDeliverableEvents(pWin);
+ return Success;
+}
+
+int
+EventSuppressForWindow(register WindowPtr pWin, register ClientPtr client,
+ Mask mask, Bool *checkOptional)
+{
+ register int i, free;
+
+ if ((mask & ~PropagateMask) && !permitOldBugs)
+ {
+ client->errorValue = mask;
+ return BadValue;
+ }
+ if (pWin->dontPropagate)
+ DontPropagateRefCnts[pWin->dontPropagate]--;
+ if (!mask)
+ i = 0;
+ else
+ {
+ for (i = DNPMCOUNT, free = 0; --i > 0; )
+ {
+ if (!DontPropagateRefCnts[i])
+ free = i;
+ else if (mask == DontPropagateMasks[i])
+ break;
+ }
+ if (!i && free)
+ {
+ i = free;
+ DontPropagateMasks[i] = mask;
+ }
+ }
+ if (i || !mask)
+ {
+ pWin->dontPropagate = i;
+ if (i)
+ DontPropagateRefCnts[i]++;
+ if (pWin->optional)
+ {
+ pWin->optional->dontPropagateMask = mask;
+ *checkOptional = TRUE;
+ }
+ }
+ else
+ {
+ if (!pWin->optional && !MakeWindowOptional (pWin))
+ {
+ if (pWin->dontPropagate)
+ DontPropagateRefCnts[pWin->dontPropagate]++;
+ return BadAlloc;
+ }
+ pWin->dontPropagate = 0;
+ pWin->optional->dontPropagateMask = mask;
+ }
+ RecalculateDeliverableEvents(pWin);
+ return Success;
+}
+
+static WindowPtr
+CommonAncestor(
+ register WindowPtr a,
+ register WindowPtr b)
+{
+ for (b = b->parent; b; b = b->parent)
+ if (IsParent(b, a)) return b;
+ return NullWindow;
+}
+
+static void
+EnterLeaveEvent(
+ int type,
+ int mode,
+ int detail,
+ register WindowPtr pWin,
+ Window child)
+{
+ xEvent event;
+ register DeviceIntPtr keybd = inputInfo.keyboard;
+ WindowPtr focus;
+ register DeviceIntPtr mouse = inputInfo.pointer;
+ register GrabPtr grab = mouse->grab;
+ Mask mask;
+
+ if ((pWin == mouse->valuator->motionHintWindow) &&
+ (detail != NotifyInferior))
+ mouse->valuator->motionHintWindow = NullWindow;
+ if (grab)
+ {
+ mask = (pWin == grab->window) ? grab->eventMask : 0;
+ if (grab->ownerEvents)
+ mask |= EventMaskForClient(pWin, rClient(grab));
+ }
+ else
+ {
+ mask = pWin->eventMask | wOtherEventMasks(pWin);
+ }
+ if (mask & filters[type])
+ {
+ event.u.u.type = type;
+ event.u.u.detail = detail;
+ event.u.enterLeave.time = currentTime.milliseconds;
+ event.u.enterLeave.rootX = sprite.hot.x;
+ event.u.enterLeave.rootY = sprite.hot.y;
+ /* Counts on the same initial structure of crossing & button events! */
+ FixUpEventFromWindow(&event, pWin, None, FALSE);
+ /* Enter/Leave events always set child */
+ event.u.enterLeave.child = child;
+ event.u.enterLeave.flags = event.u.keyButtonPointer.sameScreen ?
+ ELFlagSameScreen : 0;
+#ifdef XKB
+ if (!noXkbExtension) {
+ event.u.enterLeave.state = mouse->button->state & 0x1f00;
+ event.u.enterLeave.state |=
+ XkbGrabStateFromRec(&keybd->key->xkbInfo->state);
+ } else
+#endif
+ event.u.enterLeave.state = keybd->key->state | mouse->button->state;
+ event.u.enterLeave.mode = mode;
+ focus = keybd->focus->win;
+ if ((focus != NoneWin) &&
+ ((pWin == focus) || (focus == PointerRootWin) ||
+ IsParent(focus, pWin)))
+ event.u.enterLeave.flags |= ELFlagFocus;
+ if (grab)
+ (void)TryClientEvents(rClient(grab), &event, 1, mask,
+ filters[type], grab);
+ else
+ (void)DeliverEventsToWindow(pWin, &event, 1, filters[type],
+ NullGrab, 0);
+ }
+ if ((type == EnterNotify) && (mask & KeymapStateMask))
+ {
+ xKeymapEvent ke;
+
+#ifdef XCSECURITY
+ ClientPtr client = grab ? rClient(grab)
+ : clients[CLIENT_ID(pWin->drawable.id)];
+ if (!SecurityCheckDeviceAccess(client, keybd, FALSE))
+ {
+ bzero((char *)&ke.map[0], 31);
+ }
+ else
+#endif
+ memmove((char *)&ke.map[0], (char *)&keybd->key->down[1], 31);
+ ke.type = KeymapNotify;
+ if (grab)
+ (void)TryClientEvents(rClient(grab), (xEvent *)&ke, 1, mask,
+ KeymapStateMask, grab);
+ else
+ (void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
+ KeymapStateMask, NullGrab, 0);
+ }
+}
+
+static void
+EnterNotifies(WindowPtr ancestor, WindowPtr child, int mode, int detail)
+{
+ WindowPtr parent = child->parent;
+
+ if (ancestor == parent)
+ return;
+ EnterNotifies(ancestor, parent, mode, detail);
+ EnterLeaveEvent(EnterNotify, mode, detail, parent, child->drawable.id);
+}
+
+static void
+LeaveNotifies(WindowPtr child, WindowPtr ancestor, int mode, int detail)
+{
+ register WindowPtr pWin;
+
+ if (ancestor == child)
+ return;
+ for (pWin = child->parent; pWin != ancestor; pWin = pWin->parent)
+ {
+ EnterLeaveEvent(LeaveNotify, mode, detail, pWin, child->drawable.id);
+ child = pWin;
+ }
+}
+
+static void
+DoEnterLeaveEvents(WindowPtr fromWin, WindowPtr toWin, int mode)
+{
+ if (fromWin == toWin)
+ return;
+ if (IsParent(fromWin, toWin))
+ {
+ EnterLeaveEvent(LeaveNotify, mode, NotifyInferior, fromWin, None);
+ EnterNotifies(fromWin, toWin, mode, NotifyVirtual);
+ EnterLeaveEvent(EnterNotify, mode, NotifyAncestor, toWin, None);
+ }
+ else if (IsParent(toWin, fromWin))
+ {
+ EnterLeaveEvent(LeaveNotify, mode, NotifyAncestor, fromWin, None);
+ LeaveNotifies(fromWin, toWin, mode, NotifyVirtual);
+ EnterLeaveEvent(EnterNotify, mode, NotifyInferior, toWin, None);
+ }
+ else
+ { /* neither fromWin nor toWin is descendent of the other */
+ WindowPtr common = CommonAncestor(toWin, fromWin);
+ /* common == NullWindow ==> different screens */
+ EnterLeaveEvent(LeaveNotify, mode, NotifyNonlinear, fromWin, None);
+ LeaveNotifies(fromWin, common, mode, NotifyNonlinearVirtual);
+ EnterNotifies(common, toWin, mode, NotifyNonlinearVirtual);
+ EnterLeaveEvent(EnterNotify, mode, NotifyNonlinear, toWin, None);
+ }
+}
+
+static void
+FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, register WindowPtr pWin)
+{
+ xEvent event;
+
+#ifdef XINPUT
+ if (dev != inputInfo.keyboard)
+ {
+ DeviceFocusEvent(dev, type, mode, detail, pWin);
+ return;
+ }
+#endif
+ event.u.focus.mode = mode;
+ event.u.u.type = type;
+ event.u.u.detail = detail;
+ event.u.focus.window = pWin->drawable.id;
+ (void)DeliverEventsToWindow(pWin, &event, 1, filters[type], NullGrab,
+ 0);
+ if ((type == FocusIn) &&
+ ((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask))
+ {
+ xKeymapEvent ke;
+#ifdef XCSECURITY
+ ClientPtr client = clients[CLIENT_ID(pWin->drawable.id)];
+ if (!SecurityCheckDeviceAccess(client, dev, FALSE))
+ {
+ bzero((char *)&ke.map[0], 31);
+ }
+ else
+#endif
+ memmove((char *)&ke.map[0], (char *)&dev->key->down[1], 31);
+ ke.type = KeymapNotify;
+ (void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
+ KeymapStateMask, NullGrab, 0);
+ }
+}
+
+ /*
+ * recursive because it is easier
+ * no-op if child not descended from ancestor
+ */
+static Bool
+FocusInEvents(
+ DeviceIntPtr dev,
+ WindowPtr ancestor, WindowPtr child, WindowPtr skipChild,
+ int mode, int detail,
+ Bool doAncestor)
+{
+ if (child == NullWindow)
+ return ancestor == NullWindow;
+ if (ancestor == child)
+ {
+ if (doAncestor)
+ FocusEvent(dev, FocusIn, mode, detail, child);
+ return TRUE;
+ }
+ if (FocusInEvents(dev, ancestor, child->parent, skipChild, mode, detail,
+ doAncestor))
+ {
+ if (child != skipChild)
+ FocusEvent(dev, FocusIn, mode, detail, child);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* dies horribly if ancestor is not an ancestor of child */
+static void
+FocusOutEvents(
+ DeviceIntPtr dev,
+ WindowPtr child, WindowPtr ancestor,
+ int mode, int detail,
+ Bool doAncestor)
+{
+ register WindowPtr pWin;
+
+ for (pWin = child; pWin != ancestor; pWin = pWin->parent)
+ FocusEvent(dev, FocusOut, mode, detail, pWin);
+ if (doAncestor)
+ FocusEvent(dev, FocusOut, mode, detail, ancestor);
+}
+
+void
+DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode)
+{
+ int out, in; /* for holding details for to/from
+ PointerRoot/None */
+ int i;
+
+ if (fromWin == toWin)
+ return;
+ out = (fromWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
+ in = (toWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
+ /* wrong values if neither, but then not referenced */
+
+ if ((toWin == NullWindow) || (toWin == PointerRootWin))
+ {
+ if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
+ {
+ if (fromWin == PointerRootWin)
+ FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
+ TRUE);
+ /* Notify all the roots */
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
+ else
+#endif
+ for (i=0; i<screenInfo.numScreens; i++)
+ FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
+ }
+ else
+ {
+ if (IsParent(fromWin, sprite.win))
+ FocusOutEvents(dev, sprite.win, fromWin, mode, NotifyPointer,
+ FALSE);
+ FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
+ /* next call catches the root too, if the screen changed */
+ FocusOutEvents(dev, fromWin->parent, NullWindow, mode,
+ NotifyNonlinearVirtual, FALSE);
+ }
+ /* Notify all the roots */
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ FocusEvent(dev, FocusIn, mode, in, WindowTable[0]);
+ else
+#endif
+ for (i=0; i<screenInfo.numScreens; i++)
+ FocusEvent(dev, FocusIn, mode, in, WindowTable[i]);
+ if (toWin == PointerRootWin)
+ (void)FocusInEvents(dev, ROOT, sprite.win, NullWindow, mode,
+ NotifyPointer, TRUE);
+ }
+ else
+ {
+ if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
+ {
+ if (fromWin == PointerRootWin)
+ FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
+ TRUE);
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
+ else
+#endif
+ for (i=0; i<screenInfo.numScreens; i++)
+ FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
+ if (toWin->parent != NullWindow)
+ (void)FocusInEvents(dev, ROOT, toWin, toWin, mode,
+ NotifyNonlinearVirtual, TRUE);
+ FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
+ if (IsParent(toWin, sprite.win))
+ (void)FocusInEvents(dev, toWin, sprite.win, NullWindow, mode,
+ NotifyPointer, FALSE);
+ }
+ else
+ {
+ if (IsParent(toWin, fromWin))
+ {
+ FocusEvent(dev, FocusOut, mode, NotifyAncestor, fromWin);
+ FocusOutEvents(dev, fromWin->parent, toWin, mode,
+ NotifyVirtual, FALSE);
+ FocusEvent(dev, FocusIn, mode, NotifyInferior, toWin);
+ if ((IsParent(toWin, sprite.win)) &&
+ (sprite.win != fromWin) &&
+ (!IsParent(fromWin, sprite.win)) &&
+ (!IsParent(sprite.win, fromWin)))
+ (void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
+ mode, NotifyPointer, FALSE);
+ }
+ else
+ if (IsParent(fromWin, toWin))
+ {
+ if ((IsParent(fromWin, sprite.win)) &&
+ (sprite.win != fromWin) &&
+ (!IsParent(toWin, sprite.win)) &&
+ (!IsParent(sprite.win, toWin)))
+ FocusOutEvents(dev, sprite.win, fromWin, mode,
+ NotifyPointer, FALSE);
+ FocusEvent(dev, FocusOut, mode, NotifyInferior, fromWin);
+ (void)FocusInEvents(dev, fromWin, toWin, toWin, mode,
+ NotifyVirtual, FALSE);
+ FocusEvent(dev, FocusIn, mode, NotifyAncestor, toWin);
+ }
+ else
+ {
+ /* neither fromWin or toWin is child of other */
+ WindowPtr common = CommonAncestor(toWin, fromWin);
+ /* common == NullWindow ==> different screens */
+ if (IsParent(fromWin, sprite.win))
+ FocusOutEvents(dev, sprite.win, fromWin, mode,
+ NotifyPointer, FALSE);
+ FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
+ if (fromWin->parent != NullWindow)
+ FocusOutEvents(dev, fromWin->parent, common, mode,
+ NotifyNonlinearVirtual, FALSE);
+ if (toWin->parent != NullWindow)
+ (void)FocusInEvents(dev, common, toWin, toWin, mode,
+ NotifyNonlinearVirtual, FALSE);
+ FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
+ if (IsParent(toWin, sprite.win))
+ (void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
+ mode, NotifyPointer, FALSE);
+ }
+ }
+ }
+}
+
+int
+SetInputFocus(
+ ClientPtr client,
+ DeviceIntPtr dev,
+ Window focusID,
+ CARD8 revertTo,
+ Time ctime,
+ Bool followOK)
+{
+ register FocusClassPtr focus;
+ register WindowPtr focusWin;
+ int mode;
+ TimeStamp time;
+
+ UpdateCurrentTime();
+ if ((revertTo != RevertToParent) &&
+ (revertTo != RevertToPointerRoot) &&
+ (revertTo != RevertToNone) &&
+ ((revertTo != RevertToFollowKeyboard) || !followOK))
+ {
+ client->errorValue = revertTo;
+ return BadValue;
+ }
+ time = ClientTimeToServerTime(ctime);
+ if ((focusID == None) || (focusID == PointerRoot))
+ focusWin = (WindowPtr)(long)focusID;
+ else if ((focusID == FollowKeyboard) && followOK)
+ focusWin = inputInfo.keyboard->focus->win;
+ else if (!(focusWin = SecurityLookupWindow(focusID, client,
+ SecurityReadAccess)))
+ return BadWindow;
+ else
+ {
+ /* It is a match error to try to set the input focus to an
+ unviewable window. */
+
+ if(!focusWin->realized)
+ return(BadMatch);
+ }
+ focus = dev->focus;
+ if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, focus->time) == EARLIER))
+ return Success;
+ mode = (dev->grab) ? NotifyWhileGrabbed : NotifyNormal;
+ if (focus->win == FollowKeyboardWin)
+ DoFocusEvents(dev, inputInfo.keyboard->focus->win, focusWin, mode);
+ else
+ DoFocusEvents(dev, focus->win, focusWin, mode);
+ focus->time = time;
+ focus->revert = revertTo;
+ if (focusID == FollowKeyboard)
+ focus->win = FollowKeyboardWin;
+ else
+ focus->win = focusWin;
+ if ((focusWin == NoneWin) || (focusWin == PointerRootWin))
+ focus->traceGood = 0;
+ else
+ {
+ int depth = 0;
+ register WindowPtr pWin;
+
+ for (pWin = focusWin; pWin; pWin = pWin->parent) depth++;
+ if (depth > focus->traceSize)
+ {
+ focus->traceSize = depth+1;
+ Must_have_memory = TRUE; /* XXX */
+ focus->trace = (WindowPtr *)xrealloc(focus->trace,
+ focus->traceSize *
+ sizeof(WindowPtr));
+ Must_have_memory = FALSE; /* XXX */
+ }
+ focus->traceGood = depth;
+ for (pWin = focusWin, depth--; pWin; pWin = pWin->parent, depth--)
+ focus->trace[depth] = pWin;
+ }
+ return Success;
+}
+
+int
+ProcSetInputFocus(client)
+ ClientPtr client;
+{
+ REQUEST(xSetInputFocusReq);
+
+ REQUEST_SIZE_MATCH(xSetInputFocusReq);
+#ifdef XCSECURITY
+ if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
+ return Success;
+#endif
+ return SetInputFocus(client, inputInfo.keyboard, stuff->focus,
+ stuff->revertTo, stuff->time, FALSE);
+}
+
+int
+ProcGetInputFocus(ClientPtr client)
+{
+ xGetInputFocusReply rep;
+ /* REQUEST(xReq); */
+ FocusClassPtr focus = inputInfo.keyboard->focus;
+
+ REQUEST_SIZE_MATCH(xReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ if (focus->win == NoneWin)
+ rep.focus = None;
+ else if (focus->win == PointerRootWin)
+ rep.focus = PointerRoot;
+ else rep.focus = focus->win->drawable.id;
+ rep.revertTo = focus->revert;
+ WriteReplyToClient(client, sizeof(xGetInputFocusReply), &rep);
+ return Success;
+}
+
+int
+ProcGrabPointer(ClientPtr client)
+{
+ xGrabPointerReply rep;
+ DeviceIntPtr device = inputInfo.pointer;
+ GrabPtr grab;
+ WindowPtr pWin, confineTo;
+ CursorPtr cursor, oldCursor;
+ REQUEST(xGrabPointerReq);
+ TimeStamp time;
+
+ REQUEST_SIZE_MATCH(xGrabPointerReq);
+ UpdateCurrentTime();
+ if ((stuff->pointerMode != GrabModeSync) &&
+ (stuff->pointerMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->pointerMode;
+ return BadValue;
+ }
+ if ((stuff->keyboardMode != GrabModeSync) &&
+ (stuff->keyboardMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->keyboardMode;
+ return BadValue;
+ }
+ if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
+ {
+ client->errorValue = stuff->ownerEvents;
+ return BadValue;
+ }
+ if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
+ {
+ client->errorValue = stuff->eventMask;
+ return BadValue;
+ }
+ pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+ if (stuff->confineTo == None)
+ confineTo = NullWindow;
+ else
+ {
+ confineTo = SecurityLookupWindow(stuff->confineTo, client,
+ SecurityReadAccess);
+ if (!confineTo)
+ return BadWindow;
+ }
+ if (stuff->cursor == None)
+ cursor = NullCursor;
+ else
+ {
+ cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+ RT_CURSOR, SecurityReadAccess);
+ if (!cursor)
+ {
+ client->errorValue = stuff->cursor;
+ return BadCursor;
+ }
+ }
+ /* at this point, some sort of reply is guaranteed. */
+ time = ClientTimeToServerTime(stuff->time);
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ grab = device->grab;
+ if ((grab) && !SameClient(grab, client))
+ rep.status = AlreadyGrabbed;
+ else if ((!pWin->realized) ||
+ (confineTo &&
+ !(confineTo->realized && BorderSizeNotEmpty(confineTo))))
+ rep.status = GrabNotViewable;
+ else if (device->sync.frozen &&
+ device->sync.other && !SameClient(device->sync.other, client))
+ rep.status = GrabFrozen;
+ else if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, device->grabTime) == EARLIER))
+ rep.status = GrabInvalidTime;
+ else
+ {
+ GrabRec tempGrab;
+
+ oldCursor = NullCursor;
+ if (grab)
+ {
+ if (grab->confineTo && !confineTo)
+ ConfineCursorToWindow(ROOT, FALSE, FALSE);
+ oldCursor = grab->cursor;
+ }
+ tempGrab.cursor = cursor;
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.ownerEvents = stuff->ownerEvents;
+ tempGrab.eventMask = stuff->eventMask;
+ tempGrab.confineTo = confineTo;
+ tempGrab.window = pWin;
+ tempGrab.keyboardMode = stuff->keyboardMode;
+ tempGrab.pointerMode = stuff->pointerMode;
+ tempGrab.device = device;
+ (*device->ActivateGrab)(device, &tempGrab, time, FALSE);
+ if (oldCursor)
+ FreeCursor (oldCursor, (Cursor)0);
+ rep.status = GrabSuccess;
+ }
+ WriteReplyToClient(client, sizeof(xGrabPointerReply), &rep);
+ return Success;
+}
+
+int
+ProcChangeActivePointerGrab(ClientPtr client)
+{
+ DeviceIntPtr device = inputInfo.pointer;
+ register GrabPtr grab = device->grab;
+ CursorPtr newCursor, oldCursor;
+ REQUEST(xChangeActivePointerGrabReq);
+ TimeStamp time;
+
+ REQUEST_SIZE_MATCH(xChangeActivePointerGrabReq);
+ if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
+ {
+ client->errorValue = stuff->eventMask;
+ return BadValue;
+ }
+ if (stuff->cursor == None)
+ newCursor = NullCursor;
+ else
+ {
+ newCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+ RT_CURSOR, SecurityReadAccess);
+ if (!newCursor)
+ {
+ client->errorValue = stuff->cursor;
+ return BadCursor;
+ }
+ }
+ if (!grab)
+ return Success;
+ if (!SameClient(grab, client))
+ return Success;
+ time = ClientTimeToServerTime(stuff->time);
+ if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, device->grabTime) == EARLIER))
+ return Success;
+ oldCursor = grab->cursor;
+ grab->cursor = newCursor;
+ if (newCursor)
+ newCursor->refcnt++;
+ PostNewCursor();
+ if (oldCursor)
+ FreeCursor(oldCursor, (Cursor)0);
+ grab->eventMask = stuff->eventMask;
+ return Success;
+}
+
+int
+ProcUngrabPointer(ClientPtr client)
+{
+ DeviceIntPtr device = inputInfo.pointer;
+ GrabPtr grab;
+ TimeStamp time;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ UpdateCurrentTime();
+ grab = device->grab;
+ time = ClientTimeToServerTime(stuff->id);
+ if ((CompareTimeStamps(time, currentTime) != LATER) &&
+ (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
+ (grab) && SameClient(grab, client))
+ (*device->DeactivateGrab)(device);
+ return Success;
+}
+
+int
+GrabDevice(register ClientPtr client, register DeviceIntPtr dev,
+ unsigned this_mode, unsigned other_mode, Window grabWindow,
+ unsigned ownerEvents, Time ctime, Mask mask, CARD8 *status)
+{
+ register WindowPtr pWin;
+ register GrabPtr grab;
+ TimeStamp time;
+
+ UpdateCurrentTime();
+ if ((this_mode != GrabModeSync) && (this_mode != GrabModeAsync))
+ {
+ client->errorValue = this_mode;
+ return BadValue;
+ }
+ if ((other_mode != GrabModeSync) && (other_mode != GrabModeAsync))
+ {
+ client->errorValue = other_mode;
+ return BadValue;
+ }
+ if ((ownerEvents != xFalse) && (ownerEvents != xTrue))
+ {
+ client->errorValue = ownerEvents;
+ return BadValue;
+ }
+ pWin = SecurityLookupWindow(grabWindow, client, SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+ time = ClientTimeToServerTime(ctime);
+ grab = dev->grab;
+ if (grab && !SameClient(grab, client))
+ *status = AlreadyGrabbed;
+ else if (!pWin->realized)
+ *status = GrabNotViewable;
+ else if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, dev->grabTime) == EARLIER))
+ *status = GrabInvalidTime;
+ else if (dev->sync.frozen &&
+ dev->sync.other && !SameClient(dev->sync.other, client))
+ *status = GrabFrozen;
+ else
+ {
+ GrabRec tempGrab;
+
+ tempGrab.window = pWin;
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.ownerEvents = ownerEvents;
+ tempGrab.keyboardMode = this_mode;
+ tempGrab.pointerMode = other_mode;
+ tempGrab.eventMask = mask;
+ tempGrab.device = dev;
+ (*dev->ActivateGrab)(dev, &tempGrab, time, FALSE);
+ *status = GrabSuccess;
+ }
+ return Success;
+}
+
+int
+ProcGrabKeyboard(ClientPtr client)
+{
+ xGrabKeyboardReply rep;
+ REQUEST(xGrabKeyboardReq);
+ int result;
+
+ REQUEST_SIZE_MATCH(xGrabKeyboardReq);
+#ifdef XCSECURITY
+ if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
+ {
+ result = Success;
+ rep.status = AlreadyGrabbed;
+ }
+ else
+#endif
+ result = GrabDevice(client, inputInfo.keyboard, stuff->keyboardMode,
+ stuff->pointerMode, stuff->grabWindow,
+ stuff->ownerEvents, stuff->time,
+ KeyPressMask | KeyReleaseMask, &rep.status);
+ if (result != Success)
+ return result;
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ WriteReplyToClient(client, sizeof(xGrabKeyboardReply), &rep);
+ return Success;
+}
+
+int
+ProcUngrabKeyboard(ClientPtr client)
+{
+ DeviceIntPtr device = inputInfo.keyboard;
+ GrabPtr grab;
+ TimeStamp time;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ UpdateCurrentTime();
+ grab = device->grab;
+ time = ClientTimeToServerTime(stuff->id);
+ if ((CompareTimeStamps(time, currentTime) != LATER) &&
+ (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
+ (grab) && SameClient(grab, client))
+ (*device->DeactivateGrab)(device);
+ return Success;
+}
+
+int
+ProcQueryPointer(ClientPtr client)
+{
+ xQueryPointerReply rep;
+ WindowPtr pWin, t;
+ REQUEST(xResourceReq);
+ DeviceIntPtr mouse = inputInfo.pointer;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = SecurityLookupWindow(stuff->id, client, SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+ if (mouse->valuator->motionHintWindow)
+ MaybeStopHint(mouse, client);
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.mask = mouse->button->state | inputInfo.keyboard->key->state;
+ rep.length = 0;
+ rep.root = (ROOT)->drawable.id;
+ rep.rootX = sprite.hot.x;
+ rep.rootY = sprite.hot.y;
+ rep.child = None;
+ if (sprite.hot.pScreen == pWin->drawable.pScreen)
+ {
+ rep.sameScreen = xTrue;
+ rep.winX = sprite.hot.x - pWin->drawable.x;
+ rep.winY = sprite.hot.y - pWin->drawable.y;
+ for (t = sprite.win; t; t = t->parent)
+ if (t->parent == pWin)
+ {
+ rep.child = t->drawable.id;
+ break;
+ }
+ }
+ else
+ {
+ rep.sameScreen = xFalse;
+ rep.winX = 0;
+ rep.winY = 0;
+ }
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ rep.rootX += panoramiXdataPtr[0].x;
+ rep.rootY += panoramiXdataPtr[0].y;
+ if(stuff->id == rep.root) {
+ rep.winX += panoramiXdataPtr[0].x;
+ rep.winY += panoramiXdataPtr[0].y;
+ }
+ }
+#endif
+
+ WriteReplyToClient(client, sizeof(xQueryPointerReply), &rep);
+
+ return(Success);
+}
+
+void
+InitEvents()
+{
+ int i;
+
+ sprite.hot.pScreen = sprite.hotPhys.pScreen = (ScreenPtr)NULL;
+ inputInfo.numDevices = 0;
+ inputInfo.devices = (DeviceIntPtr)NULL;
+ inputInfo.off_devices = (DeviceIntPtr)NULL;
+ inputInfo.keyboard = (DeviceIntPtr)NULL;
+ inputInfo.pointer = (DeviceIntPtr)NULL;
+ if (spriteTraceSize == 0)
+ {
+ spriteTraceSize = 32;
+ spriteTrace = (WindowPtr *)xalloc(32*sizeof(WindowPtr));
+ if (!spriteTrace)
+ FatalError("failed to allocate spriteTrace");
+ }
+ spriteTraceGood = 0;
+ lastEventMask = OwnerGrabButtonMask;
+ filters[MotionNotify] = PointerMotionMask;
+#ifdef XEVIE
+ xeviewin =
+#endif
+ sprite.win = NullWindow;
+ sprite.current = NullCursor;
+ sprite.hotLimits.x1 = 0;
+ sprite.hotLimits.y1 = 0;
+ sprite.hotLimits.x2 = 0;
+ sprite.hotLimits.y2 = 0;
+ sprite.confined = FALSE;
+ syncEvents.replayDev = (DeviceIntPtr)NULL;
+ syncEvents.replayWin = NullWindow;
+ while (syncEvents.pending)
+ {
+ QdEventPtr next = syncEvents.pending->next;
+ xfree(syncEvents.pending);
+ syncEvents.pending = next;
+ }
+ syncEvents.pendtail = &syncEvents.pending;
+ syncEvents.playingEvents = FALSE;
+ syncEvents.time.months = 0;
+ syncEvents.time.milliseconds = 0; /* hardly matters */
+ currentTime.months = 0;
+ currentTime.milliseconds = GetTimeInMillis();
+ lastDeviceEventTime = currentTime;
+ for (i = 0; i < DNPMCOUNT; i++)
+ {
+ DontPropagateMasks[i] = 0;
+ DontPropagateRefCnts[i] = 0;
+ }
+}
+
+void
+CloseDownEvents(void)
+{
+ xfree(spriteTrace);
+ spriteTrace = NULL;
+ spriteTraceSize = 0;
+}
+
+int
+ProcSendEvent(ClientPtr client)
+{
+ WindowPtr pWin;
+ WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */
+ REQUEST(xSendEventReq);
+
+ REQUEST_SIZE_MATCH(xSendEventReq);
+
+ /* The client's event type must be a core event type or one defined by an
+ extension. */
+
+
+#ifdef NXAGENT_CLIPBOARD
+
+ if (stuff -> event.u.u.type == SelectionNotify)
+ {
+ extern int nxagentSendNotify(xEvent*);
+ if (nxagentSendNotify(&stuff->event) == 1)
+ return Success;
+ }
+#endif
+
+ if ( ! ((stuff->event.u.u.type > X_Reply &&
+ stuff->event.u.u.type < LASTEvent) ||
+ (stuff->event.u.u.type >= EXTENSION_EVENT_BASE &&
+ stuff->event.u.u.type < (unsigned)lastEvent)))
+ {
+ client->errorValue = stuff->event.u.u.type;
+ return BadValue;
+ }
+ if (stuff->event.u.u.type == ClientMessage &&
+ stuff->event.u.u.detail != 8 &&
+ stuff->event.u.u.detail != 16 &&
+ stuff->event.u.u.detail != 32 &&
+ !permitOldBugs)
+ {
+ client->errorValue = stuff->event.u.u.detail;
+ return BadValue;
+ }
+ if ((stuff->eventMask & ~AllEventMasks) && !permitOldBugs)
+ {
+ client->errorValue = stuff->eventMask;
+ return BadValue;
+ }
+
+ if (stuff->destination == PointerWindow)
+ pWin = sprite.win;
+ else if (stuff->destination == InputFocus)
+ {
+ WindowPtr inputFocus = inputInfo.keyboard->focus->win;
+
+ if (inputFocus == NoneWin)
+ return Success;
+
+ /* If the input focus is PointerRootWin, send the event to where
+ the pointer is if possible, then perhaps propogate up to root. */
+ if (inputFocus == PointerRootWin)
+ inputFocus = ROOT;
+
+ if (IsParent(inputFocus, sprite.win))
+ {
+ effectiveFocus = inputFocus;
+ pWin = sprite.win;
+ }
+ else
+ effectiveFocus = pWin = inputFocus;
+ }
+ else
+ pWin = SecurityLookupWindow(stuff->destination, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+ if ((stuff->propagate != xFalse) && (stuff->propagate != xTrue))
+ {
+ client->errorValue = stuff->propagate;
+ return BadValue;
+ }
+ stuff->event.u.u.type |= 0x80;
+ if (stuff->propagate)
+ {
+ for (;pWin; pWin = pWin->parent)
+ {
+ if (DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
+ NullGrab, 0))
+ return Success;
+ if (pWin == effectiveFocus)
+ return Success;
+ stuff->eventMask &= ~wDontPropagateMask(pWin);
+ if (!stuff->eventMask)
+ break;
+ }
+ }
+ else
+ (void)DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
+ NullGrab, 0);
+ return Success;
+}
+
+int
+ProcUngrabKey(ClientPtr client)
+{
+ REQUEST(xUngrabKeyReq);
+ WindowPtr pWin;
+ GrabRec tempGrab;
+ DeviceIntPtr keybd = inputInfo.keyboard;
+
+ REQUEST_SIZE_MATCH(xUngrabKeyReq);
+ pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+
+ if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
+ (stuff->key < keybd->key->curKeySyms.minKeyCode))
+ && (stuff->key != AnyKey))
+ {
+ client->errorValue = stuff->key;
+ return BadValue;
+ }
+ if ((stuff->modifiers != AnyModifier) &&
+ (stuff->modifiers & ~AllModifiersMask))
+ {
+ client->errorValue = stuff->modifiers;
+ return BadValue;
+ }
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.device = keybd;
+ tempGrab.window = pWin;
+ tempGrab.modifiersDetail.exact = stuff->modifiers;
+ tempGrab.modifiersDetail.pMask = NULL;
+ tempGrab.modifierDevice = inputInfo.keyboard;
+ tempGrab.type = KeyPress;
+ tempGrab.detail.exact = stuff->key;
+ tempGrab.detail.pMask = NULL;
+
+ if (!DeletePassiveGrabFromList(&tempGrab))
+ return(BadAlloc);
+ return(Success);
+}
+
+int
+ProcGrabKey(ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xGrabKeyReq);
+ GrabPtr grab;
+ DeviceIntPtr keybd = inputInfo.keyboard;
+
+ REQUEST_SIZE_MATCH(xGrabKeyReq);
+ if ((stuff->ownerEvents != xTrue) && (stuff->ownerEvents != xFalse))
+ {
+ client->errorValue = stuff->ownerEvents;
+ return(BadValue);
+ }
+ if ((stuff->pointerMode != GrabModeSync) &&
+ (stuff->pointerMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->pointerMode;
+ return BadValue;
+ }
+ if ((stuff->keyboardMode != GrabModeSync) &&
+ (stuff->keyboardMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->keyboardMode;
+ return BadValue;
+ }
+ if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
+ (stuff->key < keybd->key->curKeySyms.minKeyCode))
+ && (stuff->key != AnyKey))
+ {
+ client->errorValue = stuff->key;
+ return BadValue;
+ }
+ if ((stuff->modifiers != AnyModifier) &&
+ (stuff->modifiers & ~AllModifiersMask))
+ {
+ client->errorValue = stuff->modifiers;
+ return BadValue;
+ }
+ pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+
+ grab = CreateGrab(client->index, keybd, pWin,
+ (Mask)(KeyPressMask | KeyReleaseMask), (Bool)stuff->ownerEvents,
+ (Bool)stuff->keyboardMode, (Bool)stuff->pointerMode,
+ keybd, stuff->modifiers, KeyPress, stuff->key,
+ NullWindow, NullCursor);
+ if (!grab)
+ return BadAlloc;
+ return AddPassiveGrabToList(grab);
+}
+
+
+int
+ProcGrabButton(ClientPtr client)
+{
+ WindowPtr pWin, confineTo;
+ REQUEST(xGrabButtonReq);
+ CursorPtr cursor;
+ GrabPtr grab;
+
+ REQUEST_SIZE_MATCH(xGrabButtonReq);
+ if ((stuff->pointerMode != GrabModeSync) &&
+ (stuff->pointerMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->pointerMode;
+ return BadValue;
+ }
+ if ((stuff->keyboardMode != GrabModeSync) &&
+ (stuff->keyboardMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->keyboardMode;
+ return BadValue;
+ }
+ if ((stuff->modifiers != AnyModifier) &&
+ (stuff->modifiers & ~AllModifiersMask))
+ {
+ client->errorValue = stuff->modifiers;
+ return BadValue;
+ }
+ if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
+ {
+ client->errorValue = stuff->ownerEvents;
+ return BadValue;
+ }
+ if (stuff->eventMask & ~PointerGrabMask)
+ {
+ client->errorValue = stuff->eventMask;
+ return BadValue;
+ }
+ pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+ if (stuff->confineTo == None)
+ confineTo = NullWindow;
+ else {
+ confineTo = SecurityLookupWindow(stuff->confineTo, client,
+ SecurityReadAccess);
+ if (!confineTo)
+ return BadWindow;
+ }
+ if (stuff->cursor == None)
+ cursor = NullCursor;
+ else
+ {
+ cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+ RT_CURSOR, SecurityReadAccess);
+ if (!cursor)
+ {
+ client->errorValue = stuff->cursor;
+ return BadCursor;
+ }
+ }
+
+
+ grab = CreateGrab(client->index, inputInfo.pointer, pWin,
+ permitOldBugs ? (Mask)(stuff->eventMask |
+ ButtonPressMask | ButtonReleaseMask) :
+ (Mask)stuff->eventMask,
+ (Bool)stuff->ownerEvents, (Bool) stuff->keyboardMode,
+ (Bool)stuff->pointerMode, inputInfo.keyboard, stuff->modifiers,
+ ButtonPress, stuff->button, confineTo, cursor);
+ if (!grab)
+ return BadAlloc;
+ return AddPassiveGrabToList(grab);
+}
+
+int
+ProcUngrabButton(ClientPtr client)
+{
+ REQUEST(xUngrabButtonReq);
+ WindowPtr pWin;
+ GrabRec tempGrab;
+
+ REQUEST_SIZE_MATCH(xUngrabButtonReq);
+ if ((stuff->modifiers != AnyModifier) &&
+ (stuff->modifiers & ~AllModifiersMask))
+ {
+ client->errorValue = stuff->modifiers;
+ return BadValue;
+ }
+ pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.device = inputInfo.pointer;
+ tempGrab.window = pWin;
+ tempGrab.modifiersDetail.exact = stuff->modifiers;
+ tempGrab.modifiersDetail.pMask = NULL;
+ tempGrab.modifierDevice = inputInfo.keyboard;
+ tempGrab.type = ButtonPress;
+ tempGrab.detail.exact = stuff->button;
+ tempGrab.detail.pMask = NULL;
+
+ if (!DeletePassiveGrabFromList(&tempGrab))
+ return(BadAlloc);
+ return(Success);
+}
+
+void
+DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources)
+{
+ WindowPtr parent;
+ DeviceIntPtr mouse = inputInfo.pointer;
+ DeviceIntPtr keybd = inputInfo.keyboard;
+ FocusClassPtr focus = keybd->focus;
+ OtherClientsPtr oc;
+ GrabPtr passive;
+
+
+ /* Deactivate any grabs performed on this window, before making any
+ input focus changes. */
+
+ if (mouse->grab &&
+ ((mouse->grab->window == pWin) || (mouse->grab->confineTo == pWin)))
+ (*mouse->DeactivateGrab)(mouse);
+
+ /* Deactivating a keyboard grab should cause focus events. */
+
+ if (keybd->grab && (keybd->grab->window == pWin))
+ (*keybd->DeactivateGrab)(keybd);
+
+ /* If the focus window is a root window (ie. has no parent) then don't
+ delete the focus from it. */
+
+ if ((pWin == focus->win) && (pWin->parent != NullWindow))
+ {
+ int focusEventMode = NotifyNormal;
+
+ /* If a grab is in progress, then alter the mode of focus events. */
+
+ if (keybd->grab)
+ focusEventMode = NotifyWhileGrabbed;
+
+ switch (focus->revert)
+ {
+ case RevertToNone:
+ DoFocusEvents(keybd, pWin, NoneWin, focusEventMode);
+ focus->win = NoneWin;
+ focus->traceGood = 0;
+ break;
+ case RevertToParent:
+ parent = pWin;
+ do
+ {
+ parent = parent->parent;
+ focus->traceGood--;
+ } while (!parent->realized
+/* This would be a good protocol change -- windows being reparented
+ during SaveSet processing would cause the focus to revert to the
+ nearest enclosing window which will survive the death of the exiting
+ client, instead of ending up reverting to a dying window and thence
+ to None
+ */
+#ifdef NOTDEF
+ || clients[CLIENT_ID(parent->drawable.id)]->clientGone
+#endif
+ );
+ DoFocusEvents(keybd, pWin, parent, focusEventMode);
+ focus->win = parent;
+ focus->revert = RevertToNone;
+ break;
+ case RevertToPointerRoot:
+ DoFocusEvents(keybd, pWin, PointerRootWin, focusEventMode);
+ focus->win = PointerRootWin;
+ focus->traceGood = 0;
+ break;
+ }
+ }
+
+ if (mouse->valuator->motionHintWindow == pWin)
+ mouse->valuator->motionHintWindow = NullWindow;
+
+ if (freeResources)
+ {
+ if (pWin->dontPropagate)
+ DontPropagateRefCnts[pWin->dontPropagate]--;
+ while ( (oc = wOtherClients(pWin)) )
+ FreeResource(oc->resource, RT_NONE);
+ while ( (passive = wPassiveGrabs(pWin)) )
+ FreeResource(passive->resource, RT_NONE);
+ }
+#ifdef XINPUT
+ DeleteWindowFromAnyExtEvents(pWin, freeResources);
+#endif
+}
+
+/**
+ * Call this whenever some window at or below pWin has changed geometry
+ */
+void
+CheckCursorConfinement(WindowPtr pWin)
+{
+ GrabPtr grab = inputInfo.pointer->grab;
+ WindowPtr confineTo;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) return;
+#endif
+
+ if (grab && (confineTo = grab->confineTo))
+ {
+ if (!BorderSizeNotEmpty(confineTo))
+ (*inputInfo.pointer->DeactivateGrab)(inputInfo.pointer);
+ else if ((pWin == confineTo) || IsParent(pWin, confineTo))
+ ConfineCursorToWindow(confineTo, TRUE, TRUE);
+ }
+}
+
+Mask
+EventMaskForClient(WindowPtr pWin, ClientPtr client)
+{
+ register OtherClientsPtr other;
+
+ if (wClient (pWin) == client)
+ return pWin->eventMask;
+ for (other = wOtherClients(pWin); other; other = other->next)
+ {
+ if (SameClient(other, client))
+ return other->mask;
+ }
+ return 0;
+}
+
+int
+ProcRecolorCursor(ClientPtr client)
+{
+ CursorPtr pCursor;
+ int nscr;
+ ScreenPtr pscr;
+ Bool displayed;
+ REQUEST(xRecolorCursorReq);
+
+ REQUEST_SIZE_MATCH(xRecolorCursorReq);
+ pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+ RT_CURSOR, SecurityWriteAccess);
+ if ( !pCursor)
+ {
+ client->errorValue = stuff->cursor;
+ return (BadCursor);
+ }
+
+ pCursor->foreRed = stuff->foreRed;
+ pCursor->foreGreen = stuff->foreGreen;
+ pCursor->foreBlue = stuff->foreBlue;
+
+ pCursor->backRed = stuff->backRed;
+ pCursor->backGreen = stuff->backGreen;
+ pCursor->backBlue = stuff->backBlue;
+
+ for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
+ {
+ pscr = screenInfo.screens[nscr];
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ displayed = (pscr == sprite.screen);
+ else
+#endif
+ displayed = (pscr == sprite.hotPhys.pScreen);
+ ( *pscr->RecolorCursor)(pscr, pCursor,
+ (pCursor == sprite.current) && displayed);
+ }
+ return (Success);
+}
+
+void
+WriteEventsToClient(ClientPtr pClient, int count, xEvent *events)
+{
+#ifdef PANORAMIX
+ xEvent eventCopy;
+#endif
+ xEvent eventTo, *eventFrom;
+ int i;
+
+#ifdef XKB
+ if ((!noXkbExtension)&&(!XkbFilterEvents(pClient, count, events)))
+ return;
+#endif
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension &&
+ (panoramiXdataPtr[0].x || panoramiXdataPtr[0].y))
+ {
+ switch(events->u.u.type) {
+ case MotionNotify:
+ case ButtonPress:
+ case ButtonRelease:
+ case KeyPress:
+ case KeyRelease:
+ case EnterNotify:
+ case LeaveNotify:
+ /*
+ When multiple clients want the same event DeliverEventsToWindow
+ passes the same event structure multiple times so we can't
+ modify the one passed to us
+ */
+ count = 1; /* should always be 1 */
+ memcpy(&eventCopy, events, sizeof(xEvent));
+ eventCopy.u.keyButtonPointer.rootX += panoramiXdataPtr[0].x;
+ eventCopy.u.keyButtonPointer.rootY += panoramiXdataPtr[0].y;
+ if(eventCopy.u.keyButtonPointer.event ==
+ eventCopy.u.keyButtonPointer.root)
+ {
+ eventCopy.u.keyButtonPointer.eventX += panoramiXdataPtr[0].x;
+ eventCopy.u.keyButtonPointer.eventY += panoramiXdataPtr[0].y;
+ }
+ events = &eventCopy;
+ break;
+ default: break;
+ }
+ }
+#endif
+
+ if (EventCallback)
+ {
+ EventInfoRec eventinfo;
+ eventinfo.client = pClient;
+ eventinfo.events = events;
+ eventinfo.count = count;
+ CallCallbacks(&EventCallback, (pointer)&eventinfo);
+ }
+ if(pClient->swapped)
+ {
+ for(i = 0; i < count; i++)
+ {
+ eventFrom = &events[i];
+ /* Remember to strip off the leading bit of type in case
+ this event was sent with "SendEvent." */
+ (*EventSwapVector[eventFrom->u.u.type & 0177])
+ (eventFrom, &eventTo);
+ (void)WriteToClient(pClient, sizeof(xEvent), (char *)&eventTo);
+ }
+ }
+ else
+ {
+ (void)WriteToClient(pClient, count * sizeof(xEvent), (char *) events);
+ }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
new file mode 100644
index 000000000..91e290996
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
@@ -0,0 +1,4827 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/* $XdotOrg: xc/programs/Xserver/dix/events.c,v 1.17 2005/08/25 22:11:04 anholt Exp $ */
+/* $XFree86: xc/programs/Xserver/dix/events.c,v 3.51 2004/01/12 17:04:52 tsi Exp $ */
+/************************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+********************************************************/
+
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+/*****************************************************************
+
+Copyright 2003-2005 Sun Microsystems, Inc.
+
+All rights reserved.
+
+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, and/or sell copies of the Software, and to permit persons
+to whom the Software is furnished to do so, provided that the above
+copyright notice(s) and this permission notice appear in all copies of
+the Software and that both the above copyright notice(s) and this
+permission notice appear in supporting documentation.
+
+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
+OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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.
+
+Except as contained in this notice, the name of a copyright holder
+shall not be used in advertising or otherwise to promote the sale, use
+or other dealings in this Software without prior written authorization
+of the copyright holder.
+
+******************************************************************/
+
+/* $Xorg: events.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "Xlib.h"
+#include "misc.h"
+#include "resource.h"
+#define NEED_EVENTS
+#define NEED_REPLIES
+#include <X11/Xproto.h>
+#include "windowstr.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "cursorstr.h"
+
+#include "dixstruct.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#include "globals.h"
+
+#ifdef XKB
+#include <X11/extensions/XKBsrv.h>
+extern Bool XkbFilterEvents(ClientPtr, int, xEvent *);
+#endif
+
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+
+#ifdef XEVIE
+extern WindowPtr *WindowTable;
+extern int xevieFlag;
+extern int xevieClientIndex;
+extern DeviceIntPtr xeviemouse;
+extern DeviceIntPtr xeviekb;
+extern Mask xevieMask;
+extern Mask xevieFilters[128];
+extern int xevieEventSent;
+extern int xevieKBEventSent;
+int xeviegrabState = 0;
+xEvent *xeviexE;
+#endif
+
+#include <X11/extensions/XIproto.h>
+#include "exevents.h"
+#include "extnsionst.h"
+
+#include "dixevents.h"
+#include "dixgrabs.h"
+#include "../../dix/dispatch.h"
+
+#include "NXlib.h"
+
+#include "Events.h"
+#include "Windows.h"
+#include "Args.h"
+
+extern Display *nxagentDisplay;
+
+extern WindowPtr nxagentLastEnteredWindow;
+
+#define EXTENSION_EVENT_BASE 64
+
+#define NoSuchEvent 0x80000000 /* so doesn't match NoEventMask */
+#define StructureAndSubMask ( StructureNotifyMask | SubstructureNotifyMask )
+#define AllButtonsMask ( \
+ Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask )
+#define MotionMask ( \
+ PointerMotionMask | Button1MotionMask | \
+ Button2MotionMask | Button3MotionMask | Button4MotionMask | \
+ Button5MotionMask | ButtonMotionMask )
+#define PropagateMask ( \
+ KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \
+ MotionMask )
+#define PointerGrabMask ( \
+ ButtonPressMask | ButtonReleaseMask | \
+ EnterWindowMask | LeaveWindowMask | \
+ PointerMotionHintMask | KeymapStateMask | \
+ MotionMask )
+#define AllModifiersMask ( \
+ ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \
+ Mod3Mask | Mod4Mask | Mod5Mask )
+#define AllEventMasks (lastEventMask|(lastEventMask-1))
+/*
+ * The following relies on the fact that the Button<n>MotionMasks are equal
+ * to the corresponding Button<n>Masks from the current modifier/button state.
+ */
+#define Motion_Filter(class) (PointerMotionMask | \
+ (class)->state | (class)->motionMask)
+
+
+#define WID(w) ((w) ? ((w)->drawable.id) : 0)
+
+#define XE_KBPTR (xE->u.keyButtonPointer)
+
+
+#define rClient(obj) (clients[CLIENT_ID((obj)->resource)])
+
+CallbackListPtr EventCallback;
+CallbackListPtr DeviceEventCallback;
+
+#define DNPMCOUNT 8
+
+Mask DontPropagateMasks[DNPMCOUNT];
+static int DontPropagateRefCnts[DNPMCOUNT];
+
+#ifdef DEBUG
+static debug_events = 0;
+#endif
+InputInfo inputInfo;
+
+static struct {
+ QdEventPtr pending, *pendtail;
+ DeviceIntPtr replayDev; /* kludgy rock to put flag for */
+ WindowPtr replayWin; /* ComputeFreezes */
+ Bool playingEvents;
+ TimeStamp time;
+} syncEvents;
+
+/*
+ * The window trace information is used to avoid having to compute all the
+ * windows between the root and the current pointer window each time a button
+ * or key goes down. The grabs on each of those windows must be checked.
+ */
+static WindowPtr *spriteTrace = (WindowPtr *)NULL;
+#define ROOT spriteTrace[0]
+static int spriteTraceSize = 0;
+static int spriteTraceGood;
+
+static struct {
+ CursorPtr current;
+ BoxRec hotLimits; /* logical constraints of hot spot */
+ Bool confined; /* confined to screen */
+#if defined(SHAPE) || defined(PANORAMIX)
+ RegionPtr hotShape; /* additional logical shape constraint */
+#endif
+ BoxRec physLimits; /* physical constraints of hot spot */
+ WindowPtr win; /* window of logical position */
+ HotSpot hot; /* logical pointer position */
+ HotSpot hotPhys; /* physical pointer position */
+#ifdef PANORAMIX
+ ScreenPtr screen; /* all others are in Screen 0 coordinates */
+ RegionRec Reg1; /* Region 1 for confining motion */
+ RegionRec Reg2; /* Region 2 for confining virtual motion */
+ WindowPtr windows[MAXSCREENS];
+ WindowPtr confineWin; /* confine window */
+#endif
+} sprite; /* info about the cursor sprite */
+
+#ifdef XEVIE
+WindowPtr xeviewin;
+HotSpot xeviehot;
+#endif
+
+static void DoEnterLeaveEvents(
+ WindowPtr fromWin,
+ WindowPtr toWin,
+ int mode
+);
+
+static WindowPtr XYToWindow(
+ int x,
+ int y
+);
+
+extern int lastEvent;
+
+static Mask lastEventMask;
+
+#ifdef XINPUT
+extern int DeviceMotionNotify;
+#endif
+
+#define CantBeFiltered NoEventMask
+static Mask filters[128] =
+{
+ NoSuchEvent, /* 0 */
+ NoSuchEvent, /* 1 */
+ KeyPressMask, /* KeyPress */
+ KeyReleaseMask, /* KeyRelease */
+ ButtonPressMask, /* ButtonPress */
+ ButtonReleaseMask, /* ButtonRelease */
+ PointerMotionMask, /* MotionNotify (initial state) */
+ EnterWindowMask, /* EnterNotify */
+ LeaveWindowMask, /* LeaveNotify */
+ FocusChangeMask, /* FocusIn */
+ FocusChangeMask, /* FocusOut */
+ KeymapStateMask, /* KeymapNotify */
+ ExposureMask, /* Expose */
+ CantBeFiltered, /* GraphicsExpose */
+ CantBeFiltered, /* NoExpose */
+ VisibilityChangeMask, /* VisibilityNotify */
+ SubstructureNotifyMask, /* CreateNotify */
+ StructureAndSubMask, /* DestroyNotify */
+ StructureAndSubMask, /* UnmapNotify */
+ StructureAndSubMask, /* MapNotify */
+ SubstructureRedirectMask, /* MapRequest */
+ StructureAndSubMask, /* ReparentNotify */
+ StructureAndSubMask, /* ConfigureNotify */
+ SubstructureRedirectMask, /* ConfigureRequest */
+ StructureAndSubMask, /* GravityNotify */
+ ResizeRedirectMask, /* ResizeRequest */
+ StructureAndSubMask, /* CirculateNotify */
+ SubstructureRedirectMask, /* CirculateRequest */
+ PropertyChangeMask, /* PropertyNotify */
+ CantBeFiltered, /* SelectionClear */
+ CantBeFiltered, /* SelectionRequest */
+ CantBeFiltered, /* SelectionNotify */
+ ColormapChangeMask, /* ColormapNotify */
+ CantBeFiltered, /* ClientMessage */
+ CantBeFiltered /* MappingNotify */
+};
+
+static CARD8 criticalEvents[32] =
+{
+ 0x7c /* key and button events */
+};
+
+#ifdef PANORAMIX
+
+static void ConfineToShape(RegionPtr shape, int *px, int *py);
+static void SyntheticMotion(int x, int y);
+static void PostNewCursor(void);
+
+static Bool
+XineramaSetCursorPosition(
+ int x,
+ int y,
+ Bool generateEvent
+){
+ ScreenPtr pScreen;
+ BoxRec box;
+ int i;
+
+ /* x,y are in Screen 0 coordinates. We need to decide what Screen
+ to send the message too and what the coordinates relative to
+ that screen are. */
+
+ pScreen = sprite.screen;
+ x += panoramiXdataPtr[0].x;
+ y += panoramiXdataPtr[0].y;
+
+ if(!POINT_IN_REGION(pScreen, &XineramaScreenRegions[pScreen->myNum],
+ x, y, &box))
+ {
+ FOR_NSCREENS(i)
+ {
+ if(i == pScreen->myNum)
+ continue;
+ if(POINT_IN_REGION(pScreen, &XineramaScreenRegions[i], x, y, &box))
+ {
+ pScreen = screenInfo.screens[i];
+ break;
+ }
+ }
+ }
+
+ sprite.screen = pScreen;
+ sprite.hotPhys.x = x - panoramiXdataPtr[0].x;
+ sprite.hotPhys.y = y - panoramiXdataPtr[0].y;
+ x -= panoramiXdataPtr[pScreen->myNum].x;
+ y -= panoramiXdataPtr[pScreen->myNum].y;
+
+ return (*pScreen->SetCursorPosition)(pScreen, x, y, generateEvent);
+}
+
+
+static void
+XineramaConstrainCursor(void)
+{
+ ScreenPtr pScreen = sprite.screen;
+ BoxRec newBox = sprite.physLimits;
+
+ /* Translate the constraining box to the screen
+ the sprite is actually on */
+ newBox.x1 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x;
+ newBox.x2 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x;
+ newBox.y1 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
+ newBox.y2 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
+
+ (* pScreen->ConstrainCursor)(pScreen, &newBox);
+}
+
+static void
+XineramaCheckPhysLimits(
+ CursorPtr cursor,
+ Bool generateEvents
+){
+ HotSpot new;
+
+ if (!cursor)
+ return;
+
+ new = sprite.hotPhys;
+
+ /* I don't care what the DDX has to say about it */
+ sprite.physLimits = sprite.hotLimits;
+
+ /* constrain the pointer to those limits */
+ if (new.x < sprite.physLimits.x1)
+ new.x = sprite.physLimits.x1;
+ else
+ if (new.x >= sprite.physLimits.x2)
+ new.x = sprite.physLimits.x2 - 1;
+ if (new.y < sprite.physLimits.y1)
+ new.y = sprite.physLimits.y1;
+ else
+ if (new.y >= sprite.physLimits.y2)
+ new.y = sprite.physLimits.y2 - 1;
+
+ if (sprite.hotShape) /* more work if the shape is a mess */
+ ConfineToShape(sprite.hotShape, &new.x, &new.y);
+
+ if((new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
+ {
+ XineramaSetCursorPosition (new.x, new.y, generateEvents);
+ if (!generateEvents)
+ SyntheticMotion(new.x, new.y);
+ }
+
+ /* Tell DDX what the limits are */
+ XineramaConstrainCursor();
+}
+
+
+static Bool
+XineramaSetWindowPntrs(WindowPtr pWin)
+{
+ if(pWin == WindowTable[0]) {
+ memcpy(sprite.windows, WindowTable,
+ PanoramiXNumScreens*sizeof(WindowPtr));
+ } else {
+ PanoramiXRes *win;
+ int i;
+
+ win = (PanoramiXRes*)LookupIDByType(pWin->drawable.id, XRT_WINDOW);
+
+ if(!win)
+ return FALSE;
+
+ for(i = 0; i < PanoramiXNumScreens; i++) {
+ sprite.windows[i] = LookupIDByType(win->info[i].id, RT_WINDOW);
+ if(!sprite.windows[i]) /* window is being unmapped */
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+static void
+XineramaCheckVirtualMotion(
+ QdEventPtr qe,
+ WindowPtr pWin
+){
+
+ if (qe)
+ {
+ sprite.hot.pScreen = qe->pScreen; /* should always be Screen 0 */
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
+ pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
+ NullWindow;
+ }
+ if (pWin)
+ {
+ int x, y, off_x, off_y, i;
+ BoxRec lims;
+
+ if(!XineramaSetWindowPntrs(pWin))
+ return;
+
+ i = PanoramiXNumScreens - 1;
+
+ REGION_COPY(sprite.screen, &sprite.Reg2,
+ &sprite.windows[i]->borderSize);
+ off_x = panoramiXdataPtr[i].x;
+ off_y = panoramiXdataPtr[i].y;
+
+ while(i--) {
+ x = off_x - panoramiXdataPtr[i].x;
+ y = off_y - panoramiXdataPtr[i].y;
+
+ if(x || y)
+ REGION_TRANSLATE(sprite.screen, &sprite.Reg2, x, y);
+
+ REGION_UNION(sprite.screen, &sprite.Reg2, &sprite.Reg2,
+ &sprite.windows[i]->borderSize);
+
+ off_x = panoramiXdataPtr[i].x;
+ off_y = panoramiXdataPtr[i].y;
+ }
+
+ lims = *REGION_EXTENTS(sprite.screen, &sprite.Reg2);
+
+ if (sprite.hot.x < lims.x1)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = lims.x1;
+ else if (sprite.hot.x >= lims.x2)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = lims.x2 - 1;
+ if (sprite.hot.y < lims.y1)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = lims.y1;
+ else if (sprite.hot.y >= lims.y2)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = lims.y2 - 1;
+
+ if (REGION_NUM_RECTS(&sprite.Reg2) > 1)
+ ConfineToShape(&sprite.Reg2, &sprite.hot.x, &sprite.hot.y);
+
+ if (qe)
+ {
+ qe->pScreen = sprite.hot.pScreen;
+ qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
+ qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
+ }
+ }
+}
+
+
+static Bool
+XineramaCheckMotion(xEvent *xE)
+{
+ WindowPtr prevSpriteWin = sprite.win;
+
+ if (xE && !syncEvents.playingEvents)
+ {
+ /* Motion events entering DIX get translated to Screen 0
+ coordinates. Replayed events have already been
+ translated since they've entered DIX before */
+ XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x -
+ panoramiXdataPtr[0].x;
+ XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y -
+ panoramiXdataPtr[0].y;
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = XE_KBPTR.rootX;
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = XE_KBPTR.rootY;
+ if (sprite.hot.x < sprite.physLimits.x1)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = sprite.physLimits.x1;
+ else if (sprite.hot.x >= sprite.physLimits.x2)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = sprite.physLimits.x2 - 1;
+ if (sprite.hot.y < sprite.physLimits.y1)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = sprite.physLimits.y1;
+ else if (sprite.hot.y >= sprite.physLimits.y2)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = sprite.physLimits.y2 - 1;
+
+ if (sprite.hotShape)
+ ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
+
+ sprite.hotPhys = sprite.hot;
+ if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
+ (sprite.hotPhys.y != XE_KBPTR.rootY))
+ {
+ XineramaSetCursorPosition(
+ sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
+ }
+ XE_KBPTR.rootX = sprite.hot.x;
+ XE_KBPTR.rootY = sprite.hot.y;
+ }
+
+#ifdef XEVIE
+ xeviewin =
+#endif
+ sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
+
+ if (sprite.win != prevSpriteWin)
+ {
+ if (prevSpriteWin != NullWindow) {
+ if (!xE)
+ UpdateCurrentTimeIf();
+ DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
+ }
+ PostNewCursor();
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+static void
+XineramaConfineCursorToWindow(WindowPtr pWin, Bool generateEvents)
+{
+
+ if (syncEvents.playingEvents)
+ {
+ XineramaCheckVirtualMotion((QdEventPtr)NULL, pWin);
+ SyntheticMotion(sprite.hot.x, sprite.hot.y);
+ }
+ else
+ {
+ int x, y, off_x, off_y, i;
+
+ if(!XineramaSetWindowPntrs(pWin))
+ return;
+
+ i = PanoramiXNumScreens - 1;
+
+ REGION_COPY(sprite.screen, &sprite.Reg1,
+ &sprite.windows[i]->borderSize);
+ off_x = panoramiXdataPtr[i].x;
+ off_y = panoramiXdataPtr[i].y;
+
+ while(i--) {
+ x = off_x - panoramiXdataPtr[i].x;
+ y = off_y - panoramiXdataPtr[i].y;
+
+ if(x || y)
+ REGION_TRANSLATE(sprite.screen, &sprite.Reg1, x, y);
+
+ REGION_UNION(sprite.screen, &sprite.Reg1, &sprite.Reg1,
+ &sprite.windows[i]->borderSize);
+
+ off_x = panoramiXdataPtr[i].x;
+ off_y = panoramiXdataPtr[i].y;
+ }
+
+ sprite.hotLimits = *REGION_EXTENTS(sprite.screen, &sprite.Reg1);
+
+ if(REGION_NUM_RECTS(&sprite.Reg1) > 1)
+ sprite.hotShape = &sprite.Reg1;
+ else
+ sprite.hotShape = NullRegion;
+
+ sprite.confined = FALSE;
+ sprite.confineWin = (pWin == WindowTable[0]) ? NullWindow : pWin;
+
+ XineramaCheckPhysLimits(sprite.current, generateEvents);
+ }
+}
+
+
+static void
+XineramaChangeToCursor(CursorPtr cursor)
+{
+ if (cursor != sprite.current)
+ {
+ if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
+ (sprite.current->bits->yhot != cursor->bits->yhot))
+ XineramaCheckPhysLimits(cursor, FALSE);
+ (*sprite.screen->DisplayCursor)(sprite.screen, cursor);
+ FreeCursor(sprite.current, (Cursor)0);
+ sprite.current = cursor;
+ sprite.current->refcnt++;
+ }
+}
+
+
+#endif /* PANORAMIX */
+
+void
+SetMaskForEvent(Mask mask, int event)
+{
+ if ((event < LASTEvent) || (event >= 128))
+ FatalError("SetMaskForEvent: bogus event number");
+ filters[event] = mask;
+}
+
+void
+SetCriticalEvent(int event)
+{
+ if (event >= 128)
+ FatalError("SetCriticalEvent: bogus event number");
+ criticalEvents[event >> 3] |= 1 << (event & 7);
+}
+
+static void
+SyntheticMotion(int x, int y)
+{
+ xEvent xE;
+
+#ifdef PANORAMIX
+ /* Translate back to the sprite screen since processInputProc
+ will translate from sprite screen to screen 0 upon reentry
+ to the DIX layer */
+ if(!noPanoramiXExtension) {
+ x += panoramiXdataPtr[0].x - panoramiXdataPtr[sprite.screen->myNum].x;
+ y += panoramiXdataPtr[0].y - panoramiXdataPtr[sprite.screen->myNum].y;
+ }
+#endif
+ xE.u.keyButtonPointer.rootX = x;
+ xE.u.keyButtonPointer.rootY = y;
+ if (syncEvents.playingEvents)
+ xE.u.keyButtonPointer.time = syncEvents.time.milliseconds;
+ else
+ xE.u.keyButtonPointer.time = currentTime.milliseconds;
+ xE.u.u.type = MotionNotify;
+ (*inputInfo.pointer->public.processInputProc)(&xE, inputInfo.pointer, 1);
+}
+
+#ifdef SHAPE
+static void
+ConfineToShape(RegionPtr shape, int *px, int *py)
+{
+ BoxRec box;
+ int x = *px, y = *py;
+ int incx = 1, incy = 1;
+
+ if (POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box))
+ return;
+ box = *REGION_EXTENTS(sprite.hot.pScreen, shape);
+ /* this is rather crude */
+ do {
+ x += incx;
+ if (x >= box.x2)
+ {
+ incx = -1;
+ x = *px - 1;
+ }
+ else if (x < box.x1)
+ {
+ incx = 1;
+ x = *px;
+ y += incy;
+ if (y >= box.y2)
+ {
+ incy = -1;
+ y = *py - 1;
+ }
+ else if (y < box.y1)
+ return; /* should never get here! */
+ }
+ } while (!POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box));
+ *px = x;
+ *py = y;
+}
+#endif
+
+static void
+CheckPhysLimits(
+ CursorPtr cursor,
+ Bool generateEvents,
+ Bool confineToScreen,
+ ScreenPtr pScreen)
+{
+ HotSpot new;
+
+ if (!cursor)
+ return;
+ new = sprite.hotPhys;
+ if (pScreen)
+ new.pScreen = pScreen;
+ else
+ pScreen = new.pScreen;
+ (*pScreen->CursorLimits) (pScreen, cursor, &sprite.hotLimits,
+ &sprite.physLimits);
+ sprite.confined = confineToScreen;
+ (* pScreen->ConstrainCursor)(pScreen, &sprite.physLimits);
+ if (new.x < sprite.physLimits.x1)
+ new.x = sprite.physLimits.x1;
+ else
+ if (new.x >= sprite.physLimits.x2)
+ new.x = sprite.physLimits.x2 - 1;
+ if (new.y < sprite.physLimits.y1)
+ new.y = sprite.physLimits.y1;
+ else
+ if (new.y >= sprite.physLimits.y2)
+ new.y = sprite.physLimits.y2 - 1;
+#ifdef SHAPE
+ if (sprite.hotShape)
+ ConfineToShape(sprite.hotShape, &new.x, &new.y);
+#endif
+ if ((pScreen != sprite.hotPhys.pScreen) ||
+ (new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
+ {
+ if (pScreen != sprite.hotPhys.pScreen)
+ sprite.hotPhys = new;
+ (*pScreen->SetCursorPosition) (pScreen, new.x, new.y, generateEvents);
+ if (!generateEvents)
+ SyntheticMotion(new.x, new.y);
+ }
+}
+
+static void
+CheckVirtualMotion(
+ register QdEventPtr qe,
+ register WindowPtr pWin)
+{
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ XineramaCheckVirtualMotion(qe, pWin);
+ return;
+ }
+#endif
+ if (qe)
+ {
+ sprite.hot.pScreen = qe->pScreen;
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
+ pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
+ NullWindow;
+ }
+ if (pWin)
+ {
+ BoxRec lims;
+
+ if (sprite.hot.pScreen != pWin->drawable.pScreen)
+ {
+ sprite.hot.pScreen = pWin->drawable.pScreen;
+#ifdef XEVIE
+ xeviehot.x = xeviehot.y = 0;
+#endif
+ sprite.hot.x = sprite.hot.y = 0;
+ }
+ lims = *REGION_EXTENTS(pWin->drawable.pScreen, &pWin->borderSize);
+ if (sprite.hot.x < lims.x1)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = lims.x1;
+ else if (sprite.hot.x >= lims.x2)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = lims.x2 - 1;
+ if (sprite.hot.y < lims.y1)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = lims.y1;
+ else if (sprite.hot.y >= lims.y2)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = lims.y2 - 1;
+#ifdef SHAPE
+ if (wBoundingShape(pWin))
+ ConfineToShape(&pWin->borderSize, &sprite.hot.x, &sprite.hot.y);
+#endif
+ if (qe)
+ {
+ qe->pScreen = sprite.hot.pScreen;
+ qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
+ qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
+ }
+ }
+ ROOT = WindowTable[sprite.hot.pScreen->myNum];
+}
+
+static void
+ConfineCursorToWindow(WindowPtr pWin, Bool generateEvents, Bool confineToScreen)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ XineramaConfineCursorToWindow(pWin, generateEvents);
+ return;
+ }
+#endif
+
+ if (syncEvents.playingEvents)
+ {
+ CheckVirtualMotion((QdEventPtr)NULL, pWin);
+ SyntheticMotion(sprite.hot.x, sprite.hot.y);
+ }
+ else
+ {
+ sprite.hotLimits = *REGION_EXTENTS( pScreen, &pWin->borderSize);
+#ifdef SHAPE
+ sprite.hotShape = wBoundingShape(pWin) ? &pWin->borderSize
+ : NullRegion;
+#endif
+ CheckPhysLimits(sprite.current, generateEvents, confineToScreen,
+ pScreen);
+ }
+}
+
+Bool
+PointerConfinedToScreen()
+{
+ return sprite.confined;
+}
+
+static void
+ChangeToCursor(CursorPtr cursor)
+{
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ XineramaChangeToCursor(cursor);
+ return;
+ }
+#endif
+
+ if (cursor != sprite.current)
+ {
+ if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
+ (sprite.current->bits->yhot != cursor->bits->yhot))
+ CheckPhysLimits(cursor, FALSE, sprite.confined,
+ (ScreenPtr)NULL);
+ (*sprite.hotPhys.pScreen->DisplayCursor) (sprite.hotPhys.pScreen,
+ cursor);
+ FreeCursor(sprite.current, (Cursor)0);
+ sprite.current = cursor;
+ sprite.current->refcnt++;
+ }
+}
+
+/* returns true if b is a descendent of a */
+Bool
+IsParent(register WindowPtr a, register WindowPtr b)
+{
+ for (b = b->parent; b; b = b->parent)
+ if (b == a) return TRUE;
+ return FALSE;
+}
+
+static void
+PostNewCursor(void)
+{
+ register WindowPtr win;
+ register GrabPtr grab = inputInfo.pointer->grab;
+
+ if (syncEvents.playingEvents)
+ return;
+ if (grab)
+ {
+ if (grab->cursor)
+ {
+ ChangeToCursor(grab->cursor);
+ return;
+ }
+ if (IsParent(grab->window, sprite.win))
+ win = sprite.win;
+ else
+ win = grab->window;
+ }
+ else
+ win = sprite.win;
+ for (; win; win = win->parent)
+ if (win->optional && win->optional->cursor != NullCursor)
+ {
+ ChangeToCursor(win->optional->cursor);
+ return;
+ }
+}
+
+WindowPtr
+GetCurrentRootWindow()
+{
+ return ROOT;
+}
+
+WindowPtr
+GetSpriteWindow()
+{
+ return sprite.win;
+}
+
+CursorPtr
+GetSpriteCursor()
+{
+ return sprite.current;
+}
+
+void
+GetSpritePosition(int *px, int *py)
+{
+ *px = sprite.hotPhys.x;
+ *py = sprite.hotPhys.y;
+}
+
+#ifdef PANORAMIX
+int
+XineramaGetCursorScreen()
+{
+ if(!noPanoramiXExtension) {
+ return sprite.screen->myNum;
+ } else {
+ return 0;
+ }
+}
+#endif /* PANORAMIX */
+
+#define TIMESLOP (5 * 60 * 1000) /* 5 minutes */
+
+static void
+MonthChangedOrBadTime(register xEvent *xE)
+{
+ /* If the ddx/OS is careless about not processing timestamped events from
+ * different sources in sorted order, then it's possible for time to go
+ * backwards when it should not. Here we ensure a decent time.
+ */
+ if ((currentTime.milliseconds - XE_KBPTR.time) > TIMESLOP)
+ currentTime.months++;
+ else
+ XE_KBPTR.time = currentTime.milliseconds;
+}
+
+#define NoticeTime(xE) { \
+ if ((xE)->u.keyButtonPointer.time < currentTime.milliseconds) \
+ MonthChangedOrBadTime(xE); \
+ currentTime.milliseconds = (xE)->u.keyButtonPointer.time; \
+ lastDeviceEventTime = currentTime; }
+
+void
+NoticeEventTime(register xEvent *xE)
+{
+ if (!syncEvents.playingEvents)
+ NoticeTime(xE);
+}
+
+/**************************************************************************
+ * The following procedures deal with synchronous events *
+ **************************************************************************/
+
+void
+EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count)
+{
+ register QdEventPtr tail = *syncEvents.pendtail;
+ register QdEventPtr qe;
+ xEvent *qxE;
+
+ NoticeTime(xE);
+
+#ifdef XKB
+ /* Fix for key repeating bug. */
+ if (device->key != NULL && device->key->xkbInfo != NULL &&
+ xE->u.u.type == KeyRelease)
+ AccessXCancelRepeatKey(device->key->xkbInfo, xE->u.u.detail);
+#endif
+
+ if (DeviceEventCallback)
+ {
+ DeviceEventInfoRec eventinfo;
+ /* The RECORD spec says that the root window field of motion events
+ * must be valid. At this point, it hasn't been filled in yet, so
+ * we do it here. The long expression below is necessary to get
+ * the current root window; the apparently reasonable alternative
+ * GetCurrentRootWindow()->drawable.id doesn't give you the right
+ * answer on the first motion event after a screen change because
+ * the data that GetCurrentRootWindow relies on hasn't been
+ * updated yet.
+ */
+ if (xE->u.u.type == MotionNotify)
+ XE_KBPTR.root =
+ WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
+ eventinfo.events = xE;
+ eventinfo.count = count;
+ CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+ }
+ if (xE->u.u.type == MotionNotify)
+ {
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x -
+ panoramiXdataPtr[0].x;
+ XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y -
+ panoramiXdataPtr[0].y;
+ }
+#endif
+ sprite.hotPhys.x = XE_KBPTR.rootX;
+ sprite.hotPhys.y = XE_KBPTR.rootY;
+ /* do motion compression */
+ if (tail &&
+ (tail->event->u.u.type == MotionNotify) &&
+ (tail->pScreen == sprite.hotPhys.pScreen))
+ {
+ tail->event->u.keyButtonPointer.rootX = sprite.hotPhys.x;
+ tail->event->u.keyButtonPointer.rootY = sprite.hotPhys.y;
+ tail->event->u.keyButtonPointer.time = XE_KBPTR.time;
+ tail->months = currentTime.months;
+ return;
+ }
+ }
+ qe = (QdEventPtr)xalloc(sizeof(QdEventRec) + (count * sizeof(xEvent)));
+ if (!qe)
+ return;
+ qe->next = (QdEventPtr)NULL;
+ qe->device = device;
+ qe->pScreen = sprite.hotPhys.pScreen;
+ qe->months = currentTime.months;
+ qe->event = (xEvent *)(qe + 1);
+ qe->evcount = count;
+ for (qxE = qe->event; --count >= 0; qxE++, xE++)
+ *qxE = *xE;
+ if (tail)
+ syncEvents.pendtail = &tail->next;
+ *syncEvents.pendtail = qe;
+}
+
+static void
+PlayReleasedEvents(void)
+{
+ register QdEventPtr *prev, qe;
+ register DeviceIntPtr dev;
+
+ prev = &syncEvents.pending;
+ while ( (qe = *prev) )
+ {
+ if (!qe->device->sync.frozen)
+ {
+ *prev = qe->next;
+ if (*syncEvents.pendtail == *prev)
+ syncEvents.pendtail = prev;
+ if (qe->event->u.u.type == MotionNotify)
+ CheckVirtualMotion(qe, NullWindow);
+ syncEvents.time.months = qe->months;
+ syncEvents.time.milliseconds = qe->event->u.keyButtonPointer.time;
+#ifdef PANORAMIX
+ /* Translate back to the sprite screen since processInputProc
+ will translate from sprite screen to screen 0 upon reentry
+ to the DIX layer */
+ if(!noPanoramiXExtension) {
+ qe->event->u.keyButtonPointer.rootX +=
+ panoramiXdataPtr[0].x -
+ panoramiXdataPtr[sprite.screen->myNum].x;
+ qe->event->u.keyButtonPointer.rootY +=
+ panoramiXdataPtr[0].y -
+ panoramiXdataPtr[sprite.screen->myNum].y;
+ }
+#endif
+ (*qe->device->public.processInputProc)(qe->event, qe->device,
+ qe->evcount);
+ xfree(qe);
+ for (dev = inputInfo.devices; dev && dev->sync.frozen; dev = dev->next)
+ ;
+ if (!dev)
+ break;
+ /* Playing the event may have unfrozen another device. */
+ /* So to play it safe, restart at the head of the queue */
+ prev = &syncEvents.pending;
+ }
+ else
+ prev = &qe->next;
+ }
+}
+
+static void
+FreezeThaw(register DeviceIntPtr dev, Bool frozen)
+{
+ dev->sync.frozen = frozen;
+ if (frozen)
+ dev->public.processInputProc = dev->public.enqueueInputProc;
+ else
+ dev->public.processInputProc = dev->public.realInputProc;
+}
+
+void
+ComputeFreezes()
+{
+ register DeviceIntPtr replayDev = syncEvents.replayDev;
+ register int i;
+ WindowPtr w;
+ register xEvent *xE;
+ int count;
+ GrabPtr grab;
+ register DeviceIntPtr dev;
+
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ FreezeThaw(dev, dev->sync.other || (dev->sync.state >= FROZEN));
+ if (syncEvents.playingEvents || (!replayDev && !syncEvents.pending))
+ return;
+ syncEvents.playingEvents = TRUE;
+ if (replayDev)
+ {
+ xE = replayDev->sync.event;
+ count = replayDev->sync.evcount;
+ syncEvents.replayDev = (DeviceIntPtr)NULL;
+
+ w = XYToWindow( XE_KBPTR.rootX, XE_KBPTR.rootY);
+ for (i = 0; i < spriteTraceGood; i++)
+ {
+ if (syncEvents.replayWin == spriteTrace[i])
+ {
+ if (!CheckDeviceGrabs(replayDev, xE, i+1, count)) {
+ if (replayDev->focus)
+ DeliverFocusedEvent(replayDev, xE, w, count);
+ else
+ DeliverDeviceEvents(w, xE, NullGrab, NullWindow,
+ replayDev, count);
+ }
+ goto playmore;
+ }
+ }
+ /* must not still be in the same stack */
+ if (replayDev->focus)
+ DeliverFocusedEvent(replayDev, xE, w, count);
+ else
+ DeliverDeviceEvents(w, xE, NullGrab, NullWindow, replayDev, count);
+ }
+playmore:
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (!dev->sync.frozen)
+ {
+ PlayReleasedEvents();
+ break;
+ }
+ }
+ syncEvents.playingEvents = FALSE;
+ /* the following may have been skipped during replay, so do it now */
+ if ((grab = inputInfo.pointer->grab) && grab->confineTo)
+ {
+ if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+ sprite.hotPhys.x = sprite.hotPhys.y = 0;
+ ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+ }
+ else
+ ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
+ TRUE, FALSE);
+ PostNewCursor();
+}
+
+#ifdef RANDR
+void
+ScreenRestructured (ScreenPtr pScreen)
+{
+ GrabPtr grab;
+
+ if ((grab = inputInfo.pointer->grab) && grab->confineTo)
+ {
+ if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+ sprite.hotPhys.x = sprite.hotPhys.y = 0;
+ ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+ }
+ else
+ ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
+ TRUE, FALSE);
+}
+#endif
+
+void
+CheckGrabForSyncs(register DeviceIntPtr thisDev, Bool thisMode, Bool otherMode)
+{
+ register GrabPtr grab = thisDev->grab;
+ register DeviceIntPtr dev;
+
+ if (thisMode == GrabModeSync)
+ thisDev->sync.state = FROZEN_NO_EVENT;
+ else
+ { /* free both if same client owns both */
+ thisDev->sync.state = THAWED;
+ if (thisDev->sync.other &&
+ (CLIENT_BITS(thisDev->sync.other->resource) ==
+ CLIENT_BITS(grab->resource)))
+ thisDev->sync.other = NullGrab;
+ }
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev != thisDev)
+ {
+ if (otherMode == GrabModeSync)
+ dev->sync.other = grab;
+ else
+ { /* free both if same client owns both */
+ if (dev->sync.other &&
+ (CLIENT_BITS(dev->sync.other->resource) ==
+ CLIENT_BITS(grab->resource)))
+ dev->sync.other = NullGrab;
+ }
+ }
+ }
+ ComputeFreezes();
+}
+
+void
+ActivatePointerGrab(register DeviceIntPtr mouse, register GrabPtr grab,
+ TimeStamp time, Bool autoGrab)
+{
+ WindowPtr oldWin = (mouse->grab) ? mouse->grab->window
+ : sprite.win;
+
+ if (grab->confineTo)
+ {
+ if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+ sprite.hotPhys.x = sprite.hotPhys.y = 0;
+ ConfineCursorToWindow(grab->confineTo, FALSE, TRUE);
+ }
+ DoEnterLeaveEvents(oldWin, grab->window, NotifyGrab);
+ mouse->valuator->motionHintWindow = NullWindow;
+ if (syncEvents.playingEvents)
+ mouse->grabTime = syncEvents.time;
+ else
+ mouse->grabTime = time;
+ if (grab->cursor)
+ grab->cursor->refcnt++;
+ mouse->activeGrab = *grab;
+ mouse->grab = &mouse->activeGrab;
+ mouse->fromPassiveGrab = autoGrab;
+ PostNewCursor();
+ CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
+
+ #ifdef NXAGENT_SERVER
+
+ /*
+ * If grab is synchronous, events are delivered to clients only if they send
+ * an AllowEvent request. If mode field in AllowEvent request is SyncPointer, the
+ * delivered event is saved in a queue and replayed later, when grab is released.
+ * We should export sync grab to X as async in order to avoid events to be
+ * queued twice, in the agent and in the X server. This solution have a drawback:
+ * replayed events are not delivered to that application that are not clients of
+ * the agent.
+ * A different solution could be to make the grab asynchronous in the agent and
+ * to export it as synchronous. But this seems to be less safe.
+ *
+ * To make internal grab asynchronous, change previous line as follows.
+ *
+ * if (nxagentOption(Rootless))
+ * {
+ * CheckGrabForSyncs(mouse, GrabModeAsync, (Bool)grab->keyboardMode);
+ * }
+ * else
+ * {
+ * CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
+ * }
+ */
+
+ if (nxagentOption(Rootless) == 1)
+ {
+ /*
+ * FIXME: We should use the correct value
+ * for the cursor. Temporarily we set it
+ * to None.
+ */
+
+ int resource = nxagentWaitForResource(NXGetCollectGrabPointerResource,
+ nxagentCollectGrabPointerPredicate);
+
+ NXCollectGrabPointer(nxagentDisplay, resource, nxagentWindow(grab -> window),
+ 1, grab -> eventMask & PointerGrabMask,
+ GrabModeAsync, GrabModeAsync, (grab -> confineTo) ?
+ nxagentWindow(grab -> confineTo) : None,
+ None, CurrentTime);
+ }
+
+ #endif
+}
+
+void
+DeactivatePointerGrab(register DeviceIntPtr mouse)
+{
+ register GrabPtr grab = mouse->grab;
+ register DeviceIntPtr dev;
+
+ mouse->valuator->motionHintWindow = NullWindow;
+ mouse->grab = NullGrab;
+ mouse->sync.state = NOT_GRABBED;
+ mouse->fromPassiveGrab = FALSE;
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->sync.other == grab)
+ dev->sync.other = NullGrab;
+ }
+ DoEnterLeaveEvents(grab->window, sprite.win, NotifyUngrab);
+ if (grab->confineTo)
+ ConfineCursorToWindow(ROOT, FALSE, FALSE);
+ PostNewCursor();
+ if (grab->cursor)
+ FreeCursor(grab->cursor, (Cursor)0);
+ ComputeFreezes();
+
+ #ifdef NXAGENT_SERVER
+
+ if (nxagentOption(Rootless) == 1)
+ {
+ XUngrabPointer(nxagentDisplay, CurrentTime);
+
+ if (sprite.win == ROOT)
+ {
+ mouse -> button -> state &=
+ ~(Button1Mask | Button2Mask | Button3Mask |
+ Button4Mask | Button5Mask);
+ }
+ }
+
+ #endif
+}
+
+void
+ActivateKeyboardGrab(register DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, Bool passive)
+{
+ WindowPtr oldWin;
+
+ if (keybd->grab)
+ oldWin = keybd->grab->window;
+ else if (keybd->focus)
+ oldWin = keybd->focus->win;
+ else
+ oldWin = sprite.win;
+ if (oldWin == FollowKeyboardWin)
+ oldWin = inputInfo.keyboard->focus->win;
+ if (keybd->valuator)
+ keybd->valuator->motionHintWindow = NullWindow;
+ DoFocusEvents(keybd, oldWin, grab->window, NotifyGrab);
+ if (syncEvents.playingEvents)
+ keybd->grabTime = syncEvents.time;
+ else
+ keybd->grabTime = time;
+ keybd->activeGrab = *grab;
+ keybd->grab = &keybd->activeGrab;
+ keybd->fromPassiveGrab = passive;
+ CheckGrabForSyncs(keybd, (Bool)grab->keyboardMode, (Bool)grab->pointerMode);
+}
+
+void
+DeactivateKeyboardGrab(register DeviceIntPtr keybd)
+{
+ register GrabPtr grab = keybd->grab;
+ register DeviceIntPtr dev;
+ register WindowPtr focusWin = keybd->focus ? keybd->focus->win
+ : sprite.win;
+
+ if (focusWin == FollowKeyboardWin)
+ focusWin = inputInfo.keyboard->focus->win;
+ if (keybd->valuator)
+ keybd->valuator->motionHintWindow = NullWindow;
+ keybd->grab = NullGrab;
+ keybd->sync.state = NOT_GRABBED;
+ keybd->fromPassiveGrab = FALSE;
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->sync.other == grab)
+ dev->sync.other = NullGrab;
+ }
+ DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab);
+ ComputeFreezes();
+}
+
+void
+AllowSome(ClientPtr client, TimeStamp time, DeviceIntPtr thisDev, int newState)
+{
+ Bool thisGrabbed, otherGrabbed, othersFrozen, thisSynced;
+ TimeStamp grabTime;
+ register DeviceIntPtr dev;
+
+ thisGrabbed = thisDev->grab && SameClient(thisDev->grab, client);
+ thisSynced = FALSE;
+ otherGrabbed = FALSE;
+ othersFrozen = TRUE;
+ grabTime = thisDev->grabTime;
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev == thisDev)
+ continue;
+ if (dev->grab && SameClient(dev->grab, client))
+ {
+ if (!(thisGrabbed || otherGrabbed) ||
+ (CompareTimeStamps(dev->grabTime, grabTime) == LATER))
+ grabTime = dev->grabTime;
+ otherGrabbed = TRUE;
+ if (thisDev->sync.other == dev->grab)
+ thisSynced = TRUE;
+ if (dev->sync.state < FROZEN)
+ othersFrozen = FALSE;
+ }
+ else if (!dev->sync.other || !SameClient(dev->sync.other, client))
+ othersFrozen = FALSE;
+ }
+ if (!((thisGrabbed && thisDev->sync.state >= FROZEN) || thisSynced))
+ return;
+ if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, grabTime) == EARLIER))
+ return;
+ switch (newState)
+ {
+ case THAWED: /* Async */
+ if (thisGrabbed)
+ thisDev->sync.state = THAWED;
+ if (thisSynced)
+ thisDev->sync.other = NullGrab;
+ ComputeFreezes();
+ break;
+ case FREEZE_NEXT_EVENT: /* Sync */
+ if (thisGrabbed)
+ {
+ thisDev->sync.state = FREEZE_NEXT_EVENT;
+ if (thisSynced)
+ thisDev->sync.other = NullGrab;
+ ComputeFreezes();
+ }
+ break;
+ case THAWED_BOTH: /* AsyncBoth */
+ if (othersFrozen)
+ {
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->grab && SameClient(dev->grab, client))
+ dev->sync.state = THAWED;
+ if (dev->sync.other && SameClient(dev->sync.other, client))
+ dev->sync.other = NullGrab;
+ }
+ ComputeFreezes();
+ }
+ break;
+ case FREEZE_BOTH_NEXT_EVENT: /* SyncBoth */
+ if (othersFrozen)
+ {
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->grab && SameClient(dev->grab, client))
+ dev->sync.state = FREEZE_BOTH_NEXT_EVENT;
+ if (dev->sync.other && SameClient(dev->sync.other, client))
+ dev->sync.other = NullGrab;
+ }
+ ComputeFreezes();
+ }
+ break;
+ case NOT_GRABBED: /* Replay */
+ if (thisGrabbed && thisDev->sync.state == FROZEN_WITH_EVENT)
+ {
+ if (thisSynced)
+ thisDev->sync.other = NullGrab;
+ syncEvents.replayDev = thisDev;
+ syncEvents.replayWin = thisDev->grab->window;
+ (*thisDev->DeactivateGrab)(thisDev);
+ syncEvents.replayDev = (DeviceIntPtr)NULL;
+ }
+ break;
+ case THAW_OTHERS: /* AsyncOthers */
+ if (othersFrozen)
+ {
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev == thisDev)
+ continue;
+ if (dev->grab && SameClient(dev->grab, client))
+ dev->sync.state = THAWED;
+ if (dev->sync.other && SameClient(dev->sync.other, client))
+ dev->sync.other = NullGrab;
+ }
+ ComputeFreezes();
+ }
+ break;
+ }
+}
+
+int
+ProcAllowEvents(register ClientPtr client)
+{
+ TimeStamp time;
+ DeviceIntPtr mouse = inputInfo.pointer;
+ DeviceIntPtr keybd = inputInfo.keyboard;
+ REQUEST(xAllowEventsReq);
+
+ REQUEST_SIZE_MATCH(xAllowEventsReq);
+ time = ClientTimeToServerTime(stuff->time);
+ switch (stuff->mode)
+ {
+ case ReplayPointer:
+ AllowSome(client, time, mouse, NOT_GRABBED);
+ break;
+ case SyncPointer:
+ AllowSome(client, time, mouse, FREEZE_NEXT_EVENT);
+ break;
+ case AsyncPointer:
+ AllowSome(client, time, mouse, THAWED);
+ break;
+ case ReplayKeyboard:
+ AllowSome(client, time, keybd, NOT_GRABBED);
+ break;
+ case SyncKeyboard:
+ AllowSome(client, time, keybd, FREEZE_NEXT_EVENT);
+ break;
+ case AsyncKeyboard:
+ AllowSome(client, time, keybd, THAWED);
+ break;
+ case SyncBoth:
+ AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT);
+ break;
+ case AsyncBoth:
+ AllowSome(client, time, keybd, THAWED_BOTH);
+ break;
+ default:
+ client->errorValue = stuff->mode;
+ return BadValue;
+ }
+
+ /*
+ * This is not necessary if we export grab to X as asynchronous.
+ *
+ * if (nxagentOption(Rootless) && stuff -> mode != ReplayKeyboard &&
+ * stuff -> mode != SyncKeyboard && stuff -> mode != AsyncKeyboard)
+ * {
+ * XAllowEvents(nxagentDisplay, stuff -> mode, CurrentTime);
+ * }
+ */
+
+ return Success;
+}
+
+void
+ReleaseActiveGrabs(ClientPtr client)
+{
+ register DeviceIntPtr dev;
+ Bool done;
+
+ /* XXX CloseDownClient should remove passive grabs before
+ * releasing active grabs.
+ */
+ do {
+ done = TRUE;
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->grab && SameClient(dev->grab, client))
+ {
+ (*dev->DeactivateGrab)(dev);
+ done = FALSE;
+ }
+ }
+ } while (!done);
+}
+
+/**************************************************************************
+ * The following procedures deal with delivering events *
+ **************************************************************************/
+
+int
+TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
+ Mask filter, GrabPtr grab)
+{
+ int i;
+ int type;
+
+#ifdef DEBUG
+ if (debug_events) ErrorF(
+ "Event([%d, %d], mask=0x%x), client=%d",
+ pEvents->u.u.type, pEvents->u.u.detail, mask, client->index);
+#endif
+ if ((client) && (client != serverClient) && (!client->clientGone) &&
+ ((filter == CantBeFiltered) || (mask & filter)))
+ {
+ if (grab && !SameClient(grab, client))
+ return -1; /* don't send, but notify caller */
+ type = pEvents->u.u.type;
+ if (type == MotionNotify)
+ {
+ if (mask & PointerMotionHintMask)
+ {
+ if (WID(inputInfo.pointer->valuator->motionHintWindow) ==
+ pEvents->u.keyButtonPointer.event)
+ {
+#ifdef DEBUG
+ if (debug_events) ErrorF("\n");
+ fprintf(stderr,"motionHintWindow == keyButtonPointer.event\n");
+#endif
+ return 1; /* don't send, but pretend we did */
+ }
+ pEvents->u.u.detail = NotifyHint;
+ }
+ else
+ {
+ pEvents->u.u.detail = NotifyNormal;
+ }
+ }
+#ifdef XINPUT
+ else
+ {
+ if ((type == DeviceMotionNotify) &&
+ MaybeSendDeviceMotionNotifyHint
+ ((deviceKeyButtonPointer*)pEvents, mask) != 0)
+ return 1;
+ }
+#endif
+ type &= 0177;
+ if (type != KeymapNotify)
+ {
+ /* all extension events must have a sequence number */
+ for (i = 0; i < count; i++)
+ pEvents[i].u.u.sequenceNumber = client->sequence;
+ }
+
+ if (BitIsOn(criticalEvents, type))
+ {
+#ifdef SMART_SCHEDULE
+ if (client->smart_priority < SMART_MAX_PRIORITY)
+ client->smart_priority++;
+#endif
+ SetCriticalOutputPending();
+ }
+
+ WriteEventsToClient(client, count, pEvents);
+#ifdef DEBUG
+ if (debug_events) ErrorF( " delivered\n");
+#endif
+ return 1;
+ }
+ else
+ {
+#ifdef DEBUG
+ if (debug_events) ErrorF("\n");
+#endif
+ return 0;
+ }
+}
+
+int
+DeliverEventsToWindow(register WindowPtr pWin, xEvent *pEvents, int count,
+ Mask filter, GrabPtr grab, int mskidx)
+{
+ int deliveries = 0, nondeliveries = 0;
+ int attempt;
+ register InputClients *other;
+ ClientPtr client = NullClient;
+ Mask deliveryMask = 0; /* If a grab occurs due to a button press, then
+ this mask is the mask of the grab. */
+ int type = pEvents->u.u.type;
+
+ /* CantBeFiltered means only window owner gets the event */
+ if ((filter == CantBeFiltered) || !(type & EXTENSION_EVENT_BASE))
+ {
+ /* if nobody ever wants to see this event, skip some work */
+ if (filter != CantBeFiltered &&
+ !((wOtherEventMasks(pWin)|pWin->eventMask) & filter))
+ return 0;
+ if ( (attempt = TryClientEvents(wClient(pWin), pEvents, count,
+ pWin->eventMask, filter, grab)) )
+ {
+ if (attempt > 0)
+ {
+ deliveries++;
+ client = wClient(pWin);
+ deliveryMask = pWin->eventMask;
+ } else
+ nondeliveries--;
+ }
+ }
+ if (filter != CantBeFiltered)
+ {
+ if (type & EXTENSION_EVENT_BASE)
+ {
+ OtherInputMasks *inputMasks;
+
+ inputMasks = wOtherInputMasks(pWin);
+ if (!inputMasks ||
+ !(inputMasks->inputEvents[mskidx] & filter))
+ return 0;
+ other = inputMasks->inputClients;
+ }
+ else
+ other = (InputClients *)wOtherClients(pWin);
+ for (; other; other = other->next)
+ {
+ if ( (attempt = TryClientEvents(rClient(other), pEvents, count,
+ other->mask[mskidx], filter, grab)) )
+ {
+ if (attempt > 0)
+ {
+ deliveries++;
+ client = rClient(other);
+ deliveryMask = other->mask[mskidx];
+ } else
+ nondeliveries--;
+ }
+ }
+ }
+ if ((type == ButtonPress) && deliveries && (!grab))
+ {
+ GrabRec tempGrab;
+
+ tempGrab.device = inputInfo.pointer;
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.window = pWin;
+ tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
+ tempGrab.eventMask = deliveryMask;
+ tempGrab.keyboardMode = GrabModeAsync;
+ tempGrab.pointerMode = GrabModeAsync;
+ tempGrab.confineTo = NullWindow;
+ tempGrab.cursor = NullCursor;
+ (*inputInfo.pointer->ActivateGrab)(inputInfo.pointer, &tempGrab,
+ currentTime, TRUE);
+ }
+ else if ((type == MotionNotify) && deliveries)
+ inputInfo.pointer->valuator->motionHintWindow = pWin;
+#ifdef XINPUT
+ else
+ {
+ if (((type == DeviceMotionNotify)
+#ifdef XKB
+ || (type == DeviceButtonPress)
+#endif
+ ) && deliveries)
+ CheckDeviceGrabAndHintWindow (pWin, type,
+ (deviceKeyButtonPointer*) pEvents,
+ grab, client, deliveryMask);
+ }
+#endif
+ if (deliveries)
+ return deliveries;
+ return nondeliveries;
+}
+
+/* If the event goes to dontClient, don't send it and return 0. if
+ send works, return 1 or if send didn't work, return 2.
+ Only works for core events.
+*/
+
+#ifdef PANORAMIX
+static int
+XineramaTryClientEventsResult(
+ ClientPtr client,
+ GrabPtr grab,
+ Mask mask,
+ Mask filter
+){
+ if ((client) && (client != serverClient) && (!client->clientGone) &&
+ ((filter == CantBeFiltered) || (mask & filter)))
+ {
+ if (grab && !SameClient(grab, client)) return -1;
+ else return 1;
+ }
+ return 0;
+}
+#endif
+
+int
+MaybeDeliverEventsToClient(register WindowPtr pWin, xEvent *pEvents,
+ int count, Mask filter, ClientPtr dontClient)
+{
+ register OtherClients *other;
+
+
+ if (pWin->eventMask & filter)
+ {
+ if (wClient(pWin) == dontClient)
+ return 0;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
+ return XineramaTryClientEventsResult(
+ wClient(pWin), NullGrab, pWin->eventMask, filter);
+#endif
+ return TryClientEvents(wClient(pWin), pEvents, count,
+ pWin->eventMask, filter, NullGrab);
+ }
+ for (other = wOtherClients(pWin); other; other = other->next)
+ {
+ if (other->mask & filter)
+ {
+ if (SameClient(other, dontClient))
+ return 0;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
+ return XineramaTryClientEventsResult(
+ rClient(other), NullGrab, other->mask, filter);
+#endif
+ return TryClientEvents(rClient(other), pEvents, count,
+ other->mask, filter, NullGrab);
+ }
+ }
+ return 2;
+}
+
+static void
+FixUpEventFromWindow(
+ xEvent *xE,
+ WindowPtr pWin,
+ Window child,
+ Bool calcChild)
+{
+ if (calcChild)
+ {
+ WindowPtr w=spriteTrace[spriteTraceGood-1];
+ /* If the search ends up past the root should the child field be
+ set to none or should the value in the argument be passed
+ through. It probably doesn't matter since everyone calls
+ this function with child == None anyway. */
+
+ while (w)
+ {
+ /* If the source window is same as event window, child should be
+ none. Don't bother going all all the way back to the root. */
+
+ if (w == pWin)
+ {
+ child = None;
+ break;
+ }
+
+ if (w->parent == pWin)
+ {
+ child = w->drawable.id;
+ break;
+ }
+ w = w->parent;
+ }
+ }
+ XE_KBPTR.root = ROOT->drawable.id;
+ XE_KBPTR.event = pWin->drawable.id;
+ if (sprite.hot.pScreen == pWin->drawable.pScreen)
+ {
+ XE_KBPTR.sameScreen = xTrue;
+ XE_KBPTR.child = child;
+ XE_KBPTR.eventX =
+ XE_KBPTR.rootX - pWin->drawable.x;
+ XE_KBPTR.eventY =
+ XE_KBPTR.rootY - pWin->drawable.y;
+ }
+ else
+ {
+ XE_KBPTR.sameScreen = xFalse;
+ XE_KBPTR.child = None;
+ XE_KBPTR.eventX = 0;
+ XE_KBPTR.eventY = 0;
+ }
+}
+
+int
+DeliverDeviceEvents(register WindowPtr pWin, register xEvent *xE, GrabPtr grab,
+ register WindowPtr stopAt, DeviceIntPtr dev, int count)
+{
+ Window child = None;
+ int type = xE->u.u.type;
+ Mask filter = filters[type];
+ int deliveries = 0;
+
+ if (type & EXTENSION_EVENT_BASE)
+ {
+ register OtherInputMasks *inputMasks;
+ int mskidx = dev->id;
+
+ inputMasks = wOtherInputMasks(pWin);
+ if (inputMasks && !(filter & inputMasks->deliverableEvents[mskidx]))
+ return 0;
+ while (pWin)
+ {
+ if (inputMasks && (inputMasks->inputEvents[mskidx] & filter))
+ {
+ FixUpEventFromWindow(xE, pWin, child, FALSE);
+ deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
+ grab, mskidx);
+ if (deliveries > 0)
+ return deliveries;
+ }
+ if ((deliveries < 0) ||
+ (pWin == stopAt) ||
+ (inputMasks &&
+ (filter & inputMasks->dontPropagateMask[mskidx])))
+ return 0;
+ child = pWin->drawable.id;
+ pWin = pWin->parent;
+ if (pWin)
+ inputMasks = wOtherInputMasks(pWin);
+ }
+ }
+ else
+ {
+ if (!(filter & pWin->deliverableEvents))
+ return 0;
+ while (pWin)
+ {
+ if ((wOtherEventMasks(pWin)|pWin->eventMask) & filter)
+ {
+ FixUpEventFromWindow(xE, pWin, child, FALSE);
+ deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
+ grab, 0);
+ if (deliveries > 0)
+ return deliveries;
+ }
+ if ((deliveries < 0) ||
+ (pWin == stopAt) ||
+ (filter & wDontPropagateMask(pWin)))
+ return 0;
+ child = pWin->drawable.id;
+ pWin = pWin->parent;
+ }
+ }
+ return 0;
+}
+
+/* not useful for events that propagate up the tree or extension events */
+int
+DeliverEvents(register WindowPtr pWin, register xEvent *xE, int count,
+ register WindowPtr otherParent)
+{
+ Mask filter;
+ int deliveries;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
+ return count;
+#endif
+
+ if (!count)
+ return 0;
+ filter = filters[xE->u.u.type];
+ if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify))
+ xE->u.destroyNotify.event = pWin->drawable.id;
+ if (filter != StructureAndSubMask)
+ return DeliverEventsToWindow(pWin, xE, count, filter, NullGrab, 0);
+ deliveries = DeliverEventsToWindow(pWin, xE, count, StructureNotifyMask,
+ NullGrab, 0);
+ if (pWin->parent)
+ {
+ xE->u.destroyNotify.event = pWin->parent->drawable.id;
+ deliveries += DeliverEventsToWindow(pWin->parent, xE, count,
+ SubstructureNotifyMask, NullGrab,
+ 0);
+ if (xE->u.u.type == ReparentNotify)
+ {
+ xE->u.destroyNotify.event = otherParent->drawable.id;
+ deliveries += DeliverEventsToWindow(otherParent, xE, count,
+ SubstructureNotifyMask,
+ NullGrab, 0);
+ }
+ }
+ return deliveries;
+}
+
+
+static Bool
+PointInBorderSize(WindowPtr pWin, int x, int y)
+{
+ BoxRec box;
+
+ if(POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderSize, x, y, &box))
+ return TRUE;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
+ int i;
+
+ for(i = 1; i < PanoramiXNumScreens; i++) {
+ if(POINT_IN_REGION(sprite.screen,
+ &sprite.windows[i]->borderSize,
+ x + panoramiXdataPtr[0].x - panoramiXdataPtr[i].x,
+ y + panoramiXdataPtr[0].y - panoramiXdataPtr[i].y,
+ &box))
+ return TRUE;
+ }
+ }
+#endif
+ return FALSE;
+}
+
+static WindowPtr
+XYToWindow(int x, int y)
+{
+ register WindowPtr pWin;
+ BoxRec box;
+
+ spriteTraceGood = 1; /* root window still there */
+
+ if (nxagentOption(Rootless))
+ {
+ if (nxagentLastEnteredWindow == NULL)
+ {
+ return ROOT;
+ }
+
+ pWin = ROOT->lastChild;
+
+ while (pWin && pWin != ROOT->firstChild && pWin != nxagentLastEnteredWindow)
+ {
+ pWin = pWin->prevSib;
+ }
+ }
+ else
+ {
+ pWin = ROOT->firstChild;
+ }
+
+ while (pWin)
+ {
+ 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))
+#ifdef SHAPE
+ /* When a window is shaped, a further check
+ * is made to see if the point is inside
+ * borderSize
+ */
+ && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
+ && (!wInputShape(pWin) ||
+ POINT_IN_REGION(pWin->drawable.pScreen,
+ wInputShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box))
+#endif
+ )
+ {
+ if (spriteTraceGood >= spriteTraceSize)
+ {
+ spriteTraceSize += 10;
+ Must_have_memory = TRUE; /* XXX */
+ spriteTrace = (WindowPtr *)xrealloc(
+ spriteTrace, spriteTraceSize*sizeof(WindowPtr));
+ Must_have_memory = FALSE; /* XXX */
+ }
+ spriteTrace[spriteTraceGood++] = pWin;
+ pWin = pWin->firstChild;
+ }
+ else
+ pWin = pWin->nextSib;
+ }
+ return spriteTrace[spriteTraceGood-1];
+}
+
+static Bool
+CheckMotion(xEvent *xE)
+{
+ WindowPtr prevSpriteWin = sprite.win;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ return XineramaCheckMotion(xE);
+#endif
+
+ if (xE && !syncEvents.playingEvents)
+ {
+ if (sprite.hot.pScreen != sprite.hotPhys.pScreen)
+ {
+ sprite.hot.pScreen = sprite.hotPhys.pScreen;
+ ROOT = WindowTable[sprite.hot.pScreen->myNum];
+ }
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = XE_KBPTR.rootX;
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = XE_KBPTR.rootY;
+ if (sprite.hot.x < sprite.physLimits.x1)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = sprite.physLimits.x1;
+ else if (sprite.hot.x >= sprite.physLimits.x2)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = sprite.physLimits.x2 - 1;
+ if (sprite.hot.y < sprite.physLimits.y1)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = sprite.physLimits.y1;
+ else if (sprite.hot.y >= sprite.physLimits.y2)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = sprite.physLimits.y2 - 1;
+#ifdef SHAPE
+ if (sprite.hotShape)
+ ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
+#endif
+ sprite.hotPhys = sprite.hot;
+
+ /*
+ * This code force cursor position to be inside the
+ * root window of the agent. We can't view a reason
+ * to do this and it interacts in an undesirable way
+ * with toggling fullscreen.
+ *
+ * if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
+ * (sprite.hotPhys.y != XE_KBPTR.rootY))
+ * {
+ * (*sprite.hotPhys.pScreen->SetCursorPosition)(
+ * sprite.hotPhys.pScreen,
+ * sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
+ * }
+ */
+
+ XE_KBPTR.rootX = sprite.hot.x;
+ XE_KBPTR.rootY = sprite.hot.y;
+ }
+
+#ifdef XEVIE
+ xeviewin =
+#endif
+ sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
+#ifdef notyet
+ if (!(sprite.win->deliverableEvents &
+ Motion_Filter(inputInfo.pointer->button))
+ !syncEvents.playingEvents)
+ {
+ /* XXX Do PointerNonInterestBox here */
+ }
+#endif
+ if (sprite.win != prevSpriteWin)
+ {
+ if (prevSpriteWin != NullWindow) {
+ if (!xE)
+ UpdateCurrentTimeIf();
+ DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
+ }
+ PostNewCursor();
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void
+WindowsRestructured()
+{
+ (void) CheckMotion((xEvent *)NULL);
+}
+
+#ifdef PANORAMIX
+/* This was added to support reconfiguration under Xdmx. The problem is
+ * that if the 0th screen (i.e., WindowTable[0]) is moved to an origin
+ * other than 0,0, the information in the private sprite structure must
+ * be updated accordingly, or XYToWindow (and other routines) will not
+ * compute correctly. */
+void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff)
+{
+ ScreenPtr pScreen = win->drawable.pScreen;
+ GrabPtr grab;
+
+ if (noPanoramiXExtension) return;
+
+ sprite.hot.x -= xoff;
+ sprite.hot.y -= yoff;
+
+ sprite.hotPhys.x -= xoff;
+ sprite.hotPhys.y -= yoff;
+
+ sprite.hotLimits.x1 -= xoff;
+ sprite.hotLimits.y1 -= yoff;
+ sprite.hotLimits.x2 -= xoff;
+ sprite.hotLimits.y2 -= yoff;
+
+ if (REGION_NOTEMPTY(sprite.screen, &sprite.Reg1))
+ REGION_TRANSLATE(sprite.screen, &sprite.Reg1, xoff, yoff);
+ if (REGION_NOTEMPTY(sprite.screen, &sprite.Reg2))
+ REGION_TRANSLATE(sprite.screen, &sprite.Reg2, xoff, yoff);
+
+ /* FIXME: if we call ConfineCursorToWindow, must we do anything else? */
+ if ((grab = inputInfo.pointer->grab) && grab->confineTo) {
+ if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+ sprite.hotPhys.x = sprite.hotPhys.y = 0;
+ ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+ } else
+ ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
+ TRUE, FALSE);
+}
+#endif
+
+void
+DefineInitialRootWindow(register WindowPtr win)
+{
+ register ScreenPtr pScreen = win->drawable.pScreen;
+ #ifdef VIEWPORT_FRAME
+ extern void nxagentInitViewportFrame(ScreenPtr, WindowPtr);
+ #endif
+ extern int nxagentShadowInit(ScreenPtr, WindowPtr);
+
+ sprite.hotPhys.pScreen = pScreen;
+ sprite.hotPhys.x = pScreen->width / 2;
+ sprite.hotPhys.y = pScreen->height / 2;
+ sprite.hot = sprite.hotPhys;
+ sprite.hotLimits.x2 = pScreen->width;
+ sprite.hotLimits.y2 = pScreen->height;
+#ifdef XEVIE
+ xeviewin =
+#endif
+ sprite.win = win;
+ sprite.current = wCursor (win);
+ sprite.current->refcnt++;
+ spriteTraceGood = 1;
+ ROOT = win;
+ (*pScreen->CursorLimits) (
+ pScreen, sprite.current, &sprite.hotLimits, &sprite.physLimits);
+ sprite.confined = FALSE;
+ (*pScreen->ConstrainCursor) (pScreen, &sprite.physLimits);
+ (*pScreen->SetCursorPosition) (pScreen, sprite.hot.x, sprite.hot.y, FALSE);
+ (*pScreen->DisplayCursor) (pScreen, sprite.current);
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ sprite.hotLimits.x1 = -panoramiXdataPtr[0].x;
+ sprite.hotLimits.y1 = -panoramiXdataPtr[0].y;
+ sprite.hotLimits.x2 = PanoramiXPixWidth - panoramiXdataPtr[0].x;
+ sprite.hotLimits.y2 = PanoramiXPixHeight - panoramiXdataPtr[0].y;
+ sprite.physLimits = sprite.hotLimits;
+ sprite.confineWin = NullWindow;
+#ifdef SHAPE
+ sprite.hotShape = NullRegion;
+#endif
+ sprite.screen = pScreen;
+ /* gotta UNINIT these someplace */
+ REGION_NULL(pScreen, &sprite.Reg1);
+ REGION_NULL(pScreen, &sprite.Reg2);
+ }
+#endif
+
+ #ifdef VIEWPORT_FRAME
+ nxagentInitViewportFrame(pScreen, win);
+ #endif
+
+ if (nxagentOption(Shadow))
+ {
+ if (nxagentShadowInit(pScreen, win) == -1)
+ {
+ FatalError("Failed to connect to display '%s'", nxagentShadowDisplayName);
+ }
+ }
+}
+
+/*
+ * This does not take any shortcuts, and even ignores its argument, since
+ * it does not happen very often, and one has to walk up the tree since
+ * this might be a newly instantiated cursor for an intermediate window
+ * between the one the pointer is in and the one that the last cursor was
+ * instantiated from.
+ */
+void
+WindowHasNewCursor(WindowPtr pWin)
+{
+ PostNewCursor();
+}
+
+void
+NewCurrentScreen(ScreenPtr newScreen, int x, int y)
+{
+ sprite.hotPhys.x = x;
+ sprite.hotPhys.y = y;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ sprite.hotPhys.x += panoramiXdataPtr[newScreen->myNum].x -
+ panoramiXdataPtr[0].x;
+ sprite.hotPhys.y += panoramiXdataPtr[newScreen->myNum].y -
+ panoramiXdataPtr[0].y;
+ if (newScreen != sprite.screen) {
+ sprite.screen = newScreen;
+ /* Make sure we tell the DDX to update its copy of the screen */
+ if(sprite.confineWin)
+ XineramaConfineCursorToWindow(sprite.confineWin, TRUE);
+ else
+ XineramaConfineCursorToWindow(WindowTable[0], TRUE);
+ /* if the pointer wasn't confined, the DDX won't get
+ told of the pointer warp so we reposition it here */
+ if(!syncEvents.playingEvents)
+ (*sprite.screen->SetCursorPosition)(sprite.screen,
+ sprite.hotPhys.x + panoramiXdataPtr[0].x -
+ panoramiXdataPtr[sprite.screen->myNum].x,
+ sprite.hotPhys.y + panoramiXdataPtr[0].y -
+ panoramiXdataPtr[sprite.screen->myNum].y, FALSE);
+ }
+ } else
+#endif
+ if (newScreen != sprite.hotPhys.pScreen)
+ ConfineCursorToWindow(WindowTable[newScreen->myNum], TRUE, FALSE);
+}
+
+#ifdef PANORAMIX
+
+static Bool
+XineramaPointInWindowIsVisible(
+ WindowPtr pWin,
+ int x,
+ int y
+)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ BoxRec box;
+ int i, xoff, yoff;
+
+ if (!pWin->realized) return FALSE;
+
+ if (POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box))
+ return TRUE;
+
+ if(!XineramaSetWindowPntrs(pWin)) return FALSE;
+
+ xoff = x + panoramiXdataPtr[0].x;
+ yoff = y + panoramiXdataPtr[0].y;
+
+ for(i = 1; i < PanoramiXNumScreens; i++) {
+ pWin = sprite.windows[i];
+ pScreen = pWin->drawable.pScreen;
+ x = xoff - panoramiXdataPtr[i].x;
+ y = yoff - panoramiXdataPtr[i].y;
+
+ if(POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box)
+ && (!wInputShape(pWin) ||
+ POINT_IN_REGION(pWin->drawable.pScreen,
+ wInputShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box)))
+ return TRUE;
+
+ }
+
+ return FALSE;
+}
+
+static int
+XineramaWarpPointer(ClientPtr client)
+{
+ WindowPtr dest = NULL;
+ int x, y;
+
+ REQUEST(xWarpPointerReq);
+
+
+ if (stuff->dstWid != None)
+ {
+ dest = SecurityLookupWindow(stuff->dstWid, client, SecurityReadAccess);
+ if (!dest)
+ return BadWindow;
+ }
+ x = sprite.hotPhys.x;
+ y = sprite.hotPhys.y;
+
+ if (stuff->srcWid != None)
+ {
+ int winX, winY;
+ XID winID = stuff->srcWid;
+ WindowPtr source;
+
+ source = SecurityLookupWindow(winID, client, SecurityReadAccess);
+ if (!source) return BadWindow;
+
+ winX = source->drawable.x;
+ winY = source->drawable.y;
+ if(source == WindowTable[0]) {
+ winX -= panoramiXdataPtr[0].x;
+ winY -= panoramiXdataPtr[0].y;
+ }
+ if (x < winX + stuff->srcX ||
+ y < winY + stuff->srcY ||
+ (stuff->srcWidth != 0 &&
+ winX + stuff->srcX + (int)stuff->srcWidth < x) ||
+ (stuff->srcHeight != 0 &&
+ winY + stuff->srcY + (int)stuff->srcHeight < y) ||
+ !XineramaPointInWindowIsVisible(source, x, y))
+ return Success;
+ }
+ if (dest) {
+ x = dest->drawable.x;
+ y = dest->drawable.y;
+ if(dest == WindowTable[0]) {
+ x -= panoramiXdataPtr[0].x;
+ y -= panoramiXdataPtr[0].y;
+ }
+ }
+
+ x += stuff->dstX;
+ y += stuff->dstY;
+
+ if (x < sprite.physLimits.x1)
+ x = sprite.physLimits.x1;
+ else if (x >= sprite.physLimits.x2)
+ x = sprite.physLimits.x2 - 1;
+ if (y < sprite.physLimits.y1)
+ y = sprite.physLimits.y1;
+ else if (y >= sprite.physLimits.y2)
+ y = sprite.physLimits.y2 - 1;
+ if (sprite.hotShape)
+ ConfineToShape(sprite.hotShape, &x, &y);
+
+ XineramaSetCursorPosition(x, y, TRUE);
+
+ return Success;
+}
+
+#endif
+
+
+int
+ProcWarpPointer(ClientPtr client)
+{
+ WindowPtr dest = NULL;
+ int x, y;
+ ScreenPtr newScreen;
+
+ REQUEST(xWarpPointerReq);
+
+ REQUEST_SIZE_MATCH(xWarpPointerReq);
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ return XineramaWarpPointer(client);
+#endif
+
+ if (stuff->dstWid != None)
+ {
+ dest = SecurityLookupWindow(stuff->dstWid, client, SecurityReadAccess);
+ if (!dest)
+ return BadWindow;
+ }
+ x = sprite.hotPhys.x;
+ y = sprite.hotPhys.y;
+
+ if (stuff->srcWid != None)
+ {
+ int winX, winY;
+ XID winID = stuff->srcWid;
+ WindowPtr source;
+
+ source = SecurityLookupWindow(winID, client, SecurityReadAccess);
+ if (!source) return BadWindow;
+
+ winX = source->drawable.x;
+ winY = source->drawable.y;
+ if (source->drawable.pScreen != sprite.hotPhys.pScreen ||
+ x < winX + stuff->srcX ||
+ y < winY + stuff->srcY ||
+ (stuff->srcWidth != 0 &&
+ winX + stuff->srcX + (int)stuff->srcWidth < x) ||
+ (stuff->srcHeight != 0 &&
+ winY + stuff->srcY + (int)stuff->srcHeight < y) ||
+ !PointInWindowIsVisible(source, x, y))
+ return Success;
+ }
+ if (dest)
+ {
+ x = dest->drawable.x;
+ y = dest->drawable.y;
+ newScreen = dest->drawable.pScreen;
+ } else
+ newScreen = sprite.hotPhys.pScreen;
+
+ x += stuff->dstX;
+ y += stuff->dstY;
+
+ if (x < 0)
+ x = 0;
+ else if (x >= newScreen->width)
+ x = newScreen->width - 1;
+ if (y < 0)
+ y = 0;
+ else if (y >= newScreen->height)
+ y = newScreen->height - 1;
+
+ if (newScreen == sprite.hotPhys.pScreen)
+ {
+ if (x < sprite.physLimits.x1)
+ x = sprite.physLimits.x1;
+ else if (x >= sprite.physLimits.x2)
+ x = sprite.physLimits.x2 - 1;
+ if (y < sprite.physLimits.y1)
+ y = sprite.physLimits.y1;
+ else if (y >= sprite.physLimits.y2)
+ y = sprite.physLimits.y2 - 1;
+#if defined(SHAPE)
+ if (sprite.hotShape)
+ ConfineToShape(sprite.hotShape, &x, &y);
+#endif
+ (*newScreen->SetCursorPosition)(newScreen, x, y, TRUE);
+ }
+ else if (!PointerConfinedToScreen())
+ {
+ NewCurrentScreen(newScreen, x, y);
+ }
+ return Success;
+}
+
+static Bool
+BorderSizeNotEmpty(WindowPtr pWin)
+{
+ if(REGION_NOTEMPTY(sprite.hotPhys.pScreen, &pWin->borderSize))
+ return TRUE;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
+ int i;
+
+ for(i = 1; i < PanoramiXNumScreens; i++) {
+ if(REGION_NOTEMPTY(sprite.screen, &sprite.windows[i]->borderSize))
+ return TRUE;
+ }
+ }
+#endif
+ return FALSE;
+}
+
+/* "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a
+ passive grab set on the window to be activated. */
+
+static Bool
+CheckPassiveGrabsOnWindow(
+ WindowPtr pWin,
+ register DeviceIntPtr device,
+ register xEvent *xE,
+ int count)
+{
+ register GrabPtr grab = wPassiveGrabs(pWin);
+ GrabRec tempGrab;
+ register xEvent *dxE;
+
+ if (!grab)
+ return FALSE;
+ tempGrab.window = pWin;
+ tempGrab.device = device;
+ tempGrab.type = xE->u.u.type;
+ tempGrab.detail.exact = xE->u.u.detail;
+ tempGrab.detail.pMask = NULL;
+ tempGrab.modifiersDetail.pMask = NULL;
+ for (; grab; grab = grab->next)
+ {
+#ifdef XKB
+ DeviceIntPtr gdev;
+ XkbSrvInfoPtr xkbi;
+
+ gdev= grab->modifierDevice;
+ xkbi= gdev->key->xkbInfo;
+#endif
+ tempGrab.modifierDevice = grab->modifierDevice;
+ if ((device == grab->modifierDevice) &&
+ ((xE->u.u.type == KeyPress)
+#if defined(XINPUT) && defined(XKB)
+ || (xE->u.u.type == DeviceKeyPress)
+#endif
+ ))
+ tempGrab.modifiersDetail.exact =
+#ifdef XKB
+ (noXkbExtension?gdev->key->prev_state:xkbi->state.grab_mods);
+#else
+ grab->modifierDevice->key->prev_state;
+#endif
+ else
+ tempGrab.modifiersDetail.exact =
+#ifdef XKB
+ (noXkbExtension ? gdev->key->state : xkbi->state.grab_mods);
+#else
+ grab->modifierDevice->key->state;
+#endif
+ if (GrabMatchesSecond(&tempGrab, grab) &&
+ (!grab->confineTo ||
+ (grab->confineTo->realized &&
+ BorderSizeNotEmpty(grab->confineTo))))
+ {
+#ifdef XCSECURITY
+ if (!SecurityCheckDeviceAccess(wClient(pWin), device, FALSE))
+ return FALSE;
+#endif
+#ifdef XKB
+ if (!noXkbExtension) {
+ XE_KBPTR.state &= 0x1f00;
+ XE_KBPTR.state |=
+ tempGrab.modifiersDetail.exact&(~0x1f00);
+ }
+#endif
+ (*device->ActivateGrab)(device, grab, currentTime, TRUE);
+
+ FixUpEventFromWindow(xE, grab->window, None, TRUE);
+
+ (void) TryClientEvents(rClient(grab), xE, count,
+ filters[xE->u.u.type],
+ filters[xE->u.u.type], grab);
+
+ if (device->sync.state == FROZEN_NO_EVENT)
+ {
+ if (device->sync.evcount < count)
+ {
+ Must_have_memory = TRUE; /* XXX */
+ device->sync.event = (xEvent *)xrealloc(device->sync.event,
+ count*
+ sizeof(xEvent));
+ Must_have_memory = FALSE; /* XXX */
+ }
+ device->sync.evcount = count;
+ for (dxE = device->sync.event; --count >= 0; dxE++, xE++)
+ *dxE = *xE;
+ device->sync.state = FROZEN_WITH_EVENT;
+ }
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/**
+"CheckDeviceGrabs" handles both keyboard and pointer events that may cause
+a passive grab to be activated. If the event is a keyboard event, the
+ancestors of the focus window are traced down and tried to see if they have
+any passive grabs to be activated. If the focus window itself is reached and
+it's descendants contain they pointer, the ancestors of the window that the
+pointer is in are then traced down starting at the focus window, otherwise no
+grabs are activated. If the event is a pointer event, the ancestors of the
+window that the pointer is in are traced down starting at the root until
+CheckPassiveGrabs causes a passive grab to activate or all the windows are
+tried. PRH
+*/
+
+Bool
+CheckDeviceGrabs(register DeviceIntPtr device, register xEvent *xE,
+ int checkFirst, int count)
+{
+ register int i;
+ register WindowPtr pWin = NULL;
+ register FocusClassPtr focus = device->focus;
+
+ if (((xE->u.u.type == ButtonPress)
+#if defined(XINPUT) && defined(XKB)
+ || (xE->u.u.type == DeviceButtonPress)
+#endif
+ ) && (device->button->buttonsDown != 1))
+ return FALSE;
+
+ i = checkFirst;
+
+ if (focus)
+ {
+ for (; i < focus->traceGood; i++)
+ {
+ pWin = focus->trace[i];
+ if (pWin->optional &&
+ CheckPassiveGrabsOnWindow(pWin, device, xE, count))
+ return TRUE;
+ }
+
+ if ((focus->win == NoneWin) ||
+ (i >= spriteTraceGood) ||
+ ((i > checkFirst) && (pWin != spriteTrace[i-1])))
+ return FALSE;
+ }
+
+ for (; i < spriteTraceGood; i++)
+ {
+ pWin = spriteTrace[i];
+ if (pWin->optional &&
+ CheckPassiveGrabsOnWindow(pWin, device, xE, count))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void
+DeliverFocusedEvent(DeviceIntPtr keybd, xEvent *xE, WindowPtr window, int count)
+{
+ WindowPtr focus = keybd->focus->win;
+ int mskidx = 0;
+
+ if (focus == FollowKeyboardWin)
+ focus = inputInfo.keyboard->focus->win;
+ if (!focus)
+ return;
+ if (focus == PointerRootWin)
+ {
+ DeliverDeviceEvents(window, xE, NullGrab, NullWindow, keybd, count);
+ return;
+ }
+ if ((focus == window) || IsParent(focus, window))
+ {
+ if (DeliverDeviceEvents(window, xE, NullGrab, focus, keybd, count))
+ return;
+ }
+ /* just deliver it to the focus window */
+ FixUpEventFromWindow(xE, focus, None, FALSE);
+ if (xE->u.u.type & EXTENSION_EVENT_BASE)
+ mskidx = keybd->id;
+ (void)DeliverEventsToWindow(focus, xE, count, filters[xE->u.u.type],
+ NullGrab, mskidx);
+}
+
+void
+DeliverGrabbedEvent(register xEvent *xE, register DeviceIntPtr thisDev,
+ Bool deactivateGrab, int count)
+{
+ register GrabPtr grab = thisDev->grab;
+ int deliveries = 0;
+ register DeviceIntPtr dev;
+ register xEvent *dxE;
+
+ if (grab->ownerEvents)
+ {
+ WindowPtr focus;
+
+ if (thisDev->focus)
+ {
+ focus = thisDev->focus->win;
+ if (focus == FollowKeyboardWin)
+ focus = inputInfo.keyboard->focus->win;
+ }
+ else
+ focus = PointerRootWin;
+ if (focus == PointerRootWin)
+ deliveries = DeliverDeviceEvents(sprite.win, xE, grab, NullWindow,
+ thisDev, count);
+ else if (focus && (focus == sprite.win || IsParent(focus, sprite.win)))
+ deliveries = DeliverDeviceEvents(sprite.win, xE, grab, focus,
+ thisDev, count);
+ else if (focus)
+ deliveries = DeliverDeviceEvents(focus, xE, grab, focus,
+ thisDev, count);
+ }
+ if (!deliveries)
+ {
+ FixUpEventFromWindow(xE, grab->window, None, TRUE);
+ deliveries = TryClientEvents(rClient(grab), xE, count,
+ (Mask)grab->eventMask,
+ filters[xE->u.u.type], grab);
+ if (deliveries && (xE->u.u.type == MotionNotify
+#ifdef XINPUT
+ || xE->u.u.type == DeviceMotionNotify
+#endif
+ ))
+ thisDev->valuator->motionHintWindow = grab->window;
+ }
+ if (deliveries && !deactivateGrab && (xE->u.u.type != MotionNotify
+#ifdef XINPUT
+ && xE->u.u.type != DeviceMotionNotify
+#endif
+ ))
+ switch (thisDev->sync.state)
+ {
+ case FREEZE_BOTH_NEXT_EVENT:
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev == thisDev)
+ continue;
+ FreezeThaw(dev, TRUE);
+ if ((dev->sync.state == FREEZE_BOTH_NEXT_EVENT) &&
+ (CLIENT_BITS(dev->grab->resource) ==
+ CLIENT_BITS(thisDev->grab->resource)))
+ dev->sync.state = FROZEN_NO_EVENT;
+ else
+ dev->sync.other = thisDev->grab;
+ }
+ /* fall through */
+ case FREEZE_NEXT_EVENT:
+ thisDev->sync.state = FROZEN_WITH_EVENT;
+ FreezeThaw(thisDev, TRUE);
+ if (thisDev->sync.evcount < count)
+ {
+ Must_have_memory = TRUE; /* XXX */
+ thisDev->sync.event = (xEvent *)xrealloc(thisDev->sync.event,
+ count*sizeof(xEvent));
+ Must_have_memory = FALSE; /* XXX */
+ }
+ thisDev->sync.evcount = count;
+ for (dxE = thisDev->sync.event; --count >= 0; dxE++, xE++)
+ *dxE = *xE;
+ break;
+ }
+}
+
+void
+#ifdef XKB
+CoreProcessKeyboardEvent (register xEvent *xE, register DeviceIntPtr keybd, int count)
+#else
+ProcessKeyboardEvent (register xEvent *xE, register DeviceIntPtr keybd, int count)
+#endif
+{
+ int key, bit;
+ register BYTE *kptr;
+ register int i;
+ register CARD8 modifiers;
+ register CARD16 mask;
+ GrabPtr grab = keybd->grab;
+ Bool deactivateGrab = FALSE;
+ register KeyClassPtr keyc = keybd->key;
+#ifdef XEVIE
+ static Window rootWin = 0;
+
+ if(!xeviegrabState && xevieFlag && clients[xevieClientIndex] &&
+ (xevieMask & xevieFilters[xE->u.u.type])) {
+ key = xE->u.u.detail;
+ kptr = &keyc->down[key >> 3];
+ bit = 1 << (key & 7);
+ if((xE->u.u.type == KeyPress && (*kptr & bit)) ||
+ (xE->u.u.type == KeyRelease && !(*kptr & bit)))
+ {} else {
+#ifdef XKB
+ if(!noXkbExtension)
+ xevieKBEventSent = 1;
+#endif
+ if(!xevieKBEventSent)
+ {
+ xeviekb = keybd;
+ if(!rootWin) {
+ rootWin = GetCurrentRootWindow()->drawable.id;
+ }
+ xE->u.keyButtonPointer.event = xeviewin->drawable.id;
+ xE->u.keyButtonPointer.root = rootWin;
+ xE->u.keyButtonPointer.child = (xeviewin->firstChild) ? xeviewin->firstChild->
+drawable.id:0;
+ xE->u.keyButtonPointer.rootX = xeviehot.x;
+ xE->u.keyButtonPointer.rootY = xeviehot.y;
+ xE->u.keyButtonPointer.state = keyc->state;
+ WriteToClient(clients[xevieClientIndex], sizeof(xEvent), (char *)xE);
+#ifdef XKB
+ if(noXkbExtension)
+#endif
+ return;
+ } else {
+ xevieKBEventSent = 0;
+ }
+ }
+ }
+#endif
+
+ if (!syncEvents.playingEvents)
+ {
+ NoticeTime(xE);
+ if (DeviceEventCallback)
+ {
+ DeviceEventInfoRec eventinfo;
+ eventinfo.events = xE;
+ eventinfo.count = count;
+ CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+ }
+ }
+#ifdef XEVIE
+ /* fix for bug5094030: don't change the state bit if the event is from XEvIE client */
+ if(!(!xeviegrabState && xevieFlag && clients[xevieClientIndex] &&
+ (xevieMask & xevieFilters[xE->u.u.type]
+#ifdef XKB
+ && !noXkbExtension
+#endif
+ )))
+#endif
+ XE_KBPTR.state = (keyc->state | inputInfo.pointer->button->state);
+ XE_KBPTR.rootX = sprite.hot.x;
+ XE_KBPTR.rootY = sprite.hot.y;
+ key = xE->u.u.detail;
+ kptr = &keyc->down[key >> 3];
+ bit = 1 << (key & 7);
+ modifiers = keyc->modifierMap[key];
+#if defined(XKB) && defined(XEVIE)
+ if(!noXkbExtension && !xeviegrabState &&
+ xevieFlag && clients[xevieClientIndex] &&
+ (xevieMask & xevieFilters[xE->u.u.type])) {
+ switch(xE->u.u.type) {
+ case KeyPress: *kptr &= ~bit; break;
+ case KeyRelease: *kptr |= bit; break;
+ }
+ }
+#endif
+
+#ifdef DEBUG
+ if ((xkbDebugFlags&0x4)&&
+ ((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))) {
+ ErrorF("CoreProcessKbdEvent: Key %d %s\n",key,
+ (xE->u.u.type==KeyPress?"down":"up"));
+ }
+#endif
+ switch (xE->u.u.type)
+ {
+ case KeyPress:
+ if (*kptr & bit) /* allow ddx to generate multiple downs */
+ {
+ if (!modifiers)
+ {
+ xE->u.u.type = KeyRelease;
+ (*keybd->public.processInputProc)(xE, keybd, count);
+ xE->u.u.type = KeyPress;
+ /* release can have side effects, don't fall through */
+ (*keybd->public.processInputProc)(xE, keybd, count);
+ }
+ return;
+ }
+ inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+ *kptr |= bit;
+ keyc->prev_state = keyc->state;
+ for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
+ {
+ if (mask & modifiers)
+ {
+ /* This key affects modifier "i" */
+ keyc->modifierKeyCount[i]++;
+ keyc->state |= mask;
+ modifiers &= ~mask;
+ }
+ }
+ if (!grab && CheckDeviceGrabs(keybd, xE, 0, count))
+ {
+ keybd->activatingKey = key;
+ return;
+ }
+ break;
+ case KeyRelease:
+ if (!(*kptr & bit)) /* guard against duplicates */
+ return;
+ inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+ *kptr &= ~bit;
+ keyc->prev_state = keyc->state;
+ for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
+ {
+ if (mask & modifiers) {
+ /* This key affects modifier "i" */
+ if (--keyc->modifierKeyCount[i] <= 0) {
+ keyc->state &= ~mask;
+ keyc->modifierKeyCount[i] = 0;
+ }
+ modifiers &= ~mask;
+ }
+ }
+ if (keybd->fromPassiveGrab && (key == keybd->activatingKey))
+ deactivateGrab = TRUE;
+ break;
+ default:
+ FatalError("Impossible keyboard event");
+ }
+ if (grab)
+ DeliverGrabbedEvent(xE, keybd, deactivateGrab, count);
+ else
+ DeliverFocusedEvent(keybd, xE, sprite.win, count);
+ if (deactivateGrab)
+ (*keybd->DeactivateGrab)(keybd);
+}
+
+#ifdef XKB
+/* This function is used to set the key pressed or key released state -
+ this is only used when the pressing of keys does not cause
+ CoreProcessKeyEvent to be called, as in for example Mouse Keys.
+*/
+void
+FixKeyState (register xEvent *xE, register DeviceIntPtr keybd)
+{
+ int key, bit;
+ register BYTE *kptr;
+ register KeyClassPtr keyc = keybd->key;
+
+ key = xE->u.u.detail;
+ kptr = &keyc->down[key >> 3];
+ bit = 1 << (key & 7);
+#ifdef DEBUG
+ if ((xkbDebugFlags&0x4)&&
+ ((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))) {
+ ErrorF("FixKeyState: Key %d %s\n",key,
+ (xE->u.u.type==KeyPress?"down":"up"));
+ }
+#endif
+ switch (xE->u.u.type)
+ {
+ case KeyPress:
+ *kptr |= bit;
+ break;
+ case KeyRelease:
+ *kptr &= ~bit;
+ break;
+ default:
+ FatalError("Impossible keyboard event");
+ }
+}
+#endif
+
+void
+#ifdef XKB
+CoreProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count)
+#else
+ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count)
+#endif
+{
+ register GrabPtr grab = mouse->grab;
+ Bool deactivateGrab = FALSE;
+ register ButtonClassPtr butc = mouse->button;
+#ifdef XKB
+ XkbSrvInfoPtr xkbi;
+
+ xkbi = inputInfo.keyboard->key->xkbInfo;
+#endif
+#ifdef XEVIE
+ if(xevieFlag && clients[xevieClientIndex] && !xeviegrabState &&
+ (xevieMask & xevieFilters[xE->u.u.type])) {
+ if(xevieEventSent)
+ xevieEventSent = 0;
+ else {
+ xeviemouse = mouse;
+ WriteToClient(clients[xevieClientIndex], sizeof(xEvent), (char *)xE);
+ return;
+ }
+ }
+#endif
+
+ if (!syncEvents.playingEvents)
+ NoticeTime(xE)
+ XE_KBPTR.state = (butc->state | (
+#ifdef XKB
+ (noXkbExtension ?
+ inputInfo.keyboard->key->state :
+ xkbi->state.grab_mods)
+#else
+ inputInfo.keyboard->key->state
+#endif
+ ));
+ {
+ NoticeTime(xE);
+ if (DeviceEventCallback)
+ {
+ DeviceEventInfoRec eventinfo;
+ /* see comment in EnqueueEvents regarding the next three lines */
+ if (xE->u.u.type == MotionNotify)
+ XE_KBPTR.root =
+ WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
+ eventinfo.events = xE;
+ eventinfo.count = count;
+ CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+ }
+ }
+ if (xE->u.u.type != MotionNotify)
+ {
+ register int key;
+ register BYTE *kptr;
+ int bit;
+
+ XE_KBPTR.rootX = sprite.hot.x;
+ XE_KBPTR.rootY = sprite.hot.y;
+
+ key = xE->u.u.detail;
+ kptr = &butc->down[key >> 3];
+ bit = 1 << (key & 7);
+ switch (xE->u.u.type)
+ {
+ case ButtonPress:
+ mouse->valuator->motionHintWindow = NullWindow;
+ if (!(*kptr & bit))
+ butc->buttonsDown++;
+ butc->motionMask = ButtonMotionMask;
+ *kptr |= bit;
+#if !defined(XFree86Server) || !defined(XINPUT)
+ xE->u.u.detail = butc->map[key];
+#endif
+ if (xE->u.u.detail == 0)
+ return;
+ if (xE->u.u.detail <= 5)
+ butc->state |= (Button1Mask >> 1) << xE->u.u.detail;
+ filters[MotionNotify] = Motion_Filter(butc);
+ if (!grab)
+ if (CheckDeviceGrabs(mouse, xE, 0, count))
+ return;
+ break;
+ case ButtonRelease:
+ mouse->valuator->motionHintWindow = NullWindow;
+ if (*kptr & bit)
+ --butc->buttonsDown;
+ if (!butc->buttonsDown)
+ butc->motionMask = 0;
+ *kptr &= ~bit;
+#if !defined(XFree86Server) || !defined(XINPUT)
+ xE->u.u.detail = butc->map[key];
+#endif
+ if (xE->u.u.detail == 0)
+ return;
+ if (xE->u.u.detail <= 5)
+ butc->state &= ~((Button1Mask >> 1) << xE->u.u.detail);
+ filters[MotionNotify] = Motion_Filter(butc);
+ if (!butc->state && mouse->fromPassiveGrab)
+ deactivateGrab = TRUE;
+ break;
+ default:
+ FatalError("bogus pointer event from ddx");
+ }
+ }
+ else if (!CheckMotion(xE))
+ return;
+ if (grab)
+ DeliverGrabbedEvent(xE, mouse, deactivateGrab, count);
+ else
+ DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
+ mouse, count);
+ if (deactivateGrab)
+ (*mouse->DeactivateGrab)(mouse);
+}
+
+#define AtMostOneClient \
+ (SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask)
+
+void
+RecalculateDeliverableEvents(pWin)
+ register WindowPtr pWin;
+{
+ register OtherClients *others;
+ register WindowPtr pChild;
+
+ pChild = pWin;
+ while (1)
+ {
+ if (pChild->optional)
+ {
+ pChild->optional->otherEventMasks = 0;
+ for (others = wOtherClients(pChild); others; others = others->next)
+ {
+ pChild->optional->otherEventMasks |= others->mask;
+ }
+ }
+ pChild->deliverableEvents = pChild->eventMask|
+ wOtherEventMasks(pChild);
+ if (pChild->parent)
+ pChild->deliverableEvents |=
+ (pChild->parent->deliverableEvents &
+ ~wDontPropagateMask(pChild) & PropagateMask);
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ break;
+ pChild = pChild->nextSib;
+ }
+}
+
+/**
+ *
+ * \param value must conform to DeleteType
+ */
+int
+OtherClientGone(pointer value, XID id)
+{
+ register OtherClientsPtr other, prev;
+ register WindowPtr pWin = (WindowPtr)value;
+
+ prev = 0;
+ for (other = wOtherClients(pWin); other; other = other->next)
+ {
+ if (other->resource == id)
+ {
+ if (prev)
+ prev->next = other->next;
+ else
+ {
+ if (!(pWin->optional->otherClients = other->next))
+ CheckWindowOptionalNeed (pWin);
+ }
+ xfree(other);
+ RecalculateDeliverableEvents(pWin);
+ return(Success);
+ }
+ prev = other;
+ }
+ FatalError("client not on event list");
+ /*NOTREACHED*/
+ return -1; /* make compiler happy */
+}
+
+int
+EventSelectForWindow(register WindowPtr pWin, register ClientPtr client, Mask mask)
+{
+ Mask check;
+ OtherClients * others;
+
+ if (mask & ~AllEventMasks)
+ {
+ client->errorValue = mask;
+ return BadValue;
+ }
+ check = (mask & AtMostOneClient);
+ if (check & (pWin->eventMask|wOtherEventMasks(pWin)))
+ { /* It is illegal for two different
+ clients to select on any of the
+ events for AtMostOneClient. However,
+ it is OK, for some client to
+ continue selecting on one of those
+ events. */
+ if ((wClient(pWin) != client) && (check & pWin->eventMask))
+ return BadAccess;
+ for (others = wOtherClients (pWin); others; others = others->next)
+ {
+ if (!SameClient(others, client) && (check & others->mask))
+ return BadAccess;
+ }
+ }
+ if (wClient (pWin) == client)
+ {
+ check = pWin->eventMask;
+#ifdef SGIMISC
+ pWin->eventMask =
+ (mask & ~SGIMiscSpecialDestroyMask) | (pWin->eventMask & SGIMiscSpecialDestroyMask);
+#else
+ pWin->eventMask = mask;
+#endif
+ }
+ else
+ {
+ for (others = wOtherClients (pWin); others; others = others->next)
+ {
+ if (SameClient(others, client))
+ {
+ check = others->mask;
+#ifdef SGIMISC
+ mask = (mask & ~SGIMiscSpecialDestroyMask) | (others->mask & SGIMiscSpecialDestroyMask);
+#endif
+ if (mask == 0)
+ {
+ FreeResource(others->resource, RT_NONE);
+ return Success;
+ }
+ else
+ others->mask = mask;
+ goto maskSet;
+ }
+ }
+ check = 0;
+ if (!pWin->optional && !MakeWindowOptional (pWin))
+ return BadAlloc;
+ others = (OtherClients *) xalloc(sizeof(OtherClients));
+ if (!others)
+ return BadAlloc;
+ others->mask = mask;
+ others->resource = FakeClientID(client->index);
+ others->next = pWin->optional->otherClients;
+ pWin->optional->otherClients = others;
+ if (!AddResource(others->resource, RT_OTHERCLIENT, (pointer)pWin))
+ return BadAlloc;
+ }
+maskSet:
+ if ((inputInfo.pointer->valuator->motionHintWindow == pWin) &&
+ (mask & PointerMotionHintMask) &&
+ !(check & PointerMotionHintMask) &&
+ !inputInfo.pointer->grab)
+ inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+ RecalculateDeliverableEvents(pWin);
+ return Success;
+}
+
+int
+EventSuppressForWindow(register WindowPtr pWin, register ClientPtr client,
+ Mask mask, Bool *checkOptional)
+{
+ register int i, free;
+
+ if ((mask & ~PropagateMask) && !permitOldBugs)
+ {
+ client->errorValue = mask;
+ return BadValue;
+ }
+ if (pWin->dontPropagate)
+ DontPropagateRefCnts[pWin->dontPropagate]--;
+ if (!mask)
+ i = 0;
+ else
+ {
+ for (i = DNPMCOUNT, free = 0; --i > 0; )
+ {
+ if (!DontPropagateRefCnts[i])
+ free = i;
+ else if (mask == DontPropagateMasks[i])
+ break;
+ }
+ if (!i && free)
+ {
+ i = free;
+ DontPropagateMasks[i] = mask;
+ }
+ }
+ if (i || !mask)
+ {
+ pWin->dontPropagate = i;
+ if (i)
+ DontPropagateRefCnts[i]++;
+ if (pWin->optional)
+ {
+ pWin->optional->dontPropagateMask = mask;
+ *checkOptional = TRUE;
+ }
+ }
+ else
+ {
+ if (!pWin->optional && !MakeWindowOptional (pWin))
+ {
+ if (pWin->dontPropagate)
+ DontPropagateRefCnts[pWin->dontPropagate]++;
+ return BadAlloc;
+ }
+ pWin->dontPropagate = 0;
+ pWin->optional->dontPropagateMask = mask;
+ }
+ RecalculateDeliverableEvents(pWin);
+ return Success;
+}
+
+static WindowPtr
+CommonAncestor(
+ register WindowPtr a,
+ register WindowPtr b)
+{
+ for (b = b->parent; b; b = b->parent)
+ if (IsParent(b, a)) return b;
+ return NullWindow;
+}
+
+static void
+EnterLeaveEvent(
+ int type,
+ int mode,
+ int detail,
+ register WindowPtr pWin,
+ Window child)
+{
+ xEvent event;
+ register DeviceIntPtr keybd = inputInfo.keyboard;
+ WindowPtr focus;
+ register DeviceIntPtr mouse = inputInfo.pointer;
+ register GrabPtr grab = mouse->grab;
+ Mask mask;
+
+ if ((pWin == mouse->valuator->motionHintWindow) &&
+ (detail != NotifyInferior))
+ mouse->valuator->motionHintWindow = NullWindow;
+ if (grab)
+ {
+ mask = (pWin == grab->window) ? grab->eventMask : 0;
+ if (grab->ownerEvents)
+ mask |= EventMaskForClient(pWin, rClient(grab));
+ }
+ else
+ {
+ mask = pWin->eventMask | wOtherEventMasks(pWin);
+ }
+ if (mask & filters[type])
+ {
+ event.u.u.type = type;
+ event.u.u.detail = detail;
+ event.u.enterLeave.time = currentTime.milliseconds;
+ event.u.enterLeave.rootX = sprite.hot.x;
+ event.u.enterLeave.rootY = sprite.hot.y;
+ /* Counts on the same initial structure of crossing & button events! */
+ FixUpEventFromWindow(&event, pWin, None, FALSE);
+ /* Enter/Leave events always set child */
+ event.u.enterLeave.child = child;
+ event.u.enterLeave.flags = event.u.keyButtonPointer.sameScreen ?
+ ELFlagSameScreen : 0;
+#ifdef XKB
+ if (!noXkbExtension) {
+ event.u.enterLeave.state = mouse->button->state & 0x1f00;
+ event.u.enterLeave.state |=
+ XkbGrabStateFromRec(&keybd->key->xkbInfo->state);
+ } else
+#endif
+ event.u.enterLeave.state = keybd->key->state | mouse->button->state;
+ event.u.enterLeave.mode = mode;
+ focus = keybd->focus->win;
+ if ((focus != NoneWin) &&
+ ((pWin == focus) || (focus == PointerRootWin) ||
+ IsParent(focus, pWin)))
+ event.u.enterLeave.flags |= ELFlagFocus;
+ if (grab)
+ (void)TryClientEvents(rClient(grab), &event, 1, mask,
+ filters[type], grab);
+ else
+ (void)DeliverEventsToWindow(pWin, &event, 1, filters[type],
+ NullGrab, 0);
+ }
+ if ((type == EnterNotify) && (mask & KeymapStateMask))
+ {
+ xKeymapEvent ke;
+
+#ifdef XCSECURITY
+ ClientPtr client = grab ? rClient(grab)
+ : clients[CLIENT_ID(pWin->drawable.id)];
+ if (!SecurityCheckDeviceAccess(client, keybd, FALSE))
+ {
+ bzero((char *)&ke.map[0], 31);
+ }
+ else
+#endif
+ memmove((char *)&ke.map[0], (char *)&keybd->key->down[1], 31);
+ ke.type = KeymapNotify;
+ if (grab)
+ (void)TryClientEvents(rClient(grab), (xEvent *)&ke, 1, mask,
+ KeymapStateMask, grab);
+ else
+ (void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
+ KeymapStateMask, NullGrab, 0);
+ }
+}
+
+static void
+EnterNotifies(WindowPtr ancestor, WindowPtr child, int mode, int detail)
+{
+ WindowPtr parent = child->parent;
+
+ if (ancestor == parent)
+ return;
+ EnterNotifies(ancestor, parent, mode, detail);
+ EnterLeaveEvent(EnterNotify, mode, detail, parent, child->drawable.id);
+}
+
+static void
+LeaveNotifies(WindowPtr child, WindowPtr ancestor, int mode, int detail)
+{
+ register WindowPtr pWin;
+
+ if (ancestor == child)
+ return;
+ for (pWin = child->parent; pWin != ancestor; pWin = pWin->parent)
+ {
+ EnterLeaveEvent(LeaveNotify, mode, detail, pWin, child->drawable.id);
+ child = pWin;
+ }
+}
+
+static void
+DoEnterLeaveEvents(WindowPtr fromWin, WindowPtr toWin, int mode)
+{
+ if (fromWin == toWin)
+ return;
+ if (IsParent(fromWin, toWin))
+ {
+ EnterLeaveEvent(LeaveNotify, mode, NotifyInferior, fromWin, None);
+ EnterNotifies(fromWin, toWin, mode, NotifyVirtual);
+ EnterLeaveEvent(EnterNotify, mode, NotifyAncestor, toWin, None);
+ }
+ else if (IsParent(toWin, fromWin))
+ {
+ EnterLeaveEvent(LeaveNotify, mode, NotifyAncestor, fromWin, None);
+ LeaveNotifies(fromWin, toWin, mode, NotifyVirtual);
+ EnterLeaveEvent(EnterNotify, mode, NotifyInferior, toWin, None);
+ }
+ else
+ { /* neither fromWin nor toWin is descendent of the other */
+ WindowPtr common = CommonAncestor(toWin, fromWin);
+ /* common == NullWindow ==> different screens */
+ EnterLeaveEvent(LeaveNotify, mode, NotifyNonlinear, fromWin, None);
+ LeaveNotifies(fromWin, common, mode, NotifyNonlinearVirtual);
+ EnterNotifies(common, toWin, mode, NotifyNonlinearVirtual);
+ EnterLeaveEvent(EnterNotify, mode, NotifyNonlinear, toWin, None);
+ }
+}
+
+static void
+FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, register WindowPtr pWin)
+{
+ xEvent event;
+
+#ifdef XINPUT
+ if (dev != inputInfo.keyboard)
+ {
+ DeviceFocusEvent(dev, type, mode, detail, pWin);
+ return;
+ }
+#endif
+ event.u.focus.mode = mode;
+ event.u.u.type = type;
+ event.u.u.detail = detail;
+ event.u.focus.window = pWin->drawable.id;
+ (void)DeliverEventsToWindow(pWin, &event, 1, filters[type], NullGrab,
+ 0);
+ if ((type == FocusIn) &&
+ ((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask))
+ {
+ xKeymapEvent ke;
+#ifdef XCSECURITY
+ ClientPtr client = clients[CLIENT_ID(pWin->drawable.id)];
+ if (!SecurityCheckDeviceAccess(client, dev, FALSE))
+ {
+ bzero((char *)&ke.map[0], 31);
+ }
+ else
+#endif
+ memmove((char *)&ke.map[0], (char *)&dev->key->down[1], 31);
+ ke.type = KeymapNotify;
+ (void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
+ KeymapStateMask, NullGrab, 0);
+ }
+}
+
+ /*
+ * recursive because it is easier
+ * no-op if child not descended from ancestor
+ */
+static Bool
+FocusInEvents(
+ DeviceIntPtr dev,
+ WindowPtr ancestor, WindowPtr child, WindowPtr skipChild,
+ int mode, int detail,
+ Bool doAncestor)
+{
+ if (child == NullWindow)
+ return ancestor == NullWindow;
+ if (ancestor == child)
+ {
+ if (doAncestor)
+ FocusEvent(dev, FocusIn, mode, detail, child);
+ return TRUE;
+ }
+ if (FocusInEvents(dev, ancestor, child->parent, skipChild, mode, detail,
+ doAncestor))
+ {
+ if (child != skipChild)
+ FocusEvent(dev, FocusIn, mode, detail, child);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* dies horribly if ancestor is not an ancestor of child */
+static void
+FocusOutEvents(
+ DeviceIntPtr dev,
+ WindowPtr child, WindowPtr ancestor,
+ int mode, int detail,
+ Bool doAncestor)
+{
+ register WindowPtr pWin;
+
+ for (pWin = child; pWin != ancestor; pWin = pWin->parent)
+ FocusEvent(dev, FocusOut, mode, detail, pWin);
+ if (doAncestor)
+ FocusEvent(dev, FocusOut, mode, detail, ancestor);
+}
+
+void
+DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode)
+{
+ int out, in; /* for holding details for to/from
+ PointerRoot/None */
+ int i;
+
+ if (fromWin == toWin)
+ return;
+ out = (fromWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
+ in = (toWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
+ /* wrong values if neither, but then not referenced */
+
+ if ((toWin == NullWindow) || (toWin == PointerRootWin))
+ {
+ if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
+ {
+ if (fromWin == PointerRootWin)
+ FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
+ TRUE);
+ /* Notify all the roots */
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
+ else
+#endif
+ for (i=0; i<screenInfo.numScreens; i++)
+ FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
+ }
+ else
+ {
+ if (IsParent(fromWin, sprite.win))
+ FocusOutEvents(dev, sprite.win, fromWin, mode, NotifyPointer,
+ FALSE);
+ FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
+ /* next call catches the root too, if the screen changed */
+ FocusOutEvents(dev, fromWin->parent, NullWindow, mode,
+ NotifyNonlinearVirtual, FALSE);
+ }
+ /* Notify all the roots */
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ FocusEvent(dev, FocusIn, mode, in, WindowTable[0]);
+ else
+#endif
+ for (i=0; i<screenInfo.numScreens; i++)
+ FocusEvent(dev, FocusIn, mode, in, WindowTable[i]);
+ if (toWin == PointerRootWin)
+ (void)FocusInEvents(dev, ROOT, sprite.win, NullWindow, mode,
+ NotifyPointer, TRUE);
+ }
+ else
+ {
+ if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
+ {
+ if (fromWin == PointerRootWin)
+ FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
+ TRUE);
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
+ else
+#endif
+ for (i=0; i<screenInfo.numScreens; i++)
+ FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
+ if (toWin->parent != NullWindow)
+ (void)FocusInEvents(dev, ROOT, toWin, toWin, mode,
+ NotifyNonlinearVirtual, TRUE);
+ FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
+ if (IsParent(toWin, sprite.win))
+ (void)FocusInEvents(dev, toWin, sprite.win, NullWindow, mode,
+ NotifyPointer, FALSE);
+ }
+ else
+ {
+ if (IsParent(toWin, fromWin))
+ {
+ FocusEvent(dev, FocusOut, mode, NotifyAncestor, fromWin);
+ FocusOutEvents(dev, fromWin->parent, toWin, mode,
+ NotifyVirtual, FALSE);
+ FocusEvent(dev, FocusIn, mode, NotifyInferior, toWin);
+ if ((IsParent(toWin, sprite.win)) &&
+ (sprite.win != fromWin) &&
+ (!IsParent(fromWin, sprite.win)) &&
+ (!IsParent(sprite.win, fromWin)))
+ (void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
+ mode, NotifyPointer, FALSE);
+ }
+ else
+ if (IsParent(fromWin, toWin))
+ {
+ if ((IsParent(fromWin, sprite.win)) &&
+ (sprite.win != fromWin) &&
+ (!IsParent(toWin, sprite.win)) &&
+ (!IsParent(sprite.win, toWin)))
+ FocusOutEvents(dev, sprite.win, fromWin, mode,
+ NotifyPointer, FALSE);
+ FocusEvent(dev, FocusOut, mode, NotifyInferior, fromWin);
+ (void)FocusInEvents(dev, fromWin, toWin, toWin, mode,
+ NotifyVirtual, FALSE);
+ FocusEvent(dev, FocusIn, mode, NotifyAncestor, toWin);
+ }
+ else
+ {
+ /* neither fromWin or toWin is child of other */
+ WindowPtr common = CommonAncestor(toWin, fromWin);
+ /* common == NullWindow ==> different screens */
+ if (IsParent(fromWin, sprite.win))
+ FocusOutEvents(dev, sprite.win, fromWin, mode,
+ NotifyPointer, FALSE);
+ FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
+ if (fromWin->parent != NullWindow)
+ FocusOutEvents(dev, fromWin->parent, common, mode,
+ NotifyNonlinearVirtual, FALSE);
+ if (toWin->parent != NullWindow)
+ (void)FocusInEvents(dev, common, toWin, toWin, mode,
+ NotifyNonlinearVirtual, FALSE);
+ FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
+ if (IsParent(toWin, sprite.win))
+ (void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
+ mode, NotifyPointer, FALSE);
+ }
+ }
+ }
+}
+
+int
+SetInputFocus(
+ ClientPtr client,
+ DeviceIntPtr dev,
+ Window focusID,
+ CARD8 revertTo,
+ Time ctime,
+ Bool followOK)
+{
+ register FocusClassPtr focus;
+ register WindowPtr focusWin;
+ int mode;
+ TimeStamp time;
+
+ UpdateCurrentTime();
+ if ((revertTo != RevertToParent) &&
+ (revertTo != RevertToPointerRoot) &&
+ (revertTo != RevertToNone) &&
+ ((revertTo != RevertToFollowKeyboard) || !followOK))
+ {
+ client->errorValue = revertTo;
+ return BadValue;
+ }
+ time = ClientTimeToServerTime(ctime);
+ if ((focusID == None) || (focusID == PointerRoot))
+ focusWin = (WindowPtr)(long)focusID;
+ else if ((focusID == FollowKeyboard) && followOK)
+ focusWin = inputInfo.keyboard->focus->win;
+ else if (!(focusWin = SecurityLookupWindow(focusID, client,
+ SecurityReadAccess)))
+ return BadWindow;
+ else
+ {
+ /* It is a match error to try to set the input focus to an
+ unviewable window. */
+
+ if(!focusWin->realized)
+ return(BadMatch);
+ }
+ focus = dev->focus;
+ if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, focus->time) == EARLIER))
+ return Success;
+ mode = (dev->grab) ? NotifyWhileGrabbed : NotifyNormal;
+ if (focus->win == FollowKeyboardWin)
+ DoFocusEvents(dev, inputInfo.keyboard->focus->win, focusWin, mode);
+ else
+ DoFocusEvents(dev, focus->win, focusWin, mode);
+ focus->time = time;
+ focus->revert = revertTo;
+ if (focusID == FollowKeyboard)
+ focus->win = FollowKeyboardWin;
+ else
+ focus->win = focusWin;
+ if ((focusWin == NoneWin) || (focusWin == PointerRootWin))
+ focus->traceGood = 0;
+ else
+ {
+ int depth = 0;
+ register WindowPtr pWin;
+
+ for (pWin = focusWin; pWin; pWin = pWin->parent) depth++;
+ if (depth > focus->traceSize)
+ {
+ focus->traceSize = depth+1;
+ Must_have_memory = TRUE; /* XXX */
+ focus->trace = (WindowPtr *)xrealloc(focus->trace,
+ focus->traceSize *
+ sizeof(WindowPtr));
+ Must_have_memory = FALSE; /* XXX */
+ }
+ focus->traceGood = depth;
+ for (pWin = focusWin, depth--; pWin; pWin = pWin->parent, depth--)
+ focus->trace[depth] = pWin;
+ }
+ return Success;
+}
+
+int
+ProcSetInputFocus(client)
+ ClientPtr client;
+{
+ REQUEST(xSetInputFocusReq);
+
+ REQUEST_SIZE_MATCH(xSetInputFocusReq);
+#ifdef XCSECURITY
+ if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
+ return Success;
+#endif
+ return SetInputFocus(client, inputInfo.keyboard, stuff->focus,
+ stuff->revertTo, stuff->time, FALSE);
+}
+
+int
+ProcGetInputFocus(ClientPtr client)
+{
+ xGetInputFocusReply rep;
+ /* REQUEST(xReq); */
+ FocusClassPtr focus = inputInfo.keyboard->focus;
+
+ REQUEST_SIZE_MATCH(xReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ if (focus->win == NoneWin)
+ rep.focus = None;
+ else if (focus->win == PointerRootWin)
+ rep.focus = PointerRoot;
+ else rep.focus = focus->win->drawable.id;
+ rep.revertTo = focus->revert;
+ WriteReplyToClient(client, sizeof(xGetInputFocusReply), &rep);
+ return Success;
+}
+
+int
+ProcGrabPointer(ClientPtr client)
+{
+ xGrabPointerReply rep;
+ DeviceIntPtr device = inputInfo.pointer;
+ GrabPtr grab;
+ WindowPtr pWin, confineTo;
+ CursorPtr cursor, oldCursor;
+ REQUEST(xGrabPointerReq);
+ TimeStamp time;
+
+ REQUEST_SIZE_MATCH(xGrabPointerReq);
+ UpdateCurrentTime();
+ if ((stuff->pointerMode != GrabModeSync) &&
+ (stuff->pointerMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->pointerMode;
+ return BadValue;
+ }
+ if ((stuff->keyboardMode != GrabModeSync) &&
+ (stuff->keyboardMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->keyboardMode;
+ return BadValue;
+ }
+ if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
+ {
+ client->errorValue = stuff->ownerEvents;
+ return BadValue;
+ }
+ if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
+ {
+ client->errorValue = stuff->eventMask;
+ return BadValue;
+ }
+ pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+ if (stuff->confineTo == None)
+ confineTo = NullWindow;
+ else
+ {
+ confineTo = SecurityLookupWindow(stuff->confineTo, client,
+ SecurityReadAccess);
+ if (!confineTo)
+ return BadWindow;
+ }
+ if (stuff->cursor == None)
+ cursor = NullCursor;
+ else
+ {
+ cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+ RT_CURSOR, SecurityReadAccess);
+ if (!cursor)
+ {
+ client->errorValue = stuff->cursor;
+ return BadCursor;
+ }
+ }
+ /* at this point, some sort of reply is guaranteed. */
+ time = ClientTimeToServerTime(stuff->time);
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ grab = device->grab;
+ if ((grab) && !SameClient(grab, client))
+ rep.status = AlreadyGrabbed;
+ else if ((!pWin->realized) ||
+ (confineTo &&
+ !(confineTo->realized && BorderSizeNotEmpty(confineTo))))
+ rep.status = GrabNotViewable;
+ else if (device->sync.frozen &&
+ device->sync.other && !SameClient(device->sync.other, client))
+ rep.status = GrabFrozen;
+ else if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, device->grabTime) == EARLIER))
+ rep.status = GrabInvalidTime;
+ else
+ {
+ GrabRec tempGrab;
+
+ oldCursor = NullCursor;
+ if (grab)
+ {
+ if (grab->confineTo && !confineTo)
+ ConfineCursorToWindow(ROOT, FALSE, FALSE);
+ oldCursor = grab->cursor;
+ }
+ tempGrab.cursor = cursor;
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.ownerEvents = stuff->ownerEvents;
+ tempGrab.eventMask = stuff->eventMask;
+ tempGrab.confineTo = confineTo;
+ tempGrab.window = pWin;
+ tempGrab.keyboardMode = stuff->keyboardMode;
+ tempGrab.pointerMode = stuff->pointerMode;
+ tempGrab.device = device;
+ (*device->ActivateGrab)(device, &tempGrab, time, FALSE);
+ if (oldCursor)
+ FreeCursor (oldCursor, (Cursor)0);
+ rep.status = GrabSuccess;
+ }
+ WriteReplyToClient(client, sizeof(xGrabPointerReply), &rep);
+ return Success;
+}
+
+int
+ProcChangeActivePointerGrab(ClientPtr client)
+{
+ DeviceIntPtr device = inputInfo.pointer;
+ register GrabPtr grab = device->grab;
+ CursorPtr newCursor, oldCursor;
+ REQUEST(xChangeActivePointerGrabReq);
+ TimeStamp time;
+
+ REQUEST_SIZE_MATCH(xChangeActivePointerGrabReq);
+ if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
+ {
+ client->errorValue = stuff->eventMask;
+ return BadValue;
+ }
+ if (stuff->cursor == None)
+ newCursor = NullCursor;
+ else
+ {
+ newCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+ RT_CURSOR, SecurityReadAccess);
+ if (!newCursor)
+ {
+ client->errorValue = stuff->cursor;
+ return BadCursor;
+ }
+ }
+ if (!grab)
+ return Success;
+ if (!SameClient(grab, client))
+ return Success;
+ time = ClientTimeToServerTime(stuff->time);
+ if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, device->grabTime) == EARLIER))
+ return Success;
+ oldCursor = grab->cursor;
+ grab->cursor = newCursor;
+ if (newCursor)
+ newCursor->refcnt++;
+ PostNewCursor();
+ if (oldCursor)
+ FreeCursor(oldCursor, (Cursor)0);
+ grab->eventMask = stuff->eventMask;
+ return Success;
+}
+
+int
+ProcUngrabPointer(ClientPtr client)
+{
+ DeviceIntPtr device = inputInfo.pointer;
+ GrabPtr grab;
+ TimeStamp time;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ UpdateCurrentTime();
+ grab = device->grab;
+ time = ClientTimeToServerTime(stuff->id);
+ if ((CompareTimeStamps(time, currentTime) != LATER) &&
+ (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
+ (grab) && SameClient(grab, client))
+ (*device->DeactivateGrab)(device);
+ return Success;
+}
+
+int
+GrabDevice(register ClientPtr client, register DeviceIntPtr dev,
+ unsigned this_mode, unsigned other_mode, Window grabWindow,
+ unsigned ownerEvents, Time ctime, Mask mask, CARD8 *status)
+{
+ register WindowPtr pWin;
+ register GrabPtr grab;
+ TimeStamp time;
+
+ UpdateCurrentTime();
+ if ((this_mode != GrabModeSync) && (this_mode != GrabModeAsync))
+ {
+ client->errorValue = this_mode;
+ return BadValue;
+ }
+ if ((other_mode != GrabModeSync) && (other_mode != GrabModeAsync))
+ {
+ client->errorValue = other_mode;
+ return BadValue;
+ }
+ if ((ownerEvents != xFalse) && (ownerEvents != xTrue))
+ {
+ client->errorValue = ownerEvents;
+ return BadValue;
+ }
+ pWin = SecurityLookupWindow(grabWindow, client, SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+ time = ClientTimeToServerTime(ctime);
+ grab = dev->grab;
+ if (grab && !SameClient(grab, client))
+ *status = AlreadyGrabbed;
+ else if (!pWin->realized)
+ *status = GrabNotViewable;
+ else if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, dev->grabTime) == EARLIER))
+ *status = GrabInvalidTime;
+ else if (dev->sync.frozen &&
+ dev->sync.other && !SameClient(dev->sync.other, client))
+ *status = GrabFrozen;
+ else
+ {
+ GrabRec tempGrab;
+
+ tempGrab.window = pWin;
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.ownerEvents = ownerEvents;
+ tempGrab.keyboardMode = this_mode;
+ tempGrab.pointerMode = other_mode;
+ tempGrab.eventMask = mask;
+ tempGrab.device = dev;
+ (*dev->ActivateGrab)(dev, &tempGrab, time, FALSE);
+ *status = GrabSuccess;
+ }
+ return Success;
+}
+
+int
+ProcGrabKeyboard(ClientPtr client)
+{
+ xGrabKeyboardReply rep;
+ REQUEST(xGrabKeyboardReq);
+ int result;
+
+ REQUEST_SIZE_MATCH(xGrabKeyboardReq);
+#ifdef XCSECURITY
+ if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
+ {
+ result = Success;
+ rep.status = AlreadyGrabbed;
+ }
+ else
+#endif
+ result = GrabDevice(client, inputInfo.keyboard, stuff->keyboardMode,
+ stuff->pointerMode, stuff->grabWindow,
+ stuff->ownerEvents, stuff->time,
+ KeyPressMask | KeyReleaseMask, &rep.status);
+ if (result != Success)
+ return result;
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ WriteReplyToClient(client, sizeof(xGrabKeyboardReply), &rep);
+ return Success;
+}
+
+int
+ProcUngrabKeyboard(ClientPtr client)
+{
+ DeviceIntPtr device = inputInfo.keyboard;
+ GrabPtr grab;
+ TimeStamp time;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ UpdateCurrentTime();
+ grab = device->grab;
+ time = ClientTimeToServerTime(stuff->id);
+ if ((CompareTimeStamps(time, currentTime) != LATER) &&
+ (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
+ (grab) && SameClient(grab, client))
+ (*device->DeactivateGrab)(device);
+ return Success;
+}
+
+int
+ProcQueryPointer(ClientPtr client)
+{
+ xQueryPointerReply rep;
+ WindowPtr pWin, t;
+ REQUEST(xResourceReq);
+ DeviceIntPtr mouse = inputInfo.pointer;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = SecurityLookupWindow(stuff->id, client, SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+ if (mouse->valuator->motionHintWindow)
+ MaybeStopHint(mouse, client);
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.mask = mouse->button->state | inputInfo.keyboard->key->state;
+ rep.length = 0;
+ rep.root = (ROOT)->drawable.id;
+ rep.rootX = sprite.hot.x;
+ rep.rootY = sprite.hot.y;
+ rep.child = None;
+ if (sprite.hot.pScreen == pWin->drawable.pScreen)
+ {
+ rep.sameScreen = xTrue;
+ rep.winX = sprite.hot.x - pWin->drawable.x;
+ rep.winY = sprite.hot.y - pWin->drawable.y;
+ for (t = sprite.win; t; t = t->parent)
+ if (t->parent == pWin)
+ {
+ rep.child = t->drawable.id;
+ break;
+ }
+ }
+ else
+ {
+ rep.sameScreen = xFalse;
+ rep.winX = 0;
+ rep.winY = 0;
+ }
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ rep.rootX += panoramiXdataPtr[0].x;
+ rep.rootY += panoramiXdataPtr[0].y;
+ if(stuff->id == rep.root) {
+ rep.winX += panoramiXdataPtr[0].x;
+ rep.winY += panoramiXdataPtr[0].y;
+ }
+ }
+#endif
+
+ WriteReplyToClient(client, sizeof(xQueryPointerReply), &rep);
+
+ return(Success);
+}
+
+void
+InitEvents()
+{
+ int i;
+
+ sprite.hot.pScreen = sprite.hotPhys.pScreen = (ScreenPtr)NULL;
+ inputInfo.numDevices = 0;
+ inputInfo.devices = (DeviceIntPtr)NULL;
+ inputInfo.off_devices = (DeviceIntPtr)NULL;
+ inputInfo.keyboard = (DeviceIntPtr)NULL;
+ inputInfo.pointer = (DeviceIntPtr)NULL;
+ if (spriteTraceSize == 0)
+ {
+ spriteTraceSize = 32;
+ spriteTrace = (WindowPtr *)xalloc(32*sizeof(WindowPtr));
+ if (!spriteTrace)
+ FatalError("failed to allocate spriteTrace");
+ }
+ spriteTraceGood = 0;
+ lastEventMask = OwnerGrabButtonMask;
+ filters[MotionNotify] = PointerMotionMask;
+#ifdef XEVIE
+ xeviewin =
+#endif
+ sprite.win = NullWindow;
+ sprite.current = NullCursor;
+ sprite.hotLimits.x1 = 0;
+ sprite.hotLimits.y1 = 0;
+ sprite.hotLimits.x2 = 0;
+ sprite.hotLimits.y2 = 0;
+ sprite.confined = FALSE;
+ syncEvents.replayDev = (DeviceIntPtr)NULL;
+ syncEvents.replayWin = NullWindow;
+ while (syncEvents.pending)
+ {
+ QdEventPtr next = syncEvents.pending->next;
+ xfree(syncEvents.pending);
+ syncEvents.pending = next;
+ }
+ syncEvents.pendtail = &syncEvents.pending;
+ syncEvents.playingEvents = FALSE;
+ syncEvents.time.months = 0;
+ syncEvents.time.milliseconds = 0; /* hardly matters */
+ currentTime.months = 0;
+ currentTime.milliseconds = GetTimeInMillis();
+ lastDeviceEventTime = currentTime;
+ for (i = 0; i < DNPMCOUNT; i++)
+ {
+ DontPropagateMasks[i] = 0;
+ DontPropagateRefCnts[i] = 0;
+ }
+}
+
+void
+CloseDownEvents(void)
+{
+ xfree(spriteTrace);
+ spriteTrace = NULL;
+ spriteTraceSize = 0;
+}
+
+int
+ProcSendEvent(ClientPtr client)
+{
+ WindowPtr pWin;
+ WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */
+ REQUEST(xSendEventReq);
+
+ REQUEST_SIZE_MATCH(xSendEventReq);
+
+ /* The client's event type must be a core event type or one defined by an
+ extension. */
+
+
+#ifdef NXAGENT_CLIPBOARD
+
+ if (stuff -> event.u.u.type == SelectionNotify)
+ {
+ extern int nxagentSendNotify(xEvent*);
+ if (nxagentSendNotify(&stuff->event) == 1)
+ return Success;
+ }
+#endif
+
+ if ( ! ((stuff->event.u.u.type > X_Reply &&
+ stuff->event.u.u.type < LASTEvent) ||
+ (stuff->event.u.u.type >= EXTENSION_EVENT_BASE &&
+ stuff->event.u.u.type < (unsigned)lastEvent)))
+ {
+ client->errorValue = stuff->event.u.u.type;
+ return BadValue;
+ }
+ if (stuff->event.u.u.type == ClientMessage &&
+ stuff->event.u.u.detail != 8 &&
+ stuff->event.u.u.detail != 16 &&
+ stuff->event.u.u.detail != 32 &&
+ !permitOldBugs)
+ {
+ client->errorValue = stuff->event.u.u.detail;
+ return BadValue;
+ }
+ if ((stuff->eventMask & ~AllEventMasks) && !permitOldBugs)
+ {
+ client->errorValue = stuff->eventMask;
+ return BadValue;
+ }
+
+ if (stuff->destination == PointerWindow)
+ pWin = sprite.win;
+ else if (stuff->destination == InputFocus)
+ {
+ WindowPtr inputFocus = inputInfo.keyboard->focus->win;
+
+ if (inputFocus == NoneWin)
+ return Success;
+
+ /* If the input focus is PointerRootWin, send the event to where
+ the pointer is if possible, then perhaps propogate up to root. */
+ if (inputFocus == PointerRootWin)
+ inputFocus = ROOT;
+
+ if (IsParent(inputFocus, sprite.win))
+ {
+ effectiveFocus = inputFocus;
+ pWin = sprite.win;
+ }
+ else
+ effectiveFocus = pWin = inputFocus;
+ }
+ else
+ pWin = SecurityLookupWindow(stuff->destination, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+ if ((stuff->propagate != xFalse) && (stuff->propagate != xTrue))
+ {
+ client->errorValue = stuff->propagate;
+ return BadValue;
+ }
+ stuff->event.u.u.type |= 0x80;
+ if (stuff->propagate)
+ {
+ for (;pWin; pWin = pWin->parent)
+ {
+ if (DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
+ NullGrab, 0))
+ return Success;
+ if (pWin == effectiveFocus)
+ return Success;
+ stuff->eventMask &= ~wDontPropagateMask(pWin);
+ if (!stuff->eventMask)
+ break;
+ }
+ }
+ else
+ (void)DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
+ NullGrab, 0);
+ return Success;
+}
+
+int
+ProcUngrabKey(ClientPtr client)
+{
+ REQUEST(xUngrabKeyReq);
+ WindowPtr pWin;
+ GrabRec tempGrab;
+ DeviceIntPtr keybd = inputInfo.keyboard;
+
+ REQUEST_SIZE_MATCH(xUngrabKeyReq);
+ pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+
+ if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
+ (stuff->key < keybd->key->curKeySyms.minKeyCode))
+ && (stuff->key != AnyKey))
+ {
+ client->errorValue = stuff->key;
+ return BadValue;
+ }
+ if ((stuff->modifiers != AnyModifier) &&
+ (stuff->modifiers & ~AllModifiersMask))
+ {
+ client->errorValue = stuff->modifiers;
+ return BadValue;
+ }
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.device = keybd;
+ tempGrab.window = pWin;
+ tempGrab.modifiersDetail.exact = stuff->modifiers;
+ tempGrab.modifiersDetail.pMask = NULL;
+ tempGrab.modifierDevice = inputInfo.keyboard;
+ tempGrab.type = KeyPress;
+ tempGrab.detail.exact = stuff->key;
+ tempGrab.detail.pMask = NULL;
+
+ if (!DeletePassiveGrabFromList(&tempGrab))
+ return(BadAlloc);
+ return(Success);
+}
+
+int
+ProcGrabKey(ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xGrabKeyReq);
+ GrabPtr grab;
+ DeviceIntPtr keybd = inputInfo.keyboard;
+
+ REQUEST_SIZE_MATCH(xGrabKeyReq);
+ if ((stuff->ownerEvents != xTrue) && (stuff->ownerEvents != xFalse))
+ {
+ client->errorValue = stuff->ownerEvents;
+ return(BadValue);
+ }
+ if ((stuff->pointerMode != GrabModeSync) &&
+ (stuff->pointerMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->pointerMode;
+ return BadValue;
+ }
+ if ((stuff->keyboardMode != GrabModeSync) &&
+ (stuff->keyboardMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->keyboardMode;
+ return BadValue;
+ }
+ if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
+ (stuff->key < keybd->key->curKeySyms.minKeyCode))
+ && (stuff->key != AnyKey))
+ {
+ client->errorValue = stuff->key;
+ return BadValue;
+ }
+ if ((stuff->modifiers != AnyModifier) &&
+ (stuff->modifiers & ~AllModifiersMask))
+ {
+ client->errorValue = stuff->modifiers;
+ return BadValue;
+ }
+ pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+
+ grab = CreateGrab(client->index, keybd, pWin,
+ (Mask)(KeyPressMask | KeyReleaseMask), (Bool)stuff->ownerEvents,
+ (Bool)stuff->keyboardMode, (Bool)stuff->pointerMode,
+ keybd, stuff->modifiers, KeyPress, stuff->key,
+ NullWindow, NullCursor);
+ if (!grab)
+ return BadAlloc;
+ return AddPassiveGrabToList(grab);
+}
+
+
+int
+ProcGrabButton(ClientPtr client)
+{
+ WindowPtr pWin, confineTo;
+ REQUEST(xGrabButtonReq);
+ CursorPtr cursor;
+ GrabPtr grab;
+
+ REQUEST_SIZE_MATCH(xGrabButtonReq);
+ if ((stuff->pointerMode != GrabModeSync) &&
+ (stuff->pointerMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->pointerMode;
+ return BadValue;
+ }
+ if ((stuff->keyboardMode != GrabModeSync) &&
+ (stuff->keyboardMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->keyboardMode;
+ return BadValue;
+ }
+ if ((stuff->modifiers != AnyModifier) &&
+ (stuff->modifiers & ~AllModifiersMask))
+ {
+ client->errorValue = stuff->modifiers;
+ return BadValue;
+ }
+ if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
+ {
+ client->errorValue = stuff->ownerEvents;
+ return BadValue;
+ }
+ if (stuff->eventMask & ~PointerGrabMask)
+ {
+ client->errorValue = stuff->eventMask;
+ return BadValue;
+ }
+ pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+ if (stuff->confineTo == None)
+ confineTo = NullWindow;
+ else {
+ confineTo = SecurityLookupWindow(stuff->confineTo, client,
+ SecurityReadAccess);
+ if (!confineTo)
+ return BadWindow;
+ }
+ if (stuff->cursor == None)
+ cursor = NullCursor;
+ else
+ {
+ cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+ RT_CURSOR, SecurityReadAccess);
+ if (!cursor)
+ {
+ client->errorValue = stuff->cursor;
+ return BadCursor;
+ }
+ }
+
+
+ grab = CreateGrab(client->index, inputInfo.pointer, pWin,
+ permitOldBugs ? (Mask)(stuff->eventMask |
+ ButtonPressMask | ButtonReleaseMask) :
+ (Mask)stuff->eventMask,
+ (Bool)stuff->ownerEvents, (Bool) stuff->keyboardMode,
+ (Bool)stuff->pointerMode, inputInfo.keyboard, stuff->modifiers,
+ ButtonPress, stuff->button, confineTo, cursor);
+ if (!grab)
+ return BadAlloc;
+ return AddPassiveGrabToList(grab);
+}
+
+int
+ProcUngrabButton(ClientPtr client)
+{
+ REQUEST(xUngrabButtonReq);
+ WindowPtr pWin;
+ GrabRec tempGrab;
+
+ REQUEST_SIZE_MATCH(xUngrabButtonReq);
+ if ((stuff->modifiers != AnyModifier) &&
+ (stuff->modifiers & ~AllModifiersMask))
+ {
+ client->errorValue = stuff->modifiers;
+ return BadValue;
+ }
+ pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.device = inputInfo.pointer;
+ tempGrab.window = pWin;
+ tempGrab.modifiersDetail.exact = stuff->modifiers;
+ tempGrab.modifiersDetail.pMask = NULL;
+ tempGrab.modifierDevice = inputInfo.keyboard;
+ tempGrab.type = ButtonPress;
+ tempGrab.detail.exact = stuff->button;
+ tempGrab.detail.pMask = NULL;
+
+ if (!DeletePassiveGrabFromList(&tempGrab))
+ return(BadAlloc);
+ return(Success);
+}
+
+void
+DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources)
+{
+ WindowPtr parent;
+ DeviceIntPtr mouse = inputInfo.pointer;
+ DeviceIntPtr keybd = inputInfo.keyboard;
+ FocusClassPtr focus = keybd->focus;
+ OtherClientsPtr oc;
+ GrabPtr passive;
+
+
+ /* Deactivate any grabs performed on this window, before making any
+ input focus changes. */
+
+ if (mouse->grab &&
+ ((mouse->grab->window == pWin) || (mouse->grab->confineTo == pWin)))
+ (*mouse->DeactivateGrab)(mouse);
+
+ /* Deactivating a keyboard grab should cause focus events. */
+
+ if (keybd->grab && (keybd->grab->window == pWin))
+ (*keybd->DeactivateGrab)(keybd);
+
+ /* If the focus window is a root window (ie. has no parent) then don't
+ delete the focus from it. */
+
+ if ((pWin == focus->win) && (pWin->parent != NullWindow))
+ {
+ int focusEventMode = NotifyNormal;
+
+ /* If a grab is in progress, then alter the mode of focus events. */
+
+ if (keybd->grab)
+ focusEventMode = NotifyWhileGrabbed;
+
+ switch (focus->revert)
+ {
+ case RevertToNone:
+ DoFocusEvents(keybd, pWin, NoneWin, focusEventMode);
+ focus->win = NoneWin;
+ focus->traceGood = 0;
+ break;
+ case RevertToParent:
+ parent = pWin;
+ do
+ {
+ parent = parent->parent;
+ focus->traceGood--;
+ } while (!parent->realized
+/* This would be a good protocol change -- windows being reparented
+ during SaveSet processing would cause the focus to revert to the
+ nearest enclosing window which will survive the death of the exiting
+ client, instead of ending up reverting to a dying window and thence
+ to None
+ */
+#ifdef NOTDEF
+ || clients[CLIENT_ID(parent->drawable.id)]->clientGone
+#endif
+ );
+ DoFocusEvents(keybd, pWin, parent, focusEventMode);
+ focus->win = parent;
+ focus->revert = RevertToNone;
+ break;
+ case RevertToPointerRoot:
+ DoFocusEvents(keybd, pWin, PointerRootWin, focusEventMode);
+ focus->win = PointerRootWin;
+ focus->traceGood = 0;
+ break;
+ }
+ }
+
+ if (mouse->valuator->motionHintWindow == pWin)
+ mouse->valuator->motionHintWindow = NullWindow;
+
+ if (freeResources)
+ {
+ if (pWin->dontPropagate)
+ DontPropagateRefCnts[pWin->dontPropagate]--;
+ while ( (oc = wOtherClients(pWin)) )
+ FreeResource(oc->resource, RT_NONE);
+ while ( (passive = wPassiveGrabs(pWin)) )
+ FreeResource(passive->resource, RT_NONE);
+ }
+#ifdef XINPUT
+ DeleteWindowFromAnyExtEvents(pWin, freeResources);
+#endif
+}
+
+/**
+ * Call this whenever some window at or below pWin has changed geometry
+ */
+void
+CheckCursorConfinement(WindowPtr pWin)
+{
+ GrabPtr grab = inputInfo.pointer->grab;
+ WindowPtr confineTo;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) return;
+#endif
+
+ if (grab && (confineTo = grab->confineTo))
+ {
+ if (!BorderSizeNotEmpty(confineTo))
+ (*inputInfo.pointer->DeactivateGrab)(inputInfo.pointer);
+ else if ((pWin == confineTo) || IsParent(pWin, confineTo))
+ ConfineCursorToWindow(confineTo, TRUE, TRUE);
+ }
+}
+
+Mask
+EventMaskForClient(WindowPtr pWin, ClientPtr client)
+{
+ register OtherClientsPtr other;
+
+ if (wClient (pWin) == client)
+ return pWin->eventMask;
+ for (other = wOtherClients(pWin); other; other = other->next)
+ {
+ if (SameClient(other, client))
+ return other->mask;
+ }
+ return 0;
+}
+
+int
+ProcRecolorCursor(ClientPtr client)
+{
+ CursorPtr pCursor;
+ int nscr;
+ ScreenPtr pscr;
+ Bool displayed;
+ REQUEST(xRecolorCursorReq);
+
+ REQUEST_SIZE_MATCH(xRecolorCursorReq);
+ pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+ RT_CURSOR, SecurityWriteAccess);
+ if ( !pCursor)
+ {
+ client->errorValue = stuff->cursor;
+ return (BadCursor);
+ }
+
+ pCursor->foreRed = stuff->foreRed;
+ pCursor->foreGreen = stuff->foreGreen;
+ pCursor->foreBlue = stuff->foreBlue;
+
+ pCursor->backRed = stuff->backRed;
+ pCursor->backGreen = stuff->backGreen;
+ pCursor->backBlue = stuff->backBlue;
+
+ for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
+ {
+ pscr = screenInfo.screens[nscr];
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ displayed = (pscr == sprite.screen);
+ else
+#endif
+ displayed = (pscr == sprite.hotPhys.pScreen);
+ ( *pscr->RecolorCursor)(pscr, pCursor,
+ (pCursor == sprite.current) && displayed);
+ }
+ return (Success);
+}
+
+void
+WriteEventsToClient(ClientPtr pClient, int count, xEvent *events)
+{
+#ifdef PANORAMIX
+ xEvent eventCopy;
+#endif
+ xEvent eventTo, *eventFrom;
+ int i;
+
+#ifdef XKB
+ if ((!noXkbExtension)&&(!XkbFilterEvents(pClient, count, events)))
+ return;
+#endif
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension &&
+ (panoramiXdataPtr[0].x || panoramiXdataPtr[0].y))
+ {
+ switch(events->u.u.type) {
+ case MotionNotify:
+ case ButtonPress:
+ case ButtonRelease:
+ case KeyPress:
+ case KeyRelease:
+ case EnterNotify:
+ case LeaveNotify:
+ /*
+ When multiple clients want the same event DeliverEventsToWindow
+ passes the same event structure multiple times so we can't
+ modify the one passed to us
+ */
+ count = 1; /* should always be 1 */
+ memcpy(&eventCopy, events, sizeof(xEvent));
+ eventCopy.u.keyButtonPointer.rootX += panoramiXdataPtr[0].x;
+ eventCopy.u.keyButtonPointer.rootY += panoramiXdataPtr[0].y;
+ if(eventCopy.u.keyButtonPointer.event ==
+ eventCopy.u.keyButtonPointer.root)
+ {
+ eventCopy.u.keyButtonPointer.eventX += panoramiXdataPtr[0].x;
+ eventCopy.u.keyButtonPointer.eventY += panoramiXdataPtr[0].y;
+ }
+ events = &eventCopy;
+ break;
+ default: break;
+ }
+ }
+#endif
+
+ if (EventCallback)
+ {
+ EventInfoRec eventinfo;
+ eventinfo.client = pClient;
+ eventinfo.events = events;
+ eventinfo.count = count;
+ CallCallbacks(&EventCallback, (pointer)&eventinfo);
+ }
+ if(pClient->swapped)
+ {
+ for(i = 0; i < count; i++)
+ {
+ eventFrom = &events[i];
+ /* Remember to strip off the leading bit of type in case
+ this event was sent with "SendEvent." */
+ (*EventSwapVector[eventFrom->u.u.type & 0177])
+ (eventFrom, &eventTo);
+ (void)WriteToClient(pClient, sizeof(xEvent), (char *)&eventTo);
+ }
+ }
+ else
+ {
+ (void)WriteToClient(pClient, count * sizeof(xEvent), (char *) events);
+ }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.X.original
new file mode 100644
index 000000000..4373673f9
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.X.original
@@ -0,0 +1,4670 @@
+/* $XdotOrg: xc/programs/Xserver/dix/events.c,v 1.17 2005/08/25 22:11:04 anholt Exp $ */
+/* $XFree86: xc/programs/Xserver/dix/events.c,v 3.51 2004/01/12 17:04:52 tsi Exp $ */
+/************************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+********************************************************/
+
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+/*****************************************************************
+
+Copyright 2003-2005 Sun Microsystems, Inc.
+
+All rights reserved.
+
+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, and/or sell copies of the Software, and to permit persons
+to whom the Software is furnished to do so, provided that the above
+copyright notice(s) and this permission notice appear in all copies of
+the Software and that both the above copyright notice(s) and this
+permission notice appear in supporting documentation.
+
+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
+OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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.
+
+Except as contained in this notice, the name of a copyright holder
+shall not be used in advertising or otherwise to promote the sale, use
+or other dealings in this Software without prior written authorization
+of the copyright holder.
+
+******************************************************************/
+
+/* $Xorg: events.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "misc.h"
+#include "resource.h"
+#define NEED_EVENTS
+#define NEED_REPLIES
+#include <X11/Xproto.h>
+#include "windowstr.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "cursorstr.h"
+
+#include "dixstruct.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#include "globals.h"
+
+#ifdef XKB
+#include <X11/extensions/XKBsrv.h>
+extern Bool XkbFilterEvents(ClientPtr, int, xEvent *);
+#endif
+
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+
+#ifdef XEVIE
+extern WindowPtr *WindowTable;
+extern int xevieFlag;
+extern int xevieClientIndex;
+extern DeviceIntPtr xeviemouse;
+extern DeviceIntPtr xeviekb;
+extern Mask xevieMask;
+extern Mask xevieFilters[128];
+extern int xevieEventSent;
+extern int xevieKBEventSent;
+int xeviegrabState = 0;
+xEvent *xeviexE;
+#endif
+
+#include <X11/extensions/XIproto.h>
+#include "exevents.h"
+#include "extnsionst.h"
+
+#include "dixevents.h"
+#include "dixgrabs.h"
+#include "dispatch.h"
+
+#define EXTENSION_EVENT_BASE 64
+
+#define NoSuchEvent 0x80000000 /* so doesn't match NoEventMask */
+#define StructureAndSubMask ( StructureNotifyMask | SubstructureNotifyMask )
+#define AllButtonsMask ( \
+ Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask )
+#define MotionMask ( \
+ PointerMotionMask | Button1MotionMask | \
+ Button2MotionMask | Button3MotionMask | Button4MotionMask | \
+ Button5MotionMask | ButtonMotionMask )
+#define PropagateMask ( \
+ KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \
+ MotionMask )
+#define PointerGrabMask ( \
+ ButtonPressMask | ButtonReleaseMask | \
+ EnterWindowMask | LeaveWindowMask | \
+ PointerMotionHintMask | KeymapStateMask | \
+ MotionMask )
+#define AllModifiersMask ( \
+ ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \
+ Mod3Mask | Mod4Mask | Mod5Mask )
+#define AllEventMasks (lastEventMask|(lastEventMask-1))
+/*
+ * The following relies on the fact that the Button<n>MotionMasks are equal
+ * to the corresponding Button<n>Masks from the current modifier/button state.
+ */
+#define Motion_Filter(class) (PointerMotionMask | \
+ (class)->state | (class)->motionMask)
+
+
+#define WID(w) ((w) ? ((w)->drawable.id) : 0)
+
+#define XE_KBPTR (xE->u.keyButtonPointer)
+
+
+#define rClient(obj) (clients[CLIENT_ID((obj)->resource)])
+
+CallbackListPtr EventCallback;
+CallbackListPtr DeviceEventCallback;
+
+#define DNPMCOUNT 8
+
+Mask DontPropagateMasks[DNPMCOUNT];
+static int DontPropagateRefCnts[DNPMCOUNT];
+
+#ifdef DEBUG
+static debug_events = 0;
+#endif
+InputInfo inputInfo;
+
+static struct {
+ QdEventPtr pending, *pendtail;
+ DeviceIntPtr replayDev; /* kludgy rock to put flag for */
+ WindowPtr replayWin; /* ComputeFreezes */
+ Bool playingEvents;
+ TimeStamp time;
+} syncEvents;
+
+/*
+ * The window trace information is used to avoid having to compute all the
+ * windows between the root and the current pointer window each time a button
+ * or key goes down. The grabs on each of those windows must be checked.
+ */
+static WindowPtr *spriteTrace = (WindowPtr *)NULL;
+#define ROOT spriteTrace[0]
+static int spriteTraceSize = 0;
+static int spriteTraceGood;
+
+static struct {
+ CursorPtr current;
+ BoxRec hotLimits; /* logical constraints of hot spot */
+ Bool confined; /* confined to screen */
+#if defined(SHAPE) || defined(PANORAMIX)
+ RegionPtr hotShape; /* additional logical shape constraint */
+#endif
+ BoxRec physLimits; /* physical constraints of hot spot */
+ WindowPtr win; /* window of logical position */
+ HotSpot hot; /* logical pointer position */
+ HotSpot hotPhys; /* physical pointer position */
+#ifdef PANORAMIX
+ ScreenPtr screen; /* all others are in Screen 0 coordinates */
+ RegionRec Reg1; /* Region 1 for confining motion */
+ RegionRec Reg2; /* Region 2 for confining virtual motion */
+ WindowPtr windows[MAXSCREENS];
+ WindowPtr confineWin; /* confine window */
+#endif
+} sprite; /* info about the cursor sprite */
+
+#ifdef XEVIE
+WindowPtr xeviewin;
+HotSpot xeviehot;
+#endif
+
+static void DoEnterLeaveEvents(
+ WindowPtr fromWin,
+ WindowPtr toWin,
+ int mode
+);
+
+static WindowPtr XYToWindow(
+ int x,
+ int y
+);
+
+extern int lastEvent;
+
+static Mask lastEventMask;
+
+#ifdef XINPUT
+extern int DeviceMotionNotify;
+#endif
+
+#define CantBeFiltered NoEventMask
+static Mask filters[128] =
+{
+ NoSuchEvent, /* 0 */
+ NoSuchEvent, /* 1 */
+ KeyPressMask, /* KeyPress */
+ KeyReleaseMask, /* KeyRelease */
+ ButtonPressMask, /* ButtonPress */
+ ButtonReleaseMask, /* ButtonRelease */
+ PointerMotionMask, /* MotionNotify (initial state) */
+ EnterWindowMask, /* EnterNotify */
+ LeaveWindowMask, /* LeaveNotify */
+ FocusChangeMask, /* FocusIn */
+ FocusChangeMask, /* FocusOut */
+ KeymapStateMask, /* KeymapNotify */
+ ExposureMask, /* Expose */
+ CantBeFiltered, /* GraphicsExpose */
+ CantBeFiltered, /* NoExpose */
+ VisibilityChangeMask, /* VisibilityNotify */
+ SubstructureNotifyMask, /* CreateNotify */
+ StructureAndSubMask, /* DestroyNotify */
+ StructureAndSubMask, /* UnmapNotify */
+ StructureAndSubMask, /* MapNotify */
+ SubstructureRedirectMask, /* MapRequest */
+ StructureAndSubMask, /* ReparentNotify */
+ StructureAndSubMask, /* ConfigureNotify */
+ SubstructureRedirectMask, /* ConfigureRequest */
+ StructureAndSubMask, /* GravityNotify */
+ ResizeRedirectMask, /* ResizeRequest */
+ StructureAndSubMask, /* CirculateNotify */
+ SubstructureRedirectMask, /* CirculateRequest */
+ PropertyChangeMask, /* PropertyNotify */
+ CantBeFiltered, /* SelectionClear */
+ CantBeFiltered, /* SelectionRequest */
+ CantBeFiltered, /* SelectionNotify */
+ ColormapChangeMask, /* ColormapNotify */
+ CantBeFiltered, /* ClientMessage */
+ CantBeFiltered /* MappingNotify */
+};
+
+static CARD8 criticalEvents[32] =
+{
+ 0x7c /* key and button events */
+};
+
+#ifdef PANORAMIX
+
+static void ConfineToShape(RegionPtr shape, int *px, int *py);
+static void SyntheticMotion(int x, int y);
+static void PostNewCursor(void);
+
+static Bool
+XineramaSetCursorPosition(
+ int x,
+ int y,
+ Bool generateEvent
+){
+ ScreenPtr pScreen;
+ BoxRec box;
+ int i;
+
+ /* x,y are in Screen 0 coordinates. We need to decide what Screen
+ to send the message too and what the coordinates relative to
+ that screen are. */
+
+ pScreen = sprite.screen;
+ x += panoramiXdataPtr[0].x;
+ y += panoramiXdataPtr[0].y;
+
+ if(!POINT_IN_REGION(pScreen, &XineramaScreenRegions[pScreen->myNum],
+ x, y, &box))
+ {
+ FOR_NSCREENS(i)
+ {
+ if(i == pScreen->myNum)
+ continue;
+ if(POINT_IN_REGION(pScreen, &XineramaScreenRegions[i], x, y, &box))
+ {
+ pScreen = screenInfo.screens[i];
+ break;
+ }
+ }
+ }
+
+ sprite.screen = pScreen;
+ sprite.hotPhys.x = x - panoramiXdataPtr[0].x;
+ sprite.hotPhys.y = y - panoramiXdataPtr[0].y;
+ x -= panoramiXdataPtr[pScreen->myNum].x;
+ y -= panoramiXdataPtr[pScreen->myNum].y;
+
+ return (*pScreen->SetCursorPosition)(pScreen, x, y, generateEvent);
+}
+
+
+static void
+XineramaConstrainCursor(void)
+{
+ ScreenPtr pScreen = sprite.screen;
+ BoxRec newBox = sprite.physLimits;
+
+ /* Translate the constraining box to the screen
+ the sprite is actually on */
+ newBox.x1 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x;
+ newBox.x2 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x;
+ newBox.y1 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
+ newBox.y2 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
+
+ (* pScreen->ConstrainCursor)(pScreen, &newBox);
+}
+
+static void
+XineramaCheckPhysLimits(
+ CursorPtr cursor,
+ Bool generateEvents
+){
+ HotSpot new;
+
+ if (!cursor)
+ return;
+
+ new = sprite.hotPhys;
+
+ /* I don't care what the DDX has to say about it */
+ sprite.physLimits = sprite.hotLimits;
+
+ /* constrain the pointer to those limits */
+ if (new.x < sprite.physLimits.x1)
+ new.x = sprite.physLimits.x1;
+ else
+ if (new.x >= sprite.physLimits.x2)
+ new.x = sprite.physLimits.x2 - 1;
+ if (new.y < sprite.physLimits.y1)
+ new.y = sprite.physLimits.y1;
+ else
+ if (new.y >= sprite.physLimits.y2)
+ new.y = sprite.physLimits.y2 - 1;
+
+ if (sprite.hotShape) /* more work if the shape is a mess */
+ ConfineToShape(sprite.hotShape, &new.x, &new.y);
+
+ if((new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
+ {
+ XineramaSetCursorPosition (new.x, new.y, generateEvents);
+ if (!generateEvents)
+ SyntheticMotion(new.x, new.y);
+ }
+
+ /* Tell DDX what the limits are */
+ XineramaConstrainCursor();
+}
+
+
+static Bool
+XineramaSetWindowPntrs(WindowPtr pWin)
+{
+ if(pWin == WindowTable[0]) {
+ memcpy(sprite.windows, WindowTable,
+ PanoramiXNumScreens*sizeof(WindowPtr));
+ } else {
+ PanoramiXRes *win;
+ int i;
+
+ win = (PanoramiXRes*)LookupIDByType(pWin->drawable.id, XRT_WINDOW);
+
+ if(!win)
+ return FALSE;
+
+ for(i = 0; i < PanoramiXNumScreens; i++) {
+ sprite.windows[i] = LookupIDByType(win->info[i].id, RT_WINDOW);
+ if(!sprite.windows[i]) /* window is being unmapped */
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+static void
+XineramaCheckVirtualMotion(
+ QdEventPtr qe,
+ WindowPtr pWin
+){
+
+ if (qe)
+ {
+ sprite.hot.pScreen = qe->pScreen; /* should always be Screen 0 */
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
+ pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
+ NullWindow;
+ }
+ if (pWin)
+ {
+ int x, y, off_x, off_y, i;
+ BoxRec lims;
+
+ if(!XineramaSetWindowPntrs(pWin))
+ return;
+
+ i = PanoramiXNumScreens - 1;
+
+ REGION_COPY(sprite.screen, &sprite.Reg2,
+ &sprite.windows[i]->borderSize);
+ off_x = panoramiXdataPtr[i].x;
+ off_y = panoramiXdataPtr[i].y;
+
+ while(i--) {
+ x = off_x - panoramiXdataPtr[i].x;
+ y = off_y - panoramiXdataPtr[i].y;
+
+ if(x || y)
+ REGION_TRANSLATE(sprite.screen, &sprite.Reg2, x, y);
+
+ REGION_UNION(sprite.screen, &sprite.Reg2, &sprite.Reg2,
+ &sprite.windows[i]->borderSize);
+
+ off_x = panoramiXdataPtr[i].x;
+ off_y = panoramiXdataPtr[i].y;
+ }
+
+ lims = *REGION_EXTENTS(sprite.screen, &sprite.Reg2);
+
+ if (sprite.hot.x < lims.x1)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = lims.x1;
+ else if (sprite.hot.x >= lims.x2)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = lims.x2 - 1;
+ if (sprite.hot.y < lims.y1)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = lims.y1;
+ else if (sprite.hot.y >= lims.y2)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = lims.y2 - 1;
+
+ if (REGION_NUM_RECTS(&sprite.Reg2) > 1)
+ ConfineToShape(&sprite.Reg2, &sprite.hot.x, &sprite.hot.y);
+
+ if (qe)
+ {
+ qe->pScreen = sprite.hot.pScreen;
+ qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
+ qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
+ }
+ }
+}
+
+
+static Bool
+XineramaCheckMotion(xEvent *xE)
+{
+ WindowPtr prevSpriteWin = sprite.win;
+
+ if (xE && !syncEvents.playingEvents)
+ {
+ /* Motion events entering DIX get translated to Screen 0
+ coordinates. Replayed events have already been
+ translated since they've entered DIX before */
+ XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x -
+ panoramiXdataPtr[0].x;
+ XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y -
+ panoramiXdataPtr[0].y;
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = XE_KBPTR.rootX;
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = XE_KBPTR.rootY;
+ if (sprite.hot.x < sprite.physLimits.x1)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = sprite.physLimits.x1;
+ else if (sprite.hot.x >= sprite.physLimits.x2)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = sprite.physLimits.x2 - 1;
+ if (sprite.hot.y < sprite.physLimits.y1)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = sprite.physLimits.y1;
+ else if (sprite.hot.y >= sprite.physLimits.y2)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = sprite.physLimits.y2 - 1;
+
+ if (sprite.hotShape)
+ ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
+
+ sprite.hotPhys = sprite.hot;
+ if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
+ (sprite.hotPhys.y != XE_KBPTR.rootY))
+ {
+ XineramaSetCursorPosition(
+ sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
+ }
+ XE_KBPTR.rootX = sprite.hot.x;
+ XE_KBPTR.rootY = sprite.hot.y;
+ }
+
+#ifdef XEVIE
+ xeviewin =
+#endif
+ sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
+
+ if (sprite.win != prevSpriteWin)
+ {
+ if (prevSpriteWin != NullWindow) {
+ if (!xE)
+ UpdateCurrentTimeIf();
+ DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
+ }
+ PostNewCursor();
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+static void
+XineramaConfineCursorToWindow(WindowPtr pWin, Bool generateEvents)
+{
+
+ if (syncEvents.playingEvents)
+ {
+ XineramaCheckVirtualMotion((QdEventPtr)NULL, pWin);
+ SyntheticMotion(sprite.hot.x, sprite.hot.y);
+ }
+ else
+ {
+ int x, y, off_x, off_y, i;
+
+ if(!XineramaSetWindowPntrs(pWin))
+ return;
+
+ i = PanoramiXNumScreens - 1;
+
+ REGION_COPY(sprite.screen, &sprite.Reg1,
+ &sprite.windows[i]->borderSize);
+ off_x = panoramiXdataPtr[i].x;
+ off_y = panoramiXdataPtr[i].y;
+
+ while(i--) {
+ x = off_x - panoramiXdataPtr[i].x;
+ y = off_y - panoramiXdataPtr[i].y;
+
+ if(x || y)
+ REGION_TRANSLATE(sprite.screen, &sprite.Reg1, x, y);
+
+ REGION_UNION(sprite.screen, &sprite.Reg1, &sprite.Reg1,
+ &sprite.windows[i]->borderSize);
+
+ off_x = panoramiXdataPtr[i].x;
+ off_y = panoramiXdataPtr[i].y;
+ }
+
+ sprite.hotLimits = *REGION_EXTENTS(sprite.screen, &sprite.Reg1);
+
+ if(REGION_NUM_RECTS(&sprite.Reg1) > 1)
+ sprite.hotShape = &sprite.Reg1;
+ else
+ sprite.hotShape = NullRegion;
+
+ sprite.confined = FALSE;
+ sprite.confineWin = (pWin == WindowTable[0]) ? NullWindow : pWin;
+
+ XineramaCheckPhysLimits(sprite.current, generateEvents);
+ }
+}
+
+
+static void
+XineramaChangeToCursor(CursorPtr cursor)
+{
+ if (cursor != sprite.current)
+ {
+ if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
+ (sprite.current->bits->yhot != cursor->bits->yhot))
+ XineramaCheckPhysLimits(cursor, FALSE);
+ (*sprite.screen->DisplayCursor)(sprite.screen, cursor);
+ FreeCursor(sprite.current, (Cursor)0);
+ sprite.current = cursor;
+ sprite.current->refcnt++;
+ }
+}
+
+
+#endif /* PANORAMIX */
+
+void
+SetMaskForEvent(Mask mask, int event)
+{
+ if ((event < LASTEvent) || (event >= 128))
+ FatalError("SetMaskForEvent: bogus event number");
+ filters[event] = mask;
+}
+
+void
+SetCriticalEvent(int event)
+{
+ if (event >= 128)
+ FatalError("SetCriticalEvent: bogus event number");
+ criticalEvents[event >> 3] |= 1 << (event & 7);
+}
+
+static void
+SyntheticMotion(int x, int y)
+{
+ xEvent xE;
+
+#ifdef PANORAMIX
+ /* Translate back to the sprite screen since processInputProc
+ will translate from sprite screen to screen 0 upon reentry
+ to the DIX layer */
+ if(!noPanoramiXExtension) {
+ x += panoramiXdataPtr[0].x - panoramiXdataPtr[sprite.screen->myNum].x;
+ y += panoramiXdataPtr[0].y - panoramiXdataPtr[sprite.screen->myNum].y;
+ }
+#endif
+ xE.u.keyButtonPointer.rootX = x;
+ xE.u.keyButtonPointer.rootY = y;
+ if (syncEvents.playingEvents)
+ xE.u.keyButtonPointer.time = syncEvents.time.milliseconds;
+ else
+ xE.u.keyButtonPointer.time = currentTime.milliseconds;
+ xE.u.u.type = MotionNotify;
+ (*inputInfo.pointer->public.processInputProc)(&xE, inputInfo.pointer, 1);
+}
+
+#ifdef SHAPE
+static void
+ConfineToShape(RegionPtr shape, int *px, int *py)
+{
+ BoxRec box;
+ int x = *px, y = *py;
+ int incx = 1, incy = 1;
+
+ if (POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box))
+ return;
+ box = *REGION_EXTENTS(sprite.hot.pScreen, shape);
+ /* this is rather crude */
+ do {
+ x += incx;
+ if (x >= box.x2)
+ {
+ incx = -1;
+ x = *px - 1;
+ }
+ else if (x < box.x1)
+ {
+ incx = 1;
+ x = *px;
+ y += incy;
+ if (y >= box.y2)
+ {
+ incy = -1;
+ y = *py - 1;
+ }
+ else if (y < box.y1)
+ return; /* should never get here! */
+ }
+ } while (!POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box));
+ *px = x;
+ *py = y;
+}
+#endif
+
+static void
+CheckPhysLimits(
+ CursorPtr cursor,
+ Bool generateEvents,
+ Bool confineToScreen,
+ ScreenPtr pScreen)
+{
+ HotSpot new;
+
+ if (!cursor)
+ return;
+ new = sprite.hotPhys;
+ if (pScreen)
+ new.pScreen = pScreen;
+ else
+ pScreen = new.pScreen;
+ (*pScreen->CursorLimits) (pScreen, cursor, &sprite.hotLimits,
+ &sprite.physLimits);
+ sprite.confined = confineToScreen;
+ (* pScreen->ConstrainCursor)(pScreen, &sprite.physLimits);
+ if (new.x < sprite.physLimits.x1)
+ new.x = sprite.physLimits.x1;
+ else
+ if (new.x >= sprite.physLimits.x2)
+ new.x = sprite.physLimits.x2 - 1;
+ if (new.y < sprite.physLimits.y1)
+ new.y = sprite.physLimits.y1;
+ else
+ if (new.y >= sprite.physLimits.y2)
+ new.y = sprite.physLimits.y2 - 1;
+#ifdef SHAPE
+ if (sprite.hotShape)
+ ConfineToShape(sprite.hotShape, &new.x, &new.y);
+#endif
+ if ((pScreen != sprite.hotPhys.pScreen) ||
+ (new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
+ {
+ if (pScreen != sprite.hotPhys.pScreen)
+ sprite.hotPhys = new;
+ (*pScreen->SetCursorPosition) (pScreen, new.x, new.y, generateEvents);
+ if (!generateEvents)
+ SyntheticMotion(new.x, new.y);
+ }
+}
+
+static void
+CheckVirtualMotion(
+ register QdEventPtr qe,
+ register WindowPtr pWin)
+{
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ XineramaCheckVirtualMotion(qe, pWin);
+ return;
+ }
+#endif
+ if (qe)
+ {
+ sprite.hot.pScreen = qe->pScreen;
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
+ pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
+ NullWindow;
+ }
+ if (pWin)
+ {
+ BoxRec lims;
+
+ if (sprite.hot.pScreen != pWin->drawable.pScreen)
+ {
+ sprite.hot.pScreen = pWin->drawable.pScreen;
+#ifdef XEVIE
+ xeviehot.x = xeviehot.y = 0;
+#endif
+ sprite.hot.x = sprite.hot.y = 0;
+ }
+ lims = *REGION_EXTENTS(pWin->drawable.pScreen, &pWin->borderSize);
+ if (sprite.hot.x < lims.x1)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = lims.x1;
+ else if (sprite.hot.x >= lims.x2)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = lims.x2 - 1;
+ if (sprite.hot.y < lims.y1)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = lims.y1;
+ else if (sprite.hot.y >= lims.y2)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = lims.y2 - 1;
+#ifdef SHAPE
+ if (wBoundingShape(pWin))
+ ConfineToShape(&pWin->borderSize, &sprite.hot.x, &sprite.hot.y);
+#endif
+ if (qe)
+ {
+ qe->pScreen = sprite.hot.pScreen;
+ qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
+ qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
+ }
+ }
+ ROOT = WindowTable[sprite.hot.pScreen->myNum];
+}
+
+static void
+ConfineCursorToWindow(WindowPtr pWin, Bool generateEvents, Bool confineToScreen)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ XineramaConfineCursorToWindow(pWin, generateEvents);
+ return;
+ }
+#endif
+
+ if (syncEvents.playingEvents)
+ {
+ CheckVirtualMotion((QdEventPtr)NULL, pWin);
+ SyntheticMotion(sprite.hot.x, sprite.hot.y);
+ }
+ else
+ {
+ sprite.hotLimits = *REGION_EXTENTS( pScreen, &pWin->borderSize);
+#ifdef SHAPE
+ sprite.hotShape = wBoundingShape(pWin) ? &pWin->borderSize
+ : NullRegion;
+#endif
+ CheckPhysLimits(sprite.current, generateEvents, confineToScreen,
+ pScreen);
+ }
+}
+
+Bool
+PointerConfinedToScreen()
+{
+ return sprite.confined;
+}
+
+static void
+ChangeToCursor(CursorPtr cursor)
+{
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ XineramaChangeToCursor(cursor);
+ return;
+ }
+#endif
+
+ if (cursor != sprite.current)
+ {
+ if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
+ (sprite.current->bits->yhot != cursor->bits->yhot))
+ CheckPhysLimits(cursor, FALSE, sprite.confined,
+ (ScreenPtr)NULL);
+ (*sprite.hotPhys.pScreen->DisplayCursor) (sprite.hotPhys.pScreen,
+ cursor);
+ FreeCursor(sprite.current, (Cursor)0);
+ sprite.current = cursor;
+ sprite.current->refcnt++;
+ }
+}
+
+/* returns true if b is a descendent of a */
+Bool
+IsParent(register WindowPtr a, register WindowPtr b)
+{
+ for (b = b->parent; b; b = b->parent)
+ if (b == a) return TRUE;
+ return FALSE;
+}
+
+static void
+PostNewCursor(void)
+{
+ register WindowPtr win;
+ register GrabPtr grab = inputInfo.pointer->grab;
+
+ if (syncEvents.playingEvents)
+ return;
+ if (grab)
+ {
+ if (grab->cursor)
+ {
+ ChangeToCursor(grab->cursor);
+ return;
+ }
+ if (IsParent(grab->window, sprite.win))
+ win = sprite.win;
+ else
+ win = grab->window;
+ }
+ else
+ win = sprite.win;
+ for (; win; win = win->parent)
+ if (win->optional && win->optional->cursor != NullCursor)
+ {
+ ChangeToCursor(win->optional->cursor);
+ return;
+ }
+}
+
+WindowPtr
+GetCurrentRootWindow()
+{
+ return ROOT;
+}
+
+WindowPtr
+GetSpriteWindow()
+{
+ return sprite.win;
+}
+
+CursorPtr
+GetSpriteCursor()
+{
+ return sprite.current;
+}
+
+void
+GetSpritePosition(int *px, int *py)
+{
+ *px = sprite.hotPhys.x;
+ *py = sprite.hotPhys.y;
+}
+
+#ifdef PANORAMIX
+int
+XineramaGetCursorScreen()
+{
+ if(!noPanoramiXExtension) {
+ return sprite.screen->myNum;
+ } else {
+ return 0;
+ }
+}
+#endif /* PANORAMIX */
+
+#define TIMESLOP (5 * 60 * 1000) /* 5 minutes */
+
+static void
+MonthChangedOrBadTime(register xEvent *xE)
+{
+ /* If the ddx/OS is careless about not processing timestamped events from
+ * different sources in sorted order, then it's possible for time to go
+ * backwards when it should not. Here we ensure a decent time.
+ */
+ if ((currentTime.milliseconds - XE_KBPTR.time) > TIMESLOP)
+ currentTime.months++;
+ else
+ XE_KBPTR.time = currentTime.milliseconds;
+}
+
+#define NoticeTime(xE) { \
+ if ((xE)->u.keyButtonPointer.time < currentTime.milliseconds) \
+ MonthChangedOrBadTime(xE); \
+ currentTime.milliseconds = (xE)->u.keyButtonPointer.time; \
+ lastDeviceEventTime = currentTime; }
+
+void
+NoticeEventTime(register xEvent *xE)
+{
+ if (!syncEvents.playingEvents)
+ NoticeTime(xE);
+}
+
+/**************************************************************************
+ * The following procedures deal with synchronous events *
+ **************************************************************************/
+
+void
+EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count)
+{
+ register QdEventPtr tail = *syncEvents.pendtail;
+ register QdEventPtr qe;
+ xEvent *qxE;
+
+ NoticeTime(xE);
+
+#ifdef XKB
+ /* Fix for key repeating bug. */
+ if (device->key != NULL && device->key->xkbInfo != NULL &&
+ xE->u.u.type == KeyRelease)
+ AccessXCancelRepeatKey(device->key->xkbInfo, xE->u.u.detail);
+#endif
+
+ if (DeviceEventCallback)
+ {
+ DeviceEventInfoRec eventinfo;
+ /* The RECORD spec says that the root window field of motion events
+ * must be valid. At this point, it hasn't been filled in yet, so
+ * we do it here. The long expression below is necessary to get
+ * the current root window; the apparently reasonable alternative
+ * GetCurrentRootWindow()->drawable.id doesn't give you the right
+ * answer on the first motion event after a screen change because
+ * the data that GetCurrentRootWindow relies on hasn't been
+ * updated yet.
+ */
+ if (xE->u.u.type == MotionNotify)
+ XE_KBPTR.root =
+ WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
+ eventinfo.events = xE;
+ eventinfo.count = count;
+ CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+ }
+ if (xE->u.u.type == MotionNotify)
+ {
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x -
+ panoramiXdataPtr[0].x;
+ XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y -
+ panoramiXdataPtr[0].y;
+ }
+#endif
+ sprite.hotPhys.x = XE_KBPTR.rootX;
+ sprite.hotPhys.y = XE_KBPTR.rootY;
+ /* do motion compression */
+ if (tail &&
+ (tail->event->u.u.type == MotionNotify) &&
+ (tail->pScreen == sprite.hotPhys.pScreen))
+ {
+ tail->event->u.keyButtonPointer.rootX = sprite.hotPhys.x;
+ tail->event->u.keyButtonPointer.rootY = sprite.hotPhys.y;
+ tail->event->u.keyButtonPointer.time = XE_KBPTR.time;
+ tail->months = currentTime.months;
+ return;
+ }
+ }
+ qe = (QdEventPtr)xalloc(sizeof(QdEventRec) + (count * sizeof(xEvent)));
+ if (!qe)
+ return;
+ qe->next = (QdEventPtr)NULL;
+ qe->device = device;
+ qe->pScreen = sprite.hotPhys.pScreen;
+ qe->months = currentTime.months;
+ qe->event = (xEvent *)(qe + 1);
+ qe->evcount = count;
+ for (qxE = qe->event; --count >= 0; qxE++, xE++)
+ *qxE = *xE;
+ if (tail)
+ syncEvents.pendtail = &tail->next;
+ *syncEvents.pendtail = qe;
+}
+
+static void
+PlayReleasedEvents(void)
+{
+ register QdEventPtr *prev, qe;
+ register DeviceIntPtr dev;
+
+ prev = &syncEvents.pending;
+ while ( (qe = *prev) )
+ {
+ if (!qe->device->sync.frozen)
+ {
+ *prev = qe->next;
+ if (*syncEvents.pendtail == *prev)
+ syncEvents.pendtail = prev;
+ if (qe->event->u.u.type == MotionNotify)
+ CheckVirtualMotion(qe, NullWindow);
+ syncEvents.time.months = qe->months;
+ syncEvents.time.milliseconds = qe->event->u.keyButtonPointer.time;
+#ifdef PANORAMIX
+ /* Translate back to the sprite screen since processInputProc
+ will translate from sprite screen to screen 0 upon reentry
+ to the DIX layer */
+ if(!noPanoramiXExtension) {
+ qe->event->u.keyButtonPointer.rootX +=
+ panoramiXdataPtr[0].x -
+ panoramiXdataPtr[sprite.screen->myNum].x;
+ qe->event->u.keyButtonPointer.rootY +=
+ panoramiXdataPtr[0].y -
+ panoramiXdataPtr[sprite.screen->myNum].y;
+ }
+#endif
+ (*qe->device->public.processInputProc)(qe->event, qe->device,
+ qe->evcount);
+ xfree(qe);
+ for (dev = inputInfo.devices; dev && dev->sync.frozen; dev = dev->next)
+ ;
+ if (!dev)
+ break;
+ /* Playing the event may have unfrozen another device. */
+ /* So to play it safe, restart at the head of the queue */
+ prev = &syncEvents.pending;
+ }
+ else
+ prev = &qe->next;
+ }
+}
+
+static void
+FreezeThaw(register DeviceIntPtr dev, Bool frozen)
+{
+ dev->sync.frozen = frozen;
+ if (frozen)
+ dev->public.processInputProc = dev->public.enqueueInputProc;
+ else
+ dev->public.processInputProc = dev->public.realInputProc;
+}
+
+void
+ComputeFreezes()
+{
+ register DeviceIntPtr replayDev = syncEvents.replayDev;
+ register int i;
+ WindowPtr w;
+ register xEvent *xE;
+ int count;
+ GrabPtr grab;
+ register DeviceIntPtr dev;
+
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ FreezeThaw(dev, dev->sync.other || (dev->sync.state >= FROZEN));
+ if (syncEvents.playingEvents || (!replayDev && !syncEvents.pending))
+ return;
+ syncEvents.playingEvents = TRUE;
+ if (replayDev)
+ {
+ xE = replayDev->sync.event;
+ count = replayDev->sync.evcount;
+ syncEvents.replayDev = (DeviceIntPtr)NULL;
+
+ w = XYToWindow( XE_KBPTR.rootX, XE_KBPTR.rootY);
+ for (i = 0; i < spriteTraceGood; i++)
+ {
+ if (syncEvents.replayWin == spriteTrace[i])
+ {
+ if (!CheckDeviceGrabs(replayDev, xE, i+1, count)) {
+ if (replayDev->focus)
+ DeliverFocusedEvent(replayDev, xE, w, count);
+ else
+ DeliverDeviceEvents(w, xE, NullGrab, NullWindow,
+ replayDev, count);
+ }
+ goto playmore;
+ }
+ }
+ /* must not still be in the same stack */
+ if (replayDev->focus)
+ DeliverFocusedEvent(replayDev, xE, w, count);
+ else
+ DeliverDeviceEvents(w, xE, NullGrab, NullWindow, replayDev, count);
+ }
+playmore:
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (!dev->sync.frozen)
+ {
+ PlayReleasedEvents();
+ break;
+ }
+ }
+ syncEvents.playingEvents = FALSE;
+ /* the following may have been skipped during replay, so do it now */
+ if ((grab = inputInfo.pointer->grab) && grab->confineTo)
+ {
+ if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+ sprite.hotPhys.x = sprite.hotPhys.y = 0;
+ ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+ }
+ else
+ ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
+ TRUE, FALSE);
+ PostNewCursor();
+}
+
+#ifdef RANDR
+void
+ScreenRestructured (ScreenPtr pScreen)
+{
+ GrabPtr grab;
+
+ if ((grab = inputInfo.pointer->grab) && grab->confineTo)
+ {
+ if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+ sprite.hotPhys.x = sprite.hotPhys.y = 0;
+ ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+ }
+ else
+ ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
+ TRUE, FALSE);
+}
+#endif
+
+void
+CheckGrabForSyncs(register DeviceIntPtr thisDev, Bool thisMode, Bool otherMode)
+{
+ register GrabPtr grab = thisDev->grab;
+ register DeviceIntPtr dev;
+
+ if (thisMode == GrabModeSync)
+ thisDev->sync.state = FROZEN_NO_EVENT;
+ else
+ { /* free both if same client owns both */
+ thisDev->sync.state = THAWED;
+ if (thisDev->sync.other &&
+ (CLIENT_BITS(thisDev->sync.other->resource) ==
+ CLIENT_BITS(grab->resource)))
+ thisDev->sync.other = NullGrab;
+ }
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev != thisDev)
+ {
+ if (otherMode == GrabModeSync)
+ dev->sync.other = grab;
+ else
+ { /* free both if same client owns both */
+ if (dev->sync.other &&
+ (CLIENT_BITS(dev->sync.other->resource) ==
+ CLIENT_BITS(grab->resource)))
+ dev->sync.other = NullGrab;
+ }
+ }
+ }
+ ComputeFreezes();
+}
+
+void
+ActivatePointerGrab(register DeviceIntPtr mouse, register GrabPtr grab,
+ TimeStamp time, Bool autoGrab)
+{
+ WindowPtr oldWin = (mouse->grab) ? mouse->grab->window
+ : sprite.win;
+
+ if (grab->confineTo)
+ {
+ if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+ sprite.hotPhys.x = sprite.hotPhys.y = 0;
+ ConfineCursorToWindow(grab->confineTo, FALSE, TRUE);
+ }
+ DoEnterLeaveEvents(oldWin, grab->window, NotifyGrab);
+ mouse->valuator->motionHintWindow = NullWindow;
+ if (syncEvents.playingEvents)
+ mouse->grabTime = syncEvents.time;
+ else
+ mouse->grabTime = time;
+ if (grab->cursor)
+ grab->cursor->refcnt++;
+ mouse->activeGrab = *grab;
+ mouse->grab = &mouse->activeGrab;
+ mouse->fromPassiveGrab = autoGrab;
+ PostNewCursor();
+ CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
+}
+
+void
+DeactivatePointerGrab(register DeviceIntPtr mouse)
+{
+ register GrabPtr grab = mouse->grab;
+ register DeviceIntPtr dev;
+
+ mouse->valuator->motionHintWindow = NullWindow;
+ mouse->grab = NullGrab;
+ mouse->sync.state = NOT_GRABBED;
+ mouse->fromPassiveGrab = FALSE;
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->sync.other == grab)
+ dev->sync.other = NullGrab;
+ }
+ DoEnterLeaveEvents(grab->window, sprite.win, NotifyUngrab);
+ if (grab->confineTo)
+ ConfineCursorToWindow(ROOT, FALSE, FALSE);
+ PostNewCursor();
+ if (grab->cursor)
+ FreeCursor(grab->cursor, (Cursor)0);
+ ComputeFreezes();
+}
+
+void
+ActivateKeyboardGrab(register DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, Bool passive)
+{
+ WindowPtr oldWin;
+
+ if (keybd->grab)
+ oldWin = keybd->grab->window;
+ else if (keybd->focus)
+ oldWin = keybd->focus->win;
+ else
+ oldWin = sprite.win;
+ if (oldWin == FollowKeyboardWin)
+ oldWin = inputInfo.keyboard->focus->win;
+ if (keybd->valuator)
+ keybd->valuator->motionHintWindow = NullWindow;
+ DoFocusEvents(keybd, oldWin, grab->window, NotifyGrab);
+ if (syncEvents.playingEvents)
+ keybd->grabTime = syncEvents.time;
+ else
+ keybd->grabTime = time;
+ keybd->activeGrab = *grab;
+ keybd->grab = &keybd->activeGrab;
+ keybd->fromPassiveGrab = passive;
+ CheckGrabForSyncs(keybd, (Bool)grab->keyboardMode, (Bool)grab->pointerMode);
+}
+
+void
+DeactivateKeyboardGrab(register DeviceIntPtr keybd)
+{
+ register GrabPtr grab = keybd->grab;
+ register DeviceIntPtr dev;
+ register WindowPtr focusWin = keybd->focus ? keybd->focus->win
+ : sprite.win;
+
+ if (focusWin == FollowKeyboardWin)
+ focusWin = inputInfo.keyboard->focus->win;
+ if (keybd->valuator)
+ keybd->valuator->motionHintWindow = NullWindow;
+ keybd->grab = NullGrab;
+ keybd->sync.state = NOT_GRABBED;
+ keybd->fromPassiveGrab = FALSE;
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->sync.other == grab)
+ dev->sync.other = NullGrab;
+ }
+ DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab);
+ ComputeFreezes();
+}
+
+void
+AllowSome(ClientPtr client, TimeStamp time, DeviceIntPtr thisDev, int newState)
+{
+ Bool thisGrabbed, otherGrabbed, othersFrozen, thisSynced;
+ TimeStamp grabTime;
+ register DeviceIntPtr dev;
+
+ thisGrabbed = thisDev->grab && SameClient(thisDev->grab, client);
+ thisSynced = FALSE;
+ otherGrabbed = FALSE;
+ othersFrozen = TRUE;
+ grabTime = thisDev->grabTime;
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev == thisDev)
+ continue;
+ if (dev->grab && SameClient(dev->grab, client))
+ {
+ if (!(thisGrabbed || otherGrabbed) ||
+ (CompareTimeStamps(dev->grabTime, grabTime) == LATER))
+ grabTime = dev->grabTime;
+ otherGrabbed = TRUE;
+ if (thisDev->sync.other == dev->grab)
+ thisSynced = TRUE;
+ if (dev->sync.state < FROZEN)
+ othersFrozen = FALSE;
+ }
+ else if (!dev->sync.other || !SameClient(dev->sync.other, client))
+ othersFrozen = FALSE;
+ }
+ if (!((thisGrabbed && thisDev->sync.state >= FROZEN) || thisSynced))
+ return;
+ if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, grabTime) == EARLIER))
+ return;
+ switch (newState)
+ {
+ case THAWED: /* Async */
+ if (thisGrabbed)
+ thisDev->sync.state = THAWED;
+ if (thisSynced)
+ thisDev->sync.other = NullGrab;
+ ComputeFreezes();
+ break;
+ case FREEZE_NEXT_EVENT: /* Sync */
+ if (thisGrabbed)
+ {
+ thisDev->sync.state = FREEZE_NEXT_EVENT;
+ if (thisSynced)
+ thisDev->sync.other = NullGrab;
+ ComputeFreezes();
+ }
+ break;
+ case THAWED_BOTH: /* AsyncBoth */
+ if (othersFrozen)
+ {
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->grab && SameClient(dev->grab, client))
+ dev->sync.state = THAWED;
+ if (dev->sync.other && SameClient(dev->sync.other, client))
+ dev->sync.other = NullGrab;
+ }
+ ComputeFreezes();
+ }
+ break;
+ case FREEZE_BOTH_NEXT_EVENT: /* SyncBoth */
+ if (othersFrozen)
+ {
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->grab && SameClient(dev->grab, client))
+ dev->sync.state = FREEZE_BOTH_NEXT_EVENT;
+ if (dev->sync.other && SameClient(dev->sync.other, client))
+ dev->sync.other = NullGrab;
+ }
+ ComputeFreezes();
+ }
+ break;
+ case NOT_GRABBED: /* Replay */
+ if (thisGrabbed && thisDev->sync.state == FROZEN_WITH_EVENT)
+ {
+ if (thisSynced)
+ thisDev->sync.other = NullGrab;
+ syncEvents.replayDev = thisDev;
+ syncEvents.replayWin = thisDev->grab->window;
+ (*thisDev->DeactivateGrab)(thisDev);
+ syncEvents.replayDev = (DeviceIntPtr)NULL;
+ }
+ break;
+ case THAW_OTHERS: /* AsyncOthers */
+ if (othersFrozen)
+ {
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev == thisDev)
+ continue;
+ if (dev->grab && SameClient(dev->grab, client))
+ dev->sync.state = THAWED;
+ if (dev->sync.other && SameClient(dev->sync.other, client))
+ dev->sync.other = NullGrab;
+ }
+ ComputeFreezes();
+ }
+ break;
+ }
+}
+
+int
+ProcAllowEvents(register ClientPtr client)
+{
+ TimeStamp time;
+ DeviceIntPtr mouse = inputInfo.pointer;
+ DeviceIntPtr keybd = inputInfo.keyboard;
+ REQUEST(xAllowEventsReq);
+
+ REQUEST_SIZE_MATCH(xAllowEventsReq);
+ time = ClientTimeToServerTime(stuff->time);
+ switch (stuff->mode)
+ {
+ case ReplayPointer:
+ AllowSome(client, time, mouse, NOT_GRABBED);
+ break;
+ case SyncPointer:
+ AllowSome(client, time, mouse, FREEZE_NEXT_EVENT);
+ break;
+ case AsyncPointer:
+ AllowSome(client, time, mouse, THAWED);
+ break;
+ case ReplayKeyboard:
+ AllowSome(client, time, keybd, NOT_GRABBED);
+ break;
+ case SyncKeyboard:
+ AllowSome(client, time, keybd, FREEZE_NEXT_EVENT);
+ break;
+ case AsyncKeyboard:
+ AllowSome(client, time, keybd, THAWED);
+ break;
+ case SyncBoth:
+ AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT);
+ break;
+ case AsyncBoth:
+ AllowSome(client, time, keybd, THAWED_BOTH);
+ break;
+ default:
+ client->errorValue = stuff->mode;
+ return BadValue;
+ }
+ return Success;
+}
+
+void
+ReleaseActiveGrabs(ClientPtr client)
+{
+ register DeviceIntPtr dev;
+ Bool done;
+
+ /* XXX CloseDownClient should remove passive grabs before
+ * releasing active grabs.
+ */
+ do {
+ done = TRUE;
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->grab && SameClient(dev->grab, client))
+ {
+ (*dev->DeactivateGrab)(dev);
+ done = FALSE;
+ }
+ }
+ } while (!done);
+}
+
+/**************************************************************************
+ * The following procedures deal with delivering events *
+ **************************************************************************/
+
+int
+TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
+ Mask filter, GrabPtr grab)
+{
+ int i;
+ int type;
+
+#ifdef DEBUG
+ if (debug_events) ErrorF(
+ "Event([%d, %d], mask=0x%x), client=%d",
+ pEvents->u.u.type, pEvents->u.u.detail, mask, client->index);
+#endif
+ if ((client) && (client != serverClient) && (!client->clientGone) &&
+ ((filter == CantBeFiltered) || (mask & filter)))
+ {
+ if (grab && !SameClient(grab, client))
+ return -1; /* don't send, but notify caller */
+ type = pEvents->u.u.type;
+ if (type == MotionNotify)
+ {
+ if (mask & PointerMotionHintMask)
+ {
+ if (WID(inputInfo.pointer->valuator->motionHintWindow) ==
+ pEvents->u.keyButtonPointer.event)
+ {
+#ifdef DEBUG
+ if (debug_events) ErrorF("\n");
+ fprintf(stderr,"motionHintWindow == keyButtonPointer.event\n");
+#endif
+ return 1; /* don't send, but pretend we did */
+ }
+ pEvents->u.u.detail = NotifyHint;
+ }
+ else
+ {
+ pEvents->u.u.detail = NotifyNormal;
+ }
+ }
+#ifdef XINPUT
+ else
+ {
+ if ((type == DeviceMotionNotify) &&
+ MaybeSendDeviceMotionNotifyHint
+ ((deviceKeyButtonPointer*)pEvents, mask) != 0)
+ return 1;
+ }
+#endif
+ type &= 0177;
+ if (type != KeymapNotify)
+ {
+ /* all extension events must have a sequence number */
+ for (i = 0; i < count; i++)
+ pEvents[i].u.u.sequenceNumber = client->sequence;
+ }
+
+ if (BitIsOn(criticalEvents, type))
+ {
+#ifdef SMART_SCHEDULE
+ if (client->smart_priority < SMART_MAX_PRIORITY)
+ client->smart_priority++;
+#endif
+ SetCriticalOutputPending();
+ }
+
+ WriteEventsToClient(client, count, pEvents);
+#ifdef DEBUG
+ if (debug_events) ErrorF( " delivered\n");
+#endif
+ return 1;
+ }
+ else
+ {
+#ifdef DEBUG
+ if (debug_events) ErrorF("\n");
+#endif
+ return 0;
+ }
+}
+
+int
+DeliverEventsToWindow(register WindowPtr pWin, xEvent *pEvents, int count,
+ Mask filter, GrabPtr grab, int mskidx)
+{
+ int deliveries = 0, nondeliveries = 0;
+ int attempt;
+ register InputClients *other;
+ ClientPtr client = NullClient;
+ Mask deliveryMask = 0; /* If a grab occurs due to a button press, then
+ this mask is the mask of the grab. */
+ int type = pEvents->u.u.type;
+
+ /* CantBeFiltered means only window owner gets the event */
+ if ((filter == CantBeFiltered) || !(type & EXTENSION_EVENT_BASE))
+ {
+ /* if nobody ever wants to see this event, skip some work */
+ if (filter != CantBeFiltered &&
+ !((wOtherEventMasks(pWin)|pWin->eventMask) & filter))
+ return 0;
+ if ( (attempt = TryClientEvents(wClient(pWin), pEvents, count,
+ pWin->eventMask, filter, grab)) )
+ {
+ if (attempt > 0)
+ {
+ deliveries++;
+ client = wClient(pWin);
+ deliveryMask = pWin->eventMask;
+ } else
+ nondeliveries--;
+ }
+ }
+ if (filter != CantBeFiltered)
+ {
+ if (type & EXTENSION_EVENT_BASE)
+ {
+ OtherInputMasks *inputMasks;
+
+ inputMasks = wOtherInputMasks(pWin);
+ if (!inputMasks ||
+ !(inputMasks->inputEvents[mskidx] & filter))
+ return 0;
+ other = inputMasks->inputClients;
+ }
+ else
+ other = (InputClients *)wOtherClients(pWin);
+ for (; other; other = other->next)
+ {
+ if ( (attempt = TryClientEvents(rClient(other), pEvents, count,
+ other->mask[mskidx], filter, grab)) )
+ {
+ if (attempt > 0)
+ {
+ deliveries++;
+ client = rClient(other);
+ deliveryMask = other->mask[mskidx];
+ } else
+ nondeliveries--;
+ }
+ }
+ }
+ if ((type == ButtonPress) && deliveries && (!grab))
+ {
+ GrabRec tempGrab;
+
+ tempGrab.device = inputInfo.pointer;
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.window = pWin;
+ tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
+ tempGrab.eventMask = deliveryMask;
+ tempGrab.keyboardMode = GrabModeAsync;
+ tempGrab.pointerMode = GrabModeAsync;
+ tempGrab.confineTo = NullWindow;
+ tempGrab.cursor = NullCursor;
+ (*inputInfo.pointer->ActivateGrab)(inputInfo.pointer, &tempGrab,
+ currentTime, TRUE);
+ }
+ else if ((type == MotionNotify) && deliveries)
+ inputInfo.pointer->valuator->motionHintWindow = pWin;
+#ifdef XINPUT
+ else
+ {
+ if (((type == DeviceMotionNotify)
+#ifdef XKB
+ || (type == DeviceButtonPress)
+#endif
+ ) && deliveries)
+ CheckDeviceGrabAndHintWindow (pWin, type,
+ (deviceKeyButtonPointer*) pEvents,
+ grab, client, deliveryMask);
+ }
+#endif
+ if (deliveries)
+ return deliveries;
+ return nondeliveries;
+}
+
+/* If the event goes to dontClient, don't send it and return 0. if
+ send works, return 1 or if send didn't work, return 2.
+ Only works for core events.
+*/
+
+#ifdef PANORAMIX
+static int
+XineramaTryClientEventsResult(
+ ClientPtr client,
+ GrabPtr grab,
+ Mask mask,
+ Mask filter
+){
+ if ((client) && (client != serverClient) && (!client->clientGone) &&
+ ((filter == CantBeFiltered) || (mask & filter)))
+ {
+ if (grab && !SameClient(grab, client)) return -1;
+ else return 1;
+ }
+ return 0;
+}
+#endif
+
+int
+MaybeDeliverEventsToClient(register WindowPtr pWin, xEvent *pEvents,
+ int count, Mask filter, ClientPtr dontClient)
+{
+ register OtherClients *other;
+
+
+ if (pWin->eventMask & filter)
+ {
+ if (wClient(pWin) == dontClient)
+ return 0;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
+ return XineramaTryClientEventsResult(
+ wClient(pWin), NullGrab, pWin->eventMask, filter);
+#endif
+ return TryClientEvents(wClient(pWin), pEvents, count,
+ pWin->eventMask, filter, NullGrab);
+ }
+ for (other = wOtherClients(pWin); other; other = other->next)
+ {
+ if (other->mask & filter)
+ {
+ if (SameClient(other, dontClient))
+ return 0;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
+ return XineramaTryClientEventsResult(
+ rClient(other), NullGrab, other->mask, filter);
+#endif
+ return TryClientEvents(rClient(other), pEvents, count,
+ other->mask, filter, NullGrab);
+ }
+ }
+ return 2;
+}
+
+static void
+FixUpEventFromWindow(
+ xEvent *xE,
+ WindowPtr pWin,
+ Window child,
+ Bool calcChild)
+{
+ if (calcChild)
+ {
+ WindowPtr w=spriteTrace[spriteTraceGood-1];
+ /* If the search ends up past the root should the child field be
+ set to none or should the value in the argument be passed
+ through. It probably doesn't matter since everyone calls
+ this function with child == None anyway. */
+
+ while (w)
+ {
+ /* If the source window is same as event window, child should be
+ none. Don't bother going all all the way back to the root. */
+
+ if (w == pWin)
+ {
+ child = None;
+ break;
+ }
+
+ if (w->parent == pWin)
+ {
+ child = w->drawable.id;
+ break;
+ }
+ w = w->parent;
+ }
+ }
+ XE_KBPTR.root = ROOT->drawable.id;
+ XE_KBPTR.event = pWin->drawable.id;
+ if (sprite.hot.pScreen == pWin->drawable.pScreen)
+ {
+ XE_KBPTR.sameScreen = xTrue;
+ XE_KBPTR.child = child;
+ XE_KBPTR.eventX =
+ XE_KBPTR.rootX - pWin->drawable.x;
+ XE_KBPTR.eventY =
+ XE_KBPTR.rootY - pWin->drawable.y;
+ }
+ else
+ {
+ XE_KBPTR.sameScreen = xFalse;
+ XE_KBPTR.child = None;
+ XE_KBPTR.eventX = 0;
+ XE_KBPTR.eventY = 0;
+ }
+}
+
+int
+DeliverDeviceEvents(register WindowPtr pWin, register xEvent *xE, GrabPtr grab,
+ register WindowPtr stopAt, DeviceIntPtr dev, int count)
+{
+ Window child = None;
+ int type = xE->u.u.type;
+ Mask filter = filters[type];
+ int deliveries = 0;
+
+ if (type & EXTENSION_EVENT_BASE)
+ {
+ register OtherInputMasks *inputMasks;
+ int mskidx = dev->id;
+
+ inputMasks = wOtherInputMasks(pWin);
+ if (inputMasks && !(filter & inputMasks->deliverableEvents[mskidx]))
+ return 0;
+ while (pWin)
+ {
+ if (inputMasks && (inputMasks->inputEvents[mskidx] & filter))
+ {
+ FixUpEventFromWindow(xE, pWin, child, FALSE);
+ deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
+ grab, mskidx);
+ if (deliveries > 0)
+ return deliveries;
+ }
+ if ((deliveries < 0) ||
+ (pWin == stopAt) ||
+ (inputMasks &&
+ (filter & inputMasks->dontPropagateMask[mskidx])))
+ return 0;
+ child = pWin->drawable.id;
+ pWin = pWin->parent;
+ if (pWin)
+ inputMasks = wOtherInputMasks(pWin);
+ }
+ }
+ else
+ {
+ if (!(filter & pWin->deliverableEvents))
+ return 0;
+ while (pWin)
+ {
+ if ((wOtherEventMasks(pWin)|pWin->eventMask) & filter)
+ {
+ FixUpEventFromWindow(xE, pWin, child, FALSE);
+ deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
+ grab, 0);
+ if (deliveries > 0)
+ return deliveries;
+ }
+ if ((deliveries < 0) ||
+ (pWin == stopAt) ||
+ (filter & wDontPropagateMask(pWin)))
+ return 0;
+ child = pWin->drawable.id;
+ pWin = pWin->parent;
+ }
+ }
+ return 0;
+}
+
+/* not useful for events that propagate up the tree or extension events */
+int
+DeliverEvents(register WindowPtr pWin, register xEvent *xE, int count,
+ register WindowPtr otherParent)
+{
+ Mask filter;
+ int deliveries;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
+ return count;
+#endif
+
+ if (!count)
+ return 0;
+ filter = filters[xE->u.u.type];
+ if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify))
+ xE->u.destroyNotify.event = pWin->drawable.id;
+ if (filter != StructureAndSubMask)
+ return DeliverEventsToWindow(pWin, xE, count, filter, NullGrab, 0);
+ deliveries = DeliverEventsToWindow(pWin, xE, count, StructureNotifyMask,
+ NullGrab, 0);
+ if (pWin->parent)
+ {
+ xE->u.destroyNotify.event = pWin->parent->drawable.id;
+ deliveries += DeliverEventsToWindow(pWin->parent, xE, count,
+ SubstructureNotifyMask, NullGrab,
+ 0);
+ if (xE->u.u.type == ReparentNotify)
+ {
+ xE->u.destroyNotify.event = otherParent->drawable.id;
+ deliveries += DeliverEventsToWindow(otherParent, xE, count,
+ SubstructureNotifyMask,
+ NullGrab, 0);
+ }
+ }
+ return deliveries;
+}
+
+
+static Bool
+PointInBorderSize(WindowPtr pWin, int x, int y)
+{
+ BoxRec box;
+
+ if(POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderSize, x, y, &box))
+ return TRUE;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
+ int i;
+
+ for(i = 1; i < PanoramiXNumScreens; i++) {
+ if(POINT_IN_REGION(sprite.screen,
+ &sprite.windows[i]->borderSize,
+ x + panoramiXdataPtr[0].x - panoramiXdataPtr[i].x,
+ y + panoramiXdataPtr[0].y - panoramiXdataPtr[i].y,
+ &box))
+ return TRUE;
+ }
+ }
+#endif
+ return FALSE;
+}
+
+static WindowPtr
+XYToWindow(int x, int y)
+{
+ register WindowPtr pWin;
+ BoxRec box;
+
+ spriteTraceGood = 1; /* root window still there */
+ pWin = ROOT->firstChild;
+ while (pWin)
+ {
+ 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))
+#ifdef SHAPE
+ /* When a window is shaped, a further check
+ * is made to see if the point is inside
+ * borderSize
+ */
+ && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
+ && (!wInputShape(pWin) ||
+ POINT_IN_REGION(pWin->drawable.pScreen,
+ wInputShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box))
+#endif
+ )
+ {
+ if (spriteTraceGood >= spriteTraceSize)
+ {
+ spriteTraceSize += 10;
+ Must_have_memory = TRUE; /* XXX */
+ spriteTrace = (WindowPtr *)xrealloc(
+ spriteTrace, spriteTraceSize*sizeof(WindowPtr));
+ Must_have_memory = FALSE; /* XXX */
+ }
+ spriteTrace[spriteTraceGood++] = pWin;
+ pWin = pWin->firstChild;
+ }
+ else
+ pWin = pWin->nextSib;
+ }
+ return spriteTrace[spriteTraceGood-1];
+}
+
+static Bool
+CheckMotion(xEvent *xE)
+{
+ WindowPtr prevSpriteWin = sprite.win;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ return XineramaCheckMotion(xE);
+#endif
+
+ if (xE && !syncEvents.playingEvents)
+ {
+ if (sprite.hot.pScreen != sprite.hotPhys.pScreen)
+ {
+ sprite.hot.pScreen = sprite.hotPhys.pScreen;
+ ROOT = WindowTable[sprite.hot.pScreen->myNum];
+ }
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = XE_KBPTR.rootX;
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = XE_KBPTR.rootY;
+ if (sprite.hot.x < sprite.physLimits.x1)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = sprite.physLimits.x1;
+ else if (sprite.hot.x >= sprite.physLimits.x2)
+#ifdef XEVIE
+ xeviehot.x =
+#endif
+ sprite.hot.x = sprite.physLimits.x2 - 1;
+ if (sprite.hot.y < sprite.physLimits.y1)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = sprite.physLimits.y1;
+ else if (sprite.hot.y >= sprite.physLimits.y2)
+#ifdef XEVIE
+ xeviehot.y =
+#endif
+ sprite.hot.y = sprite.physLimits.y2 - 1;
+#ifdef SHAPE
+ if (sprite.hotShape)
+ ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
+#endif
+ sprite.hotPhys = sprite.hot;
+ if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
+ (sprite.hotPhys.y != XE_KBPTR.rootY))
+ {
+ (*sprite.hotPhys.pScreen->SetCursorPosition)(
+ sprite.hotPhys.pScreen,
+ sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
+ }
+ XE_KBPTR.rootX = sprite.hot.x;
+ XE_KBPTR.rootY = sprite.hot.y;
+ }
+
+#ifdef XEVIE
+ xeviewin =
+#endif
+ sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
+#ifdef notyet
+ if (!(sprite.win->deliverableEvents &
+ Motion_Filter(inputInfo.pointer->button))
+ !syncEvents.playingEvents)
+ {
+ /* XXX Do PointerNonInterestBox here */
+ }
+#endif
+ if (sprite.win != prevSpriteWin)
+ {
+ if (prevSpriteWin != NullWindow) {
+ if (!xE)
+ UpdateCurrentTimeIf();
+ DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
+ }
+ PostNewCursor();
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void
+WindowsRestructured()
+{
+ (void) CheckMotion((xEvent *)NULL);
+}
+
+#ifdef PANORAMIX
+/* This was added to support reconfiguration under Xdmx. The problem is
+ * that if the 0th screen (i.e., WindowTable[0]) is moved to an origin
+ * other than 0,0, the information in the private sprite structure must
+ * be updated accordingly, or XYToWindow (and other routines) will not
+ * compute correctly. */
+void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff)
+{
+ ScreenPtr pScreen = win->drawable.pScreen;
+ GrabPtr grab;
+
+ if (noPanoramiXExtension) return;
+
+ sprite.hot.x -= xoff;
+ sprite.hot.y -= yoff;
+
+ sprite.hotPhys.x -= xoff;
+ sprite.hotPhys.y -= yoff;
+
+ sprite.hotLimits.x1 -= xoff;
+ sprite.hotLimits.y1 -= yoff;
+ sprite.hotLimits.x2 -= xoff;
+ sprite.hotLimits.y2 -= yoff;
+
+ if (REGION_NOTEMPTY(sprite.screen, &sprite.Reg1))
+ REGION_TRANSLATE(sprite.screen, &sprite.Reg1, xoff, yoff);
+ if (REGION_NOTEMPTY(sprite.screen, &sprite.Reg2))
+ REGION_TRANSLATE(sprite.screen, &sprite.Reg2, xoff, yoff);
+
+ /* FIXME: if we call ConfineCursorToWindow, must we do anything else? */
+ if ((grab = inputInfo.pointer->grab) && grab->confineTo) {
+ if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+ sprite.hotPhys.x = sprite.hotPhys.y = 0;
+ ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+ } else
+ ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
+ TRUE, FALSE);
+}
+#endif
+
+void
+DefineInitialRootWindow(register WindowPtr win)
+{
+ register ScreenPtr pScreen = win->drawable.pScreen;
+
+ sprite.hotPhys.pScreen = pScreen;
+ sprite.hotPhys.x = pScreen->width / 2;
+ sprite.hotPhys.y = pScreen->height / 2;
+ sprite.hot = sprite.hotPhys;
+ sprite.hotLimits.x2 = pScreen->width;
+ sprite.hotLimits.y2 = pScreen->height;
+#ifdef XEVIE
+ xeviewin =
+#endif
+ sprite.win = win;
+ sprite.current = wCursor (win);
+ sprite.current->refcnt++;
+ spriteTraceGood = 1;
+ ROOT = win;
+ (*pScreen->CursorLimits) (
+ pScreen, sprite.current, &sprite.hotLimits, &sprite.physLimits);
+ sprite.confined = FALSE;
+ (*pScreen->ConstrainCursor) (pScreen, &sprite.physLimits);
+ (*pScreen->SetCursorPosition) (pScreen, sprite.hot.x, sprite.hot.y, FALSE);
+ (*pScreen->DisplayCursor) (pScreen, sprite.current);
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ sprite.hotLimits.x1 = -panoramiXdataPtr[0].x;
+ sprite.hotLimits.y1 = -panoramiXdataPtr[0].y;
+ sprite.hotLimits.x2 = PanoramiXPixWidth - panoramiXdataPtr[0].x;
+ sprite.hotLimits.y2 = PanoramiXPixHeight - panoramiXdataPtr[0].y;
+ sprite.physLimits = sprite.hotLimits;
+ sprite.confineWin = NullWindow;
+#ifdef SHAPE
+ sprite.hotShape = NullRegion;
+#endif
+ sprite.screen = pScreen;
+ /* gotta UNINIT these someplace */
+ REGION_NULL(pScreen, &sprite.Reg1);
+ REGION_NULL(pScreen, &sprite.Reg2);
+ }
+#endif
+}
+
+/*
+ * This does not take any shortcuts, and even ignores its argument, since
+ * it does not happen very often, and one has to walk up the tree since
+ * this might be a newly instantiated cursor for an intermediate window
+ * between the one the pointer is in and the one that the last cursor was
+ * instantiated from.
+ */
+void
+WindowHasNewCursor(WindowPtr pWin)
+{
+ PostNewCursor();
+}
+
+void
+NewCurrentScreen(ScreenPtr newScreen, int x, int y)
+{
+ sprite.hotPhys.x = x;
+ sprite.hotPhys.y = y;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ sprite.hotPhys.x += panoramiXdataPtr[newScreen->myNum].x -
+ panoramiXdataPtr[0].x;
+ sprite.hotPhys.y += panoramiXdataPtr[newScreen->myNum].y -
+ panoramiXdataPtr[0].y;
+ if (newScreen != sprite.screen) {
+ sprite.screen = newScreen;
+ /* Make sure we tell the DDX to update its copy of the screen */
+ if(sprite.confineWin)
+ XineramaConfineCursorToWindow(sprite.confineWin, TRUE);
+ else
+ XineramaConfineCursorToWindow(WindowTable[0], TRUE);
+ /* if the pointer wasn't confined, the DDX won't get
+ told of the pointer warp so we reposition it here */
+ if(!syncEvents.playingEvents)
+ (*sprite.screen->SetCursorPosition)(sprite.screen,
+ sprite.hotPhys.x + panoramiXdataPtr[0].x -
+ panoramiXdataPtr[sprite.screen->myNum].x,
+ sprite.hotPhys.y + panoramiXdataPtr[0].y -
+ panoramiXdataPtr[sprite.screen->myNum].y, FALSE);
+ }
+ } else
+#endif
+ if (newScreen != sprite.hotPhys.pScreen)
+ ConfineCursorToWindow(WindowTable[newScreen->myNum], TRUE, FALSE);
+}
+
+#ifdef PANORAMIX
+
+static Bool
+XineramaPointInWindowIsVisible(
+ WindowPtr pWin,
+ int x,
+ int y
+)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ BoxRec box;
+ int i, xoff, yoff;
+
+ if (!pWin->realized) return FALSE;
+
+ if (POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box))
+ return TRUE;
+
+ if(!XineramaSetWindowPntrs(pWin)) return FALSE;
+
+ xoff = x + panoramiXdataPtr[0].x;
+ yoff = y + panoramiXdataPtr[0].y;
+
+ for(i = 1; i < PanoramiXNumScreens; i++) {
+ pWin = sprite.windows[i];
+ pScreen = pWin->drawable.pScreen;
+ x = xoff - panoramiXdataPtr[i].x;
+ y = yoff - panoramiXdataPtr[i].y;
+
+ if(POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box)
+ && (!wInputShape(pWin) ||
+ POINT_IN_REGION(pWin->drawable.pScreen,
+ wInputShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box)))
+ return TRUE;
+
+ }
+
+ return FALSE;
+}
+
+static int
+XineramaWarpPointer(ClientPtr client)
+{
+ WindowPtr dest = NULL;
+ int x, y;
+
+ REQUEST(xWarpPointerReq);
+
+
+ if (stuff->dstWid != None)
+ {
+ dest = SecurityLookupWindow(stuff->dstWid, client, SecurityReadAccess);
+ if (!dest)
+ return BadWindow;
+ }
+ x = sprite.hotPhys.x;
+ y = sprite.hotPhys.y;
+
+ if (stuff->srcWid != None)
+ {
+ int winX, winY;
+ XID winID = stuff->srcWid;
+ WindowPtr source;
+
+ source = SecurityLookupWindow(winID, client, SecurityReadAccess);
+ if (!source) return BadWindow;
+
+ winX = source->drawable.x;
+ winY = source->drawable.y;
+ if(source == WindowTable[0]) {
+ winX -= panoramiXdataPtr[0].x;
+ winY -= panoramiXdataPtr[0].y;
+ }
+ if (x < winX + stuff->srcX ||
+ y < winY + stuff->srcY ||
+ (stuff->srcWidth != 0 &&
+ winX + stuff->srcX + (int)stuff->srcWidth < x) ||
+ (stuff->srcHeight != 0 &&
+ winY + stuff->srcY + (int)stuff->srcHeight < y) ||
+ !XineramaPointInWindowIsVisible(source, x, y))
+ return Success;
+ }
+ if (dest) {
+ x = dest->drawable.x;
+ y = dest->drawable.y;
+ if(dest == WindowTable[0]) {
+ x -= panoramiXdataPtr[0].x;
+ y -= panoramiXdataPtr[0].y;
+ }
+ }
+
+ x += stuff->dstX;
+ y += stuff->dstY;
+
+ if (x < sprite.physLimits.x1)
+ x = sprite.physLimits.x1;
+ else if (x >= sprite.physLimits.x2)
+ x = sprite.physLimits.x2 - 1;
+ if (y < sprite.physLimits.y1)
+ y = sprite.physLimits.y1;
+ else if (y >= sprite.physLimits.y2)
+ y = sprite.physLimits.y2 - 1;
+ if (sprite.hotShape)
+ ConfineToShape(sprite.hotShape, &x, &y);
+
+ XineramaSetCursorPosition(x, y, TRUE);
+
+ return Success;
+}
+
+#endif
+
+
+int
+ProcWarpPointer(ClientPtr client)
+{
+ WindowPtr dest = NULL;
+ int x, y;
+ ScreenPtr newScreen;
+
+ REQUEST(xWarpPointerReq);
+
+ REQUEST_SIZE_MATCH(xWarpPointerReq);
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ return XineramaWarpPointer(client);
+#endif
+
+ if (stuff->dstWid != None)
+ {
+ dest = SecurityLookupWindow(stuff->dstWid, client, SecurityReadAccess);
+ if (!dest)
+ return BadWindow;
+ }
+ x = sprite.hotPhys.x;
+ y = sprite.hotPhys.y;
+
+ if (stuff->srcWid != None)
+ {
+ int winX, winY;
+ XID winID = stuff->srcWid;
+ WindowPtr source;
+
+ source = SecurityLookupWindow(winID, client, SecurityReadAccess);
+ if (!source) return BadWindow;
+
+ winX = source->drawable.x;
+ winY = source->drawable.y;
+ if (source->drawable.pScreen != sprite.hotPhys.pScreen ||
+ x < winX + stuff->srcX ||
+ y < winY + stuff->srcY ||
+ (stuff->srcWidth != 0 &&
+ winX + stuff->srcX + (int)stuff->srcWidth < x) ||
+ (stuff->srcHeight != 0 &&
+ winY + stuff->srcY + (int)stuff->srcHeight < y) ||
+ !PointInWindowIsVisible(source, x, y))
+ return Success;
+ }
+ if (dest)
+ {
+ x = dest->drawable.x;
+ y = dest->drawable.y;
+ newScreen = dest->drawable.pScreen;
+ } else
+ newScreen = sprite.hotPhys.pScreen;
+
+ x += stuff->dstX;
+ y += stuff->dstY;
+
+ if (x < 0)
+ x = 0;
+ else if (x >= newScreen->width)
+ x = newScreen->width - 1;
+ if (y < 0)
+ y = 0;
+ else if (y >= newScreen->height)
+ y = newScreen->height - 1;
+
+ if (newScreen == sprite.hotPhys.pScreen)
+ {
+ if (x < sprite.physLimits.x1)
+ x = sprite.physLimits.x1;
+ else if (x >= sprite.physLimits.x2)
+ x = sprite.physLimits.x2 - 1;
+ if (y < sprite.physLimits.y1)
+ y = sprite.physLimits.y1;
+ else if (y >= sprite.physLimits.y2)
+ y = sprite.physLimits.y2 - 1;
+#if defined(SHAPE)
+ if (sprite.hotShape)
+ ConfineToShape(sprite.hotShape, &x, &y);
+#endif
+ (*newScreen->SetCursorPosition)(newScreen, x, y, TRUE);
+ }
+ else if (!PointerConfinedToScreen())
+ {
+ NewCurrentScreen(newScreen, x, y);
+ }
+ return Success;
+}
+
+static Bool
+BorderSizeNotEmpty(WindowPtr pWin)
+{
+ if(REGION_NOTEMPTY(sprite.hotPhys.pScreen, &pWin->borderSize))
+ return TRUE;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
+ int i;
+
+ for(i = 1; i < PanoramiXNumScreens; i++) {
+ if(REGION_NOTEMPTY(sprite.screen, &sprite.windows[i]->borderSize))
+ return TRUE;
+ }
+ }
+#endif
+ return FALSE;
+}
+
+/* "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a
+ passive grab set on the window to be activated. */
+
+static Bool
+CheckPassiveGrabsOnWindow(
+ WindowPtr pWin,
+ register DeviceIntPtr device,
+ register xEvent *xE,
+ int count)
+{
+ register GrabPtr grab = wPassiveGrabs(pWin);
+ GrabRec tempGrab;
+ register xEvent *dxE;
+
+ if (!grab)
+ return FALSE;
+ tempGrab.window = pWin;
+ tempGrab.device = device;
+ tempGrab.type = xE->u.u.type;
+ tempGrab.detail.exact = xE->u.u.detail;
+ tempGrab.detail.pMask = NULL;
+ tempGrab.modifiersDetail.pMask = NULL;
+ for (; grab; grab = grab->next)
+ {
+#ifdef XKB
+ DeviceIntPtr gdev;
+ XkbSrvInfoPtr xkbi;
+
+ gdev= grab->modifierDevice;
+ xkbi= gdev->key->xkbInfo;
+#endif
+ tempGrab.modifierDevice = grab->modifierDevice;
+ if ((device == grab->modifierDevice) &&
+ ((xE->u.u.type == KeyPress)
+#if defined(XINPUT) && defined(XKB)
+ || (xE->u.u.type == DeviceKeyPress)
+#endif
+ ))
+ tempGrab.modifiersDetail.exact =
+#ifdef XKB
+ (noXkbExtension?gdev->key->prev_state:xkbi->state.grab_mods);
+#else
+ grab->modifierDevice->key->prev_state;
+#endif
+ else
+ tempGrab.modifiersDetail.exact =
+#ifdef XKB
+ (noXkbExtension ? gdev->key->state : xkbi->state.grab_mods);
+#else
+ grab->modifierDevice->key->state;
+#endif
+ if (GrabMatchesSecond(&tempGrab, grab) &&
+ (!grab->confineTo ||
+ (grab->confineTo->realized &&
+ BorderSizeNotEmpty(grab->confineTo))))
+ {
+#ifdef XCSECURITY
+ if (!SecurityCheckDeviceAccess(wClient(pWin), device, FALSE))
+ return FALSE;
+#endif
+#ifdef XKB
+ if (!noXkbExtension) {
+ XE_KBPTR.state &= 0x1f00;
+ XE_KBPTR.state |=
+ tempGrab.modifiersDetail.exact&(~0x1f00);
+ }
+#endif
+ (*device->ActivateGrab)(device, grab, currentTime, TRUE);
+
+ FixUpEventFromWindow(xE, grab->window, None, TRUE);
+
+ (void) TryClientEvents(rClient(grab), xE, count,
+ filters[xE->u.u.type],
+ filters[xE->u.u.type], grab);
+
+ if (device->sync.state == FROZEN_NO_EVENT)
+ {
+ if (device->sync.evcount < count)
+ {
+ Must_have_memory = TRUE; /* XXX */
+ device->sync.event = (xEvent *)xrealloc(device->sync.event,
+ count*
+ sizeof(xEvent));
+ Must_have_memory = FALSE; /* XXX */
+ }
+ device->sync.evcount = count;
+ for (dxE = device->sync.event; --count >= 0; dxE++, xE++)
+ *dxE = *xE;
+ device->sync.state = FROZEN_WITH_EVENT;
+ }
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/**
+"CheckDeviceGrabs" handles both keyboard and pointer events that may cause
+a passive grab to be activated. If the event is a keyboard event, the
+ancestors of the focus window are traced down and tried to see if they have
+any passive grabs to be activated. If the focus window itself is reached and
+it's descendants contain they pointer, the ancestors of the window that the
+pointer is in are then traced down starting at the focus window, otherwise no
+grabs are activated. If the event is a pointer event, the ancestors of the
+window that the pointer is in are traced down starting at the root until
+CheckPassiveGrabs causes a passive grab to activate or all the windows are
+tried. PRH
+*/
+
+Bool
+CheckDeviceGrabs(register DeviceIntPtr device, register xEvent *xE,
+ int checkFirst, int count)
+{
+ register int i;
+ register WindowPtr pWin = NULL;
+ register FocusClassPtr focus = device->focus;
+
+ if (((xE->u.u.type == ButtonPress)
+#if defined(XINPUT) && defined(XKB)
+ || (xE->u.u.type == DeviceButtonPress)
+#endif
+ ) && (device->button->buttonsDown != 1))
+ return FALSE;
+
+ i = checkFirst;
+
+ if (focus)
+ {
+ for (; i < focus->traceGood; i++)
+ {
+ pWin = focus->trace[i];
+ if (pWin->optional &&
+ CheckPassiveGrabsOnWindow(pWin, device, xE, count))
+ return TRUE;
+ }
+
+ if ((focus->win == NoneWin) ||
+ (i >= spriteTraceGood) ||
+ ((i > checkFirst) && (pWin != spriteTrace[i-1])))
+ return FALSE;
+ }
+
+ for (; i < spriteTraceGood; i++)
+ {
+ pWin = spriteTrace[i];
+ if (pWin->optional &&
+ CheckPassiveGrabsOnWindow(pWin, device, xE, count))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void
+DeliverFocusedEvent(DeviceIntPtr keybd, xEvent *xE, WindowPtr window, int count)
+{
+ WindowPtr focus = keybd->focus->win;
+ int mskidx = 0;
+
+ if (focus == FollowKeyboardWin)
+ focus = inputInfo.keyboard->focus->win;
+ if (!focus)
+ return;
+ if (focus == PointerRootWin)
+ {
+ DeliverDeviceEvents(window, xE, NullGrab, NullWindow, keybd, count);
+ return;
+ }
+ if ((focus == window) || IsParent(focus, window))
+ {
+ if (DeliverDeviceEvents(window, xE, NullGrab, focus, keybd, count))
+ return;
+ }
+ /* just deliver it to the focus window */
+ FixUpEventFromWindow(xE, focus, None, FALSE);
+ if (xE->u.u.type & EXTENSION_EVENT_BASE)
+ mskidx = keybd->id;
+ (void)DeliverEventsToWindow(focus, xE, count, filters[xE->u.u.type],
+ NullGrab, mskidx);
+}
+
+void
+DeliverGrabbedEvent(register xEvent *xE, register DeviceIntPtr thisDev,
+ Bool deactivateGrab, int count)
+{
+ register GrabPtr grab = thisDev->grab;
+ int deliveries = 0;
+ register DeviceIntPtr dev;
+ register xEvent *dxE;
+
+ if (grab->ownerEvents)
+ {
+ WindowPtr focus;
+
+ if (thisDev->focus)
+ {
+ focus = thisDev->focus->win;
+ if (focus == FollowKeyboardWin)
+ focus = inputInfo.keyboard->focus->win;
+ }
+ else
+ focus = PointerRootWin;
+ if (focus == PointerRootWin)
+ deliveries = DeliverDeviceEvents(sprite.win, xE, grab, NullWindow,
+ thisDev, count);
+ else if (focus && (focus == sprite.win || IsParent(focus, sprite.win)))
+ deliveries = DeliverDeviceEvents(sprite.win, xE, grab, focus,
+ thisDev, count);
+ else if (focus)
+ deliveries = DeliverDeviceEvents(focus, xE, grab, focus,
+ thisDev, count);
+ }
+ if (!deliveries)
+ {
+ FixUpEventFromWindow(xE, grab->window, None, TRUE);
+ deliveries = TryClientEvents(rClient(grab), xE, count,
+ (Mask)grab->eventMask,
+ filters[xE->u.u.type], grab);
+ if (deliveries && (xE->u.u.type == MotionNotify
+#ifdef XINPUT
+ || xE->u.u.type == DeviceMotionNotify
+#endif
+ ))
+ thisDev->valuator->motionHintWindow = grab->window;
+ }
+ if (deliveries && !deactivateGrab && (xE->u.u.type != MotionNotify
+#ifdef XINPUT
+ && xE->u.u.type != DeviceMotionNotify
+#endif
+ ))
+ switch (thisDev->sync.state)
+ {
+ case FREEZE_BOTH_NEXT_EVENT:
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev == thisDev)
+ continue;
+ FreezeThaw(dev, TRUE);
+ if ((dev->sync.state == FREEZE_BOTH_NEXT_EVENT) &&
+ (CLIENT_BITS(dev->grab->resource) ==
+ CLIENT_BITS(thisDev->grab->resource)))
+ dev->sync.state = FROZEN_NO_EVENT;
+ else
+ dev->sync.other = thisDev->grab;
+ }
+ /* fall through */
+ case FREEZE_NEXT_EVENT:
+ thisDev->sync.state = FROZEN_WITH_EVENT;
+ FreezeThaw(thisDev, TRUE);
+ if (thisDev->sync.evcount < count)
+ {
+ Must_have_memory = TRUE; /* XXX */
+ thisDev->sync.event = (xEvent *)xrealloc(thisDev->sync.event,
+ count*sizeof(xEvent));
+ Must_have_memory = FALSE; /* XXX */
+ }
+ thisDev->sync.evcount = count;
+ for (dxE = thisDev->sync.event; --count >= 0; dxE++, xE++)
+ *dxE = *xE;
+ break;
+ }
+}
+
+void
+#ifdef XKB
+CoreProcessKeyboardEvent (register xEvent *xE, register DeviceIntPtr keybd, int count)
+#else
+ProcessKeyboardEvent (register xEvent *xE, register DeviceIntPtr keybd, int count)
+#endif
+{
+ int key, bit;
+ register BYTE *kptr;
+ register int i;
+ register CARD8 modifiers;
+ register CARD16 mask;
+ GrabPtr grab = keybd->grab;
+ Bool deactivateGrab = FALSE;
+ register KeyClassPtr keyc = keybd->key;
+#ifdef XEVIE
+ static Window rootWin = 0;
+
+ if(!xeviegrabState && xevieFlag && clients[xevieClientIndex] &&
+ (xevieMask & xevieFilters[xE->u.u.type])) {
+ key = xE->u.u.detail;
+ kptr = &keyc->down[key >> 3];
+ bit = 1 << (key & 7);
+ if((xE->u.u.type == KeyPress && (*kptr & bit)) ||
+ (xE->u.u.type == KeyRelease && !(*kptr & bit)))
+ {} else {
+#ifdef XKB
+ if(!noXkbExtension)
+ xevieKBEventSent = 1;
+#endif
+ if(!xevieKBEventSent)
+ {
+ xeviekb = keybd;
+ if(!rootWin) {
+ rootWin = GetCurrentRootWindow()->drawable.id;
+ }
+ xE->u.keyButtonPointer.event = xeviewin->drawable.id;
+ xE->u.keyButtonPointer.root = rootWin;
+ xE->u.keyButtonPointer.child = (xeviewin->firstChild) ? xeviewin->firstChild->
+drawable.id:0;
+ xE->u.keyButtonPointer.rootX = xeviehot.x;
+ xE->u.keyButtonPointer.rootY = xeviehot.y;
+ xE->u.keyButtonPointer.state = keyc->state;
+ WriteToClient(clients[xevieClientIndex], sizeof(xEvent), (char *)xE);
+#ifdef XKB
+ if(noXkbExtension)
+#endif
+ return;
+ } else {
+ xevieKBEventSent = 0;
+ }
+ }
+ }
+#endif
+
+ if (!syncEvents.playingEvents)
+ {
+ NoticeTime(xE);
+ if (DeviceEventCallback)
+ {
+ DeviceEventInfoRec eventinfo;
+ eventinfo.events = xE;
+ eventinfo.count = count;
+ CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+ }
+ }
+#ifdef XEVIE
+ /* fix for bug5094030: don't change the state bit if the event is from XEvIE client */
+ if(!(!xeviegrabState && xevieFlag && clients[xevieClientIndex] &&
+ (xevieMask & xevieFilters[xE->u.u.type]
+#ifdef XKB
+ && !noXkbExtension
+#endif
+ )))
+#endif
+ XE_KBPTR.state = (keyc->state | inputInfo.pointer->button->state);
+ XE_KBPTR.rootX = sprite.hot.x;
+ XE_KBPTR.rootY = sprite.hot.y;
+ key = xE->u.u.detail;
+ kptr = &keyc->down[key >> 3];
+ bit = 1 << (key & 7);
+ modifiers = keyc->modifierMap[key];
+#if defined(XKB) && defined(XEVIE)
+ if(!noXkbExtension && !xeviegrabState &&
+ xevieFlag && clients[xevieClientIndex] &&
+ (xevieMask & xevieFilters[xE->u.u.type])) {
+ switch(xE->u.u.type) {
+ case KeyPress: *kptr &= ~bit; break;
+ case KeyRelease: *kptr |= bit; break;
+ }
+ }
+#endif
+
+#ifdef DEBUG
+ if ((xkbDebugFlags&0x4)&&
+ ((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))) {
+ ErrorF("CoreProcessKbdEvent: Key %d %s\n",key,
+ (xE->u.u.type==KeyPress?"down":"up"));
+ }
+#endif
+ switch (xE->u.u.type)
+ {
+ case KeyPress:
+ if (*kptr & bit) /* allow ddx to generate multiple downs */
+ {
+ if (!modifiers)
+ {
+ xE->u.u.type = KeyRelease;
+ (*keybd->public.processInputProc)(xE, keybd, count);
+ xE->u.u.type = KeyPress;
+ /* release can have side effects, don't fall through */
+ (*keybd->public.processInputProc)(xE, keybd, count);
+ }
+ return;
+ }
+ inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+ *kptr |= bit;
+ keyc->prev_state = keyc->state;
+ for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
+ {
+ if (mask & modifiers)
+ {
+ /* This key affects modifier "i" */
+ keyc->modifierKeyCount[i]++;
+ keyc->state |= mask;
+ modifiers &= ~mask;
+ }
+ }
+ if (!grab && CheckDeviceGrabs(keybd, xE, 0, count))
+ {
+ keybd->activatingKey = key;
+ return;
+ }
+ break;
+ case KeyRelease:
+ if (!(*kptr & bit)) /* guard against duplicates */
+ return;
+ inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+ *kptr &= ~bit;
+ keyc->prev_state = keyc->state;
+ for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
+ {
+ if (mask & modifiers) {
+ /* This key affects modifier "i" */
+ if (--keyc->modifierKeyCount[i] <= 0) {
+ keyc->state &= ~mask;
+ keyc->modifierKeyCount[i] = 0;
+ }
+ modifiers &= ~mask;
+ }
+ }
+ if (keybd->fromPassiveGrab && (key == keybd->activatingKey))
+ deactivateGrab = TRUE;
+ break;
+ default:
+ FatalError("Impossible keyboard event");
+ }
+ if (grab)
+ DeliverGrabbedEvent(xE, keybd, deactivateGrab, count);
+ else
+ DeliverFocusedEvent(keybd, xE, sprite.win, count);
+ if (deactivateGrab)
+ (*keybd->DeactivateGrab)(keybd);
+}
+
+#ifdef XKB
+/* This function is used to set the key pressed or key released state -
+ this is only used when the pressing of keys does not cause
+ CoreProcessKeyEvent to be called, as in for example Mouse Keys.
+*/
+void
+FixKeyState (register xEvent *xE, register DeviceIntPtr keybd)
+{
+ int key, bit;
+ register BYTE *kptr;
+ register KeyClassPtr keyc = keybd->key;
+
+ key = xE->u.u.detail;
+ kptr = &keyc->down[key >> 3];
+ bit = 1 << (key & 7);
+#ifdef DEBUG
+ if ((xkbDebugFlags&0x4)&&
+ ((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))) {
+ ErrorF("FixKeyState: Key %d %s\n",key,
+ (xE->u.u.type==KeyPress?"down":"up"));
+ }
+#endif
+ switch (xE->u.u.type)
+ {
+ case KeyPress:
+ *kptr |= bit;
+ break;
+ case KeyRelease:
+ *kptr &= ~bit;
+ break;
+ default:
+ FatalError("Impossible keyboard event");
+ }
+}
+#endif
+
+void
+#ifdef XKB
+CoreProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count)
+#else
+ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count)
+#endif
+{
+ register GrabPtr grab = mouse->grab;
+ Bool deactivateGrab = FALSE;
+ register ButtonClassPtr butc = mouse->button;
+#ifdef XKB
+ XkbSrvInfoPtr xkbi= inputInfo.keyboard->key->xkbInfo;
+#endif
+#ifdef XEVIE
+ if(xevieFlag && clients[xevieClientIndex] && !xeviegrabState &&
+ (xevieMask & xevieFilters[xE->u.u.type])) {
+ if(xevieEventSent)
+ xevieEventSent = 0;
+ else {
+ xeviemouse = mouse;
+ WriteToClient(clients[xevieClientIndex], sizeof(xEvent), (char *)xE);
+ return;
+ }
+ }
+#endif
+
+ if (!syncEvents.playingEvents)
+ NoticeTime(xE)
+ XE_KBPTR.state = (butc->state | (
+#ifdef XKB
+ (noXkbExtension ?
+ inputInfo.keyboard->key->state :
+ xkbi->state.grab_mods)
+#else
+ inputInfo.keyboard->key->state
+#endif
+ ));
+ {
+ NoticeTime(xE);
+ if (DeviceEventCallback)
+ {
+ DeviceEventInfoRec eventinfo;
+ /* see comment in EnqueueEvents regarding the next three lines */
+ if (xE->u.u.type == MotionNotify)
+ XE_KBPTR.root =
+ WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
+ eventinfo.events = xE;
+ eventinfo.count = count;
+ CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+ }
+ }
+ if (xE->u.u.type != MotionNotify)
+ {
+ register int key;
+ register BYTE *kptr;
+ int bit;
+
+ XE_KBPTR.rootX = sprite.hot.x;
+ XE_KBPTR.rootY = sprite.hot.y;
+
+ key = xE->u.u.detail;
+ kptr = &butc->down[key >> 3];
+ bit = 1 << (key & 7);
+ switch (xE->u.u.type)
+ {
+ case ButtonPress:
+ mouse->valuator->motionHintWindow = NullWindow;
+ if (!(*kptr & bit))
+ butc->buttonsDown++;
+ butc->motionMask = ButtonMotionMask;
+ *kptr |= bit;
+#if !defined(XFree86Server) || !defined(XINPUT)
+ xE->u.u.detail = butc->map[key];
+#endif
+ if (xE->u.u.detail == 0)
+ return;
+ if (xE->u.u.detail <= 5)
+ butc->state |= (Button1Mask >> 1) << xE->u.u.detail;
+ filters[MotionNotify] = Motion_Filter(butc);
+ if (!grab)
+ if (CheckDeviceGrabs(mouse, xE, 0, count))
+ return;
+ break;
+ case ButtonRelease:
+ mouse->valuator->motionHintWindow = NullWindow;
+ if (*kptr & bit)
+ --butc->buttonsDown;
+ if (!butc->buttonsDown)
+ butc->motionMask = 0;
+ *kptr &= ~bit;
+#if !defined(XFree86Server) || !defined(XINPUT)
+ xE->u.u.detail = butc->map[key];
+#endif
+ if (xE->u.u.detail == 0)
+ return;
+ if (xE->u.u.detail <= 5)
+ butc->state &= ~((Button1Mask >> 1) << xE->u.u.detail);
+ filters[MotionNotify] = Motion_Filter(butc);
+ if (!butc->state && mouse->fromPassiveGrab)
+ deactivateGrab = TRUE;
+ break;
+ default:
+ FatalError("bogus pointer event from ddx");
+ }
+ }
+ else if (!CheckMotion(xE))
+ return;
+ if (grab)
+ DeliverGrabbedEvent(xE, mouse, deactivateGrab, count);
+ else
+ DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
+ mouse, count);
+ if (deactivateGrab)
+ (*mouse->DeactivateGrab)(mouse);
+}
+
+#define AtMostOneClient \
+ (SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask)
+
+void
+RecalculateDeliverableEvents(pWin)
+ register WindowPtr pWin;
+{
+ register OtherClients *others;
+ register WindowPtr pChild;
+
+ pChild = pWin;
+ while (1)
+ {
+ if (pChild->optional)
+ {
+ pChild->optional->otherEventMasks = 0;
+ for (others = wOtherClients(pChild); others; others = others->next)
+ {
+ pChild->optional->otherEventMasks |= others->mask;
+ }
+ }
+ pChild->deliverableEvents = pChild->eventMask|
+ wOtherEventMasks(pChild);
+ if (pChild->parent)
+ pChild->deliverableEvents |=
+ (pChild->parent->deliverableEvents &
+ ~wDontPropagateMask(pChild) & PropagateMask);
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ break;
+ pChild = pChild->nextSib;
+ }
+}
+
+/**
+ *
+ * \param value must conform to DeleteType
+ */
+int
+OtherClientGone(pointer value, XID id)
+{
+ register OtherClientsPtr other, prev;
+ register WindowPtr pWin = (WindowPtr)value;
+
+ prev = 0;
+ for (other = wOtherClients(pWin); other; other = other->next)
+ {
+ if (other->resource == id)
+ {
+ if (prev)
+ prev->next = other->next;
+ else
+ {
+ if (!(pWin->optional->otherClients = other->next))
+ CheckWindowOptionalNeed (pWin);
+ }
+ xfree(other);
+ RecalculateDeliverableEvents(pWin);
+ return(Success);
+ }
+ prev = other;
+ }
+ FatalError("client not on event list");
+ /*NOTREACHED*/
+ return -1; /* make compiler happy */
+}
+
+int
+EventSelectForWindow(register WindowPtr pWin, register ClientPtr client, Mask mask)
+{
+ Mask check;
+ OtherClients * others;
+
+ if (mask & ~AllEventMasks)
+ {
+ client->errorValue = mask;
+ return BadValue;
+ }
+ check = (mask & AtMostOneClient);
+ if (check & (pWin->eventMask|wOtherEventMasks(pWin)))
+ { /* It is illegal for two different
+ clients to select on any of the
+ events for AtMostOneClient. However,
+ it is OK, for some client to
+ continue selecting on one of those
+ events. */
+ if ((wClient(pWin) != client) && (check & pWin->eventMask))
+ return BadAccess;
+ for (others = wOtherClients (pWin); others; others = others->next)
+ {
+ if (!SameClient(others, client) && (check & others->mask))
+ return BadAccess;
+ }
+ }
+ if (wClient (pWin) == client)
+ {
+ check = pWin->eventMask;
+#ifdef SGIMISC
+ pWin->eventMask =
+ (mask & ~SGIMiscSpecialDestroyMask) | (pWin->eventMask & SGIMiscSpecialDestroyMask);
+#else
+ pWin->eventMask = mask;
+#endif
+ }
+ else
+ {
+ for (others = wOtherClients (pWin); others; others = others->next)
+ {
+ if (SameClient(others, client))
+ {
+ check = others->mask;
+#ifdef SGIMISC
+ mask = (mask & ~SGIMiscSpecialDestroyMask) | (others->mask & SGIMiscSpecialDestroyMask);
+#endif
+ if (mask == 0)
+ {
+ FreeResource(others->resource, RT_NONE);
+ return Success;
+ }
+ else
+ others->mask = mask;
+ goto maskSet;
+ }
+ }
+ check = 0;
+ if (!pWin->optional && !MakeWindowOptional (pWin))
+ return BadAlloc;
+ others = (OtherClients *) xalloc(sizeof(OtherClients));
+ if (!others)
+ return BadAlloc;
+ others->mask = mask;
+ others->resource = FakeClientID(client->index);
+ others->next = pWin->optional->otherClients;
+ pWin->optional->otherClients = others;
+ if (!AddResource(others->resource, RT_OTHERCLIENT, (pointer)pWin))
+ return BadAlloc;
+ }
+maskSet:
+ if ((inputInfo.pointer->valuator->motionHintWindow == pWin) &&
+ (mask & PointerMotionHintMask) &&
+ !(check & PointerMotionHintMask) &&
+ !inputInfo.pointer->grab)
+ inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+ RecalculateDeliverableEvents(pWin);
+ return Success;
+}
+
+int
+EventSuppressForWindow(register WindowPtr pWin, register ClientPtr client,
+ Mask mask, Bool *checkOptional)
+{
+ register int i, free;
+
+ if ((mask & ~PropagateMask) && !permitOldBugs)
+ {
+ client->errorValue = mask;
+ return BadValue;
+ }
+ if (pWin->dontPropagate)
+ DontPropagateRefCnts[pWin->dontPropagate]--;
+ if (!mask)
+ i = 0;
+ else
+ {
+ for (i = DNPMCOUNT, free = 0; --i > 0; )
+ {
+ if (!DontPropagateRefCnts[i])
+ free = i;
+ else if (mask == DontPropagateMasks[i])
+ break;
+ }
+ if (!i && free)
+ {
+ i = free;
+ DontPropagateMasks[i] = mask;
+ }
+ }
+ if (i || !mask)
+ {
+ pWin->dontPropagate = i;
+ if (i)
+ DontPropagateRefCnts[i]++;
+ if (pWin->optional)
+ {
+ pWin->optional->dontPropagateMask = mask;
+ *checkOptional = TRUE;
+ }
+ }
+ else
+ {
+ if (!pWin->optional && !MakeWindowOptional (pWin))
+ {
+ if (pWin->dontPropagate)
+ DontPropagateRefCnts[pWin->dontPropagate]++;
+ return BadAlloc;
+ }
+ pWin->dontPropagate = 0;
+ pWin->optional->dontPropagateMask = mask;
+ }
+ RecalculateDeliverableEvents(pWin);
+ return Success;
+}
+
+static WindowPtr
+CommonAncestor(
+ register WindowPtr a,
+ register WindowPtr b)
+{
+ for (b = b->parent; b; b = b->parent)
+ if (IsParent(b, a)) return b;
+ return NullWindow;
+}
+
+static void
+EnterLeaveEvent(
+ int type,
+ int mode,
+ int detail,
+ register WindowPtr pWin,
+ Window child)
+{
+ xEvent event;
+ register DeviceIntPtr keybd = inputInfo.keyboard;
+ WindowPtr focus;
+ register DeviceIntPtr mouse = inputInfo.pointer;
+ register GrabPtr grab = mouse->grab;
+ Mask mask;
+
+ if ((pWin == mouse->valuator->motionHintWindow) &&
+ (detail != NotifyInferior))
+ mouse->valuator->motionHintWindow = NullWindow;
+ if (grab)
+ {
+ mask = (pWin == grab->window) ? grab->eventMask : 0;
+ if (grab->ownerEvents)
+ mask |= EventMaskForClient(pWin, rClient(grab));
+ }
+ else
+ {
+ mask = pWin->eventMask | wOtherEventMasks(pWin);
+ }
+ if (mask & filters[type])
+ {
+ event.u.u.type = type;
+ event.u.u.detail = detail;
+ event.u.enterLeave.time = currentTime.milliseconds;
+ event.u.enterLeave.rootX = sprite.hot.x;
+ event.u.enterLeave.rootY = sprite.hot.y;
+ /* Counts on the same initial structure of crossing & button events! */
+ FixUpEventFromWindow(&event, pWin, None, FALSE);
+ /* Enter/Leave events always set child */
+ event.u.enterLeave.child = child;
+ event.u.enterLeave.flags = event.u.keyButtonPointer.sameScreen ?
+ ELFlagSameScreen : 0;
+#ifdef XKB
+ if (!noXkbExtension) {
+ event.u.enterLeave.state = mouse->button->state & 0x1f00;
+ event.u.enterLeave.state |=
+ XkbGrabStateFromRec(&keybd->key->xkbInfo->state);
+ } else
+#endif
+ event.u.enterLeave.state = keybd->key->state | mouse->button->state;
+ event.u.enterLeave.mode = mode;
+ focus = keybd->focus->win;
+ if ((focus != NoneWin) &&
+ ((pWin == focus) || (focus == PointerRootWin) ||
+ IsParent(focus, pWin)))
+ event.u.enterLeave.flags |= ELFlagFocus;
+ if (grab)
+ (void)TryClientEvents(rClient(grab), &event, 1, mask,
+ filters[type], grab);
+ else
+ (void)DeliverEventsToWindow(pWin, &event, 1, filters[type],
+ NullGrab, 0);
+ }
+ if ((type == EnterNotify) && (mask & KeymapStateMask))
+ {
+ xKeymapEvent ke;
+
+#ifdef XCSECURITY
+ ClientPtr client = grab ? rClient(grab)
+ : clients[CLIENT_ID(pWin->drawable.id)];
+ if (!SecurityCheckDeviceAccess(client, keybd, FALSE))
+ {
+ bzero((char *)&ke.map[0], 31);
+ }
+ else
+#endif
+ memmove((char *)&ke.map[0], (char *)&keybd->key->down[1], 31);
+ ke.type = KeymapNotify;
+ if (grab)
+ (void)TryClientEvents(rClient(grab), (xEvent *)&ke, 1, mask,
+ KeymapStateMask, grab);
+ else
+ (void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
+ KeymapStateMask, NullGrab, 0);
+ }
+}
+
+static void
+EnterNotifies(WindowPtr ancestor, WindowPtr child, int mode, int detail)
+{
+ WindowPtr parent = child->parent;
+
+ if (ancestor == parent)
+ return;
+ EnterNotifies(ancestor, parent, mode, detail);
+ EnterLeaveEvent(EnterNotify, mode, detail, parent, child->drawable.id);
+}
+
+static void
+LeaveNotifies(WindowPtr child, WindowPtr ancestor, int mode, int detail)
+{
+ register WindowPtr pWin;
+
+ if (ancestor == child)
+ return;
+ for (pWin = child->parent; pWin != ancestor; pWin = pWin->parent)
+ {
+ EnterLeaveEvent(LeaveNotify, mode, detail, pWin, child->drawable.id);
+ child = pWin;
+ }
+}
+
+static void
+DoEnterLeaveEvents(WindowPtr fromWin, WindowPtr toWin, int mode)
+{
+ if (fromWin == toWin)
+ return;
+ if (IsParent(fromWin, toWin))
+ {
+ EnterLeaveEvent(LeaveNotify, mode, NotifyInferior, fromWin, None);
+ EnterNotifies(fromWin, toWin, mode, NotifyVirtual);
+ EnterLeaveEvent(EnterNotify, mode, NotifyAncestor, toWin, None);
+ }
+ else if (IsParent(toWin, fromWin))
+ {
+ EnterLeaveEvent(LeaveNotify, mode, NotifyAncestor, fromWin, None);
+ LeaveNotifies(fromWin, toWin, mode, NotifyVirtual);
+ EnterLeaveEvent(EnterNotify, mode, NotifyInferior, toWin, None);
+ }
+ else
+ { /* neither fromWin nor toWin is descendent of the other */
+ WindowPtr common = CommonAncestor(toWin, fromWin);
+ /* common == NullWindow ==> different screens */
+ EnterLeaveEvent(LeaveNotify, mode, NotifyNonlinear, fromWin, None);
+ LeaveNotifies(fromWin, common, mode, NotifyNonlinearVirtual);
+ EnterNotifies(common, toWin, mode, NotifyNonlinearVirtual);
+ EnterLeaveEvent(EnterNotify, mode, NotifyNonlinear, toWin, None);
+ }
+}
+
+static void
+FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, register WindowPtr pWin)
+{
+ xEvent event;
+
+#ifdef XINPUT
+ if (dev != inputInfo.keyboard)
+ {
+ DeviceFocusEvent(dev, type, mode, detail, pWin);
+ return;
+ }
+#endif
+ event.u.focus.mode = mode;
+ event.u.u.type = type;
+ event.u.u.detail = detail;
+ event.u.focus.window = pWin->drawable.id;
+ (void)DeliverEventsToWindow(pWin, &event, 1, filters[type], NullGrab,
+ 0);
+ if ((type == FocusIn) &&
+ ((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask))
+ {
+ xKeymapEvent ke;
+#ifdef XCSECURITY
+ ClientPtr client = clients[CLIENT_ID(pWin->drawable.id)];
+ if (!SecurityCheckDeviceAccess(client, dev, FALSE))
+ {
+ bzero((char *)&ke.map[0], 31);
+ }
+ else
+#endif
+ memmove((char *)&ke.map[0], (char *)&dev->key->down[1], 31);
+ ke.type = KeymapNotify;
+ (void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
+ KeymapStateMask, NullGrab, 0);
+ }
+}
+
+ /*
+ * recursive because it is easier
+ * no-op if child not descended from ancestor
+ */
+static Bool
+FocusInEvents(
+ DeviceIntPtr dev,
+ WindowPtr ancestor, WindowPtr child, WindowPtr skipChild,
+ int mode, int detail,
+ Bool doAncestor)
+{
+ if (child == NullWindow)
+ return ancestor == NullWindow;
+ if (ancestor == child)
+ {
+ if (doAncestor)
+ FocusEvent(dev, FocusIn, mode, detail, child);
+ return TRUE;
+ }
+ if (FocusInEvents(dev, ancestor, child->parent, skipChild, mode, detail,
+ doAncestor))
+ {
+ if (child != skipChild)
+ FocusEvent(dev, FocusIn, mode, detail, child);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* dies horribly if ancestor is not an ancestor of child */
+static void
+FocusOutEvents(
+ DeviceIntPtr dev,
+ WindowPtr child, WindowPtr ancestor,
+ int mode, int detail,
+ Bool doAncestor)
+{
+ register WindowPtr pWin;
+
+ for (pWin = child; pWin != ancestor; pWin = pWin->parent)
+ FocusEvent(dev, FocusOut, mode, detail, pWin);
+ if (doAncestor)
+ FocusEvent(dev, FocusOut, mode, detail, ancestor);
+}
+
+void
+DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode)
+{
+ int out, in; /* for holding details for to/from
+ PointerRoot/None */
+ int i;
+
+ if (fromWin == toWin)
+ return;
+ out = (fromWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
+ in = (toWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
+ /* wrong values if neither, but then not referenced */
+
+ if ((toWin == NullWindow) || (toWin == PointerRootWin))
+ {
+ if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
+ {
+ if (fromWin == PointerRootWin)
+ FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
+ TRUE);
+ /* Notify all the roots */
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
+ else
+#endif
+ for (i=0; i<screenInfo.numScreens; i++)
+ FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
+ }
+ else
+ {
+ if (IsParent(fromWin, sprite.win))
+ FocusOutEvents(dev, sprite.win, fromWin, mode, NotifyPointer,
+ FALSE);
+ FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
+ /* next call catches the root too, if the screen changed */
+ FocusOutEvents(dev, fromWin->parent, NullWindow, mode,
+ NotifyNonlinearVirtual, FALSE);
+ }
+ /* Notify all the roots */
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ FocusEvent(dev, FocusIn, mode, in, WindowTable[0]);
+ else
+#endif
+ for (i=0; i<screenInfo.numScreens; i++)
+ FocusEvent(dev, FocusIn, mode, in, WindowTable[i]);
+ if (toWin == PointerRootWin)
+ (void)FocusInEvents(dev, ROOT, sprite.win, NullWindow, mode,
+ NotifyPointer, TRUE);
+ }
+ else
+ {
+ if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
+ {
+ if (fromWin == PointerRootWin)
+ FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
+ TRUE);
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
+ else
+#endif
+ for (i=0; i<screenInfo.numScreens; i++)
+ FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
+ if (toWin->parent != NullWindow)
+ (void)FocusInEvents(dev, ROOT, toWin, toWin, mode,
+ NotifyNonlinearVirtual, TRUE);
+ FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
+ if (IsParent(toWin, sprite.win))
+ (void)FocusInEvents(dev, toWin, sprite.win, NullWindow, mode,
+ NotifyPointer, FALSE);
+ }
+ else
+ {
+ if (IsParent(toWin, fromWin))
+ {
+ FocusEvent(dev, FocusOut, mode, NotifyAncestor, fromWin);
+ FocusOutEvents(dev, fromWin->parent, toWin, mode,
+ NotifyVirtual, FALSE);
+ FocusEvent(dev, FocusIn, mode, NotifyInferior, toWin);
+ if ((IsParent(toWin, sprite.win)) &&
+ (sprite.win != fromWin) &&
+ (!IsParent(fromWin, sprite.win)) &&
+ (!IsParent(sprite.win, fromWin)))
+ (void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
+ mode, NotifyPointer, FALSE);
+ }
+ else
+ if (IsParent(fromWin, toWin))
+ {
+ if ((IsParent(fromWin, sprite.win)) &&
+ (sprite.win != fromWin) &&
+ (!IsParent(toWin, sprite.win)) &&
+ (!IsParent(sprite.win, toWin)))
+ FocusOutEvents(dev, sprite.win, fromWin, mode,
+ NotifyPointer, FALSE);
+ FocusEvent(dev, FocusOut, mode, NotifyInferior, fromWin);
+ (void)FocusInEvents(dev, fromWin, toWin, toWin, mode,
+ NotifyVirtual, FALSE);
+ FocusEvent(dev, FocusIn, mode, NotifyAncestor, toWin);
+ }
+ else
+ {
+ /* neither fromWin or toWin is child of other */
+ WindowPtr common = CommonAncestor(toWin, fromWin);
+ /* common == NullWindow ==> different screens */
+ if (IsParent(fromWin, sprite.win))
+ FocusOutEvents(dev, sprite.win, fromWin, mode,
+ NotifyPointer, FALSE);
+ FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
+ if (fromWin->parent != NullWindow)
+ FocusOutEvents(dev, fromWin->parent, common, mode,
+ NotifyNonlinearVirtual, FALSE);
+ if (toWin->parent != NullWindow)
+ (void)FocusInEvents(dev, common, toWin, toWin, mode,
+ NotifyNonlinearVirtual, FALSE);
+ FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
+ if (IsParent(toWin, sprite.win))
+ (void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
+ mode, NotifyPointer, FALSE);
+ }
+ }
+ }
+}
+
+int
+SetInputFocus(
+ ClientPtr client,
+ DeviceIntPtr dev,
+ Window focusID,
+ CARD8 revertTo,
+ Time ctime,
+ Bool followOK)
+{
+ register FocusClassPtr focus;
+ register WindowPtr focusWin;
+ int mode;
+ TimeStamp time;
+
+ UpdateCurrentTime();
+ if ((revertTo != RevertToParent) &&
+ (revertTo != RevertToPointerRoot) &&
+ (revertTo != RevertToNone) &&
+ ((revertTo != RevertToFollowKeyboard) || !followOK))
+ {
+ client->errorValue = revertTo;
+ return BadValue;
+ }
+ time = ClientTimeToServerTime(ctime);
+ if ((focusID == None) || (focusID == PointerRoot))
+ focusWin = (WindowPtr)(long)focusID;
+ else if ((focusID == FollowKeyboard) && followOK)
+ focusWin = inputInfo.keyboard->focus->win;
+ else if (!(focusWin = SecurityLookupWindow(focusID, client,
+ SecurityReadAccess)))
+ return BadWindow;
+ else
+ {
+ /* It is a match error to try to set the input focus to an
+ unviewable window. */
+
+ if(!focusWin->realized)
+ return(BadMatch);
+ }
+ focus = dev->focus;
+ if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, focus->time) == EARLIER))
+ return Success;
+ mode = (dev->grab) ? NotifyWhileGrabbed : NotifyNormal;
+ if (focus->win == FollowKeyboardWin)
+ DoFocusEvents(dev, inputInfo.keyboard->focus->win, focusWin, mode);
+ else
+ DoFocusEvents(dev, focus->win, focusWin, mode);
+ focus->time = time;
+ focus->revert = revertTo;
+ if (focusID == FollowKeyboard)
+ focus->win = FollowKeyboardWin;
+ else
+ focus->win = focusWin;
+ if ((focusWin == NoneWin) || (focusWin == PointerRootWin))
+ focus->traceGood = 0;
+ else
+ {
+ int depth = 0;
+ register WindowPtr pWin;
+
+ for (pWin = focusWin; pWin; pWin = pWin->parent) depth++;
+ if (depth > focus->traceSize)
+ {
+ focus->traceSize = depth+1;
+ Must_have_memory = TRUE; /* XXX */
+ focus->trace = (WindowPtr *)xrealloc(focus->trace,
+ focus->traceSize *
+ sizeof(WindowPtr));
+ Must_have_memory = FALSE; /* XXX */
+ }
+ focus->traceGood = depth;
+ for (pWin = focusWin, depth--; pWin; pWin = pWin->parent, depth--)
+ focus->trace[depth] = pWin;
+ }
+ return Success;
+}
+
+int
+ProcSetInputFocus(client)
+ ClientPtr client;
+{
+ REQUEST(xSetInputFocusReq);
+
+ REQUEST_SIZE_MATCH(xSetInputFocusReq);
+#ifdef XCSECURITY
+ if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
+ return Success;
+#endif
+ return SetInputFocus(client, inputInfo.keyboard, stuff->focus,
+ stuff->revertTo, stuff->time, FALSE);
+}
+
+int
+ProcGetInputFocus(ClientPtr client)
+{
+ xGetInputFocusReply rep;
+ /* REQUEST(xReq); */
+ FocusClassPtr focus = inputInfo.keyboard->focus;
+
+ REQUEST_SIZE_MATCH(xReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ if (focus->win == NoneWin)
+ rep.focus = None;
+ else if (focus->win == PointerRootWin)
+ rep.focus = PointerRoot;
+ else rep.focus = focus->win->drawable.id;
+ rep.revertTo = focus->revert;
+ WriteReplyToClient(client, sizeof(xGetInputFocusReply), &rep);
+ return Success;
+}
+
+int
+ProcGrabPointer(ClientPtr client)
+{
+ xGrabPointerReply rep;
+ DeviceIntPtr device = inputInfo.pointer;
+ GrabPtr grab;
+ WindowPtr pWin, confineTo;
+ CursorPtr cursor, oldCursor;
+ REQUEST(xGrabPointerReq);
+ TimeStamp time;
+
+ REQUEST_SIZE_MATCH(xGrabPointerReq);
+ UpdateCurrentTime();
+ if ((stuff->pointerMode != GrabModeSync) &&
+ (stuff->pointerMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->pointerMode;
+ return BadValue;
+ }
+ if ((stuff->keyboardMode != GrabModeSync) &&
+ (stuff->keyboardMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->keyboardMode;
+ return BadValue;
+ }
+ if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
+ {
+ client->errorValue = stuff->ownerEvents;
+ return BadValue;
+ }
+ if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
+ {
+ client->errorValue = stuff->eventMask;
+ return BadValue;
+ }
+ pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+ if (stuff->confineTo == None)
+ confineTo = NullWindow;
+ else
+ {
+ confineTo = SecurityLookupWindow(stuff->confineTo, client,
+ SecurityReadAccess);
+ if (!confineTo)
+ return BadWindow;
+ }
+ if (stuff->cursor == None)
+ cursor = NullCursor;
+ else
+ {
+ cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+ RT_CURSOR, SecurityReadAccess);
+ if (!cursor)
+ {
+ client->errorValue = stuff->cursor;
+ return BadCursor;
+ }
+ }
+ /* at this point, some sort of reply is guaranteed. */
+ time = ClientTimeToServerTime(stuff->time);
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ grab = device->grab;
+ if ((grab) && !SameClient(grab, client))
+ rep.status = AlreadyGrabbed;
+ else if ((!pWin->realized) ||
+ (confineTo &&
+ !(confineTo->realized && BorderSizeNotEmpty(confineTo))))
+ rep.status = GrabNotViewable;
+ else if (device->sync.frozen &&
+ device->sync.other && !SameClient(device->sync.other, client))
+ rep.status = GrabFrozen;
+ else if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, device->grabTime) == EARLIER))
+ rep.status = GrabInvalidTime;
+ else
+ {
+ GrabRec tempGrab;
+
+ oldCursor = NullCursor;
+ if (grab)
+ {
+ if (grab->confineTo && !confineTo)
+ ConfineCursorToWindow(ROOT, FALSE, FALSE);
+ oldCursor = grab->cursor;
+ }
+ tempGrab.cursor = cursor;
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.ownerEvents = stuff->ownerEvents;
+ tempGrab.eventMask = stuff->eventMask;
+ tempGrab.confineTo = confineTo;
+ tempGrab.window = pWin;
+ tempGrab.keyboardMode = stuff->keyboardMode;
+ tempGrab.pointerMode = stuff->pointerMode;
+ tempGrab.device = device;
+ (*device->ActivateGrab)(device, &tempGrab, time, FALSE);
+ if (oldCursor)
+ FreeCursor (oldCursor, (Cursor)0);
+ rep.status = GrabSuccess;
+ }
+ WriteReplyToClient(client, sizeof(xGrabPointerReply), &rep);
+ return Success;
+}
+
+int
+ProcChangeActivePointerGrab(ClientPtr client)
+{
+ DeviceIntPtr device = inputInfo.pointer;
+ register GrabPtr grab = device->grab;
+ CursorPtr newCursor, oldCursor;
+ REQUEST(xChangeActivePointerGrabReq);
+ TimeStamp time;
+
+ REQUEST_SIZE_MATCH(xChangeActivePointerGrabReq);
+ if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
+ {
+ client->errorValue = stuff->eventMask;
+ return BadValue;
+ }
+ if (stuff->cursor == None)
+ newCursor = NullCursor;
+ else
+ {
+ newCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+ RT_CURSOR, SecurityReadAccess);
+ if (!newCursor)
+ {
+ client->errorValue = stuff->cursor;
+ return BadCursor;
+ }
+ }
+ if (!grab)
+ return Success;
+ if (!SameClient(grab, client))
+ return Success;
+ time = ClientTimeToServerTime(stuff->time);
+ if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, device->grabTime) == EARLIER))
+ return Success;
+ oldCursor = grab->cursor;
+ grab->cursor = newCursor;
+ if (newCursor)
+ newCursor->refcnt++;
+ PostNewCursor();
+ if (oldCursor)
+ FreeCursor(oldCursor, (Cursor)0);
+ grab->eventMask = stuff->eventMask;
+ return Success;
+}
+
+int
+ProcUngrabPointer(ClientPtr client)
+{
+ DeviceIntPtr device = inputInfo.pointer;
+ GrabPtr grab;
+ TimeStamp time;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ UpdateCurrentTime();
+ grab = device->grab;
+ time = ClientTimeToServerTime(stuff->id);
+ if ((CompareTimeStamps(time, currentTime) != LATER) &&
+ (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
+ (grab) && SameClient(grab, client))
+ (*device->DeactivateGrab)(device);
+ return Success;
+}
+
+int
+GrabDevice(register ClientPtr client, register DeviceIntPtr dev,
+ unsigned this_mode, unsigned other_mode, Window grabWindow,
+ unsigned ownerEvents, Time ctime, Mask mask, CARD8 *status)
+{
+ register WindowPtr pWin;
+ register GrabPtr grab;
+ TimeStamp time;
+
+ UpdateCurrentTime();
+ if ((this_mode != GrabModeSync) && (this_mode != GrabModeAsync))
+ {
+ client->errorValue = this_mode;
+ return BadValue;
+ }
+ if ((other_mode != GrabModeSync) && (other_mode != GrabModeAsync))
+ {
+ client->errorValue = other_mode;
+ return BadValue;
+ }
+ if ((ownerEvents != xFalse) && (ownerEvents != xTrue))
+ {
+ client->errorValue = ownerEvents;
+ return BadValue;
+ }
+ pWin = SecurityLookupWindow(grabWindow, client, SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+ time = ClientTimeToServerTime(ctime);
+ grab = dev->grab;
+ if (grab && !SameClient(grab, client))
+ *status = AlreadyGrabbed;
+ else if (!pWin->realized)
+ *status = GrabNotViewable;
+ else if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, dev->grabTime) == EARLIER))
+ *status = GrabInvalidTime;
+ else if (dev->sync.frozen &&
+ dev->sync.other && !SameClient(dev->sync.other, client))
+ *status = GrabFrozen;
+ else
+ {
+ GrabRec tempGrab;
+
+ tempGrab.window = pWin;
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.ownerEvents = ownerEvents;
+ tempGrab.keyboardMode = this_mode;
+ tempGrab.pointerMode = other_mode;
+ tempGrab.eventMask = mask;
+ tempGrab.device = dev;
+ (*dev->ActivateGrab)(dev, &tempGrab, time, FALSE);
+ *status = GrabSuccess;
+ }
+ return Success;
+}
+
+int
+ProcGrabKeyboard(ClientPtr client)
+{
+ xGrabKeyboardReply rep;
+ REQUEST(xGrabKeyboardReq);
+ int result;
+
+ REQUEST_SIZE_MATCH(xGrabKeyboardReq);
+#ifdef XCSECURITY
+ if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
+ {
+ result = Success;
+ rep.status = AlreadyGrabbed;
+ }
+ else
+#endif
+ result = GrabDevice(client, inputInfo.keyboard, stuff->keyboardMode,
+ stuff->pointerMode, stuff->grabWindow,
+ stuff->ownerEvents, stuff->time,
+ KeyPressMask | KeyReleaseMask, &rep.status);
+ if (result != Success)
+ return result;
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ WriteReplyToClient(client, sizeof(xGrabKeyboardReply), &rep);
+ return Success;
+}
+
+int
+ProcUngrabKeyboard(ClientPtr client)
+{
+ DeviceIntPtr device = inputInfo.keyboard;
+ GrabPtr grab;
+ TimeStamp time;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ UpdateCurrentTime();
+ grab = device->grab;
+ time = ClientTimeToServerTime(stuff->id);
+ if ((CompareTimeStamps(time, currentTime) != LATER) &&
+ (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
+ (grab) && SameClient(grab, client))
+ (*device->DeactivateGrab)(device);
+ return Success;
+}
+
+int
+ProcQueryPointer(ClientPtr client)
+{
+ xQueryPointerReply rep;
+ WindowPtr pWin, t;
+ REQUEST(xResourceReq);
+ DeviceIntPtr mouse = inputInfo.pointer;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = SecurityLookupWindow(stuff->id, client, SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+ if (mouse->valuator->motionHintWindow)
+ MaybeStopHint(mouse, client);
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.mask = mouse->button->state | inputInfo.keyboard->key->state;
+ rep.length = 0;
+ rep.root = (ROOT)->drawable.id;
+ rep.rootX = sprite.hot.x;
+ rep.rootY = sprite.hot.y;
+ rep.child = None;
+ if (sprite.hot.pScreen == pWin->drawable.pScreen)
+ {
+ rep.sameScreen = xTrue;
+ rep.winX = sprite.hot.x - pWin->drawable.x;
+ rep.winY = sprite.hot.y - pWin->drawable.y;
+ for (t = sprite.win; t; t = t->parent)
+ if (t->parent == pWin)
+ {
+ rep.child = t->drawable.id;
+ break;
+ }
+ }
+ else
+ {
+ rep.sameScreen = xFalse;
+ rep.winX = 0;
+ rep.winY = 0;
+ }
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ rep.rootX += panoramiXdataPtr[0].x;
+ rep.rootY += panoramiXdataPtr[0].y;
+ if(stuff->id == rep.root) {
+ rep.winX += panoramiXdataPtr[0].x;
+ rep.winY += panoramiXdataPtr[0].y;
+ }
+ }
+#endif
+
+ WriteReplyToClient(client, sizeof(xQueryPointerReply), &rep);
+
+ return(Success);
+}
+
+void
+InitEvents()
+{
+ int i;
+
+ sprite.hot.pScreen = sprite.hotPhys.pScreen = (ScreenPtr)NULL;
+ inputInfo.numDevices = 0;
+ inputInfo.devices = (DeviceIntPtr)NULL;
+ inputInfo.off_devices = (DeviceIntPtr)NULL;
+ inputInfo.keyboard = (DeviceIntPtr)NULL;
+ inputInfo.pointer = (DeviceIntPtr)NULL;
+ if (spriteTraceSize == 0)
+ {
+ spriteTraceSize = 32;
+ spriteTrace = (WindowPtr *)xalloc(32*sizeof(WindowPtr));
+ if (!spriteTrace)
+ FatalError("failed to allocate spriteTrace");
+ }
+ spriteTraceGood = 0;
+ lastEventMask = OwnerGrabButtonMask;
+ filters[MotionNotify] = PointerMotionMask;
+#ifdef XEVIE
+ xeviewin =
+#endif
+ sprite.win = NullWindow;
+ sprite.current = NullCursor;
+ sprite.hotLimits.x1 = 0;
+ sprite.hotLimits.y1 = 0;
+ sprite.hotLimits.x2 = 0;
+ sprite.hotLimits.y2 = 0;
+ sprite.confined = FALSE;
+ syncEvents.replayDev = (DeviceIntPtr)NULL;
+ syncEvents.replayWin = NullWindow;
+ while (syncEvents.pending)
+ {
+ QdEventPtr next = syncEvents.pending->next;
+ xfree(syncEvents.pending);
+ syncEvents.pending = next;
+ }
+ syncEvents.pendtail = &syncEvents.pending;
+ syncEvents.playingEvents = FALSE;
+ syncEvents.time.months = 0;
+ syncEvents.time.milliseconds = 0; /* hardly matters */
+ currentTime.months = 0;
+ currentTime.milliseconds = GetTimeInMillis();
+ lastDeviceEventTime = currentTime;
+ for (i = 0; i < DNPMCOUNT; i++)
+ {
+ DontPropagateMasks[i] = 0;
+ DontPropagateRefCnts[i] = 0;
+ }
+}
+
+void
+CloseDownEvents(void)
+{
+ xfree(spriteTrace);
+ spriteTrace = NULL;
+ spriteTraceSize = 0;
+}
+
+int
+ProcSendEvent(ClientPtr client)
+{
+ WindowPtr pWin;
+ WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */
+ REQUEST(xSendEventReq);
+
+ REQUEST_SIZE_MATCH(xSendEventReq);
+
+ /* The client's event type must be a core event type or one defined by an
+ extension. */
+
+ if ( ! ((stuff->event.u.u.type > X_Reply &&
+ stuff->event.u.u.type < LASTEvent) ||
+ (stuff->event.u.u.type >= EXTENSION_EVENT_BASE &&
+ stuff->event.u.u.type < (unsigned)lastEvent)))
+ {
+ client->errorValue = stuff->event.u.u.type;
+ return BadValue;
+ }
+ if (stuff->event.u.u.type == ClientMessage &&
+ stuff->event.u.u.detail != 8 &&
+ stuff->event.u.u.detail != 16 &&
+ stuff->event.u.u.detail != 32 &&
+ !permitOldBugs)
+ {
+ client->errorValue = stuff->event.u.u.detail;
+ return BadValue;
+ }
+ if ((stuff->eventMask & ~AllEventMasks) && !permitOldBugs)
+ {
+ client->errorValue = stuff->eventMask;
+ return BadValue;
+ }
+
+ if (stuff->destination == PointerWindow)
+ pWin = sprite.win;
+ else if (stuff->destination == InputFocus)
+ {
+ WindowPtr inputFocus = inputInfo.keyboard->focus->win;
+
+ if (inputFocus == NoneWin)
+ return Success;
+
+ /* If the input focus is PointerRootWin, send the event to where
+ the pointer is if possible, then perhaps propogate up to root. */
+ if (inputFocus == PointerRootWin)
+ inputFocus = ROOT;
+
+ if (IsParent(inputFocus, sprite.win))
+ {
+ effectiveFocus = inputFocus;
+ pWin = sprite.win;
+ }
+ else
+ effectiveFocus = pWin = inputFocus;
+ }
+ else
+ pWin = SecurityLookupWindow(stuff->destination, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+ if ((stuff->propagate != xFalse) && (stuff->propagate != xTrue))
+ {
+ client->errorValue = stuff->propagate;
+ return BadValue;
+ }
+ stuff->event.u.u.type |= 0x80;
+ if (stuff->propagate)
+ {
+ for (;pWin; pWin = pWin->parent)
+ {
+ if (DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
+ NullGrab, 0))
+ return Success;
+ if (pWin == effectiveFocus)
+ return Success;
+ stuff->eventMask &= ~wDontPropagateMask(pWin);
+ if (!stuff->eventMask)
+ break;
+ }
+ }
+ else
+ (void)DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
+ NullGrab, 0);
+ return Success;
+}
+
+int
+ProcUngrabKey(ClientPtr client)
+{
+ REQUEST(xUngrabKeyReq);
+ WindowPtr pWin;
+ GrabRec tempGrab;
+ DeviceIntPtr keybd = inputInfo.keyboard;
+
+ REQUEST_SIZE_MATCH(xUngrabKeyReq);
+ pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+
+ if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
+ (stuff->key < keybd->key->curKeySyms.minKeyCode))
+ && (stuff->key != AnyKey))
+ {
+ client->errorValue = stuff->key;
+ return BadValue;
+ }
+ if ((stuff->modifiers != AnyModifier) &&
+ (stuff->modifiers & ~AllModifiersMask))
+ {
+ client->errorValue = stuff->modifiers;
+ return BadValue;
+ }
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.device = keybd;
+ tempGrab.window = pWin;
+ tempGrab.modifiersDetail.exact = stuff->modifiers;
+ tempGrab.modifiersDetail.pMask = NULL;
+ tempGrab.modifierDevice = inputInfo.keyboard;
+ tempGrab.type = KeyPress;
+ tempGrab.detail.exact = stuff->key;
+ tempGrab.detail.pMask = NULL;
+
+ if (!DeletePassiveGrabFromList(&tempGrab))
+ return(BadAlloc);
+ return(Success);
+}
+
+int
+ProcGrabKey(ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xGrabKeyReq);
+ GrabPtr grab;
+ DeviceIntPtr keybd = inputInfo.keyboard;
+
+ REQUEST_SIZE_MATCH(xGrabKeyReq);
+ if ((stuff->ownerEvents != xTrue) && (stuff->ownerEvents != xFalse))
+ {
+ client->errorValue = stuff->ownerEvents;
+ return(BadValue);
+ }
+ if ((stuff->pointerMode != GrabModeSync) &&
+ (stuff->pointerMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->pointerMode;
+ return BadValue;
+ }
+ if ((stuff->keyboardMode != GrabModeSync) &&
+ (stuff->keyboardMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->keyboardMode;
+ return BadValue;
+ }
+ if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
+ (stuff->key < keybd->key->curKeySyms.minKeyCode))
+ && (stuff->key != AnyKey))
+ {
+ client->errorValue = stuff->key;
+ return BadValue;
+ }
+ if ((stuff->modifiers != AnyModifier) &&
+ (stuff->modifiers & ~AllModifiersMask))
+ {
+ client->errorValue = stuff->modifiers;
+ return BadValue;
+ }
+ pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+
+ grab = CreateGrab(client->index, keybd, pWin,
+ (Mask)(KeyPressMask | KeyReleaseMask), (Bool)stuff->ownerEvents,
+ (Bool)stuff->keyboardMode, (Bool)stuff->pointerMode,
+ keybd, stuff->modifiers, KeyPress, stuff->key,
+ NullWindow, NullCursor);
+ if (!grab)
+ return BadAlloc;
+ return AddPassiveGrabToList(grab);
+}
+
+
+int
+ProcGrabButton(ClientPtr client)
+{
+ WindowPtr pWin, confineTo;
+ REQUEST(xGrabButtonReq);
+ CursorPtr cursor;
+ GrabPtr grab;
+
+ REQUEST_SIZE_MATCH(xGrabButtonReq);
+ if ((stuff->pointerMode != GrabModeSync) &&
+ (stuff->pointerMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->pointerMode;
+ return BadValue;
+ }
+ if ((stuff->keyboardMode != GrabModeSync) &&
+ (stuff->keyboardMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->keyboardMode;
+ return BadValue;
+ }
+ if ((stuff->modifiers != AnyModifier) &&
+ (stuff->modifiers & ~AllModifiersMask))
+ {
+ client->errorValue = stuff->modifiers;
+ return BadValue;
+ }
+ if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
+ {
+ client->errorValue = stuff->ownerEvents;
+ return BadValue;
+ }
+ if (stuff->eventMask & ~PointerGrabMask)
+ {
+ client->errorValue = stuff->eventMask;
+ return BadValue;
+ }
+ pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+ if (stuff->confineTo == None)
+ confineTo = NullWindow;
+ else {
+ confineTo = SecurityLookupWindow(stuff->confineTo, client,
+ SecurityReadAccess);
+ if (!confineTo)
+ return BadWindow;
+ }
+ if (stuff->cursor == None)
+ cursor = NullCursor;
+ else
+ {
+ cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+ RT_CURSOR, SecurityReadAccess);
+ if (!cursor)
+ {
+ client->errorValue = stuff->cursor;
+ return BadCursor;
+ }
+ }
+
+
+ grab = CreateGrab(client->index, inputInfo.pointer, pWin,
+ permitOldBugs ? (Mask)(stuff->eventMask |
+ ButtonPressMask | ButtonReleaseMask) :
+ (Mask)stuff->eventMask,
+ (Bool)stuff->ownerEvents, (Bool) stuff->keyboardMode,
+ (Bool)stuff->pointerMode, inputInfo.keyboard, stuff->modifiers,
+ ButtonPress, stuff->button, confineTo, cursor);
+ if (!grab)
+ return BadAlloc;
+ return AddPassiveGrabToList(grab);
+}
+
+int
+ProcUngrabButton(ClientPtr client)
+{
+ REQUEST(xUngrabButtonReq);
+ WindowPtr pWin;
+ GrabRec tempGrab;
+
+ REQUEST_SIZE_MATCH(xUngrabButtonReq);
+ if ((stuff->modifiers != AnyModifier) &&
+ (stuff->modifiers & ~AllModifiersMask))
+ {
+ client->errorValue = stuff->modifiers;
+ return BadValue;
+ }
+ pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.device = inputInfo.pointer;
+ tempGrab.window = pWin;
+ tempGrab.modifiersDetail.exact = stuff->modifiers;
+ tempGrab.modifiersDetail.pMask = NULL;
+ tempGrab.modifierDevice = inputInfo.keyboard;
+ tempGrab.type = ButtonPress;
+ tempGrab.detail.exact = stuff->button;
+ tempGrab.detail.pMask = NULL;
+
+ if (!DeletePassiveGrabFromList(&tempGrab))
+ return(BadAlloc);
+ return(Success);
+}
+
+void
+DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources)
+{
+ WindowPtr parent;
+ DeviceIntPtr mouse = inputInfo.pointer;
+ DeviceIntPtr keybd = inputInfo.keyboard;
+ FocusClassPtr focus = keybd->focus;
+ OtherClientsPtr oc;
+ GrabPtr passive;
+
+
+ /* Deactivate any grabs performed on this window, before making any
+ input focus changes. */
+
+ if (mouse->grab &&
+ ((mouse->grab->window == pWin) || (mouse->grab->confineTo == pWin)))
+ (*mouse->DeactivateGrab)(mouse);
+
+ /* Deactivating a keyboard grab should cause focus events. */
+
+ if (keybd->grab && (keybd->grab->window == pWin))
+ (*keybd->DeactivateGrab)(keybd);
+
+ /* If the focus window is a root window (ie. has no parent) then don't
+ delete the focus from it. */
+
+ if ((pWin == focus->win) && (pWin->parent != NullWindow))
+ {
+ int focusEventMode = NotifyNormal;
+
+ /* If a grab is in progress, then alter the mode of focus events. */
+
+ if (keybd->grab)
+ focusEventMode = NotifyWhileGrabbed;
+
+ switch (focus->revert)
+ {
+ case RevertToNone:
+ DoFocusEvents(keybd, pWin, NoneWin, focusEventMode);
+ focus->win = NoneWin;
+ focus->traceGood = 0;
+ break;
+ case RevertToParent:
+ parent = pWin;
+ do
+ {
+ parent = parent->parent;
+ focus->traceGood--;
+ } while (!parent->realized
+/* This would be a good protocol change -- windows being reparented
+ during SaveSet processing would cause the focus to revert to the
+ nearest enclosing window which will survive the death of the exiting
+ client, instead of ending up reverting to a dying window and thence
+ to None
+ */
+#ifdef NOTDEF
+ || clients[CLIENT_ID(parent->drawable.id)]->clientGone
+#endif
+ );
+ DoFocusEvents(keybd, pWin, parent, focusEventMode);
+ focus->win = parent;
+ focus->revert = RevertToNone;
+ break;
+ case RevertToPointerRoot:
+ DoFocusEvents(keybd, pWin, PointerRootWin, focusEventMode);
+ focus->win = PointerRootWin;
+ focus->traceGood = 0;
+ break;
+ }
+ }
+
+ if (mouse->valuator->motionHintWindow == pWin)
+ mouse->valuator->motionHintWindow = NullWindow;
+
+ if (freeResources)
+ {
+ if (pWin->dontPropagate)
+ DontPropagateRefCnts[pWin->dontPropagate]--;
+ while ( (oc = wOtherClients(pWin)) )
+ FreeResource(oc->resource, RT_NONE);
+ while ( (passive = wPassiveGrabs(pWin)) )
+ FreeResource(passive->resource, RT_NONE);
+ }
+#ifdef XINPUT
+ DeleteWindowFromAnyExtEvents(pWin, freeResources);
+#endif
+}
+
+/**
+ * Call this whenever some window at or below pWin has changed geometry
+ */
+void
+CheckCursorConfinement(WindowPtr pWin)
+{
+ GrabPtr grab = inputInfo.pointer->grab;
+ WindowPtr confineTo;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) return;
+#endif
+
+ if (grab && (confineTo = grab->confineTo))
+ {
+ if (!BorderSizeNotEmpty(confineTo))
+ (*inputInfo.pointer->DeactivateGrab)(inputInfo.pointer);
+ else if ((pWin == confineTo) || IsParent(pWin, confineTo))
+ ConfineCursorToWindow(confineTo, TRUE, TRUE);
+ }
+}
+
+Mask
+EventMaskForClient(WindowPtr pWin, ClientPtr client)
+{
+ register OtherClientsPtr other;
+
+ if (wClient (pWin) == client)
+ return pWin->eventMask;
+ for (other = wOtherClients(pWin); other; other = other->next)
+ {
+ if (SameClient(other, client))
+ return other->mask;
+ }
+ return 0;
+}
+
+int
+ProcRecolorCursor(ClientPtr client)
+{
+ CursorPtr pCursor;
+ int nscr;
+ ScreenPtr pscr;
+ Bool displayed;
+ REQUEST(xRecolorCursorReq);
+
+ REQUEST_SIZE_MATCH(xRecolorCursorReq);
+ pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+ RT_CURSOR, SecurityWriteAccess);
+ if ( !pCursor)
+ {
+ client->errorValue = stuff->cursor;
+ return (BadCursor);
+ }
+
+ pCursor->foreRed = stuff->foreRed;
+ pCursor->foreGreen = stuff->foreGreen;
+ pCursor->foreBlue = stuff->foreBlue;
+
+ pCursor->backRed = stuff->backRed;
+ pCursor->backGreen = stuff->backGreen;
+ pCursor->backBlue = stuff->backBlue;
+
+ for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
+ {
+ pscr = screenInfo.screens[nscr];
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ displayed = (pscr == sprite.screen);
+ else
+#endif
+ displayed = (pscr == sprite.hotPhys.pScreen);
+ ( *pscr->RecolorCursor)(pscr, pCursor,
+ (pCursor == sprite.current) && displayed);
+ }
+ return (Success);
+}
+
+void
+WriteEventsToClient(ClientPtr pClient, int count, xEvent *events)
+{
+#ifdef PANORAMIX
+ xEvent eventCopy;
+#endif
+ xEvent eventTo, *eventFrom;
+ int i;
+
+#ifdef XKB
+ if ((!noXkbExtension)&&(!XkbFilterEvents(pClient, count, events)))
+ return;
+#endif
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension &&
+ (panoramiXdataPtr[0].x || panoramiXdataPtr[0].y))
+ {
+ switch(events->u.u.type) {
+ case MotionNotify:
+ case ButtonPress:
+ case ButtonRelease:
+ case KeyPress:
+ case KeyRelease:
+ case EnterNotify:
+ case LeaveNotify:
+ /*
+ When multiple clients want the same event DeliverEventsToWindow
+ passes the same event structure multiple times so we can't
+ modify the one passed to us
+ */
+ count = 1; /* should always be 1 */
+ memcpy(&eventCopy, events, sizeof(xEvent));
+ eventCopy.u.keyButtonPointer.rootX += panoramiXdataPtr[0].x;
+ eventCopy.u.keyButtonPointer.rootY += panoramiXdataPtr[0].y;
+ if(eventCopy.u.keyButtonPointer.event ==
+ eventCopy.u.keyButtonPointer.root)
+ {
+ eventCopy.u.keyButtonPointer.eventX += panoramiXdataPtr[0].x;
+ eventCopy.u.keyButtonPointer.eventY += panoramiXdataPtr[0].y;
+ }
+ events = &eventCopy;
+ break;
+ default: break;
+ }
+ }
+#endif
+
+ if (EventCallback)
+ {
+ EventInfoRec eventinfo;
+ eventinfo.client = pClient;
+ eventinfo.events = events;
+ eventinfo.count = count;
+ CallCallbacks(&EventCallback, (pointer)&eventinfo);
+ }
+ if(pClient->swapped)
+ {
+ for(i = 0; i < count; i++)
+ {
+ eventFrom = &events[i];
+ /* Remember to strip off the leading bit of type in case
+ this event was sent with "SendEvent." */
+ (*EventSwapVector[eventFrom->u.u.type & 0177])
+ (eventFrom, &eventTo);
+ (void)WriteToClient(pClient, sizeof(xEvent), (char *)&eventTo);
+ }
+ }
+ else
+ {
+ (void)WriteToClient(pClient, count * sizeof(xEvent), (char *) events);
+ }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c
new file mode 100644
index 000000000..a510c9356
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c
@@ -0,0 +1,508 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/extension.c,v 3.11 2001/12/14 19:59:31 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+/* $Xorg: extension.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#define NEED_EVENTS
+#define NEED_REPLIES
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "../../dix/dispatch.h"
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+#ifdef LBX
+#include "lbxserve.h"
+#endif
+
+#include "Trap.h"
+
+#define EXTENSION_BASE 128
+#define EXTENSION_EVENT_BASE 64
+#define LAST_EVENT 128
+#define LAST_ERROR 255
+
+ScreenProcEntry AuxillaryScreenProcs[MAXSCREENS];
+
+static ExtensionEntry **extensions = (ExtensionEntry **)NULL;
+
+int lastEvent = EXTENSION_EVENT_BASE;
+static int lastError = FirstExtensionError;
+static unsigned int NumExtensions = 0;
+
+ExtensionEntry *
+AddExtension(char *name, int NumEvents, int NumErrors,
+ int (*MainProc)(ClientPtr c1),
+ int (*SwappedMainProc)(ClientPtr c2),
+ void (*CloseDownProc)(ExtensionEntry *e),
+ unsigned short (*MinorOpcodeProc)(ClientPtr c3))
+{
+ int i;
+ register ExtensionEntry *ext, **newexts;
+
+ if (!MainProc || !SwappedMainProc || !CloseDownProc || !MinorOpcodeProc)
+ return((ExtensionEntry *) NULL);
+ if ((lastEvent + NumEvents > LAST_EVENT) ||
+ (unsigned)(lastError + NumErrors > LAST_ERROR))
+ return((ExtensionEntry *) NULL);
+
+ ext = (ExtensionEntry *) xalloc(sizeof(ExtensionEntry));
+ if (!ext)
+ return((ExtensionEntry *) NULL);
+ ext->name = (char *)xalloc(strlen(name) + 1);
+ ext->num_aliases = 0;
+ ext->aliases = (char **)NULL;
+ if (!ext->name)
+ {
+ xfree(ext);
+ return((ExtensionEntry *) NULL);
+ }
+ strcpy(ext->name, name);
+ i = NumExtensions;
+ newexts = (ExtensionEntry **) xrealloc(extensions,
+ (i + 1) * sizeof(ExtensionEntry *));
+ if (!newexts)
+ {
+ xfree(ext->name);
+ xfree(ext);
+ return((ExtensionEntry *) NULL);
+ }
+ NumExtensions++;
+ extensions = newexts;
+ extensions[i] = ext;
+ ext->index = i;
+ ext->base = i + EXTENSION_BASE;
+ ext->CloseDown = CloseDownProc;
+ ext->MinorOpcode = MinorOpcodeProc;
+ ProcVector[i + EXTENSION_BASE] = MainProc;
+ SwappedProcVector[i + EXTENSION_BASE] = SwappedMainProc;
+ if (NumEvents)
+ {
+ ext->eventBase = lastEvent;
+ ext->eventLast = lastEvent + NumEvents;
+ lastEvent += NumEvents;
+ }
+ else
+ {
+ ext->eventBase = 0;
+ ext->eventLast = 0;
+ }
+ if (NumErrors)
+ {
+ ext->errorBase = lastError;
+ ext->errorLast = lastError + NumErrors;
+ lastError += NumErrors;
+ }
+ else
+ {
+ ext->errorBase = 0;
+ ext->errorLast = 0;
+ }
+#ifdef XCSECURITY
+ ext->secure = FALSE;
+#endif
+
+#ifdef LBX
+ (void) LbxAddExtension(name, ext->base, ext->eventBase, ext->errorBase);
+#endif
+ return(ext);
+}
+
+Bool AddExtensionAlias(char *alias, ExtensionEntry *ext)
+{
+ char *name;
+ char **aliases;
+
+ aliases = (char **)xrealloc(ext->aliases,
+ (ext->num_aliases + 1) * sizeof(char *));
+ if (!aliases)
+ return FALSE;
+ ext->aliases = aliases;
+ name = (char *)xalloc(strlen(alias) + 1);
+ if (!name)
+ return FALSE;
+ strcpy(name, alias);
+ ext->aliases[ext->num_aliases] = name;
+ ext->num_aliases++;
+#ifdef LBX
+ return LbxAddExtensionAlias(ext->index, alias);
+#else
+ return TRUE;
+#endif
+}
+
+static int
+FindExtension(char *extname, int len)
+{
+ int i, j;
+
+ for (i=0; i<NumExtensions; i++)
+ {
+ if ((strlen(extensions[i]->name) == len) &&
+ !strncmp(extname, extensions[i]->name, len))
+ break;
+ for (j = extensions[i]->num_aliases; --j >= 0;)
+ {
+ if ((strlen(extensions[i]->aliases[j]) == len) &&
+ !strncmp(extname, extensions[i]->aliases[j], len))
+ break;
+ }
+ if (j >= 0) break;
+ }
+ return ((i == NumExtensions) ? -1 : i);
+}
+
+/*
+ * CheckExtension returns the extensions[] entry for the requested
+ * extension name. Maybe this could just return a Bool instead?
+ */
+ExtensionEntry *
+CheckExtension(const char *extname)
+{
+ int n;
+
+ n = FindExtension((char*)extname, strlen(extname));
+ if (n != -1)
+ return extensions[n];
+ else
+ return NULL;
+}
+
+void
+DeclareExtensionSecurity(char *extname, Bool secure)
+{
+#ifdef XCSECURITY
+ int i = FindExtension(extname, strlen(extname));
+ if (i >= 0)
+ {
+ int majorop = extensions[i]->base;
+ extensions[i]->secure = secure;
+ if (secure)
+ {
+ UntrustedProcVector[majorop] = ProcVector[majorop];
+ SwappedUntrustedProcVector[majorop] = SwappedProcVector[majorop];
+ }
+ else
+ {
+ UntrustedProcVector[majorop] = ProcBadRequest;
+ SwappedUntrustedProcVector[majorop] = ProcBadRequest;
+ }
+ }
+#endif
+#ifdef LBX
+ LbxDeclareExtensionSecurity(extname, secure);
+#endif
+}
+
+unsigned short
+StandardMinorOpcode(ClientPtr client)
+{
+ return ((xReq *)client->requestBuffer)->data;
+}
+
+unsigned short
+MinorOpcodeOfRequest(ClientPtr client)
+{
+ unsigned char major;
+
+ major = ((xReq *)client->requestBuffer)->reqType;
+ if (major < EXTENSION_BASE)
+ return 0;
+ major -= EXTENSION_BASE;
+ if (major >= NumExtensions)
+ return 0;
+ return (*extensions[major]->MinorOpcode)(client);
+}
+
+void
+CloseDownExtensions()
+{
+ register int i,j;
+
+#ifdef LBX
+ LbxCloseDownExtensions();
+#endif
+
+ for (i = NumExtensions - 1; i >= 0; i--)
+ {
+ (* extensions[i]->CloseDown)(extensions[i]);
+ NumExtensions = i;
+ xfree(extensions[i]->name);
+ for (j = extensions[i]->num_aliases; --j >= 0;)
+ xfree(extensions[i]->aliases[j]);
+ xfree(extensions[i]->aliases);
+ xfree(extensions[i]);
+ }
+ xfree(extensions);
+ extensions = (ExtensionEntry **)NULL;
+ lastEvent = EXTENSION_EVENT_BASE;
+ lastError = FirstExtensionError;
+ for (i=0; i<MAXSCREENS; i++)
+ {
+ register ScreenProcEntry *spentry = &AuxillaryScreenProcs[i];
+
+ while (spentry->num)
+ {
+ spentry->num--;
+ xfree(spentry->procList[spentry->num].name);
+ }
+ xfree(spentry->procList);
+ spentry->procList = (ProcEntryPtr)NULL;
+ }
+}
+
+
+int
+ProcQueryExtension(ClientPtr client)
+{
+ xQueryExtensionReply reply;
+ int i;
+ REQUEST(xQueryExtensionReq);
+
+ REQUEST_FIXED_SIZE(xQueryExtensionReq, stuff->nbytes);
+
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.major_opcode = 0;
+ reply.sequenceNumber = client->sequence;
+
+ if ( ! NumExtensions )
+ reply.present = xFalse;
+ else
+ {
+ i = FindExtension((char *)&stuff[1], stuff->nbytes);
+ if (i < 0
+
+ /*
+ * Hide RENDER if our implementation
+ * is faulty.
+ */
+
+ || (nxagentRenderTrap && strcmp(extensions[i]->name, "RENDER") == 0)
+#ifdef XCSECURITY
+ /* don't show insecure extensions to untrusted clients */
+ || (client->trustLevel == XSecurityClientUntrusted &&
+ !extensions[i]->secure)
+#endif
+ )
+ reply.present = xFalse;
+ else
+ {
+ reply.present = xTrue;
+ reply.major_opcode = extensions[i]->base;
+ reply.first_event = extensions[i]->eventBase;
+ reply.first_error = extensions[i]->errorBase;
+ }
+ }
+ WriteReplyToClient(client, sizeof(xQueryExtensionReply), &reply);
+ return(client->noClientException);
+}
+
+int
+ProcListExtensions(ClientPtr client)
+{
+ xListExtensionsReply reply;
+ char *bufptr, *buffer;
+ int total_length = 0;
+
+ REQUEST_SIZE_MATCH(xReq);
+
+ reply.type = X_Reply;
+ reply.nExtensions = 0;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ buffer = NULL;
+
+ if ( NumExtensions )
+ {
+ register int i, j;
+
+ for (i=0; i<NumExtensions; i++)
+ {
+#ifdef XCSECURITY
+ /* don't show insecure extensions to untrusted clients */
+ if (client->trustLevel == XSecurityClientUntrusted &&
+ !extensions[i]->secure)
+ continue;
+#endif
+ /*
+ * Hide RENDER if our implementation
+ * is faulty.
+ */
+
+ if (nxagentRenderTrap && strcmp(extensions[i]->name, "RENDER") == 0)
+ continue;
+
+ total_length += strlen(extensions[i]->name) + 1;
+ reply.nExtensions += 1 + extensions[i]->num_aliases;
+ for (j = extensions[i]->num_aliases; --j >= 0;)
+ total_length += strlen(extensions[i]->aliases[j]) + 1;
+ }
+ reply.length = (total_length + 3) >> 2;
+ buffer = bufptr = (char *)ALLOCATE_LOCAL(total_length);
+ if (!buffer)
+ return(BadAlloc);
+ for (i=0; i<NumExtensions; i++)
+ {
+ int len;
+#ifdef XCSECURITY
+ if (client->trustLevel == XSecurityClientUntrusted &&
+ !extensions[i]->secure)
+ continue;
+#endif
+ *bufptr++ = len = strlen(extensions[i]->name);
+ memmove(bufptr, extensions[i]->name, len);
+ bufptr += len;
+ for (j = extensions[i]->num_aliases; --j >= 0;)
+ {
+ *bufptr++ = len = strlen(extensions[i]->aliases[j]);
+ memmove(bufptr, extensions[i]->aliases[j], len);
+ bufptr += len;
+ }
+ }
+ }
+ WriteReplyToClient(client, sizeof(xListExtensionsReply), &reply);
+ if (reply.length)
+ {
+ WriteToClient(client, total_length, buffer);
+ DEALLOCATE_LOCAL(buffer);
+ }
+ return(client->noClientException);
+}
+
+
+ExtensionLookupProc
+LookupProc(char *name, GCPtr pGC)
+{
+ register int i;
+ register ScreenProcEntry *spentry;
+ spentry = &AuxillaryScreenProcs[pGC->pScreen->myNum];
+ if (spentry->num)
+ {
+ for (i = 0; i < spentry->num; i++)
+ if (strcmp(name, spentry->procList[i].name) == 0)
+ return(spentry->procList[i].proc);
+ }
+ return (ExtensionLookupProc)NULL;
+}
+
+Bool
+RegisterProc(char *name, GC *pGC, ExtensionLookupProc proc)
+{
+ return RegisterScreenProc(name, pGC->pScreen, proc);
+}
+
+Bool
+RegisterScreenProc(char *name, ScreenPtr pScreen, ExtensionLookupProc proc)
+{
+ register ScreenProcEntry *spentry;
+ register ProcEntryPtr procEntry = (ProcEntryPtr)NULL;
+ char *newname;
+ int i;
+
+ spentry = &AuxillaryScreenProcs[pScreen->myNum];
+ /* first replace duplicates */
+ if (spentry->num)
+ {
+ for (i = 0; i < spentry->num; i++)
+ if (strcmp(name, spentry->procList[i].name) == 0)
+ {
+ procEntry = &spentry->procList[i];
+ break;
+ }
+ }
+ if (procEntry)
+ procEntry->proc = proc;
+ else
+ {
+ newname = (char *)xalloc(strlen(name)+1);
+ if (!newname)
+ return FALSE;
+ procEntry = (ProcEntryPtr)
+ xrealloc(spentry->procList,
+ sizeof(ProcEntryRec) * (spentry->num+1));
+ if (!procEntry)
+ {
+ xfree(newname);
+ return FALSE;
+ }
+ spentry->procList = procEntry;
+ procEntry += spentry->num;
+ procEntry->name = newname;
+ strcpy(newname, name);
+ procEntry->proc = proc;
+ spentry->num++;
+ }
+ return TRUE;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.NX.original
new file mode 100644
index 000000000..a510c9356
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.NX.original
@@ -0,0 +1,508 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/extension.c,v 3.11 2001/12/14 19:59:31 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+/* $Xorg: extension.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#define NEED_EVENTS
+#define NEED_REPLIES
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "../../dix/dispatch.h"
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+#ifdef LBX
+#include "lbxserve.h"
+#endif
+
+#include "Trap.h"
+
+#define EXTENSION_BASE 128
+#define EXTENSION_EVENT_BASE 64
+#define LAST_EVENT 128
+#define LAST_ERROR 255
+
+ScreenProcEntry AuxillaryScreenProcs[MAXSCREENS];
+
+static ExtensionEntry **extensions = (ExtensionEntry **)NULL;
+
+int lastEvent = EXTENSION_EVENT_BASE;
+static int lastError = FirstExtensionError;
+static unsigned int NumExtensions = 0;
+
+ExtensionEntry *
+AddExtension(char *name, int NumEvents, int NumErrors,
+ int (*MainProc)(ClientPtr c1),
+ int (*SwappedMainProc)(ClientPtr c2),
+ void (*CloseDownProc)(ExtensionEntry *e),
+ unsigned short (*MinorOpcodeProc)(ClientPtr c3))
+{
+ int i;
+ register ExtensionEntry *ext, **newexts;
+
+ if (!MainProc || !SwappedMainProc || !CloseDownProc || !MinorOpcodeProc)
+ return((ExtensionEntry *) NULL);
+ if ((lastEvent + NumEvents > LAST_EVENT) ||
+ (unsigned)(lastError + NumErrors > LAST_ERROR))
+ return((ExtensionEntry *) NULL);
+
+ ext = (ExtensionEntry *) xalloc(sizeof(ExtensionEntry));
+ if (!ext)
+ return((ExtensionEntry *) NULL);
+ ext->name = (char *)xalloc(strlen(name) + 1);
+ ext->num_aliases = 0;
+ ext->aliases = (char **)NULL;
+ if (!ext->name)
+ {
+ xfree(ext);
+ return((ExtensionEntry *) NULL);
+ }
+ strcpy(ext->name, name);
+ i = NumExtensions;
+ newexts = (ExtensionEntry **) xrealloc(extensions,
+ (i + 1) * sizeof(ExtensionEntry *));
+ if (!newexts)
+ {
+ xfree(ext->name);
+ xfree(ext);
+ return((ExtensionEntry *) NULL);
+ }
+ NumExtensions++;
+ extensions = newexts;
+ extensions[i] = ext;
+ ext->index = i;
+ ext->base = i + EXTENSION_BASE;
+ ext->CloseDown = CloseDownProc;
+ ext->MinorOpcode = MinorOpcodeProc;
+ ProcVector[i + EXTENSION_BASE] = MainProc;
+ SwappedProcVector[i + EXTENSION_BASE] = SwappedMainProc;
+ if (NumEvents)
+ {
+ ext->eventBase = lastEvent;
+ ext->eventLast = lastEvent + NumEvents;
+ lastEvent += NumEvents;
+ }
+ else
+ {
+ ext->eventBase = 0;
+ ext->eventLast = 0;
+ }
+ if (NumErrors)
+ {
+ ext->errorBase = lastError;
+ ext->errorLast = lastError + NumErrors;
+ lastError += NumErrors;
+ }
+ else
+ {
+ ext->errorBase = 0;
+ ext->errorLast = 0;
+ }
+#ifdef XCSECURITY
+ ext->secure = FALSE;
+#endif
+
+#ifdef LBX
+ (void) LbxAddExtension(name, ext->base, ext->eventBase, ext->errorBase);
+#endif
+ return(ext);
+}
+
+Bool AddExtensionAlias(char *alias, ExtensionEntry *ext)
+{
+ char *name;
+ char **aliases;
+
+ aliases = (char **)xrealloc(ext->aliases,
+ (ext->num_aliases + 1) * sizeof(char *));
+ if (!aliases)
+ return FALSE;
+ ext->aliases = aliases;
+ name = (char *)xalloc(strlen(alias) + 1);
+ if (!name)
+ return FALSE;
+ strcpy(name, alias);
+ ext->aliases[ext->num_aliases] = name;
+ ext->num_aliases++;
+#ifdef LBX
+ return LbxAddExtensionAlias(ext->index, alias);
+#else
+ return TRUE;
+#endif
+}
+
+static int
+FindExtension(char *extname, int len)
+{
+ int i, j;
+
+ for (i=0; i<NumExtensions; i++)
+ {
+ if ((strlen(extensions[i]->name) == len) &&
+ !strncmp(extname, extensions[i]->name, len))
+ break;
+ for (j = extensions[i]->num_aliases; --j >= 0;)
+ {
+ if ((strlen(extensions[i]->aliases[j]) == len) &&
+ !strncmp(extname, extensions[i]->aliases[j], len))
+ break;
+ }
+ if (j >= 0) break;
+ }
+ return ((i == NumExtensions) ? -1 : i);
+}
+
+/*
+ * CheckExtension returns the extensions[] entry for the requested
+ * extension name. Maybe this could just return a Bool instead?
+ */
+ExtensionEntry *
+CheckExtension(const char *extname)
+{
+ int n;
+
+ n = FindExtension((char*)extname, strlen(extname));
+ if (n != -1)
+ return extensions[n];
+ else
+ return NULL;
+}
+
+void
+DeclareExtensionSecurity(char *extname, Bool secure)
+{
+#ifdef XCSECURITY
+ int i = FindExtension(extname, strlen(extname));
+ if (i >= 0)
+ {
+ int majorop = extensions[i]->base;
+ extensions[i]->secure = secure;
+ if (secure)
+ {
+ UntrustedProcVector[majorop] = ProcVector[majorop];
+ SwappedUntrustedProcVector[majorop] = SwappedProcVector[majorop];
+ }
+ else
+ {
+ UntrustedProcVector[majorop] = ProcBadRequest;
+ SwappedUntrustedProcVector[majorop] = ProcBadRequest;
+ }
+ }
+#endif
+#ifdef LBX
+ LbxDeclareExtensionSecurity(extname, secure);
+#endif
+}
+
+unsigned short
+StandardMinorOpcode(ClientPtr client)
+{
+ return ((xReq *)client->requestBuffer)->data;
+}
+
+unsigned short
+MinorOpcodeOfRequest(ClientPtr client)
+{
+ unsigned char major;
+
+ major = ((xReq *)client->requestBuffer)->reqType;
+ if (major < EXTENSION_BASE)
+ return 0;
+ major -= EXTENSION_BASE;
+ if (major >= NumExtensions)
+ return 0;
+ return (*extensions[major]->MinorOpcode)(client);
+}
+
+void
+CloseDownExtensions()
+{
+ register int i,j;
+
+#ifdef LBX
+ LbxCloseDownExtensions();
+#endif
+
+ for (i = NumExtensions - 1; i >= 0; i--)
+ {
+ (* extensions[i]->CloseDown)(extensions[i]);
+ NumExtensions = i;
+ xfree(extensions[i]->name);
+ for (j = extensions[i]->num_aliases; --j >= 0;)
+ xfree(extensions[i]->aliases[j]);
+ xfree(extensions[i]->aliases);
+ xfree(extensions[i]);
+ }
+ xfree(extensions);
+ extensions = (ExtensionEntry **)NULL;
+ lastEvent = EXTENSION_EVENT_BASE;
+ lastError = FirstExtensionError;
+ for (i=0; i<MAXSCREENS; i++)
+ {
+ register ScreenProcEntry *spentry = &AuxillaryScreenProcs[i];
+
+ while (spentry->num)
+ {
+ spentry->num--;
+ xfree(spentry->procList[spentry->num].name);
+ }
+ xfree(spentry->procList);
+ spentry->procList = (ProcEntryPtr)NULL;
+ }
+}
+
+
+int
+ProcQueryExtension(ClientPtr client)
+{
+ xQueryExtensionReply reply;
+ int i;
+ REQUEST(xQueryExtensionReq);
+
+ REQUEST_FIXED_SIZE(xQueryExtensionReq, stuff->nbytes);
+
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.major_opcode = 0;
+ reply.sequenceNumber = client->sequence;
+
+ if ( ! NumExtensions )
+ reply.present = xFalse;
+ else
+ {
+ i = FindExtension((char *)&stuff[1], stuff->nbytes);
+ if (i < 0
+
+ /*
+ * Hide RENDER if our implementation
+ * is faulty.
+ */
+
+ || (nxagentRenderTrap && strcmp(extensions[i]->name, "RENDER") == 0)
+#ifdef XCSECURITY
+ /* don't show insecure extensions to untrusted clients */
+ || (client->trustLevel == XSecurityClientUntrusted &&
+ !extensions[i]->secure)
+#endif
+ )
+ reply.present = xFalse;
+ else
+ {
+ reply.present = xTrue;
+ reply.major_opcode = extensions[i]->base;
+ reply.first_event = extensions[i]->eventBase;
+ reply.first_error = extensions[i]->errorBase;
+ }
+ }
+ WriteReplyToClient(client, sizeof(xQueryExtensionReply), &reply);
+ return(client->noClientException);
+}
+
+int
+ProcListExtensions(ClientPtr client)
+{
+ xListExtensionsReply reply;
+ char *bufptr, *buffer;
+ int total_length = 0;
+
+ REQUEST_SIZE_MATCH(xReq);
+
+ reply.type = X_Reply;
+ reply.nExtensions = 0;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ buffer = NULL;
+
+ if ( NumExtensions )
+ {
+ register int i, j;
+
+ for (i=0; i<NumExtensions; i++)
+ {
+#ifdef XCSECURITY
+ /* don't show insecure extensions to untrusted clients */
+ if (client->trustLevel == XSecurityClientUntrusted &&
+ !extensions[i]->secure)
+ continue;
+#endif
+ /*
+ * Hide RENDER if our implementation
+ * is faulty.
+ */
+
+ if (nxagentRenderTrap && strcmp(extensions[i]->name, "RENDER") == 0)
+ continue;
+
+ total_length += strlen(extensions[i]->name) + 1;
+ reply.nExtensions += 1 + extensions[i]->num_aliases;
+ for (j = extensions[i]->num_aliases; --j >= 0;)
+ total_length += strlen(extensions[i]->aliases[j]) + 1;
+ }
+ reply.length = (total_length + 3) >> 2;
+ buffer = bufptr = (char *)ALLOCATE_LOCAL(total_length);
+ if (!buffer)
+ return(BadAlloc);
+ for (i=0; i<NumExtensions; i++)
+ {
+ int len;
+#ifdef XCSECURITY
+ if (client->trustLevel == XSecurityClientUntrusted &&
+ !extensions[i]->secure)
+ continue;
+#endif
+ *bufptr++ = len = strlen(extensions[i]->name);
+ memmove(bufptr, extensions[i]->name, len);
+ bufptr += len;
+ for (j = extensions[i]->num_aliases; --j >= 0;)
+ {
+ *bufptr++ = len = strlen(extensions[i]->aliases[j]);
+ memmove(bufptr, extensions[i]->aliases[j], len);
+ bufptr += len;
+ }
+ }
+ }
+ WriteReplyToClient(client, sizeof(xListExtensionsReply), &reply);
+ if (reply.length)
+ {
+ WriteToClient(client, total_length, buffer);
+ DEALLOCATE_LOCAL(buffer);
+ }
+ return(client->noClientException);
+}
+
+
+ExtensionLookupProc
+LookupProc(char *name, GCPtr pGC)
+{
+ register int i;
+ register ScreenProcEntry *spentry;
+ spentry = &AuxillaryScreenProcs[pGC->pScreen->myNum];
+ if (spentry->num)
+ {
+ for (i = 0; i < spentry->num; i++)
+ if (strcmp(name, spentry->procList[i].name) == 0)
+ return(spentry->procList[i].proc);
+ }
+ return (ExtensionLookupProc)NULL;
+}
+
+Bool
+RegisterProc(char *name, GC *pGC, ExtensionLookupProc proc)
+{
+ return RegisterScreenProc(name, pGC->pScreen, proc);
+}
+
+Bool
+RegisterScreenProc(char *name, ScreenPtr pScreen, ExtensionLookupProc proc)
+{
+ register ScreenProcEntry *spentry;
+ register ProcEntryPtr procEntry = (ProcEntryPtr)NULL;
+ char *newname;
+ int i;
+
+ spentry = &AuxillaryScreenProcs[pScreen->myNum];
+ /* first replace duplicates */
+ if (spentry->num)
+ {
+ for (i = 0; i < spentry->num; i++)
+ if (strcmp(name, spentry->procList[i].name) == 0)
+ {
+ procEntry = &spentry->procList[i];
+ break;
+ }
+ }
+ if (procEntry)
+ procEntry->proc = proc;
+ else
+ {
+ newname = (char *)xalloc(strlen(name)+1);
+ if (!newname)
+ return FALSE;
+ procEntry = (ProcEntryPtr)
+ xrealloc(spentry->procList,
+ sizeof(ProcEntryRec) * (spentry->num+1));
+ if (!procEntry)
+ {
+ xfree(newname);
+ return FALSE;
+ }
+ spentry->procList = procEntry;
+ procEntry += spentry->num;
+ procEntry->name = newname;
+ strcpy(newname, name);
+ procEntry->proc = proc;
+ spentry->num++;
+ }
+ return TRUE;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.X.original
new file mode 100644
index 000000000..270d54f9b
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.X.original
@@ -0,0 +1,474 @@
+/* $XFree86: xc/programs/Xserver/dix/extension.c,v 3.11 2001/12/14 19:59:31 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+/* $Xorg: extension.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#define NEED_EVENTS
+#define NEED_REPLIES
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "dispatch.h"
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+#ifdef LBX
+#include "lbxserve.h"
+#endif
+
+#define EXTENSION_BASE 128
+#define EXTENSION_EVENT_BASE 64
+#define LAST_EVENT 128
+#define LAST_ERROR 255
+
+ScreenProcEntry AuxillaryScreenProcs[MAXSCREENS];
+
+static ExtensionEntry **extensions = (ExtensionEntry **)NULL;
+
+int lastEvent = EXTENSION_EVENT_BASE;
+static int lastError = FirstExtensionError;
+static unsigned int NumExtensions = 0;
+
+ExtensionEntry *
+AddExtension(char *name, int NumEvents, int NumErrors,
+ int (*MainProc)(ClientPtr c1),
+ int (*SwappedMainProc)(ClientPtr c2),
+ void (*CloseDownProc)(ExtensionEntry *e),
+ unsigned short (*MinorOpcodeProc)(ClientPtr c3))
+{
+ int i;
+ register ExtensionEntry *ext, **newexts;
+
+ if (!MainProc || !SwappedMainProc || !CloseDownProc || !MinorOpcodeProc)
+ return((ExtensionEntry *) NULL);
+ if ((lastEvent + NumEvents > LAST_EVENT) ||
+ (unsigned)(lastError + NumErrors > LAST_ERROR))
+ return((ExtensionEntry *) NULL);
+
+ ext = (ExtensionEntry *) xalloc(sizeof(ExtensionEntry));
+ if (!ext)
+ return((ExtensionEntry *) NULL);
+ ext->name = (char *)xalloc(strlen(name) + 1);
+ ext->num_aliases = 0;
+ ext->aliases = (char **)NULL;
+ if (!ext->name)
+ {
+ xfree(ext);
+ return((ExtensionEntry *) NULL);
+ }
+ strcpy(ext->name, name);
+ i = NumExtensions;
+ newexts = (ExtensionEntry **) xrealloc(extensions,
+ (i + 1) * sizeof(ExtensionEntry *));
+ if (!newexts)
+ {
+ xfree(ext->name);
+ xfree(ext);
+ return((ExtensionEntry *) NULL);
+ }
+ NumExtensions++;
+ extensions = newexts;
+ extensions[i] = ext;
+ ext->index = i;
+ ext->base = i + EXTENSION_BASE;
+ ext->CloseDown = CloseDownProc;
+ ext->MinorOpcode = MinorOpcodeProc;
+ ProcVector[i + EXTENSION_BASE] = MainProc;
+ SwappedProcVector[i + EXTENSION_BASE] = SwappedMainProc;
+ if (NumEvents)
+ {
+ ext->eventBase = lastEvent;
+ ext->eventLast = lastEvent + NumEvents;
+ lastEvent += NumEvents;
+ }
+ else
+ {
+ ext->eventBase = 0;
+ ext->eventLast = 0;
+ }
+ if (NumErrors)
+ {
+ ext->errorBase = lastError;
+ ext->errorLast = lastError + NumErrors;
+ lastError += NumErrors;
+ }
+ else
+ {
+ ext->errorBase = 0;
+ ext->errorLast = 0;
+ }
+#ifdef XCSECURITY
+ ext->secure = FALSE;
+#endif
+
+#ifdef LBX
+ (void) LbxAddExtension(name, ext->base, ext->eventBase, ext->errorBase);
+#endif
+ return(ext);
+}
+
+Bool AddExtensionAlias(char *alias, ExtensionEntry *ext)
+{
+ char *name;
+ char **aliases;
+
+ aliases = (char **)xrealloc(ext->aliases,
+ (ext->num_aliases + 1) * sizeof(char *));
+ if (!aliases)
+ return FALSE;
+ ext->aliases = aliases;
+ name = (char *)xalloc(strlen(alias) + 1);
+ if (!name)
+ return FALSE;
+ strcpy(name, alias);
+ ext->aliases[ext->num_aliases] = name;
+ ext->num_aliases++;
+#ifdef LBX
+ return LbxAddExtensionAlias(ext->index, alias);
+#else
+ return TRUE;
+#endif
+}
+
+static int
+FindExtension(char *extname, int len)
+{
+ int i, j;
+
+ for (i=0; i<NumExtensions; i++)
+ {
+ if ((strlen(extensions[i]->name) == len) &&
+ !strncmp(extname, extensions[i]->name, len))
+ break;
+ for (j = extensions[i]->num_aliases; --j >= 0;)
+ {
+ if ((strlen(extensions[i]->aliases[j]) == len) &&
+ !strncmp(extname, extensions[i]->aliases[j], len))
+ break;
+ }
+ if (j >= 0) break;
+ }
+ return ((i == NumExtensions) ? -1 : i);
+}
+
+/*
+ * CheckExtension returns the extensions[] entry for the requested
+ * extension name. Maybe this could just return a Bool instead?
+ */
+ExtensionEntry *
+CheckExtension(const char *extname)
+{
+ int n;
+
+ n = FindExtension((char*)extname, strlen(extname));
+ if (n != -1)
+ return extensions[n];
+ else
+ return NULL;
+}
+
+void
+DeclareExtensionSecurity(char *extname, Bool secure)
+{
+#ifdef XCSECURITY
+ int i = FindExtension(extname, strlen(extname));
+ if (i >= 0)
+ {
+ int majorop = extensions[i]->base;
+ extensions[i]->secure = secure;
+ if (secure)
+ {
+ UntrustedProcVector[majorop] = ProcVector[majorop];
+ SwappedUntrustedProcVector[majorop] = SwappedProcVector[majorop];
+ }
+ else
+ {
+ UntrustedProcVector[majorop] = ProcBadRequest;
+ SwappedUntrustedProcVector[majorop] = ProcBadRequest;
+ }
+ }
+#endif
+#ifdef LBX
+ LbxDeclareExtensionSecurity(extname, secure);
+#endif
+}
+
+unsigned short
+StandardMinorOpcode(ClientPtr client)
+{
+ return ((xReq *)client->requestBuffer)->data;
+}
+
+unsigned short
+MinorOpcodeOfRequest(ClientPtr client)
+{
+ unsigned char major;
+
+ major = ((xReq *)client->requestBuffer)->reqType;
+ if (major < EXTENSION_BASE)
+ return 0;
+ major -= EXTENSION_BASE;
+ if (major >= NumExtensions)
+ return 0;
+ return (*extensions[major]->MinorOpcode)(client);
+}
+
+void
+CloseDownExtensions()
+{
+ register int i,j;
+
+#ifdef LBX
+ LbxCloseDownExtensions();
+#endif
+
+ for (i = NumExtensions - 1; i >= 0; i--)
+ {
+ (* extensions[i]->CloseDown)(extensions[i]);
+ NumExtensions = i;
+ xfree(extensions[i]->name);
+ for (j = extensions[i]->num_aliases; --j >= 0;)
+ xfree(extensions[i]->aliases[j]);
+ xfree(extensions[i]->aliases);
+ xfree(extensions[i]);
+ }
+ xfree(extensions);
+ extensions = (ExtensionEntry **)NULL;
+ lastEvent = EXTENSION_EVENT_BASE;
+ lastError = FirstExtensionError;
+ for (i=0; i<MAXSCREENS; i++)
+ {
+ register ScreenProcEntry *spentry = &AuxillaryScreenProcs[i];
+
+ while (spentry->num)
+ {
+ spentry->num--;
+ xfree(spentry->procList[spentry->num].name);
+ }
+ xfree(spentry->procList);
+ spentry->procList = (ProcEntryPtr)NULL;
+ }
+}
+
+
+int
+ProcQueryExtension(ClientPtr client)
+{
+ xQueryExtensionReply reply;
+ int i;
+ REQUEST(xQueryExtensionReq);
+
+ REQUEST_FIXED_SIZE(xQueryExtensionReq, stuff->nbytes);
+
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.major_opcode = 0;
+ reply.sequenceNumber = client->sequence;
+
+ if ( ! NumExtensions )
+ reply.present = xFalse;
+ else
+ {
+ i = FindExtension((char *)&stuff[1], stuff->nbytes);
+ if (i < 0
+#ifdef XCSECURITY
+ /* don't show insecure extensions to untrusted clients */
+ || (client->trustLevel == XSecurityClientUntrusted &&
+ !extensions[i]->secure)
+#endif
+ )
+ reply.present = xFalse;
+ else
+ {
+ reply.present = xTrue;
+ reply.major_opcode = extensions[i]->base;
+ reply.first_event = extensions[i]->eventBase;
+ reply.first_error = extensions[i]->errorBase;
+ }
+ }
+ WriteReplyToClient(client, sizeof(xQueryExtensionReply), &reply);
+ return(client->noClientException);
+}
+
+int
+ProcListExtensions(ClientPtr client)
+{
+ xListExtensionsReply reply;
+ char *bufptr, *buffer;
+ int total_length = 0;
+
+ REQUEST_SIZE_MATCH(xReq);
+
+ reply.type = X_Reply;
+ reply.nExtensions = 0;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ buffer = NULL;
+
+ if ( NumExtensions )
+ {
+ register int i, j;
+
+ for (i=0; i<NumExtensions; i++)
+ {
+#ifdef XCSECURITY
+ /* don't show insecure extensions to untrusted clients */
+ if (client->trustLevel == XSecurityClientUntrusted &&
+ !extensions[i]->secure)
+ continue;
+#endif
+ total_length += strlen(extensions[i]->name) + 1;
+ reply.nExtensions += 1 + extensions[i]->num_aliases;
+ for (j = extensions[i]->num_aliases; --j >= 0;)
+ total_length += strlen(extensions[i]->aliases[j]) + 1;
+ }
+ reply.length = (total_length + 3) >> 2;
+ buffer = bufptr = (char *)ALLOCATE_LOCAL(total_length);
+ if (!buffer)
+ return(BadAlloc);
+ for (i=0; i<NumExtensions; i++)
+ {
+ int len;
+#ifdef XCSECURITY
+ if (client->trustLevel == XSecurityClientUntrusted &&
+ !extensions[i]->secure)
+ continue;
+#endif
+ *bufptr++ = len = strlen(extensions[i]->name);
+ memmove(bufptr, extensions[i]->name, len);
+ bufptr += len;
+ for (j = extensions[i]->num_aliases; --j >= 0;)
+ {
+ *bufptr++ = len = strlen(extensions[i]->aliases[j]);
+ memmove(bufptr, extensions[i]->aliases[j], len);
+ bufptr += len;
+ }
+ }
+ }
+ WriteReplyToClient(client, sizeof(xListExtensionsReply), &reply);
+ if (reply.length)
+ {
+ WriteToClient(client, total_length, buffer);
+ DEALLOCATE_LOCAL(buffer);
+ }
+ return(client->noClientException);
+}
+
+
+ExtensionLookupProc
+LookupProc(char *name, GCPtr pGC)
+{
+ register int i;
+ register ScreenProcEntry *spentry;
+ spentry = &AuxillaryScreenProcs[pGC->pScreen->myNum];
+ if (spentry->num)
+ {
+ for (i = 0; i < spentry->num; i++)
+ if (strcmp(name, spentry->procList[i].name) == 0)
+ return(spentry->procList[i].proc);
+ }
+ return (ExtensionLookupProc)NULL;
+}
+
+Bool
+RegisterProc(char *name, GC *pGC, ExtensionLookupProc proc)
+{
+ return RegisterScreenProc(name, pGC->pScreen, proc);
+}
+
+Bool
+RegisterScreenProc(char *name, ScreenPtr pScreen, ExtensionLookupProc proc)
+{
+ register ScreenProcEntry *spentry;
+ register ProcEntryPtr procEntry = (ProcEntryPtr)NULL;
+ char *newname;
+ int i;
+
+ spentry = &AuxillaryScreenProcs[pScreen->myNum];
+ /* first replace duplicates */
+ if (spentry->num)
+ {
+ for (i = 0; i < spentry->num; i++)
+ if (strcmp(name, spentry->procList[i].name) == 0)
+ {
+ procEntry = &spentry->procList[i];
+ break;
+ }
+ }
+ if (procEntry)
+ procEntry->proc = proc;
+ else
+ {
+ newname = (char *)xalloc(strlen(name)+1);
+ if (!newname)
+ return FALSE;
+ procEntry = (ProcEntryPtr)
+ xrealloc(spentry->procList,
+ sizeof(ProcEntryRec) * (spentry->num+1));
+ if (!procEntry)
+ {
+ xfree(newname);
+ return FALSE;
+ }
+ spentry->procList = procEntry;
+ procEntry += spentry->num;
+ procEntry->name = newname;
+ strcpy(newname, name);
+ procEntry->proc = proc;
+ spentry->num++;
+ }
+ return TRUE;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c
new file mode 100644
index 000000000..aee27e820
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c
@@ -0,0 +1,575 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/GL/glx/glxext.c,v 1.9 2003/09/28 20:15:43 alanh Exp $
+** The contents of this file are subject to the GLX Public License Version 1.0
+** (the "License"). You may not use this file except in compliance with the
+** License. You may obtain a copy of the License at Silicon Graphics, Inc.,
+** attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA 94043
+** or at http://www.sgi.com/software/opensource/glx/license.html.
+**
+** Software distributed under the License is distributed on an "AS IS"
+** basis. ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY
+** IMPLIED WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR
+** PURPOSE OR OF NON- INFRINGEMENT. See the License for the specific
+** language governing rights and limitations under the License.
+**
+** The Original Software is GLX version 1.2 source code, released February,
+** 1999. The developer of the Original Software is Silicon Graphics, Inc.
+** Those portions of the Subject Software created by Silicon Graphics, Inc.
+** are Copyright (c) 1991-9 Silicon Graphics, Inc. All Rights Reserved.
+**
+*/
+
+#define NEED_REPLIES
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glxserver.h"
+#include <windowstr.h>
+#include <propertyst.h>
+#include <os.h>
+#include "g_disptab.h"
+#include "unpack.h"
+#include "glxutil.h"
+#include "glxext.h"
+#include "micmap.h"
+
+#include "Trap.h"
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+void GlxWrapInitVisuals(miInitVisualsProcPtr *);
+void GlxSetVisualConfigs(int nconfigs,
+ __GLXvisualConfig *configs, void **privates);
+
+static __GLXextensionInfo *__glXExt /* = &__glDDXExtensionInfo */;
+
+/*
+** Forward declarations.
+*/
+static int __glXSwapDispatch(ClientPtr);
+static int __glXDispatch(ClientPtr);
+
+/*
+** Called when the extension is reset.
+*/
+static void ResetExtension(ExtensionEntry* extEntry)
+{
+ __glXFlushContextCache();
+ (*__glXExt->resetExtension)();
+ __glXScreenReset();
+}
+
+/*
+** Initialize the per-client context storage.
+*/
+static void ResetClientState(int clientIndex)
+{
+ __GLXclientState *cl = __glXClients[clientIndex];
+
+ if (cl->returnBuf) __glXFree(cl->returnBuf);
+ if (cl->largeCmdBuf) __glXFree(cl->largeCmdBuf);
+ if (cl->currentContexts) __glXFree(cl->currentContexts);
+ __glXMemset(cl, 0, sizeof(__GLXclientState));
+ /*
+ ** By default, assume that the client supports
+ ** GLX major version 1 minor version 0 protocol.
+ */
+ cl->GLClientmajorVersion = 1;
+ cl->GLClientminorVersion = 0;
+ if (cl->GLClientextensions) __glXFree(cl->GLClientextensions);
+
+}
+
+/*
+** Reset state used to keep track of large (multi-request) commands.
+*/
+void __glXResetLargeCommandStatus(__GLXclientState *cl)
+{
+ cl->largeCmdBytesSoFar = 0;
+ cl->largeCmdBytesTotal = 0;
+ cl->largeCmdRequestsSoFar = 0;
+ cl->largeCmdRequestsTotal = 0;
+}
+
+/*
+** This procedure is called when the client who created the context goes
+** away OR when glXDestroyContext is called. In either case, all we do is
+** flag that the ID is no longer valid, and (maybe) free the context.
+** use.
+*/
+static int ContextGone(__GLXcontext* cx, XID id)
+{
+ cx->idExists = GL_FALSE;
+ if (!cx->isCurrent) {
+ __glXFreeContext(cx);
+ }
+
+ return True;
+}
+
+/*
+** Free a client's state.
+*/
+static int ClientGone(int clientIndex, XID id)
+{
+ __GLXcontext *cx;
+ __GLXclientState *cl = __glXClients[clientIndex];
+ int i;
+
+ if (cl) {
+ /*
+ ** Free all the contexts that are current for this client.
+ */
+ for (i=0; i < cl->numCurrentContexts; i++) {
+ cx = cl->currentContexts[i];
+ if (cx) {
+ __glXDeassociateContext(cx);
+ cx->isCurrent = GL_FALSE;
+ if (!cx->idExists) {
+ __glXFreeContext(cx);
+ }
+ }
+ }
+ /*
+ ** Re-initialize the client state structure. Don't free it because
+ ** we'll probably get another client with this index and use the struct
+ ** again. There is a maximum of MAXCLIENTS of these structures.
+ */
+ ResetClientState(clientIndex);
+ }
+
+ return True;
+}
+
+/*
+** Free a GLX Pixmap.
+*/
+static int PixmapGone(__GLXpixmap *pGlxPixmap, XID id)
+{
+ PixmapPtr pPixmap = (PixmapPtr) pGlxPixmap->pDraw;
+
+ pGlxPixmap->idExists = False;
+ if (!pGlxPixmap->refcnt) {
+ /*
+ ** The DestroyPixmap routine should decrement the refcount and free
+ ** only if it's zero.
+ */
+ (*pGlxPixmap->pScreen->DestroyPixmap)(pPixmap);
+ __glXFree(pGlxPixmap);
+ }
+
+ return True;
+}
+
+/*
+** Free a context.
+*/
+GLboolean __glXFreeContext(__GLXcontext *cx)
+{
+ if (cx->idExists || cx->isCurrent) return GL_FALSE;
+
+ if (!cx->isDirect) {
+ if ((*cx->gc->exports.destroyContext)((__GLcontext *)cx->gc) == GL_FALSE) {
+ return GL_FALSE;
+ }
+ }
+ if (cx->feedbackBuf) __glXFree(cx->feedbackBuf);
+ if (cx->selectBuf) __glXFree(cx->selectBuf);
+ __glXFree(cx);
+ if (cx == __glXLastContext) {
+ __glXFlushContextCache();
+ }
+
+ return GL_TRUE;
+}
+
+extern RESTYPE __glXSwapBarrierRes;
+
+static int SwapBarrierGone(int screen, XID drawable)
+{
+ if (__glXSwapBarrierFuncs &&
+ __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc != NULL) {
+ __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc(screen, drawable, 0);
+ }
+ FreeResourceByType(drawable, __glXSwapBarrierRes, FALSE);
+ return True;
+}
+
+/************************************************************************/
+
+/*
+** These routines can be used to check whether a particular GL command
+** has caused an error. Specifically, we use them to check whether a
+** given query has caused an error, in which case a zero-length data
+** reply is sent to the client.
+*/
+
+static GLboolean errorOccured = GL_FALSE;
+
+/*
+** The GL was will call this routine if an error occurs.
+*/
+void __glXErrorCallBack(__GLinterface *gc, GLenum code)
+{
+ errorOccured = GL_TRUE;
+}
+
+/*
+** Clear the error flag before calling the GL command.
+*/
+void __glXClearErrorOccured(void)
+{
+ errorOccured = GL_FALSE;
+}
+
+/*
+** Check if the GL command caused an error.
+*/
+GLboolean __glXErrorOccured(void)
+{
+ return errorOccured;
+}
+
+/************************************************************************/
+
+/*
+** Initialize the GLX extension.
+*/
+void GlxExtensionInit(void)
+{
+ ExtensionEntry *extEntry;
+ int i;
+
+ __glXContextRes = CreateNewResourceType((DeleteType)ContextGone);
+ __glXClientRes = CreateNewResourceType((DeleteType)ClientGone);
+ __glXPixmapRes = CreateNewResourceType((DeleteType)PixmapGone);
+
+ /*
+ ** Add extension to server extensions.
+ */
+ extEntry = AddExtension(GLX_EXTENSION_NAME, __GLX_NUMBER_EVENTS,
+ __GLX_NUMBER_ERRORS, __glXDispatch,
+ __glXSwapDispatch, ResetExtension,
+ StandardMinorOpcode);
+ if (!extEntry) {
+ FatalError("__glXExtensionInit: AddExtensions failed\n");
+ return;
+ }
+ if (!AddExtensionAlias(GLX_EXTENSION_ALIAS, extEntry)) {
+ ErrorF("__glXExtensionInit: AddExtensionAlias failed\n");
+ return;
+ }
+
+ __glXBadContext = extEntry->errorBase + GLXBadContext;
+ __glXBadContextState = extEntry->errorBase + GLXBadContextState;
+ __glXBadDrawable = extEntry->errorBase + GLXBadDrawable;
+ __glXBadPixmap = extEntry->errorBase + GLXBadPixmap;
+ __glXBadContextTag = extEntry->errorBase + GLXBadContextTag;
+ __glXBadCurrentWindow = extEntry->errorBase + GLXBadCurrentWindow;
+ __glXBadRenderRequest = extEntry->errorBase + GLXBadRenderRequest;
+ __glXBadLargeRequest = extEntry->errorBase + GLXBadLargeRequest;
+ __glXUnsupportedPrivateRequest = extEntry->errorBase +
+ GLXUnsupportedPrivateRequest;
+
+ __glXSwapBarrierRes = CreateNewResourceType((DeleteType)SwapBarrierGone);
+
+ /*
+ ** Initialize table of client state. There is never a client 0.
+ */
+ for (i=1; i <= MAXCLIENTS; i++) {
+ __glXClients[i] = 0;
+ }
+
+ /*
+ ** Initialize screen specific data.
+ */
+ __glXScreenInit(screenInfo.numScreens);
+}
+
+/************************************************************************/
+
+Bool __glXCoreType(void)
+{
+ return __glXExt->type;
+}
+
+/************************************************************************/
+
+void GlxSetVisualConfigs(int nconfigs,
+ __GLXvisualConfig *configs, void **privates)
+{
+ (*__glXExt->setVisualConfigs)(nconfigs, configs, privates);
+}
+
+static miInitVisualsProcPtr saveInitVisualsProc;
+
+Bool GlxInitVisuals(VisualPtr *visualp, DepthPtr *depthp,
+ int *nvisualp, int *ndepthp,
+ int *rootDepthp, VisualID *defaultVisp,
+ unsigned long sizes, int bitsPerRGB,
+ int preferredVis)
+{
+ Bool ret;
+
+ if (saveInitVisualsProc) {
+ ret = saveInitVisualsProc(visualp, depthp, nvisualp, ndepthp,
+ rootDepthp, defaultVisp, sizes, bitsPerRGB,
+ preferredVis);
+ if (!ret)
+ return False;
+ }
+ (*__glXExt->initVisuals)(visualp, depthp, nvisualp, ndepthp, rootDepthp,
+ defaultVisp, sizes, bitsPerRGB);
+ return True;
+}
+
+void
+GlxWrapInitVisuals(miInitVisualsProcPtr *initVisProc)
+{
+ saveInitVisualsProc = *initVisProc;
+ *initVisProc = GlxInitVisuals;
+ /* HACK: this shouldn't be done here but it's the earliest time */
+ __glXExt = __glXglDDXExtensionInfo(); /* from GLcore */
+}
+
+/************************************************************************/
+
+void __glXFlushContextCache(void)
+{
+ __glXLastContext = 0;
+}
+
+/*
+** Make a context the current one for the GL (in this implementation, there
+** is only one instance of the GL, and we use it to serve all GL clients by
+** switching it between different contexts). While we are at it, look up
+** a context by its tag and return its (__GLXcontext *).
+*/
+__GLXcontext *__glXForceCurrent(__GLXclientState *cl, GLXContextTag tag,
+ int *error)
+{
+ __GLXcontext *cx;
+
+ /*
+ ** See if the context tag is legal; it is managed by the extension,
+ ** so if it's invalid, we have an implementation error.
+ */
+ cx = (__GLXcontext *) __glXLookupContextByTag(cl, tag);
+ if (!cx) {
+ cl->client->errorValue = tag;
+ *error = __glXBadContextTag;
+ return 0;
+ }
+
+ if (!cx->isDirect) {
+ if (cx->drawPriv == NULL) {
+ /*
+ ** The drawable has vanished. It must be a window, because only
+ ** windows can be destroyed from under us; GLX pixmaps are
+ ** refcounted and don't go away until no one is using them.
+ */
+ *error = __glXBadCurrentWindow;
+ return 0;
+ }
+ }
+
+ if (cx == __glXLastContext) {
+ /* No need to re-bind */
+ return cx;
+ }
+
+ /* Make this context the current one for the GL. */
+ if (!cx->isDirect) {
+ if (!(*cx->gc->exports.forceCurrent)((__GLcontext *)cx->gc)) {
+ /* Bind failed, and set the error code. Bummer */
+ cl->client->errorValue = cx->id;
+ *error = __glXBadContextState;
+ return 0;
+ }
+ }
+ __glXLastContext = cx;
+ return cx;
+}
+
+/************************************************************************/
+
+/*
+** Top level dispatcher; all commands are executed from here down.
+*/
+static int __glXDispatch(ClientPtr client)
+{
+ int result;
+
+ REQUEST(xGLXSingleReq);
+ CARD8 opcode;
+ int (*proc)(__GLXclientState *cl, GLbyte *pc);
+ __GLXclientState *cl;
+
+ opcode = stuff->glxCode;
+ cl = __glXClients[client->index];
+ if (!cl) {
+ cl = (__GLXclientState *) __glXMalloc(sizeof(__GLXclientState));
+ __glXClients[client->index] = cl;
+ if (!cl) {
+ return BadAlloc;
+ }
+ __glXMemset(cl, 0, sizeof(__GLXclientState));
+ }
+
+ if (!cl->inUse) {
+ /*
+ ** This is first request from this client. Associate a resource
+ ** with the client so we will be notified when the client dies.
+ */
+ XID xid = FakeClientID(client->index);
+ if (!AddResource( xid, __glXClientRes, (pointer)(long)client->index)) {
+ return BadAlloc;
+ }
+ ResetClientState(client->index);
+ cl->inUse = GL_TRUE;
+ cl->client = client;
+ }
+
+ /*
+ ** Check for valid opcode.
+ */
+ if (opcode >= __GLX_SINGLE_TABLE_SIZE) {
+ return BadRequest;
+ }
+
+ /*
+ ** If we're expecting a glXRenderLarge request, this better be one.
+ */
+ if ((cl->largeCmdRequestsSoFar != 0) && (opcode != X_GLXRenderLarge)) {
+ client->errorValue = stuff->glxCode;
+ return __glXBadLargeRequest;
+ }
+
+ /*
+ ** Use the opcode to index into the procedure table.
+ */
+ proc = __glXSingleTable[opcode];
+
+ /*
+ * Report upstream that we are
+ * dispatching a GLX operation.
+ */
+
+ nxagentGlxTrap = 1;
+
+ #ifdef TEST
+ fprintf(stderr, "__glXDispatch: Going to dispatch GLX operation [%d] for client [%d].\n",
+ opcode, client -> index);
+ #endif
+
+ result = (*proc)(cl, (GLbyte *) stuff);
+
+ nxagentGlxTrap = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "__glXDispatch: Dispatched GLX operation [%d] for client [%d].\n",
+ opcode, client -> index);
+ #endif
+
+ return result;
+}
+
+static int __glXSwapDispatch(ClientPtr client)
+{
+ int result;
+
+ REQUEST(xGLXSingleReq);
+ CARD8 opcode;
+ int (*proc)(__GLXclientState *cl, GLbyte *pc);
+ __GLXclientState *cl;
+
+ opcode = stuff->glxCode;
+ cl = __glXClients[client->index];
+ if (!cl) {
+ cl = (__GLXclientState *) __glXMalloc(sizeof(__GLXclientState));
+ __glXClients[client->index] = cl;
+ if (!cl) {
+ return BadAlloc;
+ }
+ __glXMemset(cl, 0, sizeof(__GLXclientState));
+ }
+
+ if (!cl->inUse) {
+ /*
+ ** This is first request from this client. Associate a resource
+ ** with the client so we will be notified when the client dies.
+ */
+ XID xid = FakeClientID(client->index);
+ if (!AddResource( xid, __glXClientRes, (pointer)(long)client->index)) {
+ return BadAlloc;
+ }
+ ResetClientState(client->index);
+ cl->inUse = GL_TRUE;
+ cl->client = client;
+ }
+
+ /*
+ ** Check for valid opcode.
+ */
+ if (opcode >= __GLX_SINGLE_TABLE_SIZE) {
+ return BadRequest;
+ }
+
+ /*
+ ** Use the opcode to index into the procedure table.
+ */
+ proc = __glXSwapSingleTable[opcode];
+
+ /*
+ * Report upstream that we are
+ * dispatching a GLX operation.
+ */
+
+ nxagentGlxTrap = 1;
+
+ #ifdef TEST
+ fprintf(stderr, "__glXDispatch: Going to dispatch GLX operation [%d] for client [%d].\n",
+ opcode, client -> index);
+ #endif
+
+ result = (*proc)(cl, (GLbyte *) stuff);
+
+ nxagentGlxTrap = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "__glXDispatch: Dispatched GLX operation [%d] for client [%d].\n",
+ opcode, client -> index);
+ #endif
+
+ return result;
+}
+
+int __glXNoSuchSingleOpcode(__GLXclientState *cl, GLbyte *pc)
+{
+ return BadRequest;
+}
+
+void __glXNoSuchRenderOpcode(GLbyte *pc)
+{
+ return;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.NX.original
new file mode 100644
index 000000000..aee27e820
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.NX.original
@@ -0,0 +1,575 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/GL/glx/glxext.c,v 1.9 2003/09/28 20:15:43 alanh Exp $
+** The contents of this file are subject to the GLX Public License Version 1.0
+** (the "License"). You may not use this file except in compliance with the
+** License. You may obtain a copy of the License at Silicon Graphics, Inc.,
+** attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA 94043
+** or at http://www.sgi.com/software/opensource/glx/license.html.
+**
+** Software distributed under the License is distributed on an "AS IS"
+** basis. ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY
+** IMPLIED WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR
+** PURPOSE OR OF NON- INFRINGEMENT. See the License for the specific
+** language governing rights and limitations under the License.
+**
+** The Original Software is GLX version 1.2 source code, released February,
+** 1999. The developer of the Original Software is Silicon Graphics, Inc.
+** Those portions of the Subject Software created by Silicon Graphics, Inc.
+** are Copyright (c) 1991-9 Silicon Graphics, Inc. All Rights Reserved.
+**
+*/
+
+#define NEED_REPLIES
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glxserver.h"
+#include <windowstr.h>
+#include <propertyst.h>
+#include <os.h>
+#include "g_disptab.h"
+#include "unpack.h"
+#include "glxutil.h"
+#include "glxext.h"
+#include "micmap.h"
+
+#include "Trap.h"
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+void GlxWrapInitVisuals(miInitVisualsProcPtr *);
+void GlxSetVisualConfigs(int nconfigs,
+ __GLXvisualConfig *configs, void **privates);
+
+static __GLXextensionInfo *__glXExt /* = &__glDDXExtensionInfo */;
+
+/*
+** Forward declarations.
+*/
+static int __glXSwapDispatch(ClientPtr);
+static int __glXDispatch(ClientPtr);
+
+/*
+** Called when the extension is reset.
+*/
+static void ResetExtension(ExtensionEntry* extEntry)
+{
+ __glXFlushContextCache();
+ (*__glXExt->resetExtension)();
+ __glXScreenReset();
+}
+
+/*
+** Initialize the per-client context storage.
+*/
+static void ResetClientState(int clientIndex)
+{
+ __GLXclientState *cl = __glXClients[clientIndex];
+
+ if (cl->returnBuf) __glXFree(cl->returnBuf);
+ if (cl->largeCmdBuf) __glXFree(cl->largeCmdBuf);
+ if (cl->currentContexts) __glXFree(cl->currentContexts);
+ __glXMemset(cl, 0, sizeof(__GLXclientState));
+ /*
+ ** By default, assume that the client supports
+ ** GLX major version 1 minor version 0 protocol.
+ */
+ cl->GLClientmajorVersion = 1;
+ cl->GLClientminorVersion = 0;
+ if (cl->GLClientextensions) __glXFree(cl->GLClientextensions);
+
+}
+
+/*
+** Reset state used to keep track of large (multi-request) commands.
+*/
+void __glXResetLargeCommandStatus(__GLXclientState *cl)
+{
+ cl->largeCmdBytesSoFar = 0;
+ cl->largeCmdBytesTotal = 0;
+ cl->largeCmdRequestsSoFar = 0;
+ cl->largeCmdRequestsTotal = 0;
+}
+
+/*
+** This procedure is called when the client who created the context goes
+** away OR when glXDestroyContext is called. In either case, all we do is
+** flag that the ID is no longer valid, and (maybe) free the context.
+** use.
+*/
+static int ContextGone(__GLXcontext* cx, XID id)
+{
+ cx->idExists = GL_FALSE;
+ if (!cx->isCurrent) {
+ __glXFreeContext(cx);
+ }
+
+ return True;
+}
+
+/*
+** Free a client's state.
+*/
+static int ClientGone(int clientIndex, XID id)
+{
+ __GLXcontext *cx;
+ __GLXclientState *cl = __glXClients[clientIndex];
+ int i;
+
+ if (cl) {
+ /*
+ ** Free all the contexts that are current for this client.
+ */
+ for (i=0; i < cl->numCurrentContexts; i++) {
+ cx = cl->currentContexts[i];
+ if (cx) {
+ __glXDeassociateContext(cx);
+ cx->isCurrent = GL_FALSE;
+ if (!cx->idExists) {
+ __glXFreeContext(cx);
+ }
+ }
+ }
+ /*
+ ** Re-initialize the client state structure. Don't free it because
+ ** we'll probably get another client with this index and use the struct
+ ** again. There is a maximum of MAXCLIENTS of these structures.
+ */
+ ResetClientState(clientIndex);
+ }
+
+ return True;
+}
+
+/*
+** Free a GLX Pixmap.
+*/
+static int PixmapGone(__GLXpixmap *pGlxPixmap, XID id)
+{
+ PixmapPtr pPixmap = (PixmapPtr) pGlxPixmap->pDraw;
+
+ pGlxPixmap->idExists = False;
+ if (!pGlxPixmap->refcnt) {
+ /*
+ ** The DestroyPixmap routine should decrement the refcount and free
+ ** only if it's zero.
+ */
+ (*pGlxPixmap->pScreen->DestroyPixmap)(pPixmap);
+ __glXFree(pGlxPixmap);
+ }
+
+ return True;
+}
+
+/*
+** Free a context.
+*/
+GLboolean __glXFreeContext(__GLXcontext *cx)
+{
+ if (cx->idExists || cx->isCurrent) return GL_FALSE;
+
+ if (!cx->isDirect) {
+ if ((*cx->gc->exports.destroyContext)((__GLcontext *)cx->gc) == GL_FALSE) {
+ return GL_FALSE;
+ }
+ }
+ if (cx->feedbackBuf) __glXFree(cx->feedbackBuf);
+ if (cx->selectBuf) __glXFree(cx->selectBuf);
+ __glXFree(cx);
+ if (cx == __glXLastContext) {
+ __glXFlushContextCache();
+ }
+
+ return GL_TRUE;
+}
+
+extern RESTYPE __glXSwapBarrierRes;
+
+static int SwapBarrierGone(int screen, XID drawable)
+{
+ if (__glXSwapBarrierFuncs &&
+ __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc != NULL) {
+ __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc(screen, drawable, 0);
+ }
+ FreeResourceByType(drawable, __glXSwapBarrierRes, FALSE);
+ return True;
+}
+
+/************************************************************************/
+
+/*
+** These routines can be used to check whether a particular GL command
+** has caused an error. Specifically, we use them to check whether a
+** given query has caused an error, in which case a zero-length data
+** reply is sent to the client.
+*/
+
+static GLboolean errorOccured = GL_FALSE;
+
+/*
+** The GL was will call this routine if an error occurs.
+*/
+void __glXErrorCallBack(__GLinterface *gc, GLenum code)
+{
+ errorOccured = GL_TRUE;
+}
+
+/*
+** Clear the error flag before calling the GL command.
+*/
+void __glXClearErrorOccured(void)
+{
+ errorOccured = GL_FALSE;
+}
+
+/*
+** Check if the GL command caused an error.
+*/
+GLboolean __glXErrorOccured(void)
+{
+ return errorOccured;
+}
+
+/************************************************************************/
+
+/*
+** Initialize the GLX extension.
+*/
+void GlxExtensionInit(void)
+{
+ ExtensionEntry *extEntry;
+ int i;
+
+ __glXContextRes = CreateNewResourceType((DeleteType)ContextGone);
+ __glXClientRes = CreateNewResourceType((DeleteType)ClientGone);
+ __glXPixmapRes = CreateNewResourceType((DeleteType)PixmapGone);
+
+ /*
+ ** Add extension to server extensions.
+ */
+ extEntry = AddExtension(GLX_EXTENSION_NAME, __GLX_NUMBER_EVENTS,
+ __GLX_NUMBER_ERRORS, __glXDispatch,
+ __glXSwapDispatch, ResetExtension,
+ StandardMinorOpcode);
+ if (!extEntry) {
+ FatalError("__glXExtensionInit: AddExtensions failed\n");
+ return;
+ }
+ if (!AddExtensionAlias(GLX_EXTENSION_ALIAS, extEntry)) {
+ ErrorF("__glXExtensionInit: AddExtensionAlias failed\n");
+ return;
+ }
+
+ __glXBadContext = extEntry->errorBase + GLXBadContext;
+ __glXBadContextState = extEntry->errorBase + GLXBadContextState;
+ __glXBadDrawable = extEntry->errorBase + GLXBadDrawable;
+ __glXBadPixmap = extEntry->errorBase + GLXBadPixmap;
+ __glXBadContextTag = extEntry->errorBase + GLXBadContextTag;
+ __glXBadCurrentWindow = extEntry->errorBase + GLXBadCurrentWindow;
+ __glXBadRenderRequest = extEntry->errorBase + GLXBadRenderRequest;
+ __glXBadLargeRequest = extEntry->errorBase + GLXBadLargeRequest;
+ __glXUnsupportedPrivateRequest = extEntry->errorBase +
+ GLXUnsupportedPrivateRequest;
+
+ __glXSwapBarrierRes = CreateNewResourceType((DeleteType)SwapBarrierGone);
+
+ /*
+ ** Initialize table of client state. There is never a client 0.
+ */
+ for (i=1; i <= MAXCLIENTS; i++) {
+ __glXClients[i] = 0;
+ }
+
+ /*
+ ** Initialize screen specific data.
+ */
+ __glXScreenInit(screenInfo.numScreens);
+}
+
+/************************************************************************/
+
+Bool __glXCoreType(void)
+{
+ return __glXExt->type;
+}
+
+/************************************************************************/
+
+void GlxSetVisualConfigs(int nconfigs,
+ __GLXvisualConfig *configs, void **privates)
+{
+ (*__glXExt->setVisualConfigs)(nconfigs, configs, privates);
+}
+
+static miInitVisualsProcPtr saveInitVisualsProc;
+
+Bool GlxInitVisuals(VisualPtr *visualp, DepthPtr *depthp,
+ int *nvisualp, int *ndepthp,
+ int *rootDepthp, VisualID *defaultVisp,
+ unsigned long sizes, int bitsPerRGB,
+ int preferredVis)
+{
+ Bool ret;
+
+ if (saveInitVisualsProc) {
+ ret = saveInitVisualsProc(visualp, depthp, nvisualp, ndepthp,
+ rootDepthp, defaultVisp, sizes, bitsPerRGB,
+ preferredVis);
+ if (!ret)
+ return False;
+ }
+ (*__glXExt->initVisuals)(visualp, depthp, nvisualp, ndepthp, rootDepthp,
+ defaultVisp, sizes, bitsPerRGB);
+ return True;
+}
+
+void
+GlxWrapInitVisuals(miInitVisualsProcPtr *initVisProc)
+{
+ saveInitVisualsProc = *initVisProc;
+ *initVisProc = GlxInitVisuals;
+ /* HACK: this shouldn't be done here but it's the earliest time */
+ __glXExt = __glXglDDXExtensionInfo(); /* from GLcore */
+}
+
+/************************************************************************/
+
+void __glXFlushContextCache(void)
+{
+ __glXLastContext = 0;
+}
+
+/*
+** Make a context the current one for the GL (in this implementation, there
+** is only one instance of the GL, and we use it to serve all GL clients by
+** switching it between different contexts). While we are at it, look up
+** a context by its tag and return its (__GLXcontext *).
+*/
+__GLXcontext *__glXForceCurrent(__GLXclientState *cl, GLXContextTag tag,
+ int *error)
+{
+ __GLXcontext *cx;
+
+ /*
+ ** See if the context tag is legal; it is managed by the extension,
+ ** so if it's invalid, we have an implementation error.
+ */
+ cx = (__GLXcontext *) __glXLookupContextByTag(cl, tag);
+ if (!cx) {
+ cl->client->errorValue = tag;
+ *error = __glXBadContextTag;
+ return 0;
+ }
+
+ if (!cx->isDirect) {
+ if (cx->drawPriv == NULL) {
+ /*
+ ** The drawable has vanished. It must be a window, because only
+ ** windows can be destroyed from under us; GLX pixmaps are
+ ** refcounted and don't go away until no one is using them.
+ */
+ *error = __glXBadCurrentWindow;
+ return 0;
+ }
+ }
+
+ if (cx == __glXLastContext) {
+ /* No need to re-bind */
+ return cx;
+ }
+
+ /* Make this context the current one for the GL. */
+ if (!cx->isDirect) {
+ if (!(*cx->gc->exports.forceCurrent)((__GLcontext *)cx->gc)) {
+ /* Bind failed, and set the error code. Bummer */
+ cl->client->errorValue = cx->id;
+ *error = __glXBadContextState;
+ return 0;
+ }
+ }
+ __glXLastContext = cx;
+ return cx;
+}
+
+/************************************************************************/
+
+/*
+** Top level dispatcher; all commands are executed from here down.
+*/
+static int __glXDispatch(ClientPtr client)
+{
+ int result;
+
+ REQUEST(xGLXSingleReq);
+ CARD8 opcode;
+ int (*proc)(__GLXclientState *cl, GLbyte *pc);
+ __GLXclientState *cl;
+
+ opcode = stuff->glxCode;
+ cl = __glXClients[client->index];
+ if (!cl) {
+ cl = (__GLXclientState *) __glXMalloc(sizeof(__GLXclientState));
+ __glXClients[client->index] = cl;
+ if (!cl) {
+ return BadAlloc;
+ }
+ __glXMemset(cl, 0, sizeof(__GLXclientState));
+ }
+
+ if (!cl->inUse) {
+ /*
+ ** This is first request from this client. Associate a resource
+ ** with the client so we will be notified when the client dies.
+ */
+ XID xid = FakeClientID(client->index);
+ if (!AddResource( xid, __glXClientRes, (pointer)(long)client->index)) {
+ return BadAlloc;
+ }
+ ResetClientState(client->index);
+ cl->inUse = GL_TRUE;
+ cl->client = client;
+ }
+
+ /*
+ ** Check for valid opcode.
+ */
+ if (opcode >= __GLX_SINGLE_TABLE_SIZE) {
+ return BadRequest;
+ }
+
+ /*
+ ** If we're expecting a glXRenderLarge request, this better be one.
+ */
+ if ((cl->largeCmdRequestsSoFar != 0) && (opcode != X_GLXRenderLarge)) {
+ client->errorValue = stuff->glxCode;
+ return __glXBadLargeRequest;
+ }
+
+ /*
+ ** Use the opcode to index into the procedure table.
+ */
+ proc = __glXSingleTable[opcode];
+
+ /*
+ * Report upstream that we are
+ * dispatching a GLX operation.
+ */
+
+ nxagentGlxTrap = 1;
+
+ #ifdef TEST
+ fprintf(stderr, "__glXDispatch: Going to dispatch GLX operation [%d] for client [%d].\n",
+ opcode, client -> index);
+ #endif
+
+ result = (*proc)(cl, (GLbyte *) stuff);
+
+ nxagentGlxTrap = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "__glXDispatch: Dispatched GLX operation [%d] for client [%d].\n",
+ opcode, client -> index);
+ #endif
+
+ return result;
+}
+
+static int __glXSwapDispatch(ClientPtr client)
+{
+ int result;
+
+ REQUEST(xGLXSingleReq);
+ CARD8 opcode;
+ int (*proc)(__GLXclientState *cl, GLbyte *pc);
+ __GLXclientState *cl;
+
+ opcode = stuff->glxCode;
+ cl = __glXClients[client->index];
+ if (!cl) {
+ cl = (__GLXclientState *) __glXMalloc(sizeof(__GLXclientState));
+ __glXClients[client->index] = cl;
+ if (!cl) {
+ return BadAlloc;
+ }
+ __glXMemset(cl, 0, sizeof(__GLXclientState));
+ }
+
+ if (!cl->inUse) {
+ /*
+ ** This is first request from this client. Associate a resource
+ ** with the client so we will be notified when the client dies.
+ */
+ XID xid = FakeClientID(client->index);
+ if (!AddResource( xid, __glXClientRes, (pointer)(long)client->index)) {
+ return BadAlloc;
+ }
+ ResetClientState(client->index);
+ cl->inUse = GL_TRUE;
+ cl->client = client;
+ }
+
+ /*
+ ** Check for valid opcode.
+ */
+ if (opcode >= __GLX_SINGLE_TABLE_SIZE) {
+ return BadRequest;
+ }
+
+ /*
+ ** Use the opcode to index into the procedure table.
+ */
+ proc = __glXSwapSingleTable[opcode];
+
+ /*
+ * Report upstream that we are
+ * dispatching a GLX operation.
+ */
+
+ nxagentGlxTrap = 1;
+
+ #ifdef TEST
+ fprintf(stderr, "__glXDispatch: Going to dispatch GLX operation [%d] for client [%d].\n",
+ opcode, client -> index);
+ #endif
+
+ result = (*proc)(cl, (GLbyte *) stuff);
+
+ nxagentGlxTrap = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "__glXDispatch: Dispatched GLX operation [%d] for client [%d].\n",
+ opcode, client -> index);
+ #endif
+
+ return result;
+}
+
+int __glXNoSuchSingleOpcode(__GLXclientState *cl, GLbyte *pc)
+{
+ return BadRequest;
+}
+
+void __glXNoSuchRenderOpcode(GLbyte *pc)
+{
+ return;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.X.original
new file mode 100644
index 000000000..fa1382983
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.X.original
@@ -0,0 +1,505 @@
+/* $XFree86: xc/programs/Xserver/GL/glx/glxext.c,v 1.9 2003/09/28 20:15:43 alanh Exp $
+** The contents of this file are subject to the GLX Public License Version 1.0
+** (the "License"). You may not use this file except in compliance with the
+** License. You may obtain a copy of the License at Silicon Graphics, Inc.,
+** attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA 94043
+** or at http://www.sgi.com/software/opensource/glx/license.html.
+**
+** Software distributed under the License is distributed on an "AS IS"
+** basis. ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY
+** IMPLIED WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR
+** PURPOSE OR OF NON- INFRINGEMENT. See the License for the specific
+** language governing rights and limitations under the License.
+**
+** The Original Software is GLX version 1.2 source code, released February,
+** 1999. The developer of the Original Software is Silicon Graphics, Inc.
+** Those portions of the Subject Software created by Silicon Graphics, Inc.
+** are Copyright (c) 1991-9 Silicon Graphics, Inc. All Rights Reserved.
+**
+*/
+
+#define NEED_REPLIES
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glxserver.h"
+#include <windowstr.h>
+#include <propertyst.h>
+#include <os.h>
+#include "g_disptab.h"
+#include "unpack.h"
+#include "glxutil.h"
+#include "glxext.h"
+#include "micmap.h"
+
+
+void GlxWrapInitVisuals(miInitVisualsProcPtr *);
+void GlxSetVisualConfigs(int nconfigs,
+ __GLXvisualConfig *configs, void **privates);
+
+static __GLXextensionInfo *__glXExt /* = &__glDDXExtensionInfo */;
+
+/*
+** Forward declarations.
+*/
+static int __glXSwapDispatch(ClientPtr);
+static int __glXDispatch(ClientPtr);
+
+/*
+** Called when the extension is reset.
+*/
+static void ResetExtension(ExtensionEntry* extEntry)
+{
+ __glXFlushContextCache();
+ (*__glXExt->resetExtension)();
+ __glXScreenReset();
+}
+
+/*
+** Initialize the per-client context storage.
+*/
+static void ResetClientState(int clientIndex)
+{
+ __GLXclientState *cl = __glXClients[clientIndex];
+
+ if (cl->returnBuf) __glXFree(cl->returnBuf);
+ if (cl->largeCmdBuf) __glXFree(cl->largeCmdBuf);
+ if (cl->currentContexts) __glXFree(cl->currentContexts);
+ __glXMemset(cl, 0, sizeof(__GLXclientState));
+ /*
+ ** By default, assume that the client supports
+ ** GLX major version 1 minor version 0 protocol.
+ */
+ cl->GLClientmajorVersion = 1;
+ cl->GLClientminorVersion = 0;
+ if (cl->GLClientextensions) __glXFree(cl->GLClientextensions);
+
+}
+
+/*
+** Reset state used to keep track of large (multi-request) commands.
+*/
+void __glXResetLargeCommandStatus(__GLXclientState *cl)
+{
+ cl->largeCmdBytesSoFar = 0;
+ cl->largeCmdBytesTotal = 0;
+ cl->largeCmdRequestsSoFar = 0;
+ cl->largeCmdRequestsTotal = 0;
+}
+
+/*
+** This procedure is called when the client who created the context goes
+** away OR when glXDestroyContext is called. In either case, all we do is
+** flag that the ID is no longer valid, and (maybe) free the context.
+** use.
+*/
+static int ContextGone(__GLXcontext* cx, XID id)
+{
+ cx->idExists = GL_FALSE;
+ if (!cx->isCurrent) {
+ __glXFreeContext(cx);
+ }
+
+ return True;
+}
+
+/*
+** Free a client's state.
+*/
+static int ClientGone(int clientIndex, XID id)
+{
+ __GLXcontext *cx;
+ __GLXclientState *cl = __glXClients[clientIndex];
+ int i;
+
+ if (cl) {
+ /*
+ ** Free all the contexts that are current for this client.
+ */
+ for (i=0; i < cl->numCurrentContexts; i++) {
+ cx = cl->currentContexts[i];
+ if (cx) {
+ __glXDeassociateContext(cx);
+ cx->isCurrent = GL_FALSE;
+ if (!cx->idExists) {
+ __glXFreeContext(cx);
+ }
+ }
+ }
+ /*
+ ** Re-initialize the client state structure. Don't free it because
+ ** we'll probably get another client with this index and use the struct
+ ** again. There is a maximum of MAXCLIENTS of these structures.
+ */
+ ResetClientState(clientIndex);
+ }
+
+ return True;
+}
+
+/*
+** Free a GLX Pixmap.
+*/
+static int PixmapGone(__GLXpixmap *pGlxPixmap, XID id)
+{
+ PixmapPtr pPixmap = (PixmapPtr) pGlxPixmap->pDraw;
+
+ pGlxPixmap->idExists = False;
+ if (!pGlxPixmap->refcnt) {
+ /*
+ ** The DestroyPixmap routine should decrement the refcount and free
+ ** only if it's zero.
+ */
+ (*pGlxPixmap->pScreen->DestroyPixmap)(pPixmap);
+ __glXFree(pGlxPixmap);
+ }
+
+ return True;
+}
+
+/*
+** Free a context.
+*/
+GLboolean __glXFreeContext(__GLXcontext *cx)
+{
+ if (cx->idExists || cx->isCurrent) return GL_FALSE;
+
+ if (!cx->isDirect) {
+ if ((*cx->gc->exports.destroyContext)((__GLcontext *)cx->gc) == GL_FALSE) {
+ return GL_FALSE;
+ }
+ }
+ if (cx->feedbackBuf) __glXFree(cx->feedbackBuf);
+ if (cx->selectBuf) __glXFree(cx->selectBuf);
+ __glXFree(cx);
+ if (cx == __glXLastContext) {
+ __glXFlushContextCache();
+ }
+
+ return GL_TRUE;
+}
+
+extern RESTYPE __glXSwapBarrierRes;
+
+static int SwapBarrierGone(int screen, XID drawable)
+{
+ if (__glXSwapBarrierFuncs &&
+ __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc != NULL) {
+ __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc(screen, drawable, 0);
+ }
+ FreeResourceByType(drawable, __glXSwapBarrierRes, FALSE);
+ return True;
+}
+
+/************************************************************************/
+
+/*
+** These routines can be used to check whether a particular GL command
+** has caused an error. Specifically, we use them to check whether a
+** given query has caused an error, in which case a zero-length data
+** reply is sent to the client.
+*/
+
+static GLboolean errorOccured = GL_FALSE;
+
+/*
+** The GL was will call this routine if an error occurs.
+*/
+void __glXErrorCallBack(__GLinterface *gc, GLenum code)
+{
+ errorOccured = GL_TRUE;
+}
+
+/*
+** Clear the error flag before calling the GL command.
+*/
+void __glXClearErrorOccured(void)
+{
+ errorOccured = GL_FALSE;
+}
+
+/*
+** Check if the GL command caused an error.
+*/
+GLboolean __glXErrorOccured(void)
+{
+ return errorOccured;
+}
+
+/************************************************************************/
+
+/*
+** Initialize the GLX extension.
+*/
+void GlxExtensionInit(void)
+{
+ ExtensionEntry *extEntry;
+ int i;
+
+ __glXContextRes = CreateNewResourceType((DeleteType)ContextGone);
+ __glXClientRes = CreateNewResourceType((DeleteType)ClientGone);
+ __glXPixmapRes = CreateNewResourceType((DeleteType)PixmapGone);
+
+ /*
+ ** Add extension to server extensions.
+ */
+ extEntry = AddExtension(GLX_EXTENSION_NAME, __GLX_NUMBER_EVENTS,
+ __GLX_NUMBER_ERRORS, __glXDispatch,
+ __glXSwapDispatch, ResetExtension,
+ StandardMinorOpcode);
+ if (!extEntry) {
+ FatalError("__glXExtensionInit: AddExtensions failed\n");
+ return;
+ }
+ if (!AddExtensionAlias(GLX_EXTENSION_ALIAS, extEntry)) {
+ ErrorF("__glXExtensionInit: AddExtensionAlias failed\n");
+ return;
+ }
+
+ __glXBadContext = extEntry->errorBase + GLXBadContext;
+ __glXBadContextState = extEntry->errorBase + GLXBadContextState;
+ __glXBadDrawable = extEntry->errorBase + GLXBadDrawable;
+ __glXBadPixmap = extEntry->errorBase + GLXBadPixmap;
+ __glXBadContextTag = extEntry->errorBase + GLXBadContextTag;
+ __glXBadCurrentWindow = extEntry->errorBase + GLXBadCurrentWindow;
+ __glXBadRenderRequest = extEntry->errorBase + GLXBadRenderRequest;
+ __glXBadLargeRequest = extEntry->errorBase + GLXBadLargeRequest;
+ __glXUnsupportedPrivateRequest = extEntry->errorBase +
+ GLXUnsupportedPrivateRequest;
+
+ __glXSwapBarrierRes = CreateNewResourceType((DeleteType)SwapBarrierGone);
+
+ /*
+ ** Initialize table of client state. There is never a client 0.
+ */
+ for (i=1; i <= MAXCLIENTS; i++) {
+ __glXClients[i] = 0;
+ }
+
+ /*
+ ** Initialize screen specific data.
+ */
+ __glXScreenInit(screenInfo.numScreens);
+}
+
+/************************************************************************/
+
+Bool __glXCoreType(void)
+{
+ return __glXExt->type;
+}
+
+/************************************************************************/
+
+void GlxSetVisualConfigs(int nconfigs,
+ __GLXvisualConfig *configs, void **privates)
+{
+ (*__glXExt->setVisualConfigs)(nconfigs, configs, privates);
+}
+
+static miInitVisualsProcPtr saveInitVisualsProc;
+
+Bool GlxInitVisuals(VisualPtr *visualp, DepthPtr *depthp,
+ int *nvisualp, int *ndepthp,
+ int *rootDepthp, VisualID *defaultVisp,
+ unsigned long sizes, int bitsPerRGB,
+ int preferredVis)
+{
+ Bool ret;
+
+ if (saveInitVisualsProc) {
+ ret = saveInitVisualsProc(visualp, depthp, nvisualp, ndepthp,
+ rootDepthp, defaultVisp, sizes, bitsPerRGB,
+ preferredVis);
+ if (!ret)
+ return False;
+ }
+ (*__glXExt->initVisuals)(visualp, depthp, nvisualp, ndepthp, rootDepthp,
+ defaultVisp, sizes, bitsPerRGB);
+ return True;
+}
+
+void
+GlxWrapInitVisuals(miInitVisualsProcPtr *initVisProc)
+{
+ saveInitVisualsProc = *initVisProc;
+ *initVisProc = GlxInitVisuals;
+ /* HACK: this shouldn't be done here but it's the earliest time */
+ __glXExt = __glXglDDXExtensionInfo(); /* from GLcore */
+}
+
+/************************************************************************/
+
+void __glXFlushContextCache(void)
+{
+ __glXLastContext = 0;
+}
+
+/*
+** Make a context the current one for the GL (in this implementation, there
+** is only one instance of the GL, and we use it to serve all GL clients by
+** switching it between different contexts). While we are at it, look up
+** a context by its tag and return its (__GLXcontext *).
+*/
+__GLXcontext *__glXForceCurrent(__GLXclientState *cl, GLXContextTag tag,
+ int *error)
+{
+ __GLXcontext *cx;
+
+ /*
+ ** See if the context tag is legal; it is managed by the extension,
+ ** so if it's invalid, we have an implementation error.
+ */
+ cx = (__GLXcontext *) __glXLookupContextByTag(cl, tag);
+ if (!cx) {
+ cl->client->errorValue = tag;
+ *error = __glXBadContextTag;
+ return 0;
+ }
+
+ if (!cx->isDirect) {
+ if (cx->drawPriv == NULL) {
+ /*
+ ** The drawable has vanished. It must be a window, because only
+ ** windows can be destroyed from under us; GLX pixmaps are
+ ** refcounted and don't go away until no one is using them.
+ */
+ *error = __glXBadCurrentWindow;
+ return 0;
+ }
+ }
+
+ if (cx == __glXLastContext) {
+ /* No need to re-bind */
+ return cx;
+ }
+
+ /* Make this context the current one for the GL. */
+ if (!cx->isDirect) {
+ if (!(*cx->gc->exports.forceCurrent)((__GLcontext *)cx->gc)) {
+ /* Bind failed, and set the error code. Bummer */
+ cl->client->errorValue = cx->id;
+ *error = __glXBadContextState;
+ return 0;
+ }
+ }
+ __glXLastContext = cx;
+ return cx;
+}
+
+/************************************************************************/
+
+/*
+** Top level dispatcher; all commands are executed from here down.
+*/
+static int __glXDispatch(ClientPtr client)
+{
+ REQUEST(xGLXSingleReq);
+ CARD8 opcode;
+ int (*proc)(__GLXclientState *cl, GLbyte *pc);
+ __GLXclientState *cl;
+
+ opcode = stuff->glxCode;
+ cl = __glXClients[client->index];
+ if (!cl) {
+ cl = (__GLXclientState *) __glXMalloc(sizeof(__GLXclientState));
+ __glXClients[client->index] = cl;
+ if (!cl) {
+ return BadAlloc;
+ }
+ __glXMemset(cl, 0, sizeof(__GLXclientState));
+ }
+
+ if (!cl->inUse) {
+ /*
+ ** This is first request from this client. Associate a resource
+ ** with the client so we will be notified when the client dies.
+ */
+ XID xid = FakeClientID(client->index);
+ if (!AddResource( xid, __glXClientRes, (pointer)(long)client->index)) {
+ return BadAlloc;
+ }
+ ResetClientState(client->index);
+ cl->inUse = GL_TRUE;
+ cl->client = client;
+ }
+
+ /*
+ ** Check for valid opcode.
+ */
+ if (opcode >= __GLX_SINGLE_TABLE_SIZE) {
+ return BadRequest;
+ }
+
+ /*
+ ** If we're expecting a glXRenderLarge request, this better be one.
+ */
+ if ((cl->largeCmdRequestsSoFar != 0) && (opcode != X_GLXRenderLarge)) {
+ client->errorValue = stuff->glxCode;
+ return __glXBadLargeRequest;
+ }
+
+ /*
+ ** Use the opcode to index into the procedure table.
+ */
+ proc = __glXSingleTable[opcode];
+ return (*proc)(cl, (GLbyte *) stuff);
+}
+
+static int __glXSwapDispatch(ClientPtr client)
+{
+ REQUEST(xGLXSingleReq);
+ CARD8 opcode;
+ int (*proc)(__GLXclientState *cl, GLbyte *pc);
+ __GLXclientState *cl;
+
+ opcode = stuff->glxCode;
+ cl = __glXClients[client->index];
+ if (!cl) {
+ cl = (__GLXclientState *) __glXMalloc(sizeof(__GLXclientState));
+ __glXClients[client->index] = cl;
+ if (!cl) {
+ return BadAlloc;
+ }
+ __glXMemset(cl, 0, sizeof(__GLXclientState));
+ }
+
+ if (!cl->inUse) {
+ /*
+ ** This is first request from this client. Associate a resource
+ ** with the client so we will be notified when the client dies.
+ */
+ XID xid = FakeClientID(client->index);
+ if (!AddResource( xid, __glXClientRes, (pointer)(long)client->index)) {
+ return BadAlloc;
+ }
+ ResetClientState(client->index);
+ cl->inUse = GL_TRUE;
+ cl->client = client;
+ }
+
+ /*
+ ** Check for valid opcode.
+ */
+ if (opcode >= __GLX_SINGLE_TABLE_SIZE) {
+ return BadRequest;
+ }
+
+ /*
+ ** Use the opcode to index into the procedure table.
+ */
+ proc = __glXSwapSingleTable[opcode];
+ return (*proc)(cl, (GLbyte *) stuff);
+}
+
+int __glXNoSuchSingleOpcode(__GLXclientState *cl, GLbyte *pc)
+{
+ return BadRequest;
+}
+
+void __glXNoSuchRenderOpcode(GLbyte *pc)
+{
+ return;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
new file mode 100644
index 000000000..06dabddaa
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
@@ -0,0 +1,566 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/glyph.c,v 1.5 2001/01/30 07:01:22 keithp Exp $
+ *
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+
+#ifdef NXAGENT_SERVER
+
+#include "NXpicturestr.h"
+#include "NXglyphstr.h"
+#include "Render.h"
+
+#define PANIC
+#define WARNING
+#undef DEBUG
+#undef TEST
+
+#endif
+
+/*
+ * From Knuth -- a good choice for hash/rehash values is p, p-2 where
+ * p and p-2 are both prime. These tables are sized to have an extra 10%
+ * free to avoid exponential performance degradation as the hash table fills
+ */
+static GlyphHashSetRec glyphHashSets[] = {
+ { 32, 43, 41 },
+ { 64, 73, 71 },
+ { 128, 151, 149 },
+ { 256, 283, 281 },
+ { 512, 571, 569 },
+ { 1024, 1153, 1151 },
+ { 2048, 2269, 2267 },
+ { 4096, 4519, 4517 },
+ { 8192, 9013, 9011 },
+ { 16384, 18043, 18041 },
+ { 32768, 36109, 36107 },
+ { 65536, 72091, 72089 },
+ { 131072, 144409, 144407 },
+ { 262144, 288361, 288359 },
+ { 524288, 576883, 576881 },
+ { 1048576, 1153459, 1153457 },
+ { 2097152, 2307163, 2307161 },
+ { 4194304, 4613893, 4613891 },
+ { 8388608, 9227641, 9227639 },
+ { 16777216, 18455029, 18455027 },
+ { 33554432, 36911011, 36911009 },
+ { 67108864, 73819861, 73819859 },
+ { 134217728, 147639589, 147639587 },
+ { 268435456, 295279081, 295279079 },
+ { 536870912, 590559793, 590559791 }
+};
+
+#define NGLYPHHASHSETS (sizeof(glyphHashSets)/sizeof(glyphHashSets[0]))
+
+const CARD8 glyphDepths[GlyphFormatNum] = { 1, 4, 8, 16, 32 };
+
+GlyphHashRec globalGlyphs[GlyphFormatNum];
+
+GlyphHashSetPtr
+FindGlyphHashSet (CARD32 filled)
+{
+ int i;
+
+ for (i = 0; i < NGLYPHHASHSETS; i++)
+ if (glyphHashSets[i].entries >= filled)
+ return &glyphHashSets[i];
+ return 0;
+}
+
+static int _GlyphSetPrivateAllocateIndex = 0;
+
+int
+AllocateGlyphSetPrivateIndex (void)
+{
+ return _GlyphSetPrivateAllocateIndex++;
+}
+
+void
+ResetGlyphSetPrivateIndex (void)
+{
+ _GlyphSetPrivateAllocateIndex = 0;
+}
+
+Bool
+_GlyphSetSetNewPrivate (GlyphSetPtr glyphSet, int n, pointer ptr)
+{
+ pointer *new;
+
+ if (n > glyphSet->maxPrivate) {
+ if (glyphSet->devPrivates &&
+ glyphSet->devPrivates != (pointer)(&glyphSet[1])) {
+ new = (pointer *) xrealloc (glyphSet->devPrivates,
+ (n + 1) * sizeof (pointer));
+ if (!new)
+ return FALSE;
+ } else {
+ new = (pointer *) xalloc ((n + 1) * sizeof (pointer));
+ if (!new)
+ return FALSE;
+ if (glyphSet->devPrivates)
+ memcpy (new,
+ glyphSet->devPrivates,
+ (glyphSet->maxPrivate + 1) * sizeof (pointer));
+ }
+ glyphSet->devPrivates = new;
+ /* Zero out new, uninitialize privates */
+ while (++glyphSet->maxPrivate < n)
+ glyphSet->devPrivates[glyphSet->maxPrivate] = (pointer)0;
+ }
+ glyphSet->devPrivates[n] = ptr;
+ return TRUE;
+}
+
+Bool
+GlyphInit (ScreenPtr pScreen)
+{
+ return TRUE;
+}
+
+GlyphRefPtr
+FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare)
+{
+ CARD32 elt, step, s;
+ GlyphPtr glyph;
+ GlyphRefPtr table, gr, del;
+ CARD32 tableSize = hash->hashSet->size;
+
+ table = hash->table;
+ elt = signature % tableSize;
+ step = 0;
+ del = 0;
+ for (;;)
+ {
+ gr = &table[elt];
+ s = gr->signature;
+ glyph = gr->glyph;
+ if (!glyph)
+ {
+ if (del)
+ gr = del;
+ break;
+ }
+ if (glyph == DeletedGlyph)
+ {
+ if (!del)
+ del = gr;
+ else if (gr == del)
+ break;
+ }
+ else if (s == signature &&
+ (!match ||
+ memcmp (&compare->info, &glyph->info, compare->size) == 0))
+ {
+ break;
+ }
+ if (!step)
+ {
+ step = signature % hash->hashSet->rehash;
+ if (!step)
+ step = 1;
+ }
+ elt += step;
+ if (elt >= tableSize)
+ elt -= tableSize;
+ }
+ return gr;
+}
+
+CARD32
+HashGlyph (GlyphPtr glyph)
+{
+ CARD32 *bits = (CARD32 *) &(glyph->info);
+ CARD32 hash;
+ int n = glyph->size / sizeof (CARD32);
+
+ hash = 0;
+ while (n--)
+ hash ^= *bits++;
+ return hash;
+}
+
+#ifdef CHECK_DUPLICATES
+void
+DuplicateRef (GlyphPtr glyph, char *where)
+{
+ ErrorF ("Duplicate Glyph 0x%x from %s\n", glyph, where);
+}
+
+void
+CheckDuplicates (GlyphHashPtr hash, char *where)
+{
+ GlyphPtr g;
+ int i, j;
+
+ for (i = 0; i < hash->hashSet->size; i++)
+ {
+ g = hash->table[i].glyph;
+ if (!g || g == DeletedGlyph)
+ continue;
+ for (j = i + 1; j < hash->hashSet->size; j++)
+ if (hash->table[j].glyph == g)
+ DuplicateRef (g, where);
+ }
+}
+#else
+#define CheckDuplicates(a,b)
+#define DuplicateRef(a,b)
+#endif
+
+void
+FreeGlyph (GlyphPtr glyph, int format)
+{
+ CheckDuplicates (&globalGlyphs[format], "FreeGlyph");
+ if (--glyph->refcnt == 0)
+ {
+ GlyphRefPtr gr;
+ int i;
+ int first;
+
+ first = -1;
+ for (i = 0; i < globalGlyphs[format].hashSet->size; i++)
+ if (globalGlyphs[format].table[i].glyph == glyph)
+ {
+ if (first != -1)
+ DuplicateRef (glyph, "FreeGlyph check");
+ first = i;
+ }
+
+ gr = FindGlyphRef (&globalGlyphs[format],
+ HashGlyph (glyph), TRUE, glyph);
+ if (gr - globalGlyphs[format].table != first)
+ DuplicateRef (glyph, "Found wrong one");
+ if (gr->glyph && gr->glyph != DeletedGlyph)
+ {
+ gr->glyph = DeletedGlyph;
+ gr->signature = 0;
+ globalGlyphs[format].tableEntries--;
+ }
+ xfree (glyph);
+ }
+}
+
+void
+AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id)
+{
+ GlyphRefPtr gr;
+ CARD32 hash;
+
+ CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph top global");
+ /* Locate existing matching glyph */
+ hash = HashGlyph (glyph);
+ gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], hash, TRUE, glyph);
+ if (gr->glyph && gr->glyph != DeletedGlyph)
+ {
+ xfree (glyph);
+ glyph = gr->glyph;
+ }
+ else
+ {
+ gr->glyph = glyph;
+ gr->signature = hash;
+ globalGlyphs[glyphSet->fdepth].tableEntries++;
+ }
+
+ /* Insert/replace glyphset value */
+ gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
+ ++glyph->refcnt;
+ if (gr->glyph && gr->glyph != DeletedGlyph)
+ FreeGlyph (gr->glyph, glyphSet->fdepth);
+ else
+ glyphSet->hash.tableEntries++;
+ gr->glyph = glyph;
+ gr->signature = id;
+
+ #ifdef NXAGENT_SERVER
+
+ gr -> corruptedGlyph = 1;
+
+ #endif
+
+ CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph bottom");
+}
+
+Bool
+DeleteGlyph (GlyphSetPtr glyphSet, Glyph id)
+{
+ GlyphRefPtr gr;
+ GlyphPtr glyph;
+
+ gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
+ glyph = gr->glyph;
+ if (glyph && glyph != DeletedGlyph)
+ {
+ gr->glyph = DeletedGlyph;
+ glyphSet->hash.tableEntries--;
+ FreeGlyph (glyph, glyphSet->fdepth);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+#ifdef NXAGENT_SERVER
+
+GlyphPtr FindGlyph (GlyphSetPtr glyphSet, Glyph id)
+{
+ GlyphRefPtr gr;
+ GlyphPtr glyph;
+
+ gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
+ glyph = gr -> glyph;
+
+ if (glyph == DeletedGlyph)
+ {
+ glyph = 0;
+ }
+ else if (gr -> corruptedGlyph == 1)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "FindGlyphRef: Going to synchronize the glyph [%p] for glyphset [%p].\n",
+ (void *) glyph, (void *) glyphSet);
+ #endif
+
+ nxagentAddGlyphs(glyphSet, &id, &(glyph -> info), 1,
+ (CARD8*)(glyph + 1), glyph -> size - sizeof(xGlyphInfo));
+ }
+
+ return glyph;
+}
+
+#else
+
+GlyphPtr
+FindGlyph (GlyphSetPtr glyphSet, Glyph id)
+{
+ GlyphPtr glyph;
+
+ glyph = FindGlyphRef (&glyphSet->hash, id, FALSE, 0)->glyph;
+ if (glyph == DeletedGlyph)
+ glyph = 0;
+ return glyph;
+}
+
+#endif
+
+GlyphPtr
+AllocateGlyph (xGlyphInfo *gi, int fdepth)
+{
+ int size;
+ GlyphPtr glyph;
+
+ size = gi->height * PixmapBytePad (gi->width, glyphDepths[fdepth]);
+ glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec));
+ if (!glyph)
+ return 0;
+ glyph->refcnt = 0;
+ glyph->size = size + sizeof (xGlyphInfo);
+ glyph->info = *gi;
+ return glyph;
+}
+
+Bool
+AllocateGlyphHash (GlyphHashPtr hash, GlyphHashSetPtr hashSet)
+{
+ hash->table = (GlyphRefPtr) xalloc (hashSet->size * sizeof (GlyphRefRec));
+ if (!hash->table)
+ return FALSE;
+ memset (hash->table, 0, hashSet->size * sizeof (GlyphRefRec));
+ hash->hashSet = hashSet;
+ hash->tableEntries = 0;
+ return TRUE;
+}
+
+Bool
+ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global)
+{
+ CARD32 tableEntries;
+ GlyphHashSetPtr hashSet;
+ GlyphHashRec newHash;
+ GlyphRefPtr gr;
+ GlyphPtr glyph;
+ int i;
+ int oldSize;
+ CARD32 s;
+
+ #ifdef NXAGENT_SERVER
+
+ CARD32 c;
+
+ #endif
+
+ tableEntries = hash->tableEntries + change;
+ hashSet = FindGlyphHashSet (tableEntries);
+ if (hashSet == hash->hashSet)
+ return TRUE;
+ if (global)
+ CheckDuplicates (hash, "ResizeGlyphHash top");
+ if (!AllocateGlyphHash (&newHash, hashSet))
+ return FALSE;
+ if (hash->table)
+ {
+ oldSize = hash->hashSet->size;
+ for (i = 0; i < oldSize; i++)
+ {
+ glyph = hash->table[i].glyph;
+ if (glyph && glyph != DeletedGlyph)
+ {
+ s = hash->table[i].signature;
+
+ #ifdef NXAGENT_SERVER
+
+ c = hash->table[i].corruptedGlyph;
+
+ #endif
+
+ gr = FindGlyphRef (&newHash, s, global, glyph);
+ gr->signature = s;
+ gr->glyph = glyph;
+
+ #ifdef NXAGENT_SERVER
+
+ gr -> corruptedGlyph = c;
+
+ #endif
+
+ ++newHash.tableEntries;
+ }
+ }
+ xfree (hash->table);
+ }
+ *hash = newHash;
+ if (global)
+ CheckDuplicates (hash, "ResizeGlyphHash bottom");
+ return TRUE;
+}
+
+Bool
+ResizeGlyphSet (GlyphSetPtr glyphSet, CARD32 change)
+{
+ return (ResizeGlyphHash (&glyphSet->hash, change, FALSE) &&
+ ResizeGlyphHash (&globalGlyphs[glyphSet->fdepth], change, TRUE));
+}
+
+GlyphSetPtr
+AllocateGlyphSet (int fdepth, PictFormatPtr format)
+{
+ GlyphSetPtr glyphSet;
+ int size;
+
+ if (!globalGlyphs[fdepth].hashSet)
+ {
+ if (!AllocateGlyphHash (&globalGlyphs[fdepth], &glyphHashSets[0]))
+ return FALSE;
+ }
+
+ size = (sizeof (GlyphSetRec) +
+ (sizeof (pointer) * _GlyphSetPrivateAllocateIndex));
+ glyphSet = xalloc (size);
+ if (!glyphSet)
+ return FALSE;
+ bzero((char *)glyphSet, size);
+ glyphSet->maxPrivate = _GlyphSetPrivateAllocateIndex - 1;
+ if (_GlyphSetPrivateAllocateIndex)
+ glyphSet->devPrivates = (pointer)(&glyphSet[1]);
+
+ if (!AllocateGlyphHash (&glyphSet->hash, &glyphHashSets[0]))
+ {
+ xfree (glyphSet);
+ return FALSE;
+ }
+ glyphSet->refcnt = 1;
+ glyphSet->fdepth = fdepth;
+ glyphSet->format = format;
+ return glyphSet;
+}
+
+int
+FreeGlyphSet (pointer value,
+ XID gid)
+{
+ GlyphSetPtr glyphSet = (GlyphSetPtr) value;
+
+ if (--glyphSet->refcnt == 0)
+ {
+ CARD32 i, tableSize = glyphSet->hash.hashSet->size;
+ GlyphRefPtr table = glyphSet->hash.table;
+ GlyphPtr glyph;
+
+ for (i = 0; i < tableSize; i++)
+ {
+ glyph = table[i].glyph;
+ if (glyph && glyph != DeletedGlyph)
+ FreeGlyph (glyph, glyphSet->fdepth);
+ }
+ if (!globalGlyphs[glyphSet->fdepth].tableEntries)
+ {
+ xfree (globalGlyphs[glyphSet->fdepth].table);
+ globalGlyphs[glyphSet->fdepth].table = 0;
+ globalGlyphs[glyphSet->fdepth].hashSet = 0;
+ }
+ else
+ ResizeGlyphHash (&globalGlyphs[glyphSet->fdepth], 0, TRUE);
+ xfree (table);
+
+ if (glyphSet->devPrivates &&
+ glyphSet->devPrivates != (pointer)(&glyphSet[1]))
+ xfree(glyphSet->devPrivates);
+
+ xfree (glyphSet);
+ }
+ return Success;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original
new file mode 100644
index 000000000..06dabddaa
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original
@@ -0,0 +1,566 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/glyph.c,v 1.5 2001/01/30 07:01:22 keithp Exp $
+ *
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+
+#ifdef NXAGENT_SERVER
+
+#include "NXpicturestr.h"
+#include "NXglyphstr.h"
+#include "Render.h"
+
+#define PANIC
+#define WARNING
+#undef DEBUG
+#undef TEST
+
+#endif
+
+/*
+ * From Knuth -- a good choice for hash/rehash values is p, p-2 where
+ * p and p-2 are both prime. These tables are sized to have an extra 10%
+ * free to avoid exponential performance degradation as the hash table fills
+ */
+static GlyphHashSetRec glyphHashSets[] = {
+ { 32, 43, 41 },
+ { 64, 73, 71 },
+ { 128, 151, 149 },
+ { 256, 283, 281 },
+ { 512, 571, 569 },
+ { 1024, 1153, 1151 },
+ { 2048, 2269, 2267 },
+ { 4096, 4519, 4517 },
+ { 8192, 9013, 9011 },
+ { 16384, 18043, 18041 },
+ { 32768, 36109, 36107 },
+ { 65536, 72091, 72089 },
+ { 131072, 144409, 144407 },
+ { 262144, 288361, 288359 },
+ { 524288, 576883, 576881 },
+ { 1048576, 1153459, 1153457 },
+ { 2097152, 2307163, 2307161 },
+ { 4194304, 4613893, 4613891 },
+ { 8388608, 9227641, 9227639 },
+ { 16777216, 18455029, 18455027 },
+ { 33554432, 36911011, 36911009 },
+ { 67108864, 73819861, 73819859 },
+ { 134217728, 147639589, 147639587 },
+ { 268435456, 295279081, 295279079 },
+ { 536870912, 590559793, 590559791 }
+};
+
+#define NGLYPHHASHSETS (sizeof(glyphHashSets)/sizeof(glyphHashSets[0]))
+
+const CARD8 glyphDepths[GlyphFormatNum] = { 1, 4, 8, 16, 32 };
+
+GlyphHashRec globalGlyphs[GlyphFormatNum];
+
+GlyphHashSetPtr
+FindGlyphHashSet (CARD32 filled)
+{
+ int i;
+
+ for (i = 0; i < NGLYPHHASHSETS; i++)
+ if (glyphHashSets[i].entries >= filled)
+ return &glyphHashSets[i];
+ return 0;
+}
+
+static int _GlyphSetPrivateAllocateIndex = 0;
+
+int
+AllocateGlyphSetPrivateIndex (void)
+{
+ return _GlyphSetPrivateAllocateIndex++;
+}
+
+void
+ResetGlyphSetPrivateIndex (void)
+{
+ _GlyphSetPrivateAllocateIndex = 0;
+}
+
+Bool
+_GlyphSetSetNewPrivate (GlyphSetPtr glyphSet, int n, pointer ptr)
+{
+ pointer *new;
+
+ if (n > glyphSet->maxPrivate) {
+ if (glyphSet->devPrivates &&
+ glyphSet->devPrivates != (pointer)(&glyphSet[1])) {
+ new = (pointer *) xrealloc (glyphSet->devPrivates,
+ (n + 1) * sizeof (pointer));
+ if (!new)
+ return FALSE;
+ } else {
+ new = (pointer *) xalloc ((n + 1) * sizeof (pointer));
+ if (!new)
+ return FALSE;
+ if (glyphSet->devPrivates)
+ memcpy (new,
+ glyphSet->devPrivates,
+ (glyphSet->maxPrivate + 1) * sizeof (pointer));
+ }
+ glyphSet->devPrivates = new;
+ /* Zero out new, uninitialize privates */
+ while (++glyphSet->maxPrivate < n)
+ glyphSet->devPrivates[glyphSet->maxPrivate] = (pointer)0;
+ }
+ glyphSet->devPrivates[n] = ptr;
+ return TRUE;
+}
+
+Bool
+GlyphInit (ScreenPtr pScreen)
+{
+ return TRUE;
+}
+
+GlyphRefPtr
+FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare)
+{
+ CARD32 elt, step, s;
+ GlyphPtr glyph;
+ GlyphRefPtr table, gr, del;
+ CARD32 tableSize = hash->hashSet->size;
+
+ table = hash->table;
+ elt = signature % tableSize;
+ step = 0;
+ del = 0;
+ for (;;)
+ {
+ gr = &table[elt];
+ s = gr->signature;
+ glyph = gr->glyph;
+ if (!glyph)
+ {
+ if (del)
+ gr = del;
+ break;
+ }
+ if (glyph == DeletedGlyph)
+ {
+ if (!del)
+ del = gr;
+ else if (gr == del)
+ break;
+ }
+ else if (s == signature &&
+ (!match ||
+ memcmp (&compare->info, &glyph->info, compare->size) == 0))
+ {
+ break;
+ }
+ if (!step)
+ {
+ step = signature % hash->hashSet->rehash;
+ if (!step)
+ step = 1;
+ }
+ elt += step;
+ if (elt >= tableSize)
+ elt -= tableSize;
+ }
+ return gr;
+}
+
+CARD32
+HashGlyph (GlyphPtr glyph)
+{
+ CARD32 *bits = (CARD32 *) &(glyph->info);
+ CARD32 hash;
+ int n = glyph->size / sizeof (CARD32);
+
+ hash = 0;
+ while (n--)
+ hash ^= *bits++;
+ return hash;
+}
+
+#ifdef CHECK_DUPLICATES
+void
+DuplicateRef (GlyphPtr glyph, char *where)
+{
+ ErrorF ("Duplicate Glyph 0x%x from %s\n", glyph, where);
+}
+
+void
+CheckDuplicates (GlyphHashPtr hash, char *where)
+{
+ GlyphPtr g;
+ int i, j;
+
+ for (i = 0; i < hash->hashSet->size; i++)
+ {
+ g = hash->table[i].glyph;
+ if (!g || g == DeletedGlyph)
+ continue;
+ for (j = i + 1; j < hash->hashSet->size; j++)
+ if (hash->table[j].glyph == g)
+ DuplicateRef (g, where);
+ }
+}
+#else
+#define CheckDuplicates(a,b)
+#define DuplicateRef(a,b)
+#endif
+
+void
+FreeGlyph (GlyphPtr glyph, int format)
+{
+ CheckDuplicates (&globalGlyphs[format], "FreeGlyph");
+ if (--glyph->refcnt == 0)
+ {
+ GlyphRefPtr gr;
+ int i;
+ int first;
+
+ first = -1;
+ for (i = 0; i < globalGlyphs[format].hashSet->size; i++)
+ if (globalGlyphs[format].table[i].glyph == glyph)
+ {
+ if (first != -1)
+ DuplicateRef (glyph, "FreeGlyph check");
+ first = i;
+ }
+
+ gr = FindGlyphRef (&globalGlyphs[format],
+ HashGlyph (glyph), TRUE, glyph);
+ if (gr - globalGlyphs[format].table != first)
+ DuplicateRef (glyph, "Found wrong one");
+ if (gr->glyph && gr->glyph != DeletedGlyph)
+ {
+ gr->glyph = DeletedGlyph;
+ gr->signature = 0;
+ globalGlyphs[format].tableEntries--;
+ }
+ xfree (glyph);
+ }
+}
+
+void
+AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id)
+{
+ GlyphRefPtr gr;
+ CARD32 hash;
+
+ CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph top global");
+ /* Locate existing matching glyph */
+ hash = HashGlyph (glyph);
+ gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], hash, TRUE, glyph);
+ if (gr->glyph && gr->glyph != DeletedGlyph)
+ {
+ xfree (glyph);
+ glyph = gr->glyph;
+ }
+ else
+ {
+ gr->glyph = glyph;
+ gr->signature = hash;
+ globalGlyphs[glyphSet->fdepth].tableEntries++;
+ }
+
+ /* Insert/replace glyphset value */
+ gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
+ ++glyph->refcnt;
+ if (gr->glyph && gr->glyph != DeletedGlyph)
+ FreeGlyph (gr->glyph, glyphSet->fdepth);
+ else
+ glyphSet->hash.tableEntries++;
+ gr->glyph = glyph;
+ gr->signature = id;
+
+ #ifdef NXAGENT_SERVER
+
+ gr -> corruptedGlyph = 1;
+
+ #endif
+
+ CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph bottom");
+}
+
+Bool
+DeleteGlyph (GlyphSetPtr glyphSet, Glyph id)
+{
+ GlyphRefPtr gr;
+ GlyphPtr glyph;
+
+ gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
+ glyph = gr->glyph;
+ if (glyph && glyph != DeletedGlyph)
+ {
+ gr->glyph = DeletedGlyph;
+ glyphSet->hash.tableEntries--;
+ FreeGlyph (glyph, glyphSet->fdepth);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+#ifdef NXAGENT_SERVER
+
+GlyphPtr FindGlyph (GlyphSetPtr glyphSet, Glyph id)
+{
+ GlyphRefPtr gr;
+ GlyphPtr glyph;
+
+ gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
+ glyph = gr -> glyph;
+
+ if (glyph == DeletedGlyph)
+ {
+ glyph = 0;
+ }
+ else if (gr -> corruptedGlyph == 1)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "FindGlyphRef: Going to synchronize the glyph [%p] for glyphset [%p].\n",
+ (void *) glyph, (void *) glyphSet);
+ #endif
+
+ nxagentAddGlyphs(glyphSet, &id, &(glyph -> info), 1,
+ (CARD8*)(glyph + 1), glyph -> size - sizeof(xGlyphInfo));
+ }
+
+ return glyph;
+}
+
+#else
+
+GlyphPtr
+FindGlyph (GlyphSetPtr glyphSet, Glyph id)
+{
+ GlyphPtr glyph;
+
+ glyph = FindGlyphRef (&glyphSet->hash, id, FALSE, 0)->glyph;
+ if (glyph == DeletedGlyph)
+ glyph = 0;
+ return glyph;
+}
+
+#endif
+
+GlyphPtr
+AllocateGlyph (xGlyphInfo *gi, int fdepth)
+{
+ int size;
+ GlyphPtr glyph;
+
+ size = gi->height * PixmapBytePad (gi->width, glyphDepths[fdepth]);
+ glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec));
+ if (!glyph)
+ return 0;
+ glyph->refcnt = 0;
+ glyph->size = size + sizeof (xGlyphInfo);
+ glyph->info = *gi;
+ return glyph;
+}
+
+Bool
+AllocateGlyphHash (GlyphHashPtr hash, GlyphHashSetPtr hashSet)
+{
+ hash->table = (GlyphRefPtr) xalloc (hashSet->size * sizeof (GlyphRefRec));
+ if (!hash->table)
+ return FALSE;
+ memset (hash->table, 0, hashSet->size * sizeof (GlyphRefRec));
+ hash->hashSet = hashSet;
+ hash->tableEntries = 0;
+ return TRUE;
+}
+
+Bool
+ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global)
+{
+ CARD32 tableEntries;
+ GlyphHashSetPtr hashSet;
+ GlyphHashRec newHash;
+ GlyphRefPtr gr;
+ GlyphPtr glyph;
+ int i;
+ int oldSize;
+ CARD32 s;
+
+ #ifdef NXAGENT_SERVER
+
+ CARD32 c;
+
+ #endif
+
+ tableEntries = hash->tableEntries + change;
+ hashSet = FindGlyphHashSet (tableEntries);
+ if (hashSet == hash->hashSet)
+ return TRUE;
+ if (global)
+ CheckDuplicates (hash, "ResizeGlyphHash top");
+ if (!AllocateGlyphHash (&newHash, hashSet))
+ return FALSE;
+ if (hash->table)
+ {
+ oldSize = hash->hashSet->size;
+ for (i = 0; i < oldSize; i++)
+ {
+ glyph = hash->table[i].glyph;
+ if (glyph && glyph != DeletedGlyph)
+ {
+ s = hash->table[i].signature;
+
+ #ifdef NXAGENT_SERVER
+
+ c = hash->table[i].corruptedGlyph;
+
+ #endif
+
+ gr = FindGlyphRef (&newHash, s, global, glyph);
+ gr->signature = s;
+ gr->glyph = glyph;
+
+ #ifdef NXAGENT_SERVER
+
+ gr -> corruptedGlyph = c;
+
+ #endif
+
+ ++newHash.tableEntries;
+ }
+ }
+ xfree (hash->table);
+ }
+ *hash = newHash;
+ if (global)
+ CheckDuplicates (hash, "ResizeGlyphHash bottom");
+ return TRUE;
+}
+
+Bool
+ResizeGlyphSet (GlyphSetPtr glyphSet, CARD32 change)
+{
+ return (ResizeGlyphHash (&glyphSet->hash, change, FALSE) &&
+ ResizeGlyphHash (&globalGlyphs[glyphSet->fdepth], change, TRUE));
+}
+
+GlyphSetPtr
+AllocateGlyphSet (int fdepth, PictFormatPtr format)
+{
+ GlyphSetPtr glyphSet;
+ int size;
+
+ if (!globalGlyphs[fdepth].hashSet)
+ {
+ if (!AllocateGlyphHash (&globalGlyphs[fdepth], &glyphHashSets[0]))
+ return FALSE;
+ }
+
+ size = (sizeof (GlyphSetRec) +
+ (sizeof (pointer) * _GlyphSetPrivateAllocateIndex));
+ glyphSet = xalloc (size);
+ if (!glyphSet)
+ return FALSE;
+ bzero((char *)glyphSet, size);
+ glyphSet->maxPrivate = _GlyphSetPrivateAllocateIndex - 1;
+ if (_GlyphSetPrivateAllocateIndex)
+ glyphSet->devPrivates = (pointer)(&glyphSet[1]);
+
+ if (!AllocateGlyphHash (&glyphSet->hash, &glyphHashSets[0]))
+ {
+ xfree (glyphSet);
+ return FALSE;
+ }
+ glyphSet->refcnt = 1;
+ glyphSet->fdepth = fdepth;
+ glyphSet->format = format;
+ return glyphSet;
+}
+
+int
+FreeGlyphSet (pointer value,
+ XID gid)
+{
+ GlyphSetPtr glyphSet = (GlyphSetPtr) value;
+
+ if (--glyphSet->refcnt == 0)
+ {
+ CARD32 i, tableSize = glyphSet->hash.hashSet->size;
+ GlyphRefPtr table = glyphSet->hash.table;
+ GlyphPtr glyph;
+
+ for (i = 0; i < tableSize; i++)
+ {
+ glyph = table[i].glyph;
+ if (glyph && glyph != DeletedGlyph)
+ FreeGlyph (glyph, glyphSet->fdepth);
+ }
+ if (!globalGlyphs[glyphSet->fdepth].tableEntries)
+ {
+ xfree (globalGlyphs[glyphSet->fdepth].table);
+ globalGlyphs[glyphSet->fdepth].table = 0;
+ globalGlyphs[glyphSet->fdepth].hashSet = 0;
+ }
+ else
+ ResizeGlyphHash (&globalGlyphs[glyphSet->fdepth], 0, TRUE);
+ xfree (table);
+
+ if (glyphSet->devPrivates &&
+ glyphSet->devPrivates != (pointer)(&glyphSet[1]))
+ xfree(glyphSet->devPrivates);
+
+ xfree (glyphSet);
+ }
+ return Success;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.X.original
new file mode 100644
index 000000000..45c5dd975
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.X.original
@@ -0,0 +1,478 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/glyph.c,v 1.5 2001/01/30 07:01:22 keithp Exp $
+ *
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+#include "picturestr.h"
+#include "glyphstr.h"
+
+/*
+ * From Knuth -- a good choice for hash/rehash values is p, p-2 where
+ * p and p-2 are both prime. These tables are sized to have an extra 10%
+ * free to avoid exponential performance degradation as the hash table fills
+ */
+static GlyphHashSetRec glyphHashSets[] = {
+ { 32, 43, 41 },
+ { 64, 73, 71 },
+ { 128, 151, 149 },
+ { 256, 283, 281 },
+ { 512, 571, 569 },
+ { 1024, 1153, 1151 },
+ { 2048, 2269, 2267 },
+ { 4096, 4519, 4517 },
+ { 8192, 9013, 9011 },
+ { 16384, 18043, 18041 },
+ { 32768, 36109, 36107 },
+ { 65536, 72091, 72089 },
+ { 131072, 144409, 144407 },
+ { 262144, 288361, 288359 },
+ { 524288, 576883, 576881 },
+ { 1048576, 1153459, 1153457 },
+ { 2097152, 2307163, 2307161 },
+ { 4194304, 4613893, 4613891 },
+ { 8388608, 9227641, 9227639 },
+ { 16777216, 18455029, 18455027 },
+ { 33554432, 36911011, 36911009 },
+ { 67108864, 73819861, 73819859 },
+ { 134217728, 147639589, 147639587 },
+ { 268435456, 295279081, 295279079 },
+ { 536870912, 590559793, 590559791 }
+};
+
+#define NGLYPHHASHSETS (sizeof(glyphHashSets)/sizeof(glyphHashSets[0]))
+
+const CARD8 glyphDepths[GlyphFormatNum] = { 1, 4, 8, 16, 32 };
+
+GlyphHashRec globalGlyphs[GlyphFormatNum];
+
+GlyphHashSetPtr
+FindGlyphHashSet (CARD32 filled)
+{
+ int i;
+
+ for (i = 0; i < NGLYPHHASHSETS; i++)
+ if (glyphHashSets[i].entries >= filled)
+ return &glyphHashSets[i];
+ return 0;
+}
+
+static int _GlyphSetPrivateAllocateIndex = 0;
+
+int
+AllocateGlyphSetPrivateIndex (void)
+{
+ return _GlyphSetPrivateAllocateIndex++;
+}
+
+void
+ResetGlyphSetPrivateIndex (void)
+{
+ _GlyphSetPrivateAllocateIndex = 0;
+}
+
+Bool
+_GlyphSetSetNewPrivate (GlyphSetPtr glyphSet, int n, pointer ptr)
+{
+ pointer *new;
+
+ if (n > glyphSet->maxPrivate) {
+ if (glyphSet->devPrivates &&
+ glyphSet->devPrivates != (pointer)(&glyphSet[1])) {
+ new = (pointer *) xrealloc (glyphSet->devPrivates,
+ (n + 1) * sizeof (pointer));
+ if (!new)
+ return FALSE;
+ } else {
+ new = (pointer *) xalloc ((n + 1) * sizeof (pointer));
+ if (!new)
+ return FALSE;
+ if (glyphSet->devPrivates)
+ memcpy (new,
+ glyphSet->devPrivates,
+ (glyphSet->maxPrivate + 1) * sizeof (pointer));
+ }
+ glyphSet->devPrivates = new;
+ /* Zero out new, uninitialize privates */
+ while (++glyphSet->maxPrivate < n)
+ glyphSet->devPrivates[glyphSet->maxPrivate] = (pointer)0;
+ }
+ glyphSet->devPrivates[n] = ptr;
+ return TRUE;
+}
+
+Bool
+GlyphInit (ScreenPtr pScreen)
+{
+ return TRUE;
+}
+
+GlyphRefPtr
+FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare)
+{
+ CARD32 elt, step, s;
+ GlyphPtr glyph;
+ GlyphRefPtr table, gr, del;
+ CARD32 tableSize = hash->hashSet->size;
+
+ table = hash->table;
+ elt = signature % tableSize;
+ step = 0;
+ del = 0;
+ for (;;)
+ {
+ gr = &table[elt];
+ s = gr->signature;
+ glyph = gr->glyph;
+ if (!glyph)
+ {
+ if (del)
+ gr = del;
+ break;
+ }
+ if (glyph == DeletedGlyph)
+ {
+ if (!del)
+ del = gr;
+ else if (gr == del)
+ break;
+ }
+ else if (s == signature &&
+ (!match ||
+ memcmp (&compare->info, &glyph->info, compare->size) == 0))
+ {
+ break;
+ }
+ if (!step)
+ {
+ step = signature % hash->hashSet->rehash;
+ if (!step)
+ step = 1;
+ }
+ elt += step;
+ if (elt >= tableSize)
+ elt -= tableSize;
+ }
+ return gr;
+}
+
+CARD32
+HashGlyph (GlyphPtr glyph)
+{
+ CARD32 *bits = (CARD32 *) &(glyph->info);
+ CARD32 hash;
+ int n = glyph->size / sizeof (CARD32);
+
+ hash = 0;
+ while (n--)
+ hash ^= *bits++;
+ return hash;
+}
+
+#ifdef CHECK_DUPLICATES
+void
+DuplicateRef (GlyphPtr glyph, char *where)
+{
+ ErrorF ("Duplicate Glyph 0x%x from %s\n", glyph, where);
+}
+
+void
+CheckDuplicates (GlyphHashPtr hash, char *where)
+{
+ GlyphPtr g;
+ int i, j;
+
+ for (i = 0; i < hash->hashSet->size; i++)
+ {
+ g = hash->table[i].glyph;
+ if (!g || g == DeletedGlyph)
+ continue;
+ for (j = i + 1; j < hash->hashSet->size; j++)
+ if (hash->table[j].glyph == g)
+ DuplicateRef (g, where);
+ }
+}
+#else
+#define CheckDuplicates(a,b)
+#define DuplicateRef(a,b)
+#endif
+
+void
+FreeGlyph (GlyphPtr glyph, int format)
+{
+ CheckDuplicates (&globalGlyphs[format], "FreeGlyph");
+ if (--glyph->refcnt == 0)
+ {
+ GlyphRefPtr gr;
+ int i;
+ int first;
+
+ first = -1;
+ for (i = 0; i < globalGlyphs[format].hashSet->size; i++)
+ if (globalGlyphs[format].table[i].glyph == glyph)
+ {
+ if (first != -1)
+ DuplicateRef (glyph, "FreeGlyph check");
+ first = i;
+ }
+
+ gr = FindGlyphRef (&globalGlyphs[format],
+ HashGlyph (glyph), TRUE, glyph);
+ if (gr - globalGlyphs[format].table != first)
+ DuplicateRef (glyph, "Found wrong one");
+ if (gr->glyph && gr->glyph != DeletedGlyph)
+ {
+ gr->glyph = DeletedGlyph;
+ gr->signature = 0;
+ globalGlyphs[format].tableEntries--;
+ }
+ xfree (glyph);
+ }
+}
+
+void
+AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id)
+{
+ GlyphRefPtr gr;
+ CARD32 hash;
+
+ CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph top global");
+ /* Locate existing matching glyph */
+ hash = HashGlyph (glyph);
+ gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], hash, TRUE, glyph);
+ if (gr->glyph && gr->glyph != DeletedGlyph)
+ {
+ xfree (glyph);
+ glyph = gr->glyph;
+ }
+ else
+ {
+ gr->glyph = glyph;
+ gr->signature = hash;
+ globalGlyphs[glyphSet->fdepth].tableEntries++;
+ }
+
+ /* Insert/replace glyphset value */
+ gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
+ ++glyph->refcnt;
+ if (gr->glyph && gr->glyph != DeletedGlyph)
+ FreeGlyph (gr->glyph, glyphSet->fdepth);
+ else
+ glyphSet->hash.tableEntries++;
+ gr->glyph = glyph;
+ gr->signature = id;
+ CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph bottom");
+}
+
+Bool
+DeleteGlyph (GlyphSetPtr glyphSet, Glyph id)
+{
+ GlyphRefPtr gr;
+ GlyphPtr glyph;
+
+ gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
+ glyph = gr->glyph;
+ if (glyph && glyph != DeletedGlyph)
+ {
+ gr->glyph = DeletedGlyph;
+ glyphSet->hash.tableEntries--;
+ FreeGlyph (glyph, glyphSet->fdepth);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+GlyphPtr
+FindGlyph (GlyphSetPtr glyphSet, Glyph id)
+{
+ GlyphPtr glyph;
+
+ glyph = FindGlyphRef (&glyphSet->hash, id, FALSE, 0)->glyph;
+ if (glyph == DeletedGlyph)
+ glyph = 0;
+ return glyph;
+}
+
+GlyphPtr
+AllocateGlyph (xGlyphInfo *gi, int fdepth)
+{
+ int size;
+ GlyphPtr glyph;
+
+ size = gi->height * PixmapBytePad (gi->width, glyphDepths[fdepth]);
+ glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec));
+ if (!glyph)
+ return 0;
+ glyph->refcnt = 0;
+ glyph->size = size + sizeof (xGlyphInfo);
+ glyph->info = *gi;
+ return glyph;
+}
+
+Bool
+AllocateGlyphHash (GlyphHashPtr hash, GlyphHashSetPtr hashSet)
+{
+ hash->table = (GlyphRefPtr) xalloc (hashSet->size * sizeof (GlyphRefRec));
+ if (!hash->table)
+ return FALSE;
+ memset (hash->table, 0, hashSet->size * sizeof (GlyphRefRec));
+ hash->hashSet = hashSet;
+ hash->tableEntries = 0;
+ return TRUE;
+}
+
+Bool
+ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global)
+{
+ CARD32 tableEntries;
+ GlyphHashSetPtr hashSet;
+ GlyphHashRec newHash;
+ GlyphRefPtr gr;
+ GlyphPtr glyph;
+ int i;
+ int oldSize;
+ CARD32 s;
+
+ tableEntries = hash->tableEntries + change;
+ hashSet = FindGlyphHashSet (tableEntries);
+ if (hashSet == hash->hashSet)
+ return TRUE;
+ if (global)
+ CheckDuplicates (hash, "ResizeGlyphHash top");
+ if (!AllocateGlyphHash (&newHash, hashSet))
+ return FALSE;
+ if (hash->table)
+ {
+ oldSize = hash->hashSet->size;
+ for (i = 0; i < oldSize; i++)
+ {
+ glyph = hash->table[i].glyph;
+ if (glyph && glyph != DeletedGlyph)
+ {
+ s = hash->table[i].signature;
+ gr = FindGlyphRef (&newHash, s, global, glyph);
+ gr->signature = s;
+ gr->glyph = glyph;
+ ++newHash.tableEntries;
+ }
+ }
+ xfree (hash->table);
+ }
+ *hash = newHash;
+ if (global)
+ CheckDuplicates (hash, "ResizeGlyphHash bottom");
+ return TRUE;
+}
+
+Bool
+ResizeGlyphSet (GlyphSetPtr glyphSet, CARD32 change)
+{
+ return (ResizeGlyphHash (&glyphSet->hash, change, FALSE) &&
+ ResizeGlyphHash (&globalGlyphs[glyphSet->fdepth], change, TRUE));
+}
+
+GlyphSetPtr
+AllocateGlyphSet (int fdepth, PictFormatPtr format)
+{
+ GlyphSetPtr glyphSet;
+ int size;
+
+ if (!globalGlyphs[fdepth].hashSet)
+ {
+ if (!AllocateGlyphHash (&globalGlyphs[fdepth], &glyphHashSets[0]))
+ return FALSE;
+ }
+
+ size = (sizeof (GlyphSetRec) +
+ (sizeof (pointer) * _GlyphSetPrivateAllocateIndex));
+ glyphSet = xalloc (size);
+ if (!glyphSet)
+ return FALSE;
+ bzero((char *)glyphSet, size);
+ glyphSet->maxPrivate = _GlyphSetPrivateAllocateIndex - 1;
+ if (_GlyphSetPrivateAllocateIndex)
+ glyphSet->devPrivates = (pointer)(&glyphSet[1]);
+
+ if (!AllocateGlyphHash (&glyphSet->hash, &glyphHashSets[0]))
+ {
+ xfree (glyphSet);
+ return FALSE;
+ }
+ glyphSet->refcnt = 1;
+ glyphSet->fdepth = fdepth;
+ glyphSet->format = format;
+ return glyphSet;
+}
+
+int
+FreeGlyphSet (pointer value,
+ XID gid)
+{
+ GlyphSetPtr glyphSet = (GlyphSetPtr) value;
+
+ if (--glyphSet->refcnt == 0)
+ {
+ CARD32 i, tableSize = glyphSet->hash.hashSet->size;
+ GlyphRefPtr table = glyphSet->hash.table;
+ GlyphPtr glyph;
+
+ for (i = 0; i < tableSize; i++)
+ {
+ glyph = table[i].glyph;
+ if (glyph && glyph != DeletedGlyph)
+ FreeGlyph (glyph, glyphSet->fdepth);
+ }
+ if (!globalGlyphs[glyphSet->fdepth].tableEntries)
+ {
+ xfree (globalGlyphs[glyphSet->fdepth].table);
+ globalGlyphs[glyphSet->fdepth].table = 0;
+ globalGlyphs[glyphSet->fdepth].hashSet = 0;
+ }
+ else
+ ResizeGlyphHash (&globalGlyphs[glyphSet->fdepth], 0, TRUE);
+ xfree (table);
+
+ if (glyphSet->devPrivates &&
+ glyphSet->devPrivates != (pointer)(&glyphSet[1]))
+ xfree(glyphSet->devPrivates);
+
+ xfree (glyphSet);
+ }
+ return Success;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c
new file mode 100644
index 000000000..3e105ac64
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c
@@ -0,0 +1,241 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/************************************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+************************************************************************/
+
+/* $Xorg: glyphcurs.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include <X11/fonts/fontstruct.h>
+#include "dixfontstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "resource.h"
+#include "dix.h"
+#include "cursorstr.h"
+#include "opaque.h"
+#include "servermd.h"
+
+#include "../../fb/fb.h"
+#include "Pixmaps.h"
+
+#ifndef True
+#define True 1
+#endif
+
+/*
+ get the bits out of the font in a portable way. to avoid
+dealing with padding and such-like, we draw the glyph into
+a bitmap, then read the bits out with GetImage, which
+uses server-natural format.
+ since all screens return the same bitmap format, we'll just use
+the first one we find.
+ the character origin lines up with the hotspot in the
+cursor metrics.
+*/
+
+int
+ServerBitsFromGlyph(FontPtr pfont, unsigned ch, register CursorMetricPtr cm, unsigned char **ppbits)
+{
+ register ScreenPtr pScreen;
+ register GCPtr pGC;
+ xRectangle rect;
+ PixmapPtr ppix;
+ long nby;
+ char *pbits;
+ ChangeGCVal gcval[3];
+ unsigned char char2b[2];
+
+ /* turn glyph index into a protocol-format char2b */
+ char2b[0] = (unsigned char)(ch >> 8);
+ char2b[1] = (unsigned char)(ch & 0xff);
+
+ pScreen = screenInfo.screens[0];
+ nby = BitmapBytePad(cm->width) * (long)cm->height;
+ pbits = (char *)xalloc(nby);
+ if (!pbits)
+ return BadAlloc;
+ /* zeroing the (pad) bits seems to help some ddx cursor handling */
+ bzero(pbits, nby);
+
+ ppix = fbCreatePixmap(pScreen, cm->width, cm->height, 1);
+ pGC = GetScratchGC(1, pScreen);
+ if (!ppix || !pGC)
+ {
+ if (ppix)
+ fbDestroyPixmap(ppix);
+ if (pGC)
+ FreeScratchGC(pGC);
+ xfree(pbits);
+ return BadAlloc;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "ServerBitsFromGlyph: Created virtual pixmap at [%p] with width [%d] height [%d] depth [%d].\n",
+ (void *) ppix, cm->width, cm->height, 1);
+ #endif
+
+ nxagentPixmapPriv(ppix) -> id = 0;
+ nxagentPixmapPriv(ppix) -> mid = 0;
+ nxagentPixmapPriv(ppix) -> isVirtual = True;
+ nxagentPixmapPriv(ppix) -> pRealPixmap = NULL;
+ nxagentPixmapPriv(ppix) -> pVirtualPixmap = NULL;
+
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = cm->width;
+ rect.height = cm->height;
+
+ pGC->stateChanges |= GCFunction | GCForeground | GCFont;
+ pGC->alu = GXcopy;
+
+ pGC->fgPixel = 0;
+
+ pfont->refcnt++;
+
+ if (pGC->font)
+ CloseFont(pGC->font, (Font)0);
+
+ pGC->font = pfont;
+
+ ValidateGC((DrawablePtr)ppix, pGC);
+ fbPolyFillRect((DrawablePtr)ppix, pGC, 1, &rect);
+
+ /* draw the glyph */
+ gcval[0].val = 1;
+ pGC->fgPixel = 1;
+
+ pGC->stateChanges |= GCForeground;
+
+ ValidateGC((DrawablePtr)ppix, pGC);
+ miPolyText16((DrawablePtr)ppix, pGC, (int)cm->xhot, (int)cm->yhot, (int)1, (unsigned short*)char2b);
+ fbGetImage((DrawablePtr)ppix, 0, 0, cm->width, cm->height,
+ XYPixmap, 1, pbits);
+ *ppbits = (unsigned char *)pbits;
+ FreeScratchGC(pGC);
+ fbDestroyPixmap(ppix);
+
+ #ifdef TEST
+ fprintf(stderr, "ServerBitsFromGlyph: Destroyed virtual pixmap at [%p].\n",
+ (void *) ppix);
+ #endif
+
+ return Success;
+}
+
+
+Bool
+CursorMetricsFromGlyph(register FontPtr pfont, unsigned ch, register CursorMetricPtr cm)
+{
+ CharInfoPtr pci;
+ unsigned long nglyphs;
+ CARD8 chs[2];
+ FontEncoding encoding;
+
+ chs[0] = ch >> 8;
+ chs[1] = ch;
+ encoding = (FONTLASTROW(pfont) == 0) ? Linear16Bit : TwoD16Bit;
+ if (encoding == Linear16Bit)
+ {
+ if (ch < pfont->info.firstCol || pfont->info.lastCol < ch)
+ return FALSE;
+ }
+ else
+ {
+ if (chs[0] < pfont->info.firstRow || pfont->info.lastRow < chs[0])
+ return FALSE;
+ if (chs[1] < pfont->info.firstCol || pfont->info.lastCol < chs[1])
+ return FALSE;
+ }
+ (*pfont->get_glyphs) (pfont, 1, chs, encoding, &nglyphs, &pci);
+ if (nglyphs == 0)
+ return FALSE;
+ cm->width = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
+ cm->height = pci->metrics.descent + pci->metrics.ascent;
+ if (pci->metrics.leftSideBearing > 0)
+ {
+ cm->width += pci->metrics.leftSideBearing;
+ cm->xhot = 0;
+ }
+ else
+ {
+ cm->xhot = -pci->metrics.leftSideBearing;
+ if (pci->metrics.rightSideBearing < 0)
+ cm->width -= pci->metrics.rightSideBearing;
+ }
+ if (pci->metrics.ascent < 0)
+ {
+ cm->height -= pci->metrics.ascent;
+ cm->yhot = 0;
+ }
+ else
+ {
+ cm->yhot = pci->metrics.ascent;
+ if (pci->metrics.descent < 0)
+ cm->height -= pci->metrics.descent;
+ }
+ return TRUE;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original
new file mode 100644
index 000000000..3e105ac64
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original
@@ -0,0 +1,241 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/************************************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+************************************************************************/
+
+/* $Xorg: glyphcurs.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include <X11/fonts/fontstruct.h>
+#include "dixfontstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "resource.h"
+#include "dix.h"
+#include "cursorstr.h"
+#include "opaque.h"
+#include "servermd.h"
+
+#include "../../fb/fb.h"
+#include "Pixmaps.h"
+
+#ifndef True
+#define True 1
+#endif
+
+/*
+ get the bits out of the font in a portable way. to avoid
+dealing with padding and such-like, we draw the glyph into
+a bitmap, then read the bits out with GetImage, which
+uses server-natural format.
+ since all screens return the same bitmap format, we'll just use
+the first one we find.
+ the character origin lines up with the hotspot in the
+cursor metrics.
+*/
+
+int
+ServerBitsFromGlyph(FontPtr pfont, unsigned ch, register CursorMetricPtr cm, unsigned char **ppbits)
+{
+ register ScreenPtr pScreen;
+ register GCPtr pGC;
+ xRectangle rect;
+ PixmapPtr ppix;
+ long nby;
+ char *pbits;
+ ChangeGCVal gcval[3];
+ unsigned char char2b[2];
+
+ /* turn glyph index into a protocol-format char2b */
+ char2b[0] = (unsigned char)(ch >> 8);
+ char2b[1] = (unsigned char)(ch & 0xff);
+
+ pScreen = screenInfo.screens[0];
+ nby = BitmapBytePad(cm->width) * (long)cm->height;
+ pbits = (char *)xalloc(nby);
+ if (!pbits)
+ return BadAlloc;
+ /* zeroing the (pad) bits seems to help some ddx cursor handling */
+ bzero(pbits, nby);
+
+ ppix = fbCreatePixmap(pScreen, cm->width, cm->height, 1);
+ pGC = GetScratchGC(1, pScreen);
+ if (!ppix || !pGC)
+ {
+ if (ppix)
+ fbDestroyPixmap(ppix);
+ if (pGC)
+ FreeScratchGC(pGC);
+ xfree(pbits);
+ return BadAlloc;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "ServerBitsFromGlyph: Created virtual pixmap at [%p] with width [%d] height [%d] depth [%d].\n",
+ (void *) ppix, cm->width, cm->height, 1);
+ #endif
+
+ nxagentPixmapPriv(ppix) -> id = 0;
+ nxagentPixmapPriv(ppix) -> mid = 0;
+ nxagentPixmapPriv(ppix) -> isVirtual = True;
+ nxagentPixmapPriv(ppix) -> pRealPixmap = NULL;
+ nxagentPixmapPriv(ppix) -> pVirtualPixmap = NULL;
+
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = cm->width;
+ rect.height = cm->height;
+
+ pGC->stateChanges |= GCFunction | GCForeground | GCFont;
+ pGC->alu = GXcopy;
+
+ pGC->fgPixel = 0;
+
+ pfont->refcnt++;
+
+ if (pGC->font)
+ CloseFont(pGC->font, (Font)0);
+
+ pGC->font = pfont;
+
+ ValidateGC((DrawablePtr)ppix, pGC);
+ fbPolyFillRect((DrawablePtr)ppix, pGC, 1, &rect);
+
+ /* draw the glyph */
+ gcval[0].val = 1;
+ pGC->fgPixel = 1;
+
+ pGC->stateChanges |= GCForeground;
+
+ ValidateGC((DrawablePtr)ppix, pGC);
+ miPolyText16((DrawablePtr)ppix, pGC, (int)cm->xhot, (int)cm->yhot, (int)1, (unsigned short*)char2b);
+ fbGetImage((DrawablePtr)ppix, 0, 0, cm->width, cm->height,
+ XYPixmap, 1, pbits);
+ *ppbits = (unsigned char *)pbits;
+ FreeScratchGC(pGC);
+ fbDestroyPixmap(ppix);
+
+ #ifdef TEST
+ fprintf(stderr, "ServerBitsFromGlyph: Destroyed virtual pixmap at [%p].\n",
+ (void *) ppix);
+ #endif
+
+ return Success;
+}
+
+
+Bool
+CursorMetricsFromGlyph(register FontPtr pfont, unsigned ch, register CursorMetricPtr cm)
+{
+ CharInfoPtr pci;
+ unsigned long nglyphs;
+ CARD8 chs[2];
+ FontEncoding encoding;
+
+ chs[0] = ch >> 8;
+ chs[1] = ch;
+ encoding = (FONTLASTROW(pfont) == 0) ? Linear16Bit : TwoD16Bit;
+ if (encoding == Linear16Bit)
+ {
+ if (ch < pfont->info.firstCol || pfont->info.lastCol < ch)
+ return FALSE;
+ }
+ else
+ {
+ if (chs[0] < pfont->info.firstRow || pfont->info.lastRow < chs[0])
+ return FALSE;
+ if (chs[1] < pfont->info.firstCol || pfont->info.lastCol < chs[1])
+ return FALSE;
+ }
+ (*pfont->get_glyphs) (pfont, 1, chs, encoding, &nglyphs, &pci);
+ if (nglyphs == 0)
+ return FALSE;
+ cm->width = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
+ cm->height = pci->metrics.descent + pci->metrics.ascent;
+ if (pci->metrics.leftSideBearing > 0)
+ {
+ cm->width += pci->metrics.leftSideBearing;
+ cm->xhot = 0;
+ }
+ else
+ {
+ cm->xhot = -pci->metrics.leftSideBearing;
+ if (pci->metrics.rightSideBearing < 0)
+ cm->width -= pci->metrics.rightSideBearing;
+ }
+ if (pci->metrics.ascent < 0)
+ {
+ cm->height -= pci->metrics.ascent;
+ cm->yhot = 0;
+ }
+ else
+ {
+ cm->yhot = pci->metrics.ascent;
+ if (pci->metrics.descent < 0)
+ cm->height -= pci->metrics.descent;
+ }
+ return TRUE;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.X.original
new file mode 100644
index 000000000..8f8adf5ce
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.X.original
@@ -0,0 +1,194 @@
+/************************************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+************************************************************************/
+
+/* $Xorg: glyphcurs.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include <X11/fonts/fontstruct.h>
+#include "dixfontstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "resource.h"
+#include "dix.h"
+#include "cursorstr.h"
+#include "opaque.h"
+#include "servermd.h"
+
+
+/*
+ get the bits out of the font in a portable way. to avoid
+dealing with padding and such-like, we draw the glyph into
+a bitmap, then read the bits out with GetImage, which
+uses server-natural format.
+ since all screens return the same bitmap format, we'll just use
+the first one we find.
+ the character origin lines up with the hotspot in the
+cursor metrics.
+*/
+
+int
+ServerBitsFromGlyph(FontPtr pfont, unsigned ch, register CursorMetricPtr cm, unsigned char **ppbits)
+{
+ register ScreenPtr pScreen;
+ register GCPtr pGC;
+ xRectangle rect;
+ PixmapPtr ppix;
+ long nby;
+ char *pbits;
+ ChangeGCVal gcval[3];
+ unsigned char char2b[2];
+
+ /* turn glyph index into a protocol-format char2b */
+ char2b[0] = (unsigned char)(ch >> 8);
+ char2b[1] = (unsigned char)(ch & 0xff);
+
+ pScreen = screenInfo.screens[0];
+ nby = BitmapBytePad(cm->width) * (long)cm->height;
+ pbits = (char *)xalloc(nby);
+ if (!pbits)
+ return BadAlloc;
+ /* zeroing the (pad) bits seems to help some ddx cursor handling */
+ bzero(pbits, nby);
+
+ ppix = (PixmapPtr)(*pScreen->CreatePixmap)(pScreen, cm->width,
+ cm->height, 1);
+ pGC = GetScratchGC(1, pScreen);
+ if (!ppix || !pGC)
+ {
+ if (ppix)
+ (*pScreen->DestroyPixmap)(ppix);
+ if (pGC)
+ FreeScratchGC(pGC);
+ xfree(pbits);
+ return BadAlloc;
+ }
+
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = cm->width;
+ rect.height = cm->height;
+
+ /* fill the pixmap with 0 */
+ gcval[0].val = GXcopy;
+ gcval[1].val = 0;
+ gcval[2].ptr = (pointer)pfont;
+ dixChangeGC(NullClient, pGC, GCFunction | GCForeground | GCFont,
+ NULL, gcval);
+ ValidateGC((DrawablePtr)ppix, pGC);
+ (*pGC->ops->PolyFillRect)((DrawablePtr)ppix, pGC, 1, &rect);
+
+ /* draw the glyph */
+ gcval[0].val = 1;
+ dixChangeGC(NullClient, pGC, GCForeground, NULL, gcval);
+ ValidateGC((DrawablePtr)ppix, pGC);
+ (*pGC->ops->PolyText16)((DrawablePtr)ppix, pGC, cm->xhot, cm->yhot,
+ 1, (unsigned short *)char2b);
+ (*pScreen->GetImage)((DrawablePtr)ppix, 0, 0, cm->width, cm->height,
+ XYPixmap, 1, pbits);
+ *ppbits = (unsigned char *)pbits;
+ FreeScratchGC(pGC);
+ (*pScreen->DestroyPixmap)(ppix);
+ return Success;
+}
+
+
+Bool
+CursorMetricsFromGlyph(register FontPtr pfont, unsigned ch, register CursorMetricPtr cm)
+{
+ CharInfoPtr pci;
+ unsigned long nglyphs;
+ CARD8 chs[2];
+ FontEncoding encoding;
+
+ chs[0] = ch >> 8;
+ chs[1] = ch;
+ encoding = (FONTLASTROW(pfont) == 0) ? Linear16Bit : TwoD16Bit;
+ if (encoding == Linear16Bit)
+ {
+ if (ch < pfont->info.firstCol || pfont->info.lastCol < ch)
+ return FALSE;
+ }
+ else
+ {
+ if (chs[0] < pfont->info.firstRow || pfont->info.lastRow < chs[0])
+ return FALSE;
+ if (chs[1] < pfont->info.firstCol || pfont->info.lastCol < chs[1])
+ return FALSE;
+ }
+ (*pfont->get_glyphs) (pfont, 1, chs, encoding, &nglyphs, &pci);
+ if (nglyphs == 0)
+ return FALSE;
+ cm->width = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
+ cm->height = pci->metrics.descent + pci->metrics.ascent;
+ if (pci->metrics.leftSideBearing > 0)
+ {
+ cm->width += pci->metrics.leftSideBearing;
+ cm->xhot = 0;
+ }
+ else
+ {
+ cm->xhot = -pci->metrics.leftSideBearing;
+ if (pci->metrics.rightSideBearing < 0)
+ cm->width -= pci->metrics.rightSideBearing;
+ }
+ if (pci->metrics.ascent < 0)
+ {
+ cm->height -= pci->metrics.ascent;
+ cm->yhot = 0;
+ }
+ else
+ {
+ cm->yhot = pci->metrics.ascent;
+ if (pci->metrics.descent < 0)
+ cm->height -= pci->metrics.descent;
+ }
+ return TRUE;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h
new file mode 100644
index 000000000..0f30843d6
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h
@@ -0,0 +1,174 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/glyphstr.h,v 1.3 2000/11/20 07:13:13 keithp Exp $
+ *
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+/*
+ * This must keep the same symbol as the original glyphstr.h
+ * or symbols will be redefined. The code here adds a field
+ * to _GlyphSet. This should be done by defining a new type
+ * and casting when appropriate.
+ */
+
+#ifndef _GLYPHSTR_H_
+#define _GLYPHSTR_H_
+
+#include <X11/extensions/renderproto.h>
+#include "../../render/picture.h"
+#include "screenint.h"
+
+#define GlyphFormat1 0
+#define GlyphFormat4 1
+#define GlyphFormat8 2
+#define GlyphFormat16 3
+#define GlyphFormat32 4
+#define GlyphFormatNum 5
+
+typedef struct _Glyph {
+ CARD32 refcnt;
+ CARD32 size; /* info + bitmap */
+ xGlyphInfo info;
+ /* bits follow */
+} GlyphRec, *GlyphPtr;
+
+typedef struct _GlyphRef {
+ CARD32 signature;
+ GlyphPtr glyph;
+ CARD16 corruptedGlyph;
+} GlyphRefRec, *GlyphRefPtr;
+
+#define DeletedGlyph ((GlyphPtr) 1)
+
+typedef struct _GlyphHashSet {
+ CARD32 entries;
+ CARD32 size;
+ CARD32 rehash;
+} GlyphHashSetRec, *GlyphHashSetPtr;
+
+typedef struct _GlyphHash {
+ GlyphRefPtr table;
+ GlyphHashSetPtr hashSet;
+ CARD32 tableEntries;
+} GlyphHashRec, *GlyphHashPtr;
+
+typedef struct _GlyphSet {
+ CARD32 refcnt;
+ PictFormatPtr format;
+ int fdepth;
+ GlyphHashRec hash;
+ int maxPrivate;
+ pointer *devPrivates;
+ CARD32 remoteID;
+} GlyphSetRec, *GlyphSetPtr;
+
+#define GlyphSetGetPrivate(pGlyphSet,n) \
+ ((n) > (pGlyphSet)->maxPrivate ? \
+ (pointer) 0 : \
+ (pGlyphSet)->devPrivates[n])
+
+#define GlyphSetSetPrivate(pGlyphSet,n,ptr) \
+ ((n) > (pGlyphSet)->maxPrivate ? \
+ _GlyphSetSetNewPrivate(pGlyphSet, n, ptr) : \
+ ((((pGlyphSet)->devPrivates[n] = (ptr)) != 0) || TRUE))
+
+typedef struct _GlyphList {
+ INT16 xOff;
+ INT16 yOff;
+ CARD8 len;
+ PictFormatPtr format;
+} GlyphListRec, *GlyphListPtr;
+
+extern GlyphHashRec globalGlyphs[GlyphFormatNum];
+
+GlyphHashSetPtr
+FindGlyphHashSet (CARD32 filled);
+
+int
+AllocateGlyphSetPrivateIndex (void);
+
+void
+ResetGlyphSetPrivateIndex (void);
+
+Bool
+_GlyphSetSetNewPrivate (GlyphSetPtr glyphSet, int n, pointer ptr);
+
+Bool
+GlyphInit (ScreenPtr pScreen);
+
+GlyphRefPtr
+FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare);
+
+CARD32
+HashGlyph (GlyphPtr glyph);
+
+void
+FreeGlyph (GlyphPtr glyph, int format);
+
+void
+AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id);
+
+Bool
+DeleteGlyph (GlyphSetPtr glyphSet, Glyph id);
+
+GlyphPtr
+FindGlyph (GlyphSetPtr glyphSet, Glyph id);
+
+GlyphPtr
+AllocateGlyph (xGlyphInfo *gi, int format);
+
+Bool
+AllocateGlyphHash (GlyphHashPtr hash, GlyphHashSetPtr hashSet);
+
+Bool
+ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global);
+
+Bool
+ResizeGlyphSet (GlyphSetPtr glyphSet, CARD32 change);
+
+GlyphSetPtr
+AllocateGlyphSet (int fdepth, PictFormatPtr format);
+
+int
+FreeGlyphSet (pointer value,
+ XID gid);
+
+
+
+#endif /* _GLYPHSTR_H_ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.NX.original
new file mode 100644
index 000000000..0f30843d6
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.NX.original
@@ -0,0 +1,174 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/glyphstr.h,v 1.3 2000/11/20 07:13:13 keithp Exp $
+ *
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+/*
+ * This must keep the same symbol as the original glyphstr.h
+ * or symbols will be redefined. The code here adds a field
+ * to _GlyphSet. This should be done by defining a new type
+ * and casting when appropriate.
+ */
+
+#ifndef _GLYPHSTR_H_
+#define _GLYPHSTR_H_
+
+#include <X11/extensions/renderproto.h>
+#include "../../render/picture.h"
+#include "screenint.h"
+
+#define GlyphFormat1 0
+#define GlyphFormat4 1
+#define GlyphFormat8 2
+#define GlyphFormat16 3
+#define GlyphFormat32 4
+#define GlyphFormatNum 5
+
+typedef struct _Glyph {
+ CARD32 refcnt;
+ CARD32 size; /* info + bitmap */
+ xGlyphInfo info;
+ /* bits follow */
+} GlyphRec, *GlyphPtr;
+
+typedef struct _GlyphRef {
+ CARD32 signature;
+ GlyphPtr glyph;
+ CARD16 corruptedGlyph;
+} GlyphRefRec, *GlyphRefPtr;
+
+#define DeletedGlyph ((GlyphPtr) 1)
+
+typedef struct _GlyphHashSet {
+ CARD32 entries;
+ CARD32 size;
+ CARD32 rehash;
+} GlyphHashSetRec, *GlyphHashSetPtr;
+
+typedef struct _GlyphHash {
+ GlyphRefPtr table;
+ GlyphHashSetPtr hashSet;
+ CARD32 tableEntries;
+} GlyphHashRec, *GlyphHashPtr;
+
+typedef struct _GlyphSet {
+ CARD32 refcnt;
+ PictFormatPtr format;
+ int fdepth;
+ GlyphHashRec hash;
+ int maxPrivate;
+ pointer *devPrivates;
+ CARD32 remoteID;
+} GlyphSetRec, *GlyphSetPtr;
+
+#define GlyphSetGetPrivate(pGlyphSet,n) \
+ ((n) > (pGlyphSet)->maxPrivate ? \
+ (pointer) 0 : \
+ (pGlyphSet)->devPrivates[n])
+
+#define GlyphSetSetPrivate(pGlyphSet,n,ptr) \
+ ((n) > (pGlyphSet)->maxPrivate ? \
+ _GlyphSetSetNewPrivate(pGlyphSet, n, ptr) : \
+ ((((pGlyphSet)->devPrivates[n] = (ptr)) != 0) || TRUE))
+
+typedef struct _GlyphList {
+ INT16 xOff;
+ INT16 yOff;
+ CARD8 len;
+ PictFormatPtr format;
+} GlyphListRec, *GlyphListPtr;
+
+extern GlyphHashRec globalGlyphs[GlyphFormatNum];
+
+GlyphHashSetPtr
+FindGlyphHashSet (CARD32 filled);
+
+int
+AllocateGlyphSetPrivateIndex (void);
+
+void
+ResetGlyphSetPrivateIndex (void);
+
+Bool
+_GlyphSetSetNewPrivate (GlyphSetPtr glyphSet, int n, pointer ptr);
+
+Bool
+GlyphInit (ScreenPtr pScreen);
+
+GlyphRefPtr
+FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare);
+
+CARD32
+HashGlyph (GlyphPtr glyph);
+
+void
+FreeGlyph (GlyphPtr glyph, int format);
+
+void
+AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id);
+
+Bool
+DeleteGlyph (GlyphSetPtr glyphSet, Glyph id);
+
+GlyphPtr
+FindGlyph (GlyphSetPtr glyphSet, Glyph id);
+
+GlyphPtr
+AllocateGlyph (xGlyphInfo *gi, int format);
+
+Bool
+AllocateGlyphHash (GlyphHashPtr hash, GlyphHashSetPtr hashSet);
+
+Bool
+ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global);
+
+Bool
+ResizeGlyphSet (GlyphSetPtr glyphSet, CARD32 change);
+
+GlyphSetPtr
+AllocateGlyphSet (int fdepth, PictFormatPtr format);
+
+int
+FreeGlyphSet (pointer value,
+ XID gid);
+
+
+
+#endif /* _GLYPHSTR_H_ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.X.original
new file mode 100644
index 000000000..f4777a248
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.X.original
@@ -0,0 +1,148 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/glyphstr.h,v 1.3 2000/11/20 07:13:13 keithp Exp $
+ *
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifndef _GLYPHSTR_H_
+#define _GLYPHSTR_H_
+
+#include <X11/extensions/renderproto.h>
+#include "picture.h"
+#include "screenint.h"
+
+#define GlyphFormat1 0
+#define GlyphFormat4 1
+#define GlyphFormat8 2
+#define GlyphFormat16 3
+#define GlyphFormat32 4
+#define GlyphFormatNum 5
+
+typedef struct _Glyph {
+ CARD32 refcnt;
+ CARD32 size; /* info + bitmap */
+ xGlyphInfo info;
+ /* bits follow */
+} GlyphRec, *GlyphPtr;
+
+typedef struct _GlyphRef {
+ CARD32 signature;
+ GlyphPtr glyph;
+} GlyphRefRec, *GlyphRefPtr;
+
+#define DeletedGlyph ((GlyphPtr) 1)
+
+typedef struct _GlyphHashSet {
+ CARD32 entries;
+ CARD32 size;
+ CARD32 rehash;
+} GlyphHashSetRec, *GlyphHashSetPtr;
+
+typedef struct _GlyphHash {
+ GlyphRefPtr table;
+ GlyphHashSetPtr hashSet;
+ CARD32 tableEntries;
+} GlyphHashRec, *GlyphHashPtr;
+
+typedef struct _GlyphSet {
+ CARD32 refcnt;
+ PictFormatPtr format;
+ int fdepth;
+ GlyphHashRec hash;
+ int maxPrivate;
+ pointer *devPrivates;
+} GlyphSetRec, *GlyphSetPtr;
+
+#define GlyphSetGetPrivate(pGlyphSet,n) \
+ ((n) > (pGlyphSet)->maxPrivate ? \
+ (pointer) 0 : \
+ (pGlyphSet)->devPrivates[n])
+
+#define GlyphSetSetPrivate(pGlyphSet,n,ptr) \
+ ((n) > (pGlyphSet)->maxPrivate ? \
+ _GlyphSetSetNewPrivate(pGlyphSet, n, ptr) : \
+ ((((pGlyphSet)->devPrivates[n] = (ptr)) != 0) || TRUE))
+
+typedef struct _GlyphList {
+ INT16 xOff;
+ INT16 yOff;
+ CARD8 len;
+ PictFormatPtr format;
+} GlyphListRec, *GlyphListPtr;
+
+extern GlyphHashRec globalGlyphs[GlyphFormatNum];
+
+GlyphHashSetPtr
+FindGlyphHashSet (CARD32 filled);
+
+int
+AllocateGlyphSetPrivateIndex (void);
+
+void
+ResetGlyphSetPrivateIndex (void);
+
+Bool
+_GlyphSetSetNewPrivate (GlyphSetPtr glyphSet, int n, pointer ptr);
+
+Bool
+GlyphInit (ScreenPtr pScreen);
+
+GlyphRefPtr
+FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare);
+
+CARD32
+HashGlyph (GlyphPtr glyph);
+
+void
+FreeGlyph (GlyphPtr glyph, int format);
+
+void
+AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id);
+
+Bool
+DeleteGlyph (GlyphSetPtr glyphSet, Glyph id);
+
+GlyphPtr
+FindGlyph (GlyphSetPtr glyphSet, Glyph id);
+
+GlyphPtr
+AllocateGlyph (xGlyphInfo *gi, int format);
+
+Bool
+AllocateGlyphHash (GlyphHashPtr hash, GlyphHashSetPtr hashSet);
+
+Bool
+ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global);
+
+Bool
+ResizeGlyphSet (GlyphSetPtr glyphSet, CARD32 change);
+
+GlyphSetPtr
+AllocateGlyphSet (int fdepth, PictFormatPtr format);
+
+int
+FreeGlyphSet (pointer value,
+ XID gid);
+
+
+
+#endif /* _GLYPHSTR_H_ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c
new file mode 100644
index 000000000..af07fdcc2
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c
@@ -0,0 +1,979 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/* $XdotOrg: xc/programs/Xserver/mi/miexpose.c,v 1.6 2005/07/03 08:53:51 daniels Exp $ */
+/* $XFree86: xc/programs/Xserver/mi/miexpose.c,v 3.9tsi Exp $ */
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+/* $Xorg: miexpose.c,v 1.4 2001/02/09 02:05:20 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#define NEED_EVENTS
+#include <X11/Xproto.h>
+#include <X11/Xprotostr.h>
+
+#include "misc.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmap.h"
+#include "input.h"
+
+#include "dixstruct.h"
+#include "mi.h"
+#include <X11/Xmd.h>
+
+#include "globals.h"
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+/*
+ machine-independent graphics exposure code. any device that uses
+the region package can call this.
+*/
+
+#ifdef NXAGENT_SERVER
+
+#include "Windows.h"
+
+#endif
+
+#ifndef RECTLIMIT
+#define RECTLIMIT 25 /* pick a number, any number > 8 */
+#endif
+
+/* miHandleExposures
+ generate a region for exposures for areas that were copied from obscured or
+non-existent areas to non-obscured areas of the destination. Paint the
+background for the region, if the destination is a window.
+
+NOTE:
+ this should generally be called, even if graphicsExposures is false,
+because this is where bits get recovered from backing store.
+
+NOTE:
+ added argument 'plane' is used to indicate how exposures from backing
+store should be accomplished. If plane is 0 (i.e. no bit plane), CopyArea
+should be used, else a CopyPlane of the indicated plane will be used. The
+exposing is done by the backing store's GraphicsExpose function, of course.
+
+*/
+
+RegionPtr
+miHandleExposures(pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty, plane)
+ register DrawablePtr pSrcDrawable;
+ register DrawablePtr pDstDrawable;
+ GCPtr pGC;
+ int srcx, srcy;
+ int width, height;
+ int dstx, dsty;
+ unsigned long plane;
+{
+ register ScreenPtr pscr;
+ RegionPtr prgnSrcClip; /* drawable-relative source clip */
+ RegionRec rgnSrcRec;
+ RegionPtr prgnDstClip; /* drawable-relative dest clip */
+ RegionRec rgnDstRec;
+ BoxRec srcBox; /* unclipped source */
+ RegionRec rgnExposed; /* exposed region, calculated source-
+ relative, made dst relative to
+ intersect with visible parts of
+ dest and send events to client,
+ and then screen relative to paint
+ the window background
+ */
+ WindowPtr pSrcWin;
+ BoxRec expBox;
+ Bool extents;
+
+#ifdef NXAGENT_SERVER
+
+ /*
+ * Set the elements reported by the compiler
+ * as uninitialized.
+ */
+
+ expBox.x1 = 0;
+ expBox.y1 = 0;
+ expBox.x2 = 0;
+ expBox.y2 = 0;
+
+#endif
+
+ /* This prevents warning about pscr not being used. */
+ pGC->pScreen = pscr = pGC->pScreen;
+
+ /* avoid work if we can */
+ if (!pGC->graphicsExposures &&
+ (pDstDrawable->type == DRAWABLE_PIXMAP) &&
+ ((pSrcDrawable->type == DRAWABLE_PIXMAP) ||
+ (((WindowPtr)pSrcDrawable)->backStorage == NULL)))
+ return NULL;
+
+ srcBox.x1 = srcx;
+ srcBox.y1 = srcy;
+ srcBox.x2 = srcx+width;
+ srcBox.y2 = srcy+height;
+
+ if (pSrcDrawable->type != DRAWABLE_PIXMAP)
+ {
+ BoxRec TsrcBox;
+
+ TsrcBox.x1 = srcx + pSrcDrawable->x;
+ TsrcBox.y1 = srcy + pSrcDrawable->y;
+ TsrcBox.x2 = TsrcBox.x1 + width;
+ TsrcBox.y2 = TsrcBox.y1 + height;
+ pSrcWin = (WindowPtr) pSrcDrawable;
+ if (pGC->subWindowMode == IncludeInferiors)
+ {
+ prgnSrcClip = NotClippedByChildren (pSrcWin);
+ if ((RECT_IN_REGION(pscr, prgnSrcClip, &TsrcBox)) == rgnIN)
+ {
+ REGION_DESTROY(pscr, prgnSrcClip);
+ return NULL;
+ }
+ }
+ else
+ {
+ if ((RECT_IN_REGION(pscr, &pSrcWin->clipList, &TsrcBox)) == rgnIN)
+ return NULL;
+ prgnSrcClip = &rgnSrcRec;
+ REGION_NULL(pscr, prgnSrcClip);
+ REGION_COPY(pscr, prgnSrcClip, &pSrcWin->clipList);
+ }
+ REGION_TRANSLATE(pscr, prgnSrcClip,
+ -pSrcDrawable->x, -pSrcDrawable->y);
+ }
+ else
+ {
+ BoxRec box;
+
+ if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) &&
+ (srcBox.x2 <= pSrcDrawable->width) &&
+ (srcBox.y2 <= pSrcDrawable->height))
+ return NULL;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pSrcDrawable->width;
+ box.y2 = pSrcDrawable->height;
+ prgnSrcClip = &rgnSrcRec;
+ REGION_INIT(pscr, prgnSrcClip, &box, 1);
+ pSrcWin = (WindowPtr)NULL;
+ }
+
+ if (pDstDrawable == pSrcDrawable)
+ {
+ prgnDstClip = prgnSrcClip;
+ }
+ else if (pDstDrawable->type != DRAWABLE_PIXMAP)
+ {
+ if (pGC->subWindowMode == IncludeInferiors)
+ {
+ prgnDstClip = NotClippedByChildren((WindowPtr)pDstDrawable);
+ }
+ else
+ {
+ prgnDstClip = &rgnDstRec;
+ REGION_NULL(pscr, prgnDstClip);
+ REGION_COPY(pscr, prgnDstClip,
+ &((WindowPtr)pDstDrawable)->clipList);
+ }
+ REGION_TRANSLATE(pscr, prgnDstClip,
+ -pDstDrawable->x, -pDstDrawable->y);
+ }
+ else
+ {
+ BoxRec box;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pDstDrawable->width;
+ box.y2 = pDstDrawable->height;
+ prgnDstClip = &rgnDstRec;
+ REGION_INIT(pscr, prgnDstClip, &box, 1);
+ }
+
+ /* drawable-relative source region */
+ REGION_INIT(pscr, &rgnExposed, &srcBox, 1);
+
+ /* now get the hidden parts of the source box*/
+ REGION_SUBTRACT(pscr, &rgnExposed, &rgnExposed, prgnSrcClip);
+
+ if (pSrcWin && pSrcWin->backStorage)
+ {
+ /*
+ * Copy any areas from the source backing store. Modifies
+ * rgnExposed.
+ */
+ (* pSrcWin->drawable.pScreen->ExposeCopy) ((WindowPtr)pSrcDrawable,
+ pDstDrawable,
+ pGC,
+ &rgnExposed,
+ srcx, srcy,
+ dstx, dsty,
+ plane);
+ }
+
+ /* move them over the destination */
+ REGION_TRANSLATE(pscr, &rgnExposed, dstx-srcx, dsty-srcy);
+
+ /* intersect with visible areas of dest */
+ REGION_INTERSECT(pscr, &rgnExposed, &rgnExposed, prgnDstClip);
+
+ /*
+ * If we have LOTS of rectangles, we decide to take the extents
+ * and force an exposure on that. This should require much less
+ * work overall, on both client and server. This is cheating, but
+ * isn't prohibited by the protocol ("spontaneous combustion" :-)
+ * for windows.
+ */
+ extents = pGC->graphicsExposures &&
+ (REGION_NUM_RECTS(&rgnExposed) > RECTLIMIT) &&
+ (pDstDrawable->type != DRAWABLE_PIXMAP);
+#ifdef SHAPE
+ if (pSrcWin)
+ {
+ RegionPtr region;
+ if (!(region = wClipShape (pSrcWin)))
+ region = wBoundingShape (pSrcWin);
+ /*
+ * If you try to CopyArea the extents of a shaped window, compacting the
+ * exposed region will undo all our work!
+ */
+ if (extents && pSrcWin && region &&
+ (RECT_IN_REGION(pscr, region, &srcBox) != rgnIN))
+ extents = FALSE;
+ }
+#endif
+ if (extents)
+ {
+ WindowPtr pWin = (WindowPtr)pDstDrawable;
+
+ expBox = *REGION_EXTENTS(pscr, &rgnExposed);
+ REGION_RESET(pscr, &rgnExposed, &expBox);
+ /* need to clear out new areas of backing store */
+ if (pWin->backStorage)
+ (void) (* pWin->drawable.pScreen->ClearBackingStore)(
+ pWin,
+ expBox.x1,
+ expBox.y1,
+ expBox.x2 - expBox.x1,
+ expBox.y2 - expBox.y1,
+ FALSE);
+ }
+ if ((pDstDrawable->type != DRAWABLE_PIXMAP) &&
+ (((WindowPtr)pDstDrawable)->backgroundState != None))
+ {
+ WindowPtr pWin = (WindowPtr)pDstDrawable;
+
+ /* make the exposed area screen-relative */
+ REGION_TRANSLATE(pscr, &rgnExposed,
+ pDstDrawable->x, pDstDrawable->y);
+
+ if (extents)
+ {
+ /* PaintWindowBackground doesn't clip, so we have to */
+ REGION_INTERSECT(pscr, &rgnExposed, &rgnExposed, &pWin->clipList);
+ }
+ (*pWin->drawable.pScreen->PaintWindowBackground)(
+ (WindowPtr)pDstDrawable, &rgnExposed, PW_BACKGROUND);
+
+ if (extents)
+ {
+ REGION_RESET(pscr, &rgnExposed, &expBox);
+ }
+ else
+ REGION_TRANSLATE(pscr, &rgnExposed,
+ -pDstDrawable->x, -pDstDrawable->y);
+ }
+ if (prgnDstClip == &rgnDstRec)
+ {
+ REGION_UNINIT(pscr, prgnDstClip);
+ }
+ else if (prgnDstClip != prgnSrcClip)
+ {
+ REGION_DESTROY(pscr, prgnDstClip);
+ }
+
+ if (prgnSrcClip == &rgnSrcRec)
+ {
+ REGION_UNINIT(pscr, prgnSrcClip);
+ }
+ else
+ {
+ REGION_DESTROY(pscr, prgnSrcClip);
+ }
+
+ if (pGC->graphicsExposures)
+ {
+ /* don't look */
+ RegionPtr exposed = REGION_CREATE(pscr, NullBox, 0);
+ *exposed = rgnExposed;
+ return exposed;
+ }
+ else
+ {
+ REGION_UNINIT(pscr, &rgnExposed);
+ return NULL;
+ }
+}
+
+/* send GraphicsExpose events, or a NoExpose event, based on the region */
+
+void
+miSendGraphicsExpose (client, pRgn, drawable, major, minor)
+ ClientPtr client;
+ RegionPtr pRgn;
+ XID drawable;
+ int major;
+ int minor;
+{
+ if (pRgn && !REGION_NIL(pRgn))
+ {
+ xEvent *pEvent;
+ register xEvent *pe;
+ register BoxPtr pBox;
+ register int i;
+ int numRects;
+
+ numRects = REGION_NUM_RECTS(pRgn);
+ pBox = REGION_RECTS(pRgn);
+ if(!(pEvent = (xEvent *)ALLOCATE_LOCAL(numRects * sizeof(xEvent))))
+ return;
+ pe = pEvent;
+
+ for (i=1; i<=numRects; i++, pe++, pBox++)
+ {
+ pe->u.u.type = GraphicsExpose;
+ pe->u.graphicsExposure.drawable = drawable;
+ pe->u.graphicsExposure.x = pBox->x1;
+ pe->u.graphicsExposure.y = pBox->y1;
+ pe->u.graphicsExposure.width = pBox->x2 - pBox->x1;
+ pe->u.graphicsExposure.height = pBox->y2 - pBox->y1;
+ pe->u.graphicsExposure.count = numRects - i;
+ pe->u.graphicsExposure.majorEvent = major;
+ pe->u.graphicsExposure.minorEvent = minor;
+ }
+ TryClientEvents(client, pEvent, numRects,
+ (Mask)0, NoEventMask, NullGrab);
+ DEALLOCATE_LOCAL(pEvent);
+ }
+ else
+ {
+ xEvent event;
+ event.u.u.type = NoExpose;
+ event.u.noExposure.drawable = drawable;
+ event.u.noExposure.majorEvent = major;
+ event.u.noExposure.minorEvent = minor;
+ TryClientEvents(client, &event, 1,
+ (Mask)0, NoEventMask, NullGrab);
+ }
+}
+
+
+void
+miSendExposures(pWin, pRgn, dx, dy)
+ WindowPtr pWin;
+ RegionPtr pRgn;
+ register int dx, dy;
+{
+ register BoxPtr pBox;
+ int numRects;
+ register xEvent *pEvent, *pe;
+ register int i;
+
+ pBox = REGION_RECTS(pRgn);
+ numRects = REGION_NUM_RECTS(pRgn);
+ if(!(pEvent = (xEvent *) ALLOCATE_LOCAL(numRects * sizeof(xEvent))))
+ return;
+
+ for (i=numRects, pe = pEvent; --i >= 0; pe++, pBox++)
+ {
+ pe->u.u.type = Expose;
+ pe->u.expose.window = pWin->drawable.id;
+ pe->u.expose.x = pBox->x1 - dx;
+ pe->u.expose.y = pBox->y1 - dy;
+ pe->u.expose.width = pBox->x2 - pBox->x1;
+ pe->u.expose.height = pBox->y2 - pBox->y1;
+ pe->u.expose.count = i;
+ }
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ int scrnum = pWin->drawable.pScreen->myNum;
+ int x = 0, y = 0;
+ XID realWin = 0;
+
+ if(!pWin->parent) {
+ x = panoramiXdataPtr[scrnum].x;
+ y = panoramiXdataPtr[scrnum].y;
+ pWin = WindowTable[0];
+ realWin = pWin->drawable.id;
+ } else if (scrnum) {
+ PanoramiXRes *win;
+ win = PanoramiXFindIDByScrnum(XRT_WINDOW,
+ pWin->drawable.id, scrnum);
+ if(!win) {
+ DEALLOCATE_LOCAL(pEvent);
+ return;
+ }
+ realWin = win->info[0].id;
+ pWin = LookupIDByType(realWin, RT_WINDOW);
+ }
+ if(x || y || scrnum)
+ for (i = 0; i < numRects; i++) {
+ pEvent[i].u.expose.window = realWin;
+ pEvent[i].u.expose.x += x;
+ pEvent[i].u.expose.y += y;
+ }
+ }
+#endif
+
+ DeliverEvents(pWin, pEvent, numRects, NullWindow);
+
+ DEALLOCATE_LOCAL(pEvent);
+}
+
+void
+miWindowExposures(pWin, prgn, other_exposed)
+ WindowPtr pWin;
+ register RegionPtr prgn, other_exposed;
+{
+#ifdef NXAGENT_SERVER
+
+ int total;
+
+#endif
+ RegionPtr exposures = prgn;
+ if (pWin->backStorage && prgn)
+ /*
+ * in some cases, backing store will cause a different
+ * region to be exposed than needs to be repainted
+ * (like when a window is mapped). RestoreAreas is
+ * allowed to return a region other than prgn,
+ * in which case this routine will free the resultant
+ * region. If exposures is null, then no events will
+ * be sent to the client; if prgn is empty
+ * no areas will be repainted.
+ */
+ exposures = (*pWin->drawable.pScreen->RestoreAreas)(pWin, prgn);
+ if ((prgn && !REGION_NIL(prgn)) ||
+ (exposures && !REGION_NIL(exposures)) || other_exposed)
+ {
+ RegionRec expRec;
+ int clientInterested;
+
+ /*
+ * Restore from backing-store FIRST.
+ */
+ clientInterested = (pWin->eventMask|wOtherEventMasks(pWin)) & ExposureMask;
+ if (other_exposed)
+ {
+ if (exposures)
+ {
+ REGION_UNION(pWin->drawable.pScreen, other_exposed,
+ exposures,
+ other_exposed);
+ if (exposures != prgn)
+ REGION_DESTROY(pWin->drawable.pScreen, exposures);
+ }
+ exposures = other_exposed;
+ }
+#ifdef NXAGENT_SERVER
+
+ /*
+ * If the number of rectangles is greater
+ * than 4, let the function decide.
+ */
+
+ total = REGION_NUM_RECTS(exposures);
+
+ if (clientInterested && exposures && (total > RECTLIMIT ||
+ (total > 4 && nxagentExtentsPredicate(total) == 1)))
+#else
+ if (clientInterested && exposures && (REGION_NUM_RECTS(exposures) > RECTLIMIT))
+#endif
+ {
+ /*
+ * If we have LOTS of rectangles, we decide to take the extents
+ * and force an exposure on that. This should require much less
+ * work overall, on both client and server. This is cheating, but
+ * isn't prohibited by the protocol ("spontaneous combustion" :-).
+ */
+ BoxRec box;
+
+ box = *REGION_EXTENTS( pWin->drawable.pScreen, exposures);
+ if (exposures == prgn) {
+ exposures = &expRec;
+ REGION_INIT( pWin->drawable.pScreen, exposures, &box, 1);
+ REGION_RESET( pWin->drawable.pScreen, prgn, &box);
+ } else {
+ REGION_RESET( pWin->drawable.pScreen, exposures, &box);
+ REGION_UNION( pWin->drawable.pScreen, prgn, prgn, exposures);
+ }
+ /* PaintWindowBackground doesn't clip, so we have to */
+ REGION_INTERSECT( pWin->drawable.pScreen, prgn, prgn, &pWin->clipList);
+ /* need to clear out new areas of backing store, too */
+ if (pWin->backStorage)
+ (void) (* pWin->drawable.pScreen->ClearBackingStore)(
+ pWin,
+ box.x1 - pWin->drawable.x,
+ box.y1 - pWin->drawable.y,
+ box.x2 - box.x1,
+ box.y2 - box.y1,
+ FALSE);
+ }
+ if (prgn && !REGION_NIL(prgn))
+ (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, prgn, PW_BACKGROUND);
+ if (clientInterested && exposures && !REGION_NIL(exposures))
+ miSendExposures(pWin, exposures,
+ pWin->drawable.x, pWin->drawable.y);
+ if (exposures == &expRec)
+ {
+ REGION_UNINIT( pWin->drawable.pScreen, exposures);
+ }
+ else if (exposures && exposures != prgn && exposures != other_exposed)
+ REGION_DESTROY( pWin->drawable.pScreen, exposures);
+ if (prgn)
+ REGION_EMPTY( pWin->drawable.pScreen, prgn);
+ }
+ else if (exposures && exposures != prgn)
+ REGION_DESTROY( pWin->drawable.pScreen, exposures);
+}
+
+
+/*
+ this code is highly unlikely. it is not haile selassie.
+
+ there is some hair here. we can't just use the window's
+clip region as it is, because if we are painting the border,
+the border is not in the client area and so we will be excluded
+when we validate the GC, and if we are painting a parent-relative
+background, the area we want to paint is in some other window.
+since we trust the code calling us to tell us to paint only areas
+that are really ours, we will temporarily give the window a
+clipList the size of the whole screen and an origin at (0,0).
+this more or less assumes that ddX code will do translation
+based on the window's absolute position, and that ValidateGC will
+look at clipList, and that no other fields from the
+window will be used. it's not possible to just draw
+in the root because it may be a different depth.
+
+to get the tile to align correctly we set the GC's tile origin to
+be the (x,y) of the window's upper left corner, after which we
+get the right bits when drawing into the root.
+
+because the clip_mask is being set to None, we may call DoChangeGC with
+fPointer set true, thus we no longer need to install the background or
+border tile in the resource table.
+*/
+
+static RESTYPE ResType = 0;
+static int numGCs = 0;
+static GCPtr screenContext[MAXSCREENS];
+
+/*ARGSUSED*/
+static int
+tossGC (
+ pointer value,
+ XID id)
+{
+ GCPtr pGC = (GCPtr)value;
+ screenContext[pGC->pScreen->myNum] = (GCPtr)NULL;
+ FreeGC (pGC, id);
+ numGCs--;
+ if (!numGCs)
+ ResType = 0;
+
+ return 0;
+}
+
+
+void
+miPaintWindow(pWin, prgn, what)
+register WindowPtr pWin;
+RegionPtr prgn;
+int what;
+{
+ int status;
+
+ Bool usingScratchGC = FALSE;
+ WindowPtr pRoot;
+
+#define FUNCTION 0
+#define FOREGROUND 1
+#define TILE 2
+#define FILLSTYLE 3
+#define ABSX 4
+#define ABSY 5
+#define CLIPMASK 6
+#define SUBWINDOW 7
+#define COUNT_BITS 8
+
+ ChangeGCVal gcval[7];
+ ChangeGCVal newValues [COUNT_BITS];
+
+ BITS32 gcmask, index, mask;
+ RegionRec prgnWin;
+ DDXPointRec oldCorner;
+ BoxRec box;
+ WindowPtr pBgWin;
+ GCPtr pGC;
+ register int i;
+ register BoxPtr pbox;
+ register ScreenPtr pScreen = pWin->drawable.pScreen;
+ register xRectangle *prect;
+ int numRects;
+
+#ifdef NXAGENT_SERVER
+
+ /*
+ * Set the elements reported by the compiler
+ * as uninitialized.
+ */
+
+ prgnWin.extents.x1 = 0;
+ prgnWin.extents.y1 = 0;
+ prgnWin.extents.x2 = 0;
+ prgnWin.extents.y2 = 0;
+
+ prgnWin.data = NULL;
+
+ oldCorner.x = 0;
+ oldCorner.y = 0;
+
+#endif
+
+ gcmask = 0;
+
+ if (what == PW_BACKGROUND)
+ {
+ switch (pWin->backgroundState) {
+ case None:
+ return;
+ case ParentRelative:
+ (*pWin->parent->drawable.pScreen->PaintWindowBackground)(pWin->parent, prgn, what);
+ return;
+ case BackgroundPixel:
+ newValues[FOREGROUND].val = pWin->background.pixel;
+ newValues[FILLSTYLE].val = FillSolid;
+ gcmask |= GCForeground | GCFillStyle;
+ break;
+ case BackgroundPixmap:
+ newValues[TILE].ptr = (pointer)pWin->background.pixmap;
+ newValues[FILLSTYLE].val = FillTiled;
+ gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
+ break;
+ }
+ }
+ else
+ {
+ if (pWin->borderIsPixel)
+ {
+ newValues[FOREGROUND].val = pWin->border.pixel;
+ newValues[FILLSTYLE].val = FillSolid;
+ gcmask |= GCForeground | GCFillStyle;
+ }
+ else
+ {
+ newValues[TILE].ptr = (pointer)pWin->border.pixmap;
+ newValues[FILLSTYLE].val = FillTiled;
+ gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
+ }
+ }
+
+ prect = (xRectangle *)ALLOCATE_LOCAL(REGION_NUM_RECTS(prgn) *
+ sizeof(xRectangle));
+ if (!prect)
+ return;
+
+ newValues[FUNCTION].val = GXcopy;
+ gcmask |= GCFunction | GCClipMask;
+
+ i = pScreen->myNum;
+ pRoot = WindowTable[i];
+
+ pBgWin = pWin;
+ if (what == PW_BORDER)
+ {
+ while (pBgWin->backgroundState == ParentRelative)
+ pBgWin = pBgWin->parent;
+ }
+
+ if ((pWin->drawable.depth != pRoot->drawable.depth) ||
+ (pWin->drawable.bitsPerPixel != pRoot->drawable.bitsPerPixel))
+ {
+ usingScratchGC = TRUE;
+ pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
+ if (!pGC)
+ {
+ DEALLOCATE_LOCAL(prect);
+ return;
+ }
+ /*
+ * mash the clip list so we can paint the border by
+ * mangling the window in place, pretending it
+ * spans the entire screen
+ */
+ if (what == PW_BORDER)
+ {
+ prgnWin = pWin->clipList;
+ oldCorner.x = pWin->drawable.x;
+ oldCorner.y = pWin->drawable.y;
+ pWin->drawable.x = pWin->drawable.y = 0;
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pScreen->width;
+ box.y2 = pScreen->height;
+ REGION_INIT(pScreen, &pWin->clipList, &box, 1);
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ newValues[ABSX].val = pBgWin->drawable.x;
+ newValues[ABSY].val = pBgWin->drawable.y;
+ }
+ else
+ {
+ newValues[ABSX].val = 0;
+ newValues[ABSY].val = 0;
+ }
+ } else {
+ /*
+ * draw the background to the root window
+ */
+ if (screenContext[i] == (GCPtr)NULL)
+ {
+ if (!ResType && !(ResType = CreateNewResourceType(tossGC)))
+ return;
+ screenContext[i] = CreateGC((DrawablePtr)pWin, (BITS32) 0,
+ (XID *)NULL, &status);
+ if (!screenContext[i])
+ return;
+ numGCs++;
+ if (!AddResource(FakeClientID(0), ResType,
+ (pointer)screenContext[i]))
+ return;
+ }
+ pGC = screenContext[i];
+ newValues[SUBWINDOW].val = IncludeInferiors;
+ newValues[ABSX].val = pBgWin->drawable.x;
+ newValues[ABSY].val = pBgWin->drawable.y;
+ gcmask |= GCSubwindowMode;
+ pWin = pRoot;
+ }
+
+ if (pWin->backStorage)
+ (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack);
+
+ mask = gcmask;
+ gcmask = 0;
+ i = 0;
+ while (mask) {
+ index = lowbit (mask);
+ mask &= ~index;
+ switch (index) {
+ case GCFunction:
+ if (pGC->alu != newValues[FUNCTION].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[FUNCTION].val;
+ }
+ break;
+ case GCTileStipXOrigin:
+ if ( pGC->patOrg.x != newValues[ABSX].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[ABSX].val;
+ }
+ break;
+ case GCTileStipYOrigin:
+ if ( pGC->patOrg.y != newValues[ABSY].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[ABSY].val;
+ }
+ break;
+ case GCClipMask:
+ if ( pGC->clientClipType != CT_NONE) {
+ gcmask |= index;
+ gcval[i++].val = CT_NONE;
+ }
+ break;
+ case GCSubwindowMode:
+ if ( pGC->subWindowMode != newValues[SUBWINDOW].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[SUBWINDOW].val;
+ }
+ break;
+ case GCTile:
+ if (pGC->tileIsPixel || pGC->tile.pixmap != newValues[TILE].ptr)
+ {
+ gcmask |= index;
+ gcval[i++].ptr = newValues[TILE].ptr;
+ }
+ break;
+ case GCFillStyle:
+ if ( pGC->fillStyle != newValues[FILLSTYLE].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[FILLSTYLE].val;
+ }
+ break;
+ case GCForeground:
+ if ( pGC->fgPixel != newValues[FOREGROUND].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[FOREGROUND].val;
+ }
+ break;
+ }
+ }
+
+ if (gcmask)
+ dixChangeGC(NullClient, pGC, gcmask, NULL, gcval);
+
+ if (pWin->drawable.serialNumber != pGC->serialNumber)
+ ValidateGC((DrawablePtr)pWin, pGC);
+
+ numRects = REGION_NUM_RECTS(prgn);
+ pbox = REGION_RECTS(prgn);
+ for (i= numRects; --i >= 0; pbox++, prect++)
+ {
+ prect->x = pbox->x1 - pWin->drawable.x;
+ prect->y = pbox->y1 - pWin->drawable.y;
+ prect->width = pbox->x2 - pbox->x1;
+ prect->height = pbox->y2 - pbox->y1;
+ }
+ prect -= numRects;
+ (*pGC->ops->PolyFillRect)((DrawablePtr)pWin, pGC, numRects, prect);
+ DEALLOCATE_LOCAL(prect);
+
+ if (pWin->backStorage)
+ (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeNothing);
+
+ if (usingScratchGC)
+ {
+ if (what == PW_BORDER)
+ {
+ REGION_UNINIT(pScreen, &pWin->clipList);
+ pWin->clipList = prgnWin;
+ pWin->drawable.x = oldCorner.x;
+ pWin->drawable.y = oldCorner.y;
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ }
+ FreeScratchGC(pGC);
+ }
+}
+
+
+/* MICLEARDRAWABLE -- sets the entire drawable to the background color of
+ * the GC. Useful when we have a scratch drawable and need to initialize
+ * it. */
+void
+miClearDrawable(pDraw, pGC)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+{
+ XID fg = pGC->fgPixel;
+ XID bg = pGC->bgPixel;
+ xRectangle rect;
+
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = pDraw->width;
+ rect.height = pDraw->height;
+ DoChangeGC(pGC, GCForeground, &bg, 0);
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->PolyFillRect)(pDraw, pGC, 1, &rect);
+ DoChangeGC(pGC, GCForeground, &fg, 0);
+ ValidateGC(pDraw, pGC);
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.NX.original
new file mode 100644
index 000000000..af07fdcc2
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.NX.original
@@ -0,0 +1,979 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/* $XdotOrg: xc/programs/Xserver/mi/miexpose.c,v 1.6 2005/07/03 08:53:51 daniels Exp $ */
+/* $XFree86: xc/programs/Xserver/mi/miexpose.c,v 3.9tsi Exp $ */
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+/* $Xorg: miexpose.c,v 1.4 2001/02/09 02:05:20 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#define NEED_EVENTS
+#include <X11/Xproto.h>
+#include <X11/Xprotostr.h>
+
+#include "misc.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmap.h"
+#include "input.h"
+
+#include "dixstruct.h"
+#include "mi.h"
+#include <X11/Xmd.h>
+
+#include "globals.h"
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+/*
+ machine-independent graphics exposure code. any device that uses
+the region package can call this.
+*/
+
+#ifdef NXAGENT_SERVER
+
+#include "Windows.h"
+
+#endif
+
+#ifndef RECTLIMIT
+#define RECTLIMIT 25 /* pick a number, any number > 8 */
+#endif
+
+/* miHandleExposures
+ generate a region for exposures for areas that were copied from obscured or
+non-existent areas to non-obscured areas of the destination. Paint the
+background for the region, if the destination is a window.
+
+NOTE:
+ this should generally be called, even if graphicsExposures is false,
+because this is where bits get recovered from backing store.
+
+NOTE:
+ added argument 'plane' is used to indicate how exposures from backing
+store should be accomplished. If plane is 0 (i.e. no bit plane), CopyArea
+should be used, else a CopyPlane of the indicated plane will be used. The
+exposing is done by the backing store's GraphicsExpose function, of course.
+
+*/
+
+RegionPtr
+miHandleExposures(pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty, plane)
+ register DrawablePtr pSrcDrawable;
+ register DrawablePtr pDstDrawable;
+ GCPtr pGC;
+ int srcx, srcy;
+ int width, height;
+ int dstx, dsty;
+ unsigned long plane;
+{
+ register ScreenPtr pscr;
+ RegionPtr prgnSrcClip; /* drawable-relative source clip */
+ RegionRec rgnSrcRec;
+ RegionPtr prgnDstClip; /* drawable-relative dest clip */
+ RegionRec rgnDstRec;
+ BoxRec srcBox; /* unclipped source */
+ RegionRec rgnExposed; /* exposed region, calculated source-
+ relative, made dst relative to
+ intersect with visible parts of
+ dest and send events to client,
+ and then screen relative to paint
+ the window background
+ */
+ WindowPtr pSrcWin;
+ BoxRec expBox;
+ Bool extents;
+
+#ifdef NXAGENT_SERVER
+
+ /*
+ * Set the elements reported by the compiler
+ * as uninitialized.
+ */
+
+ expBox.x1 = 0;
+ expBox.y1 = 0;
+ expBox.x2 = 0;
+ expBox.y2 = 0;
+
+#endif
+
+ /* This prevents warning about pscr not being used. */
+ pGC->pScreen = pscr = pGC->pScreen;
+
+ /* avoid work if we can */
+ if (!pGC->graphicsExposures &&
+ (pDstDrawable->type == DRAWABLE_PIXMAP) &&
+ ((pSrcDrawable->type == DRAWABLE_PIXMAP) ||
+ (((WindowPtr)pSrcDrawable)->backStorage == NULL)))
+ return NULL;
+
+ srcBox.x1 = srcx;
+ srcBox.y1 = srcy;
+ srcBox.x2 = srcx+width;
+ srcBox.y2 = srcy+height;
+
+ if (pSrcDrawable->type != DRAWABLE_PIXMAP)
+ {
+ BoxRec TsrcBox;
+
+ TsrcBox.x1 = srcx + pSrcDrawable->x;
+ TsrcBox.y1 = srcy + pSrcDrawable->y;
+ TsrcBox.x2 = TsrcBox.x1 + width;
+ TsrcBox.y2 = TsrcBox.y1 + height;
+ pSrcWin = (WindowPtr) pSrcDrawable;
+ if (pGC->subWindowMode == IncludeInferiors)
+ {
+ prgnSrcClip = NotClippedByChildren (pSrcWin);
+ if ((RECT_IN_REGION(pscr, prgnSrcClip, &TsrcBox)) == rgnIN)
+ {
+ REGION_DESTROY(pscr, prgnSrcClip);
+ return NULL;
+ }
+ }
+ else
+ {
+ if ((RECT_IN_REGION(pscr, &pSrcWin->clipList, &TsrcBox)) == rgnIN)
+ return NULL;
+ prgnSrcClip = &rgnSrcRec;
+ REGION_NULL(pscr, prgnSrcClip);
+ REGION_COPY(pscr, prgnSrcClip, &pSrcWin->clipList);
+ }
+ REGION_TRANSLATE(pscr, prgnSrcClip,
+ -pSrcDrawable->x, -pSrcDrawable->y);
+ }
+ else
+ {
+ BoxRec box;
+
+ if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) &&
+ (srcBox.x2 <= pSrcDrawable->width) &&
+ (srcBox.y2 <= pSrcDrawable->height))
+ return NULL;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pSrcDrawable->width;
+ box.y2 = pSrcDrawable->height;
+ prgnSrcClip = &rgnSrcRec;
+ REGION_INIT(pscr, prgnSrcClip, &box, 1);
+ pSrcWin = (WindowPtr)NULL;
+ }
+
+ if (pDstDrawable == pSrcDrawable)
+ {
+ prgnDstClip = prgnSrcClip;
+ }
+ else if (pDstDrawable->type != DRAWABLE_PIXMAP)
+ {
+ if (pGC->subWindowMode == IncludeInferiors)
+ {
+ prgnDstClip = NotClippedByChildren((WindowPtr)pDstDrawable);
+ }
+ else
+ {
+ prgnDstClip = &rgnDstRec;
+ REGION_NULL(pscr, prgnDstClip);
+ REGION_COPY(pscr, prgnDstClip,
+ &((WindowPtr)pDstDrawable)->clipList);
+ }
+ REGION_TRANSLATE(pscr, prgnDstClip,
+ -pDstDrawable->x, -pDstDrawable->y);
+ }
+ else
+ {
+ BoxRec box;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pDstDrawable->width;
+ box.y2 = pDstDrawable->height;
+ prgnDstClip = &rgnDstRec;
+ REGION_INIT(pscr, prgnDstClip, &box, 1);
+ }
+
+ /* drawable-relative source region */
+ REGION_INIT(pscr, &rgnExposed, &srcBox, 1);
+
+ /* now get the hidden parts of the source box*/
+ REGION_SUBTRACT(pscr, &rgnExposed, &rgnExposed, prgnSrcClip);
+
+ if (pSrcWin && pSrcWin->backStorage)
+ {
+ /*
+ * Copy any areas from the source backing store. Modifies
+ * rgnExposed.
+ */
+ (* pSrcWin->drawable.pScreen->ExposeCopy) ((WindowPtr)pSrcDrawable,
+ pDstDrawable,
+ pGC,
+ &rgnExposed,
+ srcx, srcy,
+ dstx, dsty,
+ plane);
+ }
+
+ /* move them over the destination */
+ REGION_TRANSLATE(pscr, &rgnExposed, dstx-srcx, dsty-srcy);
+
+ /* intersect with visible areas of dest */
+ REGION_INTERSECT(pscr, &rgnExposed, &rgnExposed, prgnDstClip);
+
+ /*
+ * If we have LOTS of rectangles, we decide to take the extents
+ * and force an exposure on that. This should require much less
+ * work overall, on both client and server. This is cheating, but
+ * isn't prohibited by the protocol ("spontaneous combustion" :-)
+ * for windows.
+ */
+ extents = pGC->graphicsExposures &&
+ (REGION_NUM_RECTS(&rgnExposed) > RECTLIMIT) &&
+ (pDstDrawable->type != DRAWABLE_PIXMAP);
+#ifdef SHAPE
+ if (pSrcWin)
+ {
+ RegionPtr region;
+ if (!(region = wClipShape (pSrcWin)))
+ region = wBoundingShape (pSrcWin);
+ /*
+ * If you try to CopyArea the extents of a shaped window, compacting the
+ * exposed region will undo all our work!
+ */
+ if (extents && pSrcWin && region &&
+ (RECT_IN_REGION(pscr, region, &srcBox) != rgnIN))
+ extents = FALSE;
+ }
+#endif
+ if (extents)
+ {
+ WindowPtr pWin = (WindowPtr)pDstDrawable;
+
+ expBox = *REGION_EXTENTS(pscr, &rgnExposed);
+ REGION_RESET(pscr, &rgnExposed, &expBox);
+ /* need to clear out new areas of backing store */
+ if (pWin->backStorage)
+ (void) (* pWin->drawable.pScreen->ClearBackingStore)(
+ pWin,
+ expBox.x1,
+ expBox.y1,
+ expBox.x2 - expBox.x1,
+ expBox.y2 - expBox.y1,
+ FALSE);
+ }
+ if ((pDstDrawable->type != DRAWABLE_PIXMAP) &&
+ (((WindowPtr)pDstDrawable)->backgroundState != None))
+ {
+ WindowPtr pWin = (WindowPtr)pDstDrawable;
+
+ /* make the exposed area screen-relative */
+ REGION_TRANSLATE(pscr, &rgnExposed,
+ pDstDrawable->x, pDstDrawable->y);
+
+ if (extents)
+ {
+ /* PaintWindowBackground doesn't clip, so we have to */
+ REGION_INTERSECT(pscr, &rgnExposed, &rgnExposed, &pWin->clipList);
+ }
+ (*pWin->drawable.pScreen->PaintWindowBackground)(
+ (WindowPtr)pDstDrawable, &rgnExposed, PW_BACKGROUND);
+
+ if (extents)
+ {
+ REGION_RESET(pscr, &rgnExposed, &expBox);
+ }
+ else
+ REGION_TRANSLATE(pscr, &rgnExposed,
+ -pDstDrawable->x, -pDstDrawable->y);
+ }
+ if (prgnDstClip == &rgnDstRec)
+ {
+ REGION_UNINIT(pscr, prgnDstClip);
+ }
+ else if (prgnDstClip != prgnSrcClip)
+ {
+ REGION_DESTROY(pscr, prgnDstClip);
+ }
+
+ if (prgnSrcClip == &rgnSrcRec)
+ {
+ REGION_UNINIT(pscr, prgnSrcClip);
+ }
+ else
+ {
+ REGION_DESTROY(pscr, prgnSrcClip);
+ }
+
+ if (pGC->graphicsExposures)
+ {
+ /* don't look */
+ RegionPtr exposed = REGION_CREATE(pscr, NullBox, 0);
+ *exposed = rgnExposed;
+ return exposed;
+ }
+ else
+ {
+ REGION_UNINIT(pscr, &rgnExposed);
+ return NULL;
+ }
+}
+
+/* send GraphicsExpose events, or a NoExpose event, based on the region */
+
+void
+miSendGraphicsExpose (client, pRgn, drawable, major, minor)
+ ClientPtr client;
+ RegionPtr pRgn;
+ XID drawable;
+ int major;
+ int minor;
+{
+ if (pRgn && !REGION_NIL(pRgn))
+ {
+ xEvent *pEvent;
+ register xEvent *pe;
+ register BoxPtr pBox;
+ register int i;
+ int numRects;
+
+ numRects = REGION_NUM_RECTS(pRgn);
+ pBox = REGION_RECTS(pRgn);
+ if(!(pEvent = (xEvent *)ALLOCATE_LOCAL(numRects * sizeof(xEvent))))
+ return;
+ pe = pEvent;
+
+ for (i=1; i<=numRects; i++, pe++, pBox++)
+ {
+ pe->u.u.type = GraphicsExpose;
+ pe->u.graphicsExposure.drawable = drawable;
+ pe->u.graphicsExposure.x = pBox->x1;
+ pe->u.graphicsExposure.y = pBox->y1;
+ pe->u.graphicsExposure.width = pBox->x2 - pBox->x1;
+ pe->u.graphicsExposure.height = pBox->y2 - pBox->y1;
+ pe->u.graphicsExposure.count = numRects - i;
+ pe->u.graphicsExposure.majorEvent = major;
+ pe->u.graphicsExposure.minorEvent = minor;
+ }
+ TryClientEvents(client, pEvent, numRects,
+ (Mask)0, NoEventMask, NullGrab);
+ DEALLOCATE_LOCAL(pEvent);
+ }
+ else
+ {
+ xEvent event;
+ event.u.u.type = NoExpose;
+ event.u.noExposure.drawable = drawable;
+ event.u.noExposure.majorEvent = major;
+ event.u.noExposure.minorEvent = minor;
+ TryClientEvents(client, &event, 1,
+ (Mask)0, NoEventMask, NullGrab);
+ }
+}
+
+
+void
+miSendExposures(pWin, pRgn, dx, dy)
+ WindowPtr pWin;
+ RegionPtr pRgn;
+ register int dx, dy;
+{
+ register BoxPtr pBox;
+ int numRects;
+ register xEvent *pEvent, *pe;
+ register int i;
+
+ pBox = REGION_RECTS(pRgn);
+ numRects = REGION_NUM_RECTS(pRgn);
+ if(!(pEvent = (xEvent *) ALLOCATE_LOCAL(numRects * sizeof(xEvent))))
+ return;
+
+ for (i=numRects, pe = pEvent; --i >= 0; pe++, pBox++)
+ {
+ pe->u.u.type = Expose;
+ pe->u.expose.window = pWin->drawable.id;
+ pe->u.expose.x = pBox->x1 - dx;
+ pe->u.expose.y = pBox->y1 - dy;
+ pe->u.expose.width = pBox->x2 - pBox->x1;
+ pe->u.expose.height = pBox->y2 - pBox->y1;
+ pe->u.expose.count = i;
+ }
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ int scrnum = pWin->drawable.pScreen->myNum;
+ int x = 0, y = 0;
+ XID realWin = 0;
+
+ if(!pWin->parent) {
+ x = panoramiXdataPtr[scrnum].x;
+ y = panoramiXdataPtr[scrnum].y;
+ pWin = WindowTable[0];
+ realWin = pWin->drawable.id;
+ } else if (scrnum) {
+ PanoramiXRes *win;
+ win = PanoramiXFindIDByScrnum(XRT_WINDOW,
+ pWin->drawable.id, scrnum);
+ if(!win) {
+ DEALLOCATE_LOCAL(pEvent);
+ return;
+ }
+ realWin = win->info[0].id;
+ pWin = LookupIDByType(realWin, RT_WINDOW);
+ }
+ if(x || y || scrnum)
+ for (i = 0; i < numRects; i++) {
+ pEvent[i].u.expose.window = realWin;
+ pEvent[i].u.expose.x += x;
+ pEvent[i].u.expose.y += y;
+ }
+ }
+#endif
+
+ DeliverEvents(pWin, pEvent, numRects, NullWindow);
+
+ DEALLOCATE_LOCAL(pEvent);
+}
+
+void
+miWindowExposures(pWin, prgn, other_exposed)
+ WindowPtr pWin;
+ register RegionPtr prgn, other_exposed;
+{
+#ifdef NXAGENT_SERVER
+
+ int total;
+
+#endif
+ RegionPtr exposures = prgn;
+ if (pWin->backStorage && prgn)
+ /*
+ * in some cases, backing store will cause a different
+ * region to be exposed than needs to be repainted
+ * (like when a window is mapped). RestoreAreas is
+ * allowed to return a region other than prgn,
+ * in which case this routine will free the resultant
+ * region. If exposures is null, then no events will
+ * be sent to the client; if prgn is empty
+ * no areas will be repainted.
+ */
+ exposures = (*pWin->drawable.pScreen->RestoreAreas)(pWin, prgn);
+ if ((prgn && !REGION_NIL(prgn)) ||
+ (exposures && !REGION_NIL(exposures)) || other_exposed)
+ {
+ RegionRec expRec;
+ int clientInterested;
+
+ /*
+ * Restore from backing-store FIRST.
+ */
+ clientInterested = (pWin->eventMask|wOtherEventMasks(pWin)) & ExposureMask;
+ if (other_exposed)
+ {
+ if (exposures)
+ {
+ REGION_UNION(pWin->drawable.pScreen, other_exposed,
+ exposures,
+ other_exposed);
+ if (exposures != prgn)
+ REGION_DESTROY(pWin->drawable.pScreen, exposures);
+ }
+ exposures = other_exposed;
+ }
+#ifdef NXAGENT_SERVER
+
+ /*
+ * If the number of rectangles is greater
+ * than 4, let the function decide.
+ */
+
+ total = REGION_NUM_RECTS(exposures);
+
+ if (clientInterested && exposures && (total > RECTLIMIT ||
+ (total > 4 && nxagentExtentsPredicate(total) == 1)))
+#else
+ if (clientInterested && exposures && (REGION_NUM_RECTS(exposures) > RECTLIMIT))
+#endif
+ {
+ /*
+ * If we have LOTS of rectangles, we decide to take the extents
+ * and force an exposure on that. This should require much less
+ * work overall, on both client and server. This is cheating, but
+ * isn't prohibited by the protocol ("spontaneous combustion" :-).
+ */
+ BoxRec box;
+
+ box = *REGION_EXTENTS( pWin->drawable.pScreen, exposures);
+ if (exposures == prgn) {
+ exposures = &expRec;
+ REGION_INIT( pWin->drawable.pScreen, exposures, &box, 1);
+ REGION_RESET( pWin->drawable.pScreen, prgn, &box);
+ } else {
+ REGION_RESET( pWin->drawable.pScreen, exposures, &box);
+ REGION_UNION( pWin->drawable.pScreen, prgn, prgn, exposures);
+ }
+ /* PaintWindowBackground doesn't clip, so we have to */
+ REGION_INTERSECT( pWin->drawable.pScreen, prgn, prgn, &pWin->clipList);
+ /* need to clear out new areas of backing store, too */
+ if (pWin->backStorage)
+ (void) (* pWin->drawable.pScreen->ClearBackingStore)(
+ pWin,
+ box.x1 - pWin->drawable.x,
+ box.y1 - pWin->drawable.y,
+ box.x2 - box.x1,
+ box.y2 - box.y1,
+ FALSE);
+ }
+ if (prgn && !REGION_NIL(prgn))
+ (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, prgn, PW_BACKGROUND);
+ if (clientInterested && exposures && !REGION_NIL(exposures))
+ miSendExposures(pWin, exposures,
+ pWin->drawable.x, pWin->drawable.y);
+ if (exposures == &expRec)
+ {
+ REGION_UNINIT( pWin->drawable.pScreen, exposures);
+ }
+ else if (exposures && exposures != prgn && exposures != other_exposed)
+ REGION_DESTROY( pWin->drawable.pScreen, exposures);
+ if (prgn)
+ REGION_EMPTY( pWin->drawable.pScreen, prgn);
+ }
+ else if (exposures && exposures != prgn)
+ REGION_DESTROY( pWin->drawable.pScreen, exposures);
+}
+
+
+/*
+ this code is highly unlikely. it is not haile selassie.
+
+ there is some hair here. we can't just use the window's
+clip region as it is, because if we are painting the border,
+the border is not in the client area and so we will be excluded
+when we validate the GC, and if we are painting a parent-relative
+background, the area we want to paint is in some other window.
+since we trust the code calling us to tell us to paint only areas
+that are really ours, we will temporarily give the window a
+clipList the size of the whole screen and an origin at (0,0).
+this more or less assumes that ddX code will do translation
+based on the window's absolute position, and that ValidateGC will
+look at clipList, and that no other fields from the
+window will be used. it's not possible to just draw
+in the root because it may be a different depth.
+
+to get the tile to align correctly we set the GC's tile origin to
+be the (x,y) of the window's upper left corner, after which we
+get the right bits when drawing into the root.
+
+because the clip_mask is being set to None, we may call DoChangeGC with
+fPointer set true, thus we no longer need to install the background or
+border tile in the resource table.
+*/
+
+static RESTYPE ResType = 0;
+static int numGCs = 0;
+static GCPtr screenContext[MAXSCREENS];
+
+/*ARGSUSED*/
+static int
+tossGC (
+ pointer value,
+ XID id)
+{
+ GCPtr pGC = (GCPtr)value;
+ screenContext[pGC->pScreen->myNum] = (GCPtr)NULL;
+ FreeGC (pGC, id);
+ numGCs--;
+ if (!numGCs)
+ ResType = 0;
+
+ return 0;
+}
+
+
+void
+miPaintWindow(pWin, prgn, what)
+register WindowPtr pWin;
+RegionPtr prgn;
+int what;
+{
+ int status;
+
+ Bool usingScratchGC = FALSE;
+ WindowPtr pRoot;
+
+#define FUNCTION 0
+#define FOREGROUND 1
+#define TILE 2
+#define FILLSTYLE 3
+#define ABSX 4
+#define ABSY 5
+#define CLIPMASK 6
+#define SUBWINDOW 7
+#define COUNT_BITS 8
+
+ ChangeGCVal gcval[7];
+ ChangeGCVal newValues [COUNT_BITS];
+
+ BITS32 gcmask, index, mask;
+ RegionRec prgnWin;
+ DDXPointRec oldCorner;
+ BoxRec box;
+ WindowPtr pBgWin;
+ GCPtr pGC;
+ register int i;
+ register BoxPtr pbox;
+ register ScreenPtr pScreen = pWin->drawable.pScreen;
+ register xRectangle *prect;
+ int numRects;
+
+#ifdef NXAGENT_SERVER
+
+ /*
+ * Set the elements reported by the compiler
+ * as uninitialized.
+ */
+
+ prgnWin.extents.x1 = 0;
+ prgnWin.extents.y1 = 0;
+ prgnWin.extents.x2 = 0;
+ prgnWin.extents.y2 = 0;
+
+ prgnWin.data = NULL;
+
+ oldCorner.x = 0;
+ oldCorner.y = 0;
+
+#endif
+
+ gcmask = 0;
+
+ if (what == PW_BACKGROUND)
+ {
+ switch (pWin->backgroundState) {
+ case None:
+ return;
+ case ParentRelative:
+ (*pWin->parent->drawable.pScreen->PaintWindowBackground)(pWin->parent, prgn, what);
+ return;
+ case BackgroundPixel:
+ newValues[FOREGROUND].val = pWin->background.pixel;
+ newValues[FILLSTYLE].val = FillSolid;
+ gcmask |= GCForeground | GCFillStyle;
+ break;
+ case BackgroundPixmap:
+ newValues[TILE].ptr = (pointer)pWin->background.pixmap;
+ newValues[FILLSTYLE].val = FillTiled;
+ gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
+ break;
+ }
+ }
+ else
+ {
+ if (pWin->borderIsPixel)
+ {
+ newValues[FOREGROUND].val = pWin->border.pixel;
+ newValues[FILLSTYLE].val = FillSolid;
+ gcmask |= GCForeground | GCFillStyle;
+ }
+ else
+ {
+ newValues[TILE].ptr = (pointer)pWin->border.pixmap;
+ newValues[FILLSTYLE].val = FillTiled;
+ gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
+ }
+ }
+
+ prect = (xRectangle *)ALLOCATE_LOCAL(REGION_NUM_RECTS(prgn) *
+ sizeof(xRectangle));
+ if (!prect)
+ return;
+
+ newValues[FUNCTION].val = GXcopy;
+ gcmask |= GCFunction | GCClipMask;
+
+ i = pScreen->myNum;
+ pRoot = WindowTable[i];
+
+ pBgWin = pWin;
+ if (what == PW_BORDER)
+ {
+ while (pBgWin->backgroundState == ParentRelative)
+ pBgWin = pBgWin->parent;
+ }
+
+ if ((pWin->drawable.depth != pRoot->drawable.depth) ||
+ (pWin->drawable.bitsPerPixel != pRoot->drawable.bitsPerPixel))
+ {
+ usingScratchGC = TRUE;
+ pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
+ if (!pGC)
+ {
+ DEALLOCATE_LOCAL(prect);
+ return;
+ }
+ /*
+ * mash the clip list so we can paint the border by
+ * mangling the window in place, pretending it
+ * spans the entire screen
+ */
+ if (what == PW_BORDER)
+ {
+ prgnWin = pWin->clipList;
+ oldCorner.x = pWin->drawable.x;
+ oldCorner.y = pWin->drawable.y;
+ pWin->drawable.x = pWin->drawable.y = 0;
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pScreen->width;
+ box.y2 = pScreen->height;
+ REGION_INIT(pScreen, &pWin->clipList, &box, 1);
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ newValues[ABSX].val = pBgWin->drawable.x;
+ newValues[ABSY].val = pBgWin->drawable.y;
+ }
+ else
+ {
+ newValues[ABSX].val = 0;
+ newValues[ABSY].val = 0;
+ }
+ } else {
+ /*
+ * draw the background to the root window
+ */
+ if (screenContext[i] == (GCPtr)NULL)
+ {
+ if (!ResType && !(ResType = CreateNewResourceType(tossGC)))
+ return;
+ screenContext[i] = CreateGC((DrawablePtr)pWin, (BITS32) 0,
+ (XID *)NULL, &status);
+ if (!screenContext[i])
+ return;
+ numGCs++;
+ if (!AddResource(FakeClientID(0), ResType,
+ (pointer)screenContext[i]))
+ return;
+ }
+ pGC = screenContext[i];
+ newValues[SUBWINDOW].val = IncludeInferiors;
+ newValues[ABSX].val = pBgWin->drawable.x;
+ newValues[ABSY].val = pBgWin->drawable.y;
+ gcmask |= GCSubwindowMode;
+ pWin = pRoot;
+ }
+
+ if (pWin->backStorage)
+ (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack);
+
+ mask = gcmask;
+ gcmask = 0;
+ i = 0;
+ while (mask) {
+ index = lowbit (mask);
+ mask &= ~index;
+ switch (index) {
+ case GCFunction:
+ if (pGC->alu != newValues[FUNCTION].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[FUNCTION].val;
+ }
+ break;
+ case GCTileStipXOrigin:
+ if ( pGC->patOrg.x != newValues[ABSX].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[ABSX].val;
+ }
+ break;
+ case GCTileStipYOrigin:
+ if ( pGC->patOrg.y != newValues[ABSY].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[ABSY].val;
+ }
+ break;
+ case GCClipMask:
+ if ( pGC->clientClipType != CT_NONE) {
+ gcmask |= index;
+ gcval[i++].val = CT_NONE;
+ }
+ break;
+ case GCSubwindowMode:
+ if ( pGC->subWindowMode != newValues[SUBWINDOW].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[SUBWINDOW].val;
+ }
+ break;
+ case GCTile:
+ if (pGC->tileIsPixel || pGC->tile.pixmap != newValues[TILE].ptr)
+ {
+ gcmask |= index;
+ gcval[i++].ptr = newValues[TILE].ptr;
+ }
+ break;
+ case GCFillStyle:
+ if ( pGC->fillStyle != newValues[FILLSTYLE].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[FILLSTYLE].val;
+ }
+ break;
+ case GCForeground:
+ if ( pGC->fgPixel != newValues[FOREGROUND].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[FOREGROUND].val;
+ }
+ break;
+ }
+ }
+
+ if (gcmask)
+ dixChangeGC(NullClient, pGC, gcmask, NULL, gcval);
+
+ if (pWin->drawable.serialNumber != pGC->serialNumber)
+ ValidateGC((DrawablePtr)pWin, pGC);
+
+ numRects = REGION_NUM_RECTS(prgn);
+ pbox = REGION_RECTS(prgn);
+ for (i= numRects; --i >= 0; pbox++, prect++)
+ {
+ prect->x = pbox->x1 - pWin->drawable.x;
+ prect->y = pbox->y1 - pWin->drawable.y;
+ prect->width = pbox->x2 - pbox->x1;
+ prect->height = pbox->y2 - pbox->y1;
+ }
+ prect -= numRects;
+ (*pGC->ops->PolyFillRect)((DrawablePtr)pWin, pGC, numRects, prect);
+ DEALLOCATE_LOCAL(prect);
+
+ if (pWin->backStorage)
+ (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeNothing);
+
+ if (usingScratchGC)
+ {
+ if (what == PW_BORDER)
+ {
+ REGION_UNINIT(pScreen, &pWin->clipList);
+ pWin->clipList = prgnWin;
+ pWin->drawable.x = oldCorner.x;
+ pWin->drawable.y = oldCorner.y;
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ }
+ FreeScratchGC(pGC);
+ }
+}
+
+
+/* MICLEARDRAWABLE -- sets the entire drawable to the background color of
+ * the GC. Useful when we have a scratch drawable and need to initialize
+ * it. */
+void
+miClearDrawable(pDraw, pGC)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+{
+ XID fg = pGC->fgPixel;
+ XID bg = pGC->bgPixel;
+ xRectangle rect;
+
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = pDraw->width;
+ rect.height = pDraw->height;
+ DoChangeGC(pGC, GCForeground, &bg, 0);
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->PolyFillRect)(pDraw, pGC, 1, &rect);
+ DoChangeGC(pGC, GCForeground, &fg, 0);
+ ValidateGC(pDraw, pGC);
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.X.original
new file mode 100644
index 000000000..9a0bd06b5
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.X.original
@@ -0,0 +1,905 @@
+/* $XdotOrg: xc/programs/Xserver/mi/miexpose.c,v 1.6 2005/07/03 08:53:51 daniels Exp $ */
+/* $XFree86: xc/programs/Xserver/mi/miexpose.c,v 3.9tsi Exp $ */
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+/* $Xorg: miexpose.c,v 1.4 2001/02/09 02:05:20 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#define NEED_EVENTS
+#include <X11/Xproto.h>
+#include <X11/Xprotostr.h>
+
+#include "misc.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmap.h"
+#include "input.h"
+
+#include "dixstruct.h"
+#include "mi.h"
+#include <X11/Xmd.h>
+
+#include "globals.h"
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+/*
+ machine-independent graphics exposure code. any device that uses
+the region package can call this.
+*/
+
+#ifndef RECTLIMIT
+#define RECTLIMIT 25 /* pick a number, any number > 8 */
+#endif
+
+/* miHandleExposures
+ generate a region for exposures for areas that were copied from obscured or
+non-existent areas to non-obscured areas of the destination. Paint the
+background for the region, if the destination is a window.
+
+NOTE:
+ this should generally be called, even if graphicsExposures is false,
+because this is where bits get recovered from backing store.
+
+NOTE:
+ added argument 'plane' is used to indicate how exposures from backing
+store should be accomplished. If plane is 0 (i.e. no bit plane), CopyArea
+should be used, else a CopyPlane of the indicated plane will be used. The
+exposing is done by the backing store's GraphicsExpose function, of course.
+
+*/
+
+RegionPtr
+miHandleExposures(pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty, plane)
+ register DrawablePtr pSrcDrawable;
+ register DrawablePtr pDstDrawable;
+ GCPtr pGC;
+ int srcx, srcy;
+ int width, height;
+ int dstx, dsty;
+ unsigned long plane;
+{
+ register ScreenPtr pscr;
+ RegionPtr prgnSrcClip; /* drawable-relative source clip */
+ RegionRec rgnSrcRec;
+ RegionPtr prgnDstClip; /* drawable-relative dest clip */
+ RegionRec rgnDstRec;
+ BoxRec srcBox; /* unclipped source */
+ RegionRec rgnExposed; /* exposed region, calculated source-
+ relative, made dst relative to
+ intersect with visible parts of
+ dest and send events to client,
+ and then screen relative to paint
+ the window background
+ */
+ WindowPtr pSrcWin;
+ BoxRec expBox;
+ Bool extents;
+
+ /* This prevents warning about pscr not being used. */
+ pGC->pScreen = pscr = pGC->pScreen;
+
+ /* avoid work if we can */
+ if (!pGC->graphicsExposures &&
+ (pDstDrawable->type == DRAWABLE_PIXMAP) &&
+ ((pSrcDrawable->type == DRAWABLE_PIXMAP) ||
+ (((WindowPtr)pSrcDrawable)->backStorage == NULL)))
+ return NULL;
+
+ srcBox.x1 = srcx;
+ srcBox.y1 = srcy;
+ srcBox.x2 = srcx+width;
+ srcBox.y2 = srcy+height;
+
+ if (pSrcDrawable->type != DRAWABLE_PIXMAP)
+ {
+ BoxRec TsrcBox;
+
+ TsrcBox.x1 = srcx + pSrcDrawable->x;
+ TsrcBox.y1 = srcy + pSrcDrawable->y;
+ TsrcBox.x2 = TsrcBox.x1 + width;
+ TsrcBox.y2 = TsrcBox.y1 + height;
+ pSrcWin = (WindowPtr) pSrcDrawable;
+ if (pGC->subWindowMode == IncludeInferiors)
+ {
+ prgnSrcClip = NotClippedByChildren (pSrcWin);
+ if ((RECT_IN_REGION(pscr, prgnSrcClip, &TsrcBox)) == rgnIN)
+ {
+ REGION_DESTROY(pscr, prgnSrcClip);
+ return NULL;
+ }
+ }
+ else
+ {
+ if ((RECT_IN_REGION(pscr, &pSrcWin->clipList, &TsrcBox)) == rgnIN)
+ return NULL;
+ prgnSrcClip = &rgnSrcRec;
+ REGION_NULL(pscr, prgnSrcClip);
+ REGION_COPY(pscr, prgnSrcClip, &pSrcWin->clipList);
+ }
+ REGION_TRANSLATE(pscr, prgnSrcClip,
+ -pSrcDrawable->x, -pSrcDrawable->y);
+ }
+ else
+ {
+ BoxRec box;
+
+ if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) &&
+ (srcBox.x2 <= pSrcDrawable->width) &&
+ (srcBox.y2 <= pSrcDrawable->height))
+ return NULL;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pSrcDrawable->width;
+ box.y2 = pSrcDrawable->height;
+ prgnSrcClip = &rgnSrcRec;
+ REGION_INIT(pscr, prgnSrcClip, &box, 1);
+ pSrcWin = (WindowPtr)NULL;
+ }
+
+ if (pDstDrawable == pSrcDrawable)
+ {
+ prgnDstClip = prgnSrcClip;
+ }
+ else if (pDstDrawable->type != DRAWABLE_PIXMAP)
+ {
+ if (pGC->subWindowMode == IncludeInferiors)
+ {
+ prgnDstClip = NotClippedByChildren((WindowPtr)pDstDrawable);
+ }
+ else
+ {
+ prgnDstClip = &rgnDstRec;
+ REGION_NULL(pscr, prgnDstClip);
+ REGION_COPY(pscr, prgnDstClip,
+ &((WindowPtr)pDstDrawable)->clipList);
+ }
+ REGION_TRANSLATE(pscr, prgnDstClip,
+ -pDstDrawable->x, -pDstDrawable->y);
+ }
+ else
+ {
+ BoxRec box;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pDstDrawable->width;
+ box.y2 = pDstDrawable->height;
+ prgnDstClip = &rgnDstRec;
+ REGION_INIT(pscr, prgnDstClip, &box, 1);
+ }
+
+ /* drawable-relative source region */
+ REGION_INIT(pscr, &rgnExposed, &srcBox, 1);
+
+ /* now get the hidden parts of the source box*/
+ REGION_SUBTRACT(pscr, &rgnExposed, &rgnExposed, prgnSrcClip);
+
+ if (pSrcWin && pSrcWin->backStorage)
+ {
+ /*
+ * Copy any areas from the source backing store. Modifies
+ * rgnExposed.
+ */
+ (* pSrcWin->drawable.pScreen->ExposeCopy) ((WindowPtr)pSrcDrawable,
+ pDstDrawable,
+ pGC,
+ &rgnExposed,
+ srcx, srcy,
+ dstx, dsty,
+ plane);
+ }
+
+ /* move them over the destination */
+ REGION_TRANSLATE(pscr, &rgnExposed, dstx-srcx, dsty-srcy);
+
+ /* intersect with visible areas of dest */
+ REGION_INTERSECT(pscr, &rgnExposed, &rgnExposed, prgnDstClip);
+
+ /*
+ * If we have LOTS of rectangles, we decide to take the extents
+ * and force an exposure on that. This should require much less
+ * work overall, on both client and server. This is cheating, but
+ * isn't prohibited by the protocol ("spontaneous combustion" :-)
+ * for windows.
+ */
+ extents = pGC->graphicsExposures &&
+ (REGION_NUM_RECTS(&rgnExposed) > RECTLIMIT) &&
+ (pDstDrawable->type != DRAWABLE_PIXMAP);
+#ifdef SHAPE
+ if (pSrcWin)
+ {
+ RegionPtr region;
+ if (!(region = wClipShape (pSrcWin)))
+ region = wBoundingShape (pSrcWin);
+ /*
+ * If you try to CopyArea the extents of a shaped window, compacting the
+ * exposed region will undo all our work!
+ */
+ if (extents && pSrcWin && region &&
+ (RECT_IN_REGION(pscr, region, &srcBox) != rgnIN))
+ extents = FALSE;
+ }
+#endif
+ if (extents)
+ {
+ WindowPtr pWin = (WindowPtr)pDstDrawable;
+
+ expBox = *REGION_EXTENTS(pscr, &rgnExposed);
+ REGION_RESET(pscr, &rgnExposed, &expBox);
+ /* need to clear out new areas of backing store */
+ if (pWin->backStorage)
+ (void) (* pWin->drawable.pScreen->ClearBackingStore)(
+ pWin,
+ expBox.x1,
+ expBox.y1,
+ expBox.x2 - expBox.x1,
+ expBox.y2 - expBox.y1,
+ FALSE);
+ }
+ if ((pDstDrawable->type != DRAWABLE_PIXMAP) &&
+ (((WindowPtr)pDstDrawable)->backgroundState != None))
+ {
+ WindowPtr pWin = (WindowPtr)pDstDrawable;
+
+ /* make the exposed area screen-relative */
+ REGION_TRANSLATE(pscr, &rgnExposed,
+ pDstDrawable->x, pDstDrawable->y);
+
+ if (extents)
+ {
+ /* PaintWindowBackground doesn't clip, so we have to */
+ REGION_INTERSECT(pscr, &rgnExposed, &rgnExposed, &pWin->clipList);
+ }
+ (*pWin->drawable.pScreen->PaintWindowBackground)(
+ (WindowPtr)pDstDrawable, &rgnExposed, PW_BACKGROUND);
+
+ if (extents)
+ {
+ REGION_RESET(pscr, &rgnExposed, &expBox);
+ }
+ else
+ REGION_TRANSLATE(pscr, &rgnExposed,
+ -pDstDrawable->x, -pDstDrawable->y);
+ }
+ if (prgnDstClip == &rgnDstRec)
+ {
+ REGION_UNINIT(pscr, prgnDstClip);
+ }
+ else if (prgnDstClip != prgnSrcClip)
+ {
+ REGION_DESTROY(pscr, prgnDstClip);
+ }
+
+ if (prgnSrcClip == &rgnSrcRec)
+ {
+ REGION_UNINIT(pscr, prgnSrcClip);
+ }
+ else
+ {
+ REGION_DESTROY(pscr, prgnSrcClip);
+ }
+
+ if (pGC->graphicsExposures)
+ {
+ /* don't look */
+ RegionPtr exposed = REGION_CREATE(pscr, NullBox, 0);
+ *exposed = rgnExposed;
+ return exposed;
+ }
+ else
+ {
+ REGION_UNINIT(pscr, &rgnExposed);
+ return NULL;
+ }
+}
+
+/* send GraphicsExpose events, or a NoExpose event, based on the region */
+
+void
+miSendGraphicsExpose (client, pRgn, drawable, major, minor)
+ ClientPtr client;
+ RegionPtr pRgn;
+ XID drawable;
+ int major;
+ int minor;
+{
+ if (pRgn && !REGION_NIL(pRgn))
+ {
+ xEvent *pEvent;
+ register xEvent *pe;
+ register BoxPtr pBox;
+ register int i;
+ int numRects;
+
+ numRects = REGION_NUM_RECTS(pRgn);
+ pBox = REGION_RECTS(pRgn);
+ if(!(pEvent = (xEvent *)ALLOCATE_LOCAL(numRects * sizeof(xEvent))))
+ return;
+ pe = pEvent;
+
+ for (i=1; i<=numRects; i++, pe++, pBox++)
+ {
+ pe->u.u.type = GraphicsExpose;
+ pe->u.graphicsExposure.drawable = drawable;
+ pe->u.graphicsExposure.x = pBox->x1;
+ pe->u.graphicsExposure.y = pBox->y1;
+ pe->u.graphicsExposure.width = pBox->x2 - pBox->x1;
+ pe->u.graphicsExposure.height = pBox->y2 - pBox->y1;
+ pe->u.graphicsExposure.count = numRects - i;
+ pe->u.graphicsExposure.majorEvent = major;
+ pe->u.graphicsExposure.minorEvent = minor;
+ }
+ TryClientEvents(client, pEvent, numRects,
+ (Mask)0, NoEventMask, NullGrab);
+ DEALLOCATE_LOCAL(pEvent);
+ }
+ else
+ {
+ xEvent event;
+ event.u.u.type = NoExpose;
+ event.u.noExposure.drawable = drawable;
+ event.u.noExposure.majorEvent = major;
+ event.u.noExposure.minorEvent = minor;
+ TryClientEvents(client, &event, 1,
+ (Mask)0, NoEventMask, NullGrab);
+ }
+}
+
+
+void
+miSendExposures(pWin, pRgn, dx, dy)
+ WindowPtr pWin;
+ RegionPtr pRgn;
+ register int dx, dy;
+{
+ register BoxPtr pBox;
+ int numRects;
+ register xEvent *pEvent, *pe;
+ register int i;
+
+ pBox = REGION_RECTS(pRgn);
+ numRects = REGION_NUM_RECTS(pRgn);
+ if(!(pEvent = (xEvent *) ALLOCATE_LOCAL(numRects * sizeof(xEvent))))
+ return;
+
+ for (i=numRects, pe = pEvent; --i >= 0; pe++, pBox++)
+ {
+ pe->u.u.type = Expose;
+ pe->u.expose.window = pWin->drawable.id;
+ pe->u.expose.x = pBox->x1 - dx;
+ pe->u.expose.y = pBox->y1 - dy;
+ pe->u.expose.width = pBox->x2 - pBox->x1;
+ pe->u.expose.height = pBox->y2 - pBox->y1;
+ pe->u.expose.count = i;
+ }
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ int scrnum = pWin->drawable.pScreen->myNum;
+ int x = 0, y = 0;
+ XID realWin = 0;
+
+ if(!pWin->parent) {
+ x = panoramiXdataPtr[scrnum].x;
+ y = panoramiXdataPtr[scrnum].y;
+ pWin = WindowTable[0];
+ realWin = pWin->drawable.id;
+ } else if (scrnum) {
+ PanoramiXRes *win;
+ win = PanoramiXFindIDByScrnum(XRT_WINDOW,
+ pWin->drawable.id, scrnum);
+ if(!win) {
+ DEALLOCATE_LOCAL(pEvent);
+ return;
+ }
+ realWin = win->info[0].id;
+ pWin = LookupIDByType(realWin, RT_WINDOW);
+ }
+ if(x || y || scrnum)
+ for (i = 0; i < numRects; i++) {
+ pEvent[i].u.expose.window = realWin;
+ pEvent[i].u.expose.x += x;
+ pEvent[i].u.expose.y += y;
+ }
+ }
+#endif
+
+ DeliverEvents(pWin, pEvent, numRects, NullWindow);
+
+ DEALLOCATE_LOCAL(pEvent);
+}
+
+void
+miWindowExposures(pWin, prgn, other_exposed)
+ WindowPtr pWin;
+ register RegionPtr prgn, other_exposed;
+{
+ RegionPtr exposures = prgn;
+ if (pWin->backStorage && prgn)
+ /*
+ * in some cases, backing store will cause a different
+ * region to be exposed than needs to be repainted
+ * (like when a window is mapped). RestoreAreas is
+ * allowed to return a region other than prgn,
+ * in which case this routine will free the resultant
+ * region. If exposures is null, then no events will
+ * be sent to the client; if prgn is empty
+ * no areas will be repainted.
+ */
+ exposures = (*pWin->drawable.pScreen->RestoreAreas)(pWin, prgn);
+ if ((prgn && !REGION_NIL(prgn)) ||
+ (exposures && !REGION_NIL(exposures)) || other_exposed)
+ {
+ RegionRec expRec;
+ int clientInterested;
+
+ /*
+ * Restore from backing-store FIRST.
+ */
+ clientInterested = (pWin->eventMask|wOtherEventMasks(pWin)) & ExposureMask;
+ if (other_exposed)
+ {
+ if (exposures)
+ {
+ REGION_UNION(pWin->drawable.pScreen, other_exposed,
+ exposures,
+ other_exposed);
+ if (exposures != prgn)
+ REGION_DESTROY(pWin->drawable.pScreen, exposures);
+ }
+ exposures = other_exposed;
+ }
+ if (clientInterested && exposures && (REGION_NUM_RECTS(exposures) > RECTLIMIT))
+ {
+ /*
+ * If we have LOTS of rectangles, we decide to take the extents
+ * and force an exposure on that. This should require much less
+ * work overall, on both client and server. This is cheating, but
+ * isn't prohibited by the protocol ("spontaneous combustion" :-).
+ */
+ BoxRec box;
+
+ box = *REGION_EXTENTS( pWin->drawable.pScreen, exposures);
+ if (exposures == prgn) {
+ exposures = &expRec;
+ REGION_INIT( pWin->drawable.pScreen, exposures, &box, 1);
+ REGION_RESET( pWin->drawable.pScreen, prgn, &box);
+ } else {
+ REGION_RESET( pWin->drawable.pScreen, exposures, &box);
+ REGION_UNION( pWin->drawable.pScreen, prgn, prgn, exposures);
+ }
+ /* PaintWindowBackground doesn't clip, so we have to */
+ REGION_INTERSECT( pWin->drawable.pScreen, prgn, prgn, &pWin->clipList);
+ /* need to clear out new areas of backing store, too */
+ if (pWin->backStorage)
+ (void) (* pWin->drawable.pScreen->ClearBackingStore)(
+ pWin,
+ box.x1 - pWin->drawable.x,
+ box.y1 - pWin->drawable.y,
+ box.x2 - box.x1,
+ box.y2 - box.y1,
+ FALSE);
+ }
+ if (prgn && !REGION_NIL(prgn))
+ (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, prgn, PW_BACKGROUND);
+ if (clientInterested && exposures && !REGION_NIL(exposures))
+ miSendExposures(pWin, exposures,
+ pWin->drawable.x, pWin->drawable.y);
+ if (exposures == &expRec)
+ {
+ REGION_UNINIT( pWin->drawable.pScreen, exposures);
+ }
+ else if (exposures && exposures != prgn && exposures != other_exposed)
+ REGION_DESTROY( pWin->drawable.pScreen, exposures);
+ if (prgn)
+ REGION_EMPTY( pWin->drawable.pScreen, prgn);
+ }
+ else if (exposures && exposures != prgn)
+ REGION_DESTROY( pWin->drawable.pScreen, exposures);
+}
+
+
+/*
+ this code is highly unlikely. it is not haile selassie.
+
+ there is some hair here. we can't just use the window's
+clip region as it is, because if we are painting the border,
+the border is not in the client area and so we will be excluded
+when we validate the GC, and if we are painting a parent-relative
+background, the area we want to paint is in some other window.
+since we trust the code calling us to tell us to paint only areas
+that are really ours, we will temporarily give the window a
+clipList the size of the whole screen and an origin at (0,0).
+this more or less assumes that ddX code will do translation
+based on the window's absolute position, and that ValidateGC will
+look at clipList, and that no other fields from the
+window will be used. it's not possible to just draw
+in the root because it may be a different depth.
+
+to get the tile to align correctly we set the GC's tile origin to
+be the (x,y) of the window's upper left corner, after which we
+get the right bits when drawing into the root.
+
+because the clip_mask is being set to None, we may call DoChangeGC with
+fPointer set true, thus we no longer need to install the background or
+border tile in the resource table.
+*/
+
+static RESTYPE ResType = 0;
+static int numGCs = 0;
+static GCPtr screenContext[MAXSCREENS];
+
+/*ARGSUSED*/
+static int
+tossGC (
+ pointer value,
+ XID id)
+{
+ GCPtr pGC = (GCPtr)value;
+ screenContext[pGC->pScreen->myNum] = (GCPtr)NULL;
+ FreeGC (pGC, id);
+ numGCs--;
+ if (!numGCs)
+ ResType = 0;
+
+ return 0;
+}
+
+
+void
+miPaintWindow(pWin, prgn, what)
+register WindowPtr pWin;
+RegionPtr prgn;
+int what;
+{
+ int status;
+
+ Bool usingScratchGC = FALSE;
+ WindowPtr pRoot;
+
+#define FUNCTION 0
+#define FOREGROUND 1
+#define TILE 2
+#define FILLSTYLE 3
+#define ABSX 4
+#define ABSY 5
+#define CLIPMASK 6
+#define SUBWINDOW 7
+#define COUNT_BITS 8
+
+ ChangeGCVal gcval[7];
+ ChangeGCVal newValues [COUNT_BITS];
+
+ BITS32 gcmask, index, mask;
+ RegionRec prgnWin;
+ DDXPointRec oldCorner;
+ BoxRec box;
+ WindowPtr pBgWin;
+ GCPtr pGC;
+ register int i;
+ register BoxPtr pbox;
+ register ScreenPtr pScreen = pWin->drawable.pScreen;
+ register xRectangle *prect;
+ int numRects;
+
+ gcmask = 0;
+
+ if (what == PW_BACKGROUND)
+ {
+ switch (pWin->backgroundState) {
+ case None:
+ return;
+ case ParentRelative:
+ (*pWin->parent->drawable.pScreen->PaintWindowBackground)(pWin->parent, prgn, what);
+ return;
+ case BackgroundPixel:
+ newValues[FOREGROUND].val = pWin->background.pixel;
+ newValues[FILLSTYLE].val = FillSolid;
+ gcmask |= GCForeground | GCFillStyle;
+ break;
+ case BackgroundPixmap:
+ newValues[TILE].ptr = (pointer)pWin->background.pixmap;
+ newValues[FILLSTYLE].val = FillTiled;
+ gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
+ break;
+ }
+ }
+ else
+ {
+ if (pWin->borderIsPixel)
+ {
+ newValues[FOREGROUND].val = pWin->border.pixel;
+ newValues[FILLSTYLE].val = FillSolid;
+ gcmask |= GCForeground | GCFillStyle;
+ }
+ else
+ {
+ newValues[TILE].ptr = (pointer)pWin->border.pixmap;
+ newValues[FILLSTYLE].val = FillTiled;
+ gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
+ }
+ }
+
+ prect = (xRectangle *)ALLOCATE_LOCAL(REGION_NUM_RECTS(prgn) *
+ sizeof(xRectangle));
+ if (!prect)
+ return;
+
+ newValues[FUNCTION].val = GXcopy;
+ gcmask |= GCFunction | GCClipMask;
+
+ i = pScreen->myNum;
+ pRoot = WindowTable[i];
+
+ pBgWin = pWin;
+ if (what == PW_BORDER)
+ {
+ while (pBgWin->backgroundState == ParentRelative)
+ pBgWin = pBgWin->parent;
+ }
+
+ if ((pWin->drawable.depth != pRoot->drawable.depth) ||
+ (pWin->drawable.bitsPerPixel != pRoot->drawable.bitsPerPixel))
+ {
+ usingScratchGC = TRUE;
+ pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
+ if (!pGC)
+ {
+ DEALLOCATE_LOCAL(prect);
+ return;
+ }
+ /*
+ * mash the clip list so we can paint the border by
+ * mangling the window in place, pretending it
+ * spans the entire screen
+ */
+ if (what == PW_BORDER)
+ {
+ prgnWin = pWin->clipList;
+ oldCorner.x = pWin->drawable.x;
+ oldCorner.y = pWin->drawable.y;
+ pWin->drawable.x = pWin->drawable.y = 0;
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pScreen->width;
+ box.y2 = pScreen->height;
+ REGION_INIT(pScreen, &pWin->clipList, &box, 1);
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ newValues[ABSX].val = pBgWin->drawable.x;
+ newValues[ABSY].val = pBgWin->drawable.y;
+ }
+ else
+ {
+ newValues[ABSX].val = 0;
+ newValues[ABSY].val = 0;
+ }
+ } else {
+ /*
+ * draw the background to the root window
+ */
+ if (screenContext[i] == (GCPtr)NULL)
+ {
+ if (!ResType && !(ResType = CreateNewResourceType(tossGC)))
+ return;
+ screenContext[i] = CreateGC((DrawablePtr)pWin, (BITS32) 0,
+ (XID *)NULL, &status);
+ if (!screenContext[i])
+ return;
+ numGCs++;
+ if (!AddResource(FakeClientID(0), ResType,
+ (pointer)screenContext[i]))
+ return;
+ }
+ pGC = screenContext[i];
+ newValues[SUBWINDOW].val = IncludeInferiors;
+ newValues[ABSX].val = pBgWin->drawable.x;
+ newValues[ABSY].val = pBgWin->drawable.y;
+ gcmask |= GCSubwindowMode;
+ pWin = pRoot;
+ }
+
+ if (pWin->backStorage)
+ (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack);
+
+ mask = gcmask;
+ gcmask = 0;
+ i = 0;
+ while (mask) {
+ index = lowbit (mask);
+ mask &= ~index;
+ switch (index) {
+ case GCFunction:
+ if (pGC->alu != newValues[FUNCTION].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[FUNCTION].val;
+ }
+ break;
+ case GCTileStipXOrigin:
+ if ( pGC->patOrg.x != newValues[ABSX].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[ABSX].val;
+ }
+ break;
+ case GCTileStipYOrigin:
+ if ( pGC->patOrg.y != newValues[ABSY].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[ABSY].val;
+ }
+ break;
+ case GCClipMask:
+ if ( pGC->clientClipType != CT_NONE) {
+ gcmask |= index;
+ gcval[i++].val = CT_NONE;
+ }
+ break;
+ case GCSubwindowMode:
+ if ( pGC->subWindowMode != newValues[SUBWINDOW].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[SUBWINDOW].val;
+ }
+ break;
+ case GCTile:
+ if (pGC->tileIsPixel || pGC->tile.pixmap != newValues[TILE].ptr)
+ {
+ gcmask |= index;
+ gcval[i++].ptr = newValues[TILE].ptr;
+ }
+ break;
+ case GCFillStyle:
+ if ( pGC->fillStyle != newValues[FILLSTYLE].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[FILLSTYLE].val;
+ }
+ break;
+ case GCForeground:
+ if ( pGC->fgPixel != newValues[FOREGROUND].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[FOREGROUND].val;
+ }
+ break;
+ }
+ }
+
+ if (gcmask)
+ dixChangeGC(NullClient, pGC, gcmask, NULL, gcval);
+
+ if (pWin->drawable.serialNumber != pGC->serialNumber)
+ ValidateGC((DrawablePtr)pWin, pGC);
+
+ numRects = REGION_NUM_RECTS(prgn);
+ pbox = REGION_RECTS(prgn);
+ for (i= numRects; --i >= 0; pbox++, prect++)
+ {
+ prect->x = pbox->x1 - pWin->drawable.x;
+ prect->y = pbox->y1 - pWin->drawable.y;
+ prect->width = pbox->x2 - pbox->x1;
+ prect->height = pbox->y2 - pbox->y1;
+ }
+ prect -= numRects;
+ (*pGC->ops->PolyFillRect)((DrawablePtr)pWin, pGC, numRects, prect);
+ DEALLOCATE_LOCAL(prect);
+
+ if (pWin->backStorage)
+ (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeNothing);
+
+ if (usingScratchGC)
+ {
+ if (what == PW_BORDER)
+ {
+ REGION_UNINIT(pScreen, &pWin->clipList);
+ pWin->clipList = prgnWin;
+ pWin->drawable.x = oldCorner.x;
+ pWin->drawable.y = oldCorner.y;
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ }
+ FreeScratchGC(pGC);
+ }
+}
+
+
+/* MICLEARDRAWABLE -- sets the entire drawable to the background color of
+ * the GC. Useful when we have a scratch drawable and need to initialize
+ * it. */
+void
+miClearDrawable(pDraw, pGC)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+{
+ XID fg = pGC->fgPixel;
+ XID bg = pGC->bgPixel;
+ xRectangle rect;
+
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = pDraw->width;
+ rect.height = pDraw->height;
+ DoChangeGC(pGC, GCForeground, &bg, 0);
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->PolyFillRect)(pDraw, pGC, 1, &rect);
+ DoChangeGC(pGC, GCForeground, &fg, 0);
+ ValidateGC(pDraw, pGC);
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c
new file mode 100644
index 000000000..6ad60223f
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c
@@ -0,0 +1,318 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/miglyph.c,v 1.4 2000/11/20 07:13:13 keithp Exp $
+ *
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+
+#ifdef NXAGENT_SERVER
+
+#include "Render.h"
+
+#endif
+
+void
+miGlyphExtents (int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs,
+ BoxPtr extents)
+{
+ int x1, x2, y1, y2;
+ int n;
+ GlyphPtr glyph;
+ int x, y;
+
+ x = 0;
+ y = 0;
+ extents->x1 = MAXSHORT;
+ extents->x2 = MINSHORT;
+ extents->y1 = MAXSHORT;
+ extents->y2 = MINSHORT;
+ while (nlist--)
+ {
+ x += list->xOff;
+ y += list->yOff;
+ n = list->len;
+ list++;
+ while (n--)
+ {
+ glyph = *glyphs++;
+ x1 = x - glyph->info.x;
+ if (x1 < MINSHORT)
+ x1 = MINSHORT;
+ y1 = y - glyph->info.y;
+ if (y1 < MINSHORT)
+ y1 = MINSHORT;
+ x2 = x1 + glyph->info.width;
+ if (x2 > MAXSHORT)
+ x2 = MAXSHORT;
+ y2 = y1 + glyph->info.height;
+ if (y2 > MAXSHORT)
+ y2 = MAXSHORT;
+ if (x1 < extents->x1)
+ extents->x1 = x1;
+ if (x2 > extents->x2)
+ extents->x2 = x2;
+ if (y1 < extents->y1)
+ extents->y1 = y1;
+ if (y2 > extents->y2)
+ extents->y2 = y2;
+ x += glyph->info.xOff;
+ y += glyph->info.yOff;
+ }
+ }
+}
+
+#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
+
+void
+miGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs)
+{
+ PixmapPtr pPixmap = 0;
+ PicturePtr pPicture;
+ PixmapPtr pMaskPixmap = 0;
+ PicturePtr pMask;
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ int width = 0, height = 0;
+ int x, y;
+ int xDst = list->xOff, yDst = list->yOff;
+ int n;
+ GlyphPtr glyph;
+ int error;
+ BoxRec extents;
+ CARD32 component_alpha;
+
+ #ifdef NXAGENT_SERVER
+
+ /*
+ * Get rid of the warning.
+ */
+
+ extents.x1 = 0;
+ extents.y1 = 0;
+
+ #endif
+
+ if (maskFormat)
+ {
+ GCPtr pGC;
+ xRectangle rect;
+
+ #ifdef NXAGENT_SERVER
+
+ if (nxagentGlyphsExtents != NullBox)
+ {
+ memcpy(&extents, nxagentGlyphsExtents, sizeof(BoxRec));
+ }
+ else
+ {
+ nxagentGlyphsExtents = (BoxPtr) xalloc(sizeof(BoxRec));
+
+ miGlyphExtents (nlist, list, glyphs, &extents);
+
+ memcpy(nxagentGlyphsExtents, &extents, sizeof(BoxRec));
+ }
+
+ #else
+
+ miGlyphExtents (nlist, list, glyphs, &extents);
+
+ #endif
+
+ if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
+ return;
+ width = extents.x2 - extents.x1;
+ height = extents.y2 - extents.y1;
+ pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, maskFormat->depth);
+
+ if (!pMaskPixmap)
+ return;
+
+ component_alpha = NeedsComponent(maskFormat->format);
+ pMask = CreatePicture (0, &pMaskPixmap->drawable,
+ maskFormat, CPComponentAlpha, &component_alpha,
+ serverClient, &error);
+
+ if (!pMask)
+ {
+ (*pScreen->DestroyPixmap) (pMaskPixmap);
+ return;
+ }
+ pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen);
+ ValidateGC (&pMaskPixmap->drawable, pGC);
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = width;
+ rect.height = height;
+ (*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
+ FreeScratchGC (pGC);
+ x = -extents.x1;
+ y = -extents.y1;
+ }
+ else
+ {
+ pMask = pDst;
+ x = 0;
+ y = 0;
+ }
+ pPicture = 0;
+ while (nlist--)
+ {
+ x += list->xOff;
+ y += list->yOff;
+ n = list->len;
+
+ while (n--)
+ {
+ glyph = *glyphs++;
+ if (!pPicture)
+ {
+ pPixmap = GetScratchPixmapHeader (pScreen, glyph->info.width, glyph->info.height,
+ list->format->depth,
+ list->format->depth,
+ 0, (pointer) (glyph + 1));
+ if (!pPixmap)
+ return;
+ component_alpha = NeedsComponent(list->format->format);
+ pPicture = CreatePicture (0, &pPixmap->drawable, list->format,
+ CPComponentAlpha, &component_alpha,
+ serverClient, &error);
+ if (!pPicture)
+ {
+ FreeScratchPixmapHeader (pPixmap);
+ return;
+ }
+ }
+ (*pScreen->ModifyPixmapHeader) (pPixmap,
+ glyph->info.width, glyph->info.height,
+ 0, 0, -1, (pointer) (glyph + 1));
+
+ #ifdef NXAGENT_SERVER
+
+ /*
+ * The following line fixes a problem with glyphs that appeared
+ * as clipped. It was a side effect due the validate function
+ * "ValidatePicture" that makes a check on the Drawable serial
+ * number instead of the picture serial number, failing thus
+ * the clip mask update.
+ */
+
+ pPicture->pDrawable->serialNumber = NEXT_SERIAL_NUMBER;
+
+ #endif
+
+ pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ if (maskFormat)
+ {
+ CompositePicture (PictOpAdd,
+ pPicture,
+ None,
+ pMask,
+ 0, 0,
+ 0, 0,
+ x - glyph->info.x,
+ y - glyph->info.y,
+ glyph->info.width,
+ glyph->info.height);
+ }
+ else
+ {
+ CompositePicture (op,
+ pSrc,
+ pPicture,
+ pDst,
+ xSrc + (x - glyph->info.x) - xDst,
+ ySrc + (y - glyph->info.y) - yDst,
+ 0, 0,
+ x - glyph->info.x,
+ y - glyph->info.y,
+ glyph->info.width,
+ glyph->info.height);
+ }
+ x += glyph->info.xOff;
+ y += glyph->info.yOff;
+ }
+
+ list++;
+ if (pPicture)
+ {
+ FreeScratchPixmapHeader (pPixmap);
+ FreePicture ((pointer) pPicture, 0);
+ pPicture = 0;
+ pPixmap = 0;
+ }
+ }
+ if (maskFormat)
+ {
+ x = extents.x1;
+ y = extents.y1;
+ CompositePicture (op,
+ pSrc,
+ pMask,
+ pDst,
+ xSrc + x - xDst,
+ ySrc + y - yDst,
+ 0, 0,
+ x, y,
+ width, height);
+
+ FreePicture ((pointer) pMask, (XID) 0);
+ (*pScreen->DestroyPixmap) (pMaskPixmap);
+ }
+
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.NX.original
new file mode 100644
index 000000000..6ad60223f
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.NX.original
@@ -0,0 +1,318 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/miglyph.c,v 1.4 2000/11/20 07:13:13 keithp Exp $
+ *
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+
+#ifdef NXAGENT_SERVER
+
+#include "Render.h"
+
+#endif
+
+void
+miGlyphExtents (int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs,
+ BoxPtr extents)
+{
+ int x1, x2, y1, y2;
+ int n;
+ GlyphPtr glyph;
+ int x, y;
+
+ x = 0;
+ y = 0;
+ extents->x1 = MAXSHORT;
+ extents->x2 = MINSHORT;
+ extents->y1 = MAXSHORT;
+ extents->y2 = MINSHORT;
+ while (nlist--)
+ {
+ x += list->xOff;
+ y += list->yOff;
+ n = list->len;
+ list++;
+ while (n--)
+ {
+ glyph = *glyphs++;
+ x1 = x - glyph->info.x;
+ if (x1 < MINSHORT)
+ x1 = MINSHORT;
+ y1 = y - glyph->info.y;
+ if (y1 < MINSHORT)
+ y1 = MINSHORT;
+ x2 = x1 + glyph->info.width;
+ if (x2 > MAXSHORT)
+ x2 = MAXSHORT;
+ y2 = y1 + glyph->info.height;
+ if (y2 > MAXSHORT)
+ y2 = MAXSHORT;
+ if (x1 < extents->x1)
+ extents->x1 = x1;
+ if (x2 > extents->x2)
+ extents->x2 = x2;
+ if (y1 < extents->y1)
+ extents->y1 = y1;
+ if (y2 > extents->y2)
+ extents->y2 = y2;
+ x += glyph->info.xOff;
+ y += glyph->info.yOff;
+ }
+ }
+}
+
+#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
+
+void
+miGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs)
+{
+ PixmapPtr pPixmap = 0;
+ PicturePtr pPicture;
+ PixmapPtr pMaskPixmap = 0;
+ PicturePtr pMask;
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ int width = 0, height = 0;
+ int x, y;
+ int xDst = list->xOff, yDst = list->yOff;
+ int n;
+ GlyphPtr glyph;
+ int error;
+ BoxRec extents;
+ CARD32 component_alpha;
+
+ #ifdef NXAGENT_SERVER
+
+ /*
+ * Get rid of the warning.
+ */
+
+ extents.x1 = 0;
+ extents.y1 = 0;
+
+ #endif
+
+ if (maskFormat)
+ {
+ GCPtr pGC;
+ xRectangle rect;
+
+ #ifdef NXAGENT_SERVER
+
+ if (nxagentGlyphsExtents != NullBox)
+ {
+ memcpy(&extents, nxagentGlyphsExtents, sizeof(BoxRec));
+ }
+ else
+ {
+ nxagentGlyphsExtents = (BoxPtr) xalloc(sizeof(BoxRec));
+
+ miGlyphExtents (nlist, list, glyphs, &extents);
+
+ memcpy(nxagentGlyphsExtents, &extents, sizeof(BoxRec));
+ }
+
+ #else
+
+ miGlyphExtents (nlist, list, glyphs, &extents);
+
+ #endif
+
+ if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
+ return;
+ width = extents.x2 - extents.x1;
+ height = extents.y2 - extents.y1;
+ pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, maskFormat->depth);
+
+ if (!pMaskPixmap)
+ return;
+
+ component_alpha = NeedsComponent(maskFormat->format);
+ pMask = CreatePicture (0, &pMaskPixmap->drawable,
+ maskFormat, CPComponentAlpha, &component_alpha,
+ serverClient, &error);
+
+ if (!pMask)
+ {
+ (*pScreen->DestroyPixmap) (pMaskPixmap);
+ return;
+ }
+ pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen);
+ ValidateGC (&pMaskPixmap->drawable, pGC);
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = width;
+ rect.height = height;
+ (*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
+ FreeScratchGC (pGC);
+ x = -extents.x1;
+ y = -extents.y1;
+ }
+ else
+ {
+ pMask = pDst;
+ x = 0;
+ y = 0;
+ }
+ pPicture = 0;
+ while (nlist--)
+ {
+ x += list->xOff;
+ y += list->yOff;
+ n = list->len;
+
+ while (n--)
+ {
+ glyph = *glyphs++;
+ if (!pPicture)
+ {
+ pPixmap = GetScratchPixmapHeader (pScreen, glyph->info.width, glyph->info.height,
+ list->format->depth,
+ list->format->depth,
+ 0, (pointer) (glyph + 1));
+ if (!pPixmap)
+ return;
+ component_alpha = NeedsComponent(list->format->format);
+ pPicture = CreatePicture (0, &pPixmap->drawable, list->format,
+ CPComponentAlpha, &component_alpha,
+ serverClient, &error);
+ if (!pPicture)
+ {
+ FreeScratchPixmapHeader (pPixmap);
+ return;
+ }
+ }
+ (*pScreen->ModifyPixmapHeader) (pPixmap,
+ glyph->info.width, glyph->info.height,
+ 0, 0, -1, (pointer) (glyph + 1));
+
+ #ifdef NXAGENT_SERVER
+
+ /*
+ * The following line fixes a problem with glyphs that appeared
+ * as clipped. It was a side effect due the validate function
+ * "ValidatePicture" that makes a check on the Drawable serial
+ * number instead of the picture serial number, failing thus
+ * the clip mask update.
+ */
+
+ pPicture->pDrawable->serialNumber = NEXT_SERIAL_NUMBER;
+
+ #endif
+
+ pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ if (maskFormat)
+ {
+ CompositePicture (PictOpAdd,
+ pPicture,
+ None,
+ pMask,
+ 0, 0,
+ 0, 0,
+ x - glyph->info.x,
+ y - glyph->info.y,
+ glyph->info.width,
+ glyph->info.height);
+ }
+ else
+ {
+ CompositePicture (op,
+ pSrc,
+ pPicture,
+ pDst,
+ xSrc + (x - glyph->info.x) - xDst,
+ ySrc + (y - glyph->info.y) - yDst,
+ 0, 0,
+ x - glyph->info.x,
+ y - glyph->info.y,
+ glyph->info.width,
+ glyph->info.height);
+ }
+ x += glyph->info.xOff;
+ y += glyph->info.yOff;
+ }
+
+ list++;
+ if (pPicture)
+ {
+ FreeScratchPixmapHeader (pPixmap);
+ FreePicture ((pointer) pPicture, 0);
+ pPicture = 0;
+ pPixmap = 0;
+ }
+ }
+ if (maskFormat)
+ {
+ x = extents.x1;
+ y = extents.y1;
+ CompositePicture (op,
+ pSrc,
+ pMask,
+ pDst,
+ xSrc + x - xDst,
+ ySrc + y - yDst,
+ 0, 0,
+ x, y,
+ width, height);
+
+ FreePicture ((pointer) pMask, (XID) 0);
+ (*pScreen->DestroyPixmap) (pMaskPixmap);
+ }
+
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.X.original
new file mode 100644
index 000000000..237ec13a4
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.X.original
@@ -0,0 +1,243 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/miglyph.c,v 1.4 2000/11/20 07:13:13 keithp Exp $
+ *
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+
+void
+miGlyphExtents (int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs,
+ BoxPtr extents)
+{
+ int x1, x2, y1, y2;
+ int n;
+ GlyphPtr glyph;
+ int x, y;
+
+ x = 0;
+ y = 0;
+ extents->x1 = MAXSHORT;
+ extents->x2 = MINSHORT;
+ extents->y1 = MAXSHORT;
+ extents->y2 = MINSHORT;
+ while (nlist--)
+ {
+ x += list->xOff;
+ y += list->yOff;
+ n = list->len;
+ list++;
+ while (n--)
+ {
+ glyph = *glyphs++;
+ x1 = x - glyph->info.x;
+ if (x1 < MINSHORT)
+ x1 = MINSHORT;
+ y1 = y - glyph->info.y;
+ if (y1 < MINSHORT)
+ y1 = MINSHORT;
+ x2 = x1 + glyph->info.width;
+ if (x2 > MAXSHORT)
+ x2 = MAXSHORT;
+ y2 = y1 + glyph->info.height;
+ if (y2 > MAXSHORT)
+ y2 = MAXSHORT;
+ if (x1 < extents->x1)
+ extents->x1 = x1;
+ if (x2 > extents->x2)
+ extents->x2 = x2;
+ if (y1 < extents->y1)
+ extents->y1 = y1;
+ if (y2 > extents->y2)
+ extents->y2 = y2;
+ x += glyph->info.xOff;
+ y += glyph->info.yOff;
+ }
+ }
+}
+
+#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
+
+void
+miGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs)
+{
+ PixmapPtr pPixmap = 0;
+ PicturePtr pPicture;
+ PixmapPtr pMaskPixmap = 0;
+ PicturePtr pMask;
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ int width = 0, height = 0;
+ int x, y;
+ int xDst = list->xOff, yDst = list->yOff;
+ int n;
+ GlyphPtr glyph;
+ int error;
+ BoxRec extents;
+ CARD32 component_alpha;
+
+ if (maskFormat)
+ {
+ GCPtr pGC;
+ xRectangle rect;
+
+ miGlyphExtents (nlist, list, glyphs, &extents);
+
+ if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
+ return;
+ width = extents.x2 - extents.x1;
+ height = extents.y2 - extents.y1;
+ pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, maskFormat->depth);
+ if (!pMaskPixmap)
+ return;
+ component_alpha = NeedsComponent(maskFormat->format);
+ pMask = CreatePicture (0, &pMaskPixmap->drawable,
+ maskFormat, CPComponentAlpha, &component_alpha,
+ serverClient, &error);
+ if (!pMask)
+ {
+ (*pScreen->DestroyPixmap) (pMaskPixmap);
+ return;
+ }
+ pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen);
+ ValidateGC (&pMaskPixmap->drawable, pGC);
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = width;
+ rect.height = height;
+ (*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
+ FreeScratchGC (pGC);
+ x = -extents.x1;
+ y = -extents.y1;
+ }
+ else
+ {
+ pMask = pDst;
+ x = 0;
+ y = 0;
+ }
+ pPicture = 0;
+ while (nlist--)
+ {
+ x += list->xOff;
+ y += list->yOff;
+ n = list->len;
+ while (n--)
+ {
+ glyph = *glyphs++;
+ if (!pPicture)
+ {
+ pPixmap = GetScratchPixmapHeader (pScreen, glyph->info.width, glyph->info.height,
+ list->format->depth,
+ list->format->depth,
+ 0, (pointer) (glyph + 1));
+ if (!pPixmap)
+ return;
+ component_alpha = NeedsComponent(list->format->format);
+ pPicture = CreatePicture (0, &pPixmap->drawable, list->format,
+ CPComponentAlpha, &component_alpha,
+ serverClient, &error);
+ if (!pPicture)
+ {
+ FreeScratchPixmapHeader (pPixmap);
+ return;
+ }
+ }
+ (*pScreen->ModifyPixmapHeader) (pPixmap,
+ glyph->info.width, glyph->info.height,
+ 0, 0, -1, (pointer) (glyph + 1));
+ pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ if (maskFormat)
+ {
+ CompositePicture (PictOpAdd,
+ pPicture,
+ None,
+ pMask,
+ 0, 0,
+ 0, 0,
+ x - glyph->info.x,
+ y - glyph->info.y,
+ glyph->info.width,
+ glyph->info.height);
+ }
+ else
+ {
+ CompositePicture (op,
+ pSrc,
+ pPicture,
+ pDst,
+ xSrc + (x - glyph->info.x) - xDst,
+ ySrc + (y - glyph->info.y) - yDst,
+ 0, 0,
+ x - glyph->info.x,
+ y - glyph->info.y,
+ glyph->info.width,
+ glyph->info.height);
+ }
+ x += glyph->info.xOff;
+ y += glyph->info.yOff;
+ }
+ list++;
+ if (pPicture)
+ {
+ FreeScratchPixmapHeader (pPixmap);
+ FreePicture ((pointer) pPicture, 0);
+ pPicture = 0;
+ pPixmap = 0;
+ }
+ }
+ if (maskFormat)
+ {
+ x = extents.x1;
+ y = extents.y1;
+ CompositePicture (op,
+ pSrc,
+ pMask,
+ pDst,
+ xSrc + x - xDst,
+ ySrc + y - yDst,
+ 0, 0,
+ x, y,
+ width, height);
+ FreePicture ((pointer) pMask, (XID) 0);
+ (*pScreen->DestroyPixmap) (pMaskPixmap);
+ }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c
new file mode 100644
index 000000000..e08f5e45f
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c
@@ -0,0 +1,233 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/mitrap.c,v 1.8 2002/09/03 19:28:28 keithp Exp $
+ *
+ * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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 "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "servermd.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+
+#ifdef NXAGENT_SERVER
+
+#include "Render.h"
+
+#endif
+
+PicturePtr
+miCreateAlphaPicture (ScreenPtr pScreen,
+ PicturePtr pDst,
+ PictFormatPtr pPictFormat,
+ CARD16 width,
+ CARD16 height)
+{
+ PixmapPtr pPixmap;
+ PicturePtr pPicture;
+ GCPtr pGC;
+ int error;
+ xRectangle rect;
+
+ if (width > 32767 || height > 32767)
+ return 0;
+
+ if (!pPictFormat)
+ {
+ if (pDst->polyEdge == PolyEdgeSharp)
+ pPictFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
+ else
+ pPictFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
+ if (!pPictFormat)
+ return 0;
+ }
+
+ pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height,
+ pPictFormat->depth);
+ if (!pPixmap)
+ return 0;
+ pGC = GetScratchGC (pPixmap->drawable.depth, pScreen);
+ if (!pGC)
+ {
+ (*pScreen->DestroyPixmap) (pPixmap);
+ return 0;
+ }
+ ValidateGC (&pPixmap->drawable, pGC);
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = width;
+ rect.height = height;
+ (*pGC->ops->PolyFillRect)(&pPixmap->drawable, pGC, 1, &rect);
+ FreeScratchGC (pGC);
+ pPicture = CreatePicture (0, &pPixmap->drawable, pPictFormat,
+ 0, 0, serverClient, &error);
+ (*pScreen->DestroyPixmap) (pPixmap);
+ return pPicture;
+}
+
+static xFixed
+miLineFixedX (xLineFixed *l, xFixed y, Bool ceil)
+{
+ xFixed dx = l->p2.x - l->p1.x;
+ xFixed_32_32 ex = (xFixed_32_32) (y - l->p1.y) * dx;
+ xFixed dy = l->p2.y - l->p1.y;
+ if (ceil)
+ ex += (dy - 1);
+ return l->p1.x + (xFixed) (ex / dy);
+}
+
+void
+miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box)
+{
+ box->y1 = MAXSHORT;
+ box->y2 = MINSHORT;
+ box->x1 = MAXSHORT;
+ box->x2 = MINSHORT;
+ for (; ntrap; ntrap--, traps++)
+ {
+ INT16 x1, y1, x2, y2;
+
+ if (!xTrapezoidValid(traps))
+ continue;
+ y1 = xFixedToInt (traps->top);
+ if (y1 < box->y1)
+ box->y1 = y1;
+
+ y2 = xFixedToInt (xFixedCeil (traps->bottom));
+ if (y2 > box->y2)
+ box->y2 = y2;
+
+ x1 = xFixedToInt (min (miLineFixedX (&traps->left, traps->top, FALSE),
+ miLineFixedX (&traps->left, traps->bottom, FALSE)));
+ if (x1 < box->x1)
+ box->x1 = x1;
+
+ x2 = xFixedToInt (xFixedCeil (max (miLineFixedX (&traps->right, traps->top, TRUE),
+ miLineFixedX (&traps->right, traps->bottom, TRUE))));
+ if (x2 > box->x2)
+ box->x2 = x2;
+ }
+}
+
+void
+miTrapezoids (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntrap,
+ xTrapezoid *traps)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+
+ /*
+ * Check for solid alpha add
+ */
+ if (op == PictOpAdd && miIsSolidAlpha (pSrc))
+ {
+ for (; ntrap; ntrap--, traps++)
+ (*ps->RasterizeTrapezoid) (pDst, traps, 0, 0);
+ }
+ else if (maskFormat)
+ {
+ PicturePtr pPicture;
+ BoxRec bounds;
+ INT16 xDst, yDst;
+ INT16 xRel, yRel;
+
+ xDst = traps[0].left.p1.x >> 16;
+ yDst = traps[0].left.p1.y >> 16;
+
+ #ifdef NXAGENT_SERVER
+
+ if (nxagentTrapezoidExtents != NullBox)
+ {
+ memcpy(&bounds, nxagentTrapezoidExtents, sizeof(BoxRec));
+ }
+ else
+ {
+ nxagentTrapezoidExtents = (BoxPtr) xalloc(sizeof(BoxRec));
+
+ miTrapezoidBounds (ntrap, traps, &bounds);
+
+ memcpy(nxagentTrapezoidExtents, &bounds, sizeof(BoxRec));
+ }
+
+ #else
+
+ miTrapezoidBounds (ntrap, traps, &bounds);
+
+ #endif
+
+ if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
+ return;
+ pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
+ bounds.x2 - bounds.x1,
+ bounds.y2 - bounds.y1);
+ if (!pPicture)
+ return;
+ for (; ntrap; ntrap--, traps++)
+ (*ps->RasterizeTrapezoid) (pPicture, traps,
+ -bounds.x1, -bounds.y1);
+ xRel = bounds.x1 + xSrc - xDst;
+ yRel = bounds.y1 + ySrc - yDst;
+ CompositePicture (op, pSrc, pPicture, pDst,
+ xRel, yRel, 0, 0, bounds.x1, bounds.y1,
+ bounds.x2 - bounds.x1,
+ bounds.y2 - bounds.y1);
+ FreePicture (pPicture, 0);
+ }
+ else
+ {
+ if (pDst->polyEdge == PolyEdgeSharp)
+ maskFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
+ else
+ maskFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
+ for (; ntrap; ntrap--, traps++)
+ miTrapezoids (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, traps);
+ }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.NX.original
new file mode 100644
index 000000000..e08f5e45f
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.NX.original
@@ -0,0 +1,233 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/mitrap.c,v 1.8 2002/09/03 19:28:28 keithp Exp $
+ *
+ * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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 "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "servermd.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+
+#ifdef NXAGENT_SERVER
+
+#include "Render.h"
+
+#endif
+
+PicturePtr
+miCreateAlphaPicture (ScreenPtr pScreen,
+ PicturePtr pDst,
+ PictFormatPtr pPictFormat,
+ CARD16 width,
+ CARD16 height)
+{
+ PixmapPtr pPixmap;
+ PicturePtr pPicture;
+ GCPtr pGC;
+ int error;
+ xRectangle rect;
+
+ if (width > 32767 || height > 32767)
+ return 0;
+
+ if (!pPictFormat)
+ {
+ if (pDst->polyEdge == PolyEdgeSharp)
+ pPictFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
+ else
+ pPictFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
+ if (!pPictFormat)
+ return 0;
+ }
+
+ pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height,
+ pPictFormat->depth);
+ if (!pPixmap)
+ return 0;
+ pGC = GetScratchGC (pPixmap->drawable.depth, pScreen);
+ if (!pGC)
+ {
+ (*pScreen->DestroyPixmap) (pPixmap);
+ return 0;
+ }
+ ValidateGC (&pPixmap->drawable, pGC);
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = width;
+ rect.height = height;
+ (*pGC->ops->PolyFillRect)(&pPixmap->drawable, pGC, 1, &rect);
+ FreeScratchGC (pGC);
+ pPicture = CreatePicture (0, &pPixmap->drawable, pPictFormat,
+ 0, 0, serverClient, &error);
+ (*pScreen->DestroyPixmap) (pPixmap);
+ return pPicture;
+}
+
+static xFixed
+miLineFixedX (xLineFixed *l, xFixed y, Bool ceil)
+{
+ xFixed dx = l->p2.x - l->p1.x;
+ xFixed_32_32 ex = (xFixed_32_32) (y - l->p1.y) * dx;
+ xFixed dy = l->p2.y - l->p1.y;
+ if (ceil)
+ ex += (dy - 1);
+ return l->p1.x + (xFixed) (ex / dy);
+}
+
+void
+miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box)
+{
+ box->y1 = MAXSHORT;
+ box->y2 = MINSHORT;
+ box->x1 = MAXSHORT;
+ box->x2 = MINSHORT;
+ for (; ntrap; ntrap--, traps++)
+ {
+ INT16 x1, y1, x2, y2;
+
+ if (!xTrapezoidValid(traps))
+ continue;
+ y1 = xFixedToInt (traps->top);
+ if (y1 < box->y1)
+ box->y1 = y1;
+
+ y2 = xFixedToInt (xFixedCeil (traps->bottom));
+ if (y2 > box->y2)
+ box->y2 = y2;
+
+ x1 = xFixedToInt (min (miLineFixedX (&traps->left, traps->top, FALSE),
+ miLineFixedX (&traps->left, traps->bottom, FALSE)));
+ if (x1 < box->x1)
+ box->x1 = x1;
+
+ x2 = xFixedToInt (xFixedCeil (max (miLineFixedX (&traps->right, traps->top, TRUE),
+ miLineFixedX (&traps->right, traps->bottom, TRUE))));
+ if (x2 > box->x2)
+ box->x2 = x2;
+ }
+}
+
+void
+miTrapezoids (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntrap,
+ xTrapezoid *traps)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+
+ /*
+ * Check for solid alpha add
+ */
+ if (op == PictOpAdd && miIsSolidAlpha (pSrc))
+ {
+ for (; ntrap; ntrap--, traps++)
+ (*ps->RasterizeTrapezoid) (pDst, traps, 0, 0);
+ }
+ else if (maskFormat)
+ {
+ PicturePtr pPicture;
+ BoxRec bounds;
+ INT16 xDst, yDst;
+ INT16 xRel, yRel;
+
+ xDst = traps[0].left.p1.x >> 16;
+ yDst = traps[0].left.p1.y >> 16;
+
+ #ifdef NXAGENT_SERVER
+
+ if (nxagentTrapezoidExtents != NullBox)
+ {
+ memcpy(&bounds, nxagentTrapezoidExtents, sizeof(BoxRec));
+ }
+ else
+ {
+ nxagentTrapezoidExtents = (BoxPtr) xalloc(sizeof(BoxRec));
+
+ miTrapezoidBounds (ntrap, traps, &bounds);
+
+ memcpy(nxagentTrapezoidExtents, &bounds, sizeof(BoxRec));
+ }
+
+ #else
+
+ miTrapezoidBounds (ntrap, traps, &bounds);
+
+ #endif
+
+ if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
+ return;
+ pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
+ bounds.x2 - bounds.x1,
+ bounds.y2 - bounds.y1);
+ if (!pPicture)
+ return;
+ for (; ntrap; ntrap--, traps++)
+ (*ps->RasterizeTrapezoid) (pPicture, traps,
+ -bounds.x1, -bounds.y1);
+ xRel = bounds.x1 + xSrc - xDst;
+ yRel = bounds.y1 + ySrc - yDst;
+ CompositePicture (op, pSrc, pPicture, pDst,
+ xRel, yRel, 0, 0, bounds.x1, bounds.y1,
+ bounds.x2 - bounds.x1,
+ bounds.y2 - bounds.y1);
+ FreePicture (pPicture, 0);
+ }
+ else
+ {
+ if (pDst->polyEdge == PolyEdgeSharp)
+ maskFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
+ else
+ maskFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
+ for (; ntrap; ntrap--, traps++)
+ miTrapezoids (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, traps);
+ }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.X.original
new file mode 100644
index 000000000..be1712420
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.X.original
@@ -0,0 +1,190 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/mitrap.c,v 1.8 2002/09/03 19:28:28 keithp Exp $
+ *
+ * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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 "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "servermd.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+
+PicturePtr
+miCreateAlphaPicture (ScreenPtr pScreen,
+ PicturePtr pDst,
+ PictFormatPtr pPictFormat,
+ CARD16 width,
+ CARD16 height)
+{
+ PixmapPtr pPixmap;
+ PicturePtr pPicture;
+ GCPtr pGC;
+ int error;
+ xRectangle rect;
+
+ if (width > 32767 || height > 32767)
+ return 0;
+
+ if (!pPictFormat)
+ {
+ if (pDst->polyEdge == PolyEdgeSharp)
+ pPictFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
+ else
+ pPictFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
+ if (!pPictFormat)
+ return 0;
+ }
+
+ pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height,
+ pPictFormat->depth);
+ if (!pPixmap)
+ return 0;
+ pGC = GetScratchGC (pPixmap->drawable.depth, pScreen);
+ if (!pGC)
+ {
+ (*pScreen->DestroyPixmap) (pPixmap);
+ return 0;
+ }
+ ValidateGC (&pPixmap->drawable, pGC);
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = width;
+ rect.height = height;
+ (*pGC->ops->PolyFillRect)(&pPixmap->drawable, pGC, 1, &rect);
+ FreeScratchGC (pGC);
+ pPicture = CreatePicture (0, &pPixmap->drawable, pPictFormat,
+ 0, 0, serverClient, &error);
+ (*pScreen->DestroyPixmap) (pPixmap);
+ return pPicture;
+}
+
+static xFixed
+miLineFixedX (xLineFixed *l, xFixed y, Bool ceil)
+{
+ xFixed dx = l->p2.x - l->p1.x;
+ xFixed_32_32 ex = (xFixed_32_32) (y - l->p1.y) * dx;
+ xFixed dy = l->p2.y - l->p1.y;
+ if (ceil)
+ ex += (dy - 1);
+ return l->p1.x + (xFixed) (ex / dy);
+}
+
+void
+miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box)
+{
+ box->y1 = MAXSHORT;
+ box->y2 = MINSHORT;
+ box->x1 = MAXSHORT;
+ box->x2 = MINSHORT;
+ for (; ntrap; ntrap--, traps++)
+ {
+ INT16 x1, y1, x2, y2;
+
+ if (!xTrapezoidValid(traps))
+ continue;
+ y1 = xFixedToInt (traps->top);
+ if (y1 < box->y1)
+ box->y1 = y1;
+
+ y2 = xFixedToInt (xFixedCeil (traps->bottom));
+ if (y2 > box->y2)
+ box->y2 = y2;
+
+ x1 = xFixedToInt (min (miLineFixedX (&traps->left, traps->top, FALSE),
+ miLineFixedX (&traps->left, traps->bottom, FALSE)));
+ if (x1 < box->x1)
+ box->x1 = x1;
+
+ x2 = xFixedToInt (xFixedCeil (max (miLineFixedX (&traps->right, traps->top, TRUE),
+ miLineFixedX (&traps->right, traps->bottom, TRUE))));
+ if (x2 > box->x2)
+ box->x2 = x2;
+ }
+}
+
+void
+miTrapezoids (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntrap,
+ xTrapezoid *traps)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+
+ /*
+ * Check for solid alpha add
+ */
+ if (op == PictOpAdd && miIsSolidAlpha (pSrc))
+ {
+ for (; ntrap; ntrap--, traps++)
+ (*ps->RasterizeTrapezoid) (pDst, traps, 0, 0);
+ }
+ else if (maskFormat)
+ {
+ PicturePtr pPicture;
+ BoxRec bounds;
+ INT16 xDst, yDst;
+ INT16 xRel, yRel;
+
+ xDst = traps[0].left.p1.x >> 16;
+ yDst = traps[0].left.p1.y >> 16;
+
+ miTrapezoidBounds (ntrap, traps, &bounds);
+ if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
+ return;
+ pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
+ bounds.x2 - bounds.x1,
+ bounds.y2 - bounds.y1);
+ if (!pPicture)
+ return;
+ for (; ntrap; ntrap--, traps++)
+ (*ps->RasterizeTrapezoid) (pPicture, traps,
+ -bounds.x1, -bounds.y1);
+ xRel = bounds.x1 + xSrc - xDst;
+ yRel = bounds.y1 + ySrc - yDst;
+ CompositePicture (op, pSrc, pPicture, pDst,
+ xRel, yRel, 0, 0, bounds.x1, bounds.y1,
+ bounds.x2 - bounds.x1,
+ bounds.y2 - bounds.y1);
+ FreePicture (pPicture, 0);
+ }
+ else
+ {
+ if (pDst->polyEdge == PolyEdgeSharp)
+ maskFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
+ else
+ maskFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
+ for (; ntrap; ntrap--, traps++)
+ miTrapezoids (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, traps);
+ }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c
new file mode 100644
index 000000000..1731e0753
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c
@@ -0,0 +1,1222 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/mi/miwindow.c,v 1.9tsi Exp $ */
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+/* $Xorg: miwindow.c,v 1.4 2001/02/09 02:05:22 xorgcvs Exp $ */
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "regionstr.h"
+#include "region.h"
+#include "mi.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "mivalidate.h"
+
+void
+miClearToBackground(pWin, x, y, w, h, generateExposures)
+ WindowPtr pWin;
+ int x,y;
+ int w,h;
+ Bool generateExposures;
+{
+ BoxRec box;
+ RegionRec reg;
+ RegionPtr pBSReg = NullRegion;
+ ScreenPtr pScreen;
+ BoxPtr extents;
+ int x1, y1, x2, y2;
+
+ /* compute everything using ints to avoid overflow */
+
+ x1 = pWin->drawable.x + x;
+ y1 = pWin->drawable.y + y;
+ if (w)
+ x2 = x1 + (int) w;
+ else
+ x2 = x1 + (int) pWin->drawable.width - (int) x;
+ if (h)
+ y2 = y1 + h;
+ else
+ y2 = y1 + (int) pWin->drawable.height - (int) y;
+
+ extents = &pWin->clipList.extents;
+
+ /* clip the resulting rectangle to the window clipList extents. This
+ * makes sure that the result will fit in a box, given that the
+ * screen is < 32768 on a side.
+ */
+
+ if (x1 < extents->x1)
+ x1 = extents->x1;
+ if (x2 > extents->x2)
+ x2 = extents->x2;
+ if (y1 < extents->y1)
+ y1 = extents->y1;
+ if (y2 > extents->y2)
+ y2 = extents->y2;
+
+ if (x2 <= x1 || y2 <= y1)
+ {
+ x2 = x1 = 0;
+ y2 = y1 = 0;
+ }
+
+ box.x1 = x1;
+ box.x2 = x2;
+ box.y1 = y1;
+ box.y2 = y2;
+
+ pScreen = pWin->drawable.pScreen;
+ REGION_INIT(pScreen, &reg, &box, 1);
+ if (pWin->backStorage)
+ {
+ /*
+ * If the window has backing-store on, call through the
+ * ClearToBackground vector to handle the special semantics
+ * (i.e. things backing store is to be cleared out and
+ * an Expose event is to be generated for those areas in backing
+ * store if generateExposures is TRUE).
+ */
+ pBSReg = (* pScreen->ClearBackingStore)(pWin, x, y, w, h,
+ generateExposures);
+ }
+
+ REGION_INTERSECT(pScreen, &reg, &reg, &pWin->clipList);
+ if (generateExposures)
+ (*pScreen->WindowExposures)(pWin, &reg, pBSReg);
+ else if (pWin->backgroundState != None)
+ (*pScreen->PaintWindowBackground)(pWin, &reg, PW_BACKGROUND);
+ REGION_UNINIT(pScreen, &reg);
+ if (pBSReg)
+ REGION_DESTROY(pScreen, pBSReg);
+}
+
+/*
+ * For SaveUnders using backing-store. The idea is that when a window is mapped
+ * with saveUnder set TRUE, any windows it obscures will have its backing
+ * store turned on setting the DIXsaveUnder bit,
+ * The backing-store code must be written to allow for this
+ */
+
+/*-
+ *-----------------------------------------------------------------------
+ * miCheckSubSaveUnder --
+ * Check all the inferiors of a window for coverage by saveUnder
+ * windows. Called from ChangeSaveUnder and CheckSaveUnder.
+ * This code is very inefficient.
+ *
+ * Results:
+ * TRUE if any windows need to have backing-store removed.
+ *
+ * Side Effects:
+ * Windows may have backing-store turned on or off.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Bool
+miCheckSubSaveUnder(
+ register WindowPtr pParent, /* Parent to check */
+ WindowPtr pFirst, /* first reconfigured window */
+ RegionPtr pRegion) /* Initial area obscured by saveUnder */
+{
+ register WindowPtr pChild; /* Current child */
+ register ScreenPtr pScreen; /* Screen to use */
+ RegionRec SubRegion; /* Area of children obscured */
+ Bool res = FALSE; /* result */
+ Bool subInited=FALSE;/* SubRegion initialized */
+
+ pScreen = pParent->drawable.pScreen;
+ if ( (pChild = pParent->firstChild) )
+ {
+ /*
+ * build region above first changed window
+ */
+
+ for (; pChild != pFirst; pChild = pChild->nextSib)
+ if (pChild->viewable && pChild->saveUnder)
+ REGION_UNION(pScreen, pRegion, pRegion, &pChild->borderSize);
+
+ /*
+ * check region below and including first changed window
+ */
+
+ for (; pChild; pChild = pChild->nextSib)
+ {
+ if (pChild->viewable)
+ {
+ /*
+ * don't save under nephew/niece windows;
+ * use a separate region
+ */
+
+ if (pChild->firstChild)
+ {
+ if (!subInited)
+ {
+ REGION_NULL(pScreen, &SubRegion);
+ subInited = TRUE;
+ }
+ REGION_COPY(pScreen, &SubRegion, pRegion);
+ res |= miCheckSubSaveUnder(pChild, pChild->firstChild,
+ &SubRegion);
+ }
+ else
+ {
+ res |= miCheckSubSaveUnder(pChild, pChild->firstChild,
+ pRegion);
+ }
+
+ if (pChild->saveUnder)
+ REGION_UNION(pScreen, pRegion, pRegion, &pChild->borderSize);
+ }
+ }
+
+ if (subInited)
+ REGION_UNINIT(pScreen, &SubRegion);
+ }
+
+ /*
+ * Check the state of this window. DIX save unders are
+ * enabled for viewable windows with some client expressing
+ * exposure interest and which intersect the save under region
+ */
+
+ if (pParent->viewable &&
+ ((pParent->eventMask | wOtherEventMasks(pParent)) & ExposureMask) &&
+ REGION_NOTEMPTY(pScreen, &pParent->borderSize) &&
+ RECT_IN_REGION(pScreen, pRegion, REGION_EXTENTS(pScreen,
+ &pParent->borderSize)) != rgnOUT)
+ {
+ if (!pParent->DIXsaveUnder)
+ {
+ pParent->DIXsaveUnder = TRUE;
+ (*pScreen->ChangeWindowAttributes) (pParent, CWBackingStore);
+ }
+ }
+ else
+ {
+ if (pParent->DIXsaveUnder)
+ {
+ res = TRUE;
+ pParent->DIXsaveUnder = FALSE;
+ }
+ }
+ return res;
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * miChangeSaveUnder --
+ * Change the save-under state of a tree of windows. Called when
+ * a window with saveUnder TRUE is mapped/unmapped/reconfigured.
+ *
+ * Results:
+ * TRUE if any windows need to have backing-store removed (which
+ * means that PostChangeSaveUnder needs to be called later to
+ * finish the job).
+ *
+ * Side Effects:
+ * Windows may have backing-store turned on or off.
+ *
+ *-----------------------------------------------------------------------
+ */
+Bool
+miChangeSaveUnder(pWin, first)
+ register WindowPtr pWin;
+ WindowPtr first; /* First window to check.
+ * Used when pWin was restacked */
+{
+ RegionRec rgn; /* Area obscured by saveUnder windows */
+ register ScreenPtr pScreen;
+ Bool res;
+
+ if (!deltaSaveUndersViewable && !numSaveUndersViewable)
+ return FALSE;
+ numSaveUndersViewable += deltaSaveUndersViewable;
+ deltaSaveUndersViewable = 0;
+ pScreen = pWin->drawable.pScreen;
+ REGION_NULL(pScreen, &rgn);
+ res = miCheckSubSaveUnder (pWin->parent,
+ pWin->saveUnder ? first : pWin->nextSib,
+ &rgn);
+ REGION_UNINIT(pScreen, &rgn);
+ return res;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miPostChangeSaveUnder --
+ * Actually turn backing-store off for those windows that no longer
+ * need to have it on.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Backing-store and SAVE_UNDER_CHANGE_BIT are turned off for those
+ * windows affected.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+miPostChangeSaveUnder(pWin, pFirst)
+ WindowPtr pWin;
+ WindowPtr pFirst;
+{
+ register WindowPtr pParent, pChild;
+ ChangeWindowAttributesProcPtr ChangeWindowAttributes;
+
+ if (!(pParent = pWin->parent))
+ return;
+ ChangeWindowAttributes = pParent->drawable.pScreen->ChangeWindowAttributes;
+ if (!pParent->DIXsaveUnder &&
+ (pParent->backingStore == NotUseful) && pParent->backStorage)
+ (*ChangeWindowAttributes)(pParent, CWBackingStore);
+ if (!(pChild = pFirst))
+ return;
+ while (1)
+ {
+ if (!pChild->DIXsaveUnder &&
+ (pChild->backingStore == NotUseful) && pChild->backStorage)
+ (*ChangeWindowAttributes)(pChild, CWBackingStore);
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ while (!pChild->nextSib)
+ {
+ pChild = pChild->parent;
+ if (pChild == pParent)
+ return;
+ }
+ pChild = pChild->nextSib;
+ }
+}
+
+void
+miMarkWindow(pWin)
+ register WindowPtr pWin;
+{
+ register ValidatePtr val;
+
+ if (pWin->valdata)
+ return;
+ val = (ValidatePtr)xnfalloc(sizeof(ValidateRec));
+ val->before.oldAbsCorner.x = pWin->drawable.x;
+ val->before.oldAbsCorner.y = pWin->drawable.y;
+ val->before.borderVisible = NullRegion;
+ val->before.resized = FALSE;
+ pWin->valdata = val;
+}
+
+Bool
+miMarkOverlappedWindows(pWin, pFirst, ppLayerWin)
+ WindowPtr pWin;
+ WindowPtr pFirst;
+ WindowPtr *ppLayerWin;
+{
+ register BoxPtr box;
+ register WindowPtr pChild, pLast;
+ Bool anyMarked = FALSE;
+ MarkWindowProcPtr MarkWindow = pWin->drawable.pScreen->MarkWindow;
+ ScreenPtr pScreen;
+
+ pScreen = pWin->drawable.pScreen;
+
+ /* single layered systems are easy */
+ if (ppLayerWin) *ppLayerWin = pWin;
+
+ if (pWin == pFirst)
+ {
+ /* Blindly mark pWin and all of its inferiors. This is a slight
+ * overkill if there are mapped windows that outside pWin's border,
+ * but it's better than wasting time on RectIn checks.
+ */
+ pChild = pWin;
+ while (1)
+ {
+ if (pChild->viewable)
+ {
+ if (REGION_BROKEN (pScreen, &pChild->winSize))
+ SetWinSize (pChild);
+ if (REGION_BROKEN (pScreen, &pChild->borderSize))
+ SetBorderSize (pChild);
+ (* MarkWindow)(pChild);
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ break;
+ pChild = pChild->nextSib;
+ }
+ anyMarked = TRUE;
+ pFirst = pFirst->nextSib;
+ }
+ if ( (pChild = pFirst) )
+ {
+ box = REGION_EXTENTS(pChild->drawable.pScreen, &pWin->borderSize);
+ pLast = pChild->parent->lastChild;
+ while (1)
+ {
+ if (pChild->viewable)
+ {
+ if (REGION_BROKEN (pScreen, &pChild->winSize))
+ SetWinSize (pChild);
+ if (REGION_BROKEN (pScreen, &pChild->borderSize))
+ SetBorderSize (pChild);
+ if (RECT_IN_REGION(pScreen, &pChild->borderSize, box))
+ {
+ (* MarkWindow)(pChild);
+ anyMarked = TRUE;
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ }
+ while (!pChild->nextSib && (pChild != pLast))
+ pChild = pChild->parent;
+ if (pChild == pLast)
+ break;
+ pChild = pChild->nextSib;
+ }
+ }
+ if (anyMarked)
+ (* MarkWindow)(pWin->parent);
+ return anyMarked;
+}
+
+/*****
+ * miHandleValidateExposures(pWin)
+ * starting at pWin, draw background in any windows that have exposure
+ * regions, translate the regions, restore any backing store,
+ * and then send any regions still exposed to the client
+ *****/
+void
+miHandleValidateExposures(pWin)
+ WindowPtr pWin;
+{
+ register WindowPtr pChild;
+ register ValidatePtr val;
+ ScreenPtr pScreen;
+ WindowExposuresProcPtr WindowExposures;
+
+ pScreen = pWin->drawable.pScreen;
+
+ pChild = pWin;
+ WindowExposures = pChild->drawable.pScreen->WindowExposures;
+ while (1)
+ {
+ if ( (val = pChild->valdata) )
+ {
+ if (REGION_NOTEMPTY(pScreen, &val->after.borderExposed))
+ (*pChild->drawable.pScreen->PaintWindowBorder)(pChild,
+ &val->after.borderExposed,
+ PW_BORDER);
+ REGION_UNINIT(pScreen, &val->after.borderExposed);
+ (*WindowExposures)(pChild, &val->after.exposed, NullRegion);
+ REGION_UNINIT(pScreen, &val->after.exposed);
+ xfree(val);
+ pChild->valdata = (ValidatePtr)NULL;
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ break;
+ pChild = pChild->nextSib;
+ }
+}
+
+void
+miMoveWindow(pWin, x, y, pNextSib, kind)
+ register WindowPtr pWin;
+ int x,y;
+ WindowPtr pNextSib;
+ VTKind kind;
+{
+ WindowPtr pParent;
+ Bool WasViewable = (Bool)(pWin->viewable);
+ short bw;
+ RegionPtr oldRegion = NULL;
+ DDXPointRec oldpt;
+ Bool anyMarked = FALSE;
+ register ScreenPtr pScreen;
+ WindowPtr windowToValidate;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ /* if this is a root window, can't be moved */
+ if (!(pParent = pWin->parent))
+ return ;
+ pScreen = pWin->drawable.pScreen;
+ bw = wBorderWidth (pWin);
+
+ oldpt.x = pWin->drawable.x;
+ oldpt.y = pWin->drawable.y;
+ if (WasViewable)
+ {
+ oldRegion = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_COPY(pScreen, oldRegion, &pWin->borderClip);
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
+ }
+ pWin->origin.x = x + (int)bw;
+ pWin->origin.y = y + (int)bw;
+ x = pWin->drawable.x = pParent->drawable.x + x + (int)bw;
+ y = pWin->drawable.y = pParent->drawable.y + y + (int)bw;
+
+ SetWinSize (pWin);
+ SetBorderSize (pWin);
+
+ (*pScreen->PositionWindow)(pWin, x, y);
+
+ windowToValidate = MoveWindowInStack(pWin, pNextSib);
+
+ ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0);
+
+ if (WasViewable)
+ {
+ if (pLayerWin == pWin)
+ anyMarked |= (*pScreen->MarkOverlappedWindows)
+ (pWin, windowToValidate, (WindowPtr *)NULL);
+ else
+ anyMarked |= (*pScreen->MarkOverlappedWindows)
+ (pWin, pLayerWin, (WindowPtr *)NULL);
+
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, windowToValidate);
+ }
+#endif /* DO_SAVE_UNDERS */
+
+ if (anyMarked)
+ {
+ (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, kind);
+ (* pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, oldRegion);
+ REGION_DESTROY(pScreen, oldRegion);
+ /* XXX need to retile border if ParentRelative origin */
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, windowToValidate);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, kind);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+}
+
+
+/*
+ * pValid is a region of the screen which has been
+ * successfully copied -- recomputed exposed regions for affected windows
+ */
+
+static int
+miRecomputeExposures (
+ register WindowPtr pWin,
+ pointer value) /* must conform to VisitWindowProcPtr */
+{
+ register ScreenPtr pScreen;
+ RegionPtr pValid = (RegionPtr)value;
+
+ if (pWin->valdata)
+ {
+ pScreen = pWin->drawable.pScreen;
+ /*
+ * compute exposed regions of this window
+ */
+ REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed,
+ &pWin->clipList, pValid);
+ /*
+ * compute exposed regions of the border
+ */
+ REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed,
+ &pWin->borderClip, &pWin->winSize);
+ REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed,
+ &pWin->valdata->after.borderExposed, pValid);
+ return WT_WALKCHILDREN;
+ }
+ return WT_NOMATCH;
+}
+
+void
+miSlideAndSizeWindow(pWin, x, y, w, h, pSib)
+ register WindowPtr pWin;
+ int x,y;
+ unsigned int w, h;
+ WindowPtr pSib;
+{
+ WindowPtr pParent;
+ Bool WasViewable = (Bool)(pWin->viewable);
+ unsigned short width = pWin->drawable.width,
+ height = pWin->drawable.height;
+ short oldx = pWin->drawable.x,
+ oldy = pWin->drawable.y;
+ int bw = wBorderWidth (pWin);
+ short dw, dh;
+ DDXPointRec oldpt;
+ RegionPtr oldRegion = NULL;
+ Bool anyMarked = FALSE;
+ register ScreenPtr pScreen;
+ WindowPtr pFirstChange;
+ register WindowPtr pChild;
+ RegionPtr gravitate[StaticGravity + 1];
+ register unsigned g;
+ int nx, ny; /* destination x,y */
+ int newx, newy; /* new inner window position */
+ RegionPtr pRegion = NULL;
+ RegionPtr destClip; /* portions of destination already written */
+ RegionPtr oldWinClip = NULL; /* old clip list for window */
+ RegionPtr borderVisible = NullRegion; /* visible area of the border */
+ RegionPtr bsExposed = NullRegion; /* backing store exposures */
+ Bool shrunk = FALSE; /* shrunk in an inner dimension */
+ Bool moved = FALSE; /* window position changed */
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ /* if this is a root window, can't be resized */
+ if (!(pParent = pWin->parent))
+ return ;
+
+ pScreen = pWin->drawable.pScreen;
+ newx = pParent->drawable.x + x + bw;
+ newy = pParent->drawable.y + y + bw;
+ if (WasViewable)
+ {
+ anyMarked = FALSE;
+ /*
+ * save the visible region of the window
+ */
+ oldRegion = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_COPY(pScreen, oldRegion, &pWin->winSize);
+
+ /*
+ * categorize child windows into regions to be moved
+ */
+ for (g = 0; g <= StaticGravity; g++)
+ gravitate[g] = (RegionPtr) NULL;
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+ {
+ g = pChild->winGravity;
+ if (g != UnmapGravity)
+ {
+ if (!gravitate[g])
+ gravitate[g] = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_UNION(pScreen, gravitate[g],
+ gravitate[g], &pChild->borderClip);
+ }
+ else
+ {
+ UnmapWindow(pChild, TRUE);
+ anyMarked = TRUE;
+ }
+ }
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ &pLayerWin);
+
+ oldWinClip = NULL;
+ if (pWin->bitGravity != ForgetGravity)
+ {
+ oldWinClip = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_COPY(pScreen, oldWinClip, &pWin->clipList);
+ }
+ /*
+ * if the window is changing size, borderExposed
+ * can't be computed correctly without some help.
+ */
+ if (pWin->drawable.height > h || pWin->drawable.width > w)
+ shrunk = TRUE;
+
+ if (newx != oldx || newy != oldy)
+ moved = TRUE;
+
+ if ((pWin->drawable.height != h || pWin->drawable.width != w) &&
+ HasBorder (pWin))
+ {
+ borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+ /* for tiled borders, we punt and draw the whole thing */
+ if (pWin->borderIsPixel || !moved)
+ {
+ if (shrunk || moved)
+ REGION_SUBTRACT(pScreen, borderVisible,
+ &pWin->borderClip,
+ &pWin->winSize);
+ else
+ REGION_COPY(pScreen, borderVisible,
+ &pWin->borderClip);
+ }
+ }
+ }
+ pWin->origin.x = x + bw;
+ pWin->origin.y = y + bw;
+ pWin->drawable.height = h;
+ pWin->drawable.width = w;
+
+ x = pWin->drawable.x = newx;
+ y = pWin->drawable.y = newy;
+
+ SetWinSize (pWin);
+ SetBorderSize (pWin);
+
+ dw = (int)w - (int)width;
+ dh = (int)h - (int)height;
+ ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh);
+
+ /* let the hardware adjust background and border pixmaps, if any */
+ (*pScreen->PositionWindow)(pWin, x, y);
+
+ pFirstChange = MoveWindowInStack(pWin, pSib);
+
+ if (WasViewable)
+ {
+ pRegion = REGION_CREATE(pScreen, NullBox, 1);
+ if (pWin->backStorage)
+ REGION_COPY(pScreen, pRegion, &pWin->clipList);
+
+ if (pLayerWin == pWin)
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
+ (WindowPtr *)NULL);
+ else
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
+ (WindowPtr *)NULL);
+
+ if (pWin->valdata)
+ {
+ pWin->valdata->before.resized = TRUE;
+ pWin->valdata->before.borderVisible = borderVisible;
+ }
+
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pFirstChange);
+ }
+#endif /* DO_SAVE_UNDERS */
+
+ if (anyMarked)
+ (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, VTOther);
+ /*
+ * the entire window is trashed unless bitGravity
+ * recovers portions of it
+ */
+ REGION_COPY(pScreen, &pWin->valdata->after.exposed, &pWin->clipList);
+ }
+
+ GravityTranslate (x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny);
+
+ if (pWin->backStorage &&
+ ((pWin->backingStore == Always) || WasViewable))
+ {
+ if (!WasViewable)
+ pRegion = &pWin->clipList; /* a convenient empty region */
+ if (pWin->bitGravity == ForgetGravity)
+ bsExposed = (*pScreen->TranslateBackingStore)
+ (pWin, 0, 0, NullRegion, oldx, oldy);
+ else
+ {
+ bsExposed = (*pScreen->TranslateBackingStore)
+ (pWin, nx - x, ny - y, pRegion, oldx, oldy);
+ }
+ }
+
+ if (WasViewable)
+ {
+ /* avoid the border */
+ if (HasBorder (pWin))
+ {
+ int offx, offy, dx, dy;
+
+ /* kruft to avoid double translates for each gravity */
+ offx = 0;
+ offy = 0;
+ for (g = 0; g <= StaticGravity; g++)
+ {
+ if (!gravitate[g])
+ continue;
+
+ /* align winSize to gravitate[g].
+ * winSize is in new coordinates,
+ * gravitate[g] is still in old coordinates */
+ GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
+
+ dx = (oldx - nx) - offx;
+ dy = (oldy - ny) - offy;
+ if (dx || dy)
+ {
+ REGION_TRANSLATE(pScreen, &pWin->winSize, dx, dy);
+ offx += dx;
+ offy += dy;
+ }
+ REGION_INTERSECT(pScreen, gravitate[g], gravitate[g],
+ &pWin->winSize);
+ }
+ /* get winSize back where it belongs */
+ if (offx || offy)
+ REGION_TRANSLATE(pScreen, &pWin->winSize, -offx, -offy);
+ }
+ /*
+ * add screen bits to the appropriate bucket
+ */
+
+ if (oldWinClip)
+ {
+ /*
+ * clip to new clipList
+ */
+ REGION_COPY(pScreen, pRegion, oldWinClip);
+ REGION_TRANSLATE(pScreen, pRegion, nx - oldx, ny - oldy);
+ REGION_INTERSECT(pScreen, oldWinClip, pRegion, &pWin->clipList);
+ /*
+ * don't step on any gravity bits which will be copied after this
+ * region. Note -- this assumes that the regions will be copied
+ * in gravity order.
+ */
+ for (g = pWin->bitGravity + 1; g <= StaticGravity; g++)
+ {
+ if (gravitate[g])
+ REGION_SUBTRACT(pScreen, oldWinClip, oldWinClip,
+ gravitate[g]);
+ }
+ REGION_TRANSLATE(pScreen, oldWinClip, oldx - nx, oldy - ny);
+ g = pWin->bitGravity;
+ if (!gravitate[g])
+ gravitate[g] = oldWinClip;
+ else
+ {
+ REGION_UNION(pScreen, gravitate[g], gravitate[g], oldWinClip);
+ REGION_DESTROY(pScreen, oldWinClip);
+ }
+ }
+
+ /*
+ * move the bits on the screen
+ */
+
+ destClip = NULL;
+
+ for (g = 0; g <= StaticGravity; g++)
+ {
+ if (!gravitate[g])
+ continue;
+
+ GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
+
+ oldpt.x = oldx + (x - nx);
+ oldpt.y = oldy + (y - ny);
+
+ /* Note that gravitate[g] is *translated* by CopyWindow */
+
+ /* only copy the remaining useful bits */
+
+ REGION_INTERSECT(pScreen, gravitate[g], gravitate[g], oldRegion);
+
+ /* clip to not overwrite already copied areas */
+
+ if (destClip) {
+ REGION_TRANSLATE(pScreen, destClip, oldpt.x - x, oldpt.y - y);
+ REGION_SUBTRACT(pScreen, gravitate[g], gravitate[g], destClip);
+ REGION_TRANSLATE(pScreen, destClip, x - oldpt.x, y - oldpt.y);
+ }
+
+ /* and move those bits */
+
+ if (oldpt.x != x || oldpt.y != y
+#ifdef COMPOSITE
+ || pWin->redirectDraw
+#endif
+ )
+ {
+ (*pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, gravitate[g]);
+ }
+
+ /* remove any overwritten bits from the remaining useful bits */
+
+ REGION_SUBTRACT(pScreen, oldRegion, oldRegion, gravitate[g]);
+
+ /*
+ * recompute exposed regions of child windows
+ */
+
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+ {
+ if (pChild->winGravity != g)
+ continue;
+ REGION_INTERSECT(pScreen, pRegion,
+ &pChild->borderClip, gravitate[g]);
+ TraverseTree (pChild, miRecomputeExposures, (pointer)pRegion);
+ }
+
+ /*
+ * remove the successfully copied regions of the
+ * window from its exposed region
+ */
+
+ if (g == pWin->bitGravity)
+ REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed,
+ &pWin->valdata->after.exposed, gravitate[g]);
+ if (!destClip)
+ destClip = gravitate[g];
+ else
+ {
+ REGION_UNION(pScreen, destClip, destClip, gravitate[g]);
+ REGION_DESTROY(pScreen, gravitate[g]);
+ }
+ }
+
+ REGION_DESTROY(pScreen, oldRegion);
+ REGION_DESTROY(pScreen, pRegion);
+ if (destClip)
+ REGION_DESTROY(pScreen, destClip);
+ if (bsExposed)
+ {
+ RegionPtr valExposed = NullRegion;
+
+ if (pWin->valdata)
+ valExposed = &pWin->valdata->after.exposed;
+ (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+ if (valExposed)
+ REGION_EMPTY(pScreen, valExposed);
+ REGION_DESTROY(pScreen, bsExposed);
+ }
+ if (anyMarked)
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ {
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pFirstChange);
+ }
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange,
+ VTOther);
+ }
+ else if (bsExposed)
+ {
+ (*pScreen->WindowExposures) (pWin, NullRegion, bsExposed);
+ REGION_DESTROY(pScreen, bsExposed);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+}
+
+WindowPtr
+miGetLayerWindow(pWin)
+ WindowPtr pWin;
+{
+ return pWin->firstChild;
+}
+
+#ifdef SHAPE
+/******
+ *
+ * miSetShape
+ * The border/window shape has changed. Recompute winSize/borderSize
+ * and send appropriate exposure events
+ */
+
+void
+miSetShape(pWin)
+ register WindowPtr pWin;
+{
+ Bool WasViewable = (Bool)(pWin->viewable);
+ register ScreenPtr pScreen = pWin->drawable.pScreen;
+ Bool anyMarked = FALSE;
+ RegionPtr pOldClip = NULL, bsExposed;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ if (WasViewable)
+ {
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ &pLayerWin);
+ if (pWin->valdata)
+ {
+ if (HasBorder (pWin))
+ {
+ RegionPtr borderVisible;
+
+ borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_SUBTRACT(pScreen, borderVisible,
+ &pWin->borderClip, &pWin->winSize);
+ pWin->valdata->before.borderVisible = borderVisible;
+ }
+ pWin->valdata->before.resized = TRUE;
+ }
+ }
+
+ SetWinSize (pWin);
+ SetBorderSize (pWin);
+
+ ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
+
+ if (WasViewable)
+ {
+ if (pWin->backStorage)
+ {
+ pOldClip = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_COPY(pScreen, pOldClip, &pWin->clipList);
+ }
+
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ (WindowPtr *)NULL);
+
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin);
+ }
+#endif /* DO_SAVE_UNDERS */
+
+ if (anyMarked)
+ (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, VTOther);
+ }
+
+ if (pWin->backStorage &&
+ ((pWin->backingStore == Always) || WasViewable))
+ {
+ if (!WasViewable)
+ pOldClip = &pWin->clipList; /* a convenient empty region */
+ bsExposed = (*pScreen->TranslateBackingStore)
+ (pWin, 0, 0, pOldClip,
+ pWin->drawable.x, pWin->drawable.y);
+#ifdef NXAGENT_SERVER
+
+ /*
+ * We got a few, rare, segfaults here after having
+ * started using the backing store. It may be a
+ * different bug but miChangeSaveUnder() calls mi-
+ * CheckSubSaveUnder() that, in turn, can change
+ * the backing store attribute of the window. This
+ * means that we may try to destroy the region
+ * even if it was not created at the beginning of
+ * this function as, at the time, the backing store
+ * was off. miCheckSubSaveUnder() appear to get a
+ * pointer to the parent, so maybe doesn't change
+ * the attribute of the window itself. This is to
+ * be better investigated.
+ */
+
+ if (WasViewable && pOldClip)
+ REGION_DESTROY(pScreen, pOldClip);
+#else
+ if (WasViewable)
+ REGION_DESTROY(pScreen, pOldClip);
+#endif
+ if (bsExposed)
+ {
+ RegionPtr valExposed = NullRegion;
+
+ if (pWin->valdata)
+ valExposed = &pWin->valdata->after.exposed;
+ (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+ if (valExposed)
+ REGION_EMPTY(pScreen, valExposed);
+ REGION_DESTROY(pScreen, bsExposed);
+ }
+ }
+ if (WasViewable)
+ {
+ if (anyMarked)
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, VTOther);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+ CheckCursorConfinement(pWin);
+}
+#endif
+
+/* Keeps the same inside(!) origin */
+
+void
+miChangeBorderWidth(pWin, width)
+ register WindowPtr pWin;
+ unsigned int width;
+{
+ int oldwidth;
+ Bool anyMarked = FALSE;
+ register ScreenPtr pScreen;
+ Bool WasViewable = (Bool)(pWin->viewable);
+ Bool HadBorder;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ oldwidth = wBorderWidth (pWin);
+ if (oldwidth == width)
+ return;
+ HadBorder = HasBorder(pWin);
+ pScreen = pWin->drawable.pScreen;
+ if (WasViewable && width < oldwidth)
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
+
+ pWin->borderWidth = width;
+ SetBorderSize (pWin);
+
+ if (WasViewable)
+ {
+ if (width > oldwidth)
+ {
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ &pLayerWin);
+ /*
+ * save the old border visible region to correctly compute
+ * borderExposed.
+ */
+ if (pWin->valdata && HadBorder)
+ {
+ RegionPtr borderVisible;
+ borderVisible = REGION_CREATE(pScreen, NULL, 1);
+ REGION_SUBTRACT(pScreen, borderVisible,
+ &pWin->borderClip, &pWin->winSize);
+ pWin->valdata->before.borderVisible = borderVisible;
+ }
+ }
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib);
+ }
+#endif /* DO_SAVE_UNDERS */
+
+ if (anyMarked)
+ {
+ (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTOther);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin,
+ VTOther);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+}
+
+void
+miMarkUnrealizedWindow(pChild, pWin, fromConfigure)
+ WindowPtr pChild;
+ WindowPtr pWin;
+ Bool fromConfigure;
+{
+ if ((pChild != pWin) || fromConfigure)
+ {
+ REGION_EMPTY(pChild->drawable.pScreen, &pChild->clipList);
+ if (pChild->drawable.pScreen->ClipNotify)
+ (* pChild->drawable.pScreen->ClipNotify)(pChild, 0, 0);
+ REGION_EMPTY(pChild->drawable.pScreen, &pChild->borderClip);
+ }
+}
+
+void
+miSegregateChildren(WindowPtr pWin, RegionPtr pReg, int depth)
+{
+ ScreenPtr pScreen;
+ WindowPtr pChild;
+
+ pScreen = pWin->drawable.pScreen;
+
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+ {
+ if (pChild->drawable.depth == depth)
+ REGION_UNION(pScreen, pReg, pReg, &pChild->borderClip);
+
+ if (pChild->firstChild)
+ miSegregateChildren(pChild, pReg, depth);
+ }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.NX.original
new file mode 100644
index 000000000..1731e0753
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.NX.original
@@ -0,0 +1,1222 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/mi/miwindow.c,v 1.9tsi Exp $ */
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+/* $Xorg: miwindow.c,v 1.4 2001/02/09 02:05:22 xorgcvs Exp $ */
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "regionstr.h"
+#include "region.h"
+#include "mi.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "mivalidate.h"
+
+void
+miClearToBackground(pWin, x, y, w, h, generateExposures)
+ WindowPtr pWin;
+ int x,y;
+ int w,h;
+ Bool generateExposures;
+{
+ BoxRec box;
+ RegionRec reg;
+ RegionPtr pBSReg = NullRegion;
+ ScreenPtr pScreen;
+ BoxPtr extents;
+ int x1, y1, x2, y2;
+
+ /* compute everything using ints to avoid overflow */
+
+ x1 = pWin->drawable.x + x;
+ y1 = pWin->drawable.y + y;
+ if (w)
+ x2 = x1 + (int) w;
+ else
+ x2 = x1 + (int) pWin->drawable.width - (int) x;
+ if (h)
+ y2 = y1 + h;
+ else
+ y2 = y1 + (int) pWin->drawable.height - (int) y;
+
+ extents = &pWin->clipList.extents;
+
+ /* clip the resulting rectangle to the window clipList extents. This
+ * makes sure that the result will fit in a box, given that the
+ * screen is < 32768 on a side.
+ */
+
+ if (x1 < extents->x1)
+ x1 = extents->x1;
+ if (x2 > extents->x2)
+ x2 = extents->x2;
+ if (y1 < extents->y1)
+ y1 = extents->y1;
+ if (y2 > extents->y2)
+ y2 = extents->y2;
+
+ if (x2 <= x1 || y2 <= y1)
+ {
+ x2 = x1 = 0;
+ y2 = y1 = 0;
+ }
+
+ box.x1 = x1;
+ box.x2 = x2;
+ box.y1 = y1;
+ box.y2 = y2;
+
+ pScreen = pWin->drawable.pScreen;
+ REGION_INIT(pScreen, &reg, &box, 1);
+ if (pWin->backStorage)
+ {
+ /*
+ * If the window has backing-store on, call through the
+ * ClearToBackground vector to handle the special semantics
+ * (i.e. things backing store is to be cleared out and
+ * an Expose event is to be generated for those areas in backing
+ * store if generateExposures is TRUE).
+ */
+ pBSReg = (* pScreen->ClearBackingStore)(pWin, x, y, w, h,
+ generateExposures);
+ }
+
+ REGION_INTERSECT(pScreen, &reg, &reg, &pWin->clipList);
+ if (generateExposures)
+ (*pScreen->WindowExposures)(pWin, &reg, pBSReg);
+ else if (pWin->backgroundState != None)
+ (*pScreen->PaintWindowBackground)(pWin, &reg, PW_BACKGROUND);
+ REGION_UNINIT(pScreen, &reg);
+ if (pBSReg)
+ REGION_DESTROY(pScreen, pBSReg);
+}
+
+/*
+ * For SaveUnders using backing-store. The idea is that when a window is mapped
+ * with saveUnder set TRUE, any windows it obscures will have its backing
+ * store turned on setting the DIXsaveUnder bit,
+ * The backing-store code must be written to allow for this
+ */
+
+/*-
+ *-----------------------------------------------------------------------
+ * miCheckSubSaveUnder --
+ * Check all the inferiors of a window for coverage by saveUnder
+ * windows. Called from ChangeSaveUnder and CheckSaveUnder.
+ * This code is very inefficient.
+ *
+ * Results:
+ * TRUE if any windows need to have backing-store removed.
+ *
+ * Side Effects:
+ * Windows may have backing-store turned on or off.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Bool
+miCheckSubSaveUnder(
+ register WindowPtr pParent, /* Parent to check */
+ WindowPtr pFirst, /* first reconfigured window */
+ RegionPtr pRegion) /* Initial area obscured by saveUnder */
+{
+ register WindowPtr pChild; /* Current child */
+ register ScreenPtr pScreen; /* Screen to use */
+ RegionRec SubRegion; /* Area of children obscured */
+ Bool res = FALSE; /* result */
+ Bool subInited=FALSE;/* SubRegion initialized */
+
+ pScreen = pParent->drawable.pScreen;
+ if ( (pChild = pParent->firstChild) )
+ {
+ /*
+ * build region above first changed window
+ */
+
+ for (; pChild != pFirst; pChild = pChild->nextSib)
+ if (pChild->viewable && pChild->saveUnder)
+ REGION_UNION(pScreen, pRegion, pRegion, &pChild->borderSize);
+
+ /*
+ * check region below and including first changed window
+ */
+
+ for (; pChild; pChild = pChild->nextSib)
+ {
+ if (pChild->viewable)
+ {
+ /*
+ * don't save under nephew/niece windows;
+ * use a separate region
+ */
+
+ if (pChild->firstChild)
+ {
+ if (!subInited)
+ {
+ REGION_NULL(pScreen, &SubRegion);
+ subInited = TRUE;
+ }
+ REGION_COPY(pScreen, &SubRegion, pRegion);
+ res |= miCheckSubSaveUnder(pChild, pChild->firstChild,
+ &SubRegion);
+ }
+ else
+ {
+ res |= miCheckSubSaveUnder(pChild, pChild->firstChild,
+ pRegion);
+ }
+
+ if (pChild->saveUnder)
+ REGION_UNION(pScreen, pRegion, pRegion, &pChild->borderSize);
+ }
+ }
+
+ if (subInited)
+ REGION_UNINIT(pScreen, &SubRegion);
+ }
+
+ /*
+ * Check the state of this window. DIX save unders are
+ * enabled for viewable windows with some client expressing
+ * exposure interest and which intersect the save under region
+ */
+
+ if (pParent->viewable &&
+ ((pParent->eventMask | wOtherEventMasks(pParent)) & ExposureMask) &&
+ REGION_NOTEMPTY(pScreen, &pParent->borderSize) &&
+ RECT_IN_REGION(pScreen, pRegion, REGION_EXTENTS(pScreen,
+ &pParent->borderSize)) != rgnOUT)
+ {
+ if (!pParent->DIXsaveUnder)
+ {
+ pParent->DIXsaveUnder = TRUE;
+ (*pScreen->ChangeWindowAttributes) (pParent, CWBackingStore);
+ }
+ }
+ else
+ {
+ if (pParent->DIXsaveUnder)
+ {
+ res = TRUE;
+ pParent->DIXsaveUnder = FALSE;
+ }
+ }
+ return res;
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * miChangeSaveUnder --
+ * Change the save-under state of a tree of windows. Called when
+ * a window with saveUnder TRUE is mapped/unmapped/reconfigured.
+ *
+ * Results:
+ * TRUE if any windows need to have backing-store removed (which
+ * means that PostChangeSaveUnder needs to be called later to
+ * finish the job).
+ *
+ * Side Effects:
+ * Windows may have backing-store turned on or off.
+ *
+ *-----------------------------------------------------------------------
+ */
+Bool
+miChangeSaveUnder(pWin, first)
+ register WindowPtr pWin;
+ WindowPtr first; /* First window to check.
+ * Used when pWin was restacked */
+{
+ RegionRec rgn; /* Area obscured by saveUnder windows */
+ register ScreenPtr pScreen;
+ Bool res;
+
+ if (!deltaSaveUndersViewable && !numSaveUndersViewable)
+ return FALSE;
+ numSaveUndersViewable += deltaSaveUndersViewable;
+ deltaSaveUndersViewable = 0;
+ pScreen = pWin->drawable.pScreen;
+ REGION_NULL(pScreen, &rgn);
+ res = miCheckSubSaveUnder (pWin->parent,
+ pWin->saveUnder ? first : pWin->nextSib,
+ &rgn);
+ REGION_UNINIT(pScreen, &rgn);
+ return res;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miPostChangeSaveUnder --
+ * Actually turn backing-store off for those windows that no longer
+ * need to have it on.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Backing-store and SAVE_UNDER_CHANGE_BIT are turned off for those
+ * windows affected.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+miPostChangeSaveUnder(pWin, pFirst)
+ WindowPtr pWin;
+ WindowPtr pFirst;
+{
+ register WindowPtr pParent, pChild;
+ ChangeWindowAttributesProcPtr ChangeWindowAttributes;
+
+ if (!(pParent = pWin->parent))
+ return;
+ ChangeWindowAttributes = pParent->drawable.pScreen->ChangeWindowAttributes;
+ if (!pParent->DIXsaveUnder &&
+ (pParent->backingStore == NotUseful) && pParent->backStorage)
+ (*ChangeWindowAttributes)(pParent, CWBackingStore);
+ if (!(pChild = pFirst))
+ return;
+ while (1)
+ {
+ if (!pChild->DIXsaveUnder &&
+ (pChild->backingStore == NotUseful) && pChild->backStorage)
+ (*ChangeWindowAttributes)(pChild, CWBackingStore);
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ while (!pChild->nextSib)
+ {
+ pChild = pChild->parent;
+ if (pChild == pParent)
+ return;
+ }
+ pChild = pChild->nextSib;
+ }
+}
+
+void
+miMarkWindow(pWin)
+ register WindowPtr pWin;
+{
+ register ValidatePtr val;
+
+ if (pWin->valdata)
+ return;
+ val = (ValidatePtr)xnfalloc(sizeof(ValidateRec));
+ val->before.oldAbsCorner.x = pWin->drawable.x;
+ val->before.oldAbsCorner.y = pWin->drawable.y;
+ val->before.borderVisible = NullRegion;
+ val->before.resized = FALSE;
+ pWin->valdata = val;
+}
+
+Bool
+miMarkOverlappedWindows(pWin, pFirst, ppLayerWin)
+ WindowPtr pWin;
+ WindowPtr pFirst;
+ WindowPtr *ppLayerWin;
+{
+ register BoxPtr box;
+ register WindowPtr pChild, pLast;
+ Bool anyMarked = FALSE;
+ MarkWindowProcPtr MarkWindow = pWin->drawable.pScreen->MarkWindow;
+ ScreenPtr pScreen;
+
+ pScreen = pWin->drawable.pScreen;
+
+ /* single layered systems are easy */
+ if (ppLayerWin) *ppLayerWin = pWin;
+
+ if (pWin == pFirst)
+ {
+ /* Blindly mark pWin and all of its inferiors. This is a slight
+ * overkill if there are mapped windows that outside pWin's border,
+ * but it's better than wasting time on RectIn checks.
+ */
+ pChild = pWin;
+ while (1)
+ {
+ if (pChild->viewable)
+ {
+ if (REGION_BROKEN (pScreen, &pChild->winSize))
+ SetWinSize (pChild);
+ if (REGION_BROKEN (pScreen, &pChild->borderSize))
+ SetBorderSize (pChild);
+ (* MarkWindow)(pChild);
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ break;
+ pChild = pChild->nextSib;
+ }
+ anyMarked = TRUE;
+ pFirst = pFirst->nextSib;
+ }
+ if ( (pChild = pFirst) )
+ {
+ box = REGION_EXTENTS(pChild->drawable.pScreen, &pWin->borderSize);
+ pLast = pChild->parent->lastChild;
+ while (1)
+ {
+ if (pChild->viewable)
+ {
+ if (REGION_BROKEN (pScreen, &pChild->winSize))
+ SetWinSize (pChild);
+ if (REGION_BROKEN (pScreen, &pChild->borderSize))
+ SetBorderSize (pChild);
+ if (RECT_IN_REGION(pScreen, &pChild->borderSize, box))
+ {
+ (* MarkWindow)(pChild);
+ anyMarked = TRUE;
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ }
+ while (!pChild->nextSib && (pChild != pLast))
+ pChild = pChild->parent;
+ if (pChild == pLast)
+ break;
+ pChild = pChild->nextSib;
+ }
+ }
+ if (anyMarked)
+ (* MarkWindow)(pWin->parent);
+ return anyMarked;
+}
+
+/*****
+ * miHandleValidateExposures(pWin)
+ * starting at pWin, draw background in any windows that have exposure
+ * regions, translate the regions, restore any backing store,
+ * and then send any regions still exposed to the client
+ *****/
+void
+miHandleValidateExposures(pWin)
+ WindowPtr pWin;
+{
+ register WindowPtr pChild;
+ register ValidatePtr val;
+ ScreenPtr pScreen;
+ WindowExposuresProcPtr WindowExposures;
+
+ pScreen = pWin->drawable.pScreen;
+
+ pChild = pWin;
+ WindowExposures = pChild->drawable.pScreen->WindowExposures;
+ while (1)
+ {
+ if ( (val = pChild->valdata) )
+ {
+ if (REGION_NOTEMPTY(pScreen, &val->after.borderExposed))
+ (*pChild->drawable.pScreen->PaintWindowBorder)(pChild,
+ &val->after.borderExposed,
+ PW_BORDER);
+ REGION_UNINIT(pScreen, &val->after.borderExposed);
+ (*WindowExposures)(pChild, &val->after.exposed, NullRegion);
+ REGION_UNINIT(pScreen, &val->after.exposed);
+ xfree(val);
+ pChild->valdata = (ValidatePtr)NULL;
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ break;
+ pChild = pChild->nextSib;
+ }
+}
+
+void
+miMoveWindow(pWin, x, y, pNextSib, kind)
+ register WindowPtr pWin;
+ int x,y;
+ WindowPtr pNextSib;
+ VTKind kind;
+{
+ WindowPtr pParent;
+ Bool WasViewable = (Bool)(pWin->viewable);
+ short bw;
+ RegionPtr oldRegion = NULL;
+ DDXPointRec oldpt;
+ Bool anyMarked = FALSE;
+ register ScreenPtr pScreen;
+ WindowPtr windowToValidate;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ /* if this is a root window, can't be moved */
+ if (!(pParent = pWin->parent))
+ return ;
+ pScreen = pWin->drawable.pScreen;
+ bw = wBorderWidth (pWin);
+
+ oldpt.x = pWin->drawable.x;
+ oldpt.y = pWin->drawable.y;
+ if (WasViewable)
+ {
+ oldRegion = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_COPY(pScreen, oldRegion, &pWin->borderClip);
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
+ }
+ pWin->origin.x = x + (int)bw;
+ pWin->origin.y = y + (int)bw;
+ x = pWin->drawable.x = pParent->drawable.x + x + (int)bw;
+ y = pWin->drawable.y = pParent->drawable.y + y + (int)bw;
+
+ SetWinSize (pWin);
+ SetBorderSize (pWin);
+
+ (*pScreen->PositionWindow)(pWin, x, y);
+
+ windowToValidate = MoveWindowInStack(pWin, pNextSib);
+
+ ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0);
+
+ if (WasViewable)
+ {
+ if (pLayerWin == pWin)
+ anyMarked |= (*pScreen->MarkOverlappedWindows)
+ (pWin, windowToValidate, (WindowPtr *)NULL);
+ else
+ anyMarked |= (*pScreen->MarkOverlappedWindows)
+ (pWin, pLayerWin, (WindowPtr *)NULL);
+
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, windowToValidate);
+ }
+#endif /* DO_SAVE_UNDERS */
+
+ if (anyMarked)
+ {
+ (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, kind);
+ (* pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, oldRegion);
+ REGION_DESTROY(pScreen, oldRegion);
+ /* XXX need to retile border if ParentRelative origin */
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, windowToValidate);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, kind);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+}
+
+
+/*
+ * pValid is a region of the screen which has been
+ * successfully copied -- recomputed exposed regions for affected windows
+ */
+
+static int
+miRecomputeExposures (
+ register WindowPtr pWin,
+ pointer value) /* must conform to VisitWindowProcPtr */
+{
+ register ScreenPtr pScreen;
+ RegionPtr pValid = (RegionPtr)value;
+
+ if (pWin->valdata)
+ {
+ pScreen = pWin->drawable.pScreen;
+ /*
+ * compute exposed regions of this window
+ */
+ REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed,
+ &pWin->clipList, pValid);
+ /*
+ * compute exposed regions of the border
+ */
+ REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed,
+ &pWin->borderClip, &pWin->winSize);
+ REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed,
+ &pWin->valdata->after.borderExposed, pValid);
+ return WT_WALKCHILDREN;
+ }
+ return WT_NOMATCH;
+}
+
+void
+miSlideAndSizeWindow(pWin, x, y, w, h, pSib)
+ register WindowPtr pWin;
+ int x,y;
+ unsigned int w, h;
+ WindowPtr pSib;
+{
+ WindowPtr pParent;
+ Bool WasViewable = (Bool)(pWin->viewable);
+ unsigned short width = pWin->drawable.width,
+ height = pWin->drawable.height;
+ short oldx = pWin->drawable.x,
+ oldy = pWin->drawable.y;
+ int bw = wBorderWidth (pWin);
+ short dw, dh;
+ DDXPointRec oldpt;
+ RegionPtr oldRegion = NULL;
+ Bool anyMarked = FALSE;
+ register ScreenPtr pScreen;
+ WindowPtr pFirstChange;
+ register WindowPtr pChild;
+ RegionPtr gravitate[StaticGravity + 1];
+ register unsigned g;
+ int nx, ny; /* destination x,y */
+ int newx, newy; /* new inner window position */
+ RegionPtr pRegion = NULL;
+ RegionPtr destClip; /* portions of destination already written */
+ RegionPtr oldWinClip = NULL; /* old clip list for window */
+ RegionPtr borderVisible = NullRegion; /* visible area of the border */
+ RegionPtr bsExposed = NullRegion; /* backing store exposures */
+ Bool shrunk = FALSE; /* shrunk in an inner dimension */
+ Bool moved = FALSE; /* window position changed */
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ /* if this is a root window, can't be resized */
+ if (!(pParent = pWin->parent))
+ return ;
+
+ pScreen = pWin->drawable.pScreen;
+ newx = pParent->drawable.x + x + bw;
+ newy = pParent->drawable.y + y + bw;
+ if (WasViewable)
+ {
+ anyMarked = FALSE;
+ /*
+ * save the visible region of the window
+ */
+ oldRegion = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_COPY(pScreen, oldRegion, &pWin->winSize);
+
+ /*
+ * categorize child windows into regions to be moved
+ */
+ for (g = 0; g <= StaticGravity; g++)
+ gravitate[g] = (RegionPtr) NULL;
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+ {
+ g = pChild->winGravity;
+ if (g != UnmapGravity)
+ {
+ if (!gravitate[g])
+ gravitate[g] = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_UNION(pScreen, gravitate[g],
+ gravitate[g], &pChild->borderClip);
+ }
+ else
+ {
+ UnmapWindow(pChild, TRUE);
+ anyMarked = TRUE;
+ }
+ }
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ &pLayerWin);
+
+ oldWinClip = NULL;
+ if (pWin->bitGravity != ForgetGravity)
+ {
+ oldWinClip = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_COPY(pScreen, oldWinClip, &pWin->clipList);
+ }
+ /*
+ * if the window is changing size, borderExposed
+ * can't be computed correctly without some help.
+ */
+ if (pWin->drawable.height > h || pWin->drawable.width > w)
+ shrunk = TRUE;
+
+ if (newx != oldx || newy != oldy)
+ moved = TRUE;
+
+ if ((pWin->drawable.height != h || pWin->drawable.width != w) &&
+ HasBorder (pWin))
+ {
+ borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+ /* for tiled borders, we punt and draw the whole thing */
+ if (pWin->borderIsPixel || !moved)
+ {
+ if (shrunk || moved)
+ REGION_SUBTRACT(pScreen, borderVisible,
+ &pWin->borderClip,
+ &pWin->winSize);
+ else
+ REGION_COPY(pScreen, borderVisible,
+ &pWin->borderClip);
+ }
+ }
+ }
+ pWin->origin.x = x + bw;
+ pWin->origin.y = y + bw;
+ pWin->drawable.height = h;
+ pWin->drawable.width = w;
+
+ x = pWin->drawable.x = newx;
+ y = pWin->drawable.y = newy;
+
+ SetWinSize (pWin);
+ SetBorderSize (pWin);
+
+ dw = (int)w - (int)width;
+ dh = (int)h - (int)height;
+ ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh);
+
+ /* let the hardware adjust background and border pixmaps, if any */
+ (*pScreen->PositionWindow)(pWin, x, y);
+
+ pFirstChange = MoveWindowInStack(pWin, pSib);
+
+ if (WasViewable)
+ {
+ pRegion = REGION_CREATE(pScreen, NullBox, 1);
+ if (pWin->backStorage)
+ REGION_COPY(pScreen, pRegion, &pWin->clipList);
+
+ if (pLayerWin == pWin)
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
+ (WindowPtr *)NULL);
+ else
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
+ (WindowPtr *)NULL);
+
+ if (pWin->valdata)
+ {
+ pWin->valdata->before.resized = TRUE;
+ pWin->valdata->before.borderVisible = borderVisible;
+ }
+
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pFirstChange);
+ }
+#endif /* DO_SAVE_UNDERS */
+
+ if (anyMarked)
+ (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, VTOther);
+ /*
+ * the entire window is trashed unless bitGravity
+ * recovers portions of it
+ */
+ REGION_COPY(pScreen, &pWin->valdata->after.exposed, &pWin->clipList);
+ }
+
+ GravityTranslate (x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny);
+
+ if (pWin->backStorage &&
+ ((pWin->backingStore == Always) || WasViewable))
+ {
+ if (!WasViewable)
+ pRegion = &pWin->clipList; /* a convenient empty region */
+ if (pWin->bitGravity == ForgetGravity)
+ bsExposed = (*pScreen->TranslateBackingStore)
+ (pWin, 0, 0, NullRegion, oldx, oldy);
+ else
+ {
+ bsExposed = (*pScreen->TranslateBackingStore)
+ (pWin, nx - x, ny - y, pRegion, oldx, oldy);
+ }
+ }
+
+ if (WasViewable)
+ {
+ /* avoid the border */
+ if (HasBorder (pWin))
+ {
+ int offx, offy, dx, dy;
+
+ /* kruft to avoid double translates for each gravity */
+ offx = 0;
+ offy = 0;
+ for (g = 0; g <= StaticGravity; g++)
+ {
+ if (!gravitate[g])
+ continue;
+
+ /* align winSize to gravitate[g].
+ * winSize is in new coordinates,
+ * gravitate[g] is still in old coordinates */
+ GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
+
+ dx = (oldx - nx) - offx;
+ dy = (oldy - ny) - offy;
+ if (dx || dy)
+ {
+ REGION_TRANSLATE(pScreen, &pWin->winSize, dx, dy);
+ offx += dx;
+ offy += dy;
+ }
+ REGION_INTERSECT(pScreen, gravitate[g], gravitate[g],
+ &pWin->winSize);
+ }
+ /* get winSize back where it belongs */
+ if (offx || offy)
+ REGION_TRANSLATE(pScreen, &pWin->winSize, -offx, -offy);
+ }
+ /*
+ * add screen bits to the appropriate bucket
+ */
+
+ if (oldWinClip)
+ {
+ /*
+ * clip to new clipList
+ */
+ REGION_COPY(pScreen, pRegion, oldWinClip);
+ REGION_TRANSLATE(pScreen, pRegion, nx - oldx, ny - oldy);
+ REGION_INTERSECT(pScreen, oldWinClip, pRegion, &pWin->clipList);
+ /*
+ * don't step on any gravity bits which will be copied after this
+ * region. Note -- this assumes that the regions will be copied
+ * in gravity order.
+ */
+ for (g = pWin->bitGravity + 1; g <= StaticGravity; g++)
+ {
+ if (gravitate[g])
+ REGION_SUBTRACT(pScreen, oldWinClip, oldWinClip,
+ gravitate[g]);
+ }
+ REGION_TRANSLATE(pScreen, oldWinClip, oldx - nx, oldy - ny);
+ g = pWin->bitGravity;
+ if (!gravitate[g])
+ gravitate[g] = oldWinClip;
+ else
+ {
+ REGION_UNION(pScreen, gravitate[g], gravitate[g], oldWinClip);
+ REGION_DESTROY(pScreen, oldWinClip);
+ }
+ }
+
+ /*
+ * move the bits on the screen
+ */
+
+ destClip = NULL;
+
+ for (g = 0; g <= StaticGravity; g++)
+ {
+ if (!gravitate[g])
+ continue;
+
+ GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
+
+ oldpt.x = oldx + (x - nx);
+ oldpt.y = oldy + (y - ny);
+
+ /* Note that gravitate[g] is *translated* by CopyWindow */
+
+ /* only copy the remaining useful bits */
+
+ REGION_INTERSECT(pScreen, gravitate[g], gravitate[g], oldRegion);
+
+ /* clip to not overwrite already copied areas */
+
+ if (destClip) {
+ REGION_TRANSLATE(pScreen, destClip, oldpt.x - x, oldpt.y - y);
+ REGION_SUBTRACT(pScreen, gravitate[g], gravitate[g], destClip);
+ REGION_TRANSLATE(pScreen, destClip, x - oldpt.x, y - oldpt.y);
+ }
+
+ /* and move those bits */
+
+ if (oldpt.x != x || oldpt.y != y
+#ifdef COMPOSITE
+ || pWin->redirectDraw
+#endif
+ )
+ {
+ (*pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, gravitate[g]);
+ }
+
+ /* remove any overwritten bits from the remaining useful bits */
+
+ REGION_SUBTRACT(pScreen, oldRegion, oldRegion, gravitate[g]);
+
+ /*
+ * recompute exposed regions of child windows
+ */
+
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+ {
+ if (pChild->winGravity != g)
+ continue;
+ REGION_INTERSECT(pScreen, pRegion,
+ &pChild->borderClip, gravitate[g]);
+ TraverseTree (pChild, miRecomputeExposures, (pointer)pRegion);
+ }
+
+ /*
+ * remove the successfully copied regions of the
+ * window from its exposed region
+ */
+
+ if (g == pWin->bitGravity)
+ REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed,
+ &pWin->valdata->after.exposed, gravitate[g]);
+ if (!destClip)
+ destClip = gravitate[g];
+ else
+ {
+ REGION_UNION(pScreen, destClip, destClip, gravitate[g]);
+ REGION_DESTROY(pScreen, gravitate[g]);
+ }
+ }
+
+ REGION_DESTROY(pScreen, oldRegion);
+ REGION_DESTROY(pScreen, pRegion);
+ if (destClip)
+ REGION_DESTROY(pScreen, destClip);
+ if (bsExposed)
+ {
+ RegionPtr valExposed = NullRegion;
+
+ if (pWin->valdata)
+ valExposed = &pWin->valdata->after.exposed;
+ (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+ if (valExposed)
+ REGION_EMPTY(pScreen, valExposed);
+ REGION_DESTROY(pScreen, bsExposed);
+ }
+ if (anyMarked)
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ {
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pFirstChange);
+ }
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange,
+ VTOther);
+ }
+ else if (bsExposed)
+ {
+ (*pScreen->WindowExposures) (pWin, NullRegion, bsExposed);
+ REGION_DESTROY(pScreen, bsExposed);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+}
+
+WindowPtr
+miGetLayerWindow(pWin)
+ WindowPtr pWin;
+{
+ return pWin->firstChild;
+}
+
+#ifdef SHAPE
+/******
+ *
+ * miSetShape
+ * The border/window shape has changed. Recompute winSize/borderSize
+ * and send appropriate exposure events
+ */
+
+void
+miSetShape(pWin)
+ register WindowPtr pWin;
+{
+ Bool WasViewable = (Bool)(pWin->viewable);
+ register ScreenPtr pScreen = pWin->drawable.pScreen;
+ Bool anyMarked = FALSE;
+ RegionPtr pOldClip = NULL, bsExposed;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ if (WasViewable)
+ {
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ &pLayerWin);
+ if (pWin->valdata)
+ {
+ if (HasBorder (pWin))
+ {
+ RegionPtr borderVisible;
+
+ borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_SUBTRACT(pScreen, borderVisible,
+ &pWin->borderClip, &pWin->winSize);
+ pWin->valdata->before.borderVisible = borderVisible;
+ }
+ pWin->valdata->before.resized = TRUE;
+ }
+ }
+
+ SetWinSize (pWin);
+ SetBorderSize (pWin);
+
+ ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
+
+ if (WasViewable)
+ {
+ if (pWin->backStorage)
+ {
+ pOldClip = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_COPY(pScreen, pOldClip, &pWin->clipList);
+ }
+
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ (WindowPtr *)NULL);
+
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin);
+ }
+#endif /* DO_SAVE_UNDERS */
+
+ if (anyMarked)
+ (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, VTOther);
+ }
+
+ if (pWin->backStorage &&
+ ((pWin->backingStore == Always) || WasViewable))
+ {
+ if (!WasViewable)
+ pOldClip = &pWin->clipList; /* a convenient empty region */
+ bsExposed = (*pScreen->TranslateBackingStore)
+ (pWin, 0, 0, pOldClip,
+ pWin->drawable.x, pWin->drawable.y);
+#ifdef NXAGENT_SERVER
+
+ /*
+ * We got a few, rare, segfaults here after having
+ * started using the backing store. It may be a
+ * different bug but miChangeSaveUnder() calls mi-
+ * CheckSubSaveUnder() that, in turn, can change
+ * the backing store attribute of the window. This
+ * means that we may try to destroy the region
+ * even if it was not created at the beginning of
+ * this function as, at the time, the backing store
+ * was off. miCheckSubSaveUnder() appear to get a
+ * pointer to the parent, so maybe doesn't change
+ * the attribute of the window itself. This is to
+ * be better investigated.
+ */
+
+ if (WasViewable && pOldClip)
+ REGION_DESTROY(pScreen, pOldClip);
+#else
+ if (WasViewable)
+ REGION_DESTROY(pScreen, pOldClip);
+#endif
+ if (bsExposed)
+ {
+ RegionPtr valExposed = NullRegion;
+
+ if (pWin->valdata)
+ valExposed = &pWin->valdata->after.exposed;
+ (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+ if (valExposed)
+ REGION_EMPTY(pScreen, valExposed);
+ REGION_DESTROY(pScreen, bsExposed);
+ }
+ }
+ if (WasViewable)
+ {
+ if (anyMarked)
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, VTOther);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+ CheckCursorConfinement(pWin);
+}
+#endif
+
+/* Keeps the same inside(!) origin */
+
+void
+miChangeBorderWidth(pWin, width)
+ register WindowPtr pWin;
+ unsigned int width;
+{
+ int oldwidth;
+ Bool anyMarked = FALSE;
+ register ScreenPtr pScreen;
+ Bool WasViewable = (Bool)(pWin->viewable);
+ Bool HadBorder;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ oldwidth = wBorderWidth (pWin);
+ if (oldwidth == width)
+ return;
+ HadBorder = HasBorder(pWin);
+ pScreen = pWin->drawable.pScreen;
+ if (WasViewable && width < oldwidth)
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
+
+ pWin->borderWidth = width;
+ SetBorderSize (pWin);
+
+ if (WasViewable)
+ {
+ if (width > oldwidth)
+ {
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ &pLayerWin);
+ /*
+ * save the old border visible region to correctly compute
+ * borderExposed.
+ */
+ if (pWin->valdata && HadBorder)
+ {
+ RegionPtr borderVisible;
+ borderVisible = REGION_CREATE(pScreen, NULL, 1);
+ REGION_SUBTRACT(pScreen, borderVisible,
+ &pWin->borderClip, &pWin->winSize);
+ pWin->valdata->before.borderVisible = borderVisible;
+ }
+ }
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib);
+ }
+#endif /* DO_SAVE_UNDERS */
+
+ if (anyMarked)
+ {
+ (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTOther);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin,
+ VTOther);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+}
+
+void
+miMarkUnrealizedWindow(pChild, pWin, fromConfigure)
+ WindowPtr pChild;
+ WindowPtr pWin;
+ Bool fromConfigure;
+{
+ if ((pChild != pWin) || fromConfigure)
+ {
+ REGION_EMPTY(pChild->drawable.pScreen, &pChild->clipList);
+ if (pChild->drawable.pScreen->ClipNotify)
+ (* pChild->drawable.pScreen->ClipNotify)(pChild, 0, 0);
+ REGION_EMPTY(pChild->drawable.pScreen, &pChild->borderClip);
+ }
+}
+
+void
+miSegregateChildren(WindowPtr pWin, RegionPtr pReg, int depth)
+{
+ ScreenPtr pScreen;
+ WindowPtr pChild;
+
+ pScreen = pWin->drawable.pScreen;
+
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+ {
+ if (pChild->drawable.depth == depth)
+ REGION_UNION(pScreen, pReg, pReg, &pChild->borderClip);
+
+ if (pChild->firstChild)
+ miSegregateChildren(pChild, pReg, depth);
+ }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.X.original
new file mode 100644
index 000000000..280d0f8eb
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.X.original
@@ -0,0 +1,1184 @@
+/* $XFree86: xc/programs/Xserver/mi/miwindow.c,v 1.9tsi Exp $ */
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+/* $Xorg: miwindow.c,v 1.4 2001/02/09 02:05:22 xorgcvs Exp $ */
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "regionstr.h"
+#include "region.h"
+#include "mi.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "mivalidate.h"
+
+void
+miClearToBackground(pWin, x, y, w, h, generateExposures)
+ WindowPtr pWin;
+ int x,y;
+ int w,h;
+ Bool generateExposures;
+{
+ BoxRec box;
+ RegionRec reg;
+ RegionPtr pBSReg = NullRegion;
+ ScreenPtr pScreen;
+ BoxPtr extents;
+ int x1, y1, x2, y2;
+
+ /* compute everything using ints to avoid overflow */
+
+ x1 = pWin->drawable.x + x;
+ y1 = pWin->drawable.y + y;
+ if (w)
+ x2 = x1 + (int) w;
+ else
+ x2 = x1 + (int) pWin->drawable.width - (int) x;
+ if (h)
+ y2 = y1 + h;
+ else
+ y2 = y1 + (int) pWin->drawable.height - (int) y;
+
+ extents = &pWin->clipList.extents;
+
+ /* clip the resulting rectangle to the window clipList extents. This
+ * makes sure that the result will fit in a box, given that the
+ * screen is < 32768 on a side.
+ */
+
+ if (x1 < extents->x1)
+ x1 = extents->x1;
+ if (x2 > extents->x2)
+ x2 = extents->x2;
+ if (y1 < extents->y1)
+ y1 = extents->y1;
+ if (y2 > extents->y2)
+ y2 = extents->y2;
+
+ if (x2 <= x1 || y2 <= y1)
+ {
+ x2 = x1 = 0;
+ y2 = y1 = 0;
+ }
+
+ box.x1 = x1;
+ box.x2 = x2;
+ box.y1 = y1;
+ box.y2 = y2;
+
+ pScreen = pWin->drawable.pScreen;
+ REGION_INIT(pScreen, &reg, &box, 1);
+ if (pWin->backStorage)
+ {
+ /*
+ * If the window has backing-store on, call through the
+ * ClearToBackground vector to handle the special semantics
+ * (i.e. things backing store is to be cleared out and
+ * an Expose event is to be generated for those areas in backing
+ * store if generateExposures is TRUE).
+ */
+ pBSReg = (* pScreen->ClearBackingStore)(pWin, x, y, w, h,
+ generateExposures);
+ }
+
+ REGION_INTERSECT(pScreen, &reg, &reg, &pWin->clipList);
+ if (generateExposures)
+ (*pScreen->WindowExposures)(pWin, &reg, pBSReg);
+ else if (pWin->backgroundState != None)
+ (*pScreen->PaintWindowBackground)(pWin, &reg, PW_BACKGROUND);
+ REGION_UNINIT(pScreen, &reg);
+ if (pBSReg)
+ REGION_DESTROY(pScreen, pBSReg);
+}
+
+/*
+ * For SaveUnders using backing-store. The idea is that when a window is mapped
+ * with saveUnder set TRUE, any windows it obscures will have its backing
+ * store turned on setting the DIXsaveUnder bit,
+ * The backing-store code must be written to allow for this
+ */
+
+/*-
+ *-----------------------------------------------------------------------
+ * miCheckSubSaveUnder --
+ * Check all the inferiors of a window for coverage by saveUnder
+ * windows. Called from ChangeSaveUnder and CheckSaveUnder.
+ * This code is very inefficient.
+ *
+ * Results:
+ * TRUE if any windows need to have backing-store removed.
+ *
+ * Side Effects:
+ * Windows may have backing-store turned on or off.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Bool
+miCheckSubSaveUnder(
+ register WindowPtr pParent, /* Parent to check */
+ WindowPtr pFirst, /* first reconfigured window */
+ RegionPtr pRegion) /* Initial area obscured by saveUnder */
+{
+ register WindowPtr pChild; /* Current child */
+ register ScreenPtr pScreen; /* Screen to use */
+ RegionRec SubRegion; /* Area of children obscured */
+ Bool res = FALSE; /* result */
+ Bool subInited=FALSE;/* SubRegion initialized */
+
+ pScreen = pParent->drawable.pScreen;
+ if ( (pChild = pParent->firstChild) )
+ {
+ /*
+ * build region above first changed window
+ */
+
+ for (; pChild != pFirst; pChild = pChild->nextSib)
+ if (pChild->viewable && pChild->saveUnder)
+ REGION_UNION(pScreen, pRegion, pRegion, &pChild->borderSize);
+
+ /*
+ * check region below and including first changed window
+ */
+
+ for (; pChild; pChild = pChild->nextSib)
+ {
+ if (pChild->viewable)
+ {
+ /*
+ * don't save under nephew/niece windows;
+ * use a separate region
+ */
+
+ if (pChild->firstChild)
+ {
+ if (!subInited)
+ {
+ REGION_NULL(pScreen, &SubRegion);
+ subInited = TRUE;
+ }
+ REGION_COPY(pScreen, &SubRegion, pRegion);
+ res |= miCheckSubSaveUnder(pChild, pChild->firstChild,
+ &SubRegion);
+ }
+ else
+ {
+ res |= miCheckSubSaveUnder(pChild, pChild->firstChild,
+ pRegion);
+ }
+
+ if (pChild->saveUnder)
+ REGION_UNION(pScreen, pRegion, pRegion, &pChild->borderSize);
+ }
+ }
+
+ if (subInited)
+ REGION_UNINIT(pScreen, &SubRegion);
+ }
+
+ /*
+ * Check the state of this window. DIX save unders are
+ * enabled for viewable windows with some client expressing
+ * exposure interest and which intersect the save under region
+ */
+
+ if (pParent->viewable &&
+ ((pParent->eventMask | wOtherEventMasks(pParent)) & ExposureMask) &&
+ REGION_NOTEMPTY(pScreen, &pParent->borderSize) &&
+ RECT_IN_REGION(pScreen, pRegion, REGION_EXTENTS(pScreen,
+ &pParent->borderSize)) != rgnOUT)
+ {
+ if (!pParent->DIXsaveUnder)
+ {
+ pParent->DIXsaveUnder = TRUE;
+ (*pScreen->ChangeWindowAttributes) (pParent, CWBackingStore);
+ }
+ }
+ else
+ {
+ if (pParent->DIXsaveUnder)
+ {
+ res = TRUE;
+ pParent->DIXsaveUnder = FALSE;
+ }
+ }
+ return res;
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * miChangeSaveUnder --
+ * Change the save-under state of a tree of windows. Called when
+ * a window with saveUnder TRUE is mapped/unmapped/reconfigured.
+ *
+ * Results:
+ * TRUE if any windows need to have backing-store removed (which
+ * means that PostChangeSaveUnder needs to be called later to
+ * finish the job).
+ *
+ * Side Effects:
+ * Windows may have backing-store turned on or off.
+ *
+ *-----------------------------------------------------------------------
+ */
+Bool
+miChangeSaveUnder(pWin, first)
+ register WindowPtr pWin;
+ WindowPtr first; /* First window to check.
+ * Used when pWin was restacked */
+{
+ RegionRec rgn; /* Area obscured by saveUnder windows */
+ register ScreenPtr pScreen;
+ Bool res;
+
+ if (!deltaSaveUndersViewable && !numSaveUndersViewable)
+ return FALSE;
+ numSaveUndersViewable += deltaSaveUndersViewable;
+ deltaSaveUndersViewable = 0;
+ pScreen = pWin->drawable.pScreen;
+ REGION_NULL(pScreen, &rgn);
+ res = miCheckSubSaveUnder (pWin->parent,
+ pWin->saveUnder ? first : pWin->nextSib,
+ &rgn);
+ REGION_UNINIT(pScreen, &rgn);
+ return res;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miPostChangeSaveUnder --
+ * Actually turn backing-store off for those windows that no longer
+ * need to have it on.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Backing-store and SAVE_UNDER_CHANGE_BIT are turned off for those
+ * windows affected.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+miPostChangeSaveUnder(pWin, pFirst)
+ WindowPtr pWin;
+ WindowPtr pFirst;
+{
+ register WindowPtr pParent, pChild;
+ ChangeWindowAttributesProcPtr ChangeWindowAttributes;
+
+ if (!(pParent = pWin->parent))
+ return;
+ ChangeWindowAttributes = pParent->drawable.pScreen->ChangeWindowAttributes;
+ if (!pParent->DIXsaveUnder &&
+ (pParent->backingStore == NotUseful) && pParent->backStorage)
+ (*ChangeWindowAttributes)(pParent, CWBackingStore);
+ if (!(pChild = pFirst))
+ return;
+ while (1)
+ {
+ if (!pChild->DIXsaveUnder &&
+ (pChild->backingStore == NotUseful) && pChild->backStorage)
+ (*ChangeWindowAttributes)(pChild, CWBackingStore);
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ while (!pChild->nextSib)
+ {
+ pChild = pChild->parent;
+ if (pChild == pParent)
+ return;
+ }
+ pChild = pChild->nextSib;
+ }
+}
+
+void
+miMarkWindow(pWin)
+ register WindowPtr pWin;
+{
+ register ValidatePtr val;
+
+ if (pWin->valdata)
+ return;
+ val = (ValidatePtr)xnfalloc(sizeof(ValidateRec));
+ val->before.oldAbsCorner.x = pWin->drawable.x;
+ val->before.oldAbsCorner.y = pWin->drawable.y;
+ val->before.borderVisible = NullRegion;
+ val->before.resized = FALSE;
+ pWin->valdata = val;
+}
+
+Bool
+miMarkOverlappedWindows(pWin, pFirst, ppLayerWin)
+ WindowPtr pWin;
+ WindowPtr pFirst;
+ WindowPtr *ppLayerWin;
+{
+ register BoxPtr box;
+ register WindowPtr pChild, pLast;
+ Bool anyMarked = FALSE;
+ MarkWindowProcPtr MarkWindow = pWin->drawable.pScreen->MarkWindow;
+ ScreenPtr pScreen;
+
+ pScreen = pWin->drawable.pScreen;
+
+ /* single layered systems are easy */
+ if (ppLayerWin) *ppLayerWin = pWin;
+
+ if (pWin == pFirst)
+ {
+ /* Blindly mark pWin and all of its inferiors. This is a slight
+ * overkill if there are mapped windows that outside pWin's border,
+ * but it's better than wasting time on RectIn checks.
+ */
+ pChild = pWin;
+ while (1)
+ {
+ if (pChild->viewable)
+ {
+ if (REGION_BROKEN (pScreen, &pChild->winSize))
+ SetWinSize (pChild);
+ if (REGION_BROKEN (pScreen, &pChild->borderSize))
+ SetBorderSize (pChild);
+ (* MarkWindow)(pChild);
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ break;
+ pChild = pChild->nextSib;
+ }
+ anyMarked = TRUE;
+ pFirst = pFirst->nextSib;
+ }
+ if ( (pChild = pFirst) )
+ {
+ box = REGION_EXTENTS(pChild->drawable.pScreen, &pWin->borderSize);
+ pLast = pChild->parent->lastChild;
+ while (1)
+ {
+ if (pChild->viewable)
+ {
+ if (REGION_BROKEN (pScreen, &pChild->winSize))
+ SetWinSize (pChild);
+ if (REGION_BROKEN (pScreen, &pChild->borderSize))
+ SetBorderSize (pChild);
+ if (RECT_IN_REGION(pScreen, &pChild->borderSize, box))
+ {
+ (* MarkWindow)(pChild);
+ anyMarked = TRUE;
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ }
+ while (!pChild->nextSib && (pChild != pLast))
+ pChild = pChild->parent;
+ if (pChild == pLast)
+ break;
+ pChild = pChild->nextSib;
+ }
+ }
+ if (anyMarked)
+ (* MarkWindow)(pWin->parent);
+ return anyMarked;
+}
+
+/*****
+ * miHandleValidateExposures(pWin)
+ * starting at pWin, draw background in any windows that have exposure
+ * regions, translate the regions, restore any backing store,
+ * and then send any regions still exposed to the client
+ *****/
+void
+miHandleValidateExposures(pWin)
+ WindowPtr pWin;
+{
+ register WindowPtr pChild;
+ register ValidatePtr val;
+ ScreenPtr pScreen;
+ WindowExposuresProcPtr WindowExposures;
+
+ pScreen = pWin->drawable.pScreen;
+
+ pChild = pWin;
+ WindowExposures = pChild->drawable.pScreen->WindowExposures;
+ while (1)
+ {
+ if ( (val = pChild->valdata) )
+ {
+ if (REGION_NOTEMPTY(pScreen, &val->after.borderExposed))
+ (*pChild->drawable.pScreen->PaintWindowBorder)(pChild,
+ &val->after.borderExposed,
+ PW_BORDER);
+ REGION_UNINIT(pScreen, &val->after.borderExposed);
+ (*WindowExposures)(pChild, &val->after.exposed, NullRegion);
+ REGION_UNINIT(pScreen, &val->after.exposed);
+ xfree(val);
+ pChild->valdata = (ValidatePtr)NULL;
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ break;
+ pChild = pChild->nextSib;
+ }
+}
+
+void
+miMoveWindow(pWin, x, y, pNextSib, kind)
+ register WindowPtr pWin;
+ int x,y;
+ WindowPtr pNextSib;
+ VTKind kind;
+{
+ WindowPtr pParent;
+ Bool WasViewable = (Bool)(pWin->viewable);
+ short bw;
+ RegionPtr oldRegion = NULL;
+ DDXPointRec oldpt;
+ Bool anyMarked = FALSE;
+ register ScreenPtr pScreen;
+ WindowPtr windowToValidate;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ /* if this is a root window, can't be moved */
+ if (!(pParent = pWin->parent))
+ return ;
+ pScreen = pWin->drawable.pScreen;
+ bw = wBorderWidth (pWin);
+
+ oldpt.x = pWin->drawable.x;
+ oldpt.y = pWin->drawable.y;
+ if (WasViewable)
+ {
+ oldRegion = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_COPY(pScreen, oldRegion, &pWin->borderClip);
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
+ }
+ pWin->origin.x = x + (int)bw;
+ pWin->origin.y = y + (int)bw;
+ x = pWin->drawable.x = pParent->drawable.x + x + (int)bw;
+ y = pWin->drawable.y = pParent->drawable.y + y + (int)bw;
+
+ SetWinSize (pWin);
+ SetBorderSize (pWin);
+
+ (*pScreen->PositionWindow)(pWin, x, y);
+
+ windowToValidate = MoveWindowInStack(pWin, pNextSib);
+
+ ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0);
+
+ if (WasViewable)
+ {
+ if (pLayerWin == pWin)
+ anyMarked |= (*pScreen->MarkOverlappedWindows)
+ (pWin, windowToValidate, (WindowPtr *)NULL);
+ else
+ anyMarked |= (*pScreen->MarkOverlappedWindows)
+ (pWin, pLayerWin, (WindowPtr *)NULL);
+
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, windowToValidate);
+ }
+#endif /* DO_SAVE_UNDERS */
+
+ if (anyMarked)
+ {
+ (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, kind);
+ (* pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, oldRegion);
+ REGION_DESTROY(pScreen, oldRegion);
+ /* XXX need to retile border if ParentRelative origin */
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, windowToValidate);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, kind);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+}
+
+
+/*
+ * pValid is a region of the screen which has been
+ * successfully copied -- recomputed exposed regions for affected windows
+ */
+
+static int
+miRecomputeExposures (
+ register WindowPtr pWin,
+ pointer value) /* must conform to VisitWindowProcPtr */
+{
+ register ScreenPtr pScreen;
+ RegionPtr pValid = (RegionPtr)value;
+
+ if (pWin->valdata)
+ {
+ pScreen = pWin->drawable.pScreen;
+ /*
+ * compute exposed regions of this window
+ */
+ REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed,
+ &pWin->clipList, pValid);
+ /*
+ * compute exposed regions of the border
+ */
+ REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed,
+ &pWin->borderClip, &pWin->winSize);
+ REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed,
+ &pWin->valdata->after.borderExposed, pValid);
+ return WT_WALKCHILDREN;
+ }
+ return WT_NOMATCH;
+}
+
+void
+miSlideAndSizeWindow(pWin, x, y, w, h, pSib)
+ register WindowPtr pWin;
+ int x,y;
+ unsigned int w, h;
+ WindowPtr pSib;
+{
+ WindowPtr pParent;
+ Bool WasViewable = (Bool)(pWin->viewable);
+ unsigned short width = pWin->drawable.width,
+ height = pWin->drawable.height;
+ short oldx = pWin->drawable.x,
+ oldy = pWin->drawable.y;
+ int bw = wBorderWidth (pWin);
+ short dw, dh;
+ DDXPointRec oldpt;
+ RegionPtr oldRegion = NULL;
+ Bool anyMarked = FALSE;
+ register ScreenPtr pScreen;
+ WindowPtr pFirstChange;
+ register WindowPtr pChild;
+ RegionPtr gravitate[StaticGravity + 1];
+ register unsigned g;
+ int nx, ny; /* destination x,y */
+ int newx, newy; /* new inner window position */
+ RegionPtr pRegion = NULL;
+ RegionPtr destClip; /* portions of destination already written */
+ RegionPtr oldWinClip = NULL; /* old clip list for window */
+ RegionPtr borderVisible = NullRegion; /* visible area of the border */
+ RegionPtr bsExposed = NullRegion; /* backing store exposures */
+ Bool shrunk = FALSE; /* shrunk in an inner dimension */
+ Bool moved = FALSE; /* window position changed */
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ /* if this is a root window, can't be resized */
+ if (!(pParent = pWin->parent))
+ return ;
+
+ pScreen = pWin->drawable.pScreen;
+ newx = pParent->drawable.x + x + bw;
+ newy = pParent->drawable.y + y + bw;
+ if (WasViewable)
+ {
+ anyMarked = FALSE;
+ /*
+ * save the visible region of the window
+ */
+ oldRegion = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_COPY(pScreen, oldRegion, &pWin->winSize);
+
+ /*
+ * categorize child windows into regions to be moved
+ */
+ for (g = 0; g <= StaticGravity; g++)
+ gravitate[g] = (RegionPtr) NULL;
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+ {
+ g = pChild->winGravity;
+ if (g != UnmapGravity)
+ {
+ if (!gravitate[g])
+ gravitate[g] = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_UNION(pScreen, gravitate[g],
+ gravitate[g], &pChild->borderClip);
+ }
+ else
+ {
+ UnmapWindow(pChild, TRUE);
+ anyMarked = TRUE;
+ }
+ }
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ &pLayerWin);
+
+ oldWinClip = NULL;
+ if (pWin->bitGravity != ForgetGravity)
+ {
+ oldWinClip = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_COPY(pScreen, oldWinClip, &pWin->clipList);
+ }
+ /*
+ * if the window is changing size, borderExposed
+ * can't be computed correctly without some help.
+ */
+ if (pWin->drawable.height > h || pWin->drawable.width > w)
+ shrunk = TRUE;
+
+ if (newx != oldx || newy != oldy)
+ moved = TRUE;
+
+ if ((pWin->drawable.height != h || pWin->drawable.width != w) &&
+ HasBorder (pWin))
+ {
+ borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+ /* for tiled borders, we punt and draw the whole thing */
+ if (pWin->borderIsPixel || !moved)
+ {
+ if (shrunk || moved)
+ REGION_SUBTRACT(pScreen, borderVisible,
+ &pWin->borderClip,
+ &pWin->winSize);
+ else
+ REGION_COPY(pScreen, borderVisible,
+ &pWin->borderClip);
+ }
+ }
+ }
+ pWin->origin.x = x + bw;
+ pWin->origin.y = y + bw;
+ pWin->drawable.height = h;
+ pWin->drawable.width = w;
+
+ x = pWin->drawable.x = newx;
+ y = pWin->drawable.y = newy;
+
+ SetWinSize (pWin);
+ SetBorderSize (pWin);
+
+ dw = (int)w - (int)width;
+ dh = (int)h - (int)height;
+ ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh);
+
+ /* let the hardware adjust background and border pixmaps, if any */
+ (*pScreen->PositionWindow)(pWin, x, y);
+
+ pFirstChange = MoveWindowInStack(pWin, pSib);
+
+ if (WasViewable)
+ {
+ pRegion = REGION_CREATE(pScreen, NullBox, 1);
+ if (pWin->backStorage)
+ REGION_COPY(pScreen, pRegion, &pWin->clipList);
+
+ if (pLayerWin == pWin)
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
+ (WindowPtr *)NULL);
+ else
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
+ (WindowPtr *)NULL);
+
+ if (pWin->valdata)
+ {
+ pWin->valdata->before.resized = TRUE;
+ pWin->valdata->before.borderVisible = borderVisible;
+ }
+
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pFirstChange);
+ }
+#endif /* DO_SAVE_UNDERS */
+
+ if (anyMarked)
+ (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, VTOther);
+ /*
+ * the entire window is trashed unless bitGravity
+ * recovers portions of it
+ */
+ REGION_COPY(pScreen, &pWin->valdata->after.exposed, &pWin->clipList);
+ }
+
+ GravityTranslate (x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny);
+
+ if (pWin->backStorage &&
+ ((pWin->backingStore == Always) || WasViewable))
+ {
+ if (!WasViewable)
+ pRegion = &pWin->clipList; /* a convenient empty region */
+ if (pWin->bitGravity == ForgetGravity)
+ bsExposed = (*pScreen->TranslateBackingStore)
+ (pWin, 0, 0, NullRegion, oldx, oldy);
+ else
+ {
+ bsExposed = (*pScreen->TranslateBackingStore)
+ (pWin, nx - x, ny - y, pRegion, oldx, oldy);
+ }
+ }
+
+ if (WasViewable)
+ {
+ /* avoid the border */
+ if (HasBorder (pWin))
+ {
+ int offx, offy, dx, dy;
+
+ /* kruft to avoid double translates for each gravity */
+ offx = 0;
+ offy = 0;
+ for (g = 0; g <= StaticGravity; g++)
+ {
+ if (!gravitate[g])
+ continue;
+
+ /* align winSize to gravitate[g].
+ * winSize is in new coordinates,
+ * gravitate[g] is still in old coordinates */
+ GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
+
+ dx = (oldx - nx) - offx;
+ dy = (oldy - ny) - offy;
+ if (dx || dy)
+ {
+ REGION_TRANSLATE(pScreen, &pWin->winSize, dx, dy);
+ offx += dx;
+ offy += dy;
+ }
+ REGION_INTERSECT(pScreen, gravitate[g], gravitate[g],
+ &pWin->winSize);
+ }
+ /* get winSize back where it belongs */
+ if (offx || offy)
+ REGION_TRANSLATE(pScreen, &pWin->winSize, -offx, -offy);
+ }
+ /*
+ * add screen bits to the appropriate bucket
+ */
+
+ if (oldWinClip)
+ {
+ /*
+ * clip to new clipList
+ */
+ REGION_COPY(pScreen, pRegion, oldWinClip);
+ REGION_TRANSLATE(pScreen, pRegion, nx - oldx, ny - oldy);
+ REGION_INTERSECT(pScreen, oldWinClip, pRegion, &pWin->clipList);
+ /*
+ * don't step on any gravity bits which will be copied after this
+ * region. Note -- this assumes that the regions will be copied
+ * in gravity order.
+ */
+ for (g = pWin->bitGravity + 1; g <= StaticGravity; g++)
+ {
+ if (gravitate[g])
+ REGION_SUBTRACT(pScreen, oldWinClip, oldWinClip,
+ gravitate[g]);
+ }
+ REGION_TRANSLATE(pScreen, oldWinClip, oldx - nx, oldy - ny);
+ g = pWin->bitGravity;
+ if (!gravitate[g])
+ gravitate[g] = oldWinClip;
+ else
+ {
+ REGION_UNION(pScreen, gravitate[g], gravitate[g], oldWinClip);
+ REGION_DESTROY(pScreen, oldWinClip);
+ }
+ }
+
+ /*
+ * move the bits on the screen
+ */
+
+ destClip = NULL;
+
+ for (g = 0; g <= StaticGravity; g++)
+ {
+ if (!gravitate[g])
+ continue;
+
+ GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
+
+ oldpt.x = oldx + (x - nx);
+ oldpt.y = oldy + (y - ny);
+
+ /* Note that gravitate[g] is *translated* by CopyWindow */
+
+ /* only copy the remaining useful bits */
+
+ REGION_INTERSECT(pScreen, gravitate[g], gravitate[g], oldRegion);
+
+ /* clip to not overwrite already copied areas */
+
+ if (destClip) {
+ REGION_TRANSLATE(pScreen, destClip, oldpt.x - x, oldpt.y - y);
+ REGION_SUBTRACT(pScreen, gravitate[g], gravitate[g], destClip);
+ REGION_TRANSLATE(pScreen, destClip, x - oldpt.x, y - oldpt.y);
+ }
+
+ /* and move those bits */
+
+ if (oldpt.x != x || oldpt.y != y
+#ifdef COMPOSITE
+ || pWin->redirectDraw
+#endif
+ )
+ {
+ (*pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, gravitate[g]);
+ }
+
+ /* remove any overwritten bits from the remaining useful bits */
+
+ REGION_SUBTRACT(pScreen, oldRegion, oldRegion, gravitate[g]);
+
+ /*
+ * recompute exposed regions of child windows
+ */
+
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+ {
+ if (pChild->winGravity != g)
+ continue;
+ REGION_INTERSECT(pScreen, pRegion,
+ &pChild->borderClip, gravitate[g]);
+ TraverseTree (pChild, miRecomputeExposures, (pointer)pRegion);
+ }
+
+ /*
+ * remove the successfully copied regions of the
+ * window from its exposed region
+ */
+
+ if (g == pWin->bitGravity)
+ REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed,
+ &pWin->valdata->after.exposed, gravitate[g]);
+ if (!destClip)
+ destClip = gravitate[g];
+ else
+ {
+ REGION_UNION(pScreen, destClip, destClip, gravitate[g]);
+ REGION_DESTROY(pScreen, gravitate[g]);
+ }
+ }
+
+ REGION_DESTROY(pScreen, oldRegion);
+ REGION_DESTROY(pScreen, pRegion);
+ if (destClip)
+ REGION_DESTROY(pScreen, destClip);
+ if (bsExposed)
+ {
+ RegionPtr valExposed = NullRegion;
+
+ if (pWin->valdata)
+ valExposed = &pWin->valdata->after.exposed;
+ (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+ if (valExposed)
+ REGION_EMPTY(pScreen, valExposed);
+ REGION_DESTROY(pScreen, bsExposed);
+ }
+ if (anyMarked)
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ {
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pFirstChange);
+ }
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange,
+ VTOther);
+ }
+ else if (bsExposed)
+ {
+ (*pScreen->WindowExposures) (pWin, NullRegion, bsExposed);
+ REGION_DESTROY(pScreen, bsExposed);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+}
+
+WindowPtr
+miGetLayerWindow(pWin)
+ WindowPtr pWin;
+{
+ return pWin->firstChild;
+}
+
+#ifdef SHAPE
+/******
+ *
+ * miSetShape
+ * The border/window shape has changed. Recompute winSize/borderSize
+ * and send appropriate exposure events
+ */
+
+void
+miSetShape(pWin)
+ register WindowPtr pWin;
+{
+ Bool WasViewable = (Bool)(pWin->viewable);
+ register ScreenPtr pScreen = pWin->drawable.pScreen;
+ Bool anyMarked = FALSE;
+ RegionPtr pOldClip = NULL, bsExposed;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ if (WasViewable)
+ {
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ &pLayerWin);
+ if (pWin->valdata)
+ {
+ if (HasBorder (pWin))
+ {
+ RegionPtr borderVisible;
+
+ borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_SUBTRACT(pScreen, borderVisible,
+ &pWin->borderClip, &pWin->winSize);
+ pWin->valdata->before.borderVisible = borderVisible;
+ }
+ pWin->valdata->before.resized = TRUE;
+ }
+ }
+
+ SetWinSize (pWin);
+ SetBorderSize (pWin);
+
+ ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
+
+ if (WasViewable)
+ {
+ if (pWin->backStorage)
+ {
+ pOldClip = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_COPY(pScreen, pOldClip, &pWin->clipList);
+ }
+
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ (WindowPtr *)NULL);
+
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin);
+ }
+#endif /* DO_SAVE_UNDERS */
+
+ if (anyMarked)
+ (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, VTOther);
+ }
+
+ if (pWin->backStorage &&
+ ((pWin->backingStore == Always) || WasViewable))
+ {
+ if (!WasViewable)
+ pOldClip = &pWin->clipList; /* a convenient empty region */
+ bsExposed = (*pScreen->TranslateBackingStore)
+ (pWin, 0, 0, pOldClip,
+ pWin->drawable.x, pWin->drawable.y);
+ if (WasViewable)
+ REGION_DESTROY(pScreen, pOldClip);
+ if (bsExposed)
+ {
+ RegionPtr valExposed = NullRegion;
+
+ if (pWin->valdata)
+ valExposed = &pWin->valdata->after.exposed;
+ (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+ if (valExposed)
+ REGION_EMPTY(pScreen, valExposed);
+ REGION_DESTROY(pScreen, bsExposed);
+ }
+ }
+ if (WasViewable)
+ {
+ if (anyMarked)
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, VTOther);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+ CheckCursorConfinement(pWin);
+}
+#endif
+
+/* Keeps the same inside(!) origin */
+
+void
+miChangeBorderWidth(pWin, width)
+ register WindowPtr pWin;
+ unsigned int width;
+{
+ int oldwidth;
+ Bool anyMarked = FALSE;
+ register ScreenPtr pScreen;
+ Bool WasViewable = (Bool)(pWin->viewable);
+ Bool HadBorder;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ oldwidth = wBorderWidth (pWin);
+ if (oldwidth == width)
+ return;
+ HadBorder = HasBorder(pWin);
+ pScreen = pWin->drawable.pScreen;
+ if (WasViewable && width < oldwidth)
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
+
+ pWin->borderWidth = width;
+ SetBorderSize (pWin);
+
+ if (WasViewable)
+ {
+ if (width > oldwidth)
+ {
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ &pLayerWin);
+ /*
+ * save the old border visible region to correctly compute
+ * borderExposed.
+ */
+ if (pWin->valdata && HadBorder)
+ {
+ RegionPtr borderVisible;
+ borderVisible = REGION_CREATE(pScreen, NULL, 1);
+ REGION_SUBTRACT(pScreen, borderVisible,
+ &pWin->borderClip, &pWin->winSize);
+ pWin->valdata->before.borderVisible = borderVisible;
+ }
+ }
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib);
+ }
+#endif /* DO_SAVE_UNDERS */
+
+ if (anyMarked)
+ {
+ (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTOther);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin,
+ VTOther);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+}
+
+void
+miMarkUnrealizedWindow(pChild, pWin, fromConfigure)
+ WindowPtr pChild;
+ WindowPtr pWin;
+ Bool fromConfigure;
+{
+ if ((pChild != pWin) || fromConfigure)
+ {
+ REGION_EMPTY(pChild->drawable.pScreen, &pChild->clipList);
+ if (pChild->drawable.pScreen->ClipNotify)
+ (* pChild->drawable.pScreen->ClipNotify)(pChild, 0, 0);
+ REGION_EMPTY(pChild->drawable.pScreen, &pChild->borderClip);
+ }
+}
+
+void
+miSegregateChildren(WindowPtr pWin, RegionPtr pReg, int depth)
+{
+ ScreenPtr pScreen;
+ WindowPtr pChild;
+
+ pScreen = pWin->drawable.pScreen;
+
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+ {
+ if (pChild->drawable.depth == depth)
+ REGION_UNION(pScreen, pReg, pReg, &pChild->borderClip);
+
+ if (pChild->firstChild)
+ miSegregateChildren(pChild, pReg, depth);
+ }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c
new file mode 100644
index 000000000..5d6f71475
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c
@@ -0,0 +1,2220 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/picture.c,v 1.29 2002/11/23 02:38:15 keithp Exp $
+ *
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+#include "NXpicturestr.h"
+
+#include "Screen.h"
+#include "Pixmaps.h"
+#include "Drawable.h"
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+void *nxagentVisualFromID(ScreenPtr pScreen, VisualID visual);
+
+void *nxagentMatchingFormats(PictFormatPtr pForm);
+
+int PictureScreenPrivateIndex = -1;
+int PictureWindowPrivateIndex;
+int PictureGeneration;
+RESTYPE PictureType;
+RESTYPE PictFormatType;
+RESTYPE GlyphSetType;
+int PictureCmapPolicy = PictureCmapPolicyDefault;
+
+typedef struct _formatInit {
+ CARD32 format;
+ CARD8 depth;
+} FormatInitRec, *FormatInitPtr;
+
+void nxagentPictureCreateDefaultFormats(ScreenPtr pScreen, FormatInitRec *formats, int *nformats);
+
+/* Picture Private machinery */
+
+static int picturePrivateCount;
+
+void
+ResetPicturePrivateIndex (void)
+{
+ picturePrivateCount = 0;
+}
+
+int
+AllocatePicturePrivateIndex (void)
+{
+ return picturePrivateCount++;
+}
+
+Bool
+AllocatePicturePrivate (ScreenPtr pScreen, int index2, unsigned int amount)
+{
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ unsigned int oldamount;
+
+ /* Round up sizes for proper alignment */
+ amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
+
+ if (index2 >= ps->PicturePrivateLen)
+ {
+ unsigned int *nsizes;
+
+ nsizes = (unsigned int *)xrealloc(ps->PicturePrivateSizes,
+ (index2 + 1) * sizeof(unsigned int));
+ if (!nsizes)
+ return FALSE;
+ while (ps->PicturePrivateLen <= index2)
+ {
+ nsizes[ps->PicturePrivateLen++] = 0;
+ ps->totalPictureSize += sizeof(DevUnion);
+ }
+ ps->PicturePrivateSizes = nsizes;
+ }
+ oldamount = ps->PicturePrivateSizes[index2];
+ if (amount > oldamount)
+ {
+ ps->PicturePrivateSizes[index2] = amount;
+ ps->totalPictureSize += (amount - oldamount);
+ }
+
+ return TRUE;
+}
+
+
+Bool
+PictureDestroyWindow (WindowPtr pWindow)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ PicturePtr pPicture;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ Bool ret;
+
+ while ((pPicture = GetPictureWindow(pWindow)))
+ {
+ SetPictureWindow(pWindow, pPicture->pNext);
+ if (pPicture->id)
+ FreeResource (pPicture->id, PictureType);
+ FreePicture ((pointer) pPicture, pPicture->id);
+ }
+ pScreen->DestroyWindow = ps->DestroyWindow;
+ ret = (*pScreen->DestroyWindow) (pWindow);
+ ps->DestroyWindow = pScreen->DestroyWindow;
+ pScreen->DestroyWindow = PictureDestroyWindow;
+ return ret;
+}
+
+Bool
+PictureCloseScreen (int index, ScreenPtr pScreen)
+{
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ Bool ret;
+ int n;
+
+ pScreen->CloseScreen = ps->CloseScreen;
+ ret = (*pScreen->CloseScreen) (index, pScreen);
+ PictureResetFilters (pScreen);
+ for (n = 0; n < ps->nformats; n++)
+ if (ps->formats[n].type == PictTypeIndexed)
+ (*ps->CloseIndexed) (pScreen, &ps->formats[n]);
+ SetPictureScreen(pScreen, 0);
+ if (ps->PicturePrivateSizes)
+ xfree (ps->PicturePrivateSizes);
+ xfree (ps->formats);
+ xfree (ps);
+ return ret;
+}
+
+void
+PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef)
+{
+ ScreenPtr pScreen = pColormap->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+
+ pScreen->StoreColors = ps->StoreColors;
+ (*pScreen->StoreColors) (pColormap, ndef, pdef);
+ ps->StoreColors = pScreen->StoreColors;
+ pScreen->StoreColors = PictureStoreColors;
+
+ if (pColormap->class == PseudoColor || pColormap->class == GrayScale)
+ {
+ PictFormatPtr format = ps->formats;
+ int nformats = ps->nformats;
+
+ while (nformats--)
+ {
+ if (format->type == PictTypeIndexed &&
+ format->index.pColormap == pColormap)
+ {
+ (*ps->UpdateIndexed) (pScreen, format, ndef, pdef);
+ break;
+ }
+ format++;
+ }
+ }
+}
+
+static int
+visualDepth (ScreenPtr pScreen, VisualPtr pVisual)
+{
+ int d, v;
+ DepthPtr pDepth;
+
+ for (d = 0; d < pScreen->numDepths; d++)
+ {
+ pDepth = &pScreen->allowedDepths[d];
+ for (v = 0; v < pDepth->numVids; v++)
+ if (pDepth->vids[v] == pVisual->vid)
+ return pDepth->depth;
+ }
+ return 0;
+}
+
+static int
+addFormat (FormatInitRec formats[256],
+ int nformat,
+ CARD32 format,
+ CARD8 depth)
+{
+ int n;
+
+ for (n = 0; n < nformat; n++)
+ if (formats[n].format == format && formats[n].depth == depth)
+ return nformat;
+ formats[nformat].format = format;
+ formats[nformat].depth = depth;
+
+ #ifdef DEBUG
+ fprintf(stderr, "addFormat: Added format [%lu] depth [%d].\n", format, depth);
+ #endif
+
+ return ++nformat;
+}
+
+#define Mask(n) ((n) == 32 ? 0xffffffff : ((1 << (n))-1))
+
+PictFormatPtr
+PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
+{
+ int nformats, f;
+ PictFormatPtr pFormats;
+ FormatInitRec formats[1024];
+ CARD32 format;
+
+#ifndef NXAGENT_SERVER
+
+ CARD8 depth;
+ VisualPtr pVisual;
+ int v;
+ int bpp;
+ int type;
+ int r, g, b;
+ int d;
+ DepthPtr pDepth;
+
+#endif
+
+ nformats = 0;
+
+#ifdef NXAGENT_SERVER
+
+ nxagentPictureCreateDefaultFormats(pScreen, formats, &nformats);
+
+#else
+
+ /* formats required by protocol */
+ formats[nformats].format = PICT_a1;
+ formats[nformats].depth = 1;
+ nformats++;
+ formats[nformats].format = PICT_a8;
+ formats[nformats].depth = 8;
+ nformats++;
+ formats[nformats].format = PICT_a4;
+ formats[nformats].depth = 4;
+ nformats++;
+ formats[nformats].format = PICT_a8r8g8b8;
+ formats[nformats].depth = 32;
+ nformats++;
+ formats[nformats].format = PICT_x8r8g8b8;
+ formats[nformats].depth = 32;
+ nformats++;
+
+ /* now look through the depths and visuals adding other formats */
+ for (v = 0; v < pScreen->numVisuals; v++)
+ {
+ pVisual = &pScreen->visuals[v];
+ depth = visualDepth (pScreen, pVisual);
+ if (!depth)
+ continue;
+ bpp = BitsPerPixel (depth);
+
+ switch (pVisual->class) {
+ case DirectColor:
+ case TrueColor:
+ r = Ones (pVisual->redMask);
+ g = Ones (pVisual->greenMask);
+ b = Ones (pVisual->blueMask);
+ type = PICT_TYPE_OTHER;
+ /*
+ * Current rendering code supports only two direct formats,
+ * fields must be packed together at the bottom of the pixel
+ * and must be either RGB or BGR
+ */
+ if (pVisual->offsetBlue == 0 &&
+ pVisual->offsetGreen == b &&
+ pVisual->offsetRed == b + g)
+ {
+ type = PICT_TYPE_ARGB;
+ }
+ else if (pVisual->offsetRed == 0 &&
+ pVisual->offsetGreen == r &&
+ pVisual->offsetBlue == r + g)
+ {
+ type = PICT_TYPE_ABGR;
+ }
+ if (type != PICT_TYPE_OTHER)
+ {
+ format = PICT_FORMAT(bpp, type, 0, r, g, b);
+ nformats = addFormat (formats, nformats, format, depth);
+ }
+ break;
+ case StaticColor:
+ case PseudoColor:
+ format = PICT_VISFORMAT (bpp, PICT_TYPE_COLOR, v);
+ nformats = addFormat (formats, nformats, format, depth);
+ break;
+ case StaticGray:
+ case GrayScale:
+ format = PICT_VISFORMAT (bpp, PICT_TYPE_GRAY, v);
+ nformats = addFormat (formats, nformats, format, depth);
+ break;
+ }
+ }
+
+ /*
+ * Walk supported depths and add useful Direct formats
+ */
+ for (d = 0; d < pScreen->numDepths; d++)
+ {
+ pDepth = &pScreen->allowedDepths[d];
+ bpp = BitsPerPixel (pDepth->depth);
+ format = 0;
+
+ switch (bpp) {
+ case 16:
+ /* depth 12 formats */
+ if (pDepth->depth >= 12)
+ {
+ nformats = addFormat (formats, nformats,
+ PICT_x4r4g4b4, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_x4b4g4r4, pDepth->depth);
+ }
+
+ /* depth 15 formats */
+ if (pDepth->depth >= 15)
+ {
+ nformats = addFormat (formats, nformats,
+ PICT_x1r5g5b5, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_x1b5g5r5, pDepth->depth);
+ }
+ /* depth 16 formats */
+ if (pDepth->depth >= 16)
+ {
+ nformats = addFormat (formats, nformats,
+ PICT_a1r5g5b5, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_a1b5g5r5, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_r5g6b5, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_b5g6r5, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_a4r4g4b4, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_a4b4g4r4, pDepth->depth);
+ }
+ break;
+ case 24:
+ if (pDepth->depth >= 24)
+ {
+ nformats = addFormat (formats, nformats,
+ PICT_r8g8b8, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_b8g8r8, pDepth->depth);
+ }
+ break;
+ case 32:
+ if (pDepth->depth >= 24)
+ {
+ nformats = addFormat (formats, nformats,
+ PICT_x8r8g8b8, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_x8b8g8r8, pDepth->depth);
+ }
+ break;
+ }
+ }
+
+#endif
+
+ pFormats = (PictFormatPtr) xalloc (nformats * sizeof (PictFormatRec));
+ if (!pFormats)
+ return 0;
+ memset (pFormats, '\0', nformats * sizeof (PictFormatRec));
+ for (f = 0; f < nformats; f++)
+ {
+ pFormats[f].id = FakeClientID (0);
+ pFormats[f].depth = formats[f].depth;
+ format = formats[f].format;
+ pFormats[f].format = format;
+ switch (PICT_FORMAT_TYPE(format)) {
+ case PICT_TYPE_ARGB:
+ pFormats[f].type = PictTypeDirect;
+
+ pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+ if (pFormats[f].direct.alphaMask)
+ pFormats[f].direct.alpha = (PICT_FORMAT_R(format) +
+ PICT_FORMAT_G(format) +
+ PICT_FORMAT_B(format));
+
+ pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
+ pFormats[f].direct.red = (PICT_FORMAT_G(format) +
+ PICT_FORMAT_B(format));
+
+ pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
+ pFormats[f].direct.green = PICT_FORMAT_B(format);
+
+ pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
+ pFormats[f].direct.blue = 0;
+ break;
+
+ case PICT_TYPE_ABGR:
+ pFormats[f].type = PictTypeDirect;
+
+ pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+ if (pFormats[f].direct.alphaMask)
+ pFormats[f].direct.alpha = (PICT_FORMAT_B(format) +
+ PICT_FORMAT_G(format) +
+ PICT_FORMAT_R(format));
+
+ pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
+ pFormats[f].direct.blue = (PICT_FORMAT_G(format) +
+ PICT_FORMAT_R(format));
+
+ pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
+ pFormats[f].direct.green = PICT_FORMAT_R(format);
+
+ pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
+ pFormats[f].direct.red = 0;
+ break;
+
+ case PICT_TYPE_A:
+ pFormats[f].type = PictTypeDirect;
+
+ pFormats[f].direct.alpha = 0;
+ pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+
+ /* remaining fields already set to zero */
+ break;
+
+ case PICT_TYPE_COLOR:
+ case PICT_TYPE_GRAY:
+ pFormats[f].type = PictTypeIndexed;
+ pFormats[f].index.vid = pScreen->visuals[PICT_FORMAT_VIS(format)].vid;
+ break;
+ }
+
+#ifdef NXAGENT_SERVER
+ if (nxagentMatchingFormats(&pFormats[f]) != NULL)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "PictureCreateDefaultFormats: Format with type [%d] depth [%d] rgb [%d,%d,%d] "
+ "mask rgb [%d,%d,%d] alpha [%d] alpha mask [%d] matches.\n",
+ pFormats[f].type, pFormats[f].depth, pFormats[f].direct.red, pFormats[f].direct.green,
+ pFormats[f].direct.blue, pFormats[f].direct.redMask, pFormats[f].direct.greenMask,
+ pFormats[f].direct.blueMask, pFormats[f].direct.alpha, pFormats[f].direct.alphaMask);
+ #endif
+ }
+ else
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "PictureCreateDefaultFormats: Format with type [%d] depth [%d] rgb [%d,%d,%d] "
+ "mask rgb [%d,%d,%d] alpha [%d] alpha mask [%d] doesn't match.\n",
+ pFormats[f].type, pFormats[f].depth, pFormats[f].direct.red, pFormats[f].direct.green,
+ pFormats[f].direct.blue, pFormats[f].direct.redMask, pFormats[f].direct.greenMask,
+ pFormats[f].direct.blueMask, pFormats[f].direct.alpha, pFormats[f].direct.alphaMask);
+ #endif
+ }
+#endif
+ }
+ *nformatp = nformats;
+ return pFormats;
+}
+
+static VisualPtr
+PictureFindVisual (ScreenPtr pScreen, VisualID visual)
+{
+ int i;
+ VisualPtr pVisual;
+ for (i = 0, pVisual = pScreen->visuals;
+ i < pScreen->numVisuals;
+ i++, pVisual++)
+ {
+ if (pVisual->vid == visual)
+ return pVisual;
+ }
+ return 0;
+}
+
+Bool
+PictureInitIndexedFormats (ScreenPtr pScreen)
+{
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+ PictFormatPtr format;
+ int nformat;
+
+ if (!ps)
+ return FALSE;
+ format = ps->formats;
+ nformat = ps->nformats;
+ while (nformat--)
+ {
+ if (format->type == PictTypeIndexed && !format->index.pColormap)
+ {
+ if (format->index.vid == pScreen->rootVisual)
+ format->index.pColormap = (ColormapPtr) LookupIDByType(pScreen->defColormap,
+ RT_COLORMAP);
+ else
+ {
+ VisualPtr pVisual;
+
+ pVisual = PictureFindVisual (pScreen, format->index.vid);
+ if (CreateColormap (FakeClientID (0), pScreen,
+ pVisual,
+ &format->index.pColormap, AllocNone,
+ 0) != Success)
+ {
+ return FALSE;
+ }
+ }
+ if (!(*ps->InitIndexed) (pScreen, format))
+ return FALSE;
+ }
+ format++;
+ }
+ return TRUE;
+}
+
+Bool
+PictureFinishInit (void)
+{
+ int s;
+
+ for (s = 0; s < screenInfo.numScreens; s++)
+ {
+ if (!PictureInitIndexedFormats (screenInfo.screens[s]))
+ return FALSE;
+ (void) AnimCurInit (screenInfo.screens[s]);
+ }
+
+ return TRUE;
+}
+
+Bool
+PictureSetSubpixelOrder (ScreenPtr pScreen, int subpixel)
+{
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+
+ if (!ps)
+ return FALSE;
+ ps->subpixel = subpixel;
+ return TRUE;
+
+}
+
+int
+PictureGetSubpixelOrder (ScreenPtr pScreen)
+{
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+
+ if (!ps)
+ return SubPixelUnknown;
+ return ps->subpixel;
+}
+
+PictFormatPtr
+PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual)
+{
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+ PictFormatPtr format;
+ int nformat;
+ int type;
+
+ if (!ps)
+ return 0;
+ format = ps->formats;
+ nformat = ps->nformats;
+ switch (pVisual->class) {
+ case StaticGray:
+ case GrayScale:
+ case StaticColor:
+ case PseudoColor:
+ type = PictTypeIndexed;
+ break;
+ case TrueColor:
+ case DirectColor:
+ type = PictTypeDirect;
+ break;
+ default:
+ return 0;
+ }
+ while (nformat--)
+ {
+ if (format->depth == depth && format->type == type)
+ {
+ if (type == PictTypeIndexed)
+ {
+ if (format->index.vid == pVisual->vid)
+ return format;
+ }
+ else
+ {
+ if (format->direct.redMask << format->direct.red ==
+ pVisual->redMask &&
+ format->direct.greenMask << format->direct.green ==
+ pVisual->greenMask &&
+ format->direct.blueMask << format->direct.blue ==
+ pVisual->blueMask)
+ {
+ return format;
+ }
+ }
+ }
+ format++;
+ }
+ return 0;
+}
+
+PictFormatPtr
+PictureMatchFormat (ScreenPtr pScreen, int depth, CARD32 f)
+{
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+ PictFormatPtr format;
+ int nformat;
+
+ if (!ps)
+ return 0;
+ format = ps->formats;
+ nformat = ps->nformats;
+ while (nformat--)
+ {
+ if (format->depth == depth && format->format == (f & 0xffffff))
+ return format;
+ format++;
+ }
+ return 0;
+}
+
+int
+PictureParseCmapPolicy (const char *name)
+{
+ if ( strcmp (name, "default" ) == 0)
+ return PictureCmapPolicyDefault;
+ else if ( strcmp (name, "mono" ) == 0)
+ return PictureCmapPolicyMono;
+ else if ( strcmp (name, "gray" ) == 0)
+ return PictureCmapPolicyGray;
+ else if ( strcmp (name, "color" ) == 0)
+ return PictureCmapPolicyColor;
+ else if ( strcmp (name, "all" ) == 0)
+ return PictureCmapPolicyAll;
+ else
+ return PictureCmapPolicyInvalid;
+}
+
+Bool
+PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
+{
+ PictureScreenPtr ps;
+ int n;
+ CARD32 type, a, r, g, b;
+
+ if (PictureGeneration != serverGeneration)
+ {
+ PictureType = CreateNewResourceType (FreePicture);
+ if (!PictureType)
+ return FALSE;
+ PictFormatType = CreateNewResourceType (FreePictFormat);
+ if (!PictFormatType)
+ return FALSE;
+ GlyphSetType = CreateNewResourceType (FreeGlyphSet);
+ if (!GlyphSetType)
+ return FALSE;
+ PictureScreenPrivateIndex = AllocateScreenPrivateIndex();
+ if (PictureScreenPrivateIndex < 0)
+ return FALSE;
+ PictureWindowPrivateIndex = AllocateWindowPrivateIndex();
+ PictureGeneration = serverGeneration;
+#ifdef XResExtension
+ RegisterResourceName (PictureType, "PICTURE");
+ RegisterResourceName (PictFormatType, "PICTFORMAT");
+ RegisterResourceName (GlyphSetType, "GLYPHSET");
+#endif
+ }
+ if (!AllocateWindowPrivate (pScreen, PictureWindowPrivateIndex, 0))
+ return FALSE;
+
+ if (!formats)
+ {
+ formats = PictureCreateDefaultFormats (pScreen, &nformats);
+ if (!formats)
+ return FALSE;
+ }
+ for (n = 0; n < nformats; n++)
+ {
+ if (!AddResource (formats[n].id, PictFormatType, (pointer) (formats+n)))
+ {
+ xfree (formats);
+ return FALSE;
+ }
+ if (formats[n].type == PictTypeIndexed)
+ {
+ VisualPtr pVisual = PictureFindVisual (pScreen, formats[n].index.vid);
+ if ((pVisual->class | DynamicClass) == PseudoColor)
+ type = PICT_TYPE_COLOR;
+ else
+ type = PICT_TYPE_GRAY;
+ a = r = g = b = 0;
+ }
+ else
+ {
+ if ((formats[n].direct.redMask|
+ formats[n].direct.blueMask|
+ formats[n].direct.greenMask) == 0)
+ type = PICT_TYPE_A;
+ else if (formats[n].direct.red > formats[n].direct.blue)
+ type = PICT_TYPE_ARGB;
+ else
+ type = PICT_TYPE_ABGR;
+ a = Ones (formats[n].direct.alphaMask);
+ r = Ones (formats[n].direct.redMask);
+ g = Ones (formats[n].direct.greenMask);
+ b = Ones (formats[n].direct.blueMask);
+ }
+ formats[n].format = PICT_FORMAT(0,type,a,r,g,b);
+ }
+ ps = (PictureScreenPtr) xalloc (sizeof (PictureScreenRec));
+ if (!ps)
+ {
+ xfree (formats);
+ return FALSE;
+ }
+ SetPictureScreen(pScreen, ps);
+ if (!GlyphInit (pScreen))
+ {
+ SetPictureScreen(pScreen, 0);
+ xfree (formats);
+ xfree (ps);
+ return FALSE;
+ }
+
+ ps->totalPictureSize = sizeof (PictureRec);
+ ps->PicturePrivateSizes = 0;
+ ps->PicturePrivateLen = 0;
+
+ ps->formats = formats;
+ ps->fallback = formats;
+ ps->nformats = nformats;
+
+ ps->filters = 0;
+ ps->nfilters = 0;
+ ps->filterAliases = 0;
+ ps->nfilterAliases = 0;
+
+ ps->subpixel = SubPixelUnknown;
+
+ ps->CloseScreen = pScreen->CloseScreen;
+ ps->DestroyWindow = pScreen->DestroyWindow;
+ ps->StoreColors = pScreen->StoreColors;
+ pScreen->DestroyWindow = PictureDestroyWindow;
+ pScreen->CloseScreen = PictureCloseScreen;
+ pScreen->StoreColors = PictureStoreColors;
+
+ if (!PictureSetDefaultFilters (pScreen))
+ {
+ PictureResetFilters (pScreen);
+ SetPictureScreen(pScreen, 0);
+ xfree (formats);
+ xfree (ps);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void
+SetPictureToDefaults (PicturePtr pPicture)
+{
+ pPicture->refcnt = 1;
+ pPicture->repeat = 0;
+ pPicture->graphicsExposures = FALSE;
+ pPicture->subWindowMode = ClipByChildren;
+ pPicture->polyEdge = PolyEdgeSharp;
+ pPicture->polyMode = PolyModePrecise;
+ pPicture->freeCompClip = FALSE;
+ pPicture->clientClipType = CT_NONE;
+ pPicture->componentAlpha = FALSE;
+ pPicture->repeatType = RepeatNone;
+
+ pPicture->alphaMap = 0;
+ pPicture->alphaOrigin.x = 0;
+ pPicture->alphaOrigin.y = 0;
+
+ pPicture->clipOrigin.x = 0;
+ pPicture->clipOrigin.y = 0;
+ pPicture->clientClip = 0;
+
+ pPicture->transform = 0;
+
+ pPicture->dither = None;
+ pPicture->filter = PictureGetFilterId (FilterNearest, -1, TRUE);
+ pPicture->filter_params = 0;
+ pPicture->filter_nparams = 0;
+
+ pPicture->serialNumber = GC_CHANGE_SERIAL_BIT;
+ pPicture->stateChanges = (1 << (CPLastBit+1)) - 1;
+ pPicture->pSourcePict = 0;
+}
+
+PicturePtr
+AllocatePicture (ScreenPtr pScreen)
+{
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ PicturePtr pPicture;
+ char *ptr;
+ DevUnion *ppriv;
+ unsigned int *sizes;
+ unsigned int size;
+ int i;
+
+ pPicture = (PicturePtr) xalloc (ps->totalPictureSize);
+ if (!pPicture)
+ return 0;
+ ppriv = (DevUnion *)(pPicture + 1);
+ pPicture->devPrivates = ppriv;
+ sizes = ps->PicturePrivateSizes;
+ ptr = (char *)(ppriv + ps->PicturePrivateLen);
+ for (i = ps->PicturePrivateLen; --i >= 0; ppriv++, sizes++)
+ {
+ if ( (size = *sizes) )
+ {
+ ppriv->ptr = (pointer)ptr;
+ ptr += size;
+ }
+ else
+ ppriv->ptr = (pointer)NULL;
+ }
+ return pPicture;
+}
+
+/*
+ * Let picture always point to the virtual pixmap.
+ * For sure this is not the best way to deal with
+ * the virtual frame-buffer.
+ */
+
+#define NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+PicturePtr
+CreatePicture (Picture pid,
+ DrawablePtr pDrawable,
+ PictFormatPtr pFormat,
+ Mask vmask,
+ XID *vlist,
+ ClientPtr client,
+ int *error)
+{
+ PicturePtr pPicture;
+ PictureScreenPtr ps = GetPictureScreen(pDrawable->pScreen);
+
+ pPicture = AllocatePicture (pDrawable->pScreen);
+ if (!pPicture)
+ {
+ *error = BadAlloc;
+ return 0;
+ }
+
+ pPicture->id = pid;
+ pPicture->pDrawable = pDrawable;
+ pPicture->pFormat = pFormat;
+ pPicture->format = pFormat->format | (pDrawable->bitsPerPixel << 24);
+ if (pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ #ifdef NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+ pPicture->pDrawable = nxagentVirtualDrawable(pDrawable);
+
+ #endif
+
+ ++((PixmapPtr)pDrawable)->refcnt;
+ pPicture->pNext = 0;
+ }
+ else
+ {
+ pPicture->pNext = GetPictureWindow(((WindowPtr) pDrawable));
+ SetPictureWindow(((WindowPtr) pDrawable), pPicture);
+ }
+
+ SetPictureToDefaults (pPicture);
+
+ if (vmask)
+ *error = ChangePicture (pPicture, vmask, vlist, 0, client);
+ else
+ *error = Success;
+ if (*error == Success)
+ *error = (*ps->CreatePicture) (pPicture);
+ if (*error != Success)
+ {
+ FreePicture (pPicture, (XID) 0);
+ pPicture = 0;
+ }
+ return pPicture;
+}
+
+static CARD32 xRenderColorToCard32(xRenderColor c)
+{
+ return
+ (c.alpha >> 8 << 24) |
+ (c.red >> 8 << 16) |
+ (c.green & 0xff00) |
+ (c.blue >> 8);
+}
+
+static unsigned int premultiply(unsigned int x)
+{
+ unsigned int a = x >> 24;
+ unsigned int t = (x & 0xff00ff) * a;
+ t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8;
+ t &= 0xff00ff;
+
+ x = ((x >> 8) & 0xff) * a;
+ x = (x + ((x >> 8) & 0xff) + 0x80);
+ x &= 0xff00;
+ x |= t | (a << 24);
+ return x;
+}
+
+static unsigned int INTERPOLATE_PIXEL_256(unsigned int x, unsigned int a,
+ unsigned int y, unsigned int b)
+{
+ CARD32 t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;
+ t >>= 8;
+ t &= 0xff00ff;
+
+ x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;
+ x &= 0xff00ff00;
+ x |= t;
+ return x;
+}
+
+static void initGradientColorTable(SourcePictPtr pGradient, int *error)
+{
+ int begin_pos, end_pos;
+ xFixed incr, dpos;
+ int pos, current_stop;
+ PictGradientStopPtr stops = pGradient->linear.stops;
+ int nstops = pGradient->linear.nstops;
+
+ /* The position where the gradient begins and ends */
+ begin_pos = (stops[0].x * PICT_GRADIENT_STOPTABLE_SIZE) >> 16;
+ end_pos = (stops[nstops - 1].x * PICT_GRADIENT_STOPTABLE_SIZE) >> 16;
+
+ pos = 0; /* The position in the color table. */
+
+ /* Up to first point */
+ while (pos <= begin_pos) {
+ pGradient->linear.colorTable[pos] = xRenderColorToCard32(stops[0].color);
+ ++pos;
+ }
+
+ incr = (1<<16)/ PICT_GRADIENT_STOPTABLE_SIZE; /* the double increment. */
+ dpos = incr * pos; /* The position in terms of 0-1. */
+
+ current_stop = 0; /* We always interpolate between current and current + 1. */
+
+ /* Gradient area */
+ while (pos < end_pos) {
+ unsigned int current_color = xRenderColorToCard32(stops[current_stop].color);
+ unsigned int next_color = xRenderColorToCard32(stops[current_stop + 1].color);
+
+ int dist = (int)(256*(dpos - stops[current_stop].x)
+ / (stops[current_stop+1].x - stops[current_stop].x));
+ int idist = 256 - dist;
+
+ pGradient->linear.colorTable[pos] = premultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
+
+ ++pos;
+ dpos += incr;
+
+ if (dpos > stops[current_stop + 1].x)
+ ++current_stop;
+ }
+
+ /* After last point */
+ while (pos < PICT_GRADIENT_STOPTABLE_SIZE) {
+ pGradient->linear.colorTable[pos] = xRenderColorToCard32(stops[nstops - 1].color);
+ ++pos;
+ }
+}
+
+static void initGradient(SourcePictPtr pGradient, int stopCount,
+ xFixed *stopPoints, xRenderColor *stopColors, int *error)
+{
+ int i;
+ xFixed dpos;
+
+ if (stopCount <= 0) {
+ *error = BadValue;
+ return;
+ }
+
+ dpos = -1;
+ for (i = 0; i < stopCount; ++i) {
+ if (stopPoints[i] <= dpos || stopPoints[i] > (1<<16)) {
+ *error = BadValue;
+ return;
+ }
+ dpos = stopPoints[i];
+ }
+
+ pGradient->linear.stops = xalloc(stopCount*sizeof(PictGradientStop));
+ if (!pGradient->linear.stops) {
+ *error = BadAlloc;
+ return;
+ }
+
+ pGradient->linear.nstops = stopCount;
+
+ for (i = 0; i < stopCount; ++i) {
+ pGradient->linear.stops[i].x = stopPoints[i];
+ pGradient->linear.stops[i].color = stopColors[i];
+ }
+ initGradientColorTable(pGradient, error);
+}
+
+static PicturePtr createSourcePicture(void)
+{
+ PicturePtr pPicture;
+ pPicture = (PicturePtr) xalloc(sizeof(PictureRec));
+ pPicture->pDrawable = 0;
+ pPicture->pFormat = 0;
+ pPicture->pNext = 0;
+
+ SetPictureToDefaults(pPicture);
+ return pPicture;
+}
+
+PicturePtr
+CreateSolidPicture (Picture pid, xRenderColor *color, int *error)
+{
+ PicturePtr pPicture;
+ pPicture = createSourcePicture();
+ if (!pPicture) {
+ *error = BadAlloc;
+ return 0;
+ }
+
+ pPicture->id = pid;
+ pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictSolidFill));
+ if (!pPicture->pSourcePict) {
+ *error = BadAlloc;
+ xfree(pPicture);
+ return 0;
+ }
+ pPicture->pSourcePict->type = SourcePictTypeSolidFill;
+ pPicture->pSourcePict->solidFill.color = xRenderColorToCard32(*color);
+ return pPicture;
+}
+
+PicturePtr
+CreateLinearGradientPicture (Picture pid, xPointFixed *p1, xPointFixed *p2,
+ int nStops, xFixed *stops, xRenderColor *colors, int *error)
+{
+ PicturePtr pPicture;
+
+ if (nStops < 2) {
+ *error = BadValue;
+ return 0;
+ }
+
+ pPicture = createSourcePicture();
+ if (!pPicture) {
+ *error = BadAlloc;
+ return 0;
+ }
+ if (p1->x == p2->x && p1->y == p2->y) {
+ *error = BadValue;
+ return 0;
+ }
+
+ pPicture->id = pid;
+ pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictLinearGradient));
+ if (!pPicture->pSourcePict) {
+ *error = BadAlloc;
+ xfree(pPicture);
+ return 0;
+ }
+
+ pPicture->pSourcePict->linear.type = SourcePictTypeLinear;
+ pPicture->pSourcePict->linear.p1 = *p1;
+ pPicture->pSourcePict->linear.p2 = *p2;
+
+ initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
+ if (*error) {
+ xfree(pPicture);
+ return 0;
+ }
+ return pPicture;
+}
+
+#define FixedToDouble(x) ((x)/65536.)
+
+PicturePtr
+CreateRadialGradientPicture (Picture pid, xPointFixed *inner, xPointFixed *outer,
+ xFixed innerRadius, xFixed outerRadius,
+ int nStops, xFixed *stops, xRenderColor *colors, int *error)
+{
+ PicturePtr pPicture;
+ PictRadialGradient *radial;
+
+ if (nStops < 2) {
+ *error = BadValue;
+ return 0;
+ }
+
+ pPicture = createSourcePicture();
+ if (!pPicture) {
+ *error = BadAlloc;
+ return 0;
+ }
+ {
+ double dx = (double)(inner->x - outer->x);
+ double dy = (double)(inner->y - outer->y);
+ if (sqrt(dx*dx + dy*dy) + (double)(innerRadius) > (double)(outerRadius)) {
+ *error = BadValue;
+ return 0;
+ }
+ }
+
+ pPicture->id = pid;
+ pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictRadialGradient));
+ if (!pPicture->pSourcePict) {
+ *error = BadAlloc;
+ xfree(pPicture);
+ return 0;
+ }
+ radial = &pPicture->pSourcePict->radial;
+
+ radial->type = SourcePictTypeRadial;
+ {
+ double x = (double)innerRadius / (double)outerRadius;
+ radial->dx = (outer->x - inner->x);
+ radial->dy = (outer->y - inner->y);
+ radial->fx = (inner->x) - x*radial->dx;
+ radial->fy = (inner->y) - x*radial->dy;
+ radial->m = 1./(1+x);
+ radial->b = -x*radial->m;
+ radial->dx /= 65536.;
+ radial->dy /= 65536.;
+ radial->fx /= 65536.;
+ radial->fy /= 65536.;
+ x = outerRadius/65536.;
+ radial->a = x*x - radial->dx*radial->dx - radial->dy*radial->dy;
+ }
+
+ initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
+ if (*error) {
+ xfree(pPicture);
+ return 0;
+ }
+ return pPicture;
+}
+
+PicturePtr
+CreateConicalGradientPicture (Picture pid, xPointFixed *center, xFixed angle,
+ int nStops, xFixed *stops, xRenderColor *colors, int *error)
+{
+ PicturePtr pPicture;
+
+ if (nStops < 2) {
+ *error = BadValue;
+ return 0;
+ }
+
+ pPicture = createSourcePicture();
+ if (!pPicture) {
+ *error = BadAlloc;
+ return 0;
+ }
+
+ pPicture->id = pid;
+ pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictConicalGradient));
+ if (!pPicture->pSourcePict) {
+ *error = BadAlloc;
+ xfree(pPicture);
+ return 0;
+ }
+
+ pPicture->pSourcePict->conical.type = SourcePictTypeConical;
+ pPicture->pSourcePict->conical.center = *center;
+ pPicture->pSourcePict->conical.angle = angle;
+
+ initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
+ if (*error) {
+ xfree(pPicture);
+ return 0;
+ }
+ return pPicture;
+}
+
+#define NEXT_VAL(_type) (vlist ? (_type) *vlist++ : (_type) ulist++->val)
+
+#define NEXT_PTR(_type) ((_type) ulist++->ptr)
+
+int
+ChangePicture (PicturePtr pPicture,
+ Mask vmask,
+ XID *vlist,
+ DevUnion *ulist,
+ ClientPtr client)
+{
+ ScreenPtr pScreen = pPicture->pDrawable ? pPicture->pDrawable->pScreen : 0;
+ PictureScreenPtr ps = pScreen ? GetPictureScreen(pScreen) : 0;
+ BITS32 index2;
+ int error = 0;
+ BITS32 maskQ;
+
+ pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ maskQ = vmask;
+ while (vmask && !error)
+ {
+ index2 = (BITS32) lowbit (vmask);
+ vmask &= ~index2;
+ pPicture->stateChanges |= index2;
+ switch (index2)
+ {
+ case CPRepeat:
+ {
+ unsigned int newr;
+ newr = NEXT_VAL(unsigned int);
+ if (newr <= RepeatReflect)
+ {
+ pPicture->repeat = (newr != RepeatNone);
+ pPicture->repeatType = newr;
+ }
+ else
+ {
+ client->errorValue = newr;
+ error = BadValue;
+ }
+ }
+ break;
+ case CPAlphaMap:
+ {
+ PicturePtr pAlpha;
+
+ if (vlist)
+ {
+ Picture pid = NEXT_VAL(Picture);
+
+ if (pid == None)
+ pAlpha = 0;
+ else
+ {
+ pAlpha = (PicturePtr) SecurityLookupIDByType(client,
+ pid,
+ PictureType,
+ SecurityWriteAccess|SecurityReadAccess);
+ if (!pAlpha)
+ {
+ client->errorValue = pid;
+ error = BadPixmap;
+ break;
+ }
+ if (pAlpha->pDrawable->type != DRAWABLE_PIXMAP)
+ {
+ client->errorValue = pid;
+ error = BadMatch;
+ break;
+ }
+ }
+ }
+ else
+ pAlpha = NEXT_PTR(PicturePtr);
+ if (!error)
+ {
+ if (pAlpha && pAlpha->pDrawable->type == DRAWABLE_PIXMAP)
+ pAlpha->refcnt++;
+ if (pPicture->alphaMap)
+ FreePicture ((pointer) pPicture->alphaMap, (XID) 0);
+ pPicture->alphaMap = pAlpha;
+ }
+ }
+ break;
+ case CPAlphaXOrigin:
+ pPicture->alphaOrigin.x = NEXT_VAL(INT16);
+ break;
+ case CPAlphaYOrigin:
+ pPicture->alphaOrigin.y = NEXT_VAL(INT16);
+ break;
+ case CPClipXOrigin:
+ pPicture->clipOrigin.x = NEXT_VAL(INT16);
+ break;
+ case CPClipYOrigin:
+ pPicture->clipOrigin.y = NEXT_VAL(INT16);
+ break;
+ case CPClipMask:
+ {
+ Pixmap pid;
+ PixmapPtr pPixmap;
+ int clipType;
+ if (!pScreen)
+ return BadDrawable;
+
+ if (vlist)
+ {
+ pid = NEXT_VAL(Pixmap);
+ if (pid == None)
+ {
+ clipType = CT_NONE;
+ pPixmap = NullPixmap;
+ }
+ else
+ {
+ clipType = CT_PIXMAP;
+ pPixmap = (PixmapPtr)SecurityLookupIDByType(client,
+ pid,
+ RT_PIXMAP,
+ SecurityReadAccess);
+ if (!pPixmap)
+ {
+ client->errorValue = pid;
+ error = BadPixmap;
+ break;
+ }
+ }
+ }
+ else
+ {
+ pPixmap = NEXT_PTR(PixmapPtr);
+ if (pPixmap)
+ clipType = CT_PIXMAP;
+ else
+ clipType = CT_NONE;
+ }
+
+ if (pPixmap)
+ {
+ if ((pPixmap->drawable.depth != 1) ||
+ (pPixmap->drawable.pScreen != pScreen))
+ {
+ error = BadMatch;
+ break;
+ }
+ else
+ {
+ clipType = CT_PIXMAP;
+ pPixmap->refcnt++;
+ }
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "ChangePicture: Going to call ChangePictureClip with clipType [%d] pPixmap [%p].\n",
+ clipType, (void *) pPixmap);
+ #endif
+
+ error = (*ps->ChangePictureClip)(pPicture, clipType,
+ (pointer)pPixmap, 0);
+ break;
+ }
+ case CPGraphicsExposure:
+ {
+ unsigned int newe;
+ newe = NEXT_VAL(unsigned int);
+ if (newe <= xTrue)
+ pPicture->graphicsExposures = newe;
+ else
+ {
+ client->errorValue = newe;
+ error = BadValue;
+ }
+ }
+ break;
+ case CPSubwindowMode:
+ {
+ unsigned int news;
+ news = NEXT_VAL(unsigned int);
+ if (news == ClipByChildren || news == IncludeInferiors)
+ pPicture->subWindowMode = news;
+ else
+ {
+ client->errorValue = news;
+ error = BadValue;
+ }
+ }
+ break;
+ case CPPolyEdge:
+ {
+ unsigned int newe;
+ newe = NEXT_VAL(unsigned int);
+ if (newe == PolyEdgeSharp || newe == PolyEdgeSmooth)
+ pPicture->polyEdge = newe;
+ else
+ {
+ client->errorValue = newe;
+ error = BadValue;
+ }
+ }
+ break;
+ case CPPolyMode:
+ {
+ unsigned int newm;
+ newm = NEXT_VAL(unsigned int);
+ if (newm == PolyModePrecise || newm == PolyModeImprecise)
+ pPicture->polyMode = newm;
+ else
+ {
+ client->errorValue = newm;
+ error = BadValue;
+ }
+ }
+ break;
+ case CPDither:
+ pPicture->dither = NEXT_VAL(Atom);
+ break;
+ case CPComponentAlpha:
+ {
+ unsigned int newca;
+
+ newca = NEXT_VAL (unsigned int);
+ if (newca <= xTrue)
+ pPicture->componentAlpha = newca;
+ else
+ {
+ client->errorValue = newca;
+ error = BadValue;
+ }
+ }
+ break;
+ default:
+ client->errorValue = maskQ;
+ error = BadValue;
+ break;
+ }
+ }
+ if (ps)
+ (*ps->ChangePicture) (pPicture, maskQ);
+ return error;
+}
+
+int
+SetPictureClipRects (PicturePtr pPicture,
+ int xOrigin,
+ int yOrigin,
+ int nRect,
+ xRectangle *rects)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ RegionPtr clientClip;
+ int result;
+
+ clientClip = RECTS_TO_REGION(pScreen,
+ nRect, rects, CT_UNSORTED);
+ if (!clientClip)
+ return BadAlloc;
+ result =(*ps->ChangePictureClip) (pPicture, CT_REGION,
+ (pointer) clientClip, 0);
+ if (result == Success)
+ {
+ pPicture->clipOrigin.x = xOrigin;
+ pPicture->clipOrigin.y = yOrigin;
+ pPicture->stateChanges |= CPClipXOrigin|CPClipYOrigin|CPClipMask;
+ pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ }
+ return result;
+}
+
+int
+SetPictureClipRegion (PicturePtr pPicture,
+ int xOrigin,
+ int yOrigin,
+ RegionPtr pRegion)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ RegionPtr clientClip;
+ int result;
+ int type;
+
+ if (pRegion)
+ {
+ type = CT_REGION;
+ clientClip = REGION_CREATE (pScreen,
+ REGION_EXTENTS(pScreen, pRegion),
+ REGION_NUM_RECTS(pRegion));
+ if (!clientClip)
+ return BadAlloc;
+ if (!REGION_COPY (pSCreen, clientClip, pRegion))
+ {
+ REGION_DESTROY (pScreen, clientClip);
+ return BadAlloc;
+ }
+ }
+ else
+ {
+ type = CT_NONE;
+ clientClip = 0;
+ }
+
+ result =(*ps->ChangePictureClip) (pPicture, type,
+ (pointer) clientClip, 0);
+ if (result == Success)
+ {
+ pPicture->clipOrigin.x = xOrigin;
+ pPicture->clipOrigin.y = yOrigin;
+ pPicture->stateChanges |= CPClipXOrigin|CPClipYOrigin|CPClipMask;
+ pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ }
+ return result;
+}
+
+
+int
+SetPictureTransform (PicturePtr pPicture,
+ PictTransform *transform)
+{
+ static const PictTransform identity = { {
+ { xFixed1, 0x00000, 0x00000 },
+ { 0x00000, xFixed1, 0x00000 },
+ { 0x00000, 0x00000, xFixed1 },
+ } };
+
+ if (transform && memcmp (transform, &identity, sizeof (PictTransform)) == 0)
+ transform = 0;
+
+ if (transform)
+ {
+ if (!pPicture->transform)
+ {
+ pPicture->transform = (PictTransform *) xalloc (sizeof (PictTransform));
+ if (!pPicture->transform)
+ return BadAlloc;
+ }
+ *pPicture->transform = *transform;
+ }
+ else
+ {
+ if (pPicture->transform)
+ {
+ xfree (pPicture->transform);
+ pPicture->transform = 0;
+ }
+ }
+ pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+
+ return Success;
+}
+
+void
+CopyPicture (PicturePtr pSrc,
+ Mask mask,
+ PicturePtr pDst)
+{
+ PictureScreenPtr ps = GetPictureScreen(pSrc->pDrawable->pScreen);
+ Mask origMask = mask;
+
+ pDst->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ pDst->stateChanges |= mask;
+
+ while (mask) {
+ Mask bit = lowbit(mask);
+
+ switch (bit)
+ {
+ case CPRepeat:
+ pDst->repeat = pSrc->repeat;
+ pDst->repeatType = pSrc->repeatType;
+ break;
+ case CPAlphaMap:
+ if (pSrc->alphaMap && pSrc->alphaMap->pDrawable->type == DRAWABLE_PIXMAP)
+ pSrc->alphaMap->refcnt++;
+ if (pDst->alphaMap)
+ FreePicture ((pointer) pDst->alphaMap, (XID) 0);
+ pDst->alphaMap = pSrc->alphaMap;
+ break;
+ case CPAlphaXOrigin:
+ pDst->alphaOrigin.x = pSrc->alphaOrigin.x;
+ break;
+ case CPAlphaYOrigin:
+ pDst->alphaOrigin.y = pSrc->alphaOrigin.y;
+ break;
+ case CPClipXOrigin:
+ pDst->clipOrigin.x = pSrc->clipOrigin.x;
+ break;
+ case CPClipYOrigin:
+ pDst->clipOrigin.y = pSrc->clipOrigin.y;
+ break;
+ case CPClipMask:
+ switch (pSrc->clientClipType) {
+ case CT_NONE:
+ (*ps->ChangePictureClip)(pDst, CT_NONE, NULL, 0);
+ break;
+ case CT_REGION:
+ if (!pSrc->clientClip) {
+ (*ps->ChangePictureClip)(pDst, CT_NONE, NULL, 0);
+ } else {
+ RegionPtr clientClip;
+ RegionPtr srcClientClip = (RegionPtr)pSrc->clientClip;
+
+ clientClip = REGION_CREATE(pSrc->pDrawable->pScreen,
+ REGION_EXTENTS(pSrc->pDrawable->pScreen, srcClientClip),
+ REGION_NUM_RECTS(srcClientClip));
+ (*ps->ChangePictureClip)(pDst, CT_REGION, clientClip, 0);
+ }
+ break;
+ default:
+ /* XXX: CT_PIXMAP unimplemented */
+ break;
+ }
+ break;
+ case CPGraphicsExposure:
+ pDst->graphicsExposures = pSrc->graphicsExposures;
+ break;
+ case CPPolyEdge:
+ pDst->polyEdge = pSrc->polyEdge;
+ break;
+ case CPPolyMode:
+ pDst->polyMode = pSrc->polyMode;
+ break;
+ case CPDither:
+ pDst->dither = pSrc->dither;
+ break;
+ case CPComponentAlpha:
+ pDst->componentAlpha = pSrc->componentAlpha;
+ break;
+ }
+ mask &= ~bit;
+ }
+
+ (*ps->ChangePicture)(pDst, origMask);
+}
+
+static void
+ValidateOnePicture (PicturePtr pPicture)
+{
+ if (pPicture->pDrawable && pPicture->serialNumber != pPicture->pDrawable->serialNumber)
+ {
+ PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen);
+
+ (*ps->ValidatePicture) (pPicture, pPicture->stateChanges);
+ pPicture->stateChanges = 0;
+ pPicture->serialNumber = pPicture->pDrawable->serialNumber;
+ }
+}
+
+void
+ValidatePicture(PicturePtr pPicture)
+{
+ ValidateOnePicture (pPicture);
+ if (pPicture->alphaMap)
+ ValidateOnePicture (pPicture->alphaMap);
+}
+
+int
+FreePicture (pointer value,
+ XID pid)
+{
+ PicturePtr pPicture = (PicturePtr) value;
+
+ if (--pPicture->refcnt == 0)
+ {
+ if (pPicture->transform)
+ xfree (pPicture->transform);
+ if (!pPicture->pDrawable) {
+ if (pPicture->pSourcePict) {
+ if (pPicture->pSourcePict->type != SourcePictTypeSolidFill)
+ xfree(pPicture->pSourcePict->linear.stops);
+ xfree(pPicture->pSourcePict);
+ }
+ } else {
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+
+ if (pPicture->alphaMap)
+ FreePicture ((pointer) pPicture->alphaMap, (XID) 0);
+ (*ps->DestroyPicture) (pPicture);
+ (*ps->DestroyPictureClip) (pPicture);
+ if (pPicture->pDrawable->type == DRAWABLE_WINDOW)
+ {
+ WindowPtr pWindow = (WindowPtr) pPicture->pDrawable;
+ PicturePtr *pPrev;
+
+ for (pPrev = (PicturePtr *) &((pWindow)->devPrivates[PictureWindowPrivateIndex].ptr);
+ *pPrev;
+ pPrev = &(*pPrev)->pNext)
+ {
+ if (*pPrev == pPicture)
+ {
+ *pPrev = pPicture->pNext;
+ break;
+ }
+ }
+ }
+ else if (pPicture->pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ (*pScreen->DestroyPixmap) ((PixmapPtr)pPicture->pDrawable);
+ }
+ }
+ xfree (pPicture);
+ }
+ return Success;
+}
+
+int
+FreePictFormat (pointer pPictFormat,
+ XID pid)
+{
+ return Success;
+}
+
+void
+CompositePicture (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
+ ValidatePicture (pSrc);
+ if (pMask)
+ ValidatePicture (pMask);
+ ValidatePicture (pDst);
+ (*ps->Composite) (op,
+ pSrc,
+ pMask,
+ pDst,
+ xSrc,
+ ySrc,
+ xMask,
+ yMask,
+ xDst,
+ yDst,
+ width,
+ height);
+}
+
+void
+CompositeGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr lists,
+ GlyphPtr *glyphs)
+{
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
+ ValidatePicture (pSrc);
+ ValidatePicture (pDst);
+
+ #ifdef TEST
+ fprintf(stderr, "CompositeGlyphs: Going to composite glyphs with "
+ "source at [%p] and destination at [%p].\n",
+ (void *) pSrc, (void *) pDst);
+ #endif
+
+ (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, lists, glyphs);
+}
+
+void
+CompositeRects (CARD8 op,
+ PicturePtr pDst,
+ xRenderColor *color,
+ int nRect,
+ xRectangle *rects)
+{
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
+ ValidatePicture (pDst);
+ (*ps->CompositeRects) (op, pDst, color, nRect, rects);
+}
+
+void
+CompositeTrapezoids (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntrap,
+ xTrapezoid *traps)
+{
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
+ ValidatePicture (pSrc);
+ ValidatePicture (pDst);
+ (*ps->Trapezoids) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntrap, traps);
+}
+
+void
+CompositeTriangles (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntriangles,
+ xTriangle *triangles)
+{
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
+ ValidatePicture (pSrc);
+ ValidatePicture (pDst);
+ (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntriangles, triangles);
+}
+
+void
+CompositeTriStrip (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoints,
+ xPointFixed *points)
+{
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
+ ValidatePicture (pSrc);
+ ValidatePicture (pDst);
+ (*ps->TriStrip) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
+}
+
+void
+CompositeTriFan (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoints,
+ xPointFixed *points)
+{
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
+ ValidatePicture (pSrc);
+ ValidatePicture (pDst);
+ (*ps->TriFan) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
+}
+
+void
+AddTraps (PicturePtr pPicture,
+ INT16 xOff,
+ INT16 yOff,
+ int ntrap,
+ xTrap *traps)
+{
+ PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen);
+
+ ValidatePicture (pPicture);
+ (*ps->AddTraps) (pPicture, xOff, yOff, ntrap, traps);
+}
+
+#define MAX_FIXED_48_16 ((xFixed_48_16) 0x7fffffff)
+#define MIN_FIXED_48_16 (-((xFixed_48_16) 1 << 31))
+
+Bool
+PictureTransformPoint3d (PictTransformPtr transform,
+ PictVectorPtr vector)
+{
+ PictVector result;
+ int i, j;
+ xFixed_32_32 partial;
+ xFixed_48_16 v;
+
+ for (j = 0; j < 3; j++)
+ {
+ v = 0;
+ for (i = 0; i < 3; i++)
+ {
+ partial = ((xFixed_48_16) transform->matrix[j][i] *
+ (xFixed_48_16) vector->vector[i]);
+ v += partial >> 16;
+ }
+ if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
+ return FALSE;
+ result.vector[j] = (xFixed) v;
+ }
+ if (!result.vector[2])
+ return FALSE;
+ *vector = result;
+ return TRUE;
+}
+
+
+Bool
+PictureTransformPoint (PictTransformPtr transform,
+ PictVectorPtr vector)
+{
+ PictVector result;
+ int i, j;
+ xFixed_32_32 partial;
+ xFixed_48_16 v;
+
+ for (j = 0; j < 3; j++)
+ {
+ v = 0;
+ for (i = 0; i < 3; i++)
+ {
+ partial = ((xFixed_48_16) transform->matrix[j][i] *
+ (xFixed_48_16) vector->vector[i]);
+ v += partial >> 16;
+ }
+ if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
+ return FALSE;
+ result.vector[j] = (xFixed) v;
+ }
+ if (!result.vector[2])
+ return FALSE;
+ for (j = 0; j < 2; j++)
+ {
+ partial = (xFixed_48_16) result.vector[j] << 16;
+ v = partial / result.vector[2];
+ if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
+ return FALSE;
+ vector->vector[j] = (xFixed) v;
+ }
+ vector->vector[2] = xFixed1;
+ return TRUE;
+}
+
+#ifndef True
+# define True 1
+#endif
+
+#ifndef False
+# define False 0
+#endif
+
+void nxagentReconnectPictFormat(void*, XID, void*);
+
+Bool nxagentReconnectAllPictFormat(void *p)
+{
+ PictFormatPtr formats_old, formats;
+ int nformats, nformats_old;
+ VisualPtr pVisual;
+ Bool success = True;
+ Bool matched;
+ int i, n;
+ CARD32 type, a, r, g, b;
+
+ #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_PICTFORMAT_DEBUG)
+ fprintf(stderr, "nxagentReconnectAllPictFormat\n");
+ #endif
+
+ formats_old = GetPictureScreen(nxagentDefaultScreen) -> formats;
+ nformats_old = GetPictureScreen(nxagentDefaultScreen) -> nformats;
+
+ /*
+ * TODO: We could copy PictureCreateDefaultFormats,
+ * in order not to waste ID with FakeClientID().
+ */
+ formats = PictureCreateDefaultFormats (nxagentDefaultScreen, &nformats);
+
+ if (!formats)
+ return False;
+
+ for (n = 0; n < nformats; n++)
+ {
+ if (formats[n].type == PictTypeIndexed)
+ {
+ pVisual = nxagentVisualFromID(nxagentDefaultScreen, formats[n].index.vid);
+
+ if ((pVisual->class | DynamicClass) == PseudoColor)
+ type = PICT_TYPE_COLOR;
+ else
+ type = PICT_TYPE_GRAY;
+ a = r = g = b = 0;
+ }
+ else
+ {
+ if ((formats[n].direct.redMask|
+ formats[n].direct.blueMask|
+ formats[n].direct.greenMask) == 0)
+ type = PICT_TYPE_A;
+ else if (formats[n].direct.red > formats[n].direct.blue)
+ type = PICT_TYPE_ARGB;
+ else
+ type = PICT_TYPE_ABGR;
+ a = Ones (formats[n].direct.alphaMask);
+ r = Ones (formats[n].direct.redMask);
+ g = Ones (formats[n].direct.greenMask);
+ b = Ones (formats[n].direct.blueMask);
+ }
+ formats[n].format = PICT_FORMAT(0,type,a,r,g,b);
+ }
+
+ for (n = 0; n < nformats_old; n++)
+ {
+ for (i = 0, matched = False; (!matched) && (i < nformats); i++)
+ {
+ if (formats_old[n].format == formats[i].format &&
+ formats_old[n].type == formats[i].type &&
+ formats_old[n].direct.red == formats[i].direct.red &&
+ formats_old[n].direct.green == formats[i].direct.green &&
+ formats_old[n].direct.blue == formats[i].direct.blue &&
+ formats_old[n].direct.redMask == formats[i].direct.redMask &&
+ formats_old[n].direct.greenMask == formats[i].direct.greenMask &&
+ formats_old[n].direct.blueMask == formats[i].direct.blueMask &&
+ formats_old[n].direct.alpha == formats[i].direct.alpha &&
+ formats_old[n].direct.alphaMask == formats[i].direct.alphaMask)
+ {
+ /*
+ * Regard depth 16 and 15 as were the same, if all other values match.
+ */
+
+ if ((formats_old[n].depth == formats[i].depth) ||
+ ((formats_old[n].depth == 15 || formats_old[n].depth == 16) &&
+ (formats[i].depth == 15 || formats[i].depth == 16)))
+ {
+ matched = True;
+ }
+ }
+ }
+
+ if (!matched)
+ {
+ return False;
+ }
+ }
+
+ xfree(formats);
+
+ /* TODO: Perhaps do i have to do PictureFinishInit ?. */
+ /* TODO: We have to check for new Render protocol version. */
+
+ for (i = 0; (i < MAXCLIENTS) && (success); i++)
+ {
+ if (clients[i])
+ {
+ FindClientResourcesByType(clients[i], PictFormatType, nxagentReconnectPictFormat, &success);
+ }
+ }
+
+ return success;
+}
+
+/*
+ * It seem we don't have nothing
+ * to do for reconnect PictureFormat.
+ */
+
+void nxagentReconnectPictFormat(void *p0, XID x1, void *p2)
+{
+ PictFormatPtr pFormat;
+ Bool *pBool;
+
+ pFormat = (PictFormatPtr)p0;
+ pBool = (Bool*)p2;
+
+ #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_PICTFORMAT_DEBUG)
+ fprintf(stderr, "nxagentReconnectPictFormat.\n");
+ #endif
+}
+
+/*
+ * The set of picture formats may change considerably
+ * between different X servers. This poses a problem
+ * while migrating NX sessions, because a requisite to
+ * successfully reconnect the session is that all pic-
+ * ture formats have to be available on the new X server.
+ * To reduce such problems, we use a limited set of
+ * pictures available on the most X servers.
+ */
+
+void nxagentPictureCreateDefaultFormats(ScreenPtr pScreen, FormatInitRec *formats, int *nformats)
+{
+ DepthPtr pDepth;
+ VisualPtr pVisual;
+
+ CARD32 format;
+ CARD8 depth;
+
+ int r, g, b;
+ int bpp;
+ int d;
+ int v;
+
+
+ formats[*nformats].format = PICT_a1;
+ formats[*nformats].depth = 1;
+ *nformats += 1;
+ formats[*nformats].format = PICT_a4;
+ formats[*nformats].depth = 4;
+ *nformats += 1;
+ formats[*nformats].format = PICT_a8;
+ formats[*nformats].depth = 8;
+ *nformats += 1;
+ formats[*nformats].format = PICT_a8r8g8b8;
+ formats[*nformats].depth = 32;
+ *nformats += 1;
+
+ /*
+ * This format should be required by the
+ * protocol, but it's not used by Xgl.
+ *
+ * formats[*nformats].format = PICT_x8r8g8b8;
+ * formats[*nformats].depth = 32;
+ * *nformats += 1;
+ */
+
+ /* now look through the depths and visuals adding other formats */
+ for (v = 0; v < pScreen->numVisuals; v++)
+ {
+ pVisual = &pScreen->visuals[v];
+ depth = visualDepth (pScreen, pVisual);
+ if (!depth)
+ continue;
+
+ bpp = BitsPerPixel (depth);
+
+ switch (pVisual->class)
+ {
+ case DirectColor:
+ case TrueColor:
+ r = Ones (pVisual->redMask);
+ g = Ones (pVisual->greenMask);
+ b = Ones (pVisual->blueMask);
+
+ if (pVisual->offsetBlue == 0 &&
+ pVisual->offsetGreen == b &&
+ pVisual->offsetRed == b + g)
+ {
+ format = PICT_FORMAT(bpp, PICT_TYPE_ARGB, 0, r, g, b);
+ *nformats = addFormat (formats, *nformats, format, depth);
+ }
+ break;
+ case StaticColor:
+ case PseudoColor:
+ case StaticGray:
+ case GrayScale:
+ break;
+ }
+ }
+
+ for (d = 0; d < pScreen -> numDepths; d++)
+ {
+ pDepth = &pScreen -> allowedDepths[d];
+ bpp = BitsPerPixel(pDepth -> depth);
+
+ switch (bpp) {
+ case 16:
+ if (pDepth->depth == 15)
+ {
+ *nformats = addFormat (formats, *nformats,
+ PICT_x1r5g5b5, pDepth->depth);
+ }
+
+ if (pDepth->depth == 16)
+ {
+ *nformats = addFormat (formats, *nformats,
+ PICT_r5g6b5, pDepth->depth);
+ }
+ break;
+ case 24:
+ if (pDepth->depth == 24)
+ {
+ *nformats = addFormat (formats, *nformats,
+ PICT_r8g8b8, pDepth->depth);
+ }
+ break;
+ case 32:
+ if (pDepth->depth == 24)
+ {
+ *nformats = addFormat (formats, *nformats,
+ PICT_x8r8g8b8, pDepth->depth);
+ }
+ break;
+ }
+ }
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original
new file mode 100644
index 000000000..5d6f71475
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original
@@ -0,0 +1,2220 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/picture.c,v 1.29 2002/11/23 02:38:15 keithp Exp $
+ *
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+#include "NXpicturestr.h"
+
+#include "Screen.h"
+#include "Pixmaps.h"
+#include "Drawable.h"
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+void *nxagentVisualFromID(ScreenPtr pScreen, VisualID visual);
+
+void *nxagentMatchingFormats(PictFormatPtr pForm);
+
+int PictureScreenPrivateIndex = -1;
+int PictureWindowPrivateIndex;
+int PictureGeneration;
+RESTYPE PictureType;
+RESTYPE PictFormatType;
+RESTYPE GlyphSetType;
+int PictureCmapPolicy = PictureCmapPolicyDefault;
+
+typedef struct _formatInit {
+ CARD32 format;
+ CARD8 depth;
+} FormatInitRec, *FormatInitPtr;
+
+void nxagentPictureCreateDefaultFormats(ScreenPtr pScreen, FormatInitRec *formats, int *nformats);
+
+/* Picture Private machinery */
+
+static int picturePrivateCount;
+
+void
+ResetPicturePrivateIndex (void)
+{
+ picturePrivateCount = 0;
+}
+
+int
+AllocatePicturePrivateIndex (void)
+{
+ return picturePrivateCount++;
+}
+
+Bool
+AllocatePicturePrivate (ScreenPtr pScreen, int index2, unsigned int amount)
+{
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ unsigned int oldamount;
+
+ /* Round up sizes for proper alignment */
+ amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
+
+ if (index2 >= ps->PicturePrivateLen)
+ {
+ unsigned int *nsizes;
+
+ nsizes = (unsigned int *)xrealloc(ps->PicturePrivateSizes,
+ (index2 + 1) * sizeof(unsigned int));
+ if (!nsizes)
+ return FALSE;
+ while (ps->PicturePrivateLen <= index2)
+ {
+ nsizes[ps->PicturePrivateLen++] = 0;
+ ps->totalPictureSize += sizeof(DevUnion);
+ }
+ ps->PicturePrivateSizes = nsizes;
+ }
+ oldamount = ps->PicturePrivateSizes[index2];
+ if (amount > oldamount)
+ {
+ ps->PicturePrivateSizes[index2] = amount;
+ ps->totalPictureSize += (amount - oldamount);
+ }
+
+ return TRUE;
+}
+
+
+Bool
+PictureDestroyWindow (WindowPtr pWindow)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ PicturePtr pPicture;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ Bool ret;
+
+ while ((pPicture = GetPictureWindow(pWindow)))
+ {
+ SetPictureWindow(pWindow, pPicture->pNext);
+ if (pPicture->id)
+ FreeResource (pPicture->id, PictureType);
+ FreePicture ((pointer) pPicture, pPicture->id);
+ }
+ pScreen->DestroyWindow = ps->DestroyWindow;
+ ret = (*pScreen->DestroyWindow) (pWindow);
+ ps->DestroyWindow = pScreen->DestroyWindow;
+ pScreen->DestroyWindow = PictureDestroyWindow;
+ return ret;
+}
+
+Bool
+PictureCloseScreen (int index, ScreenPtr pScreen)
+{
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ Bool ret;
+ int n;
+
+ pScreen->CloseScreen = ps->CloseScreen;
+ ret = (*pScreen->CloseScreen) (index, pScreen);
+ PictureResetFilters (pScreen);
+ for (n = 0; n < ps->nformats; n++)
+ if (ps->formats[n].type == PictTypeIndexed)
+ (*ps->CloseIndexed) (pScreen, &ps->formats[n]);
+ SetPictureScreen(pScreen, 0);
+ if (ps->PicturePrivateSizes)
+ xfree (ps->PicturePrivateSizes);
+ xfree (ps->formats);
+ xfree (ps);
+ return ret;
+}
+
+void
+PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef)
+{
+ ScreenPtr pScreen = pColormap->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+
+ pScreen->StoreColors = ps->StoreColors;
+ (*pScreen->StoreColors) (pColormap, ndef, pdef);
+ ps->StoreColors = pScreen->StoreColors;
+ pScreen->StoreColors = PictureStoreColors;
+
+ if (pColormap->class == PseudoColor || pColormap->class == GrayScale)
+ {
+ PictFormatPtr format = ps->formats;
+ int nformats = ps->nformats;
+
+ while (nformats--)
+ {
+ if (format->type == PictTypeIndexed &&
+ format->index.pColormap == pColormap)
+ {
+ (*ps->UpdateIndexed) (pScreen, format, ndef, pdef);
+ break;
+ }
+ format++;
+ }
+ }
+}
+
+static int
+visualDepth (ScreenPtr pScreen, VisualPtr pVisual)
+{
+ int d, v;
+ DepthPtr pDepth;
+
+ for (d = 0; d < pScreen->numDepths; d++)
+ {
+ pDepth = &pScreen->allowedDepths[d];
+ for (v = 0; v < pDepth->numVids; v++)
+ if (pDepth->vids[v] == pVisual->vid)
+ return pDepth->depth;
+ }
+ return 0;
+}
+
+static int
+addFormat (FormatInitRec formats[256],
+ int nformat,
+ CARD32 format,
+ CARD8 depth)
+{
+ int n;
+
+ for (n = 0; n < nformat; n++)
+ if (formats[n].format == format && formats[n].depth == depth)
+ return nformat;
+ formats[nformat].format = format;
+ formats[nformat].depth = depth;
+
+ #ifdef DEBUG
+ fprintf(stderr, "addFormat: Added format [%lu] depth [%d].\n", format, depth);
+ #endif
+
+ return ++nformat;
+}
+
+#define Mask(n) ((n) == 32 ? 0xffffffff : ((1 << (n))-1))
+
+PictFormatPtr
+PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
+{
+ int nformats, f;
+ PictFormatPtr pFormats;
+ FormatInitRec formats[1024];
+ CARD32 format;
+
+#ifndef NXAGENT_SERVER
+
+ CARD8 depth;
+ VisualPtr pVisual;
+ int v;
+ int bpp;
+ int type;
+ int r, g, b;
+ int d;
+ DepthPtr pDepth;
+
+#endif
+
+ nformats = 0;
+
+#ifdef NXAGENT_SERVER
+
+ nxagentPictureCreateDefaultFormats(pScreen, formats, &nformats);
+
+#else
+
+ /* formats required by protocol */
+ formats[nformats].format = PICT_a1;
+ formats[nformats].depth = 1;
+ nformats++;
+ formats[nformats].format = PICT_a8;
+ formats[nformats].depth = 8;
+ nformats++;
+ formats[nformats].format = PICT_a4;
+ formats[nformats].depth = 4;
+ nformats++;
+ formats[nformats].format = PICT_a8r8g8b8;
+ formats[nformats].depth = 32;
+ nformats++;
+ formats[nformats].format = PICT_x8r8g8b8;
+ formats[nformats].depth = 32;
+ nformats++;
+
+ /* now look through the depths and visuals adding other formats */
+ for (v = 0; v < pScreen->numVisuals; v++)
+ {
+ pVisual = &pScreen->visuals[v];
+ depth = visualDepth (pScreen, pVisual);
+ if (!depth)
+ continue;
+ bpp = BitsPerPixel (depth);
+
+ switch (pVisual->class) {
+ case DirectColor:
+ case TrueColor:
+ r = Ones (pVisual->redMask);
+ g = Ones (pVisual->greenMask);
+ b = Ones (pVisual->blueMask);
+ type = PICT_TYPE_OTHER;
+ /*
+ * Current rendering code supports only two direct formats,
+ * fields must be packed together at the bottom of the pixel
+ * and must be either RGB or BGR
+ */
+ if (pVisual->offsetBlue == 0 &&
+ pVisual->offsetGreen == b &&
+ pVisual->offsetRed == b + g)
+ {
+ type = PICT_TYPE_ARGB;
+ }
+ else if (pVisual->offsetRed == 0 &&
+ pVisual->offsetGreen == r &&
+ pVisual->offsetBlue == r + g)
+ {
+ type = PICT_TYPE_ABGR;
+ }
+ if (type != PICT_TYPE_OTHER)
+ {
+ format = PICT_FORMAT(bpp, type, 0, r, g, b);
+ nformats = addFormat (formats, nformats, format, depth);
+ }
+ break;
+ case StaticColor:
+ case PseudoColor:
+ format = PICT_VISFORMAT (bpp, PICT_TYPE_COLOR, v);
+ nformats = addFormat (formats, nformats, format, depth);
+ break;
+ case StaticGray:
+ case GrayScale:
+ format = PICT_VISFORMAT (bpp, PICT_TYPE_GRAY, v);
+ nformats = addFormat (formats, nformats, format, depth);
+ break;
+ }
+ }
+
+ /*
+ * Walk supported depths and add useful Direct formats
+ */
+ for (d = 0; d < pScreen->numDepths; d++)
+ {
+ pDepth = &pScreen->allowedDepths[d];
+ bpp = BitsPerPixel (pDepth->depth);
+ format = 0;
+
+ switch (bpp) {
+ case 16:
+ /* depth 12 formats */
+ if (pDepth->depth >= 12)
+ {
+ nformats = addFormat (formats, nformats,
+ PICT_x4r4g4b4, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_x4b4g4r4, pDepth->depth);
+ }
+
+ /* depth 15 formats */
+ if (pDepth->depth >= 15)
+ {
+ nformats = addFormat (formats, nformats,
+ PICT_x1r5g5b5, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_x1b5g5r5, pDepth->depth);
+ }
+ /* depth 16 formats */
+ if (pDepth->depth >= 16)
+ {
+ nformats = addFormat (formats, nformats,
+ PICT_a1r5g5b5, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_a1b5g5r5, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_r5g6b5, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_b5g6r5, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_a4r4g4b4, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_a4b4g4r4, pDepth->depth);
+ }
+ break;
+ case 24:
+ if (pDepth->depth >= 24)
+ {
+ nformats = addFormat (formats, nformats,
+ PICT_r8g8b8, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_b8g8r8, pDepth->depth);
+ }
+ break;
+ case 32:
+ if (pDepth->depth >= 24)
+ {
+ nformats = addFormat (formats, nformats,
+ PICT_x8r8g8b8, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_x8b8g8r8, pDepth->depth);
+ }
+ break;
+ }
+ }
+
+#endif
+
+ pFormats = (PictFormatPtr) xalloc (nformats * sizeof (PictFormatRec));
+ if (!pFormats)
+ return 0;
+ memset (pFormats, '\0', nformats * sizeof (PictFormatRec));
+ for (f = 0; f < nformats; f++)
+ {
+ pFormats[f].id = FakeClientID (0);
+ pFormats[f].depth = formats[f].depth;
+ format = formats[f].format;
+ pFormats[f].format = format;
+ switch (PICT_FORMAT_TYPE(format)) {
+ case PICT_TYPE_ARGB:
+ pFormats[f].type = PictTypeDirect;
+
+ pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+ if (pFormats[f].direct.alphaMask)
+ pFormats[f].direct.alpha = (PICT_FORMAT_R(format) +
+ PICT_FORMAT_G(format) +
+ PICT_FORMAT_B(format));
+
+ pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
+ pFormats[f].direct.red = (PICT_FORMAT_G(format) +
+ PICT_FORMAT_B(format));
+
+ pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
+ pFormats[f].direct.green = PICT_FORMAT_B(format);
+
+ pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
+ pFormats[f].direct.blue = 0;
+ break;
+
+ case PICT_TYPE_ABGR:
+ pFormats[f].type = PictTypeDirect;
+
+ pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+ if (pFormats[f].direct.alphaMask)
+ pFormats[f].direct.alpha = (PICT_FORMAT_B(format) +
+ PICT_FORMAT_G(format) +
+ PICT_FORMAT_R(format));
+
+ pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
+ pFormats[f].direct.blue = (PICT_FORMAT_G(format) +
+ PICT_FORMAT_R(format));
+
+ pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
+ pFormats[f].direct.green = PICT_FORMAT_R(format);
+
+ pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
+ pFormats[f].direct.red = 0;
+ break;
+
+ case PICT_TYPE_A:
+ pFormats[f].type = PictTypeDirect;
+
+ pFormats[f].direct.alpha = 0;
+ pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+
+ /* remaining fields already set to zero */
+ break;
+
+ case PICT_TYPE_COLOR:
+ case PICT_TYPE_GRAY:
+ pFormats[f].type = PictTypeIndexed;
+ pFormats[f].index.vid = pScreen->visuals[PICT_FORMAT_VIS(format)].vid;
+ break;
+ }
+
+#ifdef NXAGENT_SERVER
+ if (nxagentMatchingFormats(&pFormats[f]) != NULL)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "PictureCreateDefaultFormats: Format with type [%d] depth [%d] rgb [%d,%d,%d] "
+ "mask rgb [%d,%d,%d] alpha [%d] alpha mask [%d] matches.\n",
+ pFormats[f].type, pFormats[f].depth, pFormats[f].direct.red, pFormats[f].direct.green,
+ pFormats[f].direct.blue, pFormats[f].direct.redMask, pFormats[f].direct.greenMask,
+ pFormats[f].direct.blueMask, pFormats[f].direct.alpha, pFormats[f].direct.alphaMask);
+ #endif
+ }
+ else
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "PictureCreateDefaultFormats: Format with type [%d] depth [%d] rgb [%d,%d,%d] "
+ "mask rgb [%d,%d,%d] alpha [%d] alpha mask [%d] doesn't match.\n",
+ pFormats[f].type, pFormats[f].depth, pFormats[f].direct.red, pFormats[f].direct.green,
+ pFormats[f].direct.blue, pFormats[f].direct.redMask, pFormats[f].direct.greenMask,
+ pFormats[f].direct.blueMask, pFormats[f].direct.alpha, pFormats[f].direct.alphaMask);
+ #endif
+ }
+#endif
+ }
+ *nformatp = nformats;
+ return pFormats;
+}
+
+static VisualPtr
+PictureFindVisual (ScreenPtr pScreen, VisualID visual)
+{
+ int i;
+ VisualPtr pVisual;
+ for (i = 0, pVisual = pScreen->visuals;
+ i < pScreen->numVisuals;
+ i++, pVisual++)
+ {
+ if (pVisual->vid == visual)
+ return pVisual;
+ }
+ return 0;
+}
+
+Bool
+PictureInitIndexedFormats (ScreenPtr pScreen)
+{
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+ PictFormatPtr format;
+ int nformat;
+
+ if (!ps)
+ return FALSE;
+ format = ps->formats;
+ nformat = ps->nformats;
+ while (nformat--)
+ {
+ if (format->type == PictTypeIndexed && !format->index.pColormap)
+ {
+ if (format->index.vid == pScreen->rootVisual)
+ format->index.pColormap = (ColormapPtr) LookupIDByType(pScreen->defColormap,
+ RT_COLORMAP);
+ else
+ {
+ VisualPtr pVisual;
+
+ pVisual = PictureFindVisual (pScreen, format->index.vid);
+ if (CreateColormap (FakeClientID (0), pScreen,
+ pVisual,
+ &format->index.pColormap, AllocNone,
+ 0) != Success)
+ {
+ return FALSE;
+ }
+ }
+ if (!(*ps->InitIndexed) (pScreen, format))
+ return FALSE;
+ }
+ format++;
+ }
+ return TRUE;
+}
+
+Bool
+PictureFinishInit (void)
+{
+ int s;
+
+ for (s = 0; s < screenInfo.numScreens; s++)
+ {
+ if (!PictureInitIndexedFormats (screenInfo.screens[s]))
+ return FALSE;
+ (void) AnimCurInit (screenInfo.screens[s]);
+ }
+
+ return TRUE;
+}
+
+Bool
+PictureSetSubpixelOrder (ScreenPtr pScreen, int subpixel)
+{
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+
+ if (!ps)
+ return FALSE;
+ ps->subpixel = subpixel;
+ return TRUE;
+
+}
+
+int
+PictureGetSubpixelOrder (ScreenPtr pScreen)
+{
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+
+ if (!ps)
+ return SubPixelUnknown;
+ return ps->subpixel;
+}
+
+PictFormatPtr
+PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual)
+{
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+ PictFormatPtr format;
+ int nformat;
+ int type;
+
+ if (!ps)
+ return 0;
+ format = ps->formats;
+ nformat = ps->nformats;
+ switch (pVisual->class) {
+ case StaticGray:
+ case GrayScale:
+ case StaticColor:
+ case PseudoColor:
+ type = PictTypeIndexed;
+ break;
+ case TrueColor:
+ case DirectColor:
+ type = PictTypeDirect;
+ break;
+ default:
+ return 0;
+ }
+ while (nformat--)
+ {
+ if (format->depth == depth && format->type == type)
+ {
+ if (type == PictTypeIndexed)
+ {
+ if (format->index.vid == pVisual->vid)
+ return format;
+ }
+ else
+ {
+ if (format->direct.redMask << format->direct.red ==
+ pVisual->redMask &&
+ format->direct.greenMask << format->direct.green ==
+ pVisual->greenMask &&
+ format->direct.blueMask << format->direct.blue ==
+ pVisual->blueMask)
+ {
+ return format;
+ }
+ }
+ }
+ format++;
+ }
+ return 0;
+}
+
+PictFormatPtr
+PictureMatchFormat (ScreenPtr pScreen, int depth, CARD32 f)
+{
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+ PictFormatPtr format;
+ int nformat;
+
+ if (!ps)
+ return 0;
+ format = ps->formats;
+ nformat = ps->nformats;
+ while (nformat--)
+ {
+ if (format->depth == depth && format->format == (f & 0xffffff))
+ return format;
+ format++;
+ }
+ return 0;
+}
+
+int
+PictureParseCmapPolicy (const char *name)
+{
+ if ( strcmp (name, "default" ) == 0)
+ return PictureCmapPolicyDefault;
+ else if ( strcmp (name, "mono" ) == 0)
+ return PictureCmapPolicyMono;
+ else if ( strcmp (name, "gray" ) == 0)
+ return PictureCmapPolicyGray;
+ else if ( strcmp (name, "color" ) == 0)
+ return PictureCmapPolicyColor;
+ else if ( strcmp (name, "all" ) == 0)
+ return PictureCmapPolicyAll;
+ else
+ return PictureCmapPolicyInvalid;
+}
+
+Bool
+PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
+{
+ PictureScreenPtr ps;
+ int n;
+ CARD32 type, a, r, g, b;
+
+ if (PictureGeneration != serverGeneration)
+ {
+ PictureType = CreateNewResourceType (FreePicture);
+ if (!PictureType)
+ return FALSE;
+ PictFormatType = CreateNewResourceType (FreePictFormat);
+ if (!PictFormatType)
+ return FALSE;
+ GlyphSetType = CreateNewResourceType (FreeGlyphSet);
+ if (!GlyphSetType)
+ return FALSE;
+ PictureScreenPrivateIndex = AllocateScreenPrivateIndex();
+ if (PictureScreenPrivateIndex < 0)
+ return FALSE;
+ PictureWindowPrivateIndex = AllocateWindowPrivateIndex();
+ PictureGeneration = serverGeneration;
+#ifdef XResExtension
+ RegisterResourceName (PictureType, "PICTURE");
+ RegisterResourceName (PictFormatType, "PICTFORMAT");
+ RegisterResourceName (GlyphSetType, "GLYPHSET");
+#endif
+ }
+ if (!AllocateWindowPrivate (pScreen, PictureWindowPrivateIndex, 0))
+ return FALSE;
+
+ if (!formats)
+ {
+ formats = PictureCreateDefaultFormats (pScreen, &nformats);
+ if (!formats)
+ return FALSE;
+ }
+ for (n = 0; n < nformats; n++)
+ {
+ if (!AddResource (formats[n].id, PictFormatType, (pointer) (formats+n)))
+ {
+ xfree (formats);
+ return FALSE;
+ }
+ if (formats[n].type == PictTypeIndexed)
+ {
+ VisualPtr pVisual = PictureFindVisual (pScreen, formats[n].index.vid);
+ if ((pVisual->class | DynamicClass) == PseudoColor)
+ type = PICT_TYPE_COLOR;
+ else
+ type = PICT_TYPE_GRAY;
+ a = r = g = b = 0;
+ }
+ else
+ {
+ if ((formats[n].direct.redMask|
+ formats[n].direct.blueMask|
+ formats[n].direct.greenMask) == 0)
+ type = PICT_TYPE_A;
+ else if (formats[n].direct.red > formats[n].direct.blue)
+ type = PICT_TYPE_ARGB;
+ else
+ type = PICT_TYPE_ABGR;
+ a = Ones (formats[n].direct.alphaMask);
+ r = Ones (formats[n].direct.redMask);
+ g = Ones (formats[n].direct.greenMask);
+ b = Ones (formats[n].direct.blueMask);
+ }
+ formats[n].format = PICT_FORMAT(0,type,a,r,g,b);
+ }
+ ps = (PictureScreenPtr) xalloc (sizeof (PictureScreenRec));
+ if (!ps)
+ {
+ xfree (formats);
+ return FALSE;
+ }
+ SetPictureScreen(pScreen, ps);
+ if (!GlyphInit (pScreen))
+ {
+ SetPictureScreen(pScreen, 0);
+ xfree (formats);
+ xfree (ps);
+ return FALSE;
+ }
+
+ ps->totalPictureSize = sizeof (PictureRec);
+ ps->PicturePrivateSizes = 0;
+ ps->PicturePrivateLen = 0;
+
+ ps->formats = formats;
+ ps->fallback = formats;
+ ps->nformats = nformats;
+
+ ps->filters = 0;
+ ps->nfilters = 0;
+ ps->filterAliases = 0;
+ ps->nfilterAliases = 0;
+
+ ps->subpixel = SubPixelUnknown;
+
+ ps->CloseScreen = pScreen->CloseScreen;
+ ps->DestroyWindow = pScreen->DestroyWindow;
+ ps->StoreColors = pScreen->StoreColors;
+ pScreen->DestroyWindow = PictureDestroyWindow;
+ pScreen->CloseScreen = PictureCloseScreen;
+ pScreen->StoreColors = PictureStoreColors;
+
+ if (!PictureSetDefaultFilters (pScreen))
+ {
+ PictureResetFilters (pScreen);
+ SetPictureScreen(pScreen, 0);
+ xfree (formats);
+ xfree (ps);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void
+SetPictureToDefaults (PicturePtr pPicture)
+{
+ pPicture->refcnt = 1;
+ pPicture->repeat = 0;
+ pPicture->graphicsExposures = FALSE;
+ pPicture->subWindowMode = ClipByChildren;
+ pPicture->polyEdge = PolyEdgeSharp;
+ pPicture->polyMode = PolyModePrecise;
+ pPicture->freeCompClip = FALSE;
+ pPicture->clientClipType = CT_NONE;
+ pPicture->componentAlpha = FALSE;
+ pPicture->repeatType = RepeatNone;
+
+ pPicture->alphaMap = 0;
+ pPicture->alphaOrigin.x = 0;
+ pPicture->alphaOrigin.y = 0;
+
+ pPicture->clipOrigin.x = 0;
+ pPicture->clipOrigin.y = 0;
+ pPicture->clientClip = 0;
+
+ pPicture->transform = 0;
+
+ pPicture->dither = None;
+ pPicture->filter = PictureGetFilterId (FilterNearest, -1, TRUE);
+ pPicture->filter_params = 0;
+ pPicture->filter_nparams = 0;
+
+ pPicture->serialNumber = GC_CHANGE_SERIAL_BIT;
+ pPicture->stateChanges = (1 << (CPLastBit+1)) - 1;
+ pPicture->pSourcePict = 0;
+}
+
+PicturePtr
+AllocatePicture (ScreenPtr pScreen)
+{
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ PicturePtr pPicture;
+ char *ptr;
+ DevUnion *ppriv;
+ unsigned int *sizes;
+ unsigned int size;
+ int i;
+
+ pPicture = (PicturePtr) xalloc (ps->totalPictureSize);
+ if (!pPicture)
+ return 0;
+ ppriv = (DevUnion *)(pPicture + 1);
+ pPicture->devPrivates = ppriv;
+ sizes = ps->PicturePrivateSizes;
+ ptr = (char *)(ppriv + ps->PicturePrivateLen);
+ for (i = ps->PicturePrivateLen; --i >= 0; ppriv++, sizes++)
+ {
+ if ( (size = *sizes) )
+ {
+ ppriv->ptr = (pointer)ptr;
+ ptr += size;
+ }
+ else
+ ppriv->ptr = (pointer)NULL;
+ }
+ return pPicture;
+}
+
+/*
+ * Let picture always point to the virtual pixmap.
+ * For sure this is not the best way to deal with
+ * the virtual frame-buffer.
+ */
+
+#define NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+PicturePtr
+CreatePicture (Picture pid,
+ DrawablePtr pDrawable,
+ PictFormatPtr pFormat,
+ Mask vmask,
+ XID *vlist,
+ ClientPtr client,
+ int *error)
+{
+ PicturePtr pPicture;
+ PictureScreenPtr ps = GetPictureScreen(pDrawable->pScreen);
+
+ pPicture = AllocatePicture (pDrawable->pScreen);
+ if (!pPicture)
+ {
+ *error = BadAlloc;
+ return 0;
+ }
+
+ pPicture->id = pid;
+ pPicture->pDrawable = pDrawable;
+ pPicture->pFormat = pFormat;
+ pPicture->format = pFormat->format | (pDrawable->bitsPerPixel << 24);
+ if (pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ #ifdef NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+ pPicture->pDrawable = nxagentVirtualDrawable(pDrawable);
+
+ #endif
+
+ ++((PixmapPtr)pDrawable)->refcnt;
+ pPicture->pNext = 0;
+ }
+ else
+ {
+ pPicture->pNext = GetPictureWindow(((WindowPtr) pDrawable));
+ SetPictureWindow(((WindowPtr) pDrawable), pPicture);
+ }
+
+ SetPictureToDefaults (pPicture);
+
+ if (vmask)
+ *error = ChangePicture (pPicture, vmask, vlist, 0, client);
+ else
+ *error = Success;
+ if (*error == Success)
+ *error = (*ps->CreatePicture) (pPicture);
+ if (*error != Success)
+ {
+ FreePicture (pPicture, (XID) 0);
+ pPicture = 0;
+ }
+ return pPicture;
+}
+
+static CARD32 xRenderColorToCard32(xRenderColor c)
+{
+ return
+ (c.alpha >> 8 << 24) |
+ (c.red >> 8 << 16) |
+ (c.green & 0xff00) |
+ (c.blue >> 8);
+}
+
+static unsigned int premultiply(unsigned int x)
+{
+ unsigned int a = x >> 24;
+ unsigned int t = (x & 0xff00ff) * a;
+ t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8;
+ t &= 0xff00ff;
+
+ x = ((x >> 8) & 0xff) * a;
+ x = (x + ((x >> 8) & 0xff) + 0x80);
+ x &= 0xff00;
+ x |= t | (a << 24);
+ return x;
+}
+
+static unsigned int INTERPOLATE_PIXEL_256(unsigned int x, unsigned int a,
+ unsigned int y, unsigned int b)
+{
+ CARD32 t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;
+ t >>= 8;
+ t &= 0xff00ff;
+
+ x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;
+ x &= 0xff00ff00;
+ x |= t;
+ return x;
+}
+
+static void initGradientColorTable(SourcePictPtr pGradient, int *error)
+{
+ int begin_pos, end_pos;
+ xFixed incr, dpos;
+ int pos, current_stop;
+ PictGradientStopPtr stops = pGradient->linear.stops;
+ int nstops = pGradient->linear.nstops;
+
+ /* The position where the gradient begins and ends */
+ begin_pos = (stops[0].x * PICT_GRADIENT_STOPTABLE_SIZE) >> 16;
+ end_pos = (stops[nstops - 1].x * PICT_GRADIENT_STOPTABLE_SIZE) >> 16;
+
+ pos = 0; /* The position in the color table. */
+
+ /* Up to first point */
+ while (pos <= begin_pos) {
+ pGradient->linear.colorTable[pos] = xRenderColorToCard32(stops[0].color);
+ ++pos;
+ }
+
+ incr = (1<<16)/ PICT_GRADIENT_STOPTABLE_SIZE; /* the double increment. */
+ dpos = incr * pos; /* The position in terms of 0-1. */
+
+ current_stop = 0; /* We always interpolate between current and current + 1. */
+
+ /* Gradient area */
+ while (pos < end_pos) {
+ unsigned int current_color = xRenderColorToCard32(stops[current_stop].color);
+ unsigned int next_color = xRenderColorToCard32(stops[current_stop + 1].color);
+
+ int dist = (int)(256*(dpos - stops[current_stop].x)
+ / (stops[current_stop+1].x - stops[current_stop].x));
+ int idist = 256 - dist;
+
+ pGradient->linear.colorTable[pos] = premultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
+
+ ++pos;
+ dpos += incr;
+
+ if (dpos > stops[current_stop + 1].x)
+ ++current_stop;
+ }
+
+ /* After last point */
+ while (pos < PICT_GRADIENT_STOPTABLE_SIZE) {
+ pGradient->linear.colorTable[pos] = xRenderColorToCard32(stops[nstops - 1].color);
+ ++pos;
+ }
+}
+
+static void initGradient(SourcePictPtr pGradient, int stopCount,
+ xFixed *stopPoints, xRenderColor *stopColors, int *error)
+{
+ int i;
+ xFixed dpos;
+
+ if (stopCount <= 0) {
+ *error = BadValue;
+ return;
+ }
+
+ dpos = -1;
+ for (i = 0; i < stopCount; ++i) {
+ if (stopPoints[i] <= dpos || stopPoints[i] > (1<<16)) {
+ *error = BadValue;
+ return;
+ }
+ dpos = stopPoints[i];
+ }
+
+ pGradient->linear.stops = xalloc(stopCount*sizeof(PictGradientStop));
+ if (!pGradient->linear.stops) {
+ *error = BadAlloc;
+ return;
+ }
+
+ pGradient->linear.nstops = stopCount;
+
+ for (i = 0; i < stopCount; ++i) {
+ pGradient->linear.stops[i].x = stopPoints[i];
+ pGradient->linear.stops[i].color = stopColors[i];
+ }
+ initGradientColorTable(pGradient, error);
+}
+
+static PicturePtr createSourcePicture(void)
+{
+ PicturePtr pPicture;
+ pPicture = (PicturePtr) xalloc(sizeof(PictureRec));
+ pPicture->pDrawable = 0;
+ pPicture->pFormat = 0;
+ pPicture->pNext = 0;
+
+ SetPictureToDefaults(pPicture);
+ return pPicture;
+}
+
+PicturePtr
+CreateSolidPicture (Picture pid, xRenderColor *color, int *error)
+{
+ PicturePtr pPicture;
+ pPicture = createSourcePicture();
+ if (!pPicture) {
+ *error = BadAlloc;
+ return 0;
+ }
+
+ pPicture->id = pid;
+ pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictSolidFill));
+ if (!pPicture->pSourcePict) {
+ *error = BadAlloc;
+ xfree(pPicture);
+ return 0;
+ }
+ pPicture->pSourcePict->type = SourcePictTypeSolidFill;
+ pPicture->pSourcePict->solidFill.color = xRenderColorToCard32(*color);
+ return pPicture;
+}
+
+PicturePtr
+CreateLinearGradientPicture (Picture pid, xPointFixed *p1, xPointFixed *p2,
+ int nStops, xFixed *stops, xRenderColor *colors, int *error)
+{
+ PicturePtr pPicture;
+
+ if (nStops < 2) {
+ *error = BadValue;
+ return 0;
+ }
+
+ pPicture = createSourcePicture();
+ if (!pPicture) {
+ *error = BadAlloc;
+ return 0;
+ }
+ if (p1->x == p2->x && p1->y == p2->y) {
+ *error = BadValue;
+ return 0;
+ }
+
+ pPicture->id = pid;
+ pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictLinearGradient));
+ if (!pPicture->pSourcePict) {
+ *error = BadAlloc;
+ xfree(pPicture);
+ return 0;
+ }
+
+ pPicture->pSourcePict->linear.type = SourcePictTypeLinear;
+ pPicture->pSourcePict->linear.p1 = *p1;
+ pPicture->pSourcePict->linear.p2 = *p2;
+
+ initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
+ if (*error) {
+ xfree(pPicture);
+ return 0;
+ }
+ return pPicture;
+}
+
+#define FixedToDouble(x) ((x)/65536.)
+
+PicturePtr
+CreateRadialGradientPicture (Picture pid, xPointFixed *inner, xPointFixed *outer,
+ xFixed innerRadius, xFixed outerRadius,
+ int nStops, xFixed *stops, xRenderColor *colors, int *error)
+{
+ PicturePtr pPicture;
+ PictRadialGradient *radial;
+
+ if (nStops < 2) {
+ *error = BadValue;
+ return 0;
+ }
+
+ pPicture = createSourcePicture();
+ if (!pPicture) {
+ *error = BadAlloc;
+ return 0;
+ }
+ {
+ double dx = (double)(inner->x - outer->x);
+ double dy = (double)(inner->y - outer->y);
+ if (sqrt(dx*dx + dy*dy) + (double)(innerRadius) > (double)(outerRadius)) {
+ *error = BadValue;
+ return 0;
+ }
+ }
+
+ pPicture->id = pid;
+ pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictRadialGradient));
+ if (!pPicture->pSourcePict) {
+ *error = BadAlloc;
+ xfree(pPicture);
+ return 0;
+ }
+ radial = &pPicture->pSourcePict->radial;
+
+ radial->type = SourcePictTypeRadial;
+ {
+ double x = (double)innerRadius / (double)outerRadius;
+ radial->dx = (outer->x - inner->x);
+ radial->dy = (outer->y - inner->y);
+ radial->fx = (inner->x) - x*radial->dx;
+ radial->fy = (inner->y) - x*radial->dy;
+ radial->m = 1./(1+x);
+ radial->b = -x*radial->m;
+ radial->dx /= 65536.;
+ radial->dy /= 65536.;
+ radial->fx /= 65536.;
+ radial->fy /= 65536.;
+ x = outerRadius/65536.;
+ radial->a = x*x - radial->dx*radial->dx - radial->dy*radial->dy;
+ }
+
+ initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
+ if (*error) {
+ xfree(pPicture);
+ return 0;
+ }
+ return pPicture;
+}
+
+PicturePtr
+CreateConicalGradientPicture (Picture pid, xPointFixed *center, xFixed angle,
+ int nStops, xFixed *stops, xRenderColor *colors, int *error)
+{
+ PicturePtr pPicture;
+
+ if (nStops < 2) {
+ *error = BadValue;
+ return 0;
+ }
+
+ pPicture = createSourcePicture();
+ if (!pPicture) {
+ *error = BadAlloc;
+ return 0;
+ }
+
+ pPicture->id = pid;
+ pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictConicalGradient));
+ if (!pPicture->pSourcePict) {
+ *error = BadAlloc;
+ xfree(pPicture);
+ return 0;
+ }
+
+ pPicture->pSourcePict->conical.type = SourcePictTypeConical;
+ pPicture->pSourcePict->conical.center = *center;
+ pPicture->pSourcePict->conical.angle = angle;
+
+ initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
+ if (*error) {
+ xfree(pPicture);
+ return 0;
+ }
+ return pPicture;
+}
+
+#define NEXT_VAL(_type) (vlist ? (_type) *vlist++ : (_type) ulist++->val)
+
+#define NEXT_PTR(_type) ((_type) ulist++->ptr)
+
+int
+ChangePicture (PicturePtr pPicture,
+ Mask vmask,
+ XID *vlist,
+ DevUnion *ulist,
+ ClientPtr client)
+{
+ ScreenPtr pScreen = pPicture->pDrawable ? pPicture->pDrawable->pScreen : 0;
+ PictureScreenPtr ps = pScreen ? GetPictureScreen(pScreen) : 0;
+ BITS32 index2;
+ int error = 0;
+ BITS32 maskQ;
+
+ pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ maskQ = vmask;
+ while (vmask && !error)
+ {
+ index2 = (BITS32) lowbit (vmask);
+ vmask &= ~index2;
+ pPicture->stateChanges |= index2;
+ switch (index2)
+ {
+ case CPRepeat:
+ {
+ unsigned int newr;
+ newr = NEXT_VAL(unsigned int);
+ if (newr <= RepeatReflect)
+ {
+ pPicture->repeat = (newr != RepeatNone);
+ pPicture->repeatType = newr;
+ }
+ else
+ {
+ client->errorValue = newr;
+ error = BadValue;
+ }
+ }
+ break;
+ case CPAlphaMap:
+ {
+ PicturePtr pAlpha;
+
+ if (vlist)
+ {
+ Picture pid = NEXT_VAL(Picture);
+
+ if (pid == None)
+ pAlpha = 0;
+ else
+ {
+ pAlpha = (PicturePtr) SecurityLookupIDByType(client,
+ pid,
+ PictureType,
+ SecurityWriteAccess|SecurityReadAccess);
+ if (!pAlpha)
+ {
+ client->errorValue = pid;
+ error = BadPixmap;
+ break;
+ }
+ if (pAlpha->pDrawable->type != DRAWABLE_PIXMAP)
+ {
+ client->errorValue = pid;
+ error = BadMatch;
+ break;
+ }
+ }
+ }
+ else
+ pAlpha = NEXT_PTR(PicturePtr);
+ if (!error)
+ {
+ if (pAlpha && pAlpha->pDrawable->type == DRAWABLE_PIXMAP)
+ pAlpha->refcnt++;
+ if (pPicture->alphaMap)
+ FreePicture ((pointer) pPicture->alphaMap, (XID) 0);
+ pPicture->alphaMap = pAlpha;
+ }
+ }
+ break;
+ case CPAlphaXOrigin:
+ pPicture->alphaOrigin.x = NEXT_VAL(INT16);
+ break;
+ case CPAlphaYOrigin:
+ pPicture->alphaOrigin.y = NEXT_VAL(INT16);
+ break;
+ case CPClipXOrigin:
+ pPicture->clipOrigin.x = NEXT_VAL(INT16);
+ break;
+ case CPClipYOrigin:
+ pPicture->clipOrigin.y = NEXT_VAL(INT16);
+ break;
+ case CPClipMask:
+ {
+ Pixmap pid;
+ PixmapPtr pPixmap;
+ int clipType;
+ if (!pScreen)
+ return BadDrawable;
+
+ if (vlist)
+ {
+ pid = NEXT_VAL(Pixmap);
+ if (pid == None)
+ {
+ clipType = CT_NONE;
+ pPixmap = NullPixmap;
+ }
+ else
+ {
+ clipType = CT_PIXMAP;
+ pPixmap = (PixmapPtr)SecurityLookupIDByType(client,
+ pid,
+ RT_PIXMAP,
+ SecurityReadAccess);
+ if (!pPixmap)
+ {
+ client->errorValue = pid;
+ error = BadPixmap;
+ break;
+ }
+ }
+ }
+ else
+ {
+ pPixmap = NEXT_PTR(PixmapPtr);
+ if (pPixmap)
+ clipType = CT_PIXMAP;
+ else
+ clipType = CT_NONE;
+ }
+
+ if (pPixmap)
+ {
+ if ((pPixmap->drawable.depth != 1) ||
+ (pPixmap->drawable.pScreen != pScreen))
+ {
+ error = BadMatch;
+ break;
+ }
+ else
+ {
+ clipType = CT_PIXMAP;
+ pPixmap->refcnt++;
+ }
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "ChangePicture: Going to call ChangePictureClip with clipType [%d] pPixmap [%p].\n",
+ clipType, (void *) pPixmap);
+ #endif
+
+ error = (*ps->ChangePictureClip)(pPicture, clipType,
+ (pointer)pPixmap, 0);
+ break;
+ }
+ case CPGraphicsExposure:
+ {
+ unsigned int newe;
+ newe = NEXT_VAL(unsigned int);
+ if (newe <= xTrue)
+ pPicture->graphicsExposures = newe;
+ else
+ {
+ client->errorValue = newe;
+ error = BadValue;
+ }
+ }
+ break;
+ case CPSubwindowMode:
+ {
+ unsigned int news;
+ news = NEXT_VAL(unsigned int);
+ if (news == ClipByChildren || news == IncludeInferiors)
+ pPicture->subWindowMode = news;
+ else
+ {
+ client->errorValue = news;
+ error = BadValue;
+ }
+ }
+ break;
+ case CPPolyEdge:
+ {
+ unsigned int newe;
+ newe = NEXT_VAL(unsigned int);
+ if (newe == PolyEdgeSharp || newe == PolyEdgeSmooth)
+ pPicture->polyEdge = newe;
+ else
+ {
+ client->errorValue = newe;
+ error = BadValue;
+ }
+ }
+ break;
+ case CPPolyMode:
+ {
+ unsigned int newm;
+ newm = NEXT_VAL(unsigned int);
+ if (newm == PolyModePrecise || newm == PolyModeImprecise)
+ pPicture->polyMode = newm;
+ else
+ {
+ client->errorValue = newm;
+ error = BadValue;
+ }
+ }
+ break;
+ case CPDither:
+ pPicture->dither = NEXT_VAL(Atom);
+ break;
+ case CPComponentAlpha:
+ {
+ unsigned int newca;
+
+ newca = NEXT_VAL (unsigned int);
+ if (newca <= xTrue)
+ pPicture->componentAlpha = newca;
+ else
+ {
+ client->errorValue = newca;
+ error = BadValue;
+ }
+ }
+ break;
+ default:
+ client->errorValue = maskQ;
+ error = BadValue;
+ break;
+ }
+ }
+ if (ps)
+ (*ps->ChangePicture) (pPicture, maskQ);
+ return error;
+}
+
+int
+SetPictureClipRects (PicturePtr pPicture,
+ int xOrigin,
+ int yOrigin,
+ int nRect,
+ xRectangle *rects)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ RegionPtr clientClip;
+ int result;
+
+ clientClip = RECTS_TO_REGION(pScreen,
+ nRect, rects, CT_UNSORTED);
+ if (!clientClip)
+ return BadAlloc;
+ result =(*ps->ChangePictureClip) (pPicture, CT_REGION,
+ (pointer) clientClip, 0);
+ if (result == Success)
+ {
+ pPicture->clipOrigin.x = xOrigin;
+ pPicture->clipOrigin.y = yOrigin;
+ pPicture->stateChanges |= CPClipXOrigin|CPClipYOrigin|CPClipMask;
+ pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ }
+ return result;
+}
+
+int
+SetPictureClipRegion (PicturePtr pPicture,
+ int xOrigin,
+ int yOrigin,
+ RegionPtr pRegion)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ RegionPtr clientClip;
+ int result;
+ int type;
+
+ if (pRegion)
+ {
+ type = CT_REGION;
+ clientClip = REGION_CREATE (pScreen,
+ REGION_EXTENTS(pScreen, pRegion),
+ REGION_NUM_RECTS(pRegion));
+ if (!clientClip)
+ return BadAlloc;
+ if (!REGION_COPY (pSCreen, clientClip, pRegion))
+ {
+ REGION_DESTROY (pScreen, clientClip);
+ return BadAlloc;
+ }
+ }
+ else
+ {
+ type = CT_NONE;
+ clientClip = 0;
+ }
+
+ result =(*ps->ChangePictureClip) (pPicture, type,
+ (pointer) clientClip, 0);
+ if (result == Success)
+ {
+ pPicture->clipOrigin.x = xOrigin;
+ pPicture->clipOrigin.y = yOrigin;
+ pPicture->stateChanges |= CPClipXOrigin|CPClipYOrigin|CPClipMask;
+ pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ }
+ return result;
+}
+
+
+int
+SetPictureTransform (PicturePtr pPicture,
+ PictTransform *transform)
+{
+ static const PictTransform identity = { {
+ { xFixed1, 0x00000, 0x00000 },
+ { 0x00000, xFixed1, 0x00000 },
+ { 0x00000, 0x00000, xFixed1 },
+ } };
+
+ if (transform && memcmp (transform, &identity, sizeof (PictTransform)) == 0)
+ transform = 0;
+
+ if (transform)
+ {
+ if (!pPicture->transform)
+ {
+ pPicture->transform = (PictTransform *) xalloc (sizeof (PictTransform));
+ if (!pPicture->transform)
+ return BadAlloc;
+ }
+ *pPicture->transform = *transform;
+ }
+ else
+ {
+ if (pPicture->transform)
+ {
+ xfree (pPicture->transform);
+ pPicture->transform = 0;
+ }
+ }
+ pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+
+ return Success;
+}
+
+void
+CopyPicture (PicturePtr pSrc,
+ Mask mask,
+ PicturePtr pDst)
+{
+ PictureScreenPtr ps = GetPictureScreen(pSrc->pDrawable->pScreen);
+ Mask origMask = mask;
+
+ pDst->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ pDst->stateChanges |= mask;
+
+ while (mask) {
+ Mask bit = lowbit(mask);
+
+ switch (bit)
+ {
+ case CPRepeat:
+ pDst->repeat = pSrc->repeat;
+ pDst->repeatType = pSrc->repeatType;
+ break;
+ case CPAlphaMap:
+ if (pSrc->alphaMap && pSrc->alphaMap->pDrawable->type == DRAWABLE_PIXMAP)
+ pSrc->alphaMap->refcnt++;
+ if (pDst->alphaMap)
+ FreePicture ((pointer) pDst->alphaMap, (XID) 0);
+ pDst->alphaMap = pSrc->alphaMap;
+ break;
+ case CPAlphaXOrigin:
+ pDst->alphaOrigin.x = pSrc->alphaOrigin.x;
+ break;
+ case CPAlphaYOrigin:
+ pDst->alphaOrigin.y = pSrc->alphaOrigin.y;
+ break;
+ case CPClipXOrigin:
+ pDst->clipOrigin.x = pSrc->clipOrigin.x;
+ break;
+ case CPClipYOrigin:
+ pDst->clipOrigin.y = pSrc->clipOrigin.y;
+ break;
+ case CPClipMask:
+ switch (pSrc->clientClipType) {
+ case CT_NONE:
+ (*ps->ChangePictureClip)(pDst, CT_NONE, NULL, 0);
+ break;
+ case CT_REGION:
+ if (!pSrc->clientClip) {
+ (*ps->ChangePictureClip)(pDst, CT_NONE, NULL, 0);
+ } else {
+ RegionPtr clientClip;
+ RegionPtr srcClientClip = (RegionPtr)pSrc->clientClip;
+
+ clientClip = REGION_CREATE(pSrc->pDrawable->pScreen,
+ REGION_EXTENTS(pSrc->pDrawable->pScreen, srcClientClip),
+ REGION_NUM_RECTS(srcClientClip));
+ (*ps->ChangePictureClip)(pDst, CT_REGION, clientClip, 0);
+ }
+ break;
+ default:
+ /* XXX: CT_PIXMAP unimplemented */
+ break;
+ }
+ break;
+ case CPGraphicsExposure:
+ pDst->graphicsExposures = pSrc->graphicsExposures;
+ break;
+ case CPPolyEdge:
+ pDst->polyEdge = pSrc->polyEdge;
+ break;
+ case CPPolyMode:
+ pDst->polyMode = pSrc->polyMode;
+ break;
+ case CPDither:
+ pDst->dither = pSrc->dither;
+ break;
+ case CPComponentAlpha:
+ pDst->componentAlpha = pSrc->componentAlpha;
+ break;
+ }
+ mask &= ~bit;
+ }
+
+ (*ps->ChangePicture)(pDst, origMask);
+}
+
+static void
+ValidateOnePicture (PicturePtr pPicture)
+{
+ if (pPicture->pDrawable && pPicture->serialNumber != pPicture->pDrawable->serialNumber)
+ {
+ PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen);
+
+ (*ps->ValidatePicture) (pPicture, pPicture->stateChanges);
+ pPicture->stateChanges = 0;
+ pPicture->serialNumber = pPicture->pDrawable->serialNumber;
+ }
+}
+
+void
+ValidatePicture(PicturePtr pPicture)
+{
+ ValidateOnePicture (pPicture);
+ if (pPicture->alphaMap)
+ ValidateOnePicture (pPicture->alphaMap);
+}
+
+int
+FreePicture (pointer value,
+ XID pid)
+{
+ PicturePtr pPicture = (PicturePtr) value;
+
+ if (--pPicture->refcnt == 0)
+ {
+ if (pPicture->transform)
+ xfree (pPicture->transform);
+ if (!pPicture->pDrawable) {
+ if (pPicture->pSourcePict) {
+ if (pPicture->pSourcePict->type != SourcePictTypeSolidFill)
+ xfree(pPicture->pSourcePict->linear.stops);
+ xfree(pPicture->pSourcePict);
+ }
+ } else {
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+
+ if (pPicture->alphaMap)
+ FreePicture ((pointer) pPicture->alphaMap, (XID) 0);
+ (*ps->DestroyPicture) (pPicture);
+ (*ps->DestroyPictureClip) (pPicture);
+ if (pPicture->pDrawable->type == DRAWABLE_WINDOW)
+ {
+ WindowPtr pWindow = (WindowPtr) pPicture->pDrawable;
+ PicturePtr *pPrev;
+
+ for (pPrev = (PicturePtr *) &((pWindow)->devPrivates[PictureWindowPrivateIndex].ptr);
+ *pPrev;
+ pPrev = &(*pPrev)->pNext)
+ {
+ if (*pPrev == pPicture)
+ {
+ *pPrev = pPicture->pNext;
+ break;
+ }
+ }
+ }
+ else if (pPicture->pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ (*pScreen->DestroyPixmap) ((PixmapPtr)pPicture->pDrawable);
+ }
+ }
+ xfree (pPicture);
+ }
+ return Success;
+}
+
+int
+FreePictFormat (pointer pPictFormat,
+ XID pid)
+{
+ return Success;
+}
+
+void
+CompositePicture (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
+ ValidatePicture (pSrc);
+ if (pMask)
+ ValidatePicture (pMask);
+ ValidatePicture (pDst);
+ (*ps->Composite) (op,
+ pSrc,
+ pMask,
+ pDst,
+ xSrc,
+ ySrc,
+ xMask,
+ yMask,
+ xDst,
+ yDst,
+ width,
+ height);
+}
+
+void
+CompositeGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr lists,
+ GlyphPtr *glyphs)
+{
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
+ ValidatePicture (pSrc);
+ ValidatePicture (pDst);
+
+ #ifdef TEST
+ fprintf(stderr, "CompositeGlyphs: Going to composite glyphs with "
+ "source at [%p] and destination at [%p].\n",
+ (void *) pSrc, (void *) pDst);
+ #endif
+
+ (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, lists, glyphs);
+}
+
+void
+CompositeRects (CARD8 op,
+ PicturePtr pDst,
+ xRenderColor *color,
+ int nRect,
+ xRectangle *rects)
+{
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
+ ValidatePicture (pDst);
+ (*ps->CompositeRects) (op, pDst, color, nRect, rects);
+}
+
+void
+CompositeTrapezoids (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntrap,
+ xTrapezoid *traps)
+{
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
+ ValidatePicture (pSrc);
+ ValidatePicture (pDst);
+ (*ps->Trapezoids) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntrap, traps);
+}
+
+void
+CompositeTriangles (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntriangles,
+ xTriangle *triangles)
+{
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
+ ValidatePicture (pSrc);
+ ValidatePicture (pDst);
+ (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntriangles, triangles);
+}
+
+void
+CompositeTriStrip (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoints,
+ xPointFixed *points)
+{
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
+ ValidatePicture (pSrc);
+ ValidatePicture (pDst);
+ (*ps->TriStrip) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
+}
+
+void
+CompositeTriFan (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoints,
+ xPointFixed *points)
+{
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
+ ValidatePicture (pSrc);
+ ValidatePicture (pDst);
+ (*ps->TriFan) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
+}
+
+void
+AddTraps (PicturePtr pPicture,
+ INT16 xOff,
+ INT16 yOff,
+ int ntrap,
+ xTrap *traps)
+{
+ PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen);
+
+ ValidatePicture (pPicture);
+ (*ps->AddTraps) (pPicture, xOff, yOff, ntrap, traps);
+}
+
+#define MAX_FIXED_48_16 ((xFixed_48_16) 0x7fffffff)
+#define MIN_FIXED_48_16 (-((xFixed_48_16) 1 << 31))
+
+Bool
+PictureTransformPoint3d (PictTransformPtr transform,
+ PictVectorPtr vector)
+{
+ PictVector result;
+ int i, j;
+ xFixed_32_32 partial;
+ xFixed_48_16 v;
+
+ for (j = 0; j < 3; j++)
+ {
+ v = 0;
+ for (i = 0; i < 3; i++)
+ {
+ partial = ((xFixed_48_16) transform->matrix[j][i] *
+ (xFixed_48_16) vector->vector[i]);
+ v += partial >> 16;
+ }
+ if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
+ return FALSE;
+ result.vector[j] = (xFixed) v;
+ }
+ if (!result.vector[2])
+ return FALSE;
+ *vector = result;
+ return TRUE;
+}
+
+
+Bool
+PictureTransformPoint (PictTransformPtr transform,
+ PictVectorPtr vector)
+{
+ PictVector result;
+ int i, j;
+ xFixed_32_32 partial;
+ xFixed_48_16 v;
+
+ for (j = 0; j < 3; j++)
+ {
+ v = 0;
+ for (i = 0; i < 3; i++)
+ {
+ partial = ((xFixed_48_16) transform->matrix[j][i] *
+ (xFixed_48_16) vector->vector[i]);
+ v += partial >> 16;
+ }
+ if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
+ return FALSE;
+ result.vector[j] = (xFixed) v;
+ }
+ if (!result.vector[2])
+ return FALSE;
+ for (j = 0; j < 2; j++)
+ {
+ partial = (xFixed_48_16) result.vector[j] << 16;
+ v = partial / result.vector[2];
+ if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
+ return FALSE;
+ vector->vector[j] = (xFixed) v;
+ }
+ vector->vector[2] = xFixed1;
+ return TRUE;
+}
+
+#ifndef True
+# define True 1
+#endif
+
+#ifndef False
+# define False 0
+#endif
+
+void nxagentReconnectPictFormat(void*, XID, void*);
+
+Bool nxagentReconnectAllPictFormat(void *p)
+{
+ PictFormatPtr formats_old, formats;
+ int nformats, nformats_old;
+ VisualPtr pVisual;
+ Bool success = True;
+ Bool matched;
+ int i, n;
+ CARD32 type, a, r, g, b;
+
+ #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_PICTFORMAT_DEBUG)
+ fprintf(stderr, "nxagentReconnectAllPictFormat\n");
+ #endif
+
+ formats_old = GetPictureScreen(nxagentDefaultScreen) -> formats;
+ nformats_old = GetPictureScreen(nxagentDefaultScreen) -> nformats;
+
+ /*
+ * TODO: We could copy PictureCreateDefaultFormats,
+ * in order not to waste ID with FakeClientID().
+ */
+ formats = PictureCreateDefaultFormats (nxagentDefaultScreen, &nformats);
+
+ if (!formats)
+ return False;
+
+ for (n = 0; n < nformats; n++)
+ {
+ if (formats[n].type == PictTypeIndexed)
+ {
+ pVisual = nxagentVisualFromID(nxagentDefaultScreen, formats[n].index.vid);
+
+ if ((pVisual->class | DynamicClass) == PseudoColor)
+ type = PICT_TYPE_COLOR;
+ else
+ type = PICT_TYPE_GRAY;
+ a = r = g = b = 0;
+ }
+ else
+ {
+ if ((formats[n].direct.redMask|
+ formats[n].direct.blueMask|
+ formats[n].direct.greenMask) == 0)
+ type = PICT_TYPE_A;
+ else if (formats[n].direct.red > formats[n].direct.blue)
+ type = PICT_TYPE_ARGB;
+ else
+ type = PICT_TYPE_ABGR;
+ a = Ones (formats[n].direct.alphaMask);
+ r = Ones (formats[n].direct.redMask);
+ g = Ones (formats[n].direct.greenMask);
+ b = Ones (formats[n].direct.blueMask);
+ }
+ formats[n].format = PICT_FORMAT(0,type,a,r,g,b);
+ }
+
+ for (n = 0; n < nformats_old; n++)
+ {
+ for (i = 0, matched = False; (!matched) && (i < nformats); i++)
+ {
+ if (formats_old[n].format == formats[i].format &&
+ formats_old[n].type == formats[i].type &&
+ formats_old[n].direct.red == formats[i].direct.red &&
+ formats_old[n].direct.green == formats[i].direct.green &&
+ formats_old[n].direct.blue == formats[i].direct.blue &&
+ formats_old[n].direct.redMask == formats[i].direct.redMask &&
+ formats_old[n].direct.greenMask == formats[i].direct.greenMask &&
+ formats_old[n].direct.blueMask == formats[i].direct.blueMask &&
+ formats_old[n].direct.alpha == formats[i].direct.alpha &&
+ formats_old[n].direct.alphaMask == formats[i].direct.alphaMask)
+ {
+ /*
+ * Regard depth 16 and 15 as were the same, if all other values match.
+ */
+
+ if ((formats_old[n].depth == formats[i].depth) ||
+ ((formats_old[n].depth == 15 || formats_old[n].depth == 16) &&
+ (formats[i].depth == 15 || formats[i].depth == 16)))
+ {
+ matched = True;
+ }
+ }
+ }
+
+ if (!matched)
+ {
+ return False;
+ }
+ }
+
+ xfree(formats);
+
+ /* TODO: Perhaps do i have to do PictureFinishInit ?. */
+ /* TODO: We have to check for new Render protocol version. */
+
+ for (i = 0; (i < MAXCLIENTS) && (success); i++)
+ {
+ if (clients[i])
+ {
+ FindClientResourcesByType(clients[i], PictFormatType, nxagentReconnectPictFormat, &success);
+ }
+ }
+
+ return success;
+}
+
+/*
+ * It seem we don't have nothing
+ * to do for reconnect PictureFormat.
+ */
+
+void nxagentReconnectPictFormat(void *p0, XID x1, void *p2)
+{
+ PictFormatPtr pFormat;
+ Bool *pBool;
+
+ pFormat = (PictFormatPtr)p0;
+ pBool = (Bool*)p2;
+
+ #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_PICTFORMAT_DEBUG)
+ fprintf(stderr, "nxagentReconnectPictFormat.\n");
+ #endif
+}
+
+/*
+ * The set of picture formats may change considerably
+ * between different X servers. This poses a problem
+ * while migrating NX sessions, because a requisite to
+ * successfully reconnect the session is that all pic-
+ * ture formats have to be available on the new X server.
+ * To reduce such problems, we use a limited set of
+ * pictures available on the most X servers.
+ */
+
+void nxagentPictureCreateDefaultFormats(ScreenPtr pScreen, FormatInitRec *formats, int *nformats)
+{
+ DepthPtr pDepth;
+ VisualPtr pVisual;
+
+ CARD32 format;
+ CARD8 depth;
+
+ int r, g, b;
+ int bpp;
+ int d;
+ int v;
+
+
+ formats[*nformats].format = PICT_a1;
+ formats[*nformats].depth = 1;
+ *nformats += 1;
+ formats[*nformats].format = PICT_a4;
+ formats[*nformats].depth = 4;
+ *nformats += 1;
+ formats[*nformats].format = PICT_a8;
+ formats[*nformats].depth = 8;
+ *nformats += 1;
+ formats[*nformats].format = PICT_a8r8g8b8;
+ formats[*nformats].depth = 32;
+ *nformats += 1;
+
+ /*
+ * This format should be required by the
+ * protocol, but it's not used by Xgl.
+ *
+ * formats[*nformats].format = PICT_x8r8g8b8;
+ * formats[*nformats].depth = 32;
+ * *nformats += 1;
+ */
+
+ /* now look through the depths and visuals adding other formats */
+ for (v = 0; v < pScreen->numVisuals; v++)
+ {
+ pVisual = &pScreen->visuals[v];
+ depth = visualDepth (pScreen, pVisual);
+ if (!depth)
+ continue;
+
+ bpp = BitsPerPixel (depth);
+
+ switch (pVisual->class)
+ {
+ case DirectColor:
+ case TrueColor:
+ r = Ones (pVisual->redMask);
+ g = Ones (pVisual->greenMask);
+ b = Ones (pVisual->blueMask);
+
+ if (pVisual->offsetBlue == 0 &&
+ pVisual->offsetGreen == b &&
+ pVisual->offsetRed == b + g)
+ {
+ format = PICT_FORMAT(bpp, PICT_TYPE_ARGB, 0, r, g, b);
+ *nformats = addFormat (formats, *nformats, format, depth);
+ }
+ break;
+ case StaticColor:
+ case PseudoColor:
+ case StaticGray:
+ case GrayScale:
+ break;
+ }
+ }
+
+ for (d = 0; d < pScreen -> numDepths; d++)
+ {
+ pDepth = &pScreen -> allowedDepths[d];
+ bpp = BitsPerPixel(pDepth -> depth);
+
+ switch (bpp) {
+ case 16:
+ if (pDepth->depth == 15)
+ {
+ *nformats = addFormat (formats, *nformats,
+ PICT_x1r5g5b5, pDepth->depth);
+ }
+
+ if (pDepth->depth == 16)
+ {
+ *nformats = addFormat (formats, *nformats,
+ PICT_r5g6b5, pDepth->depth);
+ }
+ break;
+ case 24:
+ if (pDepth->depth == 24)
+ {
+ *nformats = addFormat (formats, *nformats,
+ PICT_r8g8b8, pDepth->depth);
+ }
+ break;
+ case 32:
+ if (pDepth->depth == 24)
+ {
+ *nformats = addFormat (formats, *nformats,
+ PICT_x8r8g8b8, pDepth->depth);
+ }
+ break;
+ }
+ }
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.X.original
new file mode 100644
index 000000000..3ed60310e
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.X.original
@@ -0,0 +1,1864 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/picture.c,v 1.29 2002/11/23 02:38:15 keithp Exp $
+ *
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+#include "picturestr.h"
+
+int PictureScreenPrivateIndex = -1;
+int PictureWindowPrivateIndex;
+int PictureGeneration;
+RESTYPE PictureType;
+RESTYPE PictFormatType;
+RESTYPE GlyphSetType;
+int PictureCmapPolicy = PictureCmapPolicyDefault;
+
+/* Picture Private machinery */
+
+static int picturePrivateCount;
+
+void
+ResetPicturePrivateIndex (void)
+{
+ picturePrivateCount = 0;
+}
+
+int
+AllocatePicturePrivateIndex (void)
+{
+ return picturePrivateCount++;
+}
+
+Bool
+AllocatePicturePrivate (ScreenPtr pScreen, int index2, unsigned int amount)
+{
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ unsigned int oldamount;
+
+ /* Round up sizes for proper alignment */
+ amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
+
+ if (index2 >= ps->PicturePrivateLen)
+ {
+ unsigned int *nsizes;
+
+ nsizes = (unsigned int *)xrealloc(ps->PicturePrivateSizes,
+ (index2 + 1) * sizeof(unsigned int));
+ if (!nsizes)
+ return FALSE;
+ while (ps->PicturePrivateLen <= index2)
+ {
+ nsizes[ps->PicturePrivateLen++] = 0;
+ ps->totalPictureSize += sizeof(DevUnion);
+ }
+ ps->PicturePrivateSizes = nsizes;
+ }
+ oldamount = ps->PicturePrivateSizes[index2];
+ if (amount > oldamount)
+ {
+ ps->PicturePrivateSizes[index2] = amount;
+ ps->totalPictureSize += (amount - oldamount);
+ }
+
+ return TRUE;
+}
+
+
+Bool
+PictureDestroyWindow (WindowPtr pWindow)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ PicturePtr pPicture;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ Bool ret;
+
+ while ((pPicture = GetPictureWindow(pWindow)))
+ {
+ SetPictureWindow(pWindow, pPicture->pNext);
+ if (pPicture->id)
+ FreeResource (pPicture->id, PictureType);
+ FreePicture ((pointer) pPicture, pPicture->id);
+ }
+ pScreen->DestroyWindow = ps->DestroyWindow;
+ ret = (*pScreen->DestroyWindow) (pWindow);
+ ps->DestroyWindow = pScreen->DestroyWindow;
+ pScreen->DestroyWindow = PictureDestroyWindow;
+ return ret;
+}
+
+Bool
+PictureCloseScreen (int index, ScreenPtr pScreen)
+{
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ Bool ret;
+ int n;
+
+ pScreen->CloseScreen = ps->CloseScreen;
+ ret = (*pScreen->CloseScreen) (index, pScreen);
+ PictureResetFilters (pScreen);
+ for (n = 0; n < ps->nformats; n++)
+ if (ps->formats[n].type == PictTypeIndexed)
+ (*ps->CloseIndexed) (pScreen, &ps->formats[n]);
+ SetPictureScreen(pScreen, 0);
+ if (ps->PicturePrivateSizes)
+ xfree (ps->PicturePrivateSizes);
+ xfree (ps->formats);
+ xfree (ps);
+ return ret;
+}
+
+void
+PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef)
+{
+ ScreenPtr pScreen = pColormap->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+
+ pScreen->StoreColors = ps->StoreColors;
+ (*pScreen->StoreColors) (pColormap, ndef, pdef);
+ ps->StoreColors = pScreen->StoreColors;
+ pScreen->StoreColors = PictureStoreColors;
+
+ if (pColormap->class == PseudoColor || pColormap->class == GrayScale)
+ {
+ PictFormatPtr format = ps->formats;
+ int nformats = ps->nformats;
+
+ while (nformats--)
+ {
+ if (format->type == PictTypeIndexed &&
+ format->index.pColormap == pColormap)
+ {
+ (*ps->UpdateIndexed) (pScreen, format, ndef, pdef);
+ break;
+ }
+ format++;
+ }
+ }
+}
+
+static int
+visualDepth (ScreenPtr pScreen, VisualPtr pVisual)
+{
+ int d, v;
+ DepthPtr pDepth;
+
+ for (d = 0; d < pScreen->numDepths; d++)
+ {
+ pDepth = &pScreen->allowedDepths[d];
+ for (v = 0; v < pDepth->numVids; v++)
+ if (pDepth->vids[v] == pVisual->vid)
+ return pDepth->depth;
+ }
+ return 0;
+}
+
+typedef struct _formatInit {
+ CARD32 format;
+ CARD8 depth;
+} FormatInitRec, *FormatInitPtr;
+
+static int
+addFormat (FormatInitRec formats[256],
+ int nformat,
+ CARD32 format,
+ CARD8 depth)
+{
+ int n;
+
+ for (n = 0; n < nformat; n++)
+ if (formats[n].format == format && formats[n].depth == depth)
+ return nformat;
+ formats[nformat].format = format;
+ formats[nformat].depth = depth;
+ return ++nformat;
+}
+
+#define Mask(n) ((n) == 32 ? 0xffffffff : ((1 << (n))-1))
+
+PictFormatPtr
+PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
+{
+ int nformats, f;
+ PictFormatPtr pFormats;
+ FormatInitRec formats[1024];
+ CARD32 format;
+ CARD8 depth;
+ VisualPtr pVisual;
+ int v;
+ int bpp;
+ int type;
+ int r, g, b;
+ int d;
+ DepthPtr pDepth;
+
+ nformats = 0;
+ /* formats required by protocol */
+ formats[nformats].format = PICT_a1;
+ formats[nformats].depth = 1;
+ nformats++;
+ formats[nformats].format = PICT_a8;
+ formats[nformats].depth = 8;
+ nformats++;
+ formats[nformats].format = PICT_a4;
+ formats[nformats].depth = 4;
+ nformats++;
+ formats[nformats].format = PICT_a8r8g8b8;
+ formats[nformats].depth = 32;
+ nformats++;
+ formats[nformats].format = PICT_x8r8g8b8;
+ formats[nformats].depth = 32;
+ nformats++;
+
+ /* now look through the depths and visuals adding other formats */
+ for (v = 0; v < pScreen->numVisuals; v++)
+ {
+ pVisual = &pScreen->visuals[v];
+ depth = visualDepth (pScreen, pVisual);
+ if (!depth)
+ continue;
+ bpp = BitsPerPixel (depth);
+ switch (pVisual->class) {
+ case DirectColor:
+ case TrueColor:
+ r = Ones (pVisual->redMask);
+ g = Ones (pVisual->greenMask);
+ b = Ones (pVisual->blueMask);
+ type = PICT_TYPE_OTHER;
+ /*
+ * Current rendering code supports only two direct formats,
+ * fields must be packed together at the bottom of the pixel
+ * and must be either RGB or BGR
+ */
+ if (pVisual->offsetBlue == 0 &&
+ pVisual->offsetGreen == b &&
+ pVisual->offsetRed == b + g)
+ {
+ type = PICT_TYPE_ARGB;
+ }
+ else if (pVisual->offsetRed == 0 &&
+ pVisual->offsetGreen == r &&
+ pVisual->offsetBlue == r + g)
+ {
+ type = PICT_TYPE_ABGR;
+ }
+ if (type != PICT_TYPE_OTHER)
+ {
+ format = PICT_FORMAT(bpp, type, 0, r, g, b);
+ nformats = addFormat (formats, nformats, format, depth);
+ }
+ break;
+ case StaticColor:
+ case PseudoColor:
+ format = PICT_VISFORMAT (bpp, PICT_TYPE_COLOR, v);
+ nformats = addFormat (formats, nformats, format, depth);
+ break;
+ case StaticGray:
+ case GrayScale:
+ format = PICT_VISFORMAT (bpp, PICT_TYPE_GRAY, v);
+ nformats = addFormat (formats, nformats, format, depth);
+ break;
+ }
+ }
+ /*
+ * Walk supported depths and add useful Direct formats
+ */
+ for (d = 0; d < pScreen->numDepths; d++)
+ {
+ pDepth = &pScreen->allowedDepths[d];
+ bpp = BitsPerPixel (pDepth->depth);
+ format = 0;
+ switch (bpp) {
+ case 16:
+ /* depth 12 formats */
+ if (pDepth->depth >= 12)
+ {
+ nformats = addFormat (formats, nformats,
+ PICT_x4r4g4b4, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_x4b4g4r4, pDepth->depth);
+ }
+ /* depth 15 formats */
+ if (pDepth->depth >= 15)
+ {
+ nformats = addFormat (formats, nformats,
+ PICT_x1r5g5b5, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_x1b5g5r5, pDepth->depth);
+ }
+ /* depth 16 formats */
+ if (pDepth->depth >= 16)
+ {
+ nformats = addFormat (formats, nformats,
+ PICT_a1r5g5b5, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_a1b5g5r5, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_r5g6b5, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_b5g6r5, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_a4r4g4b4, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_a4b4g4r4, pDepth->depth);
+ }
+ break;
+ case 24:
+ if (pDepth->depth >= 24)
+ {
+ nformats = addFormat (formats, nformats,
+ PICT_r8g8b8, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_b8g8r8, pDepth->depth);
+ }
+ break;
+ case 32:
+ if (pDepth->depth >= 24)
+ {
+ nformats = addFormat (formats, nformats,
+ PICT_x8r8g8b8, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_x8b8g8r8, pDepth->depth);
+ }
+ break;
+ }
+ }
+
+
+ pFormats = (PictFormatPtr) xalloc (nformats * sizeof (PictFormatRec));
+ if (!pFormats)
+ return 0;
+ memset (pFormats, '\0', nformats * sizeof (PictFormatRec));
+ for (f = 0; f < nformats; f++)
+ {
+ pFormats[f].id = FakeClientID (0);
+ pFormats[f].depth = formats[f].depth;
+ format = formats[f].format;
+ pFormats[f].format = format;
+ switch (PICT_FORMAT_TYPE(format)) {
+ case PICT_TYPE_ARGB:
+ pFormats[f].type = PictTypeDirect;
+
+ pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+ if (pFormats[f].direct.alphaMask)
+ pFormats[f].direct.alpha = (PICT_FORMAT_R(format) +
+ PICT_FORMAT_G(format) +
+ PICT_FORMAT_B(format));
+
+ pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
+ pFormats[f].direct.red = (PICT_FORMAT_G(format) +
+ PICT_FORMAT_B(format));
+
+ pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
+ pFormats[f].direct.green = PICT_FORMAT_B(format);
+
+ pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
+ pFormats[f].direct.blue = 0;
+ break;
+
+ case PICT_TYPE_ABGR:
+ pFormats[f].type = PictTypeDirect;
+
+ pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+ if (pFormats[f].direct.alphaMask)
+ pFormats[f].direct.alpha = (PICT_FORMAT_B(format) +
+ PICT_FORMAT_G(format) +
+ PICT_FORMAT_R(format));
+
+ pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
+ pFormats[f].direct.blue = (PICT_FORMAT_G(format) +
+ PICT_FORMAT_R(format));
+
+ pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
+ pFormats[f].direct.green = PICT_FORMAT_R(format);
+
+ pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
+ pFormats[f].direct.red = 0;
+ break;
+
+ case PICT_TYPE_A:
+ pFormats[f].type = PictTypeDirect;
+
+ pFormats[f].direct.alpha = 0;
+ pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+
+ /* remaining fields already set to zero */
+ break;
+
+ case PICT_TYPE_COLOR:
+ case PICT_TYPE_GRAY:
+ pFormats[f].type = PictTypeIndexed;
+ pFormats[f].index.vid = pScreen->visuals[PICT_FORMAT_VIS(format)].vid;
+ break;
+ }
+ }
+ *nformatp = nformats;
+ return pFormats;
+}
+
+static VisualPtr
+PictureFindVisual (ScreenPtr pScreen, VisualID visual)
+{
+ int i;
+ VisualPtr pVisual;
+ for (i = 0, pVisual = pScreen->visuals;
+ i < pScreen->numVisuals;
+ i++, pVisual++)
+ {
+ if (pVisual->vid == visual)
+ return pVisual;
+ }
+ return 0;
+}
+
+Bool
+PictureInitIndexedFormats (ScreenPtr pScreen)
+{
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+ PictFormatPtr format;
+ int nformat;
+
+ if (!ps)
+ return FALSE;
+ format = ps->formats;
+ nformat = ps->nformats;
+ while (nformat--)
+ {
+ if (format->type == PictTypeIndexed && !format->index.pColormap)
+ {
+ if (format->index.vid == pScreen->rootVisual)
+ format->index.pColormap = (ColormapPtr) LookupIDByType(pScreen->defColormap,
+ RT_COLORMAP);
+ else
+ {
+ VisualPtr pVisual;
+
+ pVisual = PictureFindVisual (pScreen, format->index.vid);
+ if (CreateColormap (FakeClientID (0), pScreen,
+ pVisual,
+ &format->index.pColormap, AllocNone,
+ 0) != Success)
+ {
+ return FALSE;
+ }
+ }
+ if (!(*ps->InitIndexed) (pScreen, format))
+ return FALSE;
+ }
+ format++;
+ }
+ return TRUE;
+}
+
+Bool
+PictureFinishInit (void)
+{
+ int s;
+
+ for (s = 0; s < screenInfo.numScreens; s++)
+ {
+ if (!PictureInitIndexedFormats (screenInfo.screens[s]))
+ return FALSE;
+ (void) AnimCurInit (screenInfo.screens[s]);
+ }
+
+ return TRUE;
+}
+
+Bool
+PictureSetSubpixelOrder (ScreenPtr pScreen, int subpixel)
+{
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+
+ if (!ps)
+ return FALSE;
+ ps->subpixel = subpixel;
+ return TRUE;
+
+}
+
+int
+PictureGetSubpixelOrder (ScreenPtr pScreen)
+{
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+
+ if (!ps)
+ return SubPixelUnknown;
+ return ps->subpixel;
+}
+
+PictFormatPtr
+PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual)
+{
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+ PictFormatPtr format;
+ int nformat;
+ int type;
+
+ if (!ps)
+ return 0;
+ format = ps->formats;
+ nformat = ps->nformats;
+ switch (pVisual->class) {
+ case StaticGray:
+ case GrayScale:
+ case StaticColor:
+ case PseudoColor:
+ type = PictTypeIndexed;
+ break;
+ case TrueColor:
+ case DirectColor:
+ type = PictTypeDirect;
+ break;
+ default:
+ return 0;
+ }
+ while (nformat--)
+ {
+ if (format->depth == depth && format->type == type)
+ {
+ if (type == PictTypeIndexed)
+ {
+ if (format->index.vid == pVisual->vid)
+ return format;
+ }
+ else
+ {
+ if (format->direct.redMask << format->direct.red ==
+ pVisual->redMask &&
+ format->direct.greenMask << format->direct.green ==
+ pVisual->greenMask &&
+ format->direct.blueMask << format->direct.blue ==
+ pVisual->blueMask)
+ {
+ return format;
+ }
+ }
+ }
+ format++;
+ }
+ return 0;
+}
+
+PictFormatPtr
+PictureMatchFormat (ScreenPtr pScreen, int depth, CARD32 f)
+{
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+ PictFormatPtr format;
+ int nformat;
+
+ if (!ps)
+ return 0;
+ format = ps->formats;
+ nformat = ps->nformats;
+ while (nformat--)
+ {
+ if (format->depth == depth && format->format == (f & 0xffffff))
+ return format;
+ format++;
+ }
+ return 0;
+}
+
+int
+PictureParseCmapPolicy (const char *name)
+{
+ if ( strcmp (name, "default" ) == 0)
+ return PictureCmapPolicyDefault;
+ else if ( strcmp (name, "mono" ) == 0)
+ return PictureCmapPolicyMono;
+ else if ( strcmp (name, "gray" ) == 0)
+ return PictureCmapPolicyGray;
+ else if ( strcmp (name, "color" ) == 0)
+ return PictureCmapPolicyColor;
+ else if ( strcmp (name, "all" ) == 0)
+ return PictureCmapPolicyAll;
+ else
+ return PictureCmapPolicyInvalid;
+}
+
+Bool
+PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
+{
+ PictureScreenPtr ps;
+ int n;
+ CARD32 type, a, r, g, b;
+
+ if (PictureGeneration != serverGeneration)
+ {
+ PictureType = CreateNewResourceType (FreePicture);
+ if (!PictureType)
+ return FALSE;
+ PictFormatType = CreateNewResourceType (FreePictFormat);
+ if (!PictFormatType)
+ return FALSE;
+ GlyphSetType = CreateNewResourceType (FreeGlyphSet);
+ if (!GlyphSetType)
+ return FALSE;
+ PictureScreenPrivateIndex = AllocateScreenPrivateIndex();
+ if (PictureScreenPrivateIndex < 0)
+ return FALSE;
+ PictureWindowPrivateIndex = AllocateWindowPrivateIndex();
+ PictureGeneration = serverGeneration;
+#ifdef XResExtension
+ RegisterResourceName (PictureType, "PICTURE");
+ RegisterResourceName (PictFormatType, "PICTFORMAT");
+ RegisterResourceName (GlyphSetType, "GLYPHSET");
+#endif
+ }
+ if (!AllocateWindowPrivate (pScreen, PictureWindowPrivateIndex, 0))
+ return FALSE;
+
+ if (!formats)
+ {
+ formats = PictureCreateDefaultFormats (pScreen, &nformats);
+ if (!formats)
+ return FALSE;
+ }
+ for (n = 0; n < nformats; n++)
+ {
+ if (!AddResource (formats[n].id, PictFormatType, (pointer) (formats+n)))
+ {
+ xfree (formats);
+ return FALSE;
+ }
+ if (formats[n].type == PictTypeIndexed)
+ {
+ VisualPtr pVisual = PictureFindVisual (pScreen, formats[n].index.vid);
+ if ((pVisual->class | DynamicClass) == PseudoColor)
+ type = PICT_TYPE_COLOR;
+ else
+ type = PICT_TYPE_GRAY;
+ a = r = g = b = 0;
+ }
+ else
+ {
+ if ((formats[n].direct.redMask|
+ formats[n].direct.blueMask|
+ formats[n].direct.greenMask) == 0)
+ type = PICT_TYPE_A;
+ else if (formats[n].direct.red > formats[n].direct.blue)
+ type = PICT_TYPE_ARGB;
+ else
+ type = PICT_TYPE_ABGR;
+ a = Ones (formats[n].direct.alphaMask);
+ r = Ones (formats[n].direct.redMask);
+ g = Ones (formats[n].direct.greenMask);
+ b = Ones (formats[n].direct.blueMask);
+ }
+ formats[n].format = PICT_FORMAT(0,type,a,r,g,b);
+ }
+ ps = (PictureScreenPtr) xalloc (sizeof (PictureScreenRec));
+ if (!ps)
+ {
+ xfree (formats);
+ return FALSE;
+ }
+ SetPictureScreen(pScreen, ps);
+ if (!GlyphInit (pScreen))
+ {
+ SetPictureScreen(pScreen, 0);
+ xfree (formats);
+ xfree (ps);
+ return FALSE;
+ }
+
+ ps->totalPictureSize = sizeof (PictureRec);
+ ps->PicturePrivateSizes = 0;
+ ps->PicturePrivateLen = 0;
+
+ ps->formats = formats;
+ ps->fallback = formats;
+ ps->nformats = nformats;
+
+ ps->filters = 0;
+ ps->nfilters = 0;
+ ps->filterAliases = 0;
+ ps->nfilterAliases = 0;
+
+ ps->subpixel = SubPixelUnknown;
+
+ ps->CloseScreen = pScreen->CloseScreen;
+ ps->DestroyWindow = pScreen->DestroyWindow;
+ ps->StoreColors = pScreen->StoreColors;
+ pScreen->DestroyWindow = PictureDestroyWindow;
+ pScreen->CloseScreen = PictureCloseScreen;
+ pScreen->StoreColors = PictureStoreColors;
+
+ if (!PictureSetDefaultFilters (pScreen))
+ {
+ PictureResetFilters (pScreen);
+ SetPictureScreen(pScreen, 0);
+ xfree (formats);
+ xfree (ps);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void
+SetPictureToDefaults (PicturePtr pPicture)
+{
+ pPicture->refcnt = 1;
+ pPicture->repeat = 0;
+ pPicture->graphicsExposures = FALSE;
+ pPicture->subWindowMode = ClipByChildren;
+ pPicture->polyEdge = PolyEdgeSharp;
+ pPicture->polyMode = PolyModePrecise;
+ pPicture->freeCompClip = FALSE;
+ pPicture->clientClipType = CT_NONE;
+ pPicture->componentAlpha = FALSE;
+ pPicture->repeatType = RepeatNone;
+
+ pPicture->alphaMap = 0;
+ pPicture->alphaOrigin.x = 0;
+ pPicture->alphaOrigin.y = 0;
+
+ pPicture->clipOrigin.x = 0;
+ pPicture->clipOrigin.y = 0;
+ pPicture->clientClip = 0;
+
+ pPicture->transform = 0;
+
+ pPicture->dither = None;
+ pPicture->filter = PictureGetFilterId (FilterNearest, -1, TRUE);
+ pPicture->filter_params = 0;
+ pPicture->filter_nparams = 0;
+
+ pPicture->serialNumber = GC_CHANGE_SERIAL_BIT;
+ pPicture->stateChanges = (1 << (CPLastBit+1)) - 1;
+ pPicture->pSourcePict = 0;
+}
+
+PicturePtr
+AllocatePicture (ScreenPtr pScreen)
+{
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ PicturePtr pPicture;
+ char *ptr;
+ DevUnion *ppriv;
+ unsigned int *sizes;
+ unsigned int size;
+ int i;
+
+ pPicture = (PicturePtr) xalloc (ps->totalPictureSize);
+ if (!pPicture)
+ return 0;
+ ppriv = (DevUnion *)(pPicture + 1);
+ pPicture->devPrivates = ppriv;
+ sizes = ps->PicturePrivateSizes;
+ ptr = (char *)(ppriv + ps->PicturePrivateLen);
+ for (i = ps->PicturePrivateLen; --i >= 0; ppriv++, sizes++)
+ {
+ if ( (size = *sizes) )
+ {
+ ppriv->ptr = (pointer)ptr;
+ ptr += size;
+ }
+ else
+ ppriv->ptr = (pointer)NULL;
+ }
+ return pPicture;
+}
+
+PicturePtr
+CreatePicture (Picture pid,
+ DrawablePtr pDrawable,
+ PictFormatPtr pFormat,
+ Mask vmask,
+ XID *vlist,
+ ClientPtr client,
+ int *error)
+{
+ PicturePtr pPicture;
+ PictureScreenPtr ps = GetPictureScreen(pDrawable->pScreen);
+
+ pPicture = AllocatePicture (pDrawable->pScreen);
+ if (!pPicture)
+ {
+ *error = BadAlloc;
+ return 0;
+ }
+
+ pPicture->id = pid;
+ pPicture->pDrawable = pDrawable;
+ pPicture->pFormat = pFormat;
+ pPicture->format = pFormat->format | (pDrawable->bitsPerPixel << 24);
+ if (pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ ++((PixmapPtr)pDrawable)->refcnt;
+ pPicture->pNext = 0;
+ }
+ else
+ {
+ pPicture->pNext = GetPictureWindow(((WindowPtr) pDrawable));
+ SetPictureWindow(((WindowPtr) pDrawable), pPicture);
+ }
+
+ SetPictureToDefaults (pPicture);
+
+ if (vmask)
+ *error = ChangePicture (pPicture, vmask, vlist, 0, client);
+ else
+ *error = Success;
+ if (*error == Success)
+ *error = (*ps->CreatePicture) (pPicture);
+ if (*error != Success)
+ {
+ FreePicture (pPicture, (XID) 0);
+ pPicture = 0;
+ }
+ return pPicture;
+}
+
+static CARD32 xRenderColorToCard32(xRenderColor c)
+{
+ return
+ (c.alpha >> 8 << 24) |
+ (c.red >> 8 << 16) |
+ (c.green & 0xff00) |
+ (c.blue >> 8);
+}
+
+static unsigned int premultiply(unsigned int x)
+{
+ unsigned int a = x >> 24;
+ unsigned int t = (x & 0xff00ff) * a;
+ t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8;
+ t &= 0xff00ff;
+
+ x = ((x >> 8) & 0xff) * a;
+ x = (x + ((x >> 8) & 0xff) + 0x80);
+ x &= 0xff00;
+ x |= t | (a << 24);
+ return x;
+}
+
+static unsigned int INTERPOLATE_PIXEL_256(unsigned int x, unsigned int a,
+ unsigned int y, unsigned int b)
+{
+ CARD32 t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;
+ t >>= 8;
+ t &= 0xff00ff;
+
+ x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;
+ x &= 0xff00ff00;
+ x |= t;
+ return x;
+}
+
+static void initGradientColorTable(SourcePictPtr pGradient, int *error)
+{
+ int begin_pos, end_pos;
+ xFixed incr, dpos;
+ int pos, current_stop;
+ PictGradientStopPtr stops = pGradient->linear.stops;
+ int nstops = pGradient->linear.nstops;
+
+ /* The position where the gradient begins and ends */
+ begin_pos = (stops[0].x * PICT_GRADIENT_STOPTABLE_SIZE) >> 16;
+ end_pos = (stops[nstops - 1].x * PICT_GRADIENT_STOPTABLE_SIZE) >> 16;
+
+ pos = 0; /* The position in the color table. */
+
+ /* Up to first point */
+ while (pos <= begin_pos) {
+ pGradient->linear.colorTable[pos] = xRenderColorToCard32(stops[0].color);
+ ++pos;
+ }
+
+ incr = (1<<16)/ PICT_GRADIENT_STOPTABLE_SIZE; /* the double increment. */
+ dpos = incr * pos; /* The position in terms of 0-1. */
+
+ current_stop = 0; /* We always interpolate between current and current + 1. */
+
+ /* Gradient area */
+ while (pos < end_pos) {
+ unsigned int current_color = xRenderColorToCard32(stops[current_stop].color);
+ unsigned int next_color = xRenderColorToCard32(stops[current_stop + 1].color);
+
+ int dist = (int)(256*(dpos - stops[current_stop].x)
+ / (stops[current_stop+1].x - stops[current_stop].x));
+ int idist = 256 - dist;
+
+ pGradient->linear.colorTable[pos] = premultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
+
+ ++pos;
+ dpos += incr;
+
+ if (dpos > stops[current_stop + 1].x)
+ ++current_stop;
+ }
+
+ /* After last point */
+ while (pos < PICT_GRADIENT_STOPTABLE_SIZE) {
+ pGradient->linear.colorTable[pos] = xRenderColorToCard32(stops[nstops - 1].color);
+ ++pos;
+ }
+}
+
+static void initGradient(SourcePictPtr pGradient, int stopCount,
+ xFixed *stopPoints, xRenderColor *stopColors, int *error)
+{
+ int i;
+ xFixed dpos;
+
+ if (stopCount <= 0) {
+ *error = BadValue;
+ return;
+ }
+
+ dpos = -1;
+ for (i = 0; i < stopCount; ++i) {
+ if (stopPoints[i] <= dpos || stopPoints[i] > (1<<16)) {
+ *error = BadValue;
+ return;
+ }
+ dpos = stopPoints[i];
+ }
+
+ pGradient->linear.stops = xalloc(stopCount*sizeof(PictGradientStop));
+ if (!pGradient->linear.stops) {
+ *error = BadAlloc;
+ return;
+ }
+
+ pGradient->linear.nstops = stopCount;
+
+ for (i = 0; i < stopCount; ++i) {
+ pGradient->linear.stops[i].x = stopPoints[i];
+ pGradient->linear.stops[i].color = stopColors[i];
+ }
+ initGradientColorTable(pGradient, error);
+}
+
+static PicturePtr createSourcePicture(void)
+{
+ PicturePtr pPicture;
+ pPicture = (PicturePtr) xalloc(sizeof(PictureRec));
+ pPicture->pDrawable = 0;
+ pPicture->pFormat = 0;
+ pPicture->pNext = 0;
+
+ SetPictureToDefaults(pPicture);
+ return pPicture;
+}
+
+PicturePtr
+CreateSolidPicture (Picture pid, xRenderColor *color, int *error)
+{
+ PicturePtr pPicture;
+ pPicture = createSourcePicture();
+ if (!pPicture) {
+ *error = BadAlloc;
+ return 0;
+ }
+
+ pPicture->id = pid;
+ pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictSolidFill));
+ if (!pPicture->pSourcePict) {
+ *error = BadAlloc;
+ xfree(pPicture);
+ return 0;
+ }
+ pPicture->pSourcePict->type = SourcePictTypeSolidFill;
+ pPicture->pSourcePict->solidFill.color = xRenderColorToCard32(*color);
+ return pPicture;
+}
+
+PicturePtr
+CreateLinearGradientPicture (Picture pid, xPointFixed *p1, xPointFixed *p2,
+ int nStops, xFixed *stops, xRenderColor *colors, int *error)
+{
+ PicturePtr pPicture;
+
+ if (nStops < 2) {
+ *error = BadValue;
+ return 0;
+ }
+
+ pPicture = createSourcePicture();
+ if (!pPicture) {
+ *error = BadAlloc;
+ return 0;
+ }
+ if (p1->x == p2->x && p1->y == p2->y) {
+ *error = BadValue;
+ return 0;
+ }
+
+ pPicture->id = pid;
+ pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictLinearGradient));
+ if (!pPicture->pSourcePict) {
+ *error = BadAlloc;
+ xfree(pPicture);
+ return 0;
+ }
+
+ pPicture->pSourcePict->linear.type = SourcePictTypeLinear;
+ pPicture->pSourcePict->linear.p1 = *p1;
+ pPicture->pSourcePict->linear.p2 = *p2;
+
+ initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
+ if (*error) {
+ xfree(pPicture);
+ return 0;
+ }
+ return pPicture;
+}
+
+#define FixedToDouble(x) ((x)/65536.)
+
+PicturePtr
+CreateRadialGradientPicture (Picture pid, xPointFixed *inner, xPointFixed *outer,
+ xFixed innerRadius, xFixed outerRadius,
+ int nStops, xFixed *stops, xRenderColor *colors, int *error)
+{
+ PicturePtr pPicture;
+ PictRadialGradient *radial;
+
+ if (nStops < 2) {
+ *error = BadValue;
+ return 0;
+ }
+
+ pPicture = createSourcePicture();
+ if (!pPicture) {
+ *error = BadAlloc;
+ return 0;
+ }
+ {
+ double dx = (double)(inner->x - outer->x);
+ double dy = (double)(inner->y - outer->y);
+ if (sqrt(dx*dx + dy*dy) + (double)(innerRadius) > (double)(outerRadius)) {
+ *error = BadValue;
+ return 0;
+ }
+ }
+
+ pPicture->id = pid;
+ pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictRadialGradient));
+ if (!pPicture->pSourcePict) {
+ *error = BadAlloc;
+ xfree(pPicture);
+ return 0;
+ }
+ radial = &pPicture->pSourcePict->radial;
+
+ radial->type = SourcePictTypeRadial;
+ {
+ double x = (double)innerRadius / (double)outerRadius;
+ radial->dx = (outer->x - inner->x);
+ radial->dy = (outer->y - inner->y);
+ radial->fx = (inner->x) - x*radial->dx;
+ radial->fy = (inner->y) - x*radial->dy;
+ radial->m = 1./(1+x);
+ radial->b = -x*radial->m;
+ radial->dx /= 65536.;
+ radial->dy /= 65536.;
+ radial->fx /= 65536.;
+ radial->fy /= 65536.;
+ x = outerRadius/65536.;
+ radial->a = x*x - radial->dx*radial->dx - radial->dy*radial->dy;
+ }
+
+ initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
+ if (*error) {
+ xfree(pPicture);
+ return 0;
+ }
+ return pPicture;
+}
+
+PicturePtr
+CreateConicalGradientPicture (Picture pid, xPointFixed *center, xFixed angle,
+ int nStops, xFixed *stops, xRenderColor *colors, int *error)
+{
+ PicturePtr pPicture;
+
+ if (nStops < 2) {
+ *error = BadValue;
+ return 0;
+ }
+
+ pPicture = createSourcePicture();
+ if (!pPicture) {
+ *error = BadAlloc;
+ return 0;
+ }
+
+ pPicture->id = pid;
+ pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictConicalGradient));
+ if (!pPicture->pSourcePict) {
+ *error = BadAlloc;
+ xfree(pPicture);
+ return 0;
+ }
+
+ pPicture->pSourcePict->conical.type = SourcePictTypeConical;
+ pPicture->pSourcePict->conical.center = *center;
+ pPicture->pSourcePict->conical.angle = angle;
+
+ initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
+ if (*error) {
+ xfree(pPicture);
+ return 0;
+ }
+ return pPicture;
+}
+
+#define NEXT_VAL(_type) (vlist ? (_type) *vlist++ : (_type) ulist++->val)
+
+#define NEXT_PTR(_type) ((_type) ulist++->ptr)
+
+int
+ChangePicture (PicturePtr pPicture,
+ Mask vmask,
+ XID *vlist,
+ DevUnion *ulist,
+ ClientPtr client)
+{
+ ScreenPtr pScreen = pPicture->pDrawable ? pPicture->pDrawable->pScreen : 0;
+ PictureScreenPtr ps = pScreen ? GetPictureScreen(pScreen) : 0;
+ BITS32 index2;
+ int error = 0;
+ BITS32 maskQ;
+
+ pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ maskQ = vmask;
+ while (vmask && !error)
+ {
+ index2 = (BITS32) lowbit (vmask);
+ vmask &= ~index2;
+ pPicture->stateChanges |= index2;
+ switch (index2)
+ {
+ case CPRepeat:
+ {
+ unsigned int newr;
+ newr = NEXT_VAL(unsigned int);
+ if (newr <= RepeatReflect)
+ {
+ pPicture->repeat = (newr != RepeatNone);
+ pPicture->repeatType = newr;
+ }
+ else
+ {
+ client->errorValue = newr;
+ error = BadValue;
+ }
+ }
+ break;
+ case CPAlphaMap:
+ {
+ PicturePtr pAlpha;
+
+ if (vlist)
+ {
+ Picture pid = NEXT_VAL(Picture);
+
+ if (pid == None)
+ pAlpha = 0;
+ else
+ {
+ pAlpha = (PicturePtr) SecurityLookupIDByType(client,
+ pid,
+ PictureType,
+ SecurityWriteAccess|SecurityReadAccess);
+ if (!pAlpha)
+ {
+ client->errorValue = pid;
+ error = BadPixmap;
+ break;
+ }
+ if (pAlpha->pDrawable->type != DRAWABLE_PIXMAP)
+ {
+ client->errorValue = pid;
+ error = BadMatch;
+ break;
+ }
+ }
+ }
+ else
+ pAlpha = NEXT_PTR(PicturePtr);
+ if (!error)
+ {
+ if (pAlpha && pAlpha->pDrawable->type == DRAWABLE_PIXMAP)
+ pAlpha->refcnt++;
+ if (pPicture->alphaMap)
+ FreePicture ((pointer) pPicture->alphaMap, (XID) 0);
+ pPicture->alphaMap = pAlpha;
+ }
+ }
+ break;
+ case CPAlphaXOrigin:
+ pPicture->alphaOrigin.x = NEXT_VAL(INT16);
+ break;
+ case CPAlphaYOrigin:
+ pPicture->alphaOrigin.y = NEXT_VAL(INT16);
+ break;
+ case CPClipXOrigin:
+ pPicture->clipOrigin.x = NEXT_VAL(INT16);
+ break;
+ case CPClipYOrigin:
+ pPicture->clipOrigin.y = NEXT_VAL(INT16);
+ break;
+ case CPClipMask:
+ {
+ Pixmap pid;
+ PixmapPtr pPixmap;
+ int clipType;
+ if (!pScreen)
+ return BadDrawable;
+
+ if (vlist)
+ {
+ pid = NEXT_VAL(Pixmap);
+ if (pid == None)
+ {
+ clipType = CT_NONE;
+ pPixmap = NullPixmap;
+ }
+ else
+ {
+ clipType = CT_PIXMAP;
+ pPixmap = (PixmapPtr)SecurityLookupIDByType(client,
+ pid,
+ RT_PIXMAP,
+ SecurityReadAccess);
+ if (!pPixmap)
+ {
+ client->errorValue = pid;
+ error = BadPixmap;
+ break;
+ }
+ }
+ }
+ else
+ {
+ pPixmap = NEXT_PTR(PixmapPtr);
+ if (pPixmap)
+ clipType = CT_PIXMAP;
+ else
+ clipType = CT_NONE;
+ }
+
+ if (pPixmap)
+ {
+ if ((pPixmap->drawable.depth != 1) ||
+ (pPixmap->drawable.pScreen != pScreen))
+ {
+ error = BadMatch;
+ break;
+ }
+ else
+ {
+ clipType = CT_PIXMAP;
+ pPixmap->refcnt++;
+ }
+ }
+ error = (*ps->ChangePictureClip)(pPicture, clipType,
+ (pointer)pPixmap, 0);
+ break;
+ }
+ case CPGraphicsExposure:
+ {
+ unsigned int newe;
+ newe = NEXT_VAL(unsigned int);
+ if (newe <= xTrue)
+ pPicture->graphicsExposures = newe;
+ else
+ {
+ client->errorValue = newe;
+ error = BadValue;
+ }
+ }
+ break;
+ case CPSubwindowMode:
+ {
+ unsigned int news;
+ news = NEXT_VAL(unsigned int);
+ if (news == ClipByChildren || news == IncludeInferiors)
+ pPicture->subWindowMode = news;
+ else
+ {
+ client->errorValue = news;
+ error = BadValue;
+ }
+ }
+ break;
+ case CPPolyEdge:
+ {
+ unsigned int newe;
+ newe = NEXT_VAL(unsigned int);
+ if (newe == PolyEdgeSharp || newe == PolyEdgeSmooth)
+ pPicture->polyEdge = newe;
+ else
+ {
+ client->errorValue = newe;
+ error = BadValue;
+ }
+ }
+ break;
+ case CPPolyMode:
+ {
+ unsigned int newm;
+ newm = NEXT_VAL(unsigned int);
+ if (newm == PolyModePrecise || newm == PolyModeImprecise)
+ pPicture->polyMode = newm;
+ else
+ {
+ client->errorValue = newm;
+ error = BadValue;
+ }
+ }
+ break;
+ case CPDither:
+ pPicture->dither = NEXT_VAL(Atom);
+ break;
+ case CPComponentAlpha:
+ {
+ unsigned int newca;
+
+ newca = NEXT_VAL (unsigned int);
+ if (newca <= xTrue)
+ pPicture->componentAlpha = newca;
+ else
+ {
+ client->errorValue = newca;
+ error = BadValue;
+ }
+ }
+ break;
+ default:
+ client->errorValue = maskQ;
+ error = BadValue;
+ break;
+ }
+ }
+ if (ps)
+ (*ps->ChangePicture) (pPicture, maskQ);
+ return error;
+}
+
+int
+SetPictureClipRects (PicturePtr pPicture,
+ int xOrigin,
+ int yOrigin,
+ int nRect,
+ xRectangle *rects)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ RegionPtr clientClip;
+ int result;
+
+ clientClip = RECTS_TO_REGION(pScreen,
+ nRect, rects, CT_UNSORTED);
+ if (!clientClip)
+ return BadAlloc;
+ result =(*ps->ChangePictureClip) (pPicture, CT_REGION,
+ (pointer) clientClip, 0);
+ if (result == Success)
+ {
+ pPicture->clipOrigin.x = xOrigin;
+ pPicture->clipOrigin.y = yOrigin;
+ pPicture->stateChanges |= CPClipXOrigin|CPClipYOrigin|CPClipMask;
+ pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ }
+ return result;
+}
+
+int
+SetPictureClipRegion (PicturePtr pPicture,
+ int xOrigin,
+ int yOrigin,
+ RegionPtr pRegion)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ RegionPtr clientClip;
+ int result;
+ int type;
+
+ if (pRegion)
+ {
+ type = CT_REGION;
+ clientClip = REGION_CREATE (pScreen,
+ REGION_EXTENTS(pScreen, pRegion),
+ REGION_NUM_RECTS(pRegion));
+ if (!clientClip)
+ return BadAlloc;
+ if (!REGION_COPY (pSCreen, clientClip, pRegion))
+ {
+ REGION_DESTROY (pScreen, clientClip);
+ return BadAlloc;
+ }
+ }
+ else
+ {
+ type = CT_NONE;
+ clientClip = 0;
+ }
+
+ result =(*ps->ChangePictureClip) (pPicture, type,
+ (pointer) clientClip, 0);
+ if (result == Success)
+ {
+ pPicture->clipOrigin.x = xOrigin;
+ pPicture->clipOrigin.y = yOrigin;
+ pPicture->stateChanges |= CPClipXOrigin|CPClipYOrigin|CPClipMask;
+ pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ }
+ return result;
+}
+
+
+int
+SetPictureTransform (PicturePtr pPicture,
+ PictTransform *transform)
+{
+ static const PictTransform identity = { {
+ { xFixed1, 0x00000, 0x00000 },
+ { 0x00000, xFixed1, 0x00000 },
+ { 0x00000, 0x00000, xFixed1 },
+ } };
+
+ if (transform && memcmp (transform, &identity, sizeof (PictTransform)) == 0)
+ transform = 0;
+
+ if (transform)
+ {
+ if (!pPicture->transform)
+ {
+ pPicture->transform = (PictTransform *) xalloc (sizeof (PictTransform));
+ if (!pPicture->transform)
+ return BadAlloc;
+ }
+ *pPicture->transform = *transform;
+ }
+ else
+ {
+ if (pPicture->transform)
+ {
+ xfree (pPicture->transform);
+ pPicture->transform = 0;
+ }
+ }
+ pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+
+ return Success;
+}
+
+void
+CopyPicture (PicturePtr pSrc,
+ Mask mask,
+ PicturePtr pDst)
+{
+ PictureScreenPtr ps = GetPictureScreen(pSrc->pDrawable->pScreen);
+ Mask origMask = mask;
+
+ pDst->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ pDst->stateChanges |= mask;
+
+ while (mask) {
+ Mask bit = lowbit(mask);
+
+ switch (bit)
+ {
+ case CPRepeat:
+ pDst->repeat = pSrc->repeat;
+ pDst->repeatType = pSrc->repeatType;
+ break;
+ case CPAlphaMap:
+ if (pSrc->alphaMap && pSrc->alphaMap->pDrawable->type == DRAWABLE_PIXMAP)
+ pSrc->alphaMap->refcnt++;
+ if (pDst->alphaMap)
+ FreePicture ((pointer) pDst->alphaMap, (XID) 0);
+ pDst->alphaMap = pSrc->alphaMap;
+ break;
+ case CPAlphaXOrigin:
+ pDst->alphaOrigin.x = pSrc->alphaOrigin.x;
+ break;
+ case CPAlphaYOrigin:
+ pDst->alphaOrigin.y = pSrc->alphaOrigin.y;
+ break;
+ case CPClipXOrigin:
+ pDst->clipOrigin.x = pSrc->clipOrigin.x;
+ break;
+ case CPClipYOrigin:
+ pDst->clipOrigin.y = pSrc->clipOrigin.y;
+ break;
+ case CPClipMask:
+ switch (pSrc->clientClipType) {
+ case CT_NONE:
+ (*ps->ChangePictureClip)(pDst, CT_NONE, NULL, 0);
+ break;
+ case CT_REGION:
+ if (!pSrc->clientClip) {
+ (*ps->ChangePictureClip)(pDst, CT_NONE, NULL, 0);
+ } else {
+ RegionPtr clientClip;
+ RegionPtr srcClientClip = (RegionPtr)pSrc->clientClip;
+
+ clientClip = REGION_CREATE(pSrc->pDrawable->pScreen,
+ REGION_EXTENTS(pSrc->pDrawable->pScreen, srcClientClip),
+ REGION_NUM_RECTS(srcClientClip));
+ (*ps->ChangePictureClip)(pDst, CT_REGION, clientClip, 0);
+ }
+ break;
+ default:
+ /* XXX: CT_PIXMAP unimplemented */
+ break;
+ }
+ break;
+ case CPGraphicsExposure:
+ pDst->graphicsExposures = pSrc->graphicsExposures;
+ break;
+ case CPPolyEdge:
+ pDst->polyEdge = pSrc->polyEdge;
+ break;
+ case CPPolyMode:
+ pDst->polyMode = pSrc->polyMode;
+ break;
+ case CPDither:
+ pDst->dither = pSrc->dither;
+ break;
+ case CPComponentAlpha:
+ pDst->componentAlpha = pSrc->componentAlpha;
+ break;
+ }
+ mask &= ~bit;
+ }
+
+ (*ps->ChangePicture)(pDst, origMask);
+}
+
+static void
+ValidateOnePicture (PicturePtr pPicture)
+{
+ if (pPicture->pDrawable && pPicture->serialNumber != pPicture->pDrawable->serialNumber)
+ {
+ PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen);
+
+ (*ps->ValidatePicture) (pPicture, pPicture->stateChanges);
+ pPicture->stateChanges = 0;
+ pPicture->serialNumber = pPicture->pDrawable->serialNumber;
+ }
+}
+
+void
+ValidatePicture(PicturePtr pPicture)
+{
+ ValidateOnePicture (pPicture);
+ if (pPicture->alphaMap)
+ ValidateOnePicture (pPicture->alphaMap);
+}
+
+int
+FreePicture (pointer value,
+ XID pid)
+{
+ PicturePtr pPicture = (PicturePtr) value;
+
+ if (--pPicture->refcnt == 0)
+ {
+ if (pPicture->transform)
+ xfree (pPicture->transform);
+ if (!pPicture->pDrawable) {
+ if (pPicture->pSourcePict) {
+ if (pPicture->pSourcePict->type != SourcePictTypeSolidFill)
+ xfree(pPicture->pSourcePict->linear.stops);
+ xfree(pPicture->pSourcePict);
+ }
+ } else {
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+
+ if (pPicture->alphaMap)
+ FreePicture ((pointer) pPicture->alphaMap, (XID) 0);
+ (*ps->DestroyPicture) (pPicture);
+ (*ps->DestroyPictureClip) (pPicture);
+ if (pPicture->pDrawable->type == DRAWABLE_WINDOW)
+ {
+ WindowPtr pWindow = (WindowPtr) pPicture->pDrawable;
+ PicturePtr *pPrev;
+
+ for (pPrev = (PicturePtr *) &((pWindow)->devPrivates[PictureWindowPrivateIndex].ptr);
+ *pPrev;
+ pPrev = &(*pPrev)->pNext)
+ {
+ if (*pPrev == pPicture)
+ {
+ *pPrev = pPicture->pNext;
+ break;
+ }
+ }
+ }
+ else if (pPicture->pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ (*pScreen->DestroyPixmap) ((PixmapPtr)pPicture->pDrawable);
+ }
+ }
+ xfree (pPicture);
+ }
+ return Success;
+}
+
+int
+FreePictFormat (pointer pPictFormat,
+ XID pid)
+{
+ return Success;
+}
+
+void
+CompositePicture (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
+ ValidatePicture (pSrc);
+ if (pMask)
+ ValidatePicture (pMask);
+ ValidatePicture (pDst);
+ (*ps->Composite) (op,
+ pSrc,
+ pMask,
+ pDst,
+ xSrc,
+ ySrc,
+ xMask,
+ yMask,
+ xDst,
+ yDst,
+ width,
+ height);
+}
+
+void
+CompositeGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr lists,
+ GlyphPtr *glyphs)
+{
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
+ ValidatePicture (pSrc);
+ ValidatePicture (pDst);
+ (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, lists, glyphs);
+}
+
+void
+CompositeRects (CARD8 op,
+ PicturePtr pDst,
+ xRenderColor *color,
+ int nRect,
+ xRectangle *rects)
+{
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
+ ValidatePicture (pDst);
+ (*ps->CompositeRects) (op, pDst, color, nRect, rects);
+}
+
+void
+CompositeTrapezoids (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntrap,
+ xTrapezoid *traps)
+{
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
+ ValidatePicture (pSrc);
+ ValidatePicture (pDst);
+ (*ps->Trapezoids) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntrap, traps);
+}
+
+void
+CompositeTriangles (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntriangles,
+ xTriangle *triangles)
+{
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
+ ValidatePicture (pSrc);
+ ValidatePicture (pDst);
+ (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntriangles, triangles);
+}
+
+void
+CompositeTriStrip (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoints,
+ xPointFixed *points)
+{
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
+ ValidatePicture (pSrc);
+ ValidatePicture (pDst);
+ (*ps->TriStrip) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
+}
+
+void
+CompositeTriFan (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoints,
+ xPointFixed *points)
+{
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
+ ValidatePicture (pSrc);
+ ValidatePicture (pDst);
+ (*ps->TriFan) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
+}
+
+void
+AddTraps (PicturePtr pPicture,
+ INT16 xOff,
+ INT16 yOff,
+ int ntrap,
+ xTrap *traps)
+{
+ PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen);
+
+ ValidatePicture (pPicture);
+ (*ps->AddTraps) (pPicture, xOff, yOff, ntrap, traps);
+}
+
+#define MAX_FIXED_48_16 ((xFixed_48_16) 0x7fffffff)
+#define MIN_FIXED_48_16 (-((xFixed_48_16) 1 << 31))
+
+Bool
+PictureTransformPoint3d (PictTransformPtr transform,
+ PictVectorPtr vector)
+{
+ PictVector result;
+ int i, j;
+ xFixed_32_32 partial;
+ xFixed_48_16 v;
+
+ for (j = 0; j < 3; j++)
+ {
+ v = 0;
+ for (i = 0; i < 3; i++)
+ {
+ partial = ((xFixed_48_16) transform->matrix[j][i] *
+ (xFixed_48_16) vector->vector[i]);
+ v += partial >> 16;
+ }
+ if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
+ return FALSE;
+ result.vector[j] = (xFixed) v;
+ }
+ if (!result.vector[2])
+ return FALSE;
+ *vector = result;
+ return TRUE;
+}
+
+
+Bool
+PictureTransformPoint (PictTransformPtr transform,
+ PictVectorPtr vector)
+{
+ PictVector result;
+ int i, j;
+ xFixed_32_32 partial;
+ xFixed_48_16 v;
+
+ for (j = 0; j < 3; j++)
+ {
+ v = 0;
+ for (i = 0; i < 3; i++)
+ {
+ partial = ((xFixed_48_16) transform->matrix[j][i] *
+ (xFixed_48_16) vector->vector[i]);
+ v += partial >> 16;
+ }
+ if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
+ return FALSE;
+ result.vector[j] = (xFixed) v;
+ }
+ if (!result.vector[2])
+ return FALSE;
+ for (j = 0; j < 2; j++)
+ {
+ partial = (xFixed_48_16) result.vector[j] << 16;
+ v = partial / result.vector[2];
+ if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
+ return FALSE;
+ vector->vector[j] = (xFixed) v;
+ }
+ vector->vector[2] = xFixed1;
+ return TRUE;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h
new file mode 100644
index 000000000..255411a9b
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h
@@ -0,0 +1,678 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/*
+ * $Id: picturestr.h,v 1.15 2005/12/09 18:35:21 ajax Exp $
+ *
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+/*
+ * This must keep the same symbol as the original
+ * picturestr.h or symbols will be redefined. We
+ * should define a new types and cast when appro-
+ * priate.
+ */
+
+#ifndef _PICTURESTR_H_
+#define _PICTURESTR_H_
+
+#include "NXglyphstr.h"
+#include "scrnintstr.h"
+#include "resource.h"
+
+typedef struct _DirectFormat {
+ CARD16 red, redMask;
+ CARD16 green, greenMask;
+ CARD16 blue, blueMask;
+ CARD16 alpha, alphaMask;
+} DirectFormatRec;
+
+typedef struct _IndexFormat {
+ VisualID vid;
+ ColormapPtr pColormap;
+ int nvalues;
+ xIndexValue *pValues;
+ void *devPrivate;
+} IndexFormatRec;
+
+typedef struct _PictFormat {
+ CARD32 id;
+ CARD32 format; /* except bpp */
+ unsigned char type;
+ unsigned char depth;
+ DirectFormatRec direct;
+ IndexFormatRec index;
+} PictFormatRec;
+
+typedef struct _PictVector {
+ xFixed vector[3];
+} PictVector, *PictVectorPtr;
+
+typedef struct _PictTransform {
+ xFixed matrix[3][3];
+} PictTransform, *PictTransformPtr;
+
+#define PICT_GRADIENT_STOPTABLE_SIZE 1024
+#define SourcePictTypeSolidFill 0
+#define SourcePictTypeLinear 1
+#define SourcePictTypeRadial 2
+#define SourcePictTypeConical 3
+
+typedef struct _PictSolidFill {
+ unsigned int type;
+ CARD32 color;
+} PictSolidFill, *PictSolidFillPtr;
+
+typedef struct _PictGradientStop {
+ xFixed x;
+ xRenderColor color;
+} PictGradientStop, *PictGradientStopPtr;
+
+typedef struct _PictGradient {
+ unsigned int type;
+ int nstops;
+ PictGradientStopPtr stops;
+ CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+} PictGradient, *PictGradientPtr;
+
+typedef struct _PictLinearGradient {
+ unsigned int type;
+ int nstops;
+ PictGradientStopPtr stops;
+ CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+ xPointFixed p1;
+ xPointFixed p2;
+} PictLinearGradient, *PictLinearGradientPtr;
+
+typedef struct _PictRadialGradient {
+ unsigned int type;
+ int nstops;
+ PictGradientStopPtr stops;
+ CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+ double fx;
+ double fy;
+ double dx;
+ double dy;
+ double a;
+ double m;
+ double b;
+} PictRadialGradient, *PictRadialGradientPtr;
+
+typedef struct _PictConicalGradient {
+ unsigned int type;
+ int nstops;
+ PictGradientStopPtr stops;
+ CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+ xPointFixed center;
+ xFixed angle;
+} PictConicalGradient, *PictConicalGradientPtr;
+
+typedef union _SourcePict {
+ unsigned int type;
+ PictSolidFill solidFill;
+ PictGradient gradient;
+ PictLinearGradient linear;
+ PictRadialGradient radial;
+ PictConicalGradient conical;
+} SourcePict, *SourcePictPtr;
+
+typedef struct _Picture {
+ DrawablePtr pDrawable;
+ PictFormatPtr pFormat;
+ CARD32 format; /* PICT_FORMAT */
+ int refcnt;
+ CARD32 id;
+ PicturePtr pNext; /* chain on same drawable */
+
+ unsigned int repeat : 1;
+ unsigned int graphicsExposures : 1;
+ unsigned int subWindowMode : 1;
+ unsigned int polyEdge : 1;
+ unsigned int polyMode : 1;
+ unsigned int freeCompClip : 1;
+ unsigned int clientClipType : 2;
+ unsigned int componentAlpha : 1;
+ unsigned int repeatType : 2;
+ unsigned int unused : 21;
+
+ PicturePtr alphaMap;
+ DDXPointRec alphaOrigin;
+
+ DDXPointRec clipOrigin;
+ pointer clientClip;
+
+ Atom dither;
+
+ unsigned long stateChanges;
+ unsigned long serialNumber;
+
+ RegionPtr pCompositeClip;
+
+ DevUnion *devPrivates;
+
+ PictTransform *transform;
+
+ int filter;
+ xFixed *filter_params;
+ int filter_nparams;
+ SourcePictPtr pSourcePict;
+} PictureRec;
+
+typedef Bool (*PictFilterValidateParamsProcPtr) (PicturePtr pPicture, int id,
+ xFixed *params, int nparams);
+typedef struct {
+ char *name;
+ int id;
+ PictFilterValidateParamsProcPtr ValidateParams;
+} PictFilterRec, *PictFilterPtr;
+
+#define PictFilterNearest 0
+#define PictFilterBilinear 1
+
+#define PictFilterFast 2
+#define PictFilterGood 3
+#define PictFilterBest 4
+
+#define PictFilterConvolution 5
+
+typedef struct {
+ char *alias;
+ int alias_id;
+ int filter_id;
+} PictFilterAliasRec, *PictFilterAliasPtr;
+
+typedef int (*CreatePictureProcPtr) (PicturePtr pPicture);
+typedef void (*DestroyPictureProcPtr) (PicturePtr pPicture);
+typedef int (*ChangePictureClipProcPtr) (PicturePtr pPicture,
+ int clipType,
+ pointer value,
+ int n);
+typedef void (*DestroyPictureClipProcPtr)(PicturePtr pPicture);
+
+typedef int (*ChangePictureTransformProcPtr) (PicturePtr pPicture,
+ PictTransform *transform);
+
+typedef int (*ChangePictureFilterProcPtr) (PicturePtr pPicture,
+ int filter,
+ xFixed *params,
+ int nparams);
+
+typedef void (*DestroyPictureFilterProcPtr) (PicturePtr pPicture);
+
+typedef void (*ChangePictureProcPtr) (PicturePtr pPicture,
+ Mask mask);
+typedef void (*ValidatePictureProcPtr) (PicturePtr pPicture,
+ Mask mask);
+typedef void (*CompositeProcPtr) (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+typedef void (*GlyphsProcPtr) (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlists,
+ GlyphListPtr lists,
+ GlyphPtr *glyphs);
+
+typedef void (*CompositeRectsProcPtr) (CARD8 op,
+ PicturePtr pDst,
+ xRenderColor *color,
+ int nRect,
+ xRectangle *rects);
+
+typedef void (*RasterizeTrapezoidProcPtr)(PicturePtr pMask,
+ xTrapezoid *trap,
+ int x_off,
+ int y_off);
+
+typedef void (*TrapezoidsProcPtr) (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntrap,
+ xTrapezoid *traps);
+
+typedef void (*TrianglesProcPtr) (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntri,
+ xTriangle *tris);
+
+typedef void (*TriStripProcPtr) (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoint,
+ xPointFixed *points);
+
+typedef void (*TriFanProcPtr) (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoint,
+ xPointFixed *points);
+
+typedef Bool (*InitIndexedProcPtr) (ScreenPtr pScreen,
+ PictFormatPtr pFormat);
+
+typedef void (*CloseIndexedProcPtr) (ScreenPtr pScreen,
+ PictFormatPtr pFormat);
+
+typedef void (*UpdateIndexedProcPtr) (ScreenPtr pScreen,
+ PictFormatPtr pFormat,
+ int ndef,
+ xColorItem *pdef);
+
+typedef void (*AddTrapsProcPtr) (PicturePtr pPicture,
+ INT16 xOff,
+ INT16 yOff,
+ int ntrap,
+ xTrap *traps);
+
+typedef void (*AddTrianglesProcPtr) (PicturePtr pPicture,
+ INT16 xOff,
+ INT16 yOff,
+ int ntri,
+ xTriangle *tris);
+
+typedef struct _PictureScreen {
+ int totalPictureSize;
+ unsigned int *PicturePrivateSizes;
+ int PicturePrivateLen;
+
+ PictFormatPtr formats;
+ PictFormatPtr fallback;
+ int nformats;
+
+ CreatePictureProcPtr CreatePicture;
+ DestroyPictureProcPtr DestroyPicture;
+ ChangePictureClipProcPtr ChangePictureClip;
+ DestroyPictureClipProcPtr DestroyPictureClip;
+
+ ChangePictureProcPtr ChangePicture;
+ ValidatePictureProcPtr ValidatePicture;
+
+ CompositeProcPtr Composite;
+ GlyphsProcPtr Glyphs;
+ CompositeRectsProcPtr CompositeRects;
+
+ DestroyWindowProcPtr DestroyWindow;
+ CloseScreenProcPtr CloseScreen;
+
+ StoreColorsProcPtr StoreColors;
+
+ InitIndexedProcPtr InitIndexed;
+ CloseIndexedProcPtr CloseIndexed;
+ UpdateIndexedProcPtr UpdateIndexed;
+
+ int subpixel;
+
+ PictFilterPtr filters;
+ int nfilters;
+ PictFilterAliasPtr filterAliases;
+ int nfilterAliases;
+
+ ChangePictureTransformProcPtr ChangePictureTransform;
+ ChangePictureFilterProcPtr ChangePictureFilter;
+ DestroyPictureFilterProcPtr DestroyPictureFilter;
+
+ TrapezoidsProcPtr Trapezoids;
+ TrianglesProcPtr Triangles;
+ TriStripProcPtr TriStrip;
+ TriFanProcPtr TriFan;
+
+ RasterizeTrapezoidProcPtr RasterizeTrapezoid;
+
+ AddTrianglesProcPtr AddTriangles;
+
+ AddTrapsProcPtr AddTraps;
+
+} PictureScreenRec, *PictureScreenPtr;
+
+extern int PictureScreenPrivateIndex;
+extern int PictureWindowPrivateIndex;
+extern RESTYPE PictureType;
+extern RESTYPE PictFormatType;
+extern RESTYPE GlyphSetType;
+
+#define GetPictureScreen(s) ((PictureScreenPtr) ((s)->devPrivates[PictureScreenPrivateIndex].ptr))
+#define GetPictureScreenIfSet(s) ((PictureScreenPrivateIndex != -1) ? GetPictureScreen(s) : NULL)
+#define SetPictureScreen(s,p) ((s)->devPrivates[PictureScreenPrivateIndex].ptr = (pointer) (p))
+#define GetPictureWindow(w) ((PicturePtr) ((w)->devPrivates[PictureWindowPrivateIndex].ptr))
+#define SetPictureWindow(w,p) ((w)->devPrivates[PictureWindowPrivateIndex].ptr = (pointer) (p))
+
+#define VERIFY_PICTURE(pPicture, pid, client, mode, err) {\
+ pPicture = SecurityLookupIDByType(client, pid, PictureType, mode);\
+ if (!pPicture) { \
+ client->errorValue = pid; \
+ return err; \
+ } \
+}
+
+#define VERIFY_ALPHA(pPicture, pid, client, mode, err) {\
+ if (pid == None) \
+ pPicture = 0; \
+ else { \
+ VERIFY_PICTURE(pPicture, pid, client, mode, err); \
+ } \
+} \
+
+void
+ResetPicturePrivateIndex (void);
+
+int
+AllocatePicturePrivateIndex (void);
+
+Bool
+AllocatePicturePrivate (ScreenPtr pScreen, int index2, unsigned int amount);
+
+Bool
+PictureDestroyWindow (WindowPtr pWindow);
+
+Bool
+PictureCloseScreen (int Index, ScreenPtr pScreen);
+
+void
+PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef);
+
+Bool
+PictureInitIndexedFormats (ScreenPtr pScreen);
+
+Bool
+PictureSetSubpixelOrder (ScreenPtr pScreen, int subpixel);
+
+int
+PictureGetSubpixelOrder (ScreenPtr pScreen);
+
+PictFormatPtr
+PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp);
+
+PictFormatPtr
+PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual);
+
+PictFormatPtr
+PictureMatchFormat (ScreenPtr pScreen, int depth, CARD32 format);
+
+Bool
+PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
+
+int
+PictureGetFilterId (char *filter, int len, Bool makeit);
+
+char *
+PictureGetFilterName (int id);
+
+int
+PictureAddFilter (ScreenPtr pScreen,
+ char *filter,
+ PictFilterValidateParamsProcPtr ValidateParams);
+
+Bool
+PictureSetFilterAlias (ScreenPtr pScreen, char *filter, char *alias);
+
+Bool
+PictureSetDefaultFilters (ScreenPtr pScreen);
+
+void
+PictureResetFilters (ScreenPtr pScreen);
+
+PictFilterPtr
+PictureFindFilter (ScreenPtr pScreen, char *name, int len);
+
+int
+SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int nparams);
+
+Bool
+PictureFinishInit (void);
+
+void
+SetPictureToDefaults (PicturePtr pPicture);
+
+PicturePtr
+AllocatePicture (ScreenPtr pScreen);
+
+#if 0
+Bool
+miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
+#endif
+
+
+PicturePtr
+CreatePicture (Picture pid,
+ DrawablePtr pDrawable,
+ PictFormatPtr pFormat,
+ Mask mask,
+ XID *list,
+ ClientPtr client,
+ int *error);
+
+int
+ChangePicture (PicturePtr pPicture,
+ Mask vmask,
+ XID *vlist,
+ DevUnion *ulist,
+ ClientPtr client);
+
+int
+SetPictureClipRects (PicturePtr pPicture,
+ int xOrigin,
+ int yOrigin,
+ int nRect,
+ xRectangle *rects);
+
+int
+SetPictureClipRegion (PicturePtr pPicture,
+ int xOrigin,
+ int yOrigin,
+ RegionPtr pRegion);
+
+int
+SetPictureTransform (PicturePtr pPicture,
+ PictTransform *transform);
+
+void
+CopyPicture (PicturePtr pSrc,
+ Mask mask,
+ PicturePtr pDst);
+
+void
+ValidatePicture(PicturePtr pPicture);
+
+int
+FreePicture (pointer pPicture,
+ XID pid);
+
+int
+FreePictFormat (pointer pPictFormat,
+ XID pid);
+
+void
+CompositePicture (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+void
+CompositeGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr lists,
+ GlyphPtr *glyphs);
+
+void
+CompositeRects (CARD8 op,
+ PicturePtr pDst,
+ xRenderColor *color,
+ int nRect,
+ xRectangle *rects);
+
+void
+CompositeTrapezoids (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntrap,
+ xTrapezoid *traps);
+
+void
+CompositeTriangles (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntriangles,
+ xTriangle *triangles);
+
+void
+CompositeTriStrip (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoints,
+ xPointFixed *points);
+
+void
+CompositeTriFan (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoints,
+ xPointFixed *points);
+
+Bool
+PictureTransformPoint (PictTransformPtr transform,
+ PictVectorPtr vector);
+
+Bool
+PictureTransformPoint3d (PictTransformPtr transform,
+ PictVectorPtr vector);
+
+void RenderExtensionInit (void);
+
+Bool
+AnimCurInit (ScreenPtr pScreen);
+
+int
+AnimCursorCreate (CursorPtr *cursors, CARD32 *deltas, int ncursor, CursorPtr *ppCursor);
+
+void
+AddTraps (PicturePtr pPicture,
+ INT16 xOff,
+ INT16 yOff,
+ int ntraps,
+ xTrap *traps);
+
+PicturePtr
+CreateSolidPicture (Picture pid,
+ xRenderColor *color,
+ int *error);
+
+PicturePtr
+CreateLinearGradientPicture (Picture pid,
+ xPointFixed *p1,
+ xPointFixed *p2,
+ int nStops,
+ xFixed *stops,
+ xRenderColor *colors,
+ int *error);
+
+PicturePtr
+CreateRadialGradientPicture (Picture pid,
+ xPointFixed *inner,
+ xPointFixed *outer,
+ xFixed innerRadius,
+ xFixed outerRadius,
+ int nStops,
+ xFixed *stops,
+ xRenderColor *colors,
+ int *error);
+
+PicturePtr
+CreateConicalGradientPicture (Picture pid,
+ xPointFixed *center,
+ xFixed angle,
+ int nStops,
+ xFixed *stops,
+ xRenderColor *colors,
+ int *error);
+
+#ifdef PANORAMIX
+void PanoramiXRenderInit (void);
+void PanoramiXRenderReset (void);
+#endif
+
+#endif /* _PICTURESTR_H_ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.NX.original
new file mode 100644
index 000000000..255411a9b
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.NX.original
@@ -0,0 +1,678 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/*
+ * $Id: picturestr.h,v 1.15 2005/12/09 18:35:21 ajax Exp $
+ *
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+/*
+ * This must keep the same symbol as the original
+ * picturestr.h or symbols will be redefined. We
+ * should define a new types and cast when appro-
+ * priate.
+ */
+
+#ifndef _PICTURESTR_H_
+#define _PICTURESTR_H_
+
+#include "NXglyphstr.h"
+#include "scrnintstr.h"
+#include "resource.h"
+
+typedef struct _DirectFormat {
+ CARD16 red, redMask;
+ CARD16 green, greenMask;
+ CARD16 blue, blueMask;
+ CARD16 alpha, alphaMask;
+} DirectFormatRec;
+
+typedef struct _IndexFormat {
+ VisualID vid;
+ ColormapPtr pColormap;
+ int nvalues;
+ xIndexValue *pValues;
+ void *devPrivate;
+} IndexFormatRec;
+
+typedef struct _PictFormat {
+ CARD32 id;
+ CARD32 format; /* except bpp */
+ unsigned char type;
+ unsigned char depth;
+ DirectFormatRec direct;
+ IndexFormatRec index;
+} PictFormatRec;
+
+typedef struct _PictVector {
+ xFixed vector[3];
+} PictVector, *PictVectorPtr;
+
+typedef struct _PictTransform {
+ xFixed matrix[3][3];
+} PictTransform, *PictTransformPtr;
+
+#define PICT_GRADIENT_STOPTABLE_SIZE 1024
+#define SourcePictTypeSolidFill 0
+#define SourcePictTypeLinear 1
+#define SourcePictTypeRadial 2
+#define SourcePictTypeConical 3
+
+typedef struct _PictSolidFill {
+ unsigned int type;
+ CARD32 color;
+} PictSolidFill, *PictSolidFillPtr;
+
+typedef struct _PictGradientStop {
+ xFixed x;
+ xRenderColor color;
+} PictGradientStop, *PictGradientStopPtr;
+
+typedef struct _PictGradient {
+ unsigned int type;
+ int nstops;
+ PictGradientStopPtr stops;
+ CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+} PictGradient, *PictGradientPtr;
+
+typedef struct _PictLinearGradient {
+ unsigned int type;
+ int nstops;
+ PictGradientStopPtr stops;
+ CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+ xPointFixed p1;
+ xPointFixed p2;
+} PictLinearGradient, *PictLinearGradientPtr;
+
+typedef struct _PictRadialGradient {
+ unsigned int type;
+ int nstops;
+ PictGradientStopPtr stops;
+ CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+ double fx;
+ double fy;
+ double dx;
+ double dy;
+ double a;
+ double m;
+ double b;
+} PictRadialGradient, *PictRadialGradientPtr;
+
+typedef struct _PictConicalGradient {
+ unsigned int type;
+ int nstops;
+ PictGradientStopPtr stops;
+ CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+ xPointFixed center;
+ xFixed angle;
+} PictConicalGradient, *PictConicalGradientPtr;
+
+typedef union _SourcePict {
+ unsigned int type;
+ PictSolidFill solidFill;
+ PictGradient gradient;
+ PictLinearGradient linear;
+ PictRadialGradient radial;
+ PictConicalGradient conical;
+} SourcePict, *SourcePictPtr;
+
+typedef struct _Picture {
+ DrawablePtr pDrawable;
+ PictFormatPtr pFormat;
+ CARD32 format; /* PICT_FORMAT */
+ int refcnt;
+ CARD32 id;
+ PicturePtr pNext; /* chain on same drawable */
+
+ unsigned int repeat : 1;
+ unsigned int graphicsExposures : 1;
+ unsigned int subWindowMode : 1;
+ unsigned int polyEdge : 1;
+ unsigned int polyMode : 1;
+ unsigned int freeCompClip : 1;
+ unsigned int clientClipType : 2;
+ unsigned int componentAlpha : 1;
+ unsigned int repeatType : 2;
+ unsigned int unused : 21;
+
+ PicturePtr alphaMap;
+ DDXPointRec alphaOrigin;
+
+ DDXPointRec clipOrigin;
+ pointer clientClip;
+
+ Atom dither;
+
+ unsigned long stateChanges;
+ unsigned long serialNumber;
+
+ RegionPtr pCompositeClip;
+
+ DevUnion *devPrivates;
+
+ PictTransform *transform;
+
+ int filter;
+ xFixed *filter_params;
+ int filter_nparams;
+ SourcePictPtr pSourcePict;
+} PictureRec;
+
+typedef Bool (*PictFilterValidateParamsProcPtr) (PicturePtr pPicture, int id,
+ xFixed *params, int nparams);
+typedef struct {
+ char *name;
+ int id;
+ PictFilterValidateParamsProcPtr ValidateParams;
+} PictFilterRec, *PictFilterPtr;
+
+#define PictFilterNearest 0
+#define PictFilterBilinear 1
+
+#define PictFilterFast 2
+#define PictFilterGood 3
+#define PictFilterBest 4
+
+#define PictFilterConvolution 5
+
+typedef struct {
+ char *alias;
+ int alias_id;
+ int filter_id;
+} PictFilterAliasRec, *PictFilterAliasPtr;
+
+typedef int (*CreatePictureProcPtr) (PicturePtr pPicture);
+typedef void (*DestroyPictureProcPtr) (PicturePtr pPicture);
+typedef int (*ChangePictureClipProcPtr) (PicturePtr pPicture,
+ int clipType,
+ pointer value,
+ int n);
+typedef void (*DestroyPictureClipProcPtr)(PicturePtr pPicture);
+
+typedef int (*ChangePictureTransformProcPtr) (PicturePtr pPicture,
+ PictTransform *transform);
+
+typedef int (*ChangePictureFilterProcPtr) (PicturePtr pPicture,
+ int filter,
+ xFixed *params,
+ int nparams);
+
+typedef void (*DestroyPictureFilterProcPtr) (PicturePtr pPicture);
+
+typedef void (*ChangePictureProcPtr) (PicturePtr pPicture,
+ Mask mask);
+typedef void (*ValidatePictureProcPtr) (PicturePtr pPicture,
+ Mask mask);
+typedef void (*CompositeProcPtr) (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+typedef void (*GlyphsProcPtr) (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlists,
+ GlyphListPtr lists,
+ GlyphPtr *glyphs);
+
+typedef void (*CompositeRectsProcPtr) (CARD8 op,
+ PicturePtr pDst,
+ xRenderColor *color,
+ int nRect,
+ xRectangle *rects);
+
+typedef void (*RasterizeTrapezoidProcPtr)(PicturePtr pMask,
+ xTrapezoid *trap,
+ int x_off,
+ int y_off);
+
+typedef void (*TrapezoidsProcPtr) (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntrap,
+ xTrapezoid *traps);
+
+typedef void (*TrianglesProcPtr) (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntri,
+ xTriangle *tris);
+
+typedef void (*TriStripProcPtr) (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoint,
+ xPointFixed *points);
+
+typedef void (*TriFanProcPtr) (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoint,
+ xPointFixed *points);
+
+typedef Bool (*InitIndexedProcPtr) (ScreenPtr pScreen,
+ PictFormatPtr pFormat);
+
+typedef void (*CloseIndexedProcPtr) (ScreenPtr pScreen,
+ PictFormatPtr pFormat);
+
+typedef void (*UpdateIndexedProcPtr) (ScreenPtr pScreen,
+ PictFormatPtr pFormat,
+ int ndef,
+ xColorItem *pdef);
+
+typedef void (*AddTrapsProcPtr) (PicturePtr pPicture,
+ INT16 xOff,
+ INT16 yOff,
+ int ntrap,
+ xTrap *traps);
+
+typedef void (*AddTrianglesProcPtr) (PicturePtr pPicture,
+ INT16 xOff,
+ INT16 yOff,
+ int ntri,
+ xTriangle *tris);
+
+typedef struct _PictureScreen {
+ int totalPictureSize;
+ unsigned int *PicturePrivateSizes;
+ int PicturePrivateLen;
+
+ PictFormatPtr formats;
+ PictFormatPtr fallback;
+ int nformats;
+
+ CreatePictureProcPtr CreatePicture;
+ DestroyPictureProcPtr DestroyPicture;
+ ChangePictureClipProcPtr ChangePictureClip;
+ DestroyPictureClipProcPtr DestroyPictureClip;
+
+ ChangePictureProcPtr ChangePicture;
+ ValidatePictureProcPtr ValidatePicture;
+
+ CompositeProcPtr Composite;
+ GlyphsProcPtr Glyphs;
+ CompositeRectsProcPtr CompositeRects;
+
+ DestroyWindowProcPtr DestroyWindow;
+ CloseScreenProcPtr CloseScreen;
+
+ StoreColorsProcPtr StoreColors;
+
+ InitIndexedProcPtr InitIndexed;
+ CloseIndexedProcPtr CloseIndexed;
+ UpdateIndexedProcPtr UpdateIndexed;
+
+ int subpixel;
+
+ PictFilterPtr filters;
+ int nfilters;
+ PictFilterAliasPtr filterAliases;
+ int nfilterAliases;
+
+ ChangePictureTransformProcPtr ChangePictureTransform;
+ ChangePictureFilterProcPtr ChangePictureFilter;
+ DestroyPictureFilterProcPtr DestroyPictureFilter;
+
+ TrapezoidsProcPtr Trapezoids;
+ TrianglesProcPtr Triangles;
+ TriStripProcPtr TriStrip;
+ TriFanProcPtr TriFan;
+
+ RasterizeTrapezoidProcPtr RasterizeTrapezoid;
+
+ AddTrianglesProcPtr AddTriangles;
+
+ AddTrapsProcPtr AddTraps;
+
+} PictureScreenRec, *PictureScreenPtr;
+
+extern int PictureScreenPrivateIndex;
+extern int PictureWindowPrivateIndex;
+extern RESTYPE PictureType;
+extern RESTYPE PictFormatType;
+extern RESTYPE GlyphSetType;
+
+#define GetPictureScreen(s) ((PictureScreenPtr) ((s)->devPrivates[PictureScreenPrivateIndex].ptr))
+#define GetPictureScreenIfSet(s) ((PictureScreenPrivateIndex != -1) ? GetPictureScreen(s) : NULL)
+#define SetPictureScreen(s,p) ((s)->devPrivates[PictureScreenPrivateIndex].ptr = (pointer) (p))
+#define GetPictureWindow(w) ((PicturePtr) ((w)->devPrivates[PictureWindowPrivateIndex].ptr))
+#define SetPictureWindow(w,p) ((w)->devPrivates[PictureWindowPrivateIndex].ptr = (pointer) (p))
+
+#define VERIFY_PICTURE(pPicture, pid, client, mode, err) {\
+ pPicture = SecurityLookupIDByType(client, pid, PictureType, mode);\
+ if (!pPicture) { \
+ client->errorValue = pid; \
+ return err; \
+ } \
+}
+
+#define VERIFY_ALPHA(pPicture, pid, client, mode, err) {\
+ if (pid == None) \
+ pPicture = 0; \
+ else { \
+ VERIFY_PICTURE(pPicture, pid, client, mode, err); \
+ } \
+} \
+
+void
+ResetPicturePrivateIndex (void);
+
+int
+AllocatePicturePrivateIndex (void);
+
+Bool
+AllocatePicturePrivate (ScreenPtr pScreen, int index2, unsigned int amount);
+
+Bool
+PictureDestroyWindow (WindowPtr pWindow);
+
+Bool
+PictureCloseScreen (int Index, ScreenPtr pScreen);
+
+void
+PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef);
+
+Bool
+PictureInitIndexedFormats (ScreenPtr pScreen);
+
+Bool
+PictureSetSubpixelOrder (ScreenPtr pScreen, int subpixel);
+
+int
+PictureGetSubpixelOrder (ScreenPtr pScreen);
+
+PictFormatPtr
+PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp);
+
+PictFormatPtr
+PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual);
+
+PictFormatPtr
+PictureMatchFormat (ScreenPtr pScreen, int depth, CARD32 format);
+
+Bool
+PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
+
+int
+PictureGetFilterId (char *filter, int len, Bool makeit);
+
+char *
+PictureGetFilterName (int id);
+
+int
+PictureAddFilter (ScreenPtr pScreen,
+ char *filter,
+ PictFilterValidateParamsProcPtr ValidateParams);
+
+Bool
+PictureSetFilterAlias (ScreenPtr pScreen, char *filter, char *alias);
+
+Bool
+PictureSetDefaultFilters (ScreenPtr pScreen);
+
+void
+PictureResetFilters (ScreenPtr pScreen);
+
+PictFilterPtr
+PictureFindFilter (ScreenPtr pScreen, char *name, int len);
+
+int
+SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int nparams);
+
+Bool
+PictureFinishInit (void);
+
+void
+SetPictureToDefaults (PicturePtr pPicture);
+
+PicturePtr
+AllocatePicture (ScreenPtr pScreen);
+
+#if 0
+Bool
+miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
+#endif
+
+
+PicturePtr
+CreatePicture (Picture pid,
+ DrawablePtr pDrawable,
+ PictFormatPtr pFormat,
+ Mask mask,
+ XID *list,
+ ClientPtr client,
+ int *error);
+
+int
+ChangePicture (PicturePtr pPicture,
+ Mask vmask,
+ XID *vlist,
+ DevUnion *ulist,
+ ClientPtr client);
+
+int
+SetPictureClipRects (PicturePtr pPicture,
+ int xOrigin,
+ int yOrigin,
+ int nRect,
+ xRectangle *rects);
+
+int
+SetPictureClipRegion (PicturePtr pPicture,
+ int xOrigin,
+ int yOrigin,
+ RegionPtr pRegion);
+
+int
+SetPictureTransform (PicturePtr pPicture,
+ PictTransform *transform);
+
+void
+CopyPicture (PicturePtr pSrc,
+ Mask mask,
+ PicturePtr pDst);
+
+void
+ValidatePicture(PicturePtr pPicture);
+
+int
+FreePicture (pointer pPicture,
+ XID pid);
+
+int
+FreePictFormat (pointer pPictFormat,
+ XID pid);
+
+void
+CompositePicture (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+void
+CompositeGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr lists,
+ GlyphPtr *glyphs);
+
+void
+CompositeRects (CARD8 op,
+ PicturePtr pDst,
+ xRenderColor *color,
+ int nRect,
+ xRectangle *rects);
+
+void
+CompositeTrapezoids (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntrap,
+ xTrapezoid *traps);
+
+void
+CompositeTriangles (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntriangles,
+ xTriangle *triangles);
+
+void
+CompositeTriStrip (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoints,
+ xPointFixed *points);
+
+void
+CompositeTriFan (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoints,
+ xPointFixed *points);
+
+Bool
+PictureTransformPoint (PictTransformPtr transform,
+ PictVectorPtr vector);
+
+Bool
+PictureTransformPoint3d (PictTransformPtr transform,
+ PictVectorPtr vector);
+
+void RenderExtensionInit (void);
+
+Bool
+AnimCurInit (ScreenPtr pScreen);
+
+int
+AnimCursorCreate (CursorPtr *cursors, CARD32 *deltas, int ncursor, CursorPtr *ppCursor);
+
+void
+AddTraps (PicturePtr pPicture,
+ INT16 xOff,
+ INT16 yOff,
+ int ntraps,
+ xTrap *traps);
+
+PicturePtr
+CreateSolidPicture (Picture pid,
+ xRenderColor *color,
+ int *error);
+
+PicturePtr
+CreateLinearGradientPicture (Picture pid,
+ xPointFixed *p1,
+ xPointFixed *p2,
+ int nStops,
+ xFixed *stops,
+ xRenderColor *colors,
+ int *error);
+
+PicturePtr
+CreateRadialGradientPicture (Picture pid,
+ xPointFixed *inner,
+ xPointFixed *outer,
+ xFixed innerRadius,
+ xFixed outerRadius,
+ int nStops,
+ xFixed *stops,
+ xRenderColor *colors,
+ int *error);
+
+PicturePtr
+CreateConicalGradientPicture (Picture pid,
+ xPointFixed *center,
+ xFixed angle,
+ int nStops,
+ xFixed *stops,
+ xRenderColor *colors,
+ int *error);
+
+#ifdef PANORAMIX
+void PanoramiXRenderInit (void);
+void PanoramiXRenderReset (void);
+#endif
+
+#endif /* _PICTURESTR_H_ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.X.original
new file mode 100644
index 000000000..4775793ab
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.X.original
@@ -0,0 +1,654 @@
+/*
+ * $Id: picturestr.h,v 1.15 2005/12/09 18:35:21 ajax Exp $
+ *
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifndef _PICTURESTR_H_
+#define _PICTURESTR_H_
+
+#include "glyphstr.h"
+#include "scrnintstr.h"
+#include "resource.h"
+
+typedef struct _DirectFormat {
+ CARD16 red, redMask;
+ CARD16 green, greenMask;
+ CARD16 blue, blueMask;
+ CARD16 alpha, alphaMask;
+} DirectFormatRec;
+
+typedef struct _IndexFormat {
+ VisualID vid;
+ ColormapPtr pColormap;
+ int nvalues;
+ xIndexValue *pValues;
+ void *devPrivate;
+} IndexFormatRec;
+
+typedef struct _PictFormat {
+ CARD32 id;
+ CARD32 format; /* except bpp */
+ unsigned char type;
+ unsigned char depth;
+ DirectFormatRec direct;
+ IndexFormatRec index;
+} PictFormatRec;
+
+typedef struct _PictVector {
+ xFixed vector[3];
+} PictVector, *PictVectorPtr;
+
+typedef struct _PictTransform {
+ xFixed matrix[3][3];
+} PictTransform, *PictTransformPtr;
+
+#define PICT_GRADIENT_STOPTABLE_SIZE 1024
+#define SourcePictTypeSolidFill 0
+#define SourcePictTypeLinear 1
+#define SourcePictTypeRadial 2
+#define SourcePictTypeConical 3
+
+typedef struct _PictSolidFill {
+ unsigned int type;
+ CARD32 color;
+} PictSolidFill, *PictSolidFillPtr;
+
+typedef struct _PictGradientStop {
+ xFixed x;
+ xRenderColor color;
+} PictGradientStop, *PictGradientStopPtr;
+
+typedef struct _PictGradient {
+ unsigned int type;
+ int nstops;
+ PictGradientStopPtr stops;
+ CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+} PictGradient, *PictGradientPtr;
+
+typedef struct _PictLinearGradient {
+ unsigned int type;
+ int nstops;
+ PictGradientStopPtr stops;
+ CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+ xPointFixed p1;
+ xPointFixed p2;
+} PictLinearGradient, *PictLinearGradientPtr;
+
+typedef struct _PictRadialGradient {
+ unsigned int type;
+ int nstops;
+ PictGradientStopPtr stops;
+ CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+ double fx;
+ double fy;
+ double dx;
+ double dy;
+ double a;
+ double m;
+ double b;
+} PictRadialGradient, *PictRadialGradientPtr;
+
+typedef struct _PictConicalGradient {
+ unsigned int type;
+ int nstops;
+ PictGradientStopPtr stops;
+ CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+ xPointFixed center;
+ xFixed angle;
+} PictConicalGradient, *PictConicalGradientPtr;
+
+typedef union _SourcePict {
+ unsigned int type;
+ PictSolidFill solidFill;
+ PictGradient gradient;
+ PictLinearGradient linear;
+ PictRadialGradient radial;
+ PictConicalGradient conical;
+} SourcePict, *SourcePictPtr;
+
+typedef struct _Picture {
+ DrawablePtr pDrawable;
+ PictFormatPtr pFormat;
+ CARD32 format; /* PICT_FORMAT */
+ int refcnt;
+ CARD32 id;
+ PicturePtr pNext; /* chain on same drawable */
+
+ unsigned int repeat : 1;
+ unsigned int graphicsExposures : 1;
+ unsigned int subWindowMode : 1;
+ unsigned int polyEdge : 1;
+ unsigned int polyMode : 1;
+ unsigned int freeCompClip : 1;
+ unsigned int clientClipType : 2;
+ unsigned int componentAlpha : 1;
+ unsigned int repeatType : 2;
+ unsigned int unused : 21;
+
+ PicturePtr alphaMap;
+ DDXPointRec alphaOrigin;
+
+ DDXPointRec clipOrigin;
+ pointer clientClip;
+
+ Atom dither;
+
+ unsigned long stateChanges;
+ unsigned long serialNumber;
+
+ RegionPtr pCompositeClip;
+
+ DevUnion *devPrivates;
+
+ PictTransform *transform;
+
+ int filter;
+ xFixed *filter_params;
+ int filter_nparams;
+ SourcePictPtr pSourcePict;
+} PictureRec;
+
+typedef Bool (*PictFilterValidateParamsProcPtr) (PicturePtr pPicture, int id,
+ xFixed *params, int nparams);
+typedef struct {
+ char *name;
+ int id;
+ PictFilterValidateParamsProcPtr ValidateParams;
+} PictFilterRec, *PictFilterPtr;
+
+#define PictFilterNearest 0
+#define PictFilterBilinear 1
+
+#define PictFilterFast 2
+#define PictFilterGood 3
+#define PictFilterBest 4
+
+#define PictFilterConvolution 5
+
+typedef struct {
+ char *alias;
+ int alias_id;
+ int filter_id;
+} PictFilterAliasRec, *PictFilterAliasPtr;
+
+typedef int (*CreatePictureProcPtr) (PicturePtr pPicture);
+typedef void (*DestroyPictureProcPtr) (PicturePtr pPicture);
+typedef int (*ChangePictureClipProcPtr) (PicturePtr pPicture,
+ int clipType,
+ pointer value,
+ int n);
+typedef void (*DestroyPictureClipProcPtr)(PicturePtr pPicture);
+
+typedef int (*ChangePictureTransformProcPtr) (PicturePtr pPicture,
+ PictTransform *transform);
+
+typedef int (*ChangePictureFilterProcPtr) (PicturePtr pPicture,
+ int filter,
+ xFixed *params,
+ int nparams);
+
+typedef void (*DestroyPictureFilterProcPtr) (PicturePtr pPicture);
+
+typedef void (*ChangePictureProcPtr) (PicturePtr pPicture,
+ Mask mask);
+typedef void (*ValidatePictureProcPtr) (PicturePtr pPicture,
+ Mask mask);
+typedef void (*CompositeProcPtr) (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+typedef void (*GlyphsProcPtr) (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlists,
+ GlyphListPtr lists,
+ GlyphPtr *glyphs);
+
+typedef void (*CompositeRectsProcPtr) (CARD8 op,
+ PicturePtr pDst,
+ xRenderColor *color,
+ int nRect,
+ xRectangle *rects);
+
+typedef void (*RasterizeTrapezoidProcPtr)(PicturePtr pMask,
+ xTrapezoid *trap,
+ int x_off,
+ int y_off);
+
+typedef void (*TrapezoidsProcPtr) (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntrap,
+ xTrapezoid *traps);
+
+typedef void (*TrianglesProcPtr) (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntri,
+ xTriangle *tris);
+
+typedef void (*TriStripProcPtr) (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoint,
+ xPointFixed *points);
+
+typedef void (*TriFanProcPtr) (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoint,
+ xPointFixed *points);
+
+typedef Bool (*InitIndexedProcPtr) (ScreenPtr pScreen,
+ PictFormatPtr pFormat);
+
+typedef void (*CloseIndexedProcPtr) (ScreenPtr pScreen,
+ PictFormatPtr pFormat);
+
+typedef void (*UpdateIndexedProcPtr) (ScreenPtr pScreen,
+ PictFormatPtr pFormat,
+ int ndef,
+ xColorItem *pdef);
+
+typedef void (*AddTrapsProcPtr) (PicturePtr pPicture,
+ INT16 xOff,
+ INT16 yOff,
+ int ntrap,
+ xTrap *traps);
+
+typedef void (*AddTrianglesProcPtr) (PicturePtr pPicture,
+ INT16 xOff,
+ INT16 yOff,
+ int ntri,
+ xTriangle *tris);
+
+typedef struct _PictureScreen {
+ int totalPictureSize;
+ unsigned int *PicturePrivateSizes;
+ int PicturePrivateLen;
+
+ PictFormatPtr formats;
+ PictFormatPtr fallback;
+ int nformats;
+
+ CreatePictureProcPtr CreatePicture;
+ DestroyPictureProcPtr DestroyPicture;
+ ChangePictureClipProcPtr ChangePictureClip;
+ DestroyPictureClipProcPtr DestroyPictureClip;
+
+ ChangePictureProcPtr ChangePicture;
+ ValidatePictureProcPtr ValidatePicture;
+
+ CompositeProcPtr Composite;
+ GlyphsProcPtr Glyphs;
+ CompositeRectsProcPtr CompositeRects;
+
+ DestroyWindowProcPtr DestroyWindow;
+ CloseScreenProcPtr CloseScreen;
+
+ StoreColorsProcPtr StoreColors;
+
+ InitIndexedProcPtr InitIndexed;
+ CloseIndexedProcPtr CloseIndexed;
+ UpdateIndexedProcPtr UpdateIndexed;
+
+ int subpixel;
+
+ PictFilterPtr filters;
+ int nfilters;
+ PictFilterAliasPtr filterAliases;
+ int nfilterAliases;
+
+ ChangePictureTransformProcPtr ChangePictureTransform;
+ ChangePictureFilterProcPtr ChangePictureFilter;
+ DestroyPictureFilterProcPtr DestroyPictureFilter;
+
+ TrapezoidsProcPtr Trapezoids;
+ TrianglesProcPtr Triangles;
+ TriStripProcPtr TriStrip;
+ TriFanProcPtr TriFan;
+
+ RasterizeTrapezoidProcPtr RasterizeTrapezoid;
+
+ AddTrianglesProcPtr AddTriangles;
+
+ AddTrapsProcPtr AddTraps;
+
+} PictureScreenRec, *PictureScreenPtr;
+
+extern int PictureScreenPrivateIndex;
+extern int PictureWindowPrivateIndex;
+extern RESTYPE PictureType;
+extern RESTYPE PictFormatType;
+extern RESTYPE GlyphSetType;
+
+#define GetPictureScreen(s) ((PictureScreenPtr) ((s)->devPrivates[PictureScreenPrivateIndex].ptr))
+#define GetPictureScreenIfSet(s) ((PictureScreenPrivateIndex != -1) ? GetPictureScreen(s) : NULL)
+#define SetPictureScreen(s,p) ((s)->devPrivates[PictureScreenPrivateIndex].ptr = (pointer) (p))
+#define GetPictureWindow(w) ((PicturePtr) ((w)->devPrivates[PictureWindowPrivateIndex].ptr))
+#define SetPictureWindow(w,p) ((w)->devPrivates[PictureWindowPrivateIndex].ptr = (pointer) (p))
+
+#define VERIFY_PICTURE(pPicture, pid, client, mode, err) {\
+ pPicture = SecurityLookupIDByType(client, pid, PictureType, mode);\
+ if (!pPicture) { \
+ client->errorValue = pid; \
+ return err; \
+ } \
+}
+
+#define VERIFY_ALPHA(pPicture, pid, client, mode, err) {\
+ if (pid == None) \
+ pPicture = 0; \
+ else { \
+ VERIFY_PICTURE(pPicture, pid, client, mode, err); \
+ } \
+} \
+
+void
+ResetPicturePrivateIndex (void);
+
+int
+AllocatePicturePrivateIndex (void);
+
+Bool
+AllocatePicturePrivate (ScreenPtr pScreen, int index2, unsigned int amount);
+
+Bool
+PictureDestroyWindow (WindowPtr pWindow);
+
+Bool
+PictureCloseScreen (int Index, ScreenPtr pScreen);
+
+void
+PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef);
+
+Bool
+PictureInitIndexedFormats (ScreenPtr pScreen);
+
+Bool
+PictureSetSubpixelOrder (ScreenPtr pScreen, int subpixel);
+
+int
+PictureGetSubpixelOrder (ScreenPtr pScreen);
+
+PictFormatPtr
+PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp);
+
+PictFormatPtr
+PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual);
+
+PictFormatPtr
+PictureMatchFormat (ScreenPtr pScreen, int depth, CARD32 format);
+
+Bool
+PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
+
+int
+PictureGetFilterId (char *filter, int len, Bool makeit);
+
+char *
+PictureGetFilterName (int id);
+
+int
+PictureAddFilter (ScreenPtr pScreen,
+ char *filter,
+ PictFilterValidateParamsProcPtr ValidateParams);
+
+Bool
+PictureSetFilterAlias (ScreenPtr pScreen, char *filter, char *alias);
+
+Bool
+PictureSetDefaultFilters (ScreenPtr pScreen);
+
+void
+PictureResetFilters (ScreenPtr pScreen);
+
+PictFilterPtr
+PictureFindFilter (ScreenPtr pScreen, char *name, int len);
+
+int
+SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int nparams);
+
+Bool
+PictureFinishInit (void);
+
+void
+SetPictureToDefaults (PicturePtr pPicture);
+
+PicturePtr
+AllocatePicture (ScreenPtr pScreen);
+
+#if 0
+Bool
+miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
+#endif
+
+
+PicturePtr
+CreatePicture (Picture pid,
+ DrawablePtr pDrawable,
+ PictFormatPtr pFormat,
+ Mask mask,
+ XID *list,
+ ClientPtr client,
+ int *error);
+
+int
+ChangePicture (PicturePtr pPicture,
+ Mask vmask,
+ XID *vlist,
+ DevUnion *ulist,
+ ClientPtr client);
+
+int
+SetPictureClipRects (PicturePtr pPicture,
+ int xOrigin,
+ int yOrigin,
+ int nRect,
+ xRectangle *rects);
+
+int
+SetPictureClipRegion (PicturePtr pPicture,
+ int xOrigin,
+ int yOrigin,
+ RegionPtr pRegion);
+
+int
+SetPictureTransform (PicturePtr pPicture,
+ PictTransform *transform);
+
+void
+CopyPicture (PicturePtr pSrc,
+ Mask mask,
+ PicturePtr pDst);
+
+void
+ValidatePicture(PicturePtr pPicture);
+
+int
+FreePicture (pointer pPicture,
+ XID pid);
+
+int
+FreePictFormat (pointer pPictFormat,
+ XID pid);
+
+void
+CompositePicture (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+void
+CompositeGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr lists,
+ GlyphPtr *glyphs);
+
+void
+CompositeRects (CARD8 op,
+ PicturePtr pDst,
+ xRenderColor *color,
+ int nRect,
+ xRectangle *rects);
+
+void
+CompositeTrapezoids (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntrap,
+ xTrapezoid *traps);
+
+void
+CompositeTriangles (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntriangles,
+ xTriangle *triangles);
+
+void
+CompositeTriStrip (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoints,
+ xPointFixed *points);
+
+void
+CompositeTriFan (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoints,
+ xPointFixed *points);
+
+Bool
+PictureTransformPoint (PictTransformPtr transform,
+ PictVectorPtr vector);
+
+Bool
+PictureTransformPoint3d (PictTransformPtr transform,
+ PictVectorPtr vector);
+
+void RenderExtensionInit (void);
+
+Bool
+AnimCurInit (ScreenPtr pScreen);
+
+int
+AnimCursorCreate (CursorPtr *cursors, CARD32 *deltas, int ncursor, CursorPtr *ppCursor);
+
+void
+AddTraps (PicturePtr pPicture,
+ INT16 xOff,
+ INT16 yOff,
+ int ntraps,
+ xTrap *traps);
+
+PicturePtr
+CreateSolidPicture (Picture pid,
+ xRenderColor *color,
+ int *error);
+
+PicturePtr
+CreateLinearGradientPicture (Picture pid,
+ xPointFixed *p1,
+ xPointFixed *p2,
+ int nStops,
+ xFixed *stops,
+ xRenderColor *colors,
+ int *error);
+
+PicturePtr
+CreateRadialGradientPicture (Picture pid,
+ xPointFixed *inner,
+ xPointFixed *outer,
+ xFixed innerRadius,
+ xFixed outerRadius,
+ int nStops,
+ xFixed *stops,
+ xRenderColor *colors,
+ int *error);
+
+PicturePtr
+CreateConicalGradientPicture (Picture pid,
+ xPointFixed *center,
+ xFixed angle,
+ int nStops,
+ xFixed *stops,
+ xRenderColor *colors,
+ int *error);
+
+#ifdef PANORAMIX
+void PanoramiXRenderInit (void);
+void PanoramiXRenderReset (void);
+#endif
+
+#endif /* _PICTURESTR_H_ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c
new file mode 100644
index 000000000..3d08a3228
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c
@@ -0,0 +1,904 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/property.c,v 3.12 2002/02/19 11:09:22 alanh Exp $ */
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+/* $Xorg: property.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include <X11/Xproto.h>
+#include "windowstr.h"
+#include "propertyst.h"
+#include "dixstruct.h"
+#include "../../dix/dispatch.h"
+#include "swaprep.h"
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+#ifdef LBX
+#include "lbxserve.h"
+#include "lbxtags.h"
+#endif
+
+#include "Options.h"
+#include "Rootless.h"
+#include "Client.h"
+
+#if defined(LBX) || defined(LBX_COMPAT)
+#if 0 /* no header in X11 environment, not used in X11 environment */
+int fWriteToClient(ClientPtr client, int len, char *buf)
+{
+ return WriteToClient(client, len, buf);
+}
+#endif
+#endif
+
+/*****************************************************************
+ * Property Stuff
+ *
+ * ChangeProperty, DeleteProperty, GetProperties,
+ * ListProperties
+ *
+ * Properties below to windows. A allocate slots each time
+ * a property is added. No fancy searching done.
+ *
+ *****************************************************************/
+
+#ifdef notdef
+static void
+PrintPropertys(WindowPtr pWin)
+{
+ PropertyPtr pProp;
+ register int j;
+
+ pProp = pWin->userProps;
+ while (pProp)
+ {
+ ErrorF( "%x %x\n", pProp->propertyName, pProp->type);
+ ErrorF("property format: %d\n", pProp->format);
+ ErrorF("property data: \n");
+ for (j=0; j<(pProp->format/8)*pProp->size; j++)
+ ErrorF("%c\n", pProp->data[j]);
+ pProp = pProp->next;
+ }
+}
+#endif
+
+int
+ProcRotateProperties(ClientPtr client)
+{
+ int i, j, delta;
+ REQUEST(xRotatePropertiesReq);
+ WindowPtr pWin;
+ register Atom * atoms;
+ PropertyPtr * props; /* array of pointer */
+ PropertyPtr pProp;
+ xEvent event;
+
+ REQUEST_FIXED_SIZE(xRotatePropertiesReq, stuff->nAtoms << 2);
+ UpdateCurrentTime();
+ pWin = (WindowPtr) SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (!stuff->nAtoms)
+ return(Success);
+ atoms = (Atom *) & stuff[1];
+ props = (PropertyPtr *)ALLOCATE_LOCAL(stuff->nAtoms * sizeof(PropertyPtr));
+ if (!props)
+ return(BadAlloc);
+ for (i = 0; i < stuff->nAtoms; i++)
+ {
+#ifdef XCSECURITY
+ char action = SecurityCheckPropertyAccess(client, pWin, atoms[i],
+ SecurityReadAccess|SecurityWriteAccess);
+#endif
+ if (!ValidAtom(atoms[i])
+#ifdef XCSECURITY
+ || (SecurityErrorOperation == action)
+#endif
+ )
+ {
+ DEALLOCATE_LOCAL(props);
+ client->errorValue = atoms[i];
+ return BadAtom;
+ }
+#ifdef XCSECURITY
+ if (SecurityIgnoreOperation == action)
+ {
+ DEALLOCATE_LOCAL(props);
+ return Success;
+ }
+#endif
+ for (j = i + 1; j < stuff->nAtoms; j++)
+ if (atoms[j] == atoms[i])
+ {
+ DEALLOCATE_LOCAL(props);
+ return BadMatch;
+ }
+ pProp = wUserProps (pWin);
+ while (pProp)
+ {
+ if (pProp->propertyName == atoms[i])
+ goto found;
+ pProp = pProp->next;
+ }
+ DEALLOCATE_LOCAL(props);
+ return BadMatch;
+found:
+ props[i] = pProp;
+ }
+ delta = stuff->nPositions;
+
+ /* If the rotation is a complete 360 degrees, then moving the properties
+ around and generating PropertyNotify events should be skipped. */
+
+ if ( (stuff->nAtoms != 0) && (abs(delta) % stuff->nAtoms) != 0 )
+ {
+ while (delta < 0) /* faster if abs value is small */
+ delta += stuff->nAtoms;
+ for (i = 0; i < stuff->nAtoms; i++)
+ {
+ /* Generate a PropertyNotify event for each property whose value
+ is changed in the order in which they appear in the request. */
+
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyNewValue;
+ event.u.property.atom = props[i]->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+
+ props[i]->propertyName = atoms[(i + delta) % stuff->nAtoms];
+ }
+ }
+ DEALLOCATE_LOCAL(props);
+ return Success;
+}
+
+int
+ProcChangeProperty(ClientPtr client)
+{
+ WindowPtr pWin;
+ char format, mode;
+ unsigned long len;
+ int sizeInBytes;
+ int totalSize;
+ int err;
+ REQUEST(xChangePropertyReq);
+
+ REQUEST_AT_LEAST_SIZE(xChangePropertyReq);
+ UpdateCurrentTime();
+ format = stuff->format;
+ mode = stuff->mode;
+ if ((mode != PropModeReplace) && (mode != PropModeAppend) &&
+ (mode != PropModePrepend))
+ {
+ client->errorValue = mode;
+ return BadValue;
+ }
+ if ((format != 8) && (format != 16) && (format != 32))
+ {
+ client->errorValue = format;
+ return BadValue;
+ }
+ len = stuff->nUnits;
+ if (len > ((0xffffffff - sizeof(xChangePropertyReq)) >> 2))
+ return BadLength;
+ sizeInBytes = format>>3;
+ totalSize = len * sizeInBytes;
+ REQUEST_FIXED_SIZE(xChangePropertyReq, totalSize);
+
+#ifdef NXAGENT_CLIPBOARD
+ {
+ extern WindowPtr nxagentGetClipboardWindow(Atom, WindowPtr);
+
+ pWin = nxagentGetClipboardWindow(stuff->property, NULL);
+ }
+
+ if (pWin == NULL)
+#endif
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (!ValidAtom(stuff->property))
+ {
+ client->errorValue = stuff->property;
+ return(BadAtom);
+ }
+ if (!ValidAtom(stuff->type))
+ {
+ client->errorValue = stuff->type;
+ return(BadAtom);
+ }
+
+#ifdef XCSECURITY
+ switch (SecurityCheckPropertyAccess(client, pWin, stuff->property,
+ SecurityWriteAccess))
+ {
+ case SecurityErrorOperation:
+ client->errorValue = stuff->property;
+ return BadAtom;
+ case SecurityIgnoreOperation:
+ return Success;
+ }
+#endif
+
+#ifdef NXAGENT_ARTSD
+ {
+ /* Do not process MCOPGLOBALS property changes,
+ they are already set reflecting the server side settings.
+ Just return success.
+ */
+ extern Atom mcop_local_atom;
+ if (stuff->property == mcop_local_atom)
+ return client->noClientException;
+ }
+#endif
+
+#ifdef LBX
+ err = LbxChangeWindowProperty(client, pWin, stuff->property, stuff->type,
+ (int)format, (int)mode, len, TRUE, (pointer)&stuff[1], TRUE, NULL);
+#else
+ err = ChangeWindowProperty(pWin, stuff->property, stuff->type, (int)format,
+ (int)mode, len, (pointer)&stuff[1], TRUE);
+#endif
+ if (err != Success)
+ return err;
+ else
+ {
+ if (nxagentOption(Rootless) == 1)
+ {
+ nxagentExportProperty(pWin, stuff->property, stuff->type, (int) format,
+ (int) mode, len, (pointer) &stuff[1]);
+ }
+
+ nxagentGuessClientHint(client, stuff->property, (char *) &stuff[1]);
+
+ nxagentGuessShadowHint(client, stuff->property);
+
+ return client->noClientException;
+ }
+}
+
+int
+ChangeWindowProperty(WindowPtr pWin, Atom property, Atom type, int format,
+ int mode, unsigned long len, pointer value,
+ Bool sendevent)
+{
+#ifdef LBX
+ return LbxChangeWindowProperty(NULL, pWin, property, type,
+ format, mode, len, TRUE, value,
+ sendevent, NULL);
+#else
+ PropertyPtr pProp;
+ xEvent event;
+ int sizeInBytes;
+ int totalSize;
+ pointer data;
+
+ sizeInBytes = format>>3;
+ totalSize = len * sizeInBytes;
+
+ /* first see if property already exists */
+
+ pProp = wUserProps (pWin);
+ while (pProp)
+ {
+ if (pProp->propertyName == property)
+ break;
+ pProp = pProp->next;
+ }
+ if (!pProp) /* just add to list */
+ {
+ if (!pWin->optional && !MakeWindowOptional (pWin))
+ return(BadAlloc);
+ pProp = (PropertyPtr)xalloc(sizeof(PropertyRec));
+ if (!pProp)
+ return(BadAlloc);
+ data = (pointer)xalloc(totalSize);
+ if (!data && len)
+ {
+ xfree(pProp);
+ return(BadAlloc);
+ }
+ pProp->propertyName = property;
+ pProp->type = type;
+ pProp->format = format;
+ pProp->data = data;
+ if (len)
+ memmove((char *)data, (char *)value, totalSize);
+ pProp->size = len;
+ pProp->next = pWin->optional->userProps;
+ pWin->optional->userProps = pProp;
+ }
+ else
+ {
+ /* To append or prepend to a property the request format and type
+ must match those of the already defined property. The
+ existing format and type are irrelevant when using the mode
+ "PropModeReplace" since they will be written over. */
+
+ if ((format != pProp->format) && (mode != PropModeReplace))
+ return(BadMatch);
+ if ((pProp->type != type) && (mode != PropModeReplace))
+ return(BadMatch);
+ if (mode == PropModeReplace)
+ {
+ if (totalSize != pProp->size * (pProp->format >> 3))
+ {
+ data = (pointer)xrealloc(pProp->data, totalSize);
+ if (!data && len)
+ return(BadAlloc);
+ pProp->data = data;
+ }
+ if (len)
+ memmove((char *)pProp->data, (char *)value, totalSize);
+ pProp->size = len;
+ pProp->type = type;
+ pProp->format = format;
+ }
+ else if (len == 0)
+ {
+ /* do nothing */
+ }
+ else if (mode == PropModeAppend)
+ {
+ data = (pointer)xrealloc(pProp->data,
+ sizeInBytes * (len + pProp->size));
+ if (!data)
+ return(BadAlloc);
+ pProp->data = data;
+ memmove(&((char *)data)[pProp->size * sizeInBytes],
+ (char *)value,
+ totalSize);
+ pProp->size += len;
+ }
+ else if (mode == PropModePrepend)
+ {
+ data = (pointer)xalloc(sizeInBytes * (len + pProp->size));
+ if (!data)
+ return(BadAlloc);
+ memmove(&((char *)data)[totalSize], (char *)pProp->data,
+ (int)(pProp->size * sizeInBytes));
+ memmove((char *)data, (char *)value, totalSize);
+ xfree(pProp->data);
+ pProp->data = data;
+ pProp->size += len;
+ }
+ }
+ if (sendevent)
+ {
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyNewValue;
+ event.u.property.atom = pProp->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+ }
+ return(Success);
+#endif
+}
+
+int
+DeleteProperty(WindowPtr pWin, Atom propName)
+{
+ PropertyPtr pProp, prevProp;
+ xEvent event;
+
+ if (!(pProp = wUserProps (pWin)))
+ return(Success);
+ prevProp = (PropertyPtr)NULL;
+ while (pProp)
+ {
+ if (pProp->propertyName == propName)
+ break;
+ prevProp = pProp;
+ pProp = pProp->next;
+ }
+ if (pProp)
+ {
+ if (prevProp == (PropertyPtr)NULL) /* takes care of head */
+ {
+ if (!(pWin->optional->userProps = pProp->next))
+ CheckWindowOptionalNeed (pWin);
+ }
+ else
+ {
+ prevProp->next = pProp->next;
+ }
+#ifdef LBX
+ if (pProp->tag_id)
+ TagDeleteTag(pProp->tag_id);
+#endif
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyDelete;
+ event.u.property.atom = pProp->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+ xfree(pProp->data);
+ xfree(pProp);
+ }
+ return(Success);
+}
+
+void
+DeleteAllWindowProperties(WindowPtr pWin)
+{
+ PropertyPtr pProp, pNextProp;
+ xEvent event;
+
+ pProp = wUserProps (pWin);
+ while (pProp)
+ {
+#ifdef LBX
+ if (pProp->tag_id)
+ TagDeleteTag(pProp->tag_id);
+#endif
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyDelete;
+ event.u.property.atom = pProp->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+ pNextProp = pProp->next;
+ xfree(pProp->data);
+ xfree(pProp);
+ pProp = pNextProp;
+ }
+}
+
+static int
+NullPropertyReply(
+ ClientPtr client,
+ ATOM propertyType,
+ int format,
+ xGetPropertyReply *reply)
+{
+ reply->nItems = 0;
+ reply->length = 0;
+ reply->bytesAfter = 0;
+ reply->propertyType = propertyType;
+ reply->format = format;
+ WriteReplyToClient(client, sizeof(xGenericReply), reply);
+ return(client->noClientException);
+}
+
+/*****************
+ * GetProperty
+ * If type Any is specified, returns the property from the specified
+ * window regardless of its type. If a type is specified, returns the
+ * property only if its type equals the specified type.
+ * If delete is True and a property is returned, the property is also
+ * deleted from the window and a PropertyNotify event is generated on the
+ * window.
+ *****************/
+
+int
+ProcGetProperty(ClientPtr client)
+{
+ PropertyPtr pProp, prevProp;
+ unsigned long n, len, ind;
+ WindowPtr pWin;
+ xGetPropertyReply reply;
+ REQUEST(xGetPropertyReq);
+
+ REQUEST_SIZE_MATCH(xGetPropertyReq);
+ if (stuff->delete)
+ UpdateCurrentTime();
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+
+ if (!ValidAtom(stuff->property))
+ {
+ client->errorValue = stuff->property;
+ return(BadAtom);
+ }
+ if ((stuff->delete != xTrue) && (stuff->delete != xFalse))
+ {
+ client->errorValue = stuff->delete;
+ return(BadValue);
+ }
+ if ((stuff->type != AnyPropertyType) && !ValidAtom(stuff->type))
+ {
+ client->errorValue = stuff->type;
+ return(BadAtom);
+ }
+
+ pProp = wUserProps (pWin);
+ prevProp = (PropertyPtr)NULL;
+ while (pProp)
+ {
+ if (pProp->propertyName == stuff->property)
+ break;
+ prevProp = pProp;
+ pProp = pProp->next;
+ }
+
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ if (!pProp)
+ return NullPropertyReply(client, None, 0, &reply);
+
+#ifdef XCSECURITY
+ {
+ Mask access_mode = SecurityReadAccess;
+
+ if (stuff->delete)
+ access_mode |= SecurityDestroyAccess;
+ switch(SecurityCheckPropertyAccess(client, pWin, stuff->property,
+ access_mode))
+ {
+ case SecurityErrorOperation:
+ client->errorValue = stuff->property;
+ return BadAtom;;
+ case SecurityIgnoreOperation:
+ return NullPropertyReply(client, pProp->type, pProp->format,
+ &reply);
+ }
+ }
+#endif
+ /* If the request type and actual type don't match. Return the
+ property information, but not the data. */
+
+ if (((stuff->type != pProp->type) &&
+ (stuff->type != AnyPropertyType))
+ )
+ {
+ reply.bytesAfter = pProp->size;
+ reply.format = pProp->format;
+ reply.length = 0;
+ reply.nItems = 0;
+ reply.propertyType = pProp->type;
+ WriteReplyToClient(client, sizeof(xGenericReply), &reply);
+ return(Success);
+ }
+#ifdef LBX
+ /* make sure we have the current value */
+ if (pProp->tag_id && pProp->owner_pid) {
+ LbxStallPropRequest(client, pProp);
+ return client->noClientException;
+ }
+#endif
+
+/*
+ * Return type, format, value to client
+ */
+ n = (pProp->format/8) * pProp->size; /* size (bytes) of prop */
+ ind = stuff->longOffset << 2;
+
+ /* If longOffset is invalid such that it causes "len" to
+ be negative, it's a value error. */
+
+ if (n < ind)
+ {
+ client->errorValue = stuff->longOffset;
+ return BadValue;
+ }
+
+ len = min(n - ind, 4 * stuff->longLength);
+
+ reply.bytesAfter = n - (ind + len);
+ reply.format = pProp->format;
+ reply.length = (len + 3) >> 2;
+ reply.nItems = len / (pProp->format / 8 );
+ reply.propertyType = pProp->type;
+
+ if (stuff->delete && (reply.bytesAfter == 0))
+ { /* send the event */
+ xEvent event;
+
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyDelete;
+ event.u.property.atom = pProp->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+ }
+
+ WriteReplyToClient(client, sizeof(xGenericReply), &reply);
+ if (len)
+ {
+ switch (reply.format) {
+ case 32: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap32Write; break;
+ case 16: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write; break;
+ default: client->pSwapReplyFunc = (ReplySwapPtr)WriteToClient; break;
+ }
+ WriteSwappedDataToClient(client, len,
+ (char *)pProp->data + ind);
+ }
+
+ if (stuff->delete && (reply.bytesAfter == 0))
+ { /* delete the Property */
+#ifdef LBX
+ if (pProp->tag_id)
+ TagDeleteTag(pProp->tag_id);
+#endif
+ if (prevProp == (PropertyPtr)NULL) /* takes care of head */
+ {
+ if (!(pWin->optional->userProps = pProp->next))
+ CheckWindowOptionalNeed (pWin);
+ }
+ else
+ prevProp->next = pProp->next;
+ xfree(pProp->data);
+ xfree(pProp);
+ }
+ return(client->noClientException);
+}
+
+#ifdef NXAGENT_CLIPBOARD
+/* GetWindowProperty clipboard use only */
+int
+GetWindowProperty(pWin, property, longOffset, longLength, delete,
+ type, actualType, format, nItems, bytesAfter, propData )
+ WindowPtr pWin;
+ Atom property;
+ long longOffset;
+ long longLength;
+ Bool delete;
+ Atom type;
+ Atom *actualType;
+ int *format;
+ unsigned long *nItems;
+ unsigned long *bytesAfter;
+ unsigned char **propData;
+{
+ PropertyPtr pProp, prevProp;
+ unsigned long n, len, ind;
+
+ if (!pWin)
+ return BadWindow;
+
+
+ if (!ValidAtom(property))
+ {
+ return(BadAtom);
+ }
+ if ((type != AnyPropertyType) && !ValidAtom(type))
+ {
+ return(BadAtom);
+ }
+
+ pProp = wUserProps (pWin);
+ prevProp = (PropertyPtr)NULL;
+
+ while (pProp)
+ {
+ if (pProp->propertyName == property)
+ break;
+ prevProp = pProp;
+ pProp = pProp->next;
+ }
+
+
+ if (!pProp)
+ return (BadAtom);
+
+ /* If the request type and actual type don't match. Return the
+ property information, but not the data. */
+
+ if (((type != pProp->type) &&
+ (type != AnyPropertyType))
+ )
+ {
+ *bytesAfter = pProp->size;
+ *format = pProp->format;
+ *nItems = 0;
+ *actualType = pProp->type;
+ return(Success);
+ }
+
+/*
+ * Return type, format, value to client
+ */
+ n = (pProp->format/8) * pProp->size; /* size (bytes) of prop */
+ ind = longOffset << 2;
+
+ /* If longOffset is invalid such that it causes "len" to
+ be negative, it's a value error. */
+
+ if (n < ind)
+ {
+ return BadValue;
+ }
+
+ len = min(n - ind, 4 * longLength);
+
+ *bytesAfter = n - (ind + len);
+ *format = pProp->format;
+ *nItems = len / (pProp->format / 8 );
+ *actualType = pProp->type;
+
+ if (delete && (*bytesAfter == 0))
+ { /* send the event */
+ xEvent event;
+
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyDelete;
+ event.u.property.atom = pProp->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+ }
+
+ if (len)
+ {
+ *propData = (unsigned char *)(pProp->data) + ind;
+ }
+
+ if (delete && (*bytesAfter == 0))
+ { /* delete the Property */
+#ifdef LBX
+ if (pProp->tag_id)
+ TagDeleteTag(pProp->tag_id);
+#endif
+ if (prevProp == (PropertyPtr)NULL) /* takes care of head */
+ {
+ if (!(pWin->optional->userProps = pProp->next))
+ CheckWindowOptionalNeed (pWin);
+ }
+ else
+ prevProp->next = pProp->next;
+ xfree(pProp->data);
+ xfree(pProp);
+ }
+ return(Success);
+}
+#endif
+
+int
+ProcListProperties(ClientPtr client)
+{
+ Atom *pAtoms = NULL, *temppAtoms;
+ xListPropertiesReply xlpr;
+ int numProps = 0;
+ WindowPtr pWin;
+ PropertyPtr pProp;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+
+ pProp = wUserProps (pWin);
+ while (pProp)
+ {
+ pProp = pProp->next;
+ numProps++;
+ }
+ if (numProps)
+ if(!(pAtoms = (Atom *)ALLOCATE_LOCAL(numProps * sizeof(Atom))))
+ return(BadAlloc);
+
+ xlpr.type = X_Reply;
+ xlpr.nProperties = numProps;
+ xlpr.length = (numProps * sizeof(Atom)) >> 2;
+ xlpr.sequenceNumber = client->sequence;
+ pProp = wUserProps (pWin);
+ temppAtoms = pAtoms;
+ while (pProp)
+ {
+ *temppAtoms++ = pProp->propertyName;
+ pProp = pProp->next;
+ }
+ WriteReplyToClient(client, sizeof(xGenericReply), &xlpr);
+ if (numProps)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write;
+ WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms);
+ DEALLOCATE_LOCAL(pAtoms);
+ }
+ return(client->noClientException);
+}
+
+int
+ProcDeleteProperty(register ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xDeletePropertyReq);
+ int result;
+
+ REQUEST_SIZE_MATCH(xDeletePropertyReq);
+ UpdateCurrentTime();
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (!ValidAtom(stuff->property))
+ {
+ client->errorValue = stuff->property;
+ return (BadAtom);
+ }
+
+#ifdef XCSECURITY
+ switch(SecurityCheckPropertyAccess(client, pWin, stuff->property,
+ SecurityDestroyAccess))
+ {
+ case SecurityErrorOperation:
+ client->errorValue = stuff->property;
+ return BadAtom;;
+ case SecurityIgnoreOperation:
+ return Success;
+ }
+#endif
+
+ result = DeleteProperty(pWin, stuff->property);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original
new file mode 100644
index 000000000..3d08a3228
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original
@@ -0,0 +1,904 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/property.c,v 3.12 2002/02/19 11:09:22 alanh Exp $ */
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+/* $Xorg: property.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include <X11/Xproto.h>
+#include "windowstr.h"
+#include "propertyst.h"
+#include "dixstruct.h"
+#include "../../dix/dispatch.h"
+#include "swaprep.h"
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+#ifdef LBX
+#include "lbxserve.h"
+#include "lbxtags.h"
+#endif
+
+#include "Options.h"
+#include "Rootless.h"
+#include "Client.h"
+
+#if defined(LBX) || defined(LBX_COMPAT)
+#if 0 /* no header in X11 environment, not used in X11 environment */
+int fWriteToClient(ClientPtr client, int len, char *buf)
+{
+ return WriteToClient(client, len, buf);
+}
+#endif
+#endif
+
+/*****************************************************************
+ * Property Stuff
+ *
+ * ChangeProperty, DeleteProperty, GetProperties,
+ * ListProperties
+ *
+ * Properties below to windows. A allocate slots each time
+ * a property is added. No fancy searching done.
+ *
+ *****************************************************************/
+
+#ifdef notdef
+static void
+PrintPropertys(WindowPtr pWin)
+{
+ PropertyPtr pProp;
+ register int j;
+
+ pProp = pWin->userProps;
+ while (pProp)
+ {
+ ErrorF( "%x %x\n", pProp->propertyName, pProp->type);
+ ErrorF("property format: %d\n", pProp->format);
+ ErrorF("property data: \n");
+ for (j=0; j<(pProp->format/8)*pProp->size; j++)
+ ErrorF("%c\n", pProp->data[j]);
+ pProp = pProp->next;
+ }
+}
+#endif
+
+int
+ProcRotateProperties(ClientPtr client)
+{
+ int i, j, delta;
+ REQUEST(xRotatePropertiesReq);
+ WindowPtr pWin;
+ register Atom * atoms;
+ PropertyPtr * props; /* array of pointer */
+ PropertyPtr pProp;
+ xEvent event;
+
+ REQUEST_FIXED_SIZE(xRotatePropertiesReq, stuff->nAtoms << 2);
+ UpdateCurrentTime();
+ pWin = (WindowPtr) SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (!stuff->nAtoms)
+ return(Success);
+ atoms = (Atom *) & stuff[1];
+ props = (PropertyPtr *)ALLOCATE_LOCAL(stuff->nAtoms * sizeof(PropertyPtr));
+ if (!props)
+ return(BadAlloc);
+ for (i = 0; i < stuff->nAtoms; i++)
+ {
+#ifdef XCSECURITY
+ char action = SecurityCheckPropertyAccess(client, pWin, atoms[i],
+ SecurityReadAccess|SecurityWriteAccess);
+#endif
+ if (!ValidAtom(atoms[i])
+#ifdef XCSECURITY
+ || (SecurityErrorOperation == action)
+#endif
+ )
+ {
+ DEALLOCATE_LOCAL(props);
+ client->errorValue = atoms[i];
+ return BadAtom;
+ }
+#ifdef XCSECURITY
+ if (SecurityIgnoreOperation == action)
+ {
+ DEALLOCATE_LOCAL(props);
+ return Success;
+ }
+#endif
+ for (j = i + 1; j < stuff->nAtoms; j++)
+ if (atoms[j] == atoms[i])
+ {
+ DEALLOCATE_LOCAL(props);
+ return BadMatch;
+ }
+ pProp = wUserProps (pWin);
+ while (pProp)
+ {
+ if (pProp->propertyName == atoms[i])
+ goto found;
+ pProp = pProp->next;
+ }
+ DEALLOCATE_LOCAL(props);
+ return BadMatch;
+found:
+ props[i] = pProp;
+ }
+ delta = stuff->nPositions;
+
+ /* If the rotation is a complete 360 degrees, then moving the properties
+ around and generating PropertyNotify events should be skipped. */
+
+ if ( (stuff->nAtoms != 0) && (abs(delta) % stuff->nAtoms) != 0 )
+ {
+ while (delta < 0) /* faster if abs value is small */
+ delta += stuff->nAtoms;
+ for (i = 0; i < stuff->nAtoms; i++)
+ {
+ /* Generate a PropertyNotify event for each property whose value
+ is changed in the order in which they appear in the request. */
+
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyNewValue;
+ event.u.property.atom = props[i]->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+
+ props[i]->propertyName = atoms[(i + delta) % stuff->nAtoms];
+ }
+ }
+ DEALLOCATE_LOCAL(props);
+ return Success;
+}
+
+int
+ProcChangeProperty(ClientPtr client)
+{
+ WindowPtr pWin;
+ char format, mode;
+ unsigned long len;
+ int sizeInBytes;
+ int totalSize;
+ int err;
+ REQUEST(xChangePropertyReq);
+
+ REQUEST_AT_LEAST_SIZE(xChangePropertyReq);
+ UpdateCurrentTime();
+ format = stuff->format;
+ mode = stuff->mode;
+ if ((mode != PropModeReplace) && (mode != PropModeAppend) &&
+ (mode != PropModePrepend))
+ {
+ client->errorValue = mode;
+ return BadValue;
+ }
+ if ((format != 8) && (format != 16) && (format != 32))
+ {
+ client->errorValue = format;
+ return BadValue;
+ }
+ len = stuff->nUnits;
+ if (len > ((0xffffffff - sizeof(xChangePropertyReq)) >> 2))
+ return BadLength;
+ sizeInBytes = format>>3;
+ totalSize = len * sizeInBytes;
+ REQUEST_FIXED_SIZE(xChangePropertyReq, totalSize);
+
+#ifdef NXAGENT_CLIPBOARD
+ {
+ extern WindowPtr nxagentGetClipboardWindow(Atom, WindowPtr);
+
+ pWin = nxagentGetClipboardWindow(stuff->property, NULL);
+ }
+
+ if (pWin == NULL)
+#endif
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (!ValidAtom(stuff->property))
+ {
+ client->errorValue = stuff->property;
+ return(BadAtom);
+ }
+ if (!ValidAtom(stuff->type))
+ {
+ client->errorValue = stuff->type;
+ return(BadAtom);
+ }
+
+#ifdef XCSECURITY
+ switch (SecurityCheckPropertyAccess(client, pWin, stuff->property,
+ SecurityWriteAccess))
+ {
+ case SecurityErrorOperation:
+ client->errorValue = stuff->property;
+ return BadAtom;
+ case SecurityIgnoreOperation:
+ return Success;
+ }
+#endif
+
+#ifdef NXAGENT_ARTSD
+ {
+ /* Do not process MCOPGLOBALS property changes,
+ they are already set reflecting the server side settings.
+ Just return success.
+ */
+ extern Atom mcop_local_atom;
+ if (stuff->property == mcop_local_atom)
+ return client->noClientException;
+ }
+#endif
+
+#ifdef LBX
+ err = LbxChangeWindowProperty(client, pWin, stuff->property, stuff->type,
+ (int)format, (int)mode, len, TRUE, (pointer)&stuff[1], TRUE, NULL);
+#else
+ err = ChangeWindowProperty(pWin, stuff->property, stuff->type, (int)format,
+ (int)mode, len, (pointer)&stuff[1], TRUE);
+#endif
+ if (err != Success)
+ return err;
+ else
+ {
+ if (nxagentOption(Rootless) == 1)
+ {
+ nxagentExportProperty(pWin, stuff->property, stuff->type, (int) format,
+ (int) mode, len, (pointer) &stuff[1]);
+ }
+
+ nxagentGuessClientHint(client, stuff->property, (char *) &stuff[1]);
+
+ nxagentGuessShadowHint(client, stuff->property);
+
+ return client->noClientException;
+ }
+}
+
+int
+ChangeWindowProperty(WindowPtr pWin, Atom property, Atom type, int format,
+ int mode, unsigned long len, pointer value,
+ Bool sendevent)
+{
+#ifdef LBX
+ return LbxChangeWindowProperty(NULL, pWin, property, type,
+ format, mode, len, TRUE, value,
+ sendevent, NULL);
+#else
+ PropertyPtr pProp;
+ xEvent event;
+ int sizeInBytes;
+ int totalSize;
+ pointer data;
+
+ sizeInBytes = format>>3;
+ totalSize = len * sizeInBytes;
+
+ /* first see if property already exists */
+
+ pProp = wUserProps (pWin);
+ while (pProp)
+ {
+ if (pProp->propertyName == property)
+ break;
+ pProp = pProp->next;
+ }
+ if (!pProp) /* just add to list */
+ {
+ if (!pWin->optional && !MakeWindowOptional (pWin))
+ return(BadAlloc);
+ pProp = (PropertyPtr)xalloc(sizeof(PropertyRec));
+ if (!pProp)
+ return(BadAlloc);
+ data = (pointer)xalloc(totalSize);
+ if (!data && len)
+ {
+ xfree(pProp);
+ return(BadAlloc);
+ }
+ pProp->propertyName = property;
+ pProp->type = type;
+ pProp->format = format;
+ pProp->data = data;
+ if (len)
+ memmove((char *)data, (char *)value, totalSize);
+ pProp->size = len;
+ pProp->next = pWin->optional->userProps;
+ pWin->optional->userProps = pProp;
+ }
+ else
+ {
+ /* To append or prepend to a property the request format and type
+ must match those of the already defined property. The
+ existing format and type are irrelevant when using the mode
+ "PropModeReplace" since they will be written over. */
+
+ if ((format != pProp->format) && (mode != PropModeReplace))
+ return(BadMatch);
+ if ((pProp->type != type) && (mode != PropModeReplace))
+ return(BadMatch);
+ if (mode == PropModeReplace)
+ {
+ if (totalSize != pProp->size * (pProp->format >> 3))
+ {
+ data = (pointer)xrealloc(pProp->data, totalSize);
+ if (!data && len)
+ return(BadAlloc);
+ pProp->data = data;
+ }
+ if (len)
+ memmove((char *)pProp->data, (char *)value, totalSize);
+ pProp->size = len;
+ pProp->type = type;
+ pProp->format = format;
+ }
+ else if (len == 0)
+ {
+ /* do nothing */
+ }
+ else if (mode == PropModeAppend)
+ {
+ data = (pointer)xrealloc(pProp->data,
+ sizeInBytes * (len + pProp->size));
+ if (!data)
+ return(BadAlloc);
+ pProp->data = data;
+ memmove(&((char *)data)[pProp->size * sizeInBytes],
+ (char *)value,
+ totalSize);
+ pProp->size += len;
+ }
+ else if (mode == PropModePrepend)
+ {
+ data = (pointer)xalloc(sizeInBytes * (len + pProp->size));
+ if (!data)
+ return(BadAlloc);
+ memmove(&((char *)data)[totalSize], (char *)pProp->data,
+ (int)(pProp->size * sizeInBytes));
+ memmove((char *)data, (char *)value, totalSize);
+ xfree(pProp->data);
+ pProp->data = data;
+ pProp->size += len;
+ }
+ }
+ if (sendevent)
+ {
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyNewValue;
+ event.u.property.atom = pProp->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+ }
+ return(Success);
+#endif
+}
+
+int
+DeleteProperty(WindowPtr pWin, Atom propName)
+{
+ PropertyPtr pProp, prevProp;
+ xEvent event;
+
+ if (!(pProp = wUserProps (pWin)))
+ return(Success);
+ prevProp = (PropertyPtr)NULL;
+ while (pProp)
+ {
+ if (pProp->propertyName == propName)
+ break;
+ prevProp = pProp;
+ pProp = pProp->next;
+ }
+ if (pProp)
+ {
+ if (prevProp == (PropertyPtr)NULL) /* takes care of head */
+ {
+ if (!(pWin->optional->userProps = pProp->next))
+ CheckWindowOptionalNeed (pWin);
+ }
+ else
+ {
+ prevProp->next = pProp->next;
+ }
+#ifdef LBX
+ if (pProp->tag_id)
+ TagDeleteTag(pProp->tag_id);
+#endif
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyDelete;
+ event.u.property.atom = pProp->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+ xfree(pProp->data);
+ xfree(pProp);
+ }
+ return(Success);
+}
+
+void
+DeleteAllWindowProperties(WindowPtr pWin)
+{
+ PropertyPtr pProp, pNextProp;
+ xEvent event;
+
+ pProp = wUserProps (pWin);
+ while (pProp)
+ {
+#ifdef LBX
+ if (pProp->tag_id)
+ TagDeleteTag(pProp->tag_id);
+#endif
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyDelete;
+ event.u.property.atom = pProp->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+ pNextProp = pProp->next;
+ xfree(pProp->data);
+ xfree(pProp);
+ pProp = pNextProp;
+ }
+}
+
+static int
+NullPropertyReply(
+ ClientPtr client,
+ ATOM propertyType,
+ int format,
+ xGetPropertyReply *reply)
+{
+ reply->nItems = 0;
+ reply->length = 0;
+ reply->bytesAfter = 0;
+ reply->propertyType = propertyType;
+ reply->format = format;
+ WriteReplyToClient(client, sizeof(xGenericReply), reply);
+ return(client->noClientException);
+}
+
+/*****************
+ * GetProperty
+ * If type Any is specified, returns the property from the specified
+ * window regardless of its type. If a type is specified, returns the
+ * property only if its type equals the specified type.
+ * If delete is True and a property is returned, the property is also
+ * deleted from the window and a PropertyNotify event is generated on the
+ * window.
+ *****************/
+
+int
+ProcGetProperty(ClientPtr client)
+{
+ PropertyPtr pProp, prevProp;
+ unsigned long n, len, ind;
+ WindowPtr pWin;
+ xGetPropertyReply reply;
+ REQUEST(xGetPropertyReq);
+
+ REQUEST_SIZE_MATCH(xGetPropertyReq);
+ if (stuff->delete)
+ UpdateCurrentTime();
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+
+ if (!ValidAtom(stuff->property))
+ {
+ client->errorValue = stuff->property;
+ return(BadAtom);
+ }
+ if ((stuff->delete != xTrue) && (stuff->delete != xFalse))
+ {
+ client->errorValue = stuff->delete;
+ return(BadValue);
+ }
+ if ((stuff->type != AnyPropertyType) && !ValidAtom(stuff->type))
+ {
+ client->errorValue = stuff->type;
+ return(BadAtom);
+ }
+
+ pProp = wUserProps (pWin);
+ prevProp = (PropertyPtr)NULL;
+ while (pProp)
+ {
+ if (pProp->propertyName == stuff->property)
+ break;
+ prevProp = pProp;
+ pProp = pProp->next;
+ }
+
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ if (!pProp)
+ return NullPropertyReply(client, None, 0, &reply);
+
+#ifdef XCSECURITY
+ {
+ Mask access_mode = SecurityReadAccess;
+
+ if (stuff->delete)
+ access_mode |= SecurityDestroyAccess;
+ switch(SecurityCheckPropertyAccess(client, pWin, stuff->property,
+ access_mode))
+ {
+ case SecurityErrorOperation:
+ client->errorValue = stuff->property;
+ return BadAtom;;
+ case SecurityIgnoreOperation:
+ return NullPropertyReply(client, pProp->type, pProp->format,
+ &reply);
+ }
+ }
+#endif
+ /* If the request type and actual type don't match. Return the
+ property information, but not the data. */
+
+ if (((stuff->type != pProp->type) &&
+ (stuff->type != AnyPropertyType))
+ )
+ {
+ reply.bytesAfter = pProp->size;
+ reply.format = pProp->format;
+ reply.length = 0;
+ reply.nItems = 0;
+ reply.propertyType = pProp->type;
+ WriteReplyToClient(client, sizeof(xGenericReply), &reply);
+ return(Success);
+ }
+#ifdef LBX
+ /* make sure we have the current value */
+ if (pProp->tag_id && pProp->owner_pid) {
+ LbxStallPropRequest(client, pProp);
+ return client->noClientException;
+ }
+#endif
+
+/*
+ * Return type, format, value to client
+ */
+ n = (pProp->format/8) * pProp->size; /* size (bytes) of prop */
+ ind = stuff->longOffset << 2;
+
+ /* If longOffset is invalid such that it causes "len" to
+ be negative, it's a value error. */
+
+ if (n < ind)
+ {
+ client->errorValue = stuff->longOffset;
+ return BadValue;
+ }
+
+ len = min(n - ind, 4 * stuff->longLength);
+
+ reply.bytesAfter = n - (ind + len);
+ reply.format = pProp->format;
+ reply.length = (len + 3) >> 2;
+ reply.nItems = len / (pProp->format / 8 );
+ reply.propertyType = pProp->type;
+
+ if (stuff->delete && (reply.bytesAfter == 0))
+ { /* send the event */
+ xEvent event;
+
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyDelete;
+ event.u.property.atom = pProp->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+ }
+
+ WriteReplyToClient(client, sizeof(xGenericReply), &reply);
+ if (len)
+ {
+ switch (reply.format) {
+ case 32: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap32Write; break;
+ case 16: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write; break;
+ default: client->pSwapReplyFunc = (ReplySwapPtr)WriteToClient; break;
+ }
+ WriteSwappedDataToClient(client, len,
+ (char *)pProp->data + ind);
+ }
+
+ if (stuff->delete && (reply.bytesAfter == 0))
+ { /* delete the Property */
+#ifdef LBX
+ if (pProp->tag_id)
+ TagDeleteTag(pProp->tag_id);
+#endif
+ if (prevProp == (PropertyPtr)NULL) /* takes care of head */
+ {
+ if (!(pWin->optional->userProps = pProp->next))
+ CheckWindowOptionalNeed (pWin);
+ }
+ else
+ prevProp->next = pProp->next;
+ xfree(pProp->data);
+ xfree(pProp);
+ }
+ return(client->noClientException);
+}
+
+#ifdef NXAGENT_CLIPBOARD
+/* GetWindowProperty clipboard use only */
+int
+GetWindowProperty(pWin, property, longOffset, longLength, delete,
+ type, actualType, format, nItems, bytesAfter, propData )
+ WindowPtr pWin;
+ Atom property;
+ long longOffset;
+ long longLength;
+ Bool delete;
+ Atom type;
+ Atom *actualType;
+ int *format;
+ unsigned long *nItems;
+ unsigned long *bytesAfter;
+ unsigned char **propData;
+{
+ PropertyPtr pProp, prevProp;
+ unsigned long n, len, ind;
+
+ if (!pWin)
+ return BadWindow;
+
+
+ if (!ValidAtom(property))
+ {
+ return(BadAtom);
+ }
+ if ((type != AnyPropertyType) && !ValidAtom(type))
+ {
+ return(BadAtom);
+ }
+
+ pProp = wUserProps (pWin);
+ prevProp = (PropertyPtr)NULL;
+
+ while (pProp)
+ {
+ if (pProp->propertyName == property)
+ break;
+ prevProp = pProp;
+ pProp = pProp->next;
+ }
+
+
+ if (!pProp)
+ return (BadAtom);
+
+ /* If the request type and actual type don't match. Return the
+ property information, but not the data. */
+
+ if (((type != pProp->type) &&
+ (type != AnyPropertyType))
+ )
+ {
+ *bytesAfter = pProp->size;
+ *format = pProp->format;
+ *nItems = 0;
+ *actualType = pProp->type;
+ return(Success);
+ }
+
+/*
+ * Return type, format, value to client
+ */
+ n = (pProp->format/8) * pProp->size; /* size (bytes) of prop */
+ ind = longOffset << 2;
+
+ /* If longOffset is invalid such that it causes "len" to
+ be negative, it's a value error. */
+
+ if (n < ind)
+ {
+ return BadValue;
+ }
+
+ len = min(n - ind, 4 * longLength);
+
+ *bytesAfter = n - (ind + len);
+ *format = pProp->format;
+ *nItems = len / (pProp->format / 8 );
+ *actualType = pProp->type;
+
+ if (delete && (*bytesAfter == 0))
+ { /* send the event */
+ xEvent event;
+
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyDelete;
+ event.u.property.atom = pProp->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+ }
+
+ if (len)
+ {
+ *propData = (unsigned char *)(pProp->data) + ind;
+ }
+
+ if (delete && (*bytesAfter == 0))
+ { /* delete the Property */
+#ifdef LBX
+ if (pProp->tag_id)
+ TagDeleteTag(pProp->tag_id);
+#endif
+ if (prevProp == (PropertyPtr)NULL) /* takes care of head */
+ {
+ if (!(pWin->optional->userProps = pProp->next))
+ CheckWindowOptionalNeed (pWin);
+ }
+ else
+ prevProp->next = pProp->next;
+ xfree(pProp->data);
+ xfree(pProp);
+ }
+ return(Success);
+}
+#endif
+
+int
+ProcListProperties(ClientPtr client)
+{
+ Atom *pAtoms = NULL, *temppAtoms;
+ xListPropertiesReply xlpr;
+ int numProps = 0;
+ WindowPtr pWin;
+ PropertyPtr pProp;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+
+ pProp = wUserProps (pWin);
+ while (pProp)
+ {
+ pProp = pProp->next;
+ numProps++;
+ }
+ if (numProps)
+ if(!(pAtoms = (Atom *)ALLOCATE_LOCAL(numProps * sizeof(Atom))))
+ return(BadAlloc);
+
+ xlpr.type = X_Reply;
+ xlpr.nProperties = numProps;
+ xlpr.length = (numProps * sizeof(Atom)) >> 2;
+ xlpr.sequenceNumber = client->sequence;
+ pProp = wUserProps (pWin);
+ temppAtoms = pAtoms;
+ while (pProp)
+ {
+ *temppAtoms++ = pProp->propertyName;
+ pProp = pProp->next;
+ }
+ WriteReplyToClient(client, sizeof(xGenericReply), &xlpr);
+ if (numProps)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write;
+ WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms);
+ DEALLOCATE_LOCAL(pAtoms);
+ }
+ return(client->noClientException);
+}
+
+int
+ProcDeleteProperty(register ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xDeletePropertyReq);
+ int result;
+
+ REQUEST_SIZE_MATCH(xDeletePropertyReq);
+ UpdateCurrentTime();
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (!ValidAtom(stuff->property))
+ {
+ client->errorValue = stuff->property;
+ return (BadAtom);
+ }
+
+#ifdef XCSECURITY
+ switch(SecurityCheckPropertyAccess(client, pWin, stuff->property,
+ SecurityDestroyAccess))
+ {
+ case SecurityErrorOperation:
+ client->errorValue = stuff->property;
+ return BadAtom;;
+ case SecurityIgnoreOperation:
+ return Success;
+ }
+#endif
+
+ result = DeleteProperty(pWin, stuff->property);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.X.original
new file mode 100644
index 000000000..cabe46ecc
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.X.original
@@ -0,0 +1,729 @@
+/* $XFree86: xc/programs/Xserver/dix/property.c,v 3.12 2002/02/19 11:09:22 alanh Exp $ */
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+/* $Xorg: property.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include <X11/Xproto.h>
+#include "windowstr.h"
+#include "propertyst.h"
+#include "dixstruct.h"
+#include "dispatch.h"
+#include "swaprep.h"
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+#ifdef LBX
+#include "lbxserve.h"
+#include "lbxtags.h"
+#endif
+
+#if defined(LBX) || defined(LBX_COMPAT)
+#if 0 /* no header in X11 environment, not used in X11 environment */
+int fWriteToClient(ClientPtr client, int len, char *buf)
+{
+ return WriteToClient(client, len, buf);
+}
+#endif
+#endif
+
+/*****************************************************************
+ * Property Stuff
+ *
+ * ChangeProperty, DeleteProperty, GetProperties,
+ * ListProperties
+ *
+ * Properties below to windows. A allocate slots each time
+ * a property is added. No fancy searching done.
+ *
+ *****************************************************************/
+
+#ifdef notdef
+static void
+PrintPropertys(WindowPtr pWin)
+{
+ PropertyPtr pProp;
+ register int j;
+
+ pProp = pWin->userProps;
+ while (pProp)
+ {
+ ErrorF( "%x %x\n", pProp->propertyName, pProp->type);
+ ErrorF("property format: %d\n", pProp->format);
+ ErrorF("property data: \n");
+ for (j=0; j<(pProp->format/8)*pProp->size; j++)
+ ErrorF("%c\n", pProp->data[j]);
+ pProp = pProp->next;
+ }
+}
+#endif
+
+int
+ProcRotateProperties(ClientPtr client)
+{
+ int i, j, delta;
+ REQUEST(xRotatePropertiesReq);
+ WindowPtr pWin;
+ register Atom * atoms;
+ PropertyPtr * props; /* array of pointer */
+ PropertyPtr pProp;
+ xEvent event;
+
+ REQUEST_FIXED_SIZE(xRotatePropertiesReq, stuff->nAtoms << 2);
+ UpdateCurrentTime();
+ pWin = (WindowPtr) SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (!stuff->nAtoms)
+ return(Success);
+ atoms = (Atom *) & stuff[1];
+ props = (PropertyPtr *)ALLOCATE_LOCAL(stuff->nAtoms * sizeof(PropertyPtr));
+ if (!props)
+ return(BadAlloc);
+ for (i = 0; i < stuff->nAtoms; i++)
+ {
+#ifdef XCSECURITY
+ char action = SecurityCheckPropertyAccess(client, pWin, atoms[i],
+ SecurityReadAccess|SecurityWriteAccess);
+#endif
+ if (!ValidAtom(atoms[i])
+#ifdef XCSECURITY
+ || (SecurityErrorOperation == action)
+#endif
+ )
+ {
+ DEALLOCATE_LOCAL(props);
+ client->errorValue = atoms[i];
+ return BadAtom;
+ }
+#ifdef XCSECURITY
+ if (SecurityIgnoreOperation == action)
+ {
+ DEALLOCATE_LOCAL(props);
+ return Success;
+ }
+#endif
+ for (j = i + 1; j < stuff->nAtoms; j++)
+ if (atoms[j] == atoms[i])
+ {
+ DEALLOCATE_LOCAL(props);
+ return BadMatch;
+ }
+ pProp = wUserProps (pWin);
+ while (pProp)
+ {
+ if (pProp->propertyName == atoms[i])
+ goto found;
+ pProp = pProp->next;
+ }
+ DEALLOCATE_LOCAL(props);
+ return BadMatch;
+found:
+ props[i] = pProp;
+ }
+ delta = stuff->nPositions;
+
+ /* If the rotation is a complete 360 degrees, then moving the properties
+ around and generating PropertyNotify events should be skipped. */
+
+ if ( (stuff->nAtoms != 0) && (abs(delta) % stuff->nAtoms) != 0 )
+ {
+ while (delta < 0) /* faster if abs value is small */
+ delta += stuff->nAtoms;
+ for (i = 0; i < stuff->nAtoms; i++)
+ {
+ /* Generate a PropertyNotify event for each property whose value
+ is changed in the order in which they appear in the request. */
+
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyNewValue;
+ event.u.property.atom = props[i]->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+
+ props[i]->propertyName = atoms[(i + delta) % stuff->nAtoms];
+ }
+ }
+ DEALLOCATE_LOCAL(props);
+ return Success;
+}
+
+int
+ProcChangeProperty(ClientPtr client)
+{
+ WindowPtr pWin;
+ char format, mode;
+ unsigned long len;
+ int sizeInBytes;
+ int totalSize;
+ int err;
+ REQUEST(xChangePropertyReq);
+
+ REQUEST_AT_LEAST_SIZE(xChangePropertyReq);
+ UpdateCurrentTime();
+ format = stuff->format;
+ mode = stuff->mode;
+ if ((mode != PropModeReplace) && (mode != PropModeAppend) &&
+ (mode != PropModePrepend))
+ {
+ client->errorValue = mode;
+ return BadValue;
+ }
+ if ((format != 8) && (format != 16) && (format != 32))
+ {
+ client->errorValue = format;
+ return BadValue;
+ }
+ len = stuff->nUnits;
+ if (len > ((0xffffffff - sizeof(xChangePropertyReq)) >> 2))
+ return BadLength;
+ sizeInBytes = format>>3;
+ totalSize = len * sizeInBytes;
+ REQUEST_FIXED_SIZE(xChangePropertyReq, totalSize);
+
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (!ValidAtom(stuff->property))
+ {
+ client->errorValue = stuff->property;
+ return(BadAtom);
+ }
+ if (!ValidAtom(stuff->type))
+ {
+ client->errorValue = stuff->type;
+ return(BadAtom);
+ }
+
+#ifdef XCSECURITY
+ switch (SecurityCheckPropertyAccess(client, pWin, stuff->property,
+ SecurityWriteAccess))
+ {
+ case SecurityErrorOperation:
+ client->errorValue = stuff->property;
+ return BadAtom;
+ case SecurityIgnoreOperation:
+ return Success;
+ }
+#endif
+
+#ifdef LBX
+ err = LbxChangeWindowProperty(client, pWin, stuff->property, stuff->type,
+ (int)format, (int)mode, len, TRUE, (pointer)&stuff[1], TRUE, NULL);
+#else
+ err = ChangeWindowProperty(pWin, stuff->property, stuff->type, (int)format,
+ (int)mode, len, (pointer)&stuff[1], TRUE);
+#endif
+ if (err != Success)
+ return err;
+ else
+ return client->noClientException;
+}
+
+int
+ChangeWindowProperty(WindowPtr pWin, Atom property, Atom type, int format,
+ int mode, unsigned long len, pointer value,
+ Bool sendevent)
+{
+#ifdef LBX
+ return LbxChangeWindowProperty(NULL, pWin, property, type,
+ format, mode, len, TRUE, value,
+ sendevent, NULL);
+#else
+ PropertyPtr pProp;
+ xEvent event;
+ int sizeInBytes;
+ int totalSize;
+ pointer data;
+
+ sizeInBytes = format>>3;
+ totalSize = len * sizeInBytes;
+
+ /* first see if property already exists */
+
+ pProp = wUserProps (pWin);
+ while (pProp)
+ {
+ if (pProp->propertyName == property)
+ break;
+ pProp = pProp->next;
+ }
+ if (!pProp) /* just add to list */
+ {
+ if (!pWin->optional && !MakeWindowOptional (pWin))
+ return(BadAlloc);
+ pProp = (PropertyPtr)xalloc(sizeof(PropertyRec));
+ if (!pProp)
+ return(BadAlloc);
+ data = (pointer)xalloc(totalSize);
+ if (!data && len)
+ {
+ xfree(pProp);
+ return(BadAlloc);
+ }
+ pProp->propertyName = property;
+ pProp->type = type;
+ pProp->format = format;
+ pProp->data = data;
+ if (len)
+ memmove((char *)data, (char *)value, totalSize);
+ pProp->size = len;
+ pProp->next = pWin->optional->userProps;
+ pWin->optional->userProps = pProp;
+ }
+ else
+ {
+ /* To append or prepend to a property the request format and type
+ must match those of the already defined property. The
+ existing format and type are irrelevant when using the mode
+ "PropModeReplace" since they will be written over. */
+
+ if ((format != pProp->format) && (mode != PropModeReplace))
+ return(BadMatch);
+ if ((pProp->type != type) && (mode != PropModeReplace))
+ return(BadMatch);
+ if (mode == PropModeReplace)
+ {
+ if (totalSize != pProp->size * (pProp->format >> 3))
+ {
+ data = (pointer)xrealloc(pProp->data, totalSize);
+ if (!data && len)
+ return(BadAlloc);
+ pProp->data = data;
+ }
+ if (len)
+ memmove((char *)pProp->data, (char *)value, totalSize);
+ pProp->size = len;
+ pProp->type = type;
+ pProp->format = format;
+ }
+ else if (len == 0)
+ {
+ /* do nothing */
+ }
+ else if (mode == PropModeAppend)
+ {
+ data = (pointer)xrealloc(pProp->data,
+ sizeInBytes * (len + pProp->size));
+ if (!data)
+ return(BadAlloc);
+ pProp->data = data;
+ memmove(&((char *)data)[pProp->size * sizeInBytes],
+ (char *)value,
+ totalSize);
+ pProp->size += len;
+ }
+ else if (mode == PropModePrepend)
+ {
+ data = (pointer)xalloc(sizeInBytes * (len + pProp->size));
+ if (!data)
+ return(BadAlloc);
+ memmove(&((char *)data)[totalSize], (char *)pProp->data,
+ (int)(pProp->size * sizeInBytes));
+ memmove((char *)data, (char *)value, totalSize);
+ xfree(pProp->data);
+ pProp->data = data;
+ pProp->size += len;
+ }
+ }
+ if (sendevent)
+ {
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyNewValue;
+ event.u.property.atom = pProp->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+ }
+ return(Success);
+#endif
+}
+
+int
+DeleteProperty(WindowPtr pWin, Atom propName)
+{
+ PropertyPtr pProp, prevProp;
+ xEvent event;
+
+ if (!(pProp = wUserProps (pWin)))
+ return(Success);
+ prevProp = (PropertyPtr)NULL;
+ while (pProp)
+ {
+ if (pProp->propertyName == propName)
+ break;
+ prevProp = pProp;
+ pProp = pProp->next;
+ }
+ if (pProp)
+ {
+ if (prevProp == (PropertyPtr)NULL) /* takes care of head */
+ {
+ if (!(pWin->optional->userProps = pProp->next))
+ CheckWindowOptionalNeed (pWin);
+ }
+ else
+ {
+ prevProp->next = pProp->next;
+ }
+#ifdef LBX
+ if (pProp->tag_id)
+ TagDeleteTag(pProp->tag_id);
+#endif
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyDelete;
+ event.u.property.atom = pProp->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+ xfree(pProp->data);
+ xfree(pProp);
+ }
+ return(Success);
+}
+
+void
+DeleteAllWindowProperties(WindowPtr pWin)
+{
+ PropertyPtr pProp, pNextProp;
+ xEvent event;
+
+ pProp = wUserProps (pWin);
+ while (pProp)
+ {
+#ifdef LBX
+ if (pProp->tag_id)
+ TagDeleteTag(pProp->tag_id);
+#endif
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyDelete;
+ event.u.property.atom = pProp->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+ pNextProp = pProp->next;
+ xfree(pProp->data);
+ xfree(pProp);
+ pProp = pNextProp;
+ }
+}
+
+static int
+NullPropertyReply(
+ ClientPtr client,
+ ATOM propertyType,
+ int format,
+ xGetPropertyReply *reply)
+{
+ reply->nItems = 0;
+ reply->length = 0;
+ reply->bytesAfter = 0;
+ reply->propertyType = propertyType;
+ reply->format = format;
+ WriteReplyToClient(client, sizeof(xGenericReply), reply);
+ return(client->noClientException);
+}
+
+/*****************
+ * GetProperty
+ * If type Any is specified, returns the property from the specified
+ * window regardless of its type. If a type is specified, returns the
+ * property only if its type equals the specified type.
+ * If delete is True and a property is returned, the property is also
+ * deleted from the window and a PropertyNotify event is generated on the
+ * window.
+ *****************/
+
+int
+ProcGetProperty(ClientPtr client)
+{
+ PropertyPtr pProp, prevProp;
+ unsigned long n, len, ind;
+ WindowPtr pWin;
+ xGetPropertyReply reply;
+ REQUEST(xGetPropertyReq);
+
+ REQUEST_SIZE_MATCH(xGetPropertyReq);
+ if (stuff->delete)
+ UpdateCurrentTime();
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return BadWindow;
+
+ if (!ValidAtom(stuff->property))
+ {
+ client->errorValue = stuff->property;
+ return(BadAtom);
+ }
+ if ((stuff->delete != xTrue) && (stuff->delete != xFalse))
+ {
+ client->errorValue = stuff->delete;
+ return(BadValue);
+ }
+ if ((stuff->type != AnyPropertyType) && !ValidAtom(stuff->type))
+ {
+ client->errorValue = stuff->type;
+ return(BadAtom);
+ }
+
+ pProp = wUserProps (pWin);
+ prevProp = (PropertyPtr)NULL;
+ while (pProp)
+ {
+ if (pProp->propertyName == stuff->property)
+ break;
+ prevProp = pProp;
+ pProp = pProp->next;
+ }
+
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ if (!pProp)
+ return NullPropertyReply(client, None, 0, &reply);
+
+#ifdef XCSECURITY
+ {
+ Mask access_mode = SecurityReadAccess;
+
+ if (stuff->delete)
+ access_mode |= SecurityDestroyAccess;
+ switch(SecurityCheckPropertyAccess(client, pWin, stuff->property,
+ access_mode))
+ {
+ case SecurityErrorOperation:
+ client->errorValue = stuff->property;
+ return BadAtom;;
+ case SecurityIgnoreOperation:
+ return NullPropertyReply(client, pProp->type, pProp->format,
+ &reply);
+ }
+ }
+#endif
+ /* If the request type and actual type don't match. Return the
+ property information, but not the data. */
+
+ if (((stuff->type != pProp->type) &&
+ (stuff->type != AnyPropertyType))
+ )
+ {
+ reply.bytesAfter = pProp->size;
+ reply.format = pProp->format;
+ reply.length = 0;
+ reply.nItems = 0;
+ reply.propertyType = pProp->type;
+ WriteReplyToClient(client, sizeof(xGenericReply), &reply);
+ return(Success);
+ }
+#ifdef LBX
+ /* make sure we have the current value */
+ if (pProp->tag_id && pProp->owner_pid) {
+ LbxStallPropRequest(client, pProp);
+ return client->noClientException;
+ }
+#endif
+
+/*
+ * Return type, format, value to client
+ */
+ n = (pProp->format/8) * pProp->size; /* size (bytes) of prop */
+ ind = stuff->longOffset << 2;
+
+ /* If longOffset is invalid such that it causes "len" to
+ be negative, it's a value error. */
+
+ if (n < ind)
+ {
+ client->errorValue = stuff->longOffset;
+ return BadValue;
+ }
+
+ len = min(n - ind, 4 * stuff->longLength);
+
+ reply.bytesAfter = n - (ind + len);
+ reply.format = pProp->format;
+ reply.length = (len + 3) >> 2;
+ reply.nItems = len / (pProp->format / 8 );
+ reply.propertyType = pProp->type;
+
+ if (stuff->delete && (reply.bytesAfter == 0))
+ { /* send the event */
+ xEvent event;
+
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyDelete;
+ event.u.property.atom = pProp->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+ }
+
+ WriteReplyToClient(client, sizeof(xGenericReply), &reply);
+ if (len)
+ {
+ switch (reply.format) {
+ case 32: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap32Write; break;
+ case 16: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write; break;
+ default: client->pSwapReplyFunc = (ReplySwapPtr)WriteToClient; break;
+ }
+ WriteSwappedDataToClient(client, len,
+ (char *)pProp->data + ind);
+ }
+
+ if (stuff->delete && (reply.bytesAfter == 0))
+ { /* delete the Property */
+#ifdef LBX
+ if (pProp->tag_id)
+ TagDeleteTag(pProp->tag_id);
+#endif
+ if (prevProp == (PropertyPtr)NULL) /* takes care of head */
+ {
+ if (!(pWin->optional->userProps = pProp->next))
+ CheckWindowOptionalNeed (pWin);
+ }
+ else
+ prevProp->next = pProp->next;
+ xfree(pProp->data);
+ xfree(pProp);
+ }
+ return(client->noClientException);
+}
+
+int
+ProcListProperties(ClientPtr client)
+{
+ Atom *pAtoms = NULL, *temppAtoms;
+ xListPropertiesReply xlpr;
+ int numProps = 0;
+ WindowPtr pWin;
+ PropertyPtr pProp;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+
+ pProp = wUserProps (pWin);
+ while (pProp)
+ {
+ pProp = pProp->next;
+ numProps++;
+ }
+ if (numProps)
+ if(!(pAtoms = (Atom *)ALLOCATE_LOCAL(numProps * sizeof(Atom))))
+ return(BadAlloc);
+
+ xlpr.type = X_Reply;
+ xlpr.nProperties = numProps;
+ xlpr.length = (numProps * sizeof(Atom)) >> 2;
+ xlpr.sequenceNumber = client->sequence;
+ pProp = wUserProps (pWin);
+ temppAtoms = pAtoms;
+ while (pProp)
+ {
+ *temppAtoms++ = pProp->propertyName;
+ pProp = pProp->next;
+ }
+ WriteReplyToClient(client, sizeof(xGenericReply), &xlpr);
+ if (numProps)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write;
+ WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms);
+ DEALLOCATE_LOCAL(pAtoms);
+ }
+ return(client->noClientException);
+}
+
+int
+ProcDeleteProperty(register ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xDeletePropertyReq);
+ int result;
+
+ REQUEST_SIZE_MATCH(xDeletePropertyReq);
+ UpdateCurrentTime();
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (!ValidAtom(stuff->property))
+ {
+ client->errorValue = stuff->property;
+ return (BadAtom);
+ }
+
+#ifdef XCSECURITY
+ switch(SecurityCheckPropertyAccess(client, pWin, stuff->property,
+ SecurityDestroyAccess))
+ {
+ case SecurityErrorOperation:
+ client->errorValue = stuff->property;
+ return BadAtom;;
+ case SecurityIgnoreOperation:
+ return Success;
+ }
+#endif
+
+ result = DeleteProperty(pWin, stuff->property);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c
new file mode 100644
index 000000000..426d15b1b
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c
@@ -0,0 +1,1344 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/randr/randr.c,v 1.21tsi Exp $
+ *
+ * Copyright © 2000, Compaq Computer Corporation,
+ * Copyright © 2002, Hewlett Packard, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Compaq or HP not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. HP makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * HP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL HP
+ * 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.
+ *
+ * Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc.
+ */
+
+
+#define NEED_REPLIES
+#define NEED_EVENTS
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#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 "extnsionst.h"
+#include "servermd.h"
+#include <X11/extensions/randr.h>
+#include <X11/extensions/randrproto.h>
+#include "../../randr/randrstr.h"
+#ifdef RENDER
+#include <X11/extensions/render.h> /* we share subpixel order information */
+#include "picturestr.h"
+#endif
+#include <X11/Xfuncproto.h>
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#endif
+
+/* From render.h */
+#ifndef SubPixelUnknown
+#define SubPixelUnknown 0
+#endif
+
+#define RR_VALIDATE
+int RRGeneration;
+int RRNScreens;
+
+static int ProcRRQueryVersion (ClientPtr pClient);
+static int ProcRRDispatch (ClientPtr pClient);
+static int SProcRRDispatch (ClientPtr pClient);
+static int SProcRRQueryVersion (ClientPtr pClient);
+
+#define wrap(priv,real,mem,func) {\
+ priv->mem = real->mem; \
+ real->mem = func; \
+}
+
+#define unwrap(priv,real,mem) {\
+ real->mem = priv->mem; \
+}
+
+#if 0
+static CARD8 RRReqCode;
+static int RRErrBase;
+#endif
+static int RREventBase;
+static RESTYPE ClientType, EventType; /* resource types for event masks */
+static int RRClientPrivateIndex;
+
+typedef struct _RRTimes {
+ TimeStamp setTime;
+ TimeStamp configTime;
+} RRTimesRec, *RRTimesPtr;
+
+typedef struct _RRClient {
+ int major_version;
+ int minor_version;
+/* RRTimesRec times[0]; */
+} RRClientRec, *RRClientPtr;
+
+/*
+ * each window has a list of clients requesting
+ * RRNotify events. Each client has a resource
+ * for each window it selects RRNotify input for,
+ * this resource is used to delete the RRNotifyRec
+ * entry from the per-window queue.
+ */
+
+typedef struct _RREvent *RREventPtr;
+
+typedef struct _RREvent {
+ RREventPtr next;
+ ClientPtr client;
+ WindowPtr window;
+ XID clientResource;
+ int mask;
+} RREventRec;
+
+int rrPrivIndex = -1;
+
+#define GetRRClient(pClient) ((RRClientPtr) (pClient)->devPrivates[RRClientPrivateIndex].ptr)
+#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient)
+
+static Bool
+RRClientKnowsRates (ClientPtr pClient)
+{
+ rrClientPriv(pClient);
+
+ return (pRRClient->major_version > 1 ||
+ (pRRClient->major_version == 1 && pRRClient->minor_version >= 1));
+}
+
+static void
+RRClientCallback (CallbackListPtr *list,
+ pointer closure,
+ pointer data)
+{
+ NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
+ ClientPtr pClient = clientinfo->client;
+ rrClientPriv(pClient);
+ RRTimesPtr pTimes = (RRTimesPtr) (pRRClient + 1);
+ int i;
+
+ pRRClient->major_version = 0;
+ pRRClient->minor_version = 0;
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ ScreenPtr pScreen = screenInfo.screens[i];
+ rrScrPriv(pScreen);
+
+ if (pScrPriv)
+ {
+ pTimes[i].setTime = pScrPriv->lastSetTime;
+ pTimes[i].configTime = pScrPriv->lastConfigTime;
+ }
+ }
+}
+
+static void
+RRResetProc (ExtensionEntry *extEntry)
+{
+}
+
+static Bool
+RRCloseScreen (int i, ScreenPtr pScreen)
+{
+ rrScrPriv(pScreen);
+
+ unwrap (pScrPriv, pScreen, CloseScreen);
+ if (pScrPriv->pSizes)
+ xfree (pScrPriv->pSizes);
+ xfree (pScrPriv);
+ RRNScreens -= 1; /* ok, one fewer screen with RandR running */
+ return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+static void
+SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent *from,
+ xRRScreenChangeNotifyEvent *to)
+{
+ to->type = from->type;
+ to->rotation = from->rotation;
+ cpswaps(from->sequenceNumber, to->sequenceNumber);
+ cpswapl(from->timestamp, to->timestamp);
+ cpswapl(from->configTimestamp, to->configTimestamp);
+ cpswapl(from->root, to->root);
+ cpswapl(from->window, to->window);
+ cpswaps(from->sizeID, to->sizeID);
+ cpswaps(from->widthInPixels, to->widthInPixels);
+ cpswaps(from->heightInPixels, to->heightInPixels);
+ cpswaps(from->widthInMillimeters, to->widthInMillimeters);
+ cpswaps(from->heightInMillimeters, to->heightInMillimeters);
+ cpswaps(from->subpixelOrder, to->subpixelOrder);
+}
+
+Bool RRScreenInit(ScreenPtr pScreen)
+{
+ rrScrPrivPtr pScrPriv;
+
+ if (RRGeneration != serverGeneration)
+ {
+ if ((rrPrivIndex = AllocateScreenPrivateIndex()) < 0)
+ return FALSE;
+ RRGeneration = serverGeneration;
+ }
+
+ pScrPriv = (rrScrPrivPtr) xalloc (sizeof (rrScrPrivRec));
+ if (!pScrPriv)
+ return FALSE;
+
+ SetRRScreen(pScreen, pScrPriv);
+
+ /*
+ * Calling function best set these function vectors
+ */
+ pScrPriv->rrSetConfig = 0;
+ pScrPriv->rrGetInfo = 0;
+ /*
+ * This value doesn't really matter -- any client must call
+ * GetScreenInfo before reading it which will automatically update
+ * the time
+ */
+ pScrPriv->lastSetTime = currentTime;
+ pScrPriv->lastConfigTime = currentTime;
+
+ wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen);
+
+ pScrPriv->rotations = RR_Rotate_0;
+
+ pScrPriv->nSizes = 0;
+ pScrPriv->nSizesInUse = 0;
+ pScrPriv->pSizes = 0;
+
+ pScrPriv->rotation = RR_Rotate_0;
+ pScrPriv->size = -1;
+
+ RRNScreens += 1; /* keep count of screens that implement randr */
+ return TRUE;
+}
+
+/*ARGSUSED*/
+static int
+RRFreeClient (pointer data, XID id)
+{
+ RREventPtr pRREvent;
+ WindowPtr pWin;
+ RREventPtr *pHead, pCur, pPrev;
+
+ pRREvent = (RREventPtr) data;
+ pWin = pRREvent->window;
+ pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, EventType);
+ if (pHead) {
+ pPrev = 0;
+ for (pCur = *pHead; pCur && pCur != pRREvent; pCur=pCur->next)
+ pPrev = pCur;
+ if (pCur)
+ {
+ if (pPrev)
+ pPrev->next = pRREvent->next;
+ else
+ *pHead = pRREvent->next;
+ }
+ }
+ xfree ((pointer) pRREvent);
+ return 1;
+}
+
+/*ARGSUSED*/
+static int
+RRFreeEvents (pointer data, XID id)
+{
+ RREventPtr *pHead, pCur, pNext;
+
+ pHead = (RREventPtr *) data;
+ for (pCur = *pHead; pCur; pCur = pNext) {
+ pNext = pCur->next;
+ FreeResource (pCur->clientResource, ClientType);
+ xfree ((pointer) pCur);
+ }
+ xfree ((pointer) pHead);
+ return 1;
+}
+
+void
+RRExtensionInit (void)
+{
+ ExtensionEntry *extEntry;
+
+ if (RRNScreens == 0) return;
+
+ RRClientPrivateIndex = AllocateClientPrivateIndex ();
+ if (!AllocateClientPrivate (RRClientPrivateIndex,
+ sizeof (RRClientRec) +
+ screenInfo.numScreens * sizeof (RRTimesRec)))
+ return;
+ if (!AddCallback (&ClientStateCallback, RRClientCallback, 0))
+ return;
+
+ ClientType = CreateNewResourceType(RRFreeClient);
+ if (!ClientType)
+ return;
+ EventType = CreateNewResourceType(RRFreeEvents);
+ if (!EventType)
+ return;
+ extEntry = AddExtension (RANDR_NAME, RRNumberEvents, RRNumberErrors,
+ ProcRRDispatch, SProcRRDispatch,
+ RRResetProc, StandardMinorOpcode);
+ if (!extEntry)
+ return;
+#if 0
+ RRReqCode = (CARD8) extEntry->base;
+ RRErrBase = extEntry->errorBase;
+#endif
+ RREventBase = extEntry->eventBase;
+ EventSwapVector[RREventBase + RRScreenChangeNotify] = (EventSwapPtr)
+ SRRScreenChangeNotifyEvent;
+
+ return;
+}
+
+int
+TellChanged (WindowPtr pWin, pointer value)
+{
+ RREventPtr *pHead, pRREvent;
+ ClientPtr client;
+ xRRScreenChangeNotifyEvent se;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ rrScrPriv(pScreen);
+ RRScreenSizePtr pSize;
+ WindowPtr pRoot = WindowTable[pScreen->myNum];
+
+ pHead = (RREventPtr *) LookupIDByType (pWin->drawable.id, EventType);
+ if (!pHead)
+ return WT_WALKCHILDREN;
+
+ se.type = RRScreenChangeNotify + RREventBase;
+ se.rotation = (CARD8) pScrPriv->rotation;
+ se.timestamp = pScrPriv->lastSetTime.milliseconds;
+ se.configTimestamp = pScrPriv->lastConfigTime.milliseconds;
+ se.root = pRoot->drawable.id;
+ se.window = pWin->drawable.id;
+#ifdef RENDER
+ se.subpixelOrder = PictureGetSubpixelOrder (pScreen);
+#else
+ se.subpixelOrder = SubPixelUnknown;
+#endif
+ if (pScrPriv->size >= 0)
+ {
+ pSize = &pScrPriv->pSizes[pScrPriv->size];
+ se.sizeID = pSize->id;
+ se.widthInPixels = pSize->width;
+ se.heightInPixels = pSize->height;
+ se.widthInMillimeters = pSize->mmWidth;
+ se.heightInMillimeters = pSize->mmHeight;
+ }
+ else
+ {
+ /*
+ * This "shouldn't happen", but a broken DDX can
+ * forget to set the current configuration on GetInfo
+ */
+ se.sizeID = 0xffff;
+ se.widthInPixels = 0;
+ se.heightInPixels = 0;
+ se.widthInMillimeters = 0;
+ se.heightInMillimeters = 0;
+ }
+ for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next)
+ {
+ client = pRREvent->client;
+ if (client == serverClient || client->clientGone)
+ continue;
+ se.sequenceNumber = client->sequence;
+ if(pRREvent->mask & RRScreenChangeNotifyMask)
+ WriteEventsToClient (client, 1, (xEvent *) &se);
+ }
+ return WT_WALKCHILDREN;
+}
+
+Bool
+RRGetInfo (ScreenPtr pScreen)
+{
+ rrScrPriv (pScreen);
+ int i, j, k, l;
+ Bool changed;
+ Rotation rotations;
+ RRScreenSizePtr pSize;
+ RRScreenRatePtr pRate;
+
+ for (i = 0; i < pScrPriv->nSizes; i++)
+ {
+ pSize = &pScrPriv->pSizes[i];
+ pSize->oldReferenced = pSize->referenced;
+ pSize->referenced = FALSE;
+ for (k = 0; k < pSize->nRates; k++)
+ {
+ pRate = &pSize->pRates[k];
+ pRate->oldReferenced = pRate->referenced;
+ pRate->referenced = FALSE;
+ }
+ }
+ if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations))
+ return FALSE;
+
+ changed = FALSE;
+
+ /*
+ * Check whether anything changed and simultaneously generate
+ * the protocol id values for the objects
+ */
+ if (rotations != pScrPriv->rotations)
+ {
+ pScrPriv->rotations = rotations;
+ changed = TRUE;
+ }
+
+ j = 0;
+ for (i = 0; i < pScrPriv->nSizes; i++)
+ {
+ pSize = &pScrPriv->pSizes[i];
+ if (pSize->oldReferenced != pSize->referenced)
+ changed = TRUE;
+ if (pSize->referenced)
+ pSize->id = j++;
+ l = 0;
+ for (k = 0; k < pSize->nRates; k++)
+ {
+ pRate = &pSize->pRates[k];
+ if (pRate->oldReferenced != pRate->referenced)
+ changed = TRUE;
+ if (pRate->referenced)
+ l++;
+ }
+ pSize->nRatesInUse = l;
+ }
+ pScrPriv->nSizesInUse = j;
+ if (changed)
+ {
+ UpdateCurrentTime ();
+ pScrPriv->lastConfigTime = currentTime;
+ WalkTree (pScreen, TellChanged, (pointer) pScreen);
+ }
+ return TRUE;
+}
+
+void
+RRSendConfigNotify (ScreenPtr pScreen)
+{
+ WindowPtr pWin = WindowTable[pScreen->myNum];
+ xEvent event;
+
+ event.u.u.type = ConfigureNotify;
+ event.u.configureNotify.window = pWin->drawable.id;
+ event.u.configureNotify.aboveSibling = None;
+ event.u.configureNotify.x = 0;
+ event.u.configureNotify.y = 0;
+
+ /* XXX xinerama stuff ? */
+
+ event.u.configureNotify.width = pWin->drawable.width;
+ event.u.configureNotify.height = pWin->drawable.height;
+ event.u.configureNotify.borderWidth = wBorderWidth (pWin);
+ event.u.configureNotify.override = pWin->overrideRedirect;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+}
+
+static int
+ProcRRQueryVersion (ClientPtr client)
+{
+ xRRQueryVersionReply rep;
+ register int n;
+ REQUEST(xRRQueryVersionReq);
+ rrClientPriv(client);
+
+ REQUEST_SIZE_MATCH(xRRQueryVersionReq);
+ pRRClient->major_version = stuff->majorVersion;
+ pRRClient->minor_version = stuff->minorVersion;
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = RANDR_MAJOR;
+ rep.minorVersion = RANDR_MINOR;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.majorVersion, n);
+ swapl(&rep.minorVersion, n);
+ }
+ WriteToClient(client, sizeof(xRRQueryVersionReply), (char *)&rep);
+ return (client->noClientException);
+}
+
+
+extern char *ConnectionInfo;
+
+static int padlength[4] = {0, 3, 2, 1};
+
+void
+RREditConnectionInfo (ScreenPtr pScreen)
+{
+ xConnSetup *connSetup;
+ char *vendor;
+ xPixmapFormat *formats;
+ xWindowRoot *root;
+ xDepth *depth;
+ xVisualType *visual;
+ int screen = 0;
+ int d;
+
+ connSetup = (xConnSetup *) ConnectionInfo;
+ vendor = (char *) connSetup + sizeof (xConnSetup);
+ formats = (xPixmapFormat *) ((char *) vendor +
+ connSetup->nbytesVendor +
+ padlength[connSetup->nbytesVendor & 3]);
+ root = (xWindowRoot *) ((char *) formats +
+ sizeof (xPixmapFormat) * screenInfo.numPixmapFormats);
+ while (screen != pScreen->myNum)
+ {
+ depth = (xDepth *) ((char *) root +
+ sizeof (xWindowRoot));
+ for (d = 0; d < root->nDepths; d++)
+ {
+ visual = (xVisualType *) ((char *) depth +
+ sizeof (xDepth));
+ depth = (xDepth *) ((char *) visual +
+ depth->nVisuals * sizeof (xVisualType));
+ }
+ root = (xWindowRoot *) ((char *) depth);
+ screen++;
+ }
+ root->pixWidth = pScreen->width;
+ root->pixHeight = pScreen->height;
+ root->mmWidth = pScreen->mmWidth;
+ root->mmHeight = pScreen->mmHeight;
+}
+
+static int
+ProcRRGetScreenInfo (ClientPtr client)
+{
+ REQUEST(xRRGetScreenInfoReq);
+ xRRGetScreenInfoReply rep;
+ WindowPtr pWin;
+ int n;
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+ CARD8 *extra;
+ unsigned long extraLen;
+
+ REQUEST_SIZE_MATCH(xRRGetScreenInfoReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityReadAccess);
+
+ if (!pWin)
+ return BadWindow;
+
+ pScreen = pWin->drawable.pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+ rep.pad = 0;
+ if (!pScrPriv)
+ {
+ rep.type = X_Reply;
+ rep.setOfRotations = RR_Rotate_0;;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
+ rep.timestamp = currentTime.milliseconds;
+ rep.configTimestamp = currentTime.milliseconds;
+ rep.nSizes = 0;
+ rep.sizeID = 0;
+ rep.rotation = RR_Rotate_0;
+ rep.rate = 0;
+ rep.nrateEnts = 0;
+ extra = 0;
+ extraLen = 0;
+ }
+ else
+ {
+ int i, j;
+ xScreenSizes *size;
+ CARD16 *rates;
+ CARD8 *data8;
+ Bool has_rate = RRClientKnowsRates (client);
+
+ RRGetInfo (pScreen);
+
+ rep.type = X_Reply;
+ rep.setOfRotations = pScrPriv->rotations;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
+ rep.timestamp = pScrPriv->lastSetTime.milliseconds;
+ rep.configTimestamp = pScrPriv->lastConfigTime.milliseconds;
+ rep.rotation = pScrPriv->rotation;
+ rep.nSizes = pScrPriv->nSizesInUse;
+ rep.rate = pScrPriv->rate;
+ rep.nrateEnts = 0;
+ if (has_rate)
+ {
+ for (i = 0; i < pScrPriv->nSizes; i++)
+ {
+ RRScreenSizePtr pSize = &pScrPriv->pSizes[i];
+ if (pSize->referenced)
+ {
+ rep.nrateEnts += (1 + pSize->nRatesInUse);
+ }
+ }
+ }
+
+ if (pScrPriv->size >= 0)
+ rep.sizeID = pScrPriv->pSizes[pScrPriv->size].id;
+ else
+ return BadImplementation;
+
+ extraLen = (rep.nSizes * sizeof (xScreenSizes) +
+ rep.nrateEnts * sizeof (CARD16));
+
+ extra = (CARD8 *) xalloc (extraLen);
+ if (!extra)
+ return BadAlloc;
+ /*
+ * First comes the size information
+ */
+ size = (xScreenSizes *) extra;
+ rates = (CARD16 *) (size + rep.nSizes);
+ for (i = 0; i < pScrPriv->nSizes; i++)
+ {
+ RRScreenSizePtr pSize = &pScrPriv->pSizes[i];
+ if (pSize->referenced)
+ {
+ size->widthInPixels = pSize->width;
+ size->heightInPixels = pSize->height;
+ size->widthInMillimeters = pSize->mmWidth;
+ size->heightInMillimeters = pSize->mmHeight;
+ if (client->swapped)
+ {
+ swaps (&size->widthInPixels, n);
+ swaps (&size->heightInPixels, n);
+ swaps (&size->widthInMillimeters, n);
+ swaps (&size->heightInMillimeters, n);
+ }
+ size++;
+ if (has_rate)
+ {
+ *rates = pSize->nRatesInUse;
+ if (client->swapped)
+ {
+ swaps (rates, n);
+ }
+ rates++;
+ for (j = 0; j < pSize->nRates; j++)
+ {
+ RRScreenRatePtr pRate = &pSize->pRates[j];
+ if (pRate->referenced)
+ {
+ *rates = pRate->rate;
+ if (client->swapped)
+ {
+ swaps (rates, n);
+ }
+ rates++;
+ }
+ }
+ }
+ }
+ }
+ data8 = (CARD8 *) rates;
+
+ if (data8 - (CARD8 *) extra != extraLen)
+ FatalError ("RRGetScreenInfo bad extra len %ld != %ld\n",
+ (unsigned long)(data8 - (CARD8 *) extra), extraLen);
+ rep.length = (extraLen + 3) >> 2;
+ }
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.timestamp, n);
+ swaps(&rep.rotation, n);
+ swaps(&rep.nSizes, n);
+ swaps(&rep.sizeID, n);
+ swaps(&rep.rate, n);
+ swaps(&rep.nrateEnts, n);
+ }
+ WriteToClient(client, sizeof(xRRGetScreenInfoReply), (char *)&rep);
+ if (extraLen)
+ {
+ WriteToClient (client, extraLen, (char *) extra);
+ xfree (extra);
+ }
+ return (client->noClientException);
+}
+
+static int
+ProcRRSetScreenConfig (ClientPtr client)
+{
+ REQUEST(xRRSetScreenConfigReq);
+ xRRSetScreenConfigReply rep;
+ DrawablePtr pDraw;
+ int n;
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+ TimeStamp configTime;
+ TimeStamp time;
+ RRScreenSizePtr pSize;
+ int i;
+ Rotation rotation;
+ int rate;
+ short oldWidth, oldHeight;
+ Bool has_rate;
+
+ UpdateCurrentTime ();
+
+ if (RRClientKnowsRates (client))
+ {
+ REQUEST_SIZE_MATCH (xRRSetScreenConfigReq);
+ has_rate = TRUE;
+ }
+ else
+ {
+ REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq);
+ has_rate = FALSE;
+ }
+
+ SECURITY_VERIFY_DRAWABLE(pDraw, stuff->drawable, client,
+ SecurityWriteAccess);
+
+ pScreen = pDraw->pScreen;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ time = ClientTimeToServerTime(stuff->timestamp);
+ configTime = ClientTimeToServerTime(stuff->configTimestamp);
+
+ oldWidth = pScreen->width;
+ oldHeight = pScreen->height;
+
+ if (!pScrPriv)
+ {
+ time = currentTime;
+ rep.status = RRSetConfigFailed;
+ goto sendReply;
+ }
+ if (!RRGetInfo (pScreen))
+ return BadAlloc;
+
+ /*
+ * if the client's config timestamp is not the same as the last config
+ * timestamp, then the config information isn't up-to-date and
+ * can't even be validated
+ */
+ if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0)
+ {
+ rep.status = RRSetConfigInvalidConfigTime;
+ goto sendReply;
+ }
+
+ /*
+ * Search for the requested size
+ */
+ pSize = 0;
+ for (i = 0; i < pScrPriv->nSizes; i++)
+ {
+ pSize = &pScrPriv->pSizes[i];
+ if (pSize->referenced && pSize->id == stuff->sizeID)
+ {
+ break;
+ }
+ }
+ if (i == pScrPriv->nSizes)
+ {
+ /*
+ * Invalid size ID
+ */
+ client->errorValue = stuff->sizeID;
+ return BadValue;
+ }
+
+ /*
+ * Validate requested rotation
+ */
+ rotation = (Rotation) stuff->rotation;
+
+ /* test the rotation bits only! */
+ switch (rotation & 0xf) {
+ case RR_Rotate_0:
+ case RR_Rotate_90:
+ case RR_Rotate_180:
+ case RR_Rotate_270:
+ break;
+ default:
+ /*
+ * Invalid rotation
+ */
+ client->errorValue = stuff->rotation;
+ return BadValue;
+ }
+
+ if ((~pScrPriv->rotations) & rotation)
+ {
+ /*
+ * requested rotation or reflection not supported by screen
+ */
+ client->errorValue = stuff->rotation;
+ return BadMatch;
+ }
+
+ /*
+ * Validate requested refresh
+ */
+ if (has_rate)
+ rate = (int) stuff->rate;
+ else
+ rate = 0;
+
+ if (rate)
+ {
+ for (i = 0; i < pSize->nRates; i++)
+ {
+ RRScreenRatePtr pRate = &pSize->pRates[i];
+ if (pRate->referenced && pRate->rate == rate)
+ break;
+ }
+ if (i == pSize->nRates)
+ {
+ /*
+ * Invalid rate
+ */
+ client->errorValue = rate;
+ return BadValue;
+ }
+ }
+
+ /*
+ * Make sure the requested set-time is not older than
+ * the last set-time
+ */
+ if (CompareTimeStamps (time, pScrPriv->lastSetTime) < 0)
+ {
+ rep.status = RRSetConfigInvalidTime;
+ goto sendReply;
+ }
+
+ /*
+ * call out to ddx routine to effect the change
+ */
+ if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate,
+ pSize))
+ {
+ /*
+ * unknown DDX failure, report to client
+ */
+ rep.status = RRSetConfigFailed;
+ goto sendReply;
+ }
+
+ /*
+ * set current extension configuration pointers
+ */
+ RRSetCurrentConfig (pScreen, rotation, rate, pSize);
+
+ /*
+ * Deliver ScreenChangeNotify events whenever
+ * the configuration is updated
+ */
+ WalkTree (pScreen, TellChanged, (pointer) pScreen);
+
+ /*
+ * Deliver ConfigureNotify events when root changes
+ * pixel size
+ */
+ if (oldWidth != pScreen->width || oldHeight != pScreen->height)
+ RRSendConfigNotify (pScreen);
+ RREditConnectionInfo (pScreen);
+
+ /*
+ * Fix pointer bounds and location
+ */
+ ScreenRestructured (pScreen);
+ pScrPriv->lastSetTime = time;
+
+ /*
+ * Report Success
+ */
+ rep.status = RRSetConfigSuccess;
+
+sendReply:
+
+ rep.type = X_Reply;
+ /* rep.status has already been filled in */
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ rep.newTimestamp = pScrPriv->lastSetTime.milliseconds;
+ rep.newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds;
+ rep.root = WindowTable[pDraw->pScreen->myNum]->drawable.id;
+
+ if (client->swapped)
+ {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.newTimestamp, n);
+ swapl(&rep.newConfigTimestamp, n);
+ swapl(&rep.root, n);
+ }
+ WriteToClient(client, sizeof(xRRSetScreenConfigReply), (char *)&rep);
+
+ return (client->noClientException);
+}
+
+int
+RRSetScreenConfig (ScreenPtr pScreen,
+ Rotation rotation,
+ int rate,
+ RRScreenSizePtr pSize)
+{
+ rrScrPrivPtr pScrPriv;
+ int i;
+ short oldWidth, oldHeight;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ oldWidth = pScreen->width;
+ oldHeight = pScreen->height;
+
+ if (!RRGetInfo (pScreen))
+ return BadAlloc;
+
+ /*
+ * Validate requested rotation
+ */
+
+ /* test the rotation bits only! */
+ switch (rotation & 0xf) {
+ case RR_Rotate_0:
+ case RR_Rotate_90:
+ case RR_Rotate_180:
+ case RR_Rotate_270:
+ break;
+ default:
+ /*
+ * Invalid rotation
+ */
+ return BadValue;
+ }
+
+ if ((~pScrPriv->rotations) & rotation)
+ {
+ /*
+ * requested rotation or reflection not supported by screen
+ */
+ return BadMatch;
+ }
+
+ /*
+ * Validate requested refresh
+ */
+ if (rate)
+ {
+ for (i = 0; i < pSize->nRates; i++)
+ {
+ RRScreenRatePtr pRate = &pSize->pRates[i];
+ if (pRate->referenced && pRate->rate == rate)
+ break;
+ }
+ if (i == pSize->nRates)
+ {
+ /*
+ * Invalid rate
+ */
+ return BadValue;
+ }
+ }
+
+ /*
+ * call out to ddx routine to effect the change
+ */
+ if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate,
+ pSize))
+ {
+ /*
+ * unknown DDX failure, report to client
+ */
+ return BadImplementation;
+ }
+
+ /*
+ * set current extension configuration pointers
+ */
+ RRSetCurrentConfig (pScreen, rotation, rate, pSize);
+
+ /*
+ * Deliver ScreenChangeNotify events whenever
+ * the configuration is updated
+ */
+ WalkTree (pScreen, TellChanged, (pointer) pScreen);
+
+ /*
+ * Deliver ConfigureNotify events when root changes
+ * pixel size
+ */
+ if (oldWidth != pScreen->width || oldHeight != pScreen->height)
+ RRSendConfigNotify (pScreen);
+ RREditConnectionInfo (pScreen);
+
+ /*
+ * Fix pointer bounds and location
+ */
+ ScreenRestructured (pScreen);
+
+ return Success;
+}
+
+static int
+ProcRRSelectInput (ClientPtr client)
+{
+ REQUEST(xRRSelectInputReq);
+ rrClientPriv(client);
+ RRTimesPtr pTimes;
+ WindowPtr pWin;
+ RREventPtr pRREvent, pNewRREvent, *pHead;
+ XID clientResource;
+
+ REQUEST_SIZE_MATCH(xRRSelectInputReq);
+ pWin = SecurityLookupWindow (stuff->window, client, SecurityWriteAccess);
+ if (!pWin)
+ return BadWindow;
+ pHead = (RREventPtr *)SecurityLookupIDByType(client,
+ pWin->drawable.id, EventType,
+ SecurityWriteAccess);
+
+ if (stuff->enable & (RRScreenChangeNotifyMask))
+ {
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ rrScrPriv (pScreen);
+
+ if (pHead)
+ {
+ /* check for existing entry. */
+ for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next)
+ if (pRREvent->client == client)
+ return Success;
+ }
+
+ /* build the entry */
+ pNewRREvent = (RREventPtr) xalloc (sizeof (RREventRec));
+ if (!pNewRREvent)
+ return BadAlloc;
+ pNewRREvent->next = 0;
+ pNewRREvent->client = client;
+ pNewRREvent->window = pWin;
+ pNewRREvent->mask = stuff->enable;
+ /*
+ * add a resource that will be deleted when
+ * the client goes away
+ */
+ clientResource = FakeClientID (client->index);
+ pNewRREvent->clientResource = clientResource;
+ if (!AddResource (clientResource, ClientType, (pointer)pNewRREvent))
+ return BadAlloc;
+ /*
+ * create a resource to contain a pointer to the list
+ * of clients selecting input. This must be indirect as
+ * the list may be arbitrarily rearranged which cannot be
+ * done through the resource database.
+ */
+ if (!pHead)
+ {
+ pHead = (RREventPtr *) xalloc (sizeof (RREventPtr));
+ if (!pHead ||
+ !AddResource (pWin->drawable.id, EventType, (pointer)pHead))
+ {
+ FreeResource (clientResource, RT_NONE);
+ return BadAlloc;
+ }
+ *pHead = 0;
+ }
+ pNewRREvent->next = *pHead;
+ *pHead = pNewRREvent;
+ /*
+ * Now see if the client needs an event
+ */
+ if (pScrPriv)
+ {
+ pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum];
+ if (CompareTimeStamps (pTimes->setTime,
+ pScrPriv->lastSetTime) != 0 ||
+ CompareTimeStamps (pTimes->configTime,
+ pScrPriv->lastConfigTime) != 0)
+ {
+ TellChanged (pWin, (pointer) pScreen);
+ }
+ }
+ }
+ else if (stuff->enable == xFalse)
+ {
+ /* delete the interest */
+ if (pHead) {
+ pNewRREvent = 0;
+ for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) {
+ if (pRREvent->client == client)
+ break;
+ pNewRREvent = pRREvent;
+ }
+ if (pRREvent) {
+ FreeResource (pRREvent->clientResource, ClientType);
+ if (pNewRREvent)
+ pNewRREvent->next = pRREvent->next;
+ else
+ *pHead = pRREvent->next;
+ xfree (pRREvent);
+ }
+ }
+ }
+ else
+ {
+ client->errorValue = stuff->enable;
+ return BadValue;
+ }
+ return Success;
+}
+
+
+static int
+ProcRRDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_RRQueryVersion:
+ return ProcRRQueryVersion(client);
+ case X_RRSetScreenConfig:
+ return ProcRRSetScreenConfig(client);
+ case X_RRSelectInput:
+ return ProcRRSelectInput(client);
+ case X_RRGetScreenInfo:
+ return ProcRRGetScreenInfo(client);
+ default:
+ return BadRequest;
+ }
+}
+
+static int
+SProcRRQueryVersion (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRRQueryVersionReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->majorVersion, n);
+ swapl(&stuff->minorVersion, n);
+ return ProcRRQueryVersion(client);
+}
+
+static int
+SProcRRGetScreenInfo (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRRGetScreenInfoReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ return ProcRRGetScreenInfo(client);
+}
+
+static int
+SProcRRSetScreenConfig (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRRSetScreenConfigReq);
+
+ if (RRClientKnowsRates (client))
+ {
+ REQUEST_SIZE_MATCH (xRRSetScreenConfigReq);
+ swaps (&stuff->rate, n);
+ }
+ else
+ {
+ REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq);
+ }
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->drawable, n);
+ swapl(&stuff->timestamp, n);
+ swaps(&stuff->sizeID, n);
+ swaps(&stuff->rotation, n);
+ return ProcRRSetScreenConfig(client);
+}
+
+static int
+SProcRRSelectInput (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRRSelectInputReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ return ProcRRSelectInput(client);
+}
+
+
+static int
+SProcRRDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_RRQueryVersion:
+ return SProcRRQueryVersion(client);
+ case X_RRSetScreenConfig:
+ return SProcRRSetScreenConfig(client);
+ case X_RRSelectInput:
+ return SProcRRSelectInput(client);
+ case X_RRGetScreenInfo:
+ return SProcRRGetScreenInfo(client);
+ default:
+ return BadRequest;
+ }
+}
+
+
+static Bool
+RRScreenSizeMatches (RRScreenSizePtr a,
+ RRScreenSizePtr b)
+{
+ if (a->width != b->width)
+ return FALSE;
+ if (a->height != b->height)
+ return FALSE;
+ if (a->mmWidth != b->mmWidth)
+ return FALSE;
+ if (a->mmHeight != b->mmHeight)
+ return FALSE;
+ return TRUE;
+}
+
+RRScreenSizePtr
+RRRegisterSize (ScreenPtr pScreen,
+ short width,
+ short height,
+ short mmWidth,
+ short mmHeight)
+{
+ rrScrPriv (pScreen);
+ int i;
+ RRScreenSize tmp;
+ RRScreenSizePtr pNew;
+
+ if (!pScrPriv)
+ return 0;
+
+ /*
+ * FIXME: The compiler reports that field
+ * id is used uninitialized here.
+ */
+
+ tmp.id = 0;
+
+ tmp.width = width;
+ tmp.height= height;
+ tmp.mmWidth = mmWidth;
+ tmp.mmHeight = mmHeight;
+ tmp.pRates = 0;
+ tmp.nRates = 0;
+ tmp.nRatesInUse = 0;
+ tmp.referenced = TRUE;
+ tmp.oldReferenced = FALSE;
+ for (i = 0; i < pScrPriv->nSizes; i++)
+ if (RRScreenSizeMatches (&tmp, &pScrPriv->pSizes[i]))
+ {
+ pScrPriv->pSizes[i].referenced = TRUE;
+ return &pScrPriv->pSizes[i];
+ }
+ pNew = xrealloc (pScrPriv->pSizes,
+ (pScrPriv->nSizes + 1) * sizeof (RRScreenSize));
+ if (!pNew)
+ return 0;
+ pNew[pScrPriv->nSizes++] = tmp;
+ pScrPriv->pSizes = pNew;
+ return &pNew[pScrPriv->nSizes-1];
+}
+
+Bool RRRegisterRate (ScreenPtr pScreen,
+ RRScreenSizePtr pSize,
+ int rate)
+{
+ rrScrPriv(pScreen);
+ int i;
+ RRScreenRatePtr pNew, pRate;
+
+ if (!pScrPriv)
+ return FALSE;
+
+ for (i = 0; i < pSize->nRates; i++)
+ {
+ pRate = &pSize->pRates[i];
+ if (pRate->rate == rate)
+ {
+ pRate->referenced = TRUE;
+ return TRUE;
+ }
+ }
+
+ pNew = xrealloc (pSize->pRates,
+ (pSize->nRates + 1) * sizeof (RRScreenRate));
+ if (!pNew)
+ return FALSE;
+ pRate = &pNew[pSize->nRates++];
+ pRate->rate = rate;
+ pRate->referenced = TRUE;
+ pRate->oldReferenced = FALSE;
+ pSize->pRates = pNew;
+ return TRUE;
+}
+
+void
+RRSetCurrentConfig (ScreenPtr pScreen,
+ Rotation rotation,
+ int rate,
+ RRScreenSizePtr pSize)
+{
+ rrScrPriv (pScreen);
+
+ if (!pScrPriv)
+ return;
+
+ pScrPriv->rotation = rotation;
+ pScrPriv->size = pSize - pScrPriv->pSizes;
+ pScrPriv->rate = rate;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original
new file mode 100644
index 000000000..426d15b1b
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original
@@ -0,0 +1,1344 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/randr/randr.c,v 1.21tsi Exp $
+ *
+ * Copyright © 2000, Compaq Computer Corporation,
+ * Copyright © 2002, Hewlett Packard, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Compaq or HP not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. HP makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * HP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL HP
+ * 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.
+ *
+ * Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc.
+ */
+
+
+#define NEED_REPLIES
+#define NEED_EVENTS
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#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 "extnsionst.h"
+#include "servermd.h"
+#include <X11/extensions/randr.h>
+#include <X11/extensions/randrproto.h>
+#include "../../randr/randrstr.h"
+#ifdef RENDER
+#include <X11/extensions/render.h> /* we share subpixel order information */
+#include "picturestr.h"
+#endif
+#include <X11/Xfuncproto.h>
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#endif
+
+/* From render.h */
+#ifndef SubPixelUnknown
+#define SubPixelUnknown 0
+#endif
+
+#define RR_VALIDATE
+int RRGeneration;
+int RRNScreens;
+
+static int ProcRRQueryVersion (ClientPtr pClient);
+static int ProcRRDispatch (ClientPtr pClient);
+static int SProcRRDispatch (ClientPtr pClient);
+static int SProcRRQueryVersion (ClientPtr pClient);
+
+#define wrap(priv,real,mem,func) {\
+ priv->mem = real->mem; \
+ real->mem = func; \
+}
+
+#define unwrap(priv,real,mem) {\
+ real->mem = priv->mem; \
+}
+
+#if 0
+static CARD8 RRReqCode;
+static int RRErrBase;
+#endif
+static int RREventBase;
+static RESTYPE ClientType, EventType; /* resource types for event masks */
+static int RRClientPrivateIndex;
+
+typedef struct _RRTimes {
+ TimeStamp setTime;
+ TimeStamp configTime;
+} RRTimesRec, *RRTimesPtr;
+
+typedef struct _RRClient {
+ int major_version;
+ int minor_version;
+/* RRTimesRec times[0]; */
+} RRClientRec, *RRClientPtr;
+
+/*
+ * each window has a list of clients requesting
+ * RRNotify events. Each client has a resource
+ * for each window it selects RRNotify input for,
+ * this resource is used to delete the RRNotifyRec
+ * entry from the per-window queue.
+ */
+
+typedef struct _RREvent *RREventPtr;
+
+typedef struct _RREvent {
+ RREventPtr next;
+ ClientPtr client;
+ WindowPtr window;
+ XID clientResource;
+ int mask;
+} RREventRec;
+
+int rrPrivIndex = -1;
+
+#define GetRRClient(pClient) ((RRClientPtr) (pClient)->devPrivates[RRClientPrivateIndex].ptr)
+#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient)
+
+static Bool
+RRClientKnowsRates (ClientPtr pClient)
+{
+ rrClientPriv(pClient);
+
+ return (pRRClient->major_version > 1 ||
+ (pRRClient->major_version == 1 && pRRClient->minor_version >= 1));
+}
+
+static void
+RRClientCallback (CallbackListPtr *list,
+ pointer closure,
+ pointer data)
+{
+ NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
+ ClientPtr pClient = clientinfo->client;
+ rrClientPriv(pClient);
+ RRTimesPtr pTimes = (RRTimesPtr) (pRRClient + 1);
+ int i;
+
+ pRRClient->major_version = 0;
+ pRRClient->minor_version = 0;
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ ScreenPtr pScreen = screenInfo.screens[i];
+ rrScrPriv(pScreen);
+
+ if (pScrPriv)
+ {
+ pTimes[i].setTime = pScrPriv->lastSetTime;
+ pTimes[i].configTime = pScrPriv->lastConfigTime;
+ }
+ }
+}
+
+static void
+RRResetProc (ExtensionEntry *extEntry)
+{
+}
+
+static Bool
+RRCloseScreen (int i, ScreenPtr pScreen)
+{
+ rrScrPriv(pScreen);
+
+ unwrap (pScrPriv, pScreen, CloseScreen);
+ if (pScrPriv->pSizes)
+ xfree (pScrPriv->pSizes);
+ xfree (pScrPriv);
+ RRNScreens -= 1; /* ok, one fewer screen with RandR running */
+ return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+static void
+SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent *from,
+ xRRScreenChangeNotifyEvent *to)
+{
+ to->type = from->type;
+ to->rotation = from->rotation;
+ cpswaps(from->sequenceNumber, to->sequenceNumber);
+ cpswapl(from->timestamp, to->timestamp);
+ cpswapl(from->configTimestamp, to->configTimestamp);
+ cpswapl(from->root, to->root);
+ cpswapl(from->window, to->window);
+ cpswaps(from->sizeID, to->sizeID);
+ cpswaps(from->widthInPixels, to->widthInPixels);
+ cpswaps(from->heightInPixels, to->heightInPixels);
+ cpswaps(from->widthInMillimeters, to->widthInMillimeters);
+ cpswaps(from->heightInMillimeters, to->heightInMillimeters);
+ cpswaps(from->subpixelOrder, to->subpixelOrder);
+}
+
+Bool RRScreenInit(ScreenPtr pScreen)
+{
+ rrScrPrivPtr pScrPriv;
+
+ if (RRGeneration != serverGeneration)
+ {
+ if ((rrPrivIndex = AllocateScreenPrivateIndex()) < 0)
+ return FALSE;
+ RRGeneration = serverGeneration;
+ }
+
+ pScrPriv = (rrScrPrivPtr) xalloc (sizeof (rrScrPrivRec));
+ if (!pScrPriv)
+ return FALSE;
+
+ SetRRScreen(pScreen, pScrPriv);
+
+ /*
+ * Calling function best set these function vectors
+ */
+ pScrPriv->rrSetConfig = 0;
+ pScrPriv->rrGetInfo = 0;
+ /*
+ * This value doesn't really matter -- any client must call
+ * GetScreenInfo before reading it which will automatically update
+ * the time
+ */
+ pScrPriv->lastSetTime = currentTime;
+ pScrPriv->lastConfigTime = currentTime;
+
+ wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen);
+
+ pScrPriv->rotations = RR_Rotate_0;
+
+ pScrPriv->nSizes = 0;
+ pScrPriv->nSizesInUse = 0;
+ pScrPriv->pSizes = 0;
+
+ pScrPriv->rotation = RR_Rotate_0;
+ pScrPriv->size = -1;
+
+ RRNScreens += 1; /* keep count of screens that implement randr */
+ return TRUE;
+}
+
+/*ARGSUSED*/
+static int
+RRFreeClient (pointer data, XID id)
+{
+ RREventPtr pRREvent;
+ WindowPtr pWin;
+ RREventPtr *pHead, pCur, pPrev;
+
+ pRREvent = (RREventPtr) data;
+ pWin = pRREvent->window;
+ pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, EventType);
+ if (pHead) {
+ pPrev = 0;
+ for (pCur = *pHead; pCur && pCur != pRREvent; pCur=pCur->next)
+ pPrev = pCur;
+ if (pCur)
+ {
+ if (pPrev)
+ pPrev->next = pRREvent->next;
+ else
+ *pHead = pRREvent->next;
+ }
+ }
+ xfree ((pointer) pRREvent);
+ return 1;
+}
+
+/*ARGSUSED*/
+static int
+RRFreeEvents (pointer data, XID id)
+{
+ RREventPtr *pHead, pCur, pNext;
+
+ pHead = (RREventPtr *) data;
+ for (pCur = *pHead; pCur; pCur = pNext) {
+ pNext = pCur->next;
+ FreeResource (pCur->clientResource, ClientType);
+ xfree ((pointer) pCur);
+ }
+ xfree ((pointer) pHead);
+ return 1;
+}
+
+void
+RRExtensionInit (void)
+{
+ ExtensionEntry *extEntry;
+
+ if (RRNScreens == 0) return;
+
+ RRClientPrivateIndex = AllocateClientPrivateIndex ();
+ if (!AllocateClientPrivate (RRClientPrivateIndex,
+ sizeof (RRClientRec) +
+ screenInfo.numScreens * sizeof (RRTimesRec)))
+ return;
+ if (!AddCallback (&ClientStateCallback, RRClientCallback, 0))
+ return;
+
+ ClientType = CreateNewResourceType(RRFreeClient);
+ if (!ClientType)
+ return;
+ EventType = CreateNewResourceType(RRFreeEvents);
+ if (!EventType)
+ return;
+ extEntry = AddExtension (RANDR_NAME, RRNumberEvents, RRNumberErrors,
+ ProcRRDispatch, SProcRRDispatch,
+ RRResetProc, StandardMinorOpcode);
+ if (!extEntry)
+ return;
+#if 0
+ RRReqCode = (CARD8) extEntry->base;
+ RRErrBase = extEntry->errorBase;
+#endif
+ RREventBase = extEntry->eventBase;
+ EventSwapVector[RREventBase + RRScreenChangeNotify] = (EventSwapPtr)
+ SRRScreenChangeNotifyEvent;
+
+ return;
+}
+
+int
+TellChanged (WindowPtr pWin, pointer value)
+{
+ RREventPtr *pHead, pRREvent;
+ ClientPtr client;
+ xRRScreenChangeNotifyEvent se;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ rrScrPriv(pScreen);
+ RRScreenSizePtr pSize;
+ WindowPtr pRoot = WindowTable[pScreen->myNum];
+
+ pHead = (RREventPtr *) LookupIDByType (pWin->drawable.id, EventType);
+ if (!pHead)
+ return WT_WALKCHILDREN;
+
+ se.type = RRScreenChangeNotify + RREventBase;
+ se.rotation = (CARD8) pScrPriv->rotation;
+ se.timestamp = pScrPriv->lastSetTime.milliseconds;
+ se.configTimestamp = pScrPriv->lastConfigTime.milliseconds;
+ se.root = pRoot->drawable.id;
+ se.window = pWin->drawable.id;
+#ifdef RENDER
+ se.subpixelOrder = PictureGetSubpixelOrder (pScreen);
+#else
+ se.subpixelOrder = SubPixelUnknown;
+#endif
+ if (pScrPriv->size >= 0)
+ {
+ pSize = &pScrPriv->pSizes[pScrPriv->size];
+ se.sizeID = pSize->id;
+ se.widthInPixels = pSize->width;
+ se.heightInPixels = pSize->height;
+ se.widthInMillimeters = pSize->mmWidth;
+ se.heightInMillimeters = pSize->mmHeight;
+ }
+ else
+ {
+ /*
+ * This "shouldn't happen", but a broken DDX can
+ * forget to set the current configuration on GetInfo
+ */
+ se.sizeID = 0xffff;
+ se.widthInPixels = 0;
+ se.heightInPixels = 0;
+ se.widthInMillimeters = 0;
+ se.heightInMillimeters = 0;
+ }
+ for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next)
+ {
+ client = pRREvent->client;
+ if (client == serverClient || client->clientGone)
+ continue;
+ se.sequenceNumber = client->sequence;
+ if(pRREvent->mask & RRScreenChangeNotifyMask)
+ WriteEventsToClient (client, 1, (xEvent *) &se);
+ }
+ return WT_WALKCHILDREN;
+}
+
+Bool
+RRGetInfo (ScreenPtr pScreen)
+{
+ rrScrPriv (pScreen);
+ int i, j, k, l;
+ Bool changed;
+ Rotation rotations;
+ RRScreenSizePtr pSize;
+ RRScreenRatePtr pRate;
+
+ for (i = 0; i < pScrPriv->nSizes; i++)
+ {
+ pSize = &pScrPriv->pSizes[i];
+ pSize->oldReferenced = pSize->referenced;
+ pSize->referenced = FALSE;
+ for (k = 0; k < pSize->nRates; k++)
+ {
+ pRate = &pSize->pRates[k];
+ pRate->oldReferenced = pRate->referenced;
+ pRate->referenced = FALSE;
+ }
+ }
+ if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations))
+ return FALSE;
+
+ changed = FALSE;
+
+ /*
+ * Check whether anything changed and simultaneously generate
+ * the protocol id values for the objects
+ */
+ if (rotations != pScrPriv->rotations)
+ {
+ pScrPriv->rotations = rotations;
+ changed = TRUE;
+ }
+
+ j = 0;
+ for (i = 0; i < pScrPriv->nSizes; i++)
+ {
+ pSize = &pScrPriv->pSizes[i];
+ if (pSize->oldReferenced != pSize->referenced)
+ changed = TRUE;
+ if (pSize->referenced)
+ pSize->id = j++;
+ l = 0;
+ for (k = 0; k < pSize->nRates; k++)
+ {
+ pRate = &pSize->pRates[k];
+ if (pRate->oldReferenced != pRate->referenced)
+ changed = TRUE;
+ if (pRate->referenced)
+ l++;
+ }
+ pSize->nRatesInUse = l;
+ }
+ pScrPriv->nSizesInUse = j;
+ if (changed)
+ {
+ UpdateCurrentTime ();
+ pScrPriv->lastConfigTime = currentTime;
+ WalkTree (pScreen, TellChanged, (pointer) pScreen);
+ }
+ return TRUE;
+}
+
+void
+RRSendConfigNotify (ScreenPtr pScreen)
+{
+ WindowPtr pWin = WindowTable[pScreen->myNum];
+ xEvent event;
+
+ event.u.u.type = ConfigureNotify;
+ event.u.configureNotify.window = pWin->drawable.id;
+ event.u.configureNotify.aboveSibling = None;
+ event.u.configureNotify.x = 0;
+ event.u.configureNotify.y = 0;
+
+ /* XXX xinerama stuff ? */
+
+ event.u.configureNotify.width = pWin->drawable.width;
+ event.u.configureNotify.height = pWin->drawable.height;
+ event.u.configureNotify.borderWidth = wBorderWidth (pWin);
+ event.u.configureNotify.override = pWin->overrideRedirect;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+}
+
+static int
+ProcRRQueryVersion (ClientPtr client)
+{
+ xRRQueryVersionReply rep;
+ register int n;
+ REQUEST(xRRQueryVersionReq);
+ rrClientPriv(client);
+
+ REQUEST_SIZE_MATCH(xRRQueryVersionReq);
+ pRRClient->major_version = stuff->majorVersion;
+ pRRClient->minor_version = stuff->minorVersion;
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = RANDR_MAJOR;
+ rep.minorVersion = RANDR_MINOR;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.majorVersion, n);
+ swapl(&rep.minorVersion, n);
+ }
+ WriteToClient(client, sizeof(xRRQueryVersionReply), (char *)&rep);
+ return (client->noClientException);
+}
+
+
+extern char *ConnectionInfo;
+
+static int padlength[4] = {0, 3, 2, 1};
+
+void
+RREditConnectionInfo (ScreenPtr pScreen)
+{
+ xConnSetup *connSetup;
+ char *vendor;
+ xPixmapFormat *formats;
+ xWindowRoot *root;
+ xDepth *depth;
+ xVisualType *visual;
+ int screen = 0;
+ int d;
+
+ connSetup = (xConnSetup *) ConnectionInfo;
+ vendor = (char *) connSetup + sizeof (xConnSetup);
+ formats = (xPixmapFormat *) ((char *) vendor +
+ connSetup->nbytesVendor +
+ padlength[connSetup->nbytesVendor & 3]);
+ root = (xWindowRoot *) ((char *) formats +
+ sizeof (xPixmapFormat) * screenInfo.numPixmapFormats);
+ while (screen != pScreen->myNum)
+ {
+ depth = (xDepth *) ((char *) root +
+ sizeof (xWindowRoot));
+ for (d = 0; d < root->nDepths; d++)
+ {
+ visual = (xVisualType *) ((char *) depth +
+ sizeof (xDepth));
+ depth = (xDepth *) ((char *) visual +
+ depth->nVisuals * sizeof (xVisualType));
+ }
+ root = (xWindowRoot *) ((char *) depth);
+ screen++;
+ }
+ root->pixWidth = pScreen->width;
+ root->pixHeight = pScreen->height;
+ root->mmWidth = pScreen->mmWidth;
+ root->mmHeight = pScreen->mmHeight;
+}
+
+static int
+ProcRRGetScreenInfo (ClientPtr client)
+{
+ REQUEST(xRRGetScreenInfoReq);
+ xRRGetScreenInfoReply rep;
+ WindowPtr pWin;
+ int n;
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+ CARD8 *extra;
+ unsigned long extraLen;
+
+ REQUEST_SIZE_MATCH(xRRGetScreenInfoReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityReadAccess);
+
+ if (!pWin)
+ return BadWindow;
+
+ pScreen = pWin->drawable.pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+ rep.pad = 0;
+ if (!pScrPriv)
+ {
+ rep.type = X_Reply;
+ rep.setOfRotations = RR_Rotate_0;;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
+ rep.timestamp = currentTime.milliseconds;
+ rep.configTimestamp = currentTime.milliseconds;
+ rep.nSizes = 0;
+ rep.sizeID = 0;
+ rep.rotation = RR_Rotate_0;
+ rep.rate = 0;
+ rep.nrateEnts = 0;
+ extra = 0;
+ extraLen = 0;
+ }
+ else
+ {
+ int i, j;
+ xScreenSizes *size;
+ CARD16 *rates;
+ CARD8 *data8;
+ Bool has_rate = RRClientKnowsRates (client);
+
+ RRGetInfo (pScreen);
+
+ rep.type = X_Reply;
+ rep.setOfRotations = pScrPriv->rotations;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
+ rep.timestamp = pScrPriv->lastSetTime.milliseconds;
+ rep.configTimestamp = pScrPriv->lastConfigTime.milliseconds;
+ rep.rotation = pScrPriv->rotation;
+ rep.nSizes = pScrPriv->nSizesInUse;
+ rep.rate = pScrPriv->rate;
+ rep.nrateEnts = 0;
+ if (has_rate)
+ {
+ for (i = 0; i < pScrPriv->nSizes; i++)
+ {
+ RRScreenSizePtr pSize = &pScrPriv->pSizes[i];
+ if (pSize->referenced)
+ {
+ rep.nrateEnts += (1 + pSize->nRatesInUse);
+ }
+ }
+ }
+
+ if (pScrPriv->size >= 0)
+ rep.sizeID = pScrPriv->pSizes[pScrPriv->size].id;
+ else
+ return BadImplementation;
+
+ extraLen = (rep.nSizes * sizeof (xScreenSizes) +
+ rep.nrateEnts * sizeof (CARD16));
+
+ extra = (CARD8 *) xalloc (extraLen);
+ if (!extra)
+ return BadAlloc;
+ /*
+ * First comes the size information
+ */
+ size = (xScreenSizes *) extra;
+ rates = (CARD16 *) (size + rep.nSizes);
+ for (i = 0; i < pScrPriv->nSizes; i++)
+ {
+ RRScreenSizePtr pSize = &pScrPriv->pSizes[i];
+ if (pSize->referenced)
+ {
+ size->widthInPixels = pSize->width;
+ size->heightInPixels = pSize->height;
+ size->widthInMillimeters = pSize->mmWidth;
+ size->heightInMillimeters = pSize->mmHeight;
+ if (client->swapped)
+ {
+ swaps (&size->widthInPixels, n);
+ swaps (&size->heightInPixels, n);
+ swaps (&size->widthInMillimeters, n);
+ swaps (&size->heightInMillimeters, n);
+ }
+ size++;
+ if (has_rate)
+ {
+ *rates = pSize->nRatesInUse;
+ if (client->swapped)
+ {
+ swaps (rates, n);
+ }
+ rates++;
+ for (j = 0; j < pSize->nRates; j++)
+ {
+ RRScreenRatePtr pRate = &pSize->pRates[j];
+ if (pRate->referenced)
+ {
+ *rates = pRate->rate;
+ if (client->swapped)
+ {
+ swaps (rates, n);
+ }
+ rates++;
+ }
+ }
+ }
+ }
+ }
+ data8 = (CARD8 *) rates;
+
+ if (data8 - (CARD8 *) extra != extraLen)
+ FatalError ("RRGetScreenInfo bad extra len %ld != %ld\n",
+ (unsigned long)(data8 - (CARD8 *) extra), extraLen);
+ rep.length = (extraLen + 3) >> 2;
+ }
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.timestamp, n);
+ swaps(&rep.rotation, n);
+ swaps(&rep.nSizes, n);
+ swaps(&rep.sizeID, n);
+ swaps(&rep.rate, n);
+ swaps(&rep.nrateEnts, n);
+ }
+ WriteToClient(client, sizeof(xRRGetScreenInfoReply), (char *)&rep);
+ if (extraLen)
+ {
+ WriteToClient (client, extraLen, (char *) extra);
+ xfree (extra);
+ }
+ return (client->noClientException);
+}
+
+static int
+ProcRRSetScreenConfig (ClientPtr client)
+{
+ REQUEST(xRRSetScreenConfigReq);
+ xRRSetScreenConfigReply rep;
+ DrawablePtr pDraw;
+ int n;
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+ TimeStamp configTime;
+ TimeStamp time;
+ RRScreenSizePtr pSize;
+ int i;
+ Rotation rotation;
+ int rate;
+ short oldWidth, oldHeight;
+ Bool has_rate;
+
+ UpdateCurrentTime ();
+
+ if (RRClientKnowsRates (client))
+ {
+ REQUEST_SIZE_MATCH (xRRSetScreenConfigReq);
+ has_rate = TRUE;
+ }
+ else
+ {
+ REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq);
+ has_rate = FALSE;
+ }
+
+ SECURITY_VERIFY_DRAWABLE(pDraw, stuff->drawable, client,
+ SecurityWriteAccess);
+
+ pScreen = pDraw->pScreen;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ time = ClientTimeToServerTime(stuff->timestamp);
+ configTime = ClientTimeToServerTime(stuff->configTimestamp);
+
+ oldWidth = pScreen->width;
+ oldHeight = pScreen->height;
+
+ if (!pScrPriv)
+ {
+ time = currentTime;
+ rep.status = RRSetConfigFailed;
+ goto sendReply;
+ }
+ if (!RRGetInfo (pScreen))
+ return BadAlloc;
+
+ /*
+ * if the client's config timestamp is not the same as the last config
+ * timestamp, then the config information isn't up-to-date and
+ * can't even be validated
+ */
+ if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0)
+ {
+ rep.status = RRSetConfigInvalidConfigTime;
+ goto sendReply;
+ }
+
+ /*
+ * Search for the requested size
+ */
+ pSize = 0;
+ for (i = 0; i < pScrPriv->nSizes; i++)
+ {
+ pSize = &pScrPriv->pSizes[i];
+ if (pSize->referenced && pSize->id == stuff->sizeID)
+ {
+ break;
+ }
+ }
+ if (i == pScrPriv->nSizes)
+ {
+ /*
+ * Invalid size ID
+ */
+ client->errorValue = stuff->sizeID;
+ return BadValue;
+ }
+
+ /*
+ * Validate requested rotation
+ */
+ rotation = (Rotation) stuff->rotation;
+
+ /* test the rotation bits only! */
+ switch (rotation & 0xf) {
+ case RR_Rotate_0:
+ case RR_Rotate_90:
+ case RR_Rotate_180:
+ case RR_Rotate_270:
+ break;
+ default:
+ /*
+ * Invalid rotation
+ */
+ client->errorValue = stuff->rotation;
+ return BadValue;
+ }
+
+ if ((~pScrPriv->rotations) & rotation)
+ {
+ /*
+ * requested rotation or reflection not supported by screen
+ */
+ client->errorValue = stuff->rotation;
+ return BadMatch;
+ }
+
+ /*
+ * Validate requested refresh
+ */
+ if (has_rate)
+ rate = (int) stuff->rate;
+ else
+ rate = 0;
+
+ if (rate)
+ {
+ for (i = 0; i < pSize->nRates; i++)
+ {
+ RRScreenRatePtr pRate = &pSize->pRates[i];
+ if (pRate->referenced && pRate->rate == rate)
+ break;
+ }
+ if (i == pSize->nRates)
+ {
+ /*
+ * Invalid rate
+ */
+ client->errorValue = rate;
+ return BadValue;
+ }
+ }
+
+ /*
+ * Make sure the requested set-time is not older than
+ * the last set-time
+ */
+ if (CompareTimeStamps (time, pScrPriv->lastSetTime) < 0)
+ {
+ rep.status = RRSetConfigInvalidTime;
+ goto sendReply;
+ }
+
+ /*
+ * call out to ddx routine to effect the change
+ */
+ if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate,
+ pSize))
+ {
+ /*
+ * unknown DDX failure, report to client
+ */
+ rep.status = RRSetConfigFailed;
+ goto sendReply;
+ }
+
+ /*
+ * set current extension configuration pointers
+ */
+ RRSetCurrentConfig (pScreen, rotation, rate, pSize);
+
+ /*
+ * Deliver ScreenChangeNotify events whenever
+ * the configuration is updated
+ */
+ WalkTree (pScreen, TellChanged, (pointer) pScreen);
+
+ /*
+ * Deliver ConfigureNotify events when root changes
+ * pixel size
+ */
+ if (oldWidth != pScreen->width || oldHeight != pScreen->height)
+ RRSendConfigNotify (pScreen);
+ RREditConnectionInfo (pScreen);
+
+ /*
+ * Fix pointer bounds and location
+ */
+ ScreenRestructured (pScreen);
+ pScrPriv->lastSetTime = time;
+
+ /*
+ * Report Success
+ */
+ rep.status = RRSetConfigSuccess;
+
+sendReply:
+
+ rep.type = X_Reply;
+ /* rep.status has already been filled in */
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ rep.newTimestamp = pScrPriv->lastSetTime.milliseconds;
+ rep.newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds;
+ rep.root = WindowTable[pDraw->pScreen->myNum]->drawable.id;
+
+ if (client->swapped)
+ {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.newTimestamp, n);
+ swapl(&rep.newConfigTimestamp, n);
+ swapl(&rep.root, n);
+ }
+ WriteToClient(client, sizeof(xRRSetScreenConfigReply), (char *)&rep);
+
+ return (client->noClientException);
+}
+
+int
+RRSetScreenConfig (ScreenPtr pScreen,
+ Rotation rotation,
+ int rate,
+ RRScreenSizePtr pSize)
+{
+ rrScrPrivPtr pScrPriv;
+ int i;
+ short oldWidth, oldHeight;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ oldWidth = pScreen->width;
+ oldHeight = pScreen->height;
+
+ if (!RRGetInfo (pScreen))
+ return BadAlloc;
+
+ /*
+ * Validate requested rotation
+ */
+
+ /* test the rotation bits only! */
+ switch (rotation & 0xf) {
+ case RR_Rotate_0:
+ case RR_Rotate_90:
+ case RR_Rotate_180:
+ case RR_Rotate_270:
+ break;
+ default:
+ /*
+ * Invalid rotation
+ */
+ return BadValue;
+ }
+
+ if ((~pScrPriv->rotations) & rotation)
+ {
+ /*
+ * requested rotation or reflection not supported by screen
+ */
+ return BadMatch;
+ }
+
+ /*
+ * Validate requested refresh
+ */
+ if (rate)
+ {
+ for (i = 0; i < pSize->nRates; i++)
+ {
+ RRScreenRatePtr pRate = &pSize->pRates[i];
+ if (pRate->referenced && pRate->rate == rate)
+ break;
+ }
+ if (i == pSize->nRates)
+ {
+ /*
+ * Invalid rate
+ */
+ return BadValue;
+ }
+ }
+
+ /*
+ * call out to ddx routine to effect the change
+ */
+ if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate,
+ pSize))
+ {
+ /*
+ * unknown DDX failure, report to client
+ */
+ return BadImplementation;
+ }
+
+ /*
+ * set current extension configuration pointers
+ */
+ RRSetCurrentConfig (pScreen, rotation, rate, pSize);
+
+ /*
+ * Deliver ScreenChangeNotify events whenever
+ * the configuration is updated
+ */
+ WalkTree (pScreen, TellChanged, (pointer) pScreen);
+
+ /*
+ * Deliver ConfigureNotify events when root changes
+ * pixel size
+ */
+ if (oldWidth != pScreen->width || oldHeight != pScreen->height)
+ RRSendConfigNotify (pScreen);
+ RREditConnectionInfo (pScreen);
+
+ /*
+ * Fix pointer bounds and location
+ */
+ ScreenRestructured (pScreen);
+
+ return Success;
+}
+
+static int
+ProcRRSelectInput (ClientPtr client)
+{
+ REQUEST(xRRSelectInputReq);
+ rrClientPriv(client);
+ RRTimesPtr pTimes;
+ WindowPtr pWin;
+ RREventPtr pRREvent, pNewRREvent, *pHead;
+ XID clientResource;
+
+ REQUEST_SIZE_MATCH(xRRSelectInputReq);
+ pWin = SecurityLookupWindow (stuff->window, client, SecurityWriteAccess);
+ if (!pWin)
+ return BadWindow;
+ pHead = (RREventPtr *)SecurityLookupIDByType(client,
+ pWin->drawable.id, EventType,
+ SecurityWriteAccess);
+
+ if (stuff->enable & (RRScreenChangeNotifyMask))
+ {
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ rrScrPriv (pScreen);
+
+ if (pHead)
+ {
+ /* check for existing entry. */
+ for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next)
+ if (pRREvent->client == client)
+ return Success;
+ }
+
+ /* build the entry */
+ pNewRREvent = (RREventPtr) xalloc (sizeof (RREventRec));
+ if (!pNewRREvent)
+ return BadAlloc;
+ pNewRREvent->next = 0;
+ pNewRREvent->client = client;
+ pNewRREvent->window = pWin;
+ pNewRREvent->mask = stuff->enable;
+ /*
+ * add a resource that will be deleted when
+ * the client goes away
+ */
+ clientResource = FakeClientID (client->index);
+ pNewRREvent->clientResource = clientResource;
+ if (!AddResource (clientResource, ClientType, (pointer)pNewRREvent))
+ return BadAlloc;
+ /*
+ * create a resource to contain a pointer to the list
+ * of clients selecting input. This must be indirect as
+ * the list may be arbitrarily rearranged which cannot be
+ * done through the resource database.
+ */
+ if (!pHead)
+ {
+ pHead = (RREventPtr *) xalloc (sizeof (RREventPtr));
+ if (!pHead ||
+ !AddResource (pWin->drawable.id, EventType, (pointer)pHead))
+ {
+ FreeResource (clientResource, RT_NONE);
+ return BadAlloc;
+ }
+ *pHead = 0;
+ }
+ pNewRREvent->next = *pHead;
+ *pHead = pNewRREvent;
+ /*
+ * Now see if the client needs an event
+ */
+ if (pScrPriv)
+ {
+ pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum];
+ if (CompareTimeStamps (pTimes->setTime,
+ pScrPriv->lastSetTime) != 0 ||
+ CompareTimeStamps (pTimes->configTime,
+ pScrPriv->lastConfigTime) != 0)
+ {
+ TellChanged (pWin, (pointer) pScreen);
+ }
+ }
+ }
+ else if (stuff->enable == xFalse)
+ {
+ /* delete the interest */
+ if (pHead) {
+ pNewRREvent = 0;
+ for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) {
+ if (pRREvent->client == client)
+ break;
+ pNewRREvent = pRREvent;
+ }
+ if (pRREvent) {
+ FreeResource (pRREvent->clientResource, ClientType);
+ if (pNewRREvent)
+ pNewRREvent->next = pRREvent->next;
+ else
+ *pHead = pRREvent->next;
+ xfree (pRREvent);
+ }
+ }
+ }
+ else
+ {
+ client->errorValue = stuff->enable;
+ return BadValue;
+ }
+ return Success;
+}
+
+
+static int
+ProcRRDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_RRQueryVersion:
+ return ProcRRQueryVersion(client);
+ case X_RRSetScreenConfig:
+ return ProcRRSetScreenConfig(client);
+ case X_RRSelectInput:
+ return ProcRRSelectInput(client);
+ case X_RRGetScreenInfo:
+ return ProcRRGetScreenInfo(client);
+ default:
+ return BadRequest;
+ }
+}
+
+static int
+SProcRRQueryVersion (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRRQueryVersionReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->majorVersion, n);
+ swapl(&stuff->minorVersion, n);
+ return ProcRRQueryVersion(client);
+}
+
+static int
+SProcRRGetScreenInfo (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRRGetScreenInfoReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ return ProcRRGetScreenInfo(client);
+}
+
+static int
+SProcRRSetScreenConfig (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRRSetScreenConfigReq);
+
+ if (RRClientKnowsRates (client))
+ {
+ REQUEST_SIZE_MATCH (xRRSetScreenConfigReq);
+ swaps (&stuff->rate, n);
+ }
+ else
+ {
+ REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq);
+ }
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->drawable, n);
+ swapl(&stuff->timestamp, n);
+ swaps(&stuff->sizeID, n);
+ swaps(&stuff->rotation, n);
+ return ProcRRSetScreenConfig(client);
+}
+
+static int
+SProcRRSelectInput (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRRSelectInputReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ return ProcRRSelectInput(client);
+}
+
+
+static int
+SProcRRDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_RRQueryVersion:
+ return SProcRRQueryVersion(client);
+ case X_RRSetScreenConfig:
+ return SProcRRSetScreenConfig(client);
+ case X_RRSelectInput:
+ return SProcRRSelectInput(client);
+ case X_RRGetScreenInfo:
+ return SProcRRGetScreenInfo(client);
+ default:
+ return BadRequest;
+ }
+}
+
+
+static Bool
+RRScreenSizeMatches (RRScreenSizePtr a,
+ RRScreenSizePtr b)
+{
+ if (a->width != b->width)
+ return FALSE;
+ if (a->height != b->height)
+ return FALSE;
+ if (a->mmWidth != b->mmWidth)
+ return FALSE;
+ if (a->mmHeight != b->mmHeight)
+ return FALSE;
+ return TRUE;
+}
+
+RRScreenSizePtr
+RRRegisterSize (ScreenPtr pScreen,
+ short width,
+ short height,
+ short mmWidth,
+ short mmHeight)
+{
+ rrScrPriv (pScreen);
+ int i;
+ RRScreenSize tmp;
+ RRScreenSizePtr pNew;
+
+ if (!pScrPriv)
+ return 0;
+
+ /*
+ * FIXME: The compiler reports that field
+ * id is used uninitialized here.
+ */
+
+ tmp.id = 0;
+
+ tmp.width = width;
+ tmp.height= height;
+ tmp.mmWidth = mmWidth;
+ tmp.mmHeight = mmHeight;
+ tmp.pRates = 0;
+ tmp.nRates = 0;
+ tmp.nRatesInUse = 0;
+ tmp.referenced = TRUE;
+ tmp.oldReferenced = FALSE;
+ for (i = 0; i < pScrPriv->nSizes; i++)
+ if (RRScreenSizeMatches (&tmp, &pScrPriv->pSizes[i]))
+ {
+ pScrPriv->pSizes[i].referenced = TRUE;
+ return &pScrPriv->pSizes[i];
+ }
+ pNew = xrealloc (pScrPriv->pSizes,
+ (pScrPriv->nSizes + 1) * sizeof (RRScreenSize));
+ if (!pNew)
+ return 0;
+ pNew[pScrPriv->nSizes++] = tmp;
+ pScrPriv->pSizes = pNew;
+ return &pNew[pScrPriv->nSizes-1];
+}
+
+Bool RRRegisterRate (ScreenPtr pScreen,
+ RRScreenSizePtr pSize,
+ int rate)
+{
+ rrScrPriv(pScreen);
+ int i;
+ RRScreenRatePtr pNew, pRate;
+
+ if (!pScrPriv)
+ return FALSE;
+
+ for (i = 0; i < pSize->nRates; i++)
+ {
+ pRate = &pSize->pRates[i];
+ if (pRate->rate == rate)
+ {
+ pRate->referenced = TRUE;
+ return TRUE;
+ }
+ }
+
+ pNew = xrealloc (pSize->pRates,
+ (pSize->nRates + 1) * sizeof (RRScreenRate));
+ if (!pNew)
+ return FALSE;
+ pRate = &pNew[pSize->nRates++];
+ pRate->rate = rate;
+ pRate->referenced = TRUE;
+ pRate->oldReferenced = FALSE;
+ pSize->pRates = pNew;
+ return TRUE;
+}
+
+void
+RRSetCurrentConfig (ScreenPtr pScreen,
+ Rotation rotation,
+ int rate,
+ RRScreenSizePtr pSize)
+{
+ rrScrPriv (pScreen);
+
+ if (!pScrPriv)
+ return;
+
+ pScrPriv->rotation = rotation;
+ pScrPriv->size = pSize - pScrPriv->pSizes;
+ pScrPriv->rate = rate;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.X.original
new file mode 100644
index 000000000..3911a3498
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.X.original
@@ -0,0 +1,1319 @@
+/*
+ * $XFree86: xc/programs/Xserver/randr/randr.c,v 1.21tsi Exp $
+ *
+ * Copyright © 2000, Compaq Computer Corporation,
+ * Copyright © 2002, Hewlett Packard, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Compaq or HP not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. HP makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * HP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL HP
+ * 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.
+ *
+ * Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc.
+ */
+
+
+#define NEED_REPLIES
+#define NEED_EVENTS
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#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 "extnsionst.h"
+#include "servermd.h"
+#include <X11/extensions/randr.h>
+#include <X11/extensions/randrproto.h>
+#include "randrstr.h"
+#ifdef RENDER
+#include <X11/extensions/render.h> /* we share subpixel order information */
+#include "picturestr.h"
+#endif
+#include <X11/Xfuncproto.h>
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#endif
+
+/* From render.h */
+#ifndef SubPixelUnknown
+#define SubPixelUnknown 0
+#endif
+
+#define RR_VALIDATE
+int RRGeneration;
+int RRNScreens;
+
+static int ProcRRQueryVersion (ClientPtr pClient);
+static int ProcRRDispatch (ClientPtr pClient);
+static int SProcRRDispatch (ClientPtr pClient);
+static int SProcRRQueryVersion (ClientPtr pClient);
+
+#define wrap(priv,real,mem,func) {\
+ priv->mem = real->mem; \
+ real->mem = func; \
+}
+
+#define unwrap(priv,real,mem) {\
+ real->mem = priv->mem; \
+}
+
+#if 0
+static CARD8 RRReqCode;
+static int RRErrBase;
+#endif
+static int RREventBase;
+static RESTYPE ClientType, EventType; /* resource types for event masks */
+static int RRClientPrivateIndex;
+
+typedef struct _RRTimes {
+ TimeStamp setTime;
+ TimeStamp configTime;
+} RRTimesRec, *RRTimesPtr;
+
+typedef struct _RRClient {
+ int major_version;
+ int minor_version;
+/* RRTimesRec times[0]; */
+} RRClientRec, *RRClientPtr;
+
+/*
+ * each window has a list of clients requesting
+ * RRNotify events. Each client has a resource
+ * for each window it selects RRNotify input for,
+ * this resource is used to delete the RRNotifyRec
+ * entry from the per-window queue.
+ */
+
+typedef struct _RREvent *RREventPtr;
+
+typedef struct _RREvent {
+ RREventPtr next;
+ ClientPtr client;
+ WindowPtr window;
+ XID clientResource;
+ int mask;
+} RREventRec;
+
+int rrPrivIndex = -1;
+
+#define GetRRClient(pClient) ((RRClientPtr) (pClient)->devPrivates[RRClientPrivateIndex].ptr)
+#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient)
+
+static Bool
+RRClientKnowsRates (ClientPtr pClient)
+{
+ rrClientPriv(pClient);
+
+ return (pRRClient->major_version > 1 ||
+ (pRRClient->major_version == 1 && pRRClient->minor_version >= 1));
+}
+
+static void
+RRClientCallback (CallbackListPtr *list,
+ pointer closure,
+ pointer data)
+{
+ NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
+ ClientPtr pClient = clientinfo->client;
+ rrClientPriv(pClient);
+ RRTimesPtr pTimes = (RRTimesPtr) (pRRClient + 1);
+ int i;
+
+ pRRClient->major_version = 0;
+ pRRClient->minor_version = 0;
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ ScreenPtr pScreen = screenInfo.screens[i];
+ rrScrPriv(pScreen);
+
+ if (pScrPriv)
+ {
+ pTimes[i].setTime = pScrPriv->lastSetTime;
+ pTimes[i].configTime = pScrPriv->lastConfigTime;
+ }
+ }
+}
+
+static void
+RRResetProc (ExtensionEntry *extEntry)
+{
+}
+
+static Bool
+RRCloseScreen (int i, ScreenPtr pScreen)
+{
+ rrScrPriv(pScreen);
+
+ unwrap (pScrPriv, pScreen, CloseScreen);
+ if (pScrPriv->pSizes)
+ xfree (pScrPriv->pSizes);
+ xfree (pScrPriv);
+ RRNScreens -= 1; /* ok, one fewer screen with RandR running */
+ return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+static void
+SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent *from,
+ xRRScreenChangeNotifyEvent *to)
+{
+ to->type = from->type;
+ to->rotation = from->rotation;
+ cpswaps(from->sequenceNumber, to->sequenceNumber);
+ cpswapl(from->timestamp, to->timestamp);
+ cpswapl(from->configTimestamp, to->configTimestamp);
+ cpswapl(from->root, to->root);
+ cpswapl(from->window, to->window);
+ cpswaps(from->sizeID, to->sizeID);
+ cpswaps(from->widthInPixels, to->widthInPixels);
+ cpswaps(from->heightInPixels, to->heightInPixels);
+ cpswaps(from->widthInMillimeters, to->widthInMillimeters);
+ cpswaps(from->heightInMillimeters, to->heightInMillimeters);
+ cpswaps(from->subpixelOrder, to->subpixelOrder);
+}
+
+Bool RRScreenInit(ScreenPtr pScreen)
+{
+ rrScrPrivPtr pScrPriv;
+
+ if (RRGeneration != serverGeneration)
+ {
+ if ((rrPrivIndex = AllocateScreenPrivateIndex()) < 0)
+ return FALSE;
+ RRGeneration = serverGeneration;
+ }
+
+ pScrPriv = (rrScrPrivPtr) xalloc (sizeof (rrScrPrivRec));
+ if (!pScrPriv)
+ return FALSE;
+
+ SetRRScreen(pScreen, pScrPriv);
+
+ /*
+ * Calling function best set these function vectors
+ */
+ pScrPriv->rrSetConfig = 0;
+ pScrPriv->rrGetInfo = 0;
+ /*
+ * This value doesn't really matter -- any client must call
+ * GetScreenInfo before reading it which will automatically update
+ * the time
+ */
+ pScrPriv->lastSetTime = currentTime;
+ pScrPriv->lastConfigTime = currentTime;
+
+ wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen);
+
+ pScrPriv->rotations = RR_Rotate_0;
+
+ pScrPriv->nSizes = 0;
+ pScrPriv->nSizesInUse = 0;
+ pScrPriv->pSizes = 0;
+
+ pScrPriv->rotation = RR_Rotate_0;
+ pScrPriv->size = -1;
+
+ RRNScreens += 1; /* keep count of screens that implement randr */
+ return TRUE;
+}
+
+/*ARGSUSED*/
+static int
+RRFreeClient (pointer data, XID id)
+{
+ RREventPtr pRREvent;
+ WindowPtr pWin;
+ RREventPtr *pHead, pCur, pPrev;
+
+ pRREvent = (RREventPtr) data;
+ pWin = pRREvent->window;
+ pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, EventType);
+ if (pHead) {
+ pPrev = 0;
+ for (pCur = *pHead; pCur && pCur != pRREvent; pCur=pCur->next)
+ pPrev = pCur;
+ if (pCur)
+ {
+ if (pPrev)
+ pPrev->next = pRREvent->next;
+ else
+ *pHead = pRREvent->next;
+ }
+ }
+ xfree ((pointer) pRREvent);
+ return 1;
+}
+
+/*ARGSUSED*/
+static int
+RRFreeEvents (pointer data, XID id)
+{
+ RREventPtr *pHead, pCur, pNext;
+
+ pHead = (RREventPtr *) data;
+ for (pCur = *pHead; pCur; pCur = pNext) {
+ pNext = pCur->next;
+ FreeResource (pCur->clientResource, ClientType);
+ xfree ((pointer) pCur);
+ }
+ xfree ((pointer) pHead);
+ return 1;
+}
+
+void
+RRExtensionInit (void)
+{
+ ExtensionEntry *extEntry;
+
+ if (RRNScreens == 0) return;
+
+ RRClientPrivateIndex = AllocateClientPrivateIndex ();
+ if (!AllocateClientPrivate (RRClientPrivateIndex,
+ sizeof (RRClientRec) +
+ screenInfo.numScreens * sizeof (RRTimesRec)))
+ return;
+ if (!AddCallback (&ClientStateCallback, RRClientCallback, 0))
+ return;
+
+ ClientType = CreateNewResourceType(RRFreeClient);
+ if (!ClientType)
+ return;
+ EventType = CreateNewResourceType(RRFreeEvents);
+ if (!EventType)
+ return;
+ extEntry = AddExtension (RANDR_NAME, RRNumberEvents, RRNumberErrors,
+ ProcRRDispatch, SProcRRDispatch,
+ RRResetProc, StandardMinorOpcode);
+ if (!extEntry)
+ return;
+#if 0
+ RRReqCode = (CARD8) extEntry->base;
+ RRErrBase = extEntry->errorBase;
+#endif
+ RREventBase = extEntry->eventBase;
+ EventSwapVector[RREventBase + RRScreenChangeNotify] = (EventSwapPtr)
+ SRRScreenChangeNotifyEvent;
+
+ return;
+}
+
+static int
+TellChanged (WindowPtr pWin, pointer value)
+{
+ RREventPtr *pHead, pRREvent;
+ ClientPtr client;
+ xRRScreenChangeNotifyEvent se;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ rrScrPriv(pScreen);
+ RRScreenSizePtr pSize;
+ WindowPtr pRoot = WindowTable[pScreen->myNum];
+
+ pHead = (RREventPtr *) LookupIDByType (pWin->drawable.id, EventType);
+ if (!pHead)
+ return WT_WALKCHILDREN;
+
+ se.type = RRScreenChangeNotify + RREventBase;
+ se.rotation = (CARD8) pScrPriv->rotation;
+ se.timestamp = pScrPriv->lastSetTime.milliseconds;
+ se.configTimestamp = pScrPriv->lastConfigTime.milliseconds;
+ se.root = pRoot->drawable.id;
+ se.window = pWin->drawable.id;
+#ifdef RENDER
+ se.subpixelOrder = PictureGetSubpixelOrder (pScreen);
+#else
+ se.subpixelOrder = SubPixelUnknown;
+#endif
+ if (pScrPriv->size >= 0)
+ {
+ pSize = &pScrPriv->pSizes[pScrPriv->size];
+ se.sizeID = pSize->id;
+ se.widthInPixels = pSize->width;
+ se.heightInPixels = pSize->height;
+ se.widthInMillimeters = pSize->mmWidth;
+ se.heightInMillimeters = pSize->mmHeight;
+ }
+ else
+ {
+ /*
+ * This "shouldn't happen", but a broken DDX can
+ * forget to set the current configuration on GetInfo
+ */
+ se.sizeID = 0xffff;
+ se.widthInPixels = 0;
+ se.heightInPixels = 0;
+ se.widthInMillimeters = 0;
+ se.heightInMillimeters = 0;
+ }
+ for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next)
+ {
+ client = pRREvent->client;
+ if (client == serverClient || client->clientGone)
+ continue;
+ se.sequenceNumber = client->sequence;
+ if(pRREvent->mask & RRScreenChangeNotifyMask)
+ WriteEventsToClient (client, 1, (xEvent *) &se);
+ }
+ return WT_WALKCHILDREN;
+}
+
+static Bool
+RRGetInfo (ScreenPtr pScreen)
+{
+ rrScrPriv (pScreen);
+ int i, j, k, l;
+ Bool changed;
+ Rotation rotations;
+ RRScreenSizePtr pSize;
+ RRScreenRatePtr pRate;
+
+ for (i = 0; i < pScrPriv->nSizes; i++)
+ {
+ pSize = &pScrPriv->pSizes[i];
+ pSize->oldReferenced = pSize->referenced;
+ pSize->referenced = FALSE;
+ for (k = 0; k < pSize->nRates; k++)
+ {
+ pRate = &pSize->pRates[k];
+ pRate->oldReferenced = pRate->referenced;
+ pRate->referenced = FALSE;
+ }
+ }
+ if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations))
+ return FALSE;
+
+ changed = FALSE;
+
+ /*
+ * Check whether anything changed and simultaneously generate
+ * the protocol id values for the objects
+ */
+ if (rotations != pScrPriv->rotations)
+ {
+ pScrPriv->rotations = rotations;
+ changed = TRUE;
+ }
+
+ j = 0;
+ for (i = 0; i < pScrPriv->nSizes; i++)
+ {
+ pSize = &pScrPriv->pSizes[i];
+ if (pSize->oldReferenced != pSize->referenced)
+ changed = TRUE;
+ if (pSize->referenced)
+ pSize->id = j++;
+ l = 0;
+ for (k = 0; k < pSize->nRates; k++)
+ {
+ pRate = &pSize->pRates[k];
+ if (pRate->oldReferenced != pRate->referenced)
+ changed = TRUE;
+ if (pRate->referenced)
+ l++;
+ }
+ pSize->nRatesInUse = l;
+ }
+ pScrPriv->nSizesInUse = j;
+ if (changed)
+ {
+ UpdateCurrentTime ();
+ pScrPriv->lastConfigTime = currentTime;
+ WalkTree (pScreen, TellChanged, (pointer) pScreen);
+ }
+ return TRUE;
+}
+
+static void
+RRSendConfigNotify (ScreenPtr pScreen)
+{
+ WindowPtr pWin = WindowTable[pScreen->myNum];
+ xEvent event;
+
+ event.u.u.type = ConfigureNotify;
+ event.u.configureNotify.window = pWin->drawable.id;
+ event.u.configureNotify.aboveSibling = None;
+ event.u.configureNotify.x = 0;
+ event.u.configureNotify.y = 0;
+
+ /* XXX xinerama stuff ? */
+
+ event.u.configureNotify.width = pWin->drawable.width;
+ event.u.configureNotify.height = pWin->drawable.height;
+ event.u.configureNotify.borderWidth = wBorderWidth (pWin);
+ event.u.configureNotify.override = pWin->overrideRedirect;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+}
+
+static int
+ProcRRQueryVersion (ClientPtr client)
+{
+ xRRQueryVersionReply rep;
+ register int n;
+ REQUEST(xRRQueryVersionReq);
+ rrClientPriv(client);
+
+ REQUEST_SIZE_MATCH(xRRQueryVersionReq);
+ pRRClient->major_version = stuff->majorVersion;
+ pRRClient->minor_version = stuff->minorVersion;
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = RANDR_MAJOR;
+ rep.minorVersion = RANDR_MINOR;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.majorVersion, n);
+ swapl(&rep.minorVersion, n);
+ }
+ WriteToClient(client, sizeof(xRRQueryVersionReply), (char *)&rep);
+ return (client->noClientException);
+}
+
+
+extern char *ConnectionInfo;
+
+static int padlength[4] = {0, 3, 2, 1};
+
+static void
+RREditConnectionInfo (ScreenPtr pScreen)
+{
+ xConnSetup *connSetup;
+ char *vendor;
+ xPixmapFormat *formats;
+ xWindowRoot *root;
+ xDepth *depth;
+ xVisualType *visual;
+ int screen = 0;
+ int d;
+
+ connSetup = (xConnSetup *) ConnectionInfo;
+ vendor = (char *) connSetup + sizeof (xConnSetup);
+ formats = (xPixmapFormat *) ((char *) vendor +
+ connSetup->nbytesVendor +
+ padlength[connSetup->nbytesVendor & 3]);
+ root = (xWindowRoot *) ((char *) formats +
+ sizeof (xPixmapFormat) * screenInfo.numPixmapFormats);
+ while (screen != pScreen->myNum)
+ {
+ depth = (xDepth *) ((char *) root +
+ sizeof (xWindowRoot));
+ for (d = 0; d < root->nDepths; d++)
+ {
+ visual = (xVisualType *) ((char *) depth +
+ sizeof (xDepth));
+ depth = (xDepth *) ((char *) visual +
+ depth->nVisuals * sizeof (xVisualType));
+ }
+ root = (xWindowRoot *) ((char *) depth);
+ screen++;
+ }
+ root->pixWidth = pScreen->width;
+ root->pixHeight = pScreen->height;
+ root->mmWidth = pScreen->mmWidth;
+ root->mmHeight = pScreen->mmHeight;
+}
+
+static int
+ProcRRGetScreenInfo (ClientPtr client)
+{
+ REQUEST(xRRGetScreenInfoReq);
+ xRRGetScreenInfoReply rep;
+ WindowPtr pWin;
+ int n;
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+ CARD8 *extra;
+ unsigned long extraLen;
+
+ REQUEST_SIZE_MATCH(xRRGetScreenInfoReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityReadAccess);
+
+ if (!pWin)
+ return BadWindow;
+
+ pScreen = pWin->drawable.pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+ rep.pad = 0;
+ if (!pScrPriv)
+ {
+ rep.type = X_Reply;
+ rep.setOfRotations = RR_Rotate_0;;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
+ rep.timestamp = currentTime.milliseconds;
+ rep.configTimestamp = currentTime.milliseconds;
+ rep.nSizes = 0;
+ rep.sizeID = 0;
+ rep.rotation = RR_Rotate_0;
+ rep.rate = 0;
+ rep.nrateEnts = 0;
+ extra = 0;
+ extraLen = 0;
+ }
+ else
+ {
+ int i, j;
+ xScreenSizes *size;
+ CARD16 *rates;
+ CARD8 *data8;
+ Bool has_rate = RRClientKnowsRates (client);
+
+ RRGetInfo (pScreen);
+
+ rep.type = X_Reply;
+ rep.setOfRotations = pScrPriv->rotations;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
+ rep.timestamp = pScrPriv->lastSetTime.milliseconds;
+ rep.configTimestamp = pScrPriv->lastConfigTime.milliseconds;
+ rep.rotation = pScrPriv->rotation;
+ rep.nSizes = pScrPriv->nSizesInUse;
+ rep.rate = pScrPriv->rate;
+ rep.nrateEnts = 0;
+ if (has_rate)
+ {
+ for (i = 0; i < pScrPriv->nSizes; i++)
+ {
+ RRScreenSizePtr pSize = &pScrPriv->pSizes[i];
+ if (pSize->referenced)
+ {
+ rep.nrateEnts += (1 + pSize->nRatesInUse);
+ }
+ }
+ }
+
+ if (pScrPriv->size >= 0)
+ rep.sizeID = pScrPriv->pSizes[pScrPriv->size].id;
+ else
+ return BadImplementation;
+
+ extraLen = (rep.nSizes * sizeof (xScreenSizes) +
+ rep.nrateEnts * sizeof (CARD16));
+
+ extra = (CARD8 *) xalloc (extraLen);
+ if (!extra)
+ return BadAlloc;
+ /*
+ * First comes the size information
+ */
+ size = (xScreenSizes *) extra;
+ rates = (CARD16 *) (size + rep.nSizes);
+ for (i = 0; i < pScrPriv->nSizes; i++)
+ {
+ RRScreenSizePtr pSize = &pScrPriv->pSizes[i];
+ if (pSize->referenced)
+ {
+ size->widthInPixels = pSize->width;
+ size->heightInPixels = pSize->height;
+ size->widthInMillimeters = pSize->mmWidth;
+ size->heightInMillimeters = pSize->mmHeight;
+ if (client->swapped)
+ {
+ swaps (&size->widthInPixels, n);
+ swaps (&size->heightInPixels, n);
+ swaps (&size->widthInMillimeters, n);
+ swaps (&size->heightInMillimeters, n);
+ }
+ size++;
+ if (has_rate)
+ {
+ *rates = pSize->nRatesInUse;
+ if (client->swapped)
+ {
+ swaps (rates, n);
+ }
+ rates++;
+ for (j = 0; j < pSize->nRates; j++)
+ {
+ RRScreenRatePtr pRate = &pSize->pRates[j];
+ if (pRate->referenced)
+ {
+ *rates = pRate->rate;
+ if (client->swapped)
+ {
+ swaps (rates, n);
+ }
+ rates++;
+ }
+ }
+ }
+ }
+ }
+ data8 = (CARD8 *) rates;
+
+ if (data8 - (CARD8 *) extra != extraLen)
+ FatalError ("RRGetScreenInfo bad extra len %ld != %ld\n",
+ (unsigned long)(data8 - (CARD8 *) extra), extraLen);
+ rep.length = (extraLen + 3) >> 2;
+ }
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.timestamp, n);
+ swaps(&rep.rotation, n);
+ swaps(&rep.nSizes, n);
+ swaps(&rep.sizeID, n);
+ swaps(&rep.rate, n);
+ swaps(&rep.nrateEnts, n);
+ }
+ WriteToClient(client, sizeof(xRRGetScreenInfoReply), (char *)&rep);
+ if (extraLen)
+ {
+ WriteToClient (client, extraLen, (char *) extra);
+ xfree (extra);
+ }
+ return (client->noClientException);
+}
+
+static int
+ProcRRSetScreenConfig (ClientPtr client)
+{
+ REQUEST(xRRSetScreenConfigReq);
+ xRRSetScreenConfigReply rep;
+ DrawablePtr pDraw;
+ int n;
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+ TimeStamp configTime;
+ TimeStamp time;
+ RRScreenSizePtr pSize;
+ int i;
+ Rotation rotation;
+ int rate;
+ short oldWidth, oldHeight;
+ Bool has_rate;
+
+ UpdateCurrentTime ();
+
+ if (RRClientKnowsRates (client))
+ {
+ REQUEST_SIZE_MATCH (xRRSetScreenConfigReq);
+ has_rate = TRUE;
+ }
+ else
+ {
+ REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq);
+ has_rate = FALSE;
+ }
+
+ SECURITY_VERIFY_DRAWABLE(pDraw, stuff->drawable, client,
+ SecurityWriteAccess);
+
+ pScreen = pDraw->pScreen;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ time = ClientTimeToServerTime(stuff->timestamp);
+ configTime = ClientTimeToServerTime(stuff->configTimestamp);
+
+ oldWidth = pScreen->width;
+ oldHeight = pScreen->height;
+
+ if (!pScrPriv)
+ {
+ time = currentTime;
+ rep.status = RRSetConfigFailed;
+ goto sendReply;
+ }
+ if (!RRGetInfo (pScreen))
+ return BadAlloc;
+
+ /*
+ * if the client's config timestamp is not the same as the last config
+ * timestamp, then the config information isn't up-to-date and
+ * can't even be validated
+ */
+ if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0)
+ {
+ rep.status = RRSetConfigInvalidConfigTime;
+ goto sendReply;
+ }
+
+ /*
+ * Search for the requested size
+ */
+ pSize = 0;
+ for (i = 0; i < pScrPriv->nSizes; i++)
+ {
+ pSize = &pScrPriv->pSizes[i];
+ if (pSize->referenced && pSize->id == stuff->sizeID)
+ {
+ break;
+ }
+ }
+ if (i == pScrPriv->nSizes)
+ {
+ /*
+ * Invalid size ID
+ */
+ client->errorValue = stuff->sizeID;
+ return BadValue;
+ }
+
+ /*
+ * Validate requested rotation
+ */
+ rotation = (Rotation) stuff->rotation;
+
+ /* test the rotation bits only! */
+ switch (rotation & 0xf) {
+ case RR_Rotate_0:
+ case RR_Rotate_90:
+ case RR_Rotate_180:
+ case RR_Rotate_270:
+ break;
+ default:
+ /*
+ * Invalid rotation
+ */
+ client->errorValue = stuff->rotation;
+ return BadValue;
+ }
+
+ if ((~pScrPriv->rotations) & rotation)
+ {
+ /*
+ * requested rotation or reflection not supported by screen
+ */
+ client->errorValue = stuff->rotation;
+ return BadMatch;
+ }
+
+ /*
+ * Validate requested refresh
+ */
+ if (has_rate)
+ rate = (int) stuff->rate;
+ else
+ rate = 0;
+
+ if (rate)
+ {
+ for (i = 0; i < pSize->nRates; i++)
+ {
+ RRScreenRatePtr pRate = &pSize->pRates[i];
+ if (pRate->referenced && pRate->rate == rate)
+ break;
+ }
+ if (i == pSize->nRates)
+ {
+ /*
+ * Invalid rate
+ */
+ client->errorValue = rate;
+ return BadValue;
+ }
+ }
+
+ /*
+ * Make sure the requested set-time is not older than
+ * the last set-time
+ */
+ if (CompareTimeStamps (time, pScrPriv->lastSetTime) < 0)
+ {
+ rep.status = RRSetConfigInvalidTime;
+ goto sendReply;
+ }
+
+ /*
+ * call out to ddx routine to effect the change
+ */
+ if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate,
+ pSize))
+ {
+ /*
+ * unknown DDX failure, report to client
+ */
+ rep.status = RRSetConfigFailed;
+ goto sendReply;
+ }
+
+ /*
+ * set current extension configuration pointers
+ */
+ RRSetCurrentConfig (pScreen, rotation, rate, pSize);
+
+ /*
+ * Deliver ScreenChangeNotify events whenever
+ * the configuration is updated
+ */
+ WalkTree (pScreen, TellChanged, (pointer) pScreen);
+
+ /*
+ * Deliver ConfigureNotify events when root changes
+ * pixel size
+ */
+ if (oldWidth != pScreen->width || oldHeight != pScreen->height)
+ RRSendConfigNotify (pScreen);
+ RREditConnectionInfo (pScreen);
+
+ /*
+ * Fix pointer bounds and location
+ */
+ ScreenRestructured (pScreen);
+ pScrPriv->lastSetTime = time;
+
+ /*
+ * Report Success
+ */
+ rep.status = RRSetConfigSuccess;
+
+sendReply:
+
+ rep.type = X_Reply;
+ /* rep.status has already been filled in */
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ rep.newTimestamp = pScrPriv->lastSetTime.milliseconds;
+ rep.newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds;
+ rep.root = WindowTable[pDraw->pScreen->myNum]->drawable.id;
+
+ if (client->swapped)
+ {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.newTimestamp, n);
+ swapl(&rep.newConfigTimestamp, n);
+ swapl(&rep.root, n);
+ }
+ WriteToClient(client, sizeof(xRRSetScreenConfigReply), (char *)&rep);
+
+ return (client->noClientException);
+}
+
+int
+RRSetScreenConfig (ScreenPtr pScreen,
+ Rotation rotation,
+ int rate,
+ RRScreenSizePtr pSize)
+{
+ rrScrPrivPtr pScrPriv;
+ int i;
+ short oldWidth, oldHeight;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ oldWidth = pScreen->width;
+ oldHeight = pScreen->height;
+
+ if (!RRGetInfo (pScreen))
+ return BadAlloc;
+
+ /*
+ * Validate requested rotation
+ */
+
+ /* test the rotation bits only! */
+ switch (rotation & 0xf) {
+ case RR_Rotate_0:
+ case RR_Rotate_90:
+ case RR_Rotate_180:
+ case RR_Rotate_270:
+ break;
+ default:
+ /*
+ * Invalid rotation
+ */
+ return BadValue;
+ }
+
+ if ((~pScrPriv->rotations) & rotation)
+ {
+ /*
+ * requested rotation or reflection not supported by screen
+ */
+ return BadMatch;
+ }
+
+ /*
+ * Validate requested refresh
+ */
+ if (rate)
+ {
+ for (i = 0; i < pSize->nRates; i++)
+ {
+ RRScreenRatePtr pRate = &pSize->pRates[i];
+ if (pRate->referenced && pRate->rate == rate)
+ break;
+ }
+ if (i == pSize->nRates)
+ {
+ /*
+ * Invalid rate
+ */
+ return BadValue;
+ }
+ }
+
+ /*
+ * call out to ddx routine to effect the change
+ */
+ if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate,
+ pSize))
+ {
+ /*
+ * unknown DDX failure, report to client
+ */
+ return BadImplementation;
+ }
+
+ /*
+ * set current extension configuration pointers
+ */
+ RRSetCurrentConfig (pScreen, rotation, rate, pSize);
+
+ /*
+ * Deliver ScreenChangeNotify events whenever
+ * the configuration is updated
+ */
+ WalkTree (pScreen, TellChanged, (pointer) pScreen);
+
+ /*
+ * Deliver ConfigureNotify events when root changes
+ * pixel size
+ */
+ if (oldWidth != pScreen->width || oldHeight != pScreen->height)
+ RRSendConfigNotify (pScreen);
+ RREditConnectionInfo (pScreen);
+
+ /*
+ * Fix pointer bounds and location
+ */
+ ScreenRestructured (pScreen);
+
+ return Success;
+}
+
+static int
+ProcRRSelectInput (ClientPtr client)
+{
+ REQUEST(xRRSelectInputReq);
+ rrClientPriv(client);
+ RRTimesPtr pTimes;
+ WindowPtr pWin;
+ RREventPtr pRREvent, pNewRREvent, *pHead;
+ XID clientResource;
+
+ REQUEST_SIZE_MATCH(xRRSelectInputReq);
+ pWin = SecurityLookupWindow (stuff->window, client, SecurityWriteAccess);
+ if (!pWin)
+ return BadWindow;
+ pHead = (RREventPtr *)SecurityLookupIDByType(client,
+ pWin->drawable.id, EventType,
+ SecurityWriteAccess);
+
+ if (stuff->enable & (RRScreenChangeNotifyMask))
+ {
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ rrScrPriv (pScreen);
+
+ if (pHead)
+ {
+ /* check for existing entry. */
+ for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next)
+ if (pRREvent->client == client)
+ return Success;
+ }
+
+ /* build the entry */
+ pNewRREvent = (RREventPtr) xalloc (sizeof (RREventRec));
+ if (!pNewRREvent)
+ return BadAlloc;
+ pNewRREvent->next = 0;
+ pNewRREvent->client = client;
+ pNewRREvent->window = pWin;
+ pNewRREvent->mask = stuff->enable;
+ /*
+ * add a resource that will be deleted when
+ * the client goes away
+ */
+ clientResource = FakeClientID (client->index);
+ pNewRREvent->clientResource = clientResource;
+ if (!AddResource (clientResource, ClientType, (pointer)pNewRREvent))
+ return BadAlloc;
+ /*
+ * create a resource to contain a pointer to the list
+ * of clients selecting input. This must be indirect as
+ * the list may be arbitrarily rearranged which cannot be
+ * done through the resource database.
+ */
+ if (!pHead)
+ {
+ pHead = (RREventPtr *) xalloc (sizeof (RREventPtr));
+ if (!pHead ||
+ !AddResource (pWin->drawable.id, EventType, (pointer)pHead))
+ {
+ FreeResource (clientResource, RT_NONE);
+ return BadAlloc;
+ }
+ *pHead = 0;
+ }
+ pNewRREvent->next = *pHead;
+ *pHead = pNewRREvent;
+ /*
+ * Now see if the client needs an event
+ */
+ if (pScrPriv)
+ {
+ pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum];
+ if (CompareTimeStamps (pTimes->setTime,
+ pScrPriv->lastSetTime) != 0 ||
+ CompareTimeStamps (pTimes->configTime,
+ pScrPriv->lastConfigTime) != 0)
+ {
+ TellChanged (pWin, (pointer) pScreen);
+ }
+ }
+ }
+ else if (stuff->enable == xFalse)
+ {
+ /* delete the interest */
+ if (pHead) {
+ pNewRREvent = 0;
+ for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) {
+ if (pRREvent->client == client)
+ break;
+ pNewRREvent = pRREvent;
+ }
+ if (pRREvent) {
+ FreeResource (pRREvent->clientResource, ClientType);
+ if (pNewRREvent)
+ pNewRREvent->next = pRREvent->next;
+ else
+ *pHead = pRREvent->next;
+ xfree (pRREvent);
+ }
+ }
+ }
+ else
+ {
+ client->errorValue = stuff->enable;
+ return BadValue;
+ }
+ return Success;
+}
+
+
+static int
+ProcRRDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_RRQueryVersion:
+ return ProcRRQueryVersion(client);
+ case X_RRSetScreenConfig:
+ return ProcRRSetScreenConfig(client);
+ case X_RRSelectInput:
+ return ProcRRSelectInput(client);
+ case X_RRGetScreenInfo:
+ return ProcRRGetScreenInfo(client);
+ default:
+ return BadRequest;
+ }
+}
+
+static int
+SProcRRQueryVersion (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRRQueryVersionReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->majorVersion, n);
+ swapl(&stuff->minorVersion, n);
+ return ProcRRQueryVersion(client);
+}
+
+static int
+SProcRRGetScreenInfo (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRRGetScreenInfoReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ return ProcRRGetScreenInfo(client);
+}
+
+static int
+SProcRRSetScreenConfig (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRRSetScreenConfigReq);
+
+ if (RRClientKnowsRates (client))
+ {
+ REQUEST_SIZE_MATCH (xRRSetScreenConfigReq);
+ swaps (&stuff->rate, n);
+ }
+ else
+ {
+ REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq);
+ }
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->drawable, n);
+ swapl(&stuff->timestamp, n);
+ swaps(&stuff->sizeID, n);
+ swaps(&stuff->rotation, n);
+ return ProcRRSetScreenConfig(client);
+}
+
+static int
+SProcRRSelectInput (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRRSelectInputReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ return ProcRRSelectInput(client);
+}
+
+
+static int
+SProcRRDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_RRQueryVersion:
+ return SProcRRQueryVersion(client);
+ case X_RRSetScreenConfig:
+ return SProcRRSetScreenConfig(client);
+ case X_RRSelectInput:
+ return SProcRRSelectInput(client);
+ case X_RRGetScreenInfo:
+ return SProcRRGetScreenInfo(client);
+ default:
+ return BadRequest;
+ }
+}
+
+
+static Bool
+RRScreenSizeMatches (RRScreenSizePtr a,
+ RRScreenSizePtr b)
+{
+ if (a->width != b->width)
+ return FALSE;
+ if (a->height != b->height)
+ return FALSE;
+ if (a->mmWidth != b->mmWidth)
+ return FALSE;
+ if (a->mmHeight != b->mmHeight)
+ return FALSE;
+ return TRUE;
+}
+
+RRScreenSizePtr
+RRRegisterSize (ScreenPtr pScreen,
+ short width,
+ short height,
+ short mmWidth,
+ short mmHeight)
+{
+ rrScrPriv (pScreen);
+ int i;
+ RRScreenSize tmp;
+ RRScreenSizePtr pNew;
+
+ if (!pScrPriv)
+ return 0;
+
+ tmp.width = width;
+ tmp.height= height;
+ tmp.mmWidth = mmWidth;
+ tmp.mmHeight = mmHeight;
+ tmp.pRates = 0;
+ tmp.nRates = 0;
+ tmp.nRatesInUse = 0;
+ tmp.referenced = TRUE;
+ tmp.oldReferenced = FALSE;
+ for (i = 0; i < pScrPriv->nSizes; i++)
+ if (RRScreenSizeMatches (&tmp, &pScrPriv->pSizes[i]))
+ {
+ pScrPriv->pSizes[i].referenced = TRUE;
+ return &pScrPriv->pSizes[i];
+ }
+ pNew = xrealloc (pScrPriv->pSizes,
+ (pScrPriv->nSizes + 1) * sizeof (RRScreenSize));
+ if (!pNew)
+ return 0;
+ pNew[pScrPriv->nSizes++] = tmp;
+ pScrPriv->pSizes = pNew;
+ return &pNew[pScrPriv->nSizes-1];
+}
+
+Bool RRRegisterRate (ScreenPtr pScreen,
+ RRScreenSizePtr pSize,
+ int rate)
+{
+ rrScrPriv(pScreen);
+ int i;
+ RRScreenRatePtr pNew, pRate;
+
+ if (!pScrPriv)
+ return FALSE;
+
+ for (i = 0; i < pSize->nRates; i++)
+ {
+ pRate = &pSize->pRates[i];
+ if (pRate->rate == rate)
+ {
+ pRate->referenced = TRUE;
+ return TRUE;
+ }
+ }
+
+ pNew = xrealloc (pSize->pRates,
+ (pSize->nRates + 1) * sizeof (RRScreenRate));
+ if (!pNew)
+ return FALSE;
+ pRate = &pNew[pSize->nRates++];
+ pRate->rate = rate;
+ pRate->referenced = TRUE;
+ pRate->oldReferenced = FALSE;
+ pSize->pRates = pNew;
+ return TRUE;
+}
+
+void
+RRSetCurrentConfig (ScreenPtr pScreen,
+ Rotation rotation,
+ int rate,
+ RRScreenSizePtr pSize)
+{
+ rrScrPriv (pScreen);
+
+ if (!pScrPriv)
+ return;
+
+ pScrPriv->rotation = rotation;
+ pScrPriv->size = pSize - pScrPriv->pSizes;
+ pScrPriv->rate = rate;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
new file mode 100644
index 000000000..00c55cde7
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
@@ -0,0 +1,3799 @@
+/* $XdotOrg: xc/programs/Xserver/render/render.c,v 1.12 2005/08/28 19:47:39 ajax Exp $ */
+/*
+ * $XFree86: xc/programs/Xserver/render/render.c,v 1.27tsi Exp $
+ *
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+#define NEED_REPLIES
+#define NEED_EVENTS
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#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 "colormapst.h"
+#include "extnsionst.h"
+#include "servermd.h"
+#include <X11/extensions/render.h>
+#include <X11/extensions/renderproto.h>
+#include <X11/Xfuncproto.h>
+#include "cursorstr.h"
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#endif
+
+#if !defined(UINT32_MAX)
+#define UINT32_MAX 0xffffffffU
+#endif
+
+#include "NXpicturestr.h"
+#include "NXglyphstr.h"
+
+#include "Trap.h"
+
+#include "Render.h"
+#include "Pixmaps.h"
+#include "Options.h"
+#include "Screen.h"
+#include "Cursor.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+#ifdef TEST
+#include "Literals.h"
+#endif
+
+/*
+ * From NXmiglyph.c.
+ */
+
+void miGlyphExtents(int nlist, GlyphListPtr list,
+ GlyphPtr *glyphs, BoxPtr extents);
+
+/*
+ * From NXmitrap.c.
+ */
+
+void miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box);
+
+/*
+ * Functions from Render.c.
+ */
+
+int nxagentCursorSaveRenderInfo(ScreenPtr, CursorPtr);
+void nxagentCursorPostSaveRenderInfo(CursorPtr, ScreenPtr, PicturePtr, int, int);
+int nxagentRenderRealizeCursor(ScreenPtr, CursorPtr);
+int nxagentCreatePicture(PicturePtr, Mask);
+void nxagentDestroyPicture(PicturePtr pPicture);
+void nxagentChangePicture(PicturePtr, Mask);
+int nxagentChangePictureClip(PicturePtr, int, int, xRectangle *, int, int);
+void nxagentComposite(CARD8, PicturePtr, PicturePtr, PicturePtr, INT16, INT16,
+ INT16, INT16, INT16, INT16, CARD16, CARD16);
+void nxagentCompositeRects(CARD8, PicturePtr, xRenderColor *, int, xRectangle *);
+void nxagentCreateGlyphSet(GlyphSetPtr glyphSet);
+void nxagentReferenceGlyphSet(GlyphSetPtr glyphSet);
+void nxagentFreeGlyphs(GlyphSetPtr glyphSet, CARD32 *gids, int nglyph);
+void nxagentFreeGlyphSet(GlyphSetPtr glyphSet);
+void nxagentSetPictureTransform(PicturePtr pPicture, pointer transform);
+void nxagentSetPictureFilter(PicturePtr pPicture, char *filter, int name_size,
+ pointer params, int nparams);
+void nxagentTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat,
+ INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid *traps);
+
+/*
+ * The void pointer is actually a XGlyphElt8.
+ */
+
+void nxagentGlyphs(CARD8, PicturePtr, PicturePtr, PictFormatPtr,
+ INT16, INT16, int, void *, int, GlyphPtr *);
+
+static int ProcRenderQueryVersion (ClientPtr pClient);
+static int ProcRenderQueryPictFormats (ClientPtr pClient);
+static int ProcRenderQueryPictIndexValues (ClientPtr pClient);
+static int ProcRenderQueryDithers (ClientPtr pClient);
+static int ProcRenderCreatePicture (ClientPtr pClient);
+static int ProcRenderChangePicture (ClientPtr pClient);
+static int ProcRenderSetPictureClipRectangles (ClientPtr pClient);
+static int ProcRenderFreePicture (ClientPtr pClient);
+static int ProcRenderComposite (ClientPtr pClient);
+static int ProcRenderScale (ClientPtr pClient);
+static int ProcRenderTrapezoids (ClientPtr pClient);
+static int ProcRenderTriangles (ClientPtr pClient);
+static int ProcRenderTriStrip (ClientPtr pClient);
+static int ProcRenderTriFan (ClientPtr pClient);
+static int ProcRenderColorTrapezoids (ClientPtr pClient);
+static int ProcRenderColorTriangles (ClientPtr pClient);
+static int ProcRenderTransform (ClientPtr pClient);
+static int ProcRenderCreateGlyphSet (ClientPtr pClient);
+static int ProcRenderReferenceGlyphSet (ClientPtr pClient);
+static int ProcRenderFreeGlyphSet (ClientPtr pClient);
+static int ProcRenderAddGlyphs (ClientPtr pClient);
+static int ProcRenderAddGlyphsFromPicture (ClientPtr pClient);
+static int ProcRenderFreeGlyphs (ClientPtr pClient);
+static int ProcRenderCompositeGlyphs (ClientPtr pClient);
+static int ProcRenderFillRectangles (ClientPtr pClient);
+static int ProcRenderCreateCursor (ClientPtr pClient);
+static int ProcRenderSetPictureTransform (ClientPtr pClient);
+static int ProcRenderQueryFilters (ClientPtr pClient);
+static int ProcRenderSetPictureFilter (ClientPtr pClient);
+static int ProcRenderCreateAnimCursor (ClientPtr pClient);
+static int ProcRenderAddTraps (ClientPtr pClient);
+static int ProcRenderCreateSolidFill (ClientPtr pClient);
+static int ProcRenderCreateLinearGradient (ClientPtr pClient);
+static int ProcRenderCreateRadialGradient (ClientPtr pClient);
+static int ProcRenderCreateConicalGradient (ClientPtr pClient);
+
+static int ProcRenderDispatch (ClientPtr pClient);
+
+static int SProcRenderQueryVersion (ClientPtr pClient);
+static int SProcRenderQueryPictFormats (ClientPtr pClient);
+static int SProcRenderQueryPictIndexValues (ClientPtr pClient);
+static int SProcRenderQueryDithers (ClientPtr pClient);
+static int SProcRenderCreatePicture (ClientPtr pClient);
+static int SProcRenderChangePicture (ClientPtr pClient);
+static int SProcRenderSetPictureClipRectangles (ClientPtr pClient);
+static int SProcRenderFreePicture (ClientPtr pClient);
+static int SProcRenderComposite (ClientPtr pClient);
+static int SProcRenderScale (ClientPtr pClient);
+static int SProcRenderTrapezoids (ClientPtr pClient);
+static int SProcRenderTriangles (ClientPtr pClient);
+static int SProcRenderTriStrip (ClientPtr pClient);
+static int SProcRenderTriFan (ClientPtr pClient);
+static int SProcRenderColorTrapezoids (ClientPtr pClient);
+static int SProcRenderColorTriangles (ClientPtr pClient);
+static int SProcRenderTransform (ClientPtr pClient);
+static int SProcRenderCreateGlyphSet (ClientPtr pClient);
+static int SProcRenderReferenceGlyphSet (ClientPtr pClient);
+static int SProcRenderFreeGlyphSet (ClientPtr pClient);
+static int SProcRenderAddGlyphs (ClientPtr pClient);
+static int SProcRenderAddGlyphsFromPicture (ClientPtr pClient);
+static int SProcRenderFreeGlyphs (ClientPtr pClient);
+static int SProcRenderCompositeGlyphs (ClientPtr pClient);
+static int SProcRenderFillRectangles (ClientPtr pClient);
+static int SProcRenderCreateCursor (ClientPtr pClient);
+static int SProcRenderSetPictureTransform (ClientPtr pClient);
+static int SProcRenderQueryFilters (ClientPtr pClient);
+static int SProcRenderSetPictureFilter (ClientPtr pClient);
+static int SProcRenderCreateAnimCursor (ClientPtr pClient);
+static int SProcRenderAddTraps (ClientPtr pClient);
+static int SProcRenderCreateSolidFill (ClientPtr pClient);
+static int SProcRenderCreateLinearGradient (ClientPtr pClient);
+static int SProcRenderCreateRadialGradient (ClientPtr pClient);
+static int SProcRenderCreateConicalGradient (ClientPtr pClient);
+
+static int SProcRenderDispatch (ClientPtr pClient);
+
+int (*ProcRenderVector[RenderNumberRequests])(ClientPtr) = {
+ ProcRenderQueryVersion,
+ ProcRenderQueryPictFormats,
+ ProcRenderQueryPictIndexValues,
+ ProcRenderQueryDithers,
+ ProcRenderCreatePicture,
+ ProcRenderChangePicture,
+ ProcRenderSetPictureClipRectangles,
+ ProcRenderFreePicture,
+ ProcRenderComposite,
+ ProcRenderScale,
+ ProcRenderTrapezoids,
+ ProcRenderTriangles,
+ ProcRenderTriStrip,
+ ProcRenderTriFan,
+ ProcRenderColorTrapezoids,
+ ProcRenderColorTriangles,
+ ProcRenderTransform,
+ ProcRenderCreateGlyphSet,
+ ProcRenderReferenceGlyphSet,
+ ProcRenderFreeGlyphSet,
+ ProcRenderAddGlyphs,
+ ProcRenderAddGlyphsFromPicture,
+ ProcRenderFreeGlyphs,
+ ProcRenderCompositeGlyphs,
+ ProcRenderCompositeGlyphs,
+ ProcRenderCompositeGlyphs,
+ ProcRenderFillRectangles,
+ ProcRenderCreateCursor,
+ ProcRenderSetPictureTransform,
+ ProcRenderQueryFilters,
+ ProcRenderSetPictureFilter,
+ ProcRenderCreateAnimCursor,
+ ProcRenderAddTraps,
+ ProcRenderCreateSolidFill,
+ ProcRenderCreateLinearGradient,
+ ProcRenderCreateRadialGradient,
+ ProcRenderCreateConicalGradient
+};
+
+int (*SProcRenderVector[RenderNumberRequests])(ClientPtr) = {
+ SProcRenderQueryVersion,
+ SProcRenderQueryPictFormats,
+ SProcRenderQueryPictIndexValues,
+ SProcRenderQueryDithers,
+ SProcRenderCreatePicture,
+ SProcRenderChangePicture,
+ SProcRenderSetPictureClipRectangles,
+ SProcRenderFreePicture,
+ SProcRenderComposite,
+ SProcRenderScale,
+ SProcRenderTrapezoids,
+ SProcRenderTriangles,
+ SProcRenderTriStrip,
+ SProcRenderTriFan,
+ SProcRenderColorTrapezoids,
+ SProcRenderColorTriangles,
+ SProcRenderTransform,
+ SProcRenderCreateGlyphSet,
+ SProcRenderReferenceGlyphSet,
+ SProcRenderFreeGlyphSet,
+ SProcRenderAddGlyphs,
+ SProcRenderAddGlyphsFromPicture,
+ SProcRenderFreeGlyphs,
+ SProcRenderCompositeGlyphs,
+ SProcRenderCompositeGlyphs,
+ SProcRenderCompositeGlyphs,
+ SProcRenderFillRectangles,
+ SProcRenderCreateCursor,
+ SProcRenderSetPictureTransform,
+ SProcRenderQueryFilters,
+ SProcRenderSetPictureFilter,
+ SProcRenderCreateAnimCursor,
+ SProcRenderAddTraps,
+ SProcRenderCreateSolidFill,
+ SProcRenderCreateLinearGradient,
+ SProcRenderCreateRadialGradient,
+ SProcRenderCreateConicalGradient
+};
+
+static void
+RenderResetProc (ExtensionEntry *extEntry);
+
+#if 0
+static CARD8 RenderReqCode;
+#endif
+int RenderErrBase;
+int RenderClientPrivateIndex;
+
+typedef struct _RenderClient {
+ int major_version;
+ int minor_version;
+} RenderClientRec, *RenderClientPtr;
+
+#define GetRenderClient(pClient) ((RenderClientPtr) (pClient)->devPrivates[RenderClientPrivateIndex].ptr)
+
+static void
+RenderClientCallback (CallbackListPtr *list,
+ pointer closure,
+ pointer data)
+{
+ NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
+ ClientPtr pClient = clientinfo->client;
+ RenderClientPtr pRenderClient = GetRenderClient (pClient);
+
+ pRenderClient->major_version = 0;
+ pRenderClient->minor_version = 0;
+}
+
+void
+RenderExtensionInit (void)
+{
+ ExtensionEntry *extEntry;
+
+ if (!PictureType)
+ return;
+ if (!PictureFinishInit ())
+ return;
+ RenderClientPrivateIndex = AllocateClientPrivateIndex ();
+ if (!AllocateClientPrivate (RenderClientPrivateIndex,
+ sizeof (RenderClientRec)))
+ return;
+ if (!AddCallback (&ClientStateCallback, RenderClientCallback, 0))
+ return;
+
+ extEntry = AddExtension (RENDER_NAME, 0, RenderNumberErrors,
+ ProcRenderDispatch, SProcRenderDispatch,
+ RenderResetProc, StandardMinorOpcode);
+ if (!extEntry)
+ return;
+#if 0
+ RenderReqCode = (CARD8) extEntry->base;
+#endif
+ RenderErrBase = extEntry->errorBase;
+}
+
+static void
+RenderResetProc (ExtensionEntry *extEntry)
+{
+ ResetPicturePrivateIndex();
+ ResetGlyphSetPrivateIndex();
+}
+
+static int
+ProcRenderQueryVersion (ClientPtr client)
+{
+ RenderClientPtr pRenderClient = GetRenderClient (client);
+ xRenderQueryVersionReply rep;
+ register int n;
+ REQUEST(xRenderQueryVersionReq);
+
+ pRenderClient->major_version = stuff->majorVersion;
+ pRenderClient->minor_version = stuff->minorVersion;
+
+ REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = nxagentRenderVersionMajor;
+ rep.minorVersion = nxagentRenderVersionMinor;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.majorVersion, n);
+ swapl(&rep.minorVersion, n);
+ }
+ WriteToClient(client, sizeof(xRenderQueryVersionReply), (char *)&rep);
+ return (client->noClientException);
+}
+
+#if 0
+static int
+VisualDepth (ScreenPtr pScreen, VisualPtr pVisual)
+{
+ DepthPtr pDepth;
+ int d, v;
+
+ for (d = 0; d < pScreen->numDepths; d++)
+ {
+ pDepth = pScreen->allowedDepths + d;
+ for (v = 0; v < pDepth->numVids; v++)
+ {
+ if (pDepth->vids[v] == pVisual->vid)
+ return pDepth->depth;
+ }
+ }
+ return 0;
+}
+#endif
+
+static VisualPtr
+findVisual (ScreenPtr pScreen, VisualID vid)
+{
+ VisualPtr pVisual;
+ int v;
+
+ for (v = 0; v < pScreen->numVisuals; v++)
+ {
+ pVisual = pScreen->visuals + v;
+ if (pVisual->vid == vid)
+ return pVisual;
+ }
+ return 0;
+}
+
+extern char *ConnectionInfo;
+
+static int
+ProcRenderQueryPictFormats (ClientPtr client)
+{
+ RenderClientPtr pRenderClient = GetRenderClient (client);
+ xRenderQueryPictFormatsReply *reply;
+ xPictScreen *pictScreen;
+ xPictDepth *pictDepth;
+ xPictVisual *pictVisual;
+ xPictFormInfo *pictForm;
+ CARD32 *pictSubpixel;
+ ScreenPtr pScreen;
+ VisualPtr pVisual;
+ DepthPtr pDepth;
+ int v, d;
+ PictureScreenPtr ps;
+ PictFormatPtr pFormat;
+ int nformat;
+ int ndepth;
+ int nvisual;
+ int rlength;
+ int s;
+ int n;
+ int numScreens;
+ int numSubpixel;
+
+ extern int nxagentAlphaEnabled;
+/* REQUEST(xRenderQueryPictFormatsReq); */
+
+ REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
+
+#ifdef PANORAMIX
+ if (noPanoramiXExtension)
+ numScreens = screenInfo.numScreens;
+ else
+ numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
+#else
+ numScreens = screenInfo.numScreens;
+#endif
+ ndepth = nformat = nvisual = 0;
+ for (s = 0; s < numScreens; s++)
+ {
+ pScreen = screenInfo.screens[s];
+ for (d = 0; d < pScreen->numDepths; d++)
+ {
+ pDepth = pScreen->allowedDepths + d;
+ ++ndepth;
+
+ for (v = 0; v < pDepth->numVids; v++)
+ {
+ pVisual = findVisual (pScreen, pDepth->vids[v]);
+ if (pVisual && PictureMatchVisual (pScreen, pDepth->depth, pVisual))
+ ++nvisual;
+ }
+ }
+ ps = GetPictureScreenIfSet(pScreen);
+ if (ps)
+ nformat += ps->nformats;
+ }
+ if (pRenderClient->major_version == 0 && pRenderClient->minor_version < 6)
+ numSubpixel = 0;
+ else
+ numSubpixel = numScreens;
+
+ rlength = (sizeof (xRenderQueryPictFormatsReply) +
+ nformat * sizeof (xPictFormInfo) +
+ numScreens * sizeof (xPictScreen) +
+ ndepth * sizeof (xPictDepth) +
+ nvisual * sizeof (xPictVisual) +
+ numSubpixel * sizeof (CARD32));
+ reply = (xRenderQueryPictFormatsReply *) xalloc (rlength);
+ if (!reply)
+ return BadAlloc;
+ reply->type = X_Reply;
+ reply->sequenceNumber = client->sequence;
+ reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+ reply->numFormats = nformat;
+ reply->numScreens = numScreens;
+ reply->numDepths = ndepth;
+ reply->numVisuals = nvisual;
+ reply->numSubpixel = numSubpixel;
+
+ pictForm = (xPictFormInfo *) (reply + 1);
+
+ for (s = 0; s < numScreens; s++)
+ {
+ pScreen = screenInfo.screens[s];
+ ps = GetPictureScreenIfSet(pScreen);
+ if (ps)
+ {
+ for (nformat = 0, pFormat = ps->formats;
+ nformat < ps->nformats;
+ nformat++, pFormat++)
+ {
+ pictForm->id = pFormat->id;
+ pictForm->type = pFormat->type;
+ pictForm->depth = pFormat->depth;
+ pictForm->direct.red = pFormat->direct.red;
+ pictForm->direct.redMask = pFormat->direct.redMask;
+ pictForm->direct.green = pFormat->direct.green;
+ pictForm->direct.greenMask = pFormat->direct.greenMask;
+ pictForm->direct.blue = pFormat->direct.blue;
+ pictForm->direct.blueMask = pFormat->direct.blueMask;
+ pictForm->direct.alpha = nxagentAlphaEnabled ? pFormat->direct.alpha : 0;
+ pictForm->direct.alphaMask = pFormat->direct.alphaMask;
+ if (pFormat->type == PictTypeIndexed && pFormat->index.pColormap)
+ pictForm->colormap = pFormat->index.pColormap->mid;
+ else
+ pictForm->colormap = None;
+ if (client->swapped)
+ {
+ swapl (&pictForm->id, n);
+ swaps (&pictForm->direct.red, n);
+ swaps (&pictForm->direct.redMask, n);
+ swaps (&pictForm->direct.green, n);
+ swaps (&pictForm->direct.greenMask, n);
+ swaps (&pictForm->direct.blue, n);
+ swaps (&pictForm->direct.blueMask, n);
+ swaps (&pictForm->direct.alpha, n);
+ swaps (&pictForm->direct.alphaMask, n);
+ swapl (&pictForm->colormap, n);
+ }
+ pictForm++;
+ }
+ }
+ }
+
+ pictScreen = (xPictScreen *) pictForm;
+ for (s = 0; s < numScreens; s++)
+ {
+ pScreen = screenInfo.screens[s];
+ pictDepth = (xPictDepth *) (pictScreen + 1);
+ ndepth = 0;
+ for (d = 0; d < pScreen->numDepths; d++)
+ {
+ pictVisual = (xPictVisual *) (pictDepth + 1);
+ pDepth = pScreen->allowedDepths + d;
+
+ nvisual = 0;
+ for (v = 0; v < pDepth->numVids; v++)
+ {
+ pVisual = findVisual (pScreen, pDepth->vids[v]);
+ if (pVisual && (pFormat = PictureMatchVisual (pScreen,
+ pDepth->depth,
+ pVisual)))
+ {
+ pictVisual->visual = pVisual->vid;
+ pictVisual->format = pFormat->id;
+ if (client->swapped)
+ {
+ swapl (&pictVisual->visual, n);
+ swapl (&pictVisual->format, n);
+ }
+ pictVisual++;
+ nvisual++;
+ }
+ }
+ pictDepth->depth = pDepth->depth;
+ pictDepth->nPictVisuals = nvisual;
+ if (client->swapped)
+ {
+ swaps (&pictDepth->nPictVisuals, n);
+ }
+ ndepth++;
+ pictDepth = (xPictDepth *) pictVisual;
+ }
+ pictScreen->nDepth = ndepth;
+ ps = GetPictureScreenIfSet(pScreen);
+ if (ps)
+ pictScreen->fallback = ps->fallback->id;
+ else
+ pictScreen->fallback = 0;
+ if (client->swapped)
+ {
+ swapl (&pictScreen->nDepth, n);
+ swapl (&pictScreen->fallback, n);
+ }
+ pictScreen = (xPictScreen *) pictDepth;
+ }
+ pictSubpixel = (CARD32 *) pictScreen;
+
+ for (s = 0; s < numSubpixel; s++)
+ {
+ pScreen = screenInfo.screens[s];
+ ps = GetPictureScreenIfSet(pScreen);
+ if (ps)
+ *pictSubpixel = ps->subpixel;
+ else
+ *pictSubpixel = SubPixelUnknown;
+ if (client->swapped)
+ {
+ swapl (pictSubpixel, n);
+ }
+ ++pictSubpixel;
+ }
+
+ if (client->swapped)
+ {
+ swaps (&reply->sequenceNumber, n);
+ swapl (&reply->length, n);
+ swapl (&reply->numFormats, n);
+ swapl (&reply->numScreens, n);
+ swapl (&reply->numDepths, n);
+ swapl (&reply->numVisuals, n);
+ swapl (&reply->numSubpixel, n);
+ }
+ WriteToClient(client, rlength, (char *) reply);
+ xfree (reply);
+ return client->noClientException;
+}
+
+static int
+ProcRenderQueryPictIndexValues (ClientPtr client)
+{
+ PictFormatPtr pFormat;
+ int num;
+ int rlength;
+ int i, n;
+ REQUEST(xRenderQueryPictIndexValuesReq);
+ xRenderQueryPictIndexValuesReply *reply;
+ xIndexValue *values;
+
+ REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq);
+
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->format,
+ PictFormatType,
+ SecurityReadAccess);
+
+ if (!pFormat)
+ {
+ client->errorValue = stuff->format;
+ return RenderErrBase + BadPictFormat;
+ }
+ if (pFormat->type != PictTypeIndexed)
+ {
+ client->errorValue = stuff->format;
+ return BadMatch;
+ }
+ num = pFormat->index.nvalues;
+ rlength = (sizeof (xRenderQueryPictIndexValuesReply) +
+ num * sizeof(xIndexValue));
+ reply = (xRenderQueryPictIndexValuesReply *) xalloc (rlength);
+ if (!reply)
+ return BadAlloc;
+
+ reply->type = X_Reply;
+ reply->sequenceNumber = client->sequence;
+ reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+ reply->numIndexValues = num;
+
+ values = (xIndexValue *) (reply + 1);
+
+ memcpy (reply + 1, pFormat->index.pValues, num * sizeof (xIndexValue));
+
+ if (client->swapped)
+ {
+ for (i = 0; i < num; i++)
+ {
+ swapl (&values[i].pixel, n);
+ swaps (&values[i].red, n);
+ swaps (&values[i].green, n);
+ swaps (&values[i].blue, n);
+ swaps (&values[i].alpha, n);
+ }
+ swaps (&reply->sequenceNumber, n);
+ swapl (&reply->length, n);
+ swapl (&reply->numIndexValues, n);
+ }
+
+ WriteToClient(client, rlength, (char *) reply);
+ xfree(reply);
+ return (client->noClientException);
+}
+
+static int
+ProcRenderQueryDithers (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+ProcRenderCreatePicture (ClientPtr client)
+{
+ PicturePtr pPicture;
+ DrawablePtr pDrawable;
+ PictFormatPtr pFormat;
+ int len;
+ int error;
+ REQUEST(xRenderCreatePictureReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
+
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+ SECURITY_VERIFY_DRAWABLE(pDrawable, stuff->drawable, client,
+ SecurityWriteAccess);
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->format,
+ PictFormatType,
+ SecurityReadAccess);
+ if (!pFormat)
+ {
+ client->errorValue = stuff->format;
+ return RenderErrBase + BadPictFormat;
+ }
+ if (pFormat->depth != pDrawable->depth)
+ return BadMatch;
+ len = client->req_len - (sizeof(xRenderCreatePictureReq) >> 2);
+ if (Ones(stuff->mask) != len)
+ return BadLength;
+
+ pPicture = CreatePicture (stuff->pid,
+ pDrawable,
+ pFormat,
+ stuff->mask,
+ (XID *) (stuff + 1),
+ client,
+ &error);
+ if (!pPicture)
+ return error;
+ nxagentCreatePicture(pPicture, stuff -> mask);
+
+ if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+ return BadAlloc;
+ return Success;
+}
+
+static int
+ProcRenderChangePicture (ClientPtr client)
+{
+ PicturePtr pPicture;
+ REQUEST(xRenderChangePictureReq);
+ int len;
+ int error;
+
+ REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
+ VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ len = client->req_len - (sizeof(xRenderChangePictureReq) >> 2);
+ if (Ones(stuff->mask) != len)
+ return BadLength;
+
+ error = ChangePicture (pPicture, stuff->mask, (XID *) (stuff + 1),
+ (DevUnion *) 0, client);
+
+ nxagentChangePicture(pPicture, stuff->mask);
+
+ return error;
+}
+
+static int
+ProcRenderSetPictureClipRectangles (ClientPtr client)
+{
+ REQUEST(xRenderSetPictureClipRectanglesReq);
+ PicturePtr pPicture;
+ int nr;
+ int result;
+
+ REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
+ VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pPicture->pDrawable)
+ return BadDrawable;
+
+ /*
+ * The original code used sizeof(xRenderChangePictureReq).
+ * This was harmless, as both structures have the same size.
+ *
+ * nr = (client->req_len << 2) - sizeof(xRenderChangePictureReq);
+ */
+ nr = (client->req_len << 2) - sizeof(xRenderSetPictureClipRectanglesReq);
+ if (nr & 4)
+ return BadLength;
+ nr >>= 3;
+ result = SetPictureClipRects (pPicture,
+ stuff->xOrigin, stuff->yOrigin,
+ nr, (xRectangle *) &stuff[1]);
+ nxagentChangePictureClip (pPicture,
+ CT_NONE,
+ nr,
+ (xRectangle *) &stuff[1],
+ (int)stuff -> xOrigin,
+ (int)stuff -> yOrigin);
+
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+static int
+ProcRenderFreePicture (ClientPtr client)
+{
+ PicturePtr pPicture;
+ REQUEST(xRenderFreePictureReq);
+
+ REQUEST_SIZE_MATCH(xRenderFreePictureReq);
+
+ VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityDestroyAccess,
+ RenderErrBase + BadPicture);
+
+ nxagentDestroyPicture(pPicture);
+
+ FreeResource (stuff->picture, RT_NONE);
+ return(client->noClientException);
+}
+
+static Bool
+PictOpValid (CARD8 op)
+{
+ if (/*PictOpMinimum <= op && */ op <= PictOpMaximum)
+ return TRUE;
+ if (PictOpDisjointMinimum <= op && op <= PictOpDisjointMaximum)
+ return TRUE;
+ if (PictOpConjointMinimum <= op && op <= PictOpConjointMaximum)
+ return TRUE;
+ return FALSE;
+}
+
+/*
+ * Check if both pictures have drawables which are
+ * virtual pixmaps. See the corresponding define
+ * in NXpicture.c
+ */
+
+#define NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+#ifdef NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+#define nxagentCompositePredicate(pSrc, pDst) TRUE
+
+#else
+
+/*
+ * This is still under development. The final
+ * goal is to let pictures point to the real
+ * pixmaps instead of pointing to virtuals.
+ */
+
+int nxagentCompositePredicate(PicturePtr pSrc, PicturePtr pDst)
+{
+ PixmapPtr pPixmap1;
+ PixmapPtr pPixmap2;
+
+ pPixmap1 = (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP ?
+ ((PixmapPtr) pSrc -> pDrawable) : NULL);
+
+ pPixmap2 = (pDst -> pDrawable -> type == DRAWABLE_PIXMAP ?
+ ((PixmapPtr) pDst -> pDrawable) : NULL);
+
+ if (pPixmap1 == NULL || pPixmap2 == NULL)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCompositePredicate: Case 0.\n");
+ #endif
+
+ return FALSE;
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCompositePredicate: Case 1.\n");
+ #endif
+
+ if (nxagentPixmapIsVirtual(pPixmap1) == 1 &&
+ nxagentPixmapIsVirtual(pPixmap2) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCompositePredicate: Case 2.\n");
+ #endif
+
+ return TRUE;
+ }
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCompositePredicate: Case 3.\n");
+ #endif
+
+ return FALSE;
+}
+
+#endif
+
+static int
+ProcRenderComposite (ClientPtr client)
+{
+ PicturePtr pSrc, pMask, pDst;
+ REQUEST(xRenderCompositeReq);
+
+ REQUEST_SIZE_MATCH(xRenderCompositeReq);
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_ALPHA (pMask, stuff->mask, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) ||
+ (pMask && pMask->pDrawable && pSrc->pDrawable->pScreen != pMask->pDrawable->pScreen))
+ return BadMatch;
+
+ ValidatePicture (pSrc);
+ if (pMask)
+ ValidatePicture (pMask);
+ ValidatePicture (pDst);
+
+ #ifdef NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+ if (nxagentCompositePredicate(pSrc, pDst))
+ {
+ #ifdef TEST
+ fprintf(stderr, "ProcRenderComposite: Going to composite with "
+ "source at [%p] mask at [%p] and destination at [%p].\n",
+ (void *) pSrc, (void *) pMask, (void *) pDst);
+ #endif
+
+ CompositePicture (stuff->op,
+ pSrc,
+ pMask,
+ pDst,
+ stuff->xSrc,
+ stuff->ySrc,
+ stuff->xMask,
+ stuff->yMask,
+ stuff->xDst,
+ stuff->yDst,
+ stuff->width,
+ stuff->height);
+ }
+
+ #else
+
+ if (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP &&
+ pDst -> pDrawable -> type == DRAWABLE_PIXMAP &&
+ (!pMask || pMask -> pDrawable -> type == DRAWABLE_PIXMAP))
+ {
+ PixmapPtr pVirtualPixmapSrc;
+ PixmapPtr pVirtualPixmapDst;
+ PixmapPtr pVirtualPixmapMask;
+
+ PicturePtr pVirtualPictureSrc;
+ PicturePtr pVirtualPictureDst;
+ PicturePtr pVirtualPictureMask;
+
+ pVirtualPixmapSrc = (PixmapPtr) pSrc -> pDrawable;
+ pVirtualPictureSrc = nxagentPixmapPriv(pVirtualPixmapSrc) -> pPicture;
+
+ pVirtualPixmapDst = (PixmapPtr) pDst -> pDrawable;
+ pVirtualPictureDst = nxagentPixmapPriv(pVirtualPixmapDst) -> pPicture;
+
+ if (pMask)
+ {
+ pVirtualPixmapMask = (PixmapPtr) pMask -> pDrawable;
+ pVirtualPictureMask = nxagentPixmapPriv(pVirtualPixmapMask) -> pPicture;
+ }
+ else
+ {
+ pVirtualPixmapMask = NULL;
+ pVirtualPictureMask = NULL;
+ }
+
+ if (pVirtualPictureSrc && pVirtualPictureDst)
+ {
+ #ifdef TEST
+ fprintf(stderr, "ProcRenderComposite: Going to composite with "
+ "source at [%p] mask at [%p] and destination at [%p].\n",
+ (void *) pVirtualPixmapSrc, (void *) pVirtualPixmapMask,
+ (void *) pVirtualPixmapDst);
+ #endif
+
+ CompositePicture (stuff->op,
+ pVirtualPictureSrc,
+ pVirtualPictureMask,
+ pVirtualPictureDst,
+ stuff->xSrc,
+ stuff->ySrc,
+ stuff->xMask,
+ stuff->yMask,
+ stuff->xDst,
+ stuff->yDst,
+ stuff->width,
+ stuff->height);
+ }
+ }
+
+ #endif
+
+ nxagentComposite (stuff -> op,
+ pSrc,
+ pMask,
+ pDst,
+ stuff -> xSrc,
+ stuff -> ySrc,
+ stuff -> xMask,
+ stuff -> yMask,
+ stuff -> xDst,
+ stuff -> yDst,
+ stuff -> width,
+ stuff -> height);
+
+ return Success;
+}
+
+static int
+ProcRenderScale (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+ProcRenderTrapezoids (ClientPtr client)
+{
+ int ntraps;
+ PicturePtr pSrc, pDst;
+ PictFormatPtr pFormat;
+ REQUEST(xRenderTrapezoidsReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+ return BadMatch;
+ if (stuff->maskFormat)
+ {
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->maskFormat,
+ PictFormatType,
+ SecurityReadAccess);
+ if (!pFormat)
+ {
+ client->errorValue = stuff->maskFormat;
+ return RenderErrBase + BadPictFormat;
+ }
+ }
+ else
+ pFormat = 0;
+ ntraps = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq);
+ if (ntraps % sizeof (xTrapezoid))
+ return BadLength;
+ ntraps /= sizeof (xTrapezoid);
+ if (ntraps)
+ {
+ if (pFormat != NULL)
+ {
+ nxagentTrapezoidExtents = (BoxPtr) xalloc(sizeof(BoxRec));
+
+ miTrapezoidBounds (ntraps, (xTrapezoid *) &stuff[1], nxagentTrapezoidExtents);
+ }
+
+ if (nxagentCompositePredicate(pSrc, pDst) == 1)
+ {
+ CompositeTrapezoids (stuff->op, pSrc, pDst, pFormat,
+ stuff->xSrc, stuff->ySrc,
+ ntraps, (xTrapezoid *) &stuff[1]);
+ }
+
+ nxagentTrapezoids (stuff->op, pSrc, pDst, pFormat,
+ stuff->xSrc, stuff->ySrc,
+ ntraps, (xTrapezoid *) &stuff[1]);
+
+ if (nxagentTrapezoidExtents != NullBox)
+ {
+ xfree(nxagentTrapezoidExtents);
+
+ nxagentTrapezoidExtents = NullBox;
+ }
+ }
+
+ return client->noClientException;
+}
+
+static int
+ProcRenderTriangles (ClientPtr client)
+{
+ int ntris;
+ PicturePtr pSrc, pDst;
+ PictFormatPtr pFormat;
+ REQUEST(xRenderTrianglesReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+ return BadMatch;
+ if (stuff->maskFormat)
+ {
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->maskFormat,
+ PictFormatType,
+ SecurityReadAccess);
+ if (!pFormat)
+ {
+ client->errorValue = stuff->maskFormat;
+ return RenderErrBase + BadPictFormat;
+ }
+ }
+ else
+ pFormat = 0;
+ ntris = (client->req_len << 2) - sizeof (xRenderTrianglesReq);
+ if (ntris % sizeof (xTriangle))
+ return BadLength;
+ ntris /= sizeof (xTriangle);
+ if (ntris)
+ CompositeTriangles (stuff->op, pSrc, pDst, pFormat,
+ stuff->xSrc, stuff->ySrc,
+ ntris, (xTriangle *) &stuff[1]);
+ return client->noClientException;
+}
+
+static int
+ProcRenderTriStrip (ClientPtr client)
+{
+ int npoints;
+ PicturePtr pSrc, pDst;
+ PictFormatPtr pFormat;
+ REQUEST(xRenderTrianglesReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+ return BadMatch;
+ if (stuff->maskFormat)
+ {
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->maskFormat,
+ PictFormatType,
+ SecurityReadAccess);
+ if (!pFormat)
+ {
+ client->errorValue = stuff->maskFormat;
+ return RenderErrBase + BadPictFormat;
+ }
+ }
+ else
+ pFormat = 0;
+ npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq));
+ if (npoints & 4)
+ return(BadLength);
+ npoints >>= 3;
+ if (npoints >= 3)
+ CompositeTriStrip (stuff->op, pSrc, pDst, pFormat,
+ stuff->xSrc, stuff->ySrc,
+ npoints, (xPointFixed *) &stuff[1]);
+ return client->noClientException;
+}
+
+static int
+ProcRenderTriFan (ClientPtr client)
+{
+ int npoints;
+ PicturePtr pSrc, pDst;
+ PictFormatPtr pFormat;
+ REQUEST(xRenderTrianglesReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+ return BadMatch;
+ if (stuff->maskFormat)
+ {
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->maskFormat,
+ PictFormatType,
+ SecurityReadAccess);
+ if (!pFormat)
+ {
+ client->errorValue = stuff->maskFormat;
+ return RenderErrBase + BadPictFormat;
+ }
+ }
+ else
+ pFormat = 0;
+ npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq));
+ if (npoints & 4)
+ return(BadLength);
+ npoints >>= 3;
+ if (npoints >= 3)
+ CompositeTriFan (stuff->op, pSrc, pDst, pFormat,
+ stuff->xSrc, stuff->ySrc,
+ npoints, (xPointFixed *) &stuff[1]);
+ return client->noClientException;
+}
+
+static int
+ProcRenderColorTrapezoids (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+ProcRenderColorTriangles (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+ProcRenderTransform (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+ProcRenderCreateGlyphSet (ClientPtr client)
+{
+ GlyphSetPtr glyphSet;
+ PictFormatPtr format;
+ int f;
+ REQUEST(xRenderCreateGlyphSetReq);
+
+ REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
+
+ LEGAL_NEW_RESOURCE(stuff->gsid, client);
+ format = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->format,
+ PictFormatType,
+ SecurityReadAccess);
+ if (!format)
+ {
+ client->errorValue = stuff->format;
+ return RenderErrBase + BadPictFormat;
+ }
+ switch (format->depth) {
+ case 1:
+ f = GlyphFormat1;
+ break;
+ case 4:
+ f = GlyphFormat4;
+ break;
+ case 8:
+ f = GlyphFormat8;
+ break;
+ case 16:
+ f = GlyphFormat16;
+ break;
+ case 32:
+ f = GlyphFormat32;
+ break;
+ default:
+ return BadMatch;
+ }
+ if (format->type != PictTypeDirect)
+ return BadMatch;
+ glyphSet = AllocateGlyphSet (f, format);
+ if (!glyphSet)
+ return BadAlloc;
+ if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
+ return BadAlloc;
+
+ nxagentCreateGlyphSet(glyphSet);
+
+ return Success;
+}
+
+static int
+ProcRenderReferenceGlyphSet (ClientPtr client)
+{
+ GlyphSetPtr glyphSet;
+ REQUEST(xRenderReferenceGlyphSetReq);
+
+ REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);
+
+ LEGAL_NEW_RESOURCE(stuff->gsid, client);
+
+ glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ stuff->existing,
+ GlyphSetType,
+ SecurityWriteAccess);
+ if (!glyphSet)
+ {
+ client->errorValue = stuff->existing;
+ return RenderErrBase + BadGlyphSet;
+ }
+ glyphSet->refcnt++;
+
+ nxagentReferenceGlyphSet(glyphSet);
+
+ if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
+ return BadAlloc;
+ return client->noClientException;
+}
+
+#define NLOCALDELTA 64
+#define NLOCALGLYPH 256
+
+static int
+ProcRenderFreeGlyphSet (ClientPtr client)
+{
+ GlyphSetPtr glyphSet;
+ REQUEST(xRenderFreeGlyphSetReq);
+
+ REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
+ glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ stuff->glyphset,
+ GlyphSetType,
+ SecurityDestroyAccess);
+ if (!glyphSet)
+ {
+ client->errorValue = stuff->glyphset;
+ return RenderErrBase + BadGlyphSet;
+ }
+
+ nxagentFreeGlyphSet(glyphSet);
+
+ FreeResource (stuff->glyphset, RT_NONE);
+ return client->noClientException;
+}
+
+typedef struct _GlyphNew {
+ Glyph id;
+ GlyphPtr glyph;
+} GlyphNewRec, *GlyphNewPtr;
+
+static int
+ProcRenderAddGlyphs (ClientPtr client)
+{
+ GlyphSetPtr glyphSet;
+ REQUEST(xRenderAddGlyphsReq);
+ GlyphNewRec glyphsLocal[NLOCALGLYPH];
+ GlyphNewPtr glyphsBase, glyphs;
+ GlyphPtr glyph = NULL;
+ int remain, nglyphs;
+ CARD32 *gids;
+ xGlyphInfo *gi;
+ CARD8 *bits;
+ int size;
+ int err = BadAlloc;
+
+ int totSizeImages;
+
+ REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
+ glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ stuff->glyphset,
+ GlyphSetType,
+ SecurityWriteAccess);
+ if (!glyphSet)
+ {
+ client->errorValue = stuff->glyphset;
+ return RenderErrBase + BadGlyphSet;
+ }
+
+ nglyphs = stuff->nglyphs;
+ if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec))
+ return BadAlloc;
+
+ if (nglyphs <= NLOCALGLYPH)
+ glyphsBase = glyphsLocal;
+ else
+ {
+ glyphsBase = (GlyphNewPtr) Xalloc (nglyphs * sizeof (GlyphNewRec));
+ if (!glyphsBase)
+ return BadAlloc;
+ }
+
+ remain = (client->req_len << 2) - sizeof (xRenderAddGlyphsReq);
+
+ glyphs = glyphsBase;
+
+ totSizeImages = 0;
+ gids = (CARD32 *) (stuff + 1);
+ gi = (xGlyphInfo *) (gids + nglyphs);
+ bits = (CARD8 *) (gi + nglyphs);
+ remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs;
+
+ while (remain >= 0 && nglyphs)
+ {
+ glyph = AllocateGlyph (gi, glyphSet->fdepth);
+ if (!glyph)
+ {
+ err = BadAlloc;
+ goto bail;
+ }
+
+ glyphs->glyph = glyph;
+ glyphs->id = *gids;
+
+ size = glyph->size - sizeof (xGlyphInfo);
+ if (remain < size)
+ break;
+ memcpy ((CARD8 *) (glyph + 1), bits, size);
+
+ if (size & 3)
+ size += 4 - (size & 3);
+ bits += size;
+ totSizeImages += size;
+ remain -= size;
+ gi++;
+ gids++;
+ glyphs++;
+ nglyphs--;
+ }
+
+ if (nglyphs || remain)
+ {
+ err = BadLength;
+ goto bail;
+ }
+ nglyphs = stuff->nglyphs;
+ if (!ResizeGlyphSet (glyphSet, nglyphs))
+ {
+ err = BadAlloc;
+ goto bail;
+ }
+ glyphs = glyphsBase;
+ while (nglyphs--) {
+ AddGlyph (glyphSet, glyphs->glyph, glyphs->id);
+ glyphs++;
+ }
+
+ if (glyphsBase != glyphsLocal)
+ Xfree (glyphsBase);
+ return client->noClientException;
+bail:
+ while (glyphs != glyphsBase)
+ {
+ --glyphs;
+ xfree (glyphs->glyph);
+ }
+ if (glyphsBase != glyphsLocal)
+ Xfree (glyphsBase);
+ return err;
+}
+
+static int
+ProcRenderAddGlyphsFromPicture (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+ProcRenderFreeGlyphs (ClientPtr client)
+{
+ REQUEST(xRenderFreeGlyphsReq);
+ GlyphSetPtr glyphSet;
+ int nglyph;
+ CARD32 *gids;
+ CARD32 glyph;
+
+ REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
+ glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ stuff->glyphset,
+ GlyphSetType,
+ SecurityWriteAccess);
+ if (!glyphSet)
+ {
+ client->errorValue = stuff->glyphset;
+ return RenderErrBase + BadGlyphSet;
+ }
+ nglyph = ((client->req_len << 2) - sizeof (xRenderFreeGlyphsReq)) >> 2;
+ gids = (CARD32 *) (stuff + 1);
+
+ nxagentFreeGlyphs(glyphSet, gids, nglyph);
+
+ while (nglyph-- > 0)
+ {
+ glyph = *gids++;
+ if (!DeleteGlyph (glyphSet, glyph))
+ {
+ client->errorValue = glyph;
+ return RenderErrBase + BadGlyph;
+ }
+ }
+ return client->noClientException;
+}
+
+typedef struct XGlyphElt8{
+ GlyphSet glyphset;
+ _Xconst char *chars;
+ int nchars;
+ int xOff;
+ int yOff;
+} XGlyphElt8;
+
+static int
+ProcRenderCompositeGlyphs (ClientPtr client)
+{
+ GlyphSetPtr glyphSet;
+ GlyphSet gs;
+ PicturePtr pSrc, pDst;
+ PictFormatPtr pFormat;
+ GlyphListRec listsLocal[NLOCALDELTA];
+ GlyphListPtr lists, listsBase;
+ GlyphPtr glyphsLocal[NLOCALGLYPH];
+ Glyph glyph;
+ GlyphPtr *glyphs, *glyphsBase;
+ xGlyphElt *elt;
+ CARD8 *buffer, *end;
+ int nglyph;
+ int nlist;
+ int space;
+ int size;
+ int n;
+
+ XGlyphElt8 *elements, *elementsBase;
+
+ REQUEST(xRenderCompositeGlyphsReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
+
+ switch (stuff->renderReqType) {
+ default: size = 1; break;
+ case X_RenderCompositeGlyphs16: size = 2; break;
+ case X_RenderCompositeGlyphs32: size = 4; break;
+ }
+
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+ return BadMatch;
+ if (stuff->maskFormat)
+ {
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->maskFormat,
+ PictFormatType,
+ SecurityReadAccess);
+ if (!pFormat)
+ {
+ client->errorValue = stuff->maskFormat;
+ return RenderErrBase + BadPictFormat;
+ }
+ }
+ else
+ pFormat = 0;
+
+ glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ stuff->glyphset,
+ GlyphSetType,
+ SecurityReadAccess);
+ if (!glyphSet)
+ {
+ client->errorValue = stuff->glyphset;
+ return RenderErrBase + BadGlyphSet;
+ }
+
+ buffer = (CARD8 *) (stuff + 1);
+ end = (CARD8 *) stuff + (client->req_len << 2);
+ nglyph = 0;
+ nlist = 0;
+ while (buffer + sizeof (xGlyphElt) < end)
+ {
+ elt = (xGlyphElt *) buffer;
+ buffer += sizeof (xGlyphElt);
+
+ if (elt->len == 0xff)
+ {
+ buffer += 4;
+ }
+ else
+ {
+ nlist++;
+ nglyph += elt->len;
+ space = size * elt->len;
+ if (space & 3)
+ space += 4 - (space & 3);
+ buffer += space;
+ }
+ }
+ if (nglyph <= NLOCALGLYPH)
+ glyphsBase = glyphsLocal;
+ else
+ {
+ glyphsBase = (GlyphPtr *) ALLOCATE_LOCAL (nglyph * sizeof (GlyphPtr));
+ if (!glyphsBase)
+ return BadAlloc;
+ }
+ if (nlist <= NLOCALDELTA)
+ listsBase = listsLocal;
+ else
+ {
+ listsBase = (GlyphListPtr) ALLOCATE_LOCAL (nlist * sizeof (GlyphListRec));
+ if (!listsBase)
+ return BadAlloc;
+ }
+
+ elementsBase = xalloc(nlist * sizeof(XGlyphElt8));
+ if (!elementsBase)
+ return BadAlloc;
+
+ buffer = (CARD8 *) (stuff + 1);
+ glyphs = glyphsBase;
+ lists = listsBase;
+ elements = elementsBase;
+ while (buffer + sizeof (xGlyphElt) < end)
+ {
+ elt = (xGlyphElt *) buffer;
+ buffer += sizeof (xGlyphElt);
+
+ if (elt->len == 0xff)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "ProcRenderCompositeGlyphs: Glyphset change with base size [%d].\n",
+ size);
+ #endif
+
+ if (buffer + sizeof (GlyphSet) < end)
+ {
+ memcpy(&gs, buffer, sizeof(GlyphSet));
+ glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ gs,
+ GlyphSetType,
+ SecurityReadAccess);
+ if (!glyphSet)
+ {
+ client->errorValue = gs;
+ if (glyphsBase != glyphsLocal)
+ DEALLOCATE_LOCAL (glyphsBase);
+ if (listsBase != listsLocal)
+ DEALLOCATE_LOCAL (listsBase);
+ return RenderErrBase + BadGlyphSet;
+ }
+ }
+ buffer += 4;
+ }
+ else
+ {
+ lists->xOff = elt->deltax;
+ lists->yOff = elt->deltay;
+ lists->format = glyphSet->format;
+ lists->len = 0;
+
+ if (glyphSet -> remoteID == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "ProcRenderCompositeGlyphs: Going to reconnect glyphset at [%p].\n",
+ (void *) glyphSet);
+ #endif
+
+ nxagentReconnectGlyphSet(glyphSet, (XID) 0, (void*) NULL);
+ }
+
+ elements -> glyphset = glyphSet -> remoteID;
+ elements -> chars = (char *) buffer;
+ elements -> nchars = elt->len;
+ elements -> xOff = elt->deltax;
+ elements -> yOff = elt->deltay;
+ n = elt->len;
+ while (n--)
+ {
+ if (buffer + size <= end)
+ {
+ switch (size) {
+ case 1:
+ glyph = *((CARD8 *)buffer); break;
+ case 2:
+ glyph = *((CARD16 *)buffer); break;
+ case 4:
+ default:
+ glyph = *((CARD32 *)buffer); break;
+ }
+ if ((*glyphs = FindGlyph (glyphSet, glyph)))
+ {
+ lists->len++;
+ glyphs++;
+ }
+ }
+ buffer += size;
+ }
+ space = size * elt->len;
+ if (space & 3)
+ buffer += 4 - (space & 3);
+ lists++;
+ elements++;
+ }
+ }
+ if (buffer > end)
+ return BadLength;
+
+ /*
+ * We need to know the glyphs extents to synchronize
+ * the drawables involved in the composite text ope-
+ * ration. Also we need to synchronize only the back-
+ * ground of the text we are going to render, so the
+ * operations on the framebuffer must be executed
+ * after the X requests.
+ */
+
+ nxagentGlyphsExtents = (BoxPtr) xalloc(sizeof(BoxRec));
+
+ miGlyphExtents(nlist, listsBase, glyphsBase, nxagentGlyphsExtents);
+
+ nxagentGlyphs(stuff -> op,
+ pSrc,
+ pDst,
+ pFormat,
+ stuff -> xSrc,
+ stuff -> ySrc,
+ nlist,
+ elementsBase,
+ size,
+ glyphsBase);
+
+ if (nxagentCompositePredicate(pSrc, pDst) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "ProcRenderCompositeGlyphs: Going to composite glyphs with "
+ "source at [%p] and destination at [%p].\n",
+ (void *) pSrc, (void *) pDst);
+ #endif
+
+ CompositeGlyphs(stuff -> op,
+ pSrc,
+ pDst,
+ pFormat,
+ stuff -> xSrc,
+ stuff -> ySrc,
+ nlist,
+ listsBase,
+ glyphsBase);
+ }
+
+ xfree(nxagentGlyphsExtents);
+ nxagentGlyphsExtents = NullBox;
+
+ if (glyphsBase != glyphsLocal)
+ DEALLOCATE_LOCAL (glyphsBase);
+ if (listsBase != listsLocal)
+ DEALLOCATE_LOCAL (listsBase);
+
+ xfree(elementsBase);
+
+ return client->noClientException;
+}
+
+static int
+ProcRenderFillRectangles (ClientPtr client)
+{
+ PicturePtr pDst;
+ int things;
+ REQUEST(xRenderFillRectanglesReq);
+
+ REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+
+ things = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq);
+ if (things & 4)
+ return(BadLength);
+ things >>= 3;
+
+ CompositeRects (stuff->op,
+ pDst,
+ &stuff->color,
+ things,
+ (xRectangle *) &stuff[1]);
+
+ ValidatePicture (pDst);
+ nxagentCompositeRects(stuff -> op,
+ pDst,
+ &stuff -> color,
+ things,
+ (xRectangle *) &stuff[1]);
+
+ return client->noClientException;
+}
+
+static void
+SetBit (unsigned char *line, int x, int bit)
+{
+ unsigned char mask;
+
+ if (screenInfo.bitmapBitOrder == LSBFirst)
+ mask = (1 << (x & 7));
+ else
+ mask = (0x80 >> (x & 7));
+ /* XXX assumes byte order is host byte order */
+ line += (x >> 3);
+ if (bit)
+ *line |= mask;
+ else
+ *line &= ~mask;
+}
+
+#define DITHER_DIM 2
+
+static CARD32 orderedDither[DITHER_DIM][DITHER_DIM] = {
+ { 1, 3, },
+ { 4, 2, },
+};
+
+#define DITHER_SIZE ((sizeof orderedDither / sizeof orderedDither[0][0]) + 1)
+
+static int
+ProcRenderCreateCursor (ClientPtr client)
+{
+ REQUEST(xRenderCreateCursorReq);
+ PicturePtr pSrc;
+ ScreenPtr pScreen;
+ unsigned short width, height;
+ CARD32 *argbbits, *argb;
+ unsigned char *srcbits, *srcline;
+ unsigned char *mskbits, *mskline;
+ int stride;
+ int x, y;
+ int nbytes_mono;
+ CursorMetricRec cm;
+ CursorPtr pCursor;
+ CARD32 twocolor[3];
+ int ncolor;
+
+ RealizeCursorProcPtr saveRealizeCursor;
+
+ REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
+ LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+ VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ if (!pSrc->pDrawable)
+ return BadDrawable;
+ pScreen = pSrc->pDrawable->pScreen;
+ width = pSrc->pDrawable->width;
+ height = pSrc->pDrawable->height;
+ if ( stuff->x > width
+ || stuff->y > height )
+ return (BadMatch);
+ argbbits = xalloc (width * height * sizeof (CARD32));
+ if (!argbbits)
+ return (BadAlloc);
+
+ stride = BitmapBytePad(width);
+ nbytes_mono = stride*height;
+ srcbits = (unsigned char *)xalloc(nbytes_mono);
+ if (!srcbits)
+ {
+ xfree (argbbits);
+ return (BadAlloc);
+ }
+ mskbits = (unsigned char *)xalloc(nbytes_mono);
+ if (!mskbits)
+ {
+ xfree(argbbits);
+ xfree(srcbits);
+ return (BadAlloc);
+ }
+ bzero ((char *) mskbits, nbytes_mono);
+ bzero ((char *) srcbits, nbytes_mono);
+
+ if (pSrc->format == PICT_a8r8g8b8)
+ {
+ (*pScreen->GetImage) (pSrc->pDrawable,
+ 0, 0, width, height, ZPixmap,
+ 0xffffffff, (pointer) argbbits);
+ }
+ else
+ {
+ PixmapPtr pPixmap;
+ PicturePtr pPicture;
+ PictFormatPtr pFormat;
+ int error;
+
+ pFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8);
+ if (!pFormat)
+ {
+ xfree (argbbits);
+ xfree (srcbits);
+ xfree (mskbits);
+ return (BadImplementation);
+ }
+ pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32);
+ if (!pPixmap)
+ {
+ xfree (argbbits);
+ xfree (srcbits);
+ xfree (mskbits);
+ return (BadAlloc);
+ }
+ pPicture = CreatePicture (0, &pPixmap->drawable, pFormat, 0, 0,
+ client, &error);
+ if (!pPicture)
+ {
+ xfree (argbbits);
+ xfree (srcbits);
+ xfree (mskbits);
+ return error;
+ }
+ (*pScreen->DestroyPixmap) (pPixmap);
+ CompositePicture (PictOpSrc,
+ pSrc, 0, pPicture,
+ 0, 0, 0, 0, 0, 0, width, height);
+ (*pScreen->GetImage) (pPicture->pDrawable,
+ 0, 0, width, height, ZPixmap,
+ 0xffffffff, (pointer) argbbits);
+ FreePicture (pPicture, 0);
+ }
+ /*
+ * Check whether the cursor can be directly supported by
+ * the core cursor code
+ */
+ ncolor = 0;
+ argb = argbbits;
+ for (y = 0; ncolor <= 2 && y < height; y++)
+ {
+ for (x = 0; ncolor <= 2 && x < width; x++)
+ {
+ CARD32 p = *argb++;
+ CARD32 a = (p >> 24);
+
+ if (a == 0) /* transparent */
+ continue;
+ if (a == 0xff) /* opaque */
+ {
+ int n;
+ for (n = 0; n < ncolor; n++)
+ if (p == twocolor[n])
+ break;
+ if (n == ncolor)
+ twocolor[ncolor++] = p;
+ }
+ else
+ ncolor = 3;
+ }
+ }
+
+ /*
+ * Convert argb image to two plane cursor
+ */
+ srcline = srcbits;
+ mskline = mskbits;
+ argb = argbbits;
+ for (y = 0; y < height; y++)
+ {
+ for (x = 0; x < width; x++)
+ {
+ CARD32 p = *argb++;
+
+ if (ncolor <= 2)
+ {
+ CARD32 a = ((p >> 24));
+
+ SetBit (mskline, x, a != 0);
+ SetBit (srcline, x, a != 0 && p == twocolor[0]);
+ }
+ else
+ {
+ CARD32 a = ((p >> 24) * DITHER_SIZE + 127) / 255;
+ CARD32 i = ((CvtR8G8B8toY15(p) >> 7) * DITHER_SIZE + 127) / 255;
+ CARD32 d = orderedDither[y&(DITHER_DIM-1)][x&(DITHER_DIM-1)];
+ /* Set mask from dithered alpha value */
+ SetBit(mskline, x, a > d);
+ /* Set src from dithered intensity value */
+ SetBit(srcline, x, a > d && i <= d);
+ }
+ }
+ srcline += stride;
+ mskline += stride;
+ }
+ /*
+ * Dither to white and black if the cursor has more than two colors
+ */
+ if (ncolor > 2)
+ {
+ twocolor[0] = 0xff000000;
+ twocolor[1] = 0xffffffff;
+ }
+ else
+ {
+ xfree (argbbits);
+ argbbits = 0;
+ }
+
+#define GetByte(p,s) (((p) >> (s)) & 0xff)
+#define GetColor(p,s) (GetByte(p,s) | (GetByte(p,s) << 8))
+
+ cm.width = width;
+ cm.height = height;
+ cm.xhot = stuff->x;
+ cm.yhot = stuff->y;
+
+ /*
+ * This cursor uses RENDER, so we make sure
+ * that it is allocated in a way that allows
+ * the mi and dix layers to handle it but we
+ * later create it on the server by mirror-
+ * ing the RENDER operation we got from the
+ * client.
+ */
+
+ saveRealizeCursor = pScreen -> RealizeCursor;
+
+ pScreen -> RealizeCursor = nxagentCursorSaveRenderInfo;
+
+ pCursor = AllocCursorARGB (srcbits, mskbits, argbbits, &cm,
+ GetColor(twocolor[0], 16),
+ GetColor(twocolor[0], 8),
+ GetColor(twocolor[0], 0),
+ GetColor(twocolor[1], 16),
+ GetColor(twocolor[1], 8),
+ GetColor(twocolor[1], 0));
+
+ pScreen -> RealizeCursor = saveRealizeCursor;
+
+ /*
+ * Store into the private data members the
+ * information needed to recreate it at
+ * reconnection. This is done in two steps
+ * as in the first step we don't have the
+ * picture info.
+ */
+
+ if (pCursor == NULL)
+ {
+ return BadAlloc;
+ }
+
+ nxagentCursorPostSaveRenderInfo(pCursor, pScreen, pSrc, stuff -> x, stuff -> y);
+
+ nxagentRenderRealizeCursor(pScreen, pCursor);
+
+ if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+ return (client->noClientException);
+ return BadAlloc;
+}
+
+static int
+ProcRenderSetPictureTransform (ClientPtr client)
+{
+ REQUEST(xRenderSetPictureTransformReq);
+ PicturePtr pPicture;
+ int result;
+
+ REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
+ VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ result = SetPictureTransform (pPicture, (PictTransform *) &stuff->transform);
+
+ nxagentSetPictureTransform(pPicture, &stuff->transform);
+
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+static int
+ProcRenderQueryFilters (ClientPtr client)
+{
+ REQUEST (xRenderQueryFiltersReq);
+ DrawablePtr pDrawable;
+ xRenderQueryFiltersReply *reply;
+ int nbytesName;
+ int nnames;
+ ScreenPtr pScreen;
+ PictureScreenPtr ps;
+ int i, j;
+ int len;
+ int total_bytes;
+ INT16 *aliases;
+ char *names;
+
+ REQUEST_SIZE_MATCH(xRenderQueryFiltersReq);
+ SECURITY_VERIFY_DRAWABLE(pDrawable, stuff->drawable, client, SecurityReadAccess);
+
+ pScreen = pDrawable->pScreen;
+ nbytesName = 0;
+ nnames = 0;
+ ps = GetPictureScreenIfSet(pScreen);
+ if (ps)
+ {
+ for (i = 0; i < ps->nfilters; i++)
+ nbytesName += 1 + strlen (ps->filters[i].name);
+ for (i = 0; i < ps->nfilterAliases; i++)
+ nbytesName += 1 + strlen (ps->filterAliases[i].alias);
+ nnames = ps->nfilters + ps->nfilterAliases;
+ }
+ len = ((nnames + 1) >> 1) + ((nbytesName + 3) >> 2);
+ total_bytes = sizeof (xRenderQueryFiltersReply) + (len << 2);
+ reply = (xRenderQueryFiltersReply *) xalloc (total_bytes);
+ if (!reply)
+ return BadAlloc;
+ aliases = (INT16 *) (reply + 1);
+ names = (char *) (aliases + ((nnames + 1) & ~1));
+
+ reply->type = X_Reply;
+ reply->sequenceNumber = client->sequence;
+ reply->length = len;
+ reply->numAliases = nnames;
+ reply->numFilters = nnames;
+ if (ps)
+ {
+
+ /* fill in alias values */
+ for (i = 0; i < ps->nfilters; i++)
+ aliases[i] = FilterAliasNone;
+ for (i = 0; i < ps->nfilterAliases; i++)
+ {
+ for (j = 0; j < ps->nfilters; j++)
+ if (ps->filterAliases[i].filter_id == ps->filters[j].id)
+ break;
+ if (j == ps->nfilters)
+ {
+ for (j = 0; j < ps->nfilterAliases; j++)
+ if (ps->filterAliases[i].filter_id ==
+ ps->filterAliases[j].alias_id)
+ {
+ break;
+ }
+ if (j == ps->nfilterAliases)
+ j = FilterAliasNone;
+ else
+ j = j + ps->nfilters;
+ }
+ aliases[i + ps->nfilters] = j;
+ }
+
+ /* fill in filter names */
+ for (i = 0; i < ps->nfilters; i++)
+ {
+ j = strlen (ps->filters[i].name);
+ *names++ = j;
+ strncpy (names, ps->filters[i].name, j);
+ names += j;
+ }
+
+ /* fill in filter alias names */
+ for (i = 0; i < ps->nfilterAliases; i++)
+ {
+ j = strlen (ps->filterAliases[i].alias);
+ *names++ = j;
+ strncpy (names, ps->filterAliases[i].alias, j);
+ names += j;
+ }
+ }
+
+ if (client->swapped)
+ {
+ register int n;
+
+ for (i = 0; i < (int)reply->numAliases; i++)
+ {
+ swaps (&aliases[i], n);
+ }
+ swaps(&reply->sequenceNumber, n);
+ swapl(&reply->length, n);
+ swapl(&reply->numAliases, n);
+ swapl(&reply->numFilters, n);
+ }
+ WriteToClient(client, total_bytes, (char *) reply);
+ xfree (reply);
+
+ return(client->noClientException);
+}
+
+static int
+ProcRenderSetPictureFilter (ClientPtr client)
+{
+ REQUEST (xRenderSetPictureFilterReq);
+ PicturePtr pPicture;
+ int result;
+ xFixed *params;
+ int nparams;
+ char *name;
+
+ REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
+ VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ name = (char *) (stuff + 1);
+ params = (xFixed *) (name + ((stuff->nbytes + 3) & ~3));
+ nparams = ((xFixed *) stuff + client->req_len) - params;
+ result = SetPictureFilter (pPicture, name, stuff->nbytes, params, nparams);
+
+ nxagentSetPictureFilter(pPicture, name, stuff->nbytes, params, nparams);
+
+ return result;
+}
+
+static int
+ProcRenderCreateAnimCursor (ClientPtr client)
+{
+ REQUEST(xRenderCreateAnimCursorReq);
+ CursorPtr *cursors;
+ CARD32 *deltas;
+ CursorPtr pCursor;
+ int ncursor;
+ xAnimCursorElt *elt;
+ int i;
+ int ret;
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq);
+ LEGAL_NEW_RESOURCE(stuff->cid, client);
+ if (client->req_len & 1)
+ return BadLength;
+ ncursor = (client->req_len - (SIZEOF(xRenderCreateAnimCursorReq) >> 2)) >> 1;
+ cursors = xalloc (ncursor * (sizeof (CursorPtr) + sizeof (CARD32)));
+ if (!cursors)
+ return BadAlloc;
+ deltas = (CARD32 *) (cursors + ncursor);
+ elt = (xAnimCursorElt *) (stuff + 1);
+ for (i = 0; i < ncursor; i++)
+ {
+ cursors[i] = (CursorPtr)SecurityLookupIDByType(client, elt->cursor,
+ RT_CURSOR, SecurityReadAccess);
+ if (!cursors[i])
+ {
+ xfree (cursors);
+ client->errorValue = elt->cursor;
+ return BadCursor;
+ }
+ deltas[i] = elt->delay;
+ elt++;
+ }
+ ret = AnimCursorCreate (cursors, deltas, ncursor, &pCursor);
+ xfree (cursors);
+ if (ret != Success)
+ return ret;
+
+ nxagentAnimCursorBits = pCursor -> bits;
+
+ for (i = 0; i < MAXSCREENS; i++)
+ {
+ pCursor -> devPriv[i] = NULL;
+ }
+
+ if (AddResource (stuff->cid, RT_CURSOR, (pointer)pCursor))
+ return client->noClientException;
+ return BadAlloc;
+}
+
+static int
+ProcRenderAddTraps (ClientPtr client)
+{
+ int ntraps;
+ PicturePtr pPicture;
+ REQUEST(xRenderAddTrapsReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq);
+ VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pPicture->pDrawable)
+ return BadDrawable;
+ ntraps = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
+ if (ntraps % sizeof (xTrap))
+ return BadLength;
+ ntraps /= sizeof (xTrap);
+ if (ntraps)
+ AddTraps (pPicture,
+ stuff->xOff, stuff->yOff,
+ ntraps, (xTrap *) &stuff[1]);
+ return client->noClientException;
+}
+
+static int ProcRenderCreateSolidFill(ClientPtr client)
+{
+ PicturePtr pPicture;
+ int error = 0;
+ REQUEST(xRenderCreateSolidFillReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
+
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+ pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error);
+ if (!pPicture)
+ return error;
+ if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+ return BadAlloc;
+ return Success;
+}
+
+static int ProcRenderCreateLinearGradient (ClientPtr client)
+{
+ PicturePtr pPicture;
+ int len;
+ int error = 0;
+ xFixed *stops;
+ xRenderColor *colors;
+ REQUEST(xRenderCreateLinearGradientReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
+
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ stops = (xFixed *)(stuff + 1);
+ colors = (xRenderColor *)(stops + stuff->nStops);
+
+ pPicture = CreateLinearGradientPicture (stuff->pid, &stuff->p1, &stuff->p2,
+ stuff->nStops, stops, colors, &error);
+ if (!pPicture)
+ return error;
+ if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+ return BadAlloc;
+ return Success;
+}
+
+static int ProcRenderCreateRadialGradient (ClientPtr client)
+{
+ PicturePtr pPicture;
+ int len;
+ int error = 0;
+ xFixed *stops;
+ xRenderColor *colors;
+ REQUEST(xRenderCreateRadialGradientReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
+
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ stops = (xFixed *)(stuff + 1);
+ colors = (xRenderColor *)(stops + stuff->nStops);
+
+ pPicture = CreateRadialGradientPicture (stuff->pid, &stuff->inner, &stuff->outer,
+ stuff->inner_radius, stuff->outer_radius,
+ stuff->nStops, stops, colors, &error);
+ if (!pPicture)
+ return error;
+ if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+ return BadAlloc;
+ return Success;
+}
+
+static int ProcRenderCreateConicalGradient (ClientPtr client)
+{
+ PicturePtr pPicture;
+ int len;
+ int error = 0;
+ xFixed *stops;
+ xRenderColor *colors;
+ REQUEST(xRenderCreateConicalGradientReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
+
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ stops = (xFixed *)(stuff + 1);
+ colors = (xRenderColor *)(stops + stuff->nStops);
+
+ pPicture = CreateConicalGradientPicture (stuff->pid, &stuff->center, stuff->angle,
+ stuff->nStops, stops, colors, &error);
+ if (!pPicture)
+ return error;
+ if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+ return BadAlloc;
+ return Success;
+}
+
+
+static int
+ProcRenderDispatch (ClientPtr client)
+{
+ int result;
+
+ REQUEST(xReq);
+
+ /*
+ * Let the client fail if we are
+ * hiding the RENDER extension.
+ */
+
+ if (nxagentRenderTrap)
+ {
+ return BadRequest;
+ }
+
+ if (stuff->data < RenderNumberRequests)
+ {
+ #ifdef TEST
+ fprintf(stderr, "ProcRenderDispatch: Request [%s] OPCODE#%d.\n",
+ nxagentRenderRequestLiteral[stuff->data], stuff->data);
+ #endif
+
+ /*
+ * Set the nxagentGCTrap flag while
+ * dispatching a render operation to
+ * avoid reentrancy in GCOps.c.
+ */
+
+ nxagentGCTrap = 1;
+
+ result = (*ProcRenderVector[stuff->data]) (client);
+
+ nxagentGCTrap = 0;
+
+ return result;
+ }
+ else
+ return BadRequest;
+}
+
+static int
+SProcRenderQueryVersion (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderQueryVersionReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->majorVersion, n);
+ swapl(&stuff->minorVersion, n);
+ return (*ProcRenderVector[stuff->renderReqType])(client);
+}
+
+static int
+SProcRenderQueryPictFormats (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderQueryPictFormatsReq);
+ swaps(&stuff->length, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryPictIndexValues (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderQueryPictIndexValuesReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->format, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryDithers (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+SProcRenderCreatePicture (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderCreatePictureReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->pid, n);
+ swapl(&stuff->drawable, n);
+ swapl(&stuff->format, n);
+ swapl(&stuff->mask, n);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderChangePicture (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderChangePictureReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->picture, n);
+ swapl(&stuff->mask, n);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderSetPictureClipRectangles (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderSetPictureClipRectanglesReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->picture, n);
+ SwapRestS(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderFreePicture (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderFreePictureReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->picture, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderComposite (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderCompositeReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->src, n);
+ swapl(&stuff->mask, n);
+ swapl(&stuff->dst, n);
+ swaps(&stuff->xSrc, n);
+ swaps(&stuff->ySrc, n);
+ swaps(&stuff->xMask, n);
+ swaps(&stuff->yMask, n);
+ swaps(&stuff->xDst, n);
+ swaps(&stuff->yDst, n);
+ swaps(&stuff->width, n);
+ swaps(&stuff->height, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderScale (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderScaleReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->src, n);
+ swapl(&stuff->dst, n);
+ swapl(&stuff->colorScale, n);
+ swapl(&stuff->alphaScale, n);
+ swaps(&stuff->xSrc, n);
+ swaps(&stuff->ySrc, n);
+ swaps(&stuff->xDst, n);
+ swaps(&stuff->yDst, n);
+ swaps(&stuff->width, n);
+ swaps(&stuff->height, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTrapezoids (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderTrapezoidsReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
+ swaps (&stuff->length, n);
+ swapl (&stuff->src, n);
+ swapl (&stuff->dst, n);
+ swapl (&stuff->maskFormat, n);
+ swaps (&stuff->xSrc, n);
+ swaps (&stuff->ySrc, n);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriangles (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderTrianglesReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+ swaps (&stuff->length, n);
+ swapl (&stuff->src, n);
+ swapl (&stuff->dst, n);
+ swapl (&stuff->maskFormat, n);
+ swaps (&stuff->xSrc, n);
+ swaps (&stuff->ySrc, n);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriStrip (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderTriStripReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTriStripReq);
+ swaps (&stuff->length, n);
+ swapl (&stuff->src, n);
+ swapl (&stuff->dst, n);
+ swapl (&stuff->maskFormat, n);
+ swaps (&stuff->xSrc, n);
+ swaps (&stuff->ySrc, n);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriFan (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderTriFanReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTriFanReq);
+ swaps (&stuff->length, n);
+ swapl (&stuff->src, n);
+ swapl (&stuff->dst, n);
+ swapl (&stuff->maskFormat, n);
+ swaps (&stuff->xSrc, n);
+ swaps (&stuff->ySrc, n);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderColorTrapezoids (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+SProcRenderColorTriangles (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+SProcRenderTransform (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+SProcRenderCreateGlyphSet (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderCreateGlyphSetReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->gsid, n);
+ swapl(&stuff->format, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderReferenceGlyphSet (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderReferenceGlyphSetReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->gsid, n);
+ swapl(&stuff->existing, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderFreeGlyphSet (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderFreeGlyphSetReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->glyphset, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderAddGlyphs (ClientPtr client)
+{
+ register int n;
+ register unsigned int i;
+ CARD32 *gids;
+ void *end;
+ xGlyphInfo *gi;
+ REQUEST(xRenderAddGlyphsReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->glyphset, n);
+ swapl(&stuff->nglyphs, n);
+ if (stuff->nglyphs & 0xe0000000)
+ return BadLength;
+ end = (CARD8 *) stuff + (client->req_len << 2);
+ gids = (CARD32 *) (stuff + 1);
+ gi = (xGlyphInfo *) (gids + stuff->nglyphs);
+ if ((char *) end - (char *) (gids + stuff->nglyphs) < 0)
+ return BadLength;
+ if ((char *) end - (char *) (gi + stuff->nglyphs) < 0)
+ return BadLength;
+ for (i = 0; i < stuff->nglyphs; i++)
+ {
+ swapl (&gids[i], n);
+ swaps (&gi[i].width, n);
+ swaps (&gi[i].height, n);
+ swaps (&gi[i].x, n);
+ swaps (&gi[i].y, n);
+ swaps (&gi[i].xOff, n);
+ swaps (&gi[i].yOff, n);
+ }
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderAddGlyphsFromPicture (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+SProcRenderFreeGlyphs (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderFreeGlyphsReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->glyphset, n);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCompositeGlyphs (ClientPtr client)
+{
+ register int n;
+ xGlyphElt *elt;
+ CARD8 *buffer;
+ CARD8 *end;
+ int space;
+ int i;
+ int size;
+
+ REQUEST(xRenderCompositeGlyphsReq);
+
+ switch (stuff->renderReqType) {
+ default: size = 1; break;
+ case X_RenderCompositeGlyphs16: size = 2; break;
+ case X_RenderCompositeGlyphs32: size = 4; break;
+ }
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->src, n);
+ swapl(&stuff->dst, n);
+ swapl(&stuff->maskFormat, n);
+ swapl(&stuff->glyphset, n);
+ swaps(&stuff->xSrc, n);
+ swaps(&stuff->ySrc, n);
+ buffer = (CARD8 *) (stuff + 1);
+ end = (CARD8 *) stuff + (client->req_len << 2);
+ while (buffer + sizeof (xGlyphElt) < end)
+ {
+ elt = (xGlyphElt *) buffer;
+ buffer += sizeof (xGlyphElt);
+
+ swaps (&elt->deltax, n);
+ swaps (&elt->deltay, n);
+
+ i = elt->len;
+ if (i == 0xff)
+ {
+ swapl (buffer, n);
+ buffer += 4;
+ }
+ else
+ {
+ space = size * i;
+ switch (size) {
+ case 1:
+ buffer += i;
+ break;
+ case 2:
+ while (i--)
+ {
+ swaps (buffer, n);
+ buffer += 2;
+ }
+ break;
+ case 4:
+ while (i--)
+ {
+ swapl (buffer, n);
+ buffer += 4;
+ }
+ break;
+ }
+ if (space & 3)
+ buffer += 4 - (space & 3);
+ }
+ }
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderFillRectangles (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderFillRectanglesReq);
+
+ REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->dst, n);
+ swaps(&stuff->color.red, n);
+ swaps(&stuff->color.green, n);
+ swaps(&stuff->color.blue, n);
+ swaps(&stuff->color.alpha, n);
+ SwapRestS(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateCursor (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderCreateCursorReq);
+ REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->cid, n);
+ swapl(&stuff->src, n);
+ swaps(&stuff->x, n);
+ swaps(&stuff->y, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderSetPictureTransform (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderSetPictureTransformReq);
+ REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->picture, n);
+ swapl(&stuff->transform.matrix11, n);
+ swapl(&stuff->transform.matrix12, n);
+ swapl(&stuff->transform.matrix13, n);
+ swapl(&stuff->transform.matrix21, n);
+ swapl(&stuff->transform.matrix22, n);
+ swapl(&stuff->transform.matrix23, n);
+ swapl(&stuff->transform.matrix31, n);
+ swapl(&stuff->transform.matrix32, n);
+ swapl(&stuff->transform.matrix33, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryFilters (ClientPtr client)
+{
+ register int n;
+ REQUEST (xRenderQueryFiltersReq);
+ REQUEST_SIZE_MATCH (xRenderQueryFiltersReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->drawable, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderSetPictureFilter (ClientPtr client)
+{
+ register int n;
+ REQUEST (xRenderSetPictureFilterReq);
+ REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->picture, n);
+ swaps(&stuff->nbytes, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateAnimCursor (ClientPtr client)
+{
+ register int n;
+ REQUEST (xRenderCreateAnimCursorReq);
+ REQUEST_AT_LEAST_SIZE (xRenderCreateAnimCursorReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->cid, n);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderAddTraps (ClientPtr client)
+{
+ register int n;
+ REQUEST (xRenderAddTrapsReq);
+ REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->picture, n);
+ swaps(&stuff->xOff, n);
+ swaps(&stuff->yOff, n);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateSolidFill(ClientPtr client)
+{
+ register int n;
+ REQUEST (xRenderCreateSolidFillReq);
+ REQUEST_AT_LEAST_SIZE (xRenderCreateSolidFillReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->pid, n);
+ swaps(&stuff->color.alpha, n);
+ swaps(&stuff->color.red, n);
+ swaps(&stuff->color.green, n);
+ swaps(&stuff->color.blue, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static void swapStops(void *stuff, int n)
+{
+ int i;
+ CARD32 *stops;
+ CARD16 *colors;
+ stops = (CARD32 *)(stuff);
+ for (i = 0; i < n; ++i) {
+ swapl(stops, n);
+ ++stops;
+ }
+ colors = (CARD16 *)(stops);
+ for (i = 0; i < 4*n; ++i) {
+ swaps(stops, n);
+ ++stops;
+ }
+}
+
+static int
+SProcRenderCreateLinearGradient (ClientPtr client)
+{
+ register int n;
+ int len;
+ REQUEST (xRenderCreateLinearGradientReq);
+ REQUEST_AT_LEAST_SIZE (xRenderCreateLinearGradientReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->pid, n);
+ swapl(&stuff->p1.x, n);
+ swapl(&stuff->p1.y, n);
+ swapl(&stuff->p2.x, n);
+ swapl(&stuff->p2.y, n);
+ swapl(&stuff->nStops, n);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ swapStops(stuff+1, stuff->nStops);
+
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateRadialGradient (ClientPtr client)
+{
+ register int n;
+ int len;
+ REQUEST (xRenderCreateRadialGradientReq);
+ REQUEST_AT_LEAST_SIZE (xRenderCreateRadialGradientReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->pid, n);
+ swapl(&stuff->inner.x, n);
+ swapl(&stuff->inner.y, n);
+ swapl(&stuff->outer.x, n);
+ swapl(&stuff->outer.y, n);
+ swapl(&stuff->inner_radius, n);
+ swapl(&stuff->outer_radius, n);
+ swapl(&stuff->nStops, n);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ swapStops(stuff+1, stuff->nStops);
+
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateConicalGradient (ClientPtr client)
+{
+ register int n;
+ int len;
+ REQUEST (xRenderCreateConicalGradientReq);
+ REQUEST_AT_LEAST_SIZE (xRenderCreateConicalGradientReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->pid, n);
+ swapl(&stuff->center.x, n);
+ swapl(&stuff->center.y, n);
+ swapl(&stuff->angle, n);
+ swapl(&stuff->nStops, n);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ swapStops(stuff+1, stuff->nStops);
+
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderDispatch (ClientPtr client)
+{
+ int result;
+
+ REQUEST(xReq);
+
+ /*
+ * Let the client fail if we are
+ * hiding the RENDER extension.
+ */
+
+ if (nxagentRenderTrap)
+ {
+ return BadRequest;
+ }
+
+ if (stuff->data < RenderNumberRequests)
+ {
+ /*
+ * Set the nxagentGCTrap flag while
+ * dispatching a render operation to
+ * avoid reentrancy in GCOps.c.
+ */
+
+ nxagentGCTrap = 1;
+
+ result = (*SProcRenderVector[stuff->data]) (client);
+
+ nxagentGCTrap = 0;
+
+ return result;
+ }
+ else
+ return BadRequest;
+}
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+
+#define VERIFY_XIN_PICTURE(pPicture, pid, client, mode, err) {\
+ pPicture = SecurityLookupIDByType(client, pid, XRT_PICTURE, mode);\
+ if (!pPicture) { \
+ client->errorValue = pid; \
+ return err; \
+ } \
+}
+
+#define VERIFY_XIN_ALPHA(pPicture, pid, client, mode, err) {\
+ if (pid == None) \
+ pPicture = 0; \
+ else { \
+ VERIFY_XIN_PICTURE(pPicture, pid, client, mode, err); \
+ } \
+} \
+
+int (*PanoramiXSaveRenderVector[RenderNumberRequests])(ClientPtr);
+
+unsigned long XRT_PICTURE;
+
+static int
+PanoramiXRenderCreatePicture (ClientPtr client)
+{
+ REQUEST(xRenderCreatePictureReq);
+ PanoramiXRes *refDraw, *newPict;
+ int result = Success, j;
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
+ if(!(refDraw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+ return BadDrawable;
+ if(!(newPict = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes))))
+ return BadAlloc;
+ newPict->type = XRT_PICTURE;
+ newPict->info[0].id = stuff->pid;
+
+ if (refDraw->type == XRT_WINDOW &&
+ stuff->drawable == WindowTable[0]->drawable.id)
+ {
+ newPict->u.pict.root = TRUE;
+ }
+ else
+ newPict->u.pict.root = FALSE;
+
+ for(j = 1; j < PanoramiXNumScreens; j++)
+ newPict->info[j].id = FakeClientID(client->index);
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->pid = newPict->info[j].id;
+ stuff->drawable = refDraw->info[j].id;
+ result = (*PanoramiXSaveRenderVector[X_RenderCreatePicture]) (client);
+ if(result != Success) break;
+ }
+
+ if (result == Success)
+ AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
+ else
+ xfree(newPict);
+
+ return (result);
+}
+
+static int
+PanoramiXRenderChangePicture (ClientPtr client)
+{
+ PanoramiXRes *pict;
+ int result = Success, j;
+ REQUEST(xRenderChangePictureReq);
+
+ REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
+
+ VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->picture = pict->info[j].id;
+ result = (*PanoramiXSaveRenderVector[X_RenderChangePicture]) (client);
+ if(result != Success) break;
+ }
+
+ return (result);
+}
+
+static int
+PanoramiXRenderSetPictureClipRectangles (ClientPtr client)
+{
+ REQUEST(xRenderSetPictureClipRectanglesReq);
+ int result = Success, j;
+ PanoramiXRes *pict;
+
+ REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
+
+ VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->picture = pict->info[j].id;
+ result = (*PanoramiXSaveRenderVector[X_RenderSetPictureClipRectangles]) (client);
+ if(result != Success) break;
+ }
+
+ return (result);
+}
+
+static int
+PanoramiXRenderSetPictureTransform (ClientPtr client)
+{
+ REQUEST(xRenderSetPictureTransformReq);
+ int result = Success, j;
+ PanoramiXRes *pict;
+
+ REQUEST_AT_LEAST_SIZE(xRenderSetPictureTransformReq);
+
+ VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->picture = pict->info[j].id;
+ result = (*PanoramiXSaveRenderVector[X_RenderSetPictureTransform]) (client);
+ if(result != Success) break;
+ }
+
+ return (result);
+}
+
+static int
+PanoramiXRenderSetPictureFilter (ClientPtr client)
+{
+ REQUEST(xRenderSetPictureFilterReq);
+ int result = Success, j;
+ PanoramiXRes *pict;
+
+ REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq);
+
+ VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->picture = pict->info[j].id;
+ result = (*PanoramiXSaveRenderVector[X_RenderSetPictureFilter]) (client);
+ if(result != Success) break;
+ }
+
+ return (result);
+}
+
+static int
+PanoramiXRenderFreePicture (ClientPtr client)
+{
+ PanoramiXRes *pict;
+ int result = Success, j;
+ REQUEST(xRenderFreePictureReq);
+
+ REQUEST_SIZE_MATCH(xRenderFreePictureReq);
+
+ client->errorValue = stuff->picture;
+
+ VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityDestroyAccess,
+ RenderErrBase + BadPicture);
+
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->picture = pict->info[j].id;
+ result = (*PanoramiXSaveRenderVector[X_RenderFreePicture]) (client);
+ if(result != Success) break;
+ }
+
+ /* Since ProcRenderFreePicture is using FreeResource, it will free
+ our resource for us on the last pass through the loop above */
+
+ return (result);
+}
+
+static int
+PanoramiXRenderComposite (ClientPtr client)
+{
+ PanoramiXRes *src, *msk, *dst;
+ int result = Success, j;
+ xRenderCompositeReq orig;
+ REQUEST(xRenderCompositeReq);
+
+ REQUEST_SIZE_MATCH(xRenderCompositeReq);
+
+ VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_XIN_ALPHA (msk, stuff->mask, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ orig = *stuff;
+
+ FOR_NSCREENS_FORWARD(j) {
+ stuff->src = src->info[j].id;
+ if (src->u.pict.root)
+ {
+ stuff->xSrc = orig.xSrc - panoramiXdataPtr[j].x;
+ stuff->ySrc = orig.ySrc - panoramiXdataPtr[j].y;
+ }
+ stuff->dst = dst->info[j].id;
+ if (dst->u.pict.root)
+ {
+ stuff->xDst = orig.xDst - panoramiXdataPtr[j].x;
+ stuff->yDst = orig.yDst - panoramiXdataPtr[j].y;
+ }
+ if (msk)
+ {
+ stuff->mask = msk->info[j].id;
+ if (msk->u.pict.root)
+ {
+ stuff->xMask = orig.xMask - panoramiXdataPtr[j].x;
+ stuff->yMask = orig.yMask - panoramiXdataPtr[j].y;
+ }
+ }
+ result = (*PanoramiXSaveRenderVector[X_RenderComposite]) (client);
+ if(result != Success) break;
+ }
+
+ return result;
+}
+
+static int
+PanoramiXRenderCompositeGlyphs (ClientPtr client)
+{
+ PanoramiXRes *src, *dst;
+ int result = Success, j;
+ REQUEST(xRenderCompositeGlyphsReq);
+ xGlyphElt origElt, *elt;
+ INT16 xSrc, ySrc;
+
+ REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
+ VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ if (client->req_len << 2 >= (sizeof (xRenderCompositeGlyphsReq) +
+ sizeof (xGlyphElt)))
+ {
+ elt = (xGlyphElt *) (stuff + 1);
+ origElt = *elt;
+ xSrc = stuff->xSrc;
+ ySrc = stuff->ySrc;
+ FOR_NSCREENS_FORWARD(j) {
+ stuff->src = src->info[j].id;
+ if (src->u.pict.root)
+ {
+ stuff->xSrc = xSrc - panoramiXdataPtr[j].x;
+ stuff->ySrc = ySrc - panoramiXdataPtr[j].y;
+ }
+ stuff->dst = dst->info[j].id;
+ if (dst->u.pict.root)
+ {
+ elt->deltax = origElt.deltax - panoramiXdataPtr[j].x;
+ elt->deltay = origElt.deltay - panoramiXdataPtr[j].y;
+ }
+ result = (*PanoramiXSaveRenderVector[stuff->renderReqType]) (client);
+ if(result != Success) break;
+ }
+ }
+
+ return result;
+}
+
+static int
+PanoramiXRenderFillRectangles (ClientPtr client)
+{
+ PanoramiXRes *dst;
+ int result = Success, j;
+ REQUEST(xRenderFillRectanglesReq);
+ char *extra;
+ int extra_len;
+
+ REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ extra_len = (client->req_len << 2) - sizeof (xRenderFillRectanglesReq);
+ if (extra_len &&
+ (extra = (char *) ALLOCATE_LOCAL (extra_len)))
+ {
+ memcpy (extra, stuff + 1, extra_len);
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ if (dst->u.pict.root)
+ {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ xRectangle *rects = (xRectangle *) (stuff + 1);
+ int i = extra_len / sizeof (xRectangle);
+
+ while (i--)
+ {
+ rects->x -= x_off;
+ rects->y -= y_off;
+ rects++;
+ }
+ }
+ }
+ stuff->dst = dst->info[j].id;
+ result = (*PanoramiXSaveRenderVector[X_RenderFillRectangles]) (client);
+ if(result != Success) break;
+ }
+ DEALLOCATE_LOCAL(extra);
+ }
+
+ return result;
+}
+
+static int
+PanoramiXRenderTrapezoids(ClientPtr client)
+{
+ PanoramiXRes *src, *dst;
+ int result = Success, j;
+ REQUEST(xRenderTrapezoidsReq);
+ char *extra;
+ int extra_len;
+
+ REQUEST_AT_LEAST_SIZE (xRenderTrapezoidsReq);
+
+ VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ extra_len = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq);
+
+ if (extra_len &&
+ (extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+ memcpy (extra, stuff + 1, extra_len);
+
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ if (dst->u.pict.root) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ xTrapezoid *trap = (xTrapezoid *) (stuff + 1);
+ int i = extra_len / sizeof (xTrapezoid);
+
+ while (i--) {
+ trap->top -= y_off;
+ trap->bottom -= y_off;
+ trap->left.p1.x -= x_off;
+ trap->left.p1.y -= y_off;
+ trap->left.p2.x -= x_off;
+ trap->left.p2.y -= y_off;
+ trap->right.p1.x -= x_off;
+ trap->right.p1.y -= y_off;
+ trap->right.p2.x -= x_off;
+ trap->right.p2.y -= y_off;
+ trap++;
+ }
+ }
+ }
+
+ stuff->src = src->info[j].id;
+ stuff->dst = dst->info[j].id;
+ result =
+ (*PanoramiXSaveRenderVector[X_RenderTrapezoids]) (client);
+
+ if(result != Success) break;
+ }
+
+ DEALLOCATE_LOCAL(extra);
+ }
+
+ return result;
+}
+
+static int
+PanoramiXRenderTriangles(ClientPtr client)
+{
+ PanoramiXRes *src, *dst;
+ int result = Success, j;
+ REQUEST(xRenderTrianglesReq);
+ char *extra;
+ int extra_len;
+
+ REQUEST_AT_LEAST_SIZE (xRenderTrianglesReq);
+
+ VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ extra_len = (client->req_len << 2) - sizeof (xRenderTrianglesReq);
+
+ if (extra_len &&
+ (extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+ memcpy (extra, stuff + 1, extra_len);
+
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ if (dst->u.pict.root) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ xTriangle *tri = (xTriangle *) (stuff + 1);
+ int i = extra_len / sizeof (xTriangle);
+
+ while (i--) {
+ tri->p1.x -= x_off;
+ tri->p1.y -= y_off;
+ tri->p2.x -= x_off;
+ tri->p2.y -= y_off;
+ tri->p3.x -= x_off;
+ tri->p3.y -= y_off;
+ tri++;
+ }
+ }
+ }
+
+ stuff->src = src->info[j].id;
+ stuff->dst = dst->info[j].id;
+ result =
+ (*PanoramiXSaveRenderVector[X_RenderTriangles]) (client);
+
+ if(result != Success) break;
+ }
+
+ DEALLOCATE_LOCAL(extra);
+ }
+
+ return result;
+}
+
+static int
+PanoramiXRenderTriStrip(ClientPtr client)
+{
+ PanoramiXRes *src, *dst;
+ int result = Success, j;
+ REQUEST(xRenderTriStripReq);
+ char *extra;
+ int extra_len;
+
+ REQUEST_AT_LEAST_SIZE (xRenderTriStripReq);
+
+ VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ extra_len = (client->req_len << 2) - sizeof (xRenderTriStripReq);
+
+ if (extra_len &&
+ (extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+ memcpy (extra, stuff + 1, extra_len);
+
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ if (dst->u.pict.root) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ xPointFixed *fixed = (xPointFixed *) (stuff + 1);
+ int i = extra_len / sizeof (xPointFixed);
+
+ while (i--) {
+ fixed->x -= x_off;
+ fixed->y -= y_off;
+ fixed++;
+ }
+ }
+ }
+
+ stuff->src = src->info[j].id;
+ stuff->dst = dst->info[j].id;
+ result =
+ (*PanoramiXSaveRenderVector[X_RenderTriStrip]) (client);
+
+ if(result != Success) break;
+ }
+
+ DEALLOCATE_LOCAL(extra);
+ }
+
+ return result;
+}
+
+static int
+PanoramiXRenderTriFan(ClientPtr client)
+{
+ PanoramiXRes *src, *dst;
+ int result = Success, j;
+ REQUEST(xRenderTriFanReq);
+ char *extra;
+ int extra_len;
+
+ REQUEST_AT_LEAST_SIZE (xRenderTriFanReq);
+
+ VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ extra_len = (client->req_len << 2) - sizeof (xRenderTriFanReq);
+
+ if (extra_len &&
+ (extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+ memcpy (extra, stuff + 1, extra_len);
+
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ if (dst->u.pict.root) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ xPointFixed *fixed = (xPointFixed *) (stuff + 1);
+ int i = extra_len / sizeof (xPointFixed);
+
+ while (i--) {
+ fixed->x -= x_off;
+ fixed->y -= y_off;
+ fixed++;
+ }
+ }
+ }
+
+ stuff->src = src->info[j].id;
+ stuff->dst = dst->info[j].id;
+ result =
+ (*PanoramiXSaveRenderVector[X_RenderTriFan]) (client);
+
+ if(result != Success) break;
+ }
+
+ DEALLOCATE_LOCAL(extra);
+ }
+
+ return result;
+}
+
+#if 0 /* Not implemented yet */
+
+static int
+PanoramiXRenderColorTrapezoids(ClientPtr client)
+{
+ PanoramiXRes *src, *dst;
+ int result = Success, j;
+ REQUEST(xRenderColorTrapezoidsReq);
+ char *extra;
+ int extra_len;
+
+ REQUEST_AT_LEAST_SIZE (xRenderColorTrapezoidsReq);
+
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ extra_len = (client->req_len << 2) - sizeof (xRenderColorTrapezoidsReq);
+
+ if (extra_len &&
+ (extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+ memcpy (extra, stuff + 1, extra_len);
+
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ if (dst->u.pict.root) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ ....;
+ }
+ }
+
+ stuff->dst = dst->info[j].id;
+ result =
+ (*PanoramiXSaveRenderVector[X_RenderColorTrapezoids]) (client);
+
+ if(result != Success) break;
+ }
+
+ DEALLOCATE_LOCAL(extra);
+ }
+
+ return result;
+}
+
+static int
+PanoramiXRenderColorTriangles(ClientPtr client)
+{
+ PanoramiXRes *src, *dst;
+ int result = Success, j;
+ REQUEST(xRenderColorTrianglesReq);
+ char *extra;
+ int extra_len;
+
+ REQUEST_AT_LEAST_SIZE (xRenderColorTrianglesReq);
+
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ extra_len = (client->req_len << 2) - sizeof (xRenderColorTrianglesReq);
+
+ if (extra_len &&
+ (extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+ memcpy (extra, stuff + 1, extra_len);
+
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ if (dst->u.pict.root) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ ....;
+ }
+ }
+
+ stuff->dst = dst->info[j].id;
+ result =
+ (*PanoramiXSaveRenderVector[X_RenderColorTriangles]) (client);
+
+ if(result != Success) break;
+ }
+
+ DEALLOCATE_LOCAL(extra);
+ }
+
+ return result;
+}
+
+#endif
+
+static int
+PanoramiXRenderAddTraps (ClientPtr client)
+{
+ PanoramiXRes *picture;
+ int result = Success, j;
+ REQUEST(xRenderAddTrapsReq);
+ char *extra;
+ int extra_len;
+ INT16 x_off, y_off;
+
+ REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq);
+ VERIFY_XIN_PICTURE (picture, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ extra_len = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
+ if (extra_len &&
+ (extra = (char *) ALLOCATE_LOCAL (extra_len)))
+ {
+ memcpy (extra, stuff + 1, extra_len);
+ x_off = stuff->xOff;
+ y_off = stuff->yOff;
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ stuff->picture = picture->info[j].id;
+
+ if (picture->u.pict.root)
+ {
+ stuff->xOff = x_off + panoramiXdataPtr[j].x;
+ stuff->yOff = y_off + panoramiXdataPtr[j].y;
+ }
+ result = (*PanoramiXSaveRenderVector[X_RenderAddTraps]) (client);
+ if(result != Success) break;
+ }
+ DEALLOCATE_LOCAL(extra);
+ }
+
+ return result;
+}
+
+void
+PanoramiXRenderInit (void)
+{
+ int i;
+
+ XRT_PICTURE = CreateNewResourceType (XineramaDeleteResource);
+ for (i = 0; i < RenderNumberRequests; i++)
+ PanoramiXSaveRenderVector[i] = ProcRenderVector[i];
+ /*
+ * Stuff in Xinerama aware request processing hooks
+ */
+ ProcRenderVector[X_RenderCreatePicture] = PanoramiXRenderCreatePicture;
+ ProcRenderVector[X_RenderChangePicture] = PanoramiXRenderChangePicture;
+ ProcRenderVector[X_RenderSetPictureTransform] = PanoramiXRenderSetPictureTransform;
+ ProcRenderVector[X_RenderSetPictureFilter] = PanoramiXRenderSetPictureFilter;
+ ProcRenderVector[X_RenderSetPictureClipRectangles] = PanoramiXRenderSetPictureClipRectangles;
+ ProcRenderVector[X_RenderFreePicture] = PanoramiXRenderFreePicture;
+ ProcRenderVector[X_RenderComposite] = PanoramiXRenderComposite;
+ ProcRenderVector[X_RenderCompositeGlyphs8] = PanoramiXRenderCompositeGlyphs;
+ ProcRenderVector[X_RenderCompositeGlyphs16] = PanoramiXRenderCompositeGlyphs;
+ ProcRenderVector[X_RenderCompositeGlyphs32] = PanoramiXRenderCompositeGlyphs;
+ ProcRenderVector[X_RenderFillRectangles] = PanoramiXRenderFillRectangles;
+
+ ProcRenderVector[X_RenderTrapezoids] = PanoramiXRenderTrapezoids;
+ ProcRenderVector[X_RenderTriangles] = PanoramiXRenderTriangles;
+ ProcRenderVector[X_RenderTriStrip] = PanoramiXRenderTriStrip;
+ ProcRenderVector[X_RenderTriFan] = PanoramiXRenderTriFan;
+ ProcRenderVector[X_RenderAddTraps] = PanoramiXRenderAddTraps;
+}
+
+void
+PanoramiXRenderReset (void)
+{
+ int i;
+ for (i = 0; i < RenderNumberRequests; i++)
+ ProcRenderVector[i] = PanoramiXSaveRenderVector[i];
+}
+
+#endif /* PANORAMIX */
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
new file mode 100644
index 000000000..00c55cde7
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
@@ -0,0 +1,3799 @@
+/* $XdotOrg: xc/programs/Xserver/render/render.c,v 1.12 2005/08/28 19:47:39 ajax Exp $ */
+/*
+ * $XFree86: xc/programs/Xserver/render/render.c,v 1.27tsi Exp $
+ *
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+#define NEED_REPLIES
+#define NEED_EVENTS
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#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 "colormapst.h"
+#include "extnsionst.h"
+#include "servermd.h"
+#include <X11/extensions/render.h>
+#include <X11/extensions/renderproto.h>
+#include <X11/Xfuncproto.h>
+#include "cursorstr.h"
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#endif
+
+#if !defined(UINT32_MAX)
+#define UINT32_MAX 0xffffffffU
+#endif
+
+#include "NXpicturestr.h"
+#include "NXglyphstr.h"
+
+#include "Trap.h"
+
+#include "Render.h"
+#include "Pixmaps.h"
+#include "Options.h"
+#include "Screen.h"
+#include "Cursor.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+#ifdef TEST
+#include "Literals.h"
+#endif
+
+/*
+ * From NXmiglyph.c.
+ */
+
+void miGlyphExtents(int nlist, GlyphListPtr list,
+ GlyphPtr *glyphs, BoxPtr extents);
+
+/*
+ * From NXmitrap.c.
+ */
+
+void miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box);
+
+/*
+ * Functions from Render.c.
+ */
+
+int nxagentCursorSaveRenderInfo(ScreenPtr, CursorPtr);
+void nxagentCursorPostSaveRenderInfo(CursorPtr, ScreenPtr, PicturePtr, int, int);
+int nxagentRenderRealizeCursor(ScreenPtr, CursorPtr);
+int nxagentCreatePicture(PicturePtr, Mask);
+void nxagentDestroyPicture(PicturePtr pPicture);
+void nxagentChangePicture(PicturePtr, Mask);
+int nxagentChangePictureClip(PicturePtr, int, int, xRectangle *, int, int);
+void nxagentComposite(CARD8, PicturePtr, PicturePtr, PicturePtr, INT16, INT16,
+ INT16, INT16, INT16, INT16, CARD16, CARD16);
+void nxagentCompositeRects(CARD8, PicturePtr, xRenderColor *, int, xRectangle *);
+void nxagentCreateGlyphSet(GlyphSetPtr glyphSet);
+void nxagentReferenceGlyphSet(GlyphSetPtr glyphSet);
+void nxagentFreeGlyphs(GlyphSetPtr glyphSet, CARD32 *gids, int nglyph);
+void nxagentFreeGlyphSet(GlyphSetPtr glyphSet);
+void nxagentSetPictureTransform(PicturePtr pPicture, pointer transform);
+void nxagentSetPictureFilter(PicturePtr pPicture, char *filter, int name_size,
+ pointer params, int nparams);
+void nxagentTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat,
+ INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid *traps);
+
+/*
+ * The void pointer is actually a XGlyphElt8.
+ */
+
+void nxagentGlyphs(CARD8, PicturePtr, PicturePtr, PictFormatPtr,
+ INT16, INT16, int, void *, int, GlyphPtr *);
+
+static int ProcRenderQueryVersion (ClientPtr pClient);
+static int ProcRenderQueryPictFormats (ClientPtr pClient);
+static int ProcRenderQueryPictIndexValues (ClientPtr pClient);
+static int ProcRenderQueryDithers (ClientPtr pClient);
+static int ProcRenderCreatePicture (ClientPtr pClient);
+static int ProcRenderChangePicture (ClientPtr pClient);
+static int ProcRenderSetPictureClipRectangles (ClientPtr pClient);
+static int ProcRenderFreePicture (ClientPtr pClient);
+static int ProcRenderComposite (ClientPtr pClient);
+static int ProcRenderScale (ClientPtr pClient);
+static int ProcRenderTrapezoids (ClientPtr pClient);
+static int ProcRenderTriangles (ClientPtr pClient);
+static int ProcRenderTriStrip (ClientPtr pClient);
+static int ProcRenderTriFan (ClientPtr pClient);
+static int ProcRenderColorTrapezoids (ClientPtr pClient);
+static int ProcRenderColorTriangles (ClientPtr pClient);
+static int ProcRenderTransform (ClientPtr pClient);
+static int ProcRenderCreateGlyphSet (ClientPtr pClient);
+static int ProcRenderReferenceGlyphSet (ClientPtr pClient);
+static int ProcRenderFreeGlyphSet (ClientPtr pClient);
+static int ProcRenderAddGlyphs (ClientPtr pClient);
+static int ProcRenderAddGlyphsFromPicture (ClientPtr pClient);
+static int ProcRenderFreeGlyphs (ClientPtr pClient);
+static int ProcRenderCompositeGlyphs (ClientPtr pClient);
+static int ProcRenderFillRectangles (ClientPtr pClient);
+static int ProcRenderCreateCursor (ClientPtr pClient);
+static int ProcRenderSetPictureTransform (ClientPtr pClient);
+static int ProcRenderQueryFilters (ClientPtr pClient);
+static int ProcRenderSetPictureFilter (ClientPtr pClient);
+static int ProcRenderCreateAnimCursor (ClientPtr pClient);
+static int ProcRenderAddTraps (ClientPtr pClient);
+static int ProcRenderCreateSolidFill (ClientPtr pClient);
+static int ProcRenderCreateLinearGradient (ClientPtr pClient);
+static int ProcRenderCreateRadialGradient (ClientPtr pClient);
+static int ProcRenderCreateConicalGradient (ClientPtr pClient);
+
+static int ProcRenderDispatch (ClientPtr pClient);
+
+static int SProcRenderQueryVersion (ClientPtr pClient);
+static int SProcRenderQueryPictFormats (ClientPtr pClient);
+static int SProcRenderQueryPictIndexValues (ClientPtr pClient);
+static int SProcRenderQueryDithers (ClientPtr pClient);
+static int SProcRenderCreatePicture (ClientPtr pClient);
+static int SProcRenderChangePicture (ClientPtr pClient);
+static int SProcRenderSetPictureClipRectangles (ClientPtr pClient);
+static int SProcRenderFreePicture (ClientPtr pClient);
+static int SProcRenderComposite (ClientPtr pClient);
+static int SProcRenderScale (ClientPtr pClient);
+static int SProcRenderTrapezoids (ClientPtr pClient);
+static int SProcRenderTriangles (ClientPtr pClient);
+static int SProcRenderTriStrip (ClientPtr pClient);
+static int SProcRenderTriFan (ClientPtr pClient);
+static int SProcRenderColorTrapezoids (ClientPtr pClient);
+static int SProcRenderColorTriangles (ClientPtr pClient);
+static int SProcRenderTransform (ClientPtr pClient);
+static int SProcRenderCreateGlyphSet (ClientPtr pClient);
+static int SProcRenderReferenceGlyphSet (ClientPtr pClient);
+static int SProcRenderFreeGlyphSet (ClientPtr pClient);
+static int SProcRenderAddGlyphs (ClientPtr pClient);
+static int SProcRenderAddGlyphsFromPicture (ClientPtr pClient);
+static int SProcRenderFreeGlyphs (ClientPtr pClient);
+static int SProcRenderCompositeGlyphs (ClientPtr pClient);
+static int SProcRenderFillRectangles (ClientPtr pClient);
+static int SProcRenderCreateCursor (ClientPtr pClient);
+static int SProcRenderSetPictureTransform (ClientPtr pClient);
+static int SProcRenderQueryFilters (ClientPtr pClient);
+static int SProcRenderSetPictureFilter (ClientPtr pClient);
+static int SProcRenderCreateAnimCursor (ClientPtr pClient);
+static int SProcRenderAddTraps (ClientPtr pClient);
+static int SProcRenderCreateSolidFill (ClientPtr pClient);
+static int SProcRenderCreateLinearGradient (ClientPtr pClient);
+static int SProcRenderCreateRadialGradient (ClientPtr pClient);
+static int SProcRenderCreateConicalGradient (ClientPtr pClient);
+
+static int SProcRenderDispatch (ClientPtr pClient);
+
+int (*ProcRenderVector[RenderNumberRequests])(ClientPtr) = {
+ ProcRenderQueryVersion,
+ ProcRenderQueryPictFormats,
+ ProcRenderQueryPictIndexValues,
+ ProcRenderQueryDithers,
+ ProcRenderCreatePicture,
+ ProcRenderChangePicture,
+ ProcRenderSetPictureClipRectangles,
+ ProcRenderFreePicture,
+ ProcRenderComposite,
+ ProcRenderScale,
+ ProcRenderTrapezoids,
+ ProcRenderTriangles,
+ ProcRenderTriStrip,
+ ProcRenderTriFan,
+ ProcRenderColorTrapezoids,
+ ProcRenderColorTriangles,
+ ProcRenderTransform,
+ ProcRenderCreateGlyphSet,
+ ProcRenderReferenceGlyphSet,
+ ProcRenderFreeGlyphSet,
+ ProcRenderAddGlyphs,
+ ProcRenderAddGlyphsFromPicture,
+ ProcRenderFreeGlyphs,
+ ProcRenderCompositeGlyphs,
+ ProcRenderCompositeGlyphs,
+ ProcRenderCompositeGlyphs,
+ ProcRenderFillRectangles,
+ ProcRenderCreateCursor,
+ ProcRenderSetPictureTransform,
+ ProcRenderQueryFilters,
+ ProcRenderSetPictureFilter,
+ ProcRenderCreateAnimCursor,
+ ProcRenderAddTraps,
+ ProcRenderCreateSolidFill,
+ ProcRenderCreateLinearGradient,
+ ProcRenderCreateRadialGradient,
+ ProcRenderCreateConicalGradient
+};
+
+int (*SProcRenderVector[RenderNumberRequests])(ClientPtr) = {
+ SProcRenderQueryVersion,
+ SProcRenderQueryPictFormats,
+ SProcRenderQueryPictIndexValues,
+ SProcRenderQueryDithers,
+ SProcRenderCreatePicture,
+ SProcRenderChangePicture,
+ SProcRenderSetPictureClipRectangles,
+ SProcRenderFreePicture,
+ SProcRenderComposite,
+ SProcRenderScale,
+ SProcRenderTrapezoids,
+ SProcRenderTriangles,
+ SProcRenderTriStrip,
+ SProcRenderTriFan,
+ SProcRenderColorTrapezoids,
+ SProcRenderColorTriangles,
+ SProcRenderTransform,
+ SProcRenderCreateGlyphSet,
+ SProcRenderReferenceGlyphSet,
+ SProcRenderFreeGlyphSet,
+ SProcRenderAddGlyphs,
+ SProcRenderAddGlyphsFromPicture,
+ SProcRenderFreeGlyphs,
+ SProcRenderCompositeGlyphs,
+ SProcRenderCompositeGlyphs,
+ SProcRenderCompositeGlyphs,
+ SProcRenderFillRectangles,
+ SProcRenderCreateCursor,
+ SProcRenderSetPictureTransform,
+ SProcRenderQueryFilters,
+ SProcRenderSetPictureFilter,
+ SProcRenderCreateAnimCursor,
+ SProcRenderAddTraps,
+ SProcRenderCreateSolidFill,
+ SProcRenderCreateLinearGradient,
+ SProcRenderCreateRadialGradient,
+ SProcRenderCreateConicalGradient
+};
+
+static void
+RenderResetProc (ExtensionEntry *extEntry);
+
+#if 0
+static CARD8 RenderReqCode;
+#endif
+int RenderErrBase;
+int RenderClientPrivateIndex;
+
+typedef struct _RenderClient {
+ int major_version;
+ int minor_version;
+} RenderClientRec, *RenderClientPtr;
+
+#define GetRenderClient(pClient) ((RenderClientPtr) (pClient)->devPrivates[RenderClientPrivateIndex].ptr)
+
+static void
+RenderClientCallback (CallbackListPtr *list,
+ pointer closure,
+ pointer data)
+{
+ NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
+ ClientPtr pClient = clientinfo->client;
+ RenderClientPtr pRenderClient = GetRenderClient (pClient);
+
+ pRenderClient->major_version = 0;
+ pRenderClient->minor_version = 0;
+}
+
+void
+RenderExtensionInit (void)
+{
+ ExtensionEntry *extEntry;
+
+ if (!PictureType)
+ return;
+ if (!PictureFinishInit ())
+ return;
+ RenderClientPrivateIndex = AllocateClientPrivateIndex ();
+ if (!AllocateClientPrivate (RenderClientPrivateIndex,
+ sizeof (RenderClientRec)))
+ return;
+ if (!AddCallback (&ClientStateCallback, RenderClientCallback, 0))
+ return;
+
+ extEntry = AddExtension (RENDER_NAME, 0, RenderNumberErrors,
+ ProcRenderDispatch, SProcRenderDispatch,
+ RenderResetProc, StandardMinorOpcode);
+ if (!extEntry)
+ return;
+#if 0
+ RenderReqCode = (CARD8) extEntry->base;
+#endif
+ RenderErrBase = extEntry->errorBase;
+}
+
+static void
+RenderResetProc (ExtensionEntry *extEntry)
+{
+ ResetPicturePrivateIndex();
+ ResetGlyphSetPrivateIndex();
+}
+
+static int
+ProcRenderQueryVersion (ClientPtr client)
+{
+ RenderClientPtr pRenderClient = GetRenderClient (client);
+ xRenderQueryVersionReply rep;
+ register int n;
+ REQUEST(xRenderQueryVersionReq);
+
+ pRenderClient->major_version = stuff->majorVersion;
+ pRenderClient->minor_version = stuff->minorVersion;
+
+ REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = nxagentRenderVersionMajor;
+ rep.minorVersion = nxagentRenderVersionMinor;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.majorVersion, n);
+ swapl(&rep.minorVersion, n);
+ }
+ WriteToClient(client, sizeof(xRenderQueryVersionReply), (char *)&rep);
+ return (client->noClientException);
+}
+
+#if 0
+static int
+VisualDepth (ScreenPtr pScreen, VisualPtr pVisual)
+{
+ DepthPtr pDepth;
+ int d, v;
+
+ for (d = 0; d < pScreen->numDepths; d++)
+ {
+ pDepth = pScreen->allowedDepths + d;
+ for (v = 0; v < pDepth->numVids; v++)
+ {
+ if (pDepth->vids[v] == pVisual->vid)
+ return pDepth->depth;
+ }
+ }
+ return 0;
+}
+#endif
+
+static VisualPtr
+findVisual (ScreenPtr pScreen, VisualID vid)
+{
+ VisualPtr pVisual;
+ int v;
+
+ for (v = 0; v < pScreen->numVisuals; v++)
+ {
+ pVisual = pScreen->visuals + v;
+ if (pVisual->vid == vid)
+ return pVisual;
+ }
+ return 0;
+}
+
+extern char *ConnectionInfo;
+
+static int
+ProcRenderQueryPictFormats (ClientPtr client)
+{
+ RenderClientPtr pRenderClient = GetRenderClient (client);
+ xRenderQueryPictFormatsReply *reply;
+ xPictScreen *pictScreen;
+ xPictDepth *pictDepth;
+ xPictVisual *pictVisual;
+ xPictFormInfo *pictForm;
+ CARD32 *pictSubpixel;
+ ScreenPtr pScreen;
+ VisualPtr pVisual;
+ DepthPtr pDepth;
+ int v, d;
+ PictureScreenPtr ps;
+ PictFormatPtr pFormat;
+ int nformat;
+ int ndepth;
+ int nvisual;
+ int rlength;
+ int s;
+ int n;
+ int numScreens;
+ int numSubpixel;
+
+ extern int nxagentAlphaEnabled;
+/* REQUEST(xRenderQueryPictFormatsReq); */
+
+ REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
+
+#ifdef PANORAMIX
+ if (noPanoramiXExtension)
+ numScreens = screenInfo.numScreens;
+ else
+ numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
+#else
+ numScreens = screenInfo.numScreens;
+#endif
+ ndepth = nformat = nvisual = 0;
+ for (s = 0; s < numScreens; s++)
+ {
+ pScreen = screenInfo.screens[s];
+ for (d = 0; d < pScreen->numDepths; d++)
+ {
+ pDepth = pScreen->allowedDepths + d;
+ ++ndepth;
+
+ for (v = 0; v < pDepth->numVids; v++)
+ {
+ pVisual = findVisual (pScreen, pDepth->vids[v]);
+ if (pVisual && PictureMatchVisual (pScreen, pDepth->depth, pVisual))
+ ++nvisual;
+ }
+ }
+ ps = GetPictureScreenIfSet(pScreen);
+ if (ps)
+ nformat += ps->nformats;
+ }
+ if (pRenderClient->major_version == 0 && pRenderClient->minor_version < 6)
+ numSubpixel = 0;
+ else
+ numSubpixel = numScreens;
+
+ rlength = (sizeof (xRenderQueryPictFormatsReply) +
+ nformat * sizeof (xPictFormInfo) +
+ numScreens * sizeof (xPictScreen) +
+ ndepth * sizeof (xPictDepth) +
+ nvisual * sizeof (xPictVisual) +
+ numSubpixel * sizeof (CARD32));
+ reply = (xRenderQueryPictFormatsReply *) xalloc (rlength);
+ if (!reply)
+ return BadAlloc;
+ reply->type = X_Reply;
+ reply->sequenceNumber = client->sequence;
+ reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+ reply->numFormats = nformat;
+ reply->numScreens = numScreens;
+ reply->numDepths = ndepth;
+ reply->numVisuals = nvisual;
+ reply->numSubpixel = numSubpixel;
+
+ pictForm = (xPictFormInfo *) (reply + 1);
+
+ for (s = 0; s < numScreens; s++)
+ {
+ pScreen = screenInfo.screens[s];
+ ps = GetPictureScreenIfSet(pScreen);
+ if (ps)
+ {
+ for (nformat = 0, pFormat = ps->formats;
+ nformat < ps->nformats;
+ nformat++, pFormat++)
+ {
+ pictForm->id = pFormat->id;
+ pictForm->type = pFormat->type;
+ pictForm->depth = pFormat->depth;
+ pictForm->direct.red = pFormat->direct.red;
+ pictForm->direct.redMask = pFormat->direct.redMask;
+ pictForm->direct.green = pFormat->direct.green;
+ pictForm->direct.greenMask = pFormat->direct.greenMask;
+ pictForm->direct.blue = pFormat->direct.blue;
+ pictForm->direct.blueMask = pFormat->direct.blueMask;
+ pictForm->direct.alpha = nxagentAlphaEnabled ? pFormat->direct.alpha : 0;
+ pictForm->direct.alphaMask = pFormat->direct.alphaMask;
+ if (pFormat->type == PictTypeIndexed && pFormat->index.pColormap)
+ pictForm->colormap = pFormat->index.pColormap->mid;
+ else
+ pictForm->colormap = None;
+ if (client->swapped)
+ {
+ swapl (&pictForm->id, n);
+ swaps (&pictForm->direct.red, n);
+ swaps (&pictForm->direct.redMask, n);
+ swaps (&pictForm->direct.green, n);
+ swaps (&pictForm->direct.greenMask, n);
+ swaps (&pictForm->direct.blue, n);
+ swaps (&pictForm->direct.blueMask, n);
+ swaps (&pictForm->direct.alpha, n);
+ swaps (&pictForm->direct.alphaMask, n);
+ swapl (&pictForm->colormap, n);
+ }
+ pictForm++;
+ }
+ }
+ }
+
+ pictScreen = (xPictScreen *) pictForm;
+ for (s = 0; s < numScreens; s++)
+ {
+ pScreen = screenInfo.screens[s];
+ pictDepth = (xPictDepth *) (pictScreen + 1);
+ ndepth = 0;
+ for (d = 0; d < pScreen->numDepths; d++)
+ {
+ pictVisual = (xPictVisual *) (pictDepth + 1);
+ pDepth = pScreen->allowedDepths + d;
+
+ nvisual = 0;
+ for (v = 0; v < pDepth->numVids; v++)
+ {
+ pVisual = findVisual (pScreen, pDepth->vids[v]);
+ if (pVisual && (pFormat = PictureMatchVisual (pScreen,
+ pDepth->depth,
+ pVisual)))
+ {
+ pictVisual->visual = pVisual->vid;
+ pictVisual->format = pFormat->id;
+ if (client->swapped)
+ {
+ swapl (&pictVisual->visual, n);
+ swapl (&pictVisual->format, n);
+ }
+ pictVisual++;
+ nvisual++;
+ }
+ }
+ pictDepth->depth = pDepth->depth;
+ pictDepth->nPictVisuals = nvisual;
+ if (client->swapped)
+ {
+ swaps (&pictDepth->nPictVisuals, n);
+ }
+ ndepth++;
+ pictDepth = (xPictDepth *) pictVisual;
+ }
+ pictScreen->nDepth = ndepth;
+ ps = GetPictureScreenIfSet(pScreen);
+ if (ps)
+ pictScreen->fallback = ps->fallback->id;
+ else
+ pictScreen->fallback = 0;
+ if (client->swapped)
+ {
+ swapl (&pictScreen->nDepth, n);
+ swapl (&pictScreen->fallback, n);
+ }
+ pictScreen = (xPictScreen *) pictDepth;
+ }
+ pictSubpixel = (CARD32 *) pictScreen;
+
+ for (s = 0; s < numSubpixel; s++)
+ {
+ pScreen = screenInfo.screens[s];
+ ps = GetPictureScreenIfSet(pScreen);
+ if (ps)
+ *pictSubpixel = ps->subpixel;
+ else
+ *pictSubpixel = SubPixelUnknown;
+ if (client->swapped)
+ {
+ swapl (pictSubpixel, n);
+ }
+ ++pictSubpixel;
+ }
+
+ if (client->swapped)
+ {
+ swaps (&reply->sequenceNumber, n);
+ swapl (&reply->length, n);
+ swapl (&reply->numFormats, n);
+ swapl (&reply->numScreens, n);
+ swapl (&reply->numDepths, n);
+ swapl (&reply->numVisuals, n);
+ swapl (&reply->numSubpixel, n);
+ }
+ WriteToClient(client, rlength, (char *) reply);
+ xfree (reply);
+ return client->noClientException;
+}
+
+static int
+ProcRenderQueryPictIndexValues (ClientPtr client)
+{
+ PictFormatPtr pFormat;
+ int num;
+ int rlength;
+ int i, n;
+ REQUEST(xRenderQueryPictIndexValuesReq);
+ xRenderQueryPictIndexValuesReply *reply;
+ xIndexValue *values;
+
+ REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq);
+
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->format,
+ PictFormatType,
+ SecurityReadAccess);
+
+ if (!pFormat)
+ {
+ client->errorValue = stuff->format;
+ return RenderErrBase + BadPictFormat;
+ }
+ if (pFormat->type != PictTypeIndexed)
+ {
+ client->errorValue = stuff->format;
+ return BadMatch;
+ }
+ num = pFormat->index.nvalues;
+ rlength = (sizeof (xRenderQueryPictIndexValuesReply) +
+ num * sizeof(xIndexValue));
+ reply = (xRenderQueryPictIndexValuesReply *) xalloc (rlength);
+ if (!reply)
+ return BadAlloc;
+
+ reply->type = X_Reply;
+ reply->sequenceNumber = client->sequence;
+ reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+ reply->numIndexValues = num;
+
+ values = (xIndexValue *) (reply + 1);
+
+ memcpy (reply + 1, pFormat->index.pValues, num * sizeof (xIndexValue));
+
+ if (client->swapped)
+ {
+ for (i = 0; i < num; i++)
+ {
+ swapl (&values[i].pixel, n);
+ swaps (&values[i].red, n);
+ swaps (&values[i].green, n);
+ swaps (&values[i].blue, n);
+ swaps (&values[i].alpha, n);
+ }
+ swaps (&reply->sequenceNumber, n);
+ swapl (&reply->length, n);
+ swapl (&reply->numIndexValues, n);
+ }
+
+ WriteToClient(client, rlength, (char *) reply);
+ xfree(reply);
+ return (client->noClientException);
+}
+
+static int
+ProcRenderQueryDithers (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+ProcRenderCreatePicture (ClientPtr client)
+{
+ PicturePtr pPicture;
+ DrawablePtr pDrawable;
+ PictFormatPtr pFormat;
+ int len;
+ int error;
+ REQUEST(xRenderCreatePictureReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
+
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+ SECURITY_VERIFY_DRAWABLE(pDrawable, stuff->drawable, client,
+ SecurityWriteAccess);
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->format,
+ PictFormatType,
+ SecurityReadAccess);
+ if (!pFormat)
+ {
+ client->errorValue = stuff->format;
+ return RenderErrBase + BadPictFormat;
+ }
+ if (pFormat->depth != pDrawable->depth)
+ return BadMatch;
+ len = client->req_len - (sizeof(xRenderCreatePictureReq) >> 2);
+ if (Ones(stuff->mask) != len)
+ return BadLength;
+
+ pPicture = CreatePicture (stuff->pid,
+ pDrawable,
+ pFormat,
+ stuff->mask,
+ (XID *) (stuff + 1),
+ client,
+ &error);
+ if (!pPicture)
+ return error;
+ nxagentCreatePicture(pPicture, stuff -> mask);
+
+ if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+ return BadAlloc;
+ return Success;
+}
+
+static int
+ProcRenderChangePicture (ClientPtr client)
+{
+ PicturePtr pPicture;
+ REQUEST(xRenderChangePictureReq);
+ int len;
+ int error;
+
+ REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
+ VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ len = client->req_len - (sizeof(xRenderChangePictureReq) >> 2);
+ if (Ones(stuff->mask) != len)
+ return BadLength;
+
+ error = ChangePicture (pPicture, stuff->mask, (XID *) (stuff + 1),
+ (DevUnion *) 0, client);
+
+ nxagentChangePicture(pPicture, stuff->mask);
+
+ return error;
+}
+
+static int
+ProcRenderSetPictureClipRectangles (ClientPtr client)
+{
+ REQUEST(xRenderSetPictureClipRectanglesReq);
+ PicturePtr pPicture;
+ int nr;
+ int result;
+
+ REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
+ VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pPicture->pDrawable)
+ return BadDrawable;
+
+ /*
+ * The original code used sizeof(xRenderChangePictureReq).
+ * This was harmless, as both structures have the same size.
+ *
+ * nr = (client->req_len << 2) - sizeof(xRenderChangePictureReq);
+ */
+ nr = (client->req_len << 2) - sizeof(xRenderSetPictureClipRectanglesReq);
+ if (nr & 4)
+ return BadLength;
+ nr >>= 3;
+ result = SetPictureClipRects (pPicture,
+ stuff->xOrigin, stuff->yOrigin,
+ nr, (xRectangle *) &stuff[1]);
+ nxagentChangePictureClip (pPicture,
+ CT_NONE,
+ nr,
+ (xRectangle *) &stuff[1],
+ (int)stuff -> xOrigin,
+ (int)stuff -> yOrigin);
+
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+static int
+ProcRenderFreePicture (ClientPtr client)
+{
+ PicturePtr pPicture;
+ REQUEST(xRenderFreePictureReq);
+
+ REQUEST_SIZE_MATCH(xRenderFreePictureReq);
+
+ VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityDestroyAccess,
+ RenderErrBase + BadPicture);
+
+ nxagentDestroyPicture(pPicture);
+
+ FreeResource (stuff->picture, RT_NONE);
+ return(client->noClientException);
+}
+
+static Bool
+PictOpValid (CARD8 op)
+{
+ if (/*PictOpMinimum <= op && */ op <= PictOpMaximum)
+ return TRUE;
+ if (PictOpDisjointMinimum <= op && op <= PictOpDisjointMaximum)
+ return TRUE;
+ if (PictOpConjointMinimum <= op && op <= PictOpConjointMaximum)
+ return TRUE;
+ return FALSE;
+}
+
+/*
+ * Check if both pictures have drawables which are
+ * virtual pixmaps. See the corresponding define
+ * in NXpicture.c
+ */
+
+#define NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+#ifdef NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+#define nxagentCompositePredicate(pSrc, pDst) TRUE
+
+#else
+
+/*
+ * This is still under development. The final
+ * goal is to let pictures point to the real
+ * pixmaps instead of pointing to virtuals.
+ */
+
+int nxagentCompositePredicate(PicturePtr pSrc, PicturePtr pDst)
+{
+ PixmapPtr pPixmap1;
+ PixmapPtr pPixmap2;
+
+ pPixmap1 = (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP ?
+ ((PixmapPtr) pSrc -> pDrawable) : NULL);
+
+ pPixmap2 = (pDst -> pDrawable -> type == DRAWABLE_PIXMAP ?
+ ((PixmapPtr) pDst -> pDrawable) : NULL);
+
+ if (pPixmap1 == NULL || pPixmap2 == NULL)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCompositePredicate: Case 0.\n");
+ #endif
+
+ return FALSE;
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCompositePredicate: Case 1.\n");
+ #endif
+
+ if (nxagentPixmapIsVirtual(pPixmap1) == 1 &&
+ nxagentPixmapIsVirtual(pPixmap2) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCompositePredicate: Case 2.\n");
+ #endif
+
+ return TRUE;
+ }
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCompositePredicate: Case 3.\n");
+ #endif
+
+ return FALSE;
+}
+
+#endif
+
+static int
+ProcRenderComposite (ClientPtr client)
+{
+ PicturePtr pSrc, pMask, pDst;
+ REQUEST(xRenderCompositeReq);
+
+ REQUEST_SIZE_MATCH(xRenderCompositeReq);
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_ALPHA (pMask, stuff->mask, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) ||
+ (pMask && pMask->pDrawable && pSrc->pDrawable->pScreen != pMask->pDrawable->pScreen))
+ return BadMatch;
+
+ ValidatePicture (pSrc);
+ if (pMask)
+ ValidatePicture (pMask);
+ ValidatePicture (pDst);
+
+ #ifdef NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+ if (nxagentCompositePredicate(pSrc, pDst))
+ {
+ #ifdef TEST
+ fprintf(stderr, "ProcRenderComposite: Going to composite with "
+ "source at [%p] mask at [%p] and destination at [%p].\n",
+ (void *) pSrc, (void *) pMask, (void *) pDst);
+ #endif
+
+ CompositePicture (stuff->op,
+ pSrc,
+ pMask,
+ pDst,
+ stuff->xSrc,
+ stuff->ySrc,
+ stuff->xMask,
+ stuff->yMask,
+ stuff->xDst,
+ stuff->yDst,
+ stuff->width,
+ stuff->height);
+ }
+
+ #else
+
+ if (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP &&
+ pDst -> pDrawable -> type == DRAWABLE_PIXMAP &&
+ (!pMask || pMask -> pDrawable -> type == DRAWABLE_PIXMAP))
+ {
+ PixmapPtr pVirtualPixmapSrc;
+ PixmapPtr pVirtualPixmapDst;
+ PixmapPtr pVirtualPixmapMask;
+
+ PicturePtr pVirtualPictureSrc;
+ PicturePtr pVirtualPictureDst;
+ PicturePtr pVirtualPictureMask;
+
+ pVirtualPixmapSrc = (PixmapPtr) pSrc -> pDrawable;
+ pVirtualPictureSrc = nxagentPixmapPriv(pVirtualPixmapSrc) -> pPicture;
+
+ pVirtualPixmapDst = (PixmapPtr) pDst -> pDrawable;
+ pVirtualPictureDst = nxagentPixmapPriv(pVirtualPixmapDst) -> pPicture;
+
+ if (pMask)
+ {
+ pVirtualPixmapMask = (PixmapPtr) pMask -> pDrawable;
+ pVirtualPictureMask = nxagentPixmapPriv(pVirtualPixmapMask) -> pPicture;
+ }
+ else
+ {
+ pVirtualPixmapMask = NULL;
+ pVirtualPictureMask = NULL;
+ }
+
+ if (pVirtualPictureSrc && pVirtualPictureDst)
+ {
+ #ifdef TEST
+ fprintf(stderr, "ProcRenderComposite: Going to composite with "
+ "source at [%p] mask at [%p] and destination at [%p].\n",
+ (void *) pVirtualPixmapSrc, (void *) pVirtualPixmapMask,
+ (void *) pVirtualPixmapDst);
+ #endif
+
+ CompositePicture (stuff->op,
+ pVirtualPictureSrc,
+ pVirtualPictureMask,
+ pVirtualPictureDst,
+ stuff->xSrc,
+ stuff->ySrc,
+ stuff->xMask,
+ stuff->yMask,
+ stuff->xDst,
+ stuff->yDst,
+ stuff->width,
+ stuff->height);
+ }
+ }
+
+ #endif
+
+ nxagentComposite (stuff -> op,
+ pSrc,
+ pMask,
+ pDst,
+ stuff -> xSrc,
+ stuff -> ySrc,
+ stuff -> xMask,
+ stuff -> yMask,
+ stuff -> xDst,
+ stuff -> yDst,
+ stuff -> width,
+ stuff -> height);
+
+ return Success;
+}
+
+static int
+ProcRenderScale (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+ProcRenderTrapezoids (ClientPtr client)
+{
+ int ntraps;
+ PicturePtr pSrc, pDst;
+ PictFormatPtr pFormat;
+ REQUEST(xRenderTrapezoidsReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+ return BadMatch;
+ if (stuff->maskFormat)
+ {
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->maskFormat,
+ PictFormatType,
+ SecurityReadAccess);
+ if (!pFormat)
+ {
+ client->errorValue = stuff->maskFormat;
+ return RenderErrBase + BadPictFormat;
+ }
+ }
+ else
+ pFormat = 0;
+ ntraps = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq);
+ if (ntraps % sizeof (xTrapezoid))
+ return BadLength;
+ ntraps /= sizeof (xTrapezoid);
+ if (ntraps)
+ {
+ if (pFormat != NULL)
+ {
+ nxagentTrapezoidExtents = (BoxPtr) xalloc(sizeof(BoxRec));
+
+ miTrapezoidBounds (ntraps, (xTrapezoid *) &stuff[1], nxagentTrapezoidExtents);
+ }
+
+ if (nxagentCompositePredicate(pSrc, pDst) == 1)
+ {
+ CompositeTrapezoids (stuff->op, pSrc, pDst, pFormat,
+ stuff->xSrc, stuff->ySrc,
+ ntraps, (xTrapezoid *) &stuff[1]);
+ }
+
+ nxagentTrapezoids (stuff->op, pSrc, pDst, pFormat,
+ stuff->xSrc, stuff->ySrc,
+ ntraps, (xTrapezoid *) &stuff[1]);
+
+ if (nxagentTrapezoidExtents != NullBox)
+ {
+ xfree(nxagentTrapezoidExtents);
+
+ nxagentTrapezoidExtents = NullBox;
+ }
+ }
+
+ return client->noClientException;
+}
+
+static int
+ProcRenderTriangles (ClientPtr client)
+{
+ int ntris;
+ PicturePtr pSrc, pDst;
+ PictFormatPtr pFormat;
+ REQUEST(xRenderTrianglesReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+ return BadMatch;
+ if (stuff->maskFormat)
+ {
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->maskFormat,
+ PictFormatType,
+ SecurityReadAccess);
+ if (!pFormat)
+ {
+ client->errorValue = stuff->maskFormat;
+ return RenderErrBase + BadPictFormat;
+ }
+ }
+ else
+ pFormat = 0;
+ ntris = (client->req_len << 2) - sizeof (xRenderTrianglesReq);
+ if (ntris % sizeof (xTriangle))
+ return BadLength;
+ ntris /= sizeof (xTriangle);
+ if (ntris)
+ CompositeTriangles (stuff->op, pSrc, pDst, pFormat,
+ stuff->xSrc, stuff->ySrc,
+ ntris, (xTriangle *) &stuff[1]);
+ return client->noClientException;
+}
+
+static int
+ProcRenderTriStrip (ClientPtr client)
+{
+ int npoints;
+ PicturePtr pSrc, pDst;
+ PictFormatPtr pFormat;
+ REQUEST(xRenderTrianglesReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+ return BadMatch;
+ if (stuff->maskFormat)
+ {
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->maskFormat,
+ PictFormatType,
+ SecurityReadAccess);
+ if (!pFormat)
+ {
+ client->errorValue = stuff->maskFormat;
+ return RenderErrBase + BadPictFormat;
+ }
+ }
+ else
+ pFormat = 0;
+ npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq));
+ if (npoints & 4)
+ return(BadLength);
+ npoints >>= 3;
+ if (npoints >= 3)
+ CompositeTriStrip (stuff->op, pSrc, pDst, pFormat,
+ stuff->xSrc, stuff->ySrc,
+ npoints, (xPointFixed *) &stuff[1]);
+ return client->noClientException;
+}
+
+static int
+ProcRenderTriFan (ClientPtr client)
+{
+ int npoints;
+ PicturePtr pSrc, pDst;
+ PictFormatPtr pFormat;
+ REQUEST(xRenderTrianglesReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+ return BadMatch;
+ if (stuff->maskFormat)
+ {
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->maskFormat,
+ PictFormatType,
+ SecurityReadAccess);
+ if (!pFormat)
+ {
+ client->errorValue = stuff->maskFormat;
+ return RenderErrBase + BadPictFormat;
+ }
+ }
+ else
+ pFormat = 0;
+ npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq));
+ if (npoints & 4)
+ return(BadLength);
+ npoints >>= 3;
+ if (npoints >= 3)
+ CompositeTriFan (stuff->op, pSrc, pDst, pFormat,
+ stuff->xSrc, stuff->ySrc,
+ npoints, (xPointFixed *) &stuff[1]);
+ return client->noClientException;
+}
+
+static int
+ProcRenderColorTrapezoids (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+ProcRenderColorTriangles (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+ProcRenderTransform (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+ProcRenderCreateGlyphSet (ClientPtr client)
+{
+ GlyphSetPtr glyphSet;
+ PictFormatPtr format;
+ int f;
+ REQUEST(xRenderCreateGlyphSetReq);
+
+ REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
+
+ LEGAL_NEW_RESOURCE(stuff->gsid, client);
+ format = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->format,
+ PictFormatType,
+ SecurityReadAccess);
+ if (!format)
+ {
+ client->errorValue = stuff->format;
+ return RenderErrBase + BadPictFormat;
+ }
+ switch (format->depth) {
+ case 1:
+ f = GlyphFormat1;
+ break;
+ case 4:
+ f = GlyphFormat4;
+ break;
+ case 8:
+ f = GlyphFormat8;
+ break;
+ case 16:
+ f = GlyphFormat16;
+ break;
+ case 32:
+ f = GlyphFormat32;
+ break;
+ default:
+ return BadMatch;
+ }
+ if (format->type != PictTypeDirect)
+ return BadMatch;
+ glyphSet = AllocateGlyphSet (f, format);
+ if (!glyphSet)
+ return BadAlloc;
+ if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
+ return BadAlloc;
+
+ nxagentCreateGlyphSet(glyphSet);
+
+ return Success;
+}
+
+static int
+ProcRenderReferenceGlyphSet (ClientPtr client)
+{
+ GlyphSetPtr glyphSet;
+ REQUEST(xRenderReferenceGlyphSetReq);
+
+ REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);
+
+ LEGAL_NEW_RESOURCE(stuff->gsid, client);
+
+ glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ stuff->existing,
+ GlyphSetType,
+ SecurityWriteAccess);
+ if (!glyphSet)
+ {
+ client->errorValue = stuff->existing;
+ return RenderErrBase + BadGlyphSet;
+ }
+ glyphSet->refcnt++;
+
+ nxagentReferenceGlyphSet(glyphSet);
+
+ if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
+ return BadAlloc;
+ return client->noClientException;
+}
+
+#define NLOCALDELTA 64
+#define NLOCALGLYPH 256
+
+static int
+ProcRenderFreeGlyphSet (ClientPtr client)
+{
+ GlyphSetPtr glyphSet;
+ REQUEST(xRenderFreeGlyphSetReq);
+
+ REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
+ glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ stuff->glyphset,
+ GlyphSetType,
+ SecurityDestroyAccess);
+ if (!glyphSet)
+ {
+ client->errorValue = stuff->glyphset;
+ return RenderErrBase + BadGlyphSet;
+ }
+
+ nxagentFreeGlyphSet(glyphSet);
+
+ FreeResource (stuff->glyphset, RT_NONE);
+ return client->noClientException;
+}
+
+typedef struct _GlyphNew {
+ Glyph id;
+ GlyphPtr glyph;
+} GlyphNewRec, *GlyphNewPtr;
+
+static int
+ProcRenderAddGlyphs (ClientPtr client)
+{
+ GlyphSetPtr glyphSet;
+ REQUEST(xRenderAddGlyphsReq);
+ GlyphNewRec glyphsLocal[NLOCALGLYPH];
+ GlyphNewPtr glyphsBase, glyphs;
+ GlyphPtr glyph = NULL;
+ int remain, nglyphs;
+ CARD32 *gids;
+ xGlyphInfo *gi;
+ CARD8 *bits;
+ int size;
+ int err = BadAlloc;
+
+ int totSizeImages;
+
+ REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
+ glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ stuff->glyphset,
+ GlyphSetType,
+ SecurityWriteAccess);
+ if (!glyphSet)
+ {
+ client->errorValue = stuff->glyphset;
+ return RenderErrBase + BadGlyphSet;
+ }
+
+ nglyphs = stuff->nglyphs;
+ if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec))
+ return BadAlloc;
+
+ if (nglyphs <= NLOCALGLYPH)
+ glyphsBase = glyphsLocal;
+ else
+ {
+ glyphsBase = (GlyphNewPtr) Xalloc (nglyphs * sizeof (GlyphNewRec));
+ if (!glyphsBase)
+ return BadAlloc;
+ }
+
+ remain = (client->req_len << 2) - sizeof (xRenderAddGlyphsReq);
+
+ glyphs = glyphsBase;
+
+ totSizeImages = 0;
+ gids = (CARD32 *) (stuff + 1);
+ gi = (xGlyphInfo *) (gids + nglyphs);
+ bits = (CARD8 *) (gi + nglyphs);
+ remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs;
+
+ while (remain >= 0 && nglyphs)
+ {
+ glyph = AllocateGlyph (gi, glyphSet->fdepth);
+ if (!glyph)
+ {
+ err = BadAlloc;
+ goto bail;
+ }
+
+ glyphs->glyph = glyph;
+ glyphs->id = *gids;
+
+ size = glyph->size - sizeof (xGlyphInfo);
+ if (remain < size)
+ break;
+ memcpy ((CARD8 *) (glyph + 1), bits, size);
+
+ if (size & 3)
+ size += 4 - (size & 3);
+ bits += size;
+ totSizeImages += size;
+ remain -= size;
+ gi++;
+ gids++;
+ glyphs++;
+ nglyphs--;
+ }
+
+ if (nglyphs || remain)
+ {
+ err = BadLength;
+ goto bail;
+ }
+ nglyphs = stuff->nglyphs;
+ if (!ResizeGlyphSet (glyphSet, nglyphs))
+ {
+ err = BadAlloc;
+ goto bail;
+ }
+ glyphs = glyphsBase;
+ while (nglyphs--) {
+ AddGlyph (glyphSet, glyphs->glyph, glyphs->id);
+ glyphs++;
+ }
+
+ if (glyphsBase != glyphsLocal)
+ Xfree (glyphsBase);
+ return client->noClientException;
+bail:
+ while (glyphs != glyphsBase)
+ {
+ --glyphs;
+ xfree (glyphs->glyph);
+ }
+ if (glyphsBase != glyphsLocal)
+ Xfree (glyphsBase);
+ return err;
+}
+
+static int
+ProcRenderAddGlyphsFromPicture (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+ProcRenderFreeGlyphs (ClientPtr client)
+{
+ REQUEST(xRenderFreeGlyphsReq);
+ GlyphSetPtr glyphSet;
+ int nglyph;
+ CARD32 *gids;
+ CARD32 glyph;
+
+ REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
+ glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ stuff->glyphset,
+ GlyphSetType,
+ SecurityWriteAccess);
+ if (!glyphSet)
+ {
+ client->errorValue = stuff->glyphset;
+ return RenderErrBase + BadGlyphSet;
+ }
+ nglyph = ((client->req_len << 2) - sizeof (xRenderFreeGlyphsReq)) >> 2;
+ gids = (CARD32 *) (stuff + 1);
+
+ nxagentFreeGlyphs(glyphSet, gids, nglyph);
+
+ while (nglyph-- > 0)
+ {
+ glyph = *gids++;
+ if (!DeleteGlyph (glyphSet, glyph))
+ {
+ client->errorValue = glyph;
+ return RenderErrBase + BadGlyph;
+ }
+ }
+ return client->noClientException;
+}
+
+typedef struct XGlyphElt8{
+ GlyphSet glyphset;
+ _Xconst char *chars;
+ int nchars;
+ int xOff;
+ int yOff;
+} XGlyphElt8;
+
+static int
+ProcRenderCompositeGlyphs (ClientPtr client)
+{
+ GlyphSetPtr glyphSet;
+ GlyphSet gs;
+ PicturePtr pSrc, pDst;
+ PictFormatPtr pFormat;
+ GlyphListRec listsLocal[NLOCALDELTA];
+ GlyphListPtr lists, listsBase;
+ GlyphPtr glyphsLocal[NLOCALGLYPH];
+ Glyph glyph;
+ GlyphPtr *glyphs, *glyphsBase;
+ xGlyphElt *elt;
+ CARD8 *buffer, *end;
+ int nglyph;
+ int nlist;
+ int space;
+ int size;
+ int n;
+
+ XGlyphElt8 *elements, *elementsBase;
+
+ REQUEST(xRenderCompositeGlyphsReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
+
+ switch (stuff->renderReqType) {
+ default: size = 1; break;
+ case X_RenderCompositeGlyphs16: size = 2; break;
+ case X_RenderCompositeGlyphs32: size = 4; break;
+ }
+
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+ return BadMatch;
+ if (stuff->maskFormat)
+ {
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->maskFormat,
+ PictFormatType,
+ SecurityReadAccess);
+ if (!pFormat)
+ {
+ client->errorValue = stuff->maskFormat;
+ return RenderErrBase + BadPictFormat;
+ }
+ }
+ else
+ pFormat = 0;
+
+ glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ stuff->glyphset,
+ GlyphSetType,
+ SecurityReadAccess);
+ if (!glyphSet)
+ {
+ client->errorValue = stuff->glyphset;
+ return RenderErrBase + BadGlyphSet;
+ }
+
+ buffer = (CARD8 *) (stuff + 1);
+ end = (CARD8 *) stuff + (client->req_len << 2);
+ nglyph = 0;
+ nlist = 0;
+ while (buffer + sizeof (xGlyphElt) < end)
+ {
+ elt = (xGlyphElt *) buffer;
+ buffer += sizeof (xGlyphElt);
+
+ if (elt->len == 0xff)
+ {
+ buffer += 4;
+ }
+ else
+ {
+ nlist++;
+ nglyph += elt->len;
+ space = size * elt->len;
+ if (space & 3)
+ space += 4 - (space & 3);
+ buffer += space;
+ }
+ }
+ if (nglyph <= NLOCALGLYPH)
+ glyphsBase = glyphsLocal;
+ else
+ {
+ glyphsBase = (GlyphPtr *) ALLOCATE_LOCAL (nglyph * sizeof (GlyphPtr));
+ if (!glyphsBase)
+ return BadAlloc;
+ }
+ if (nlist <= NLOCALDELTA)
+ listsBase = listsLocal;
+ else
+ {
+ listsBase = (GlyphListPtr) ALLOCATE_LOCAL (nlist * sizeof (GlyphListRec));
+ if (!listsBase)
+ return BadAlloc;
+ }
+
+ elementsBase = xalloc(nlist * sizeof(XGlyphElt8));
+ if (!elementsBase)
+ return BadAlloc;
+
+ buffer = (CARD8 *) (stuff + 1);
+ glyphs = glyphsBase;
+ lists = listsBase;
+ elements = elementsBase;
+ while (buffer + sizeof (xGlyphElt) < end)
+ {
+ elt = (xGlyphElt *) buffer;
+ buffer += sizeof (xGlyphElt);
+
+ if (elt->len == 0xff)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "ProcRenderCompositeGlyphs: Glyphset change with base size [%d].\n",
+ size);
+ #endif
+
+ if (buffer + sizeof (GlyphSet) < end)
+ {
+ memcpy(&gs, buffer, sizeof(GlyphSet));
+ glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ gs,
+ GlyphSetType,
+ SecurityReadAccess);
+ if (!glyphSet)
+ {
+ client->errorValue = gs;
+ if (glyphsBase != glyphsLocal)
+ DEALLOCATE_LOCAL (glyphsBase);
+ if (listsBase != listsLocal)
+ DEALLOCATE_LOCAL (listsBase);
+ return RenderErrBase + BadGlyphSet;
+ }
+ }
+ buffer += 4;
+ }
+ else
+ {
+ lists->xOff = elt->deltax;
+ lists->yOff = elt->deltay;
+ lists->format = glyphSet->format;
+ lists->len = 0;
+
+ if (glyphSet -> remoteID == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "ProcRenderCompositeGlyphs: Going to reconnect glyphset at [%p].\n",
+ (void *) glyphSet);
+ #endif
+
+ nxagentReconnectGlyphSet(glyphSet, (XID) 0, (void*) NULL);
+ }
+
+ elements -> glyphset = glyphSet -> remoteID;
+ elements -> chars = (char *) buffer;
+ elements -> nchars = elt->len;
+ elements -> xOff = elt->deltax;
+ elements -> yOff = elt->deltay;
+ n = elt->len;
+ while (n--)
+ {
+ if (buffer + size <= end)
+ {
+ switch (size) {
+ case 1:
+ glyph = *((CARD8 *)buffer); break;
+ case 2:
+ glyph = *((CARD16 *)buffer); break;
+ case 4:
+ default:
+ glyph = *((CARD32 *)buffer); break;
+ }
+ if ((*glyphs = FindGlyph (glyphSet, glyph)))
+ {
+ lists->len++;
+ glyphs++;
+ }
+ }
+ buffer += size;
+ }
+ space = size * elt->len;
+ if (space & 3)
+ buffer += 4 - (space & 3);
+ lists++;
+ elements++;
+ }
+ }
+ if (buffer > end)
+ return BadLength;
+
+ /*
+ * We need to know the glyphs extents to synchronize
+ * the drawables involved in the composite text ope-
+ * ration. Also we need to synchronize only the back-
+ * ground of the text we are going to render, so the
+ * operations on the framebuffer must be executed
+ * after the X requests.
+ */
+
+ nxagentGlyphsExtents = (BoxPtr) xalloc(sizeof(BoxRec));
+
+ miGlyphExtents(nlist, listsBase, glyphsBase, nxagentGlyphsExtents);
+
+ nxagentGlyphs(stuff -> op,
+ pSrc,
+ pDst,
+ pFormat,
+ stuff -> xSrc,
+ stuff -> ySrc,
+ nlist,
+ elementsBase,
+ size,
+ glyphsBase);
+
+ if (nxagentCompositePredicate(pSrc, pDst) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "ProcRenderCompositeGlyphs: Going to composite glyphs with "
+ "source at [%p] and destination at [%p].\n",
+ (void *) pSrc, (void *) pDst);
+ #endif
+
+ CompositeGlyphs(stuff -> op,
+ pSrc,
+ pDst,
+ pFormat,
+ stuff -> xSrc,
+ stuff -> ySrc,
+ nlist,
+ listsBase,
+ glyphsBase);
+ }
+
+ xfree(nxagentGlyphsExtents);
+ nxagentGlyphsExtents = NullBox;
+
+ if (glyphsBase != glyphsLocal)
+ DEALLOCATE_LOCAL (glyphsBase);
+ if (listsBase != listsLocal)
+ DEALLOCATE_LOCAL (listsBase);
+
+ xfree(elementsBase);
+
+ return client->noClientException;
+}
+
+static int
+ProcRenderFillRectangles (ClientPtr client)
+{
+ PicturePtr pDst;
+ int things;
+ REQUEST(xRenderFillRectanglesReq);
+
+ REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+
+ things = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq);
+ if (things & 4)
+ return(BadLength);
+ things >>= 3;
+
+ CompositeRects (stuff->op,
+ pDst,
+ &stuff->color,
+ things,
+ (xRectangle *) &stuff[1]);
+
+ ValidatePicture (pDst);
+ nxagentCompositeRects(stuff -> op,
+ pDst,
+ &stuff -> color,
+ things,
+ (xRectangle *) &stuff[1]);
+
+ return client->noClientException;
+}
+
+static void
+SetBit (unsigned char *line, int x, int bit)
+{
+ unsigned char mask;
+
+ if (screenInfo.bitmapBitOrder == LSBFirst)
+ mask = (1 << (x & 7));
+ else
+ mask = (0x80 >> (x & 7));
+ /* XXX assumes byte order is host byte order */
+ line += (x >> 3);
+ if (bit)
+ *line |= mask;
+ else
+ *line &= ~mask;
+}
+
+#define DITHER_DIM 2
+
+static CARD32 orderedDither[DITHER_DIM][DITHER_DIM] = {
+ { 1, 3, },
+ { 4, 2, },
+};
+
+#define DITHER_SIZE ((sizeof orderedDither / sizeof orderedDither[0][0]) + 1)
+
+static int
+ProcRenderCreateCursor (ClientPtr client)
+{
+ REQUEST(xRenderCreateCursorReq);
+ PicturePtr pSrc;
+ ScreenPtr pScreen;
+ unsigned short width, height;
+ CARD32 *argbbits, *argb;
+ unsigned char *srcbits, *srcline;
+ unsigned char *mskbits, *mskline;
+ int stride;
+ int x, y;
+ int nbytes_mono;
+ CursorMetricRec cm;
+ CursorPtr pCursor;
+ CARD32 twocolor[3];
+ int ncolor;
+
+ RealizeCursorProcPtr saveRealizeCursor;
+
+ REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
+ LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+ VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ if (!pSrc->pDrawable)
+ return BadDrawable;
+ pScreen = pSrc->pDrawable->pScreen;
+ width = pSrc->pDrawable->width;
+ height = pSrc->pDrawable->height;
+ if ( stuff->x > width
+ || stuff->y > height )
+ return (BadMatch);
+ argbbits = xalloc (width * height * sizeof (CARD32));
+ if (!argbbits)
+ return (BadAlloc);
+
+ stride = BitmapBytePad(width);
+ nbytes_mono = stride*height;
+ srcbits = (unsigned char *)xalloc(nbytes_mono);
+ if (!srcbits)
+ {
+ xfree (argbbits);
+ return (BadAlloc);
+ }
+ mskbits = (unsigned char *)xalloc(nbytes_mono);
+ if (!mskbits)
+ {
+ xfree(argbbits);
+ xfree(srcbits);
+ return (BadAlloc);
+ }
+ bzero ((char *) mskbits, nbytes_mono);
+ bzero ((char *) srcbits, nbytes_mono);
+
+ if (pSrc->format == PICT_a8r8g8b8)
+ {
+ (*pScreen->GetImage) (pSrc->pDrawable,
+ 0, 0, width, height, ZPixmap,
+ 0xffffffff, (pointer) argbbits);
+ }
+ else
+ {
+ PixmapPtr pPixmap;
+ PicturePtr pPicture;
+ PictFormatPtr pFormat;
+ int error;
+
+ pFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8);
+ if (!pFormat)
+ {
+ xfree (argbbits);
+ xfree (srcbits);
+ xfree (mskbits);
+ return (BadImplementation);
+ }
+ pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32);
+ if (!pPixmap)
+ {
+ xfree (argbbits);
+ xfree (srcbits);
+ xfree (mskbits);
+ return (BadAlloc);
+ }
+ pPicture = CreatePicture (0, &pPixmap->drawable, pFormat, 0, 0,
+ client, &error);
+ if (!pPicture)
+ {
+ xfree (argbbits);
+ xfree (srcbits);
+ xfree (mskbits);
+ return error;
+ }
+ (*pScreen->DestroyPixmap) (pPixmap);
+ CompositePicture (PictOpSrc,
+ pSrc, 0, pPicture,
+ 0, 0, 0, 0, 0, 0, width, height);
+ (*pScreen->GetImage) (pPicture->pDrawable,
+ 0, 0, width, height, ZPixmap,
+ 0xffffffff, (pointer) argbbits);
+ FreePicture (pPicture, 0);
+ }
+ /*
+ * Check whether the cursor can be directly supported by
+ * the core cursor code
+ */
+ ncolor = 0;
+ argb = argbbits;
+ for (y = 0; ncolor <= 2 && y < height; y++)
+ {
+ for (x = 0; ncolor <= 2 && x < width; x++)
+ {
+ CARD32 p = *argb++;
+ CARD32 a = (p >> 24);
+
+ if (a == 0) /* transparent */
+ continue;
+ if (a == 0xff) /* opaque */
+ {
+ int n;
+ for (n = 0; n < ncolor; n++)
+ if (p == twocolor[n])
+ break;
+ if (n == ncolor)
+ twocolor[ncolor++] = p;
+ }
+ else
+ ncolor = 3;
+ }
+ }
+
+ /*
+ * Convert argb image to two plane cursor
+ */
+ srcline = srcbits;
+ mskline = mskbits;
+ argb = argbbits;
+ for (y = 0; y < height; y++)
+ {
+ for (x = 0; x < width; x++)
+ {
+ CARD32 p = *argb++;
+
+ if (ncolor <= 2)
+ {
+ CARD32 a = ((p >> 24));
+
+ SetBit (mskline, x, a != 0);
+ SetBit (srcline, x, a != 0 && p == twocolor[0]);
+ }
+ else
+ {
+ CARD32 a = ((p >> 24) * DITHER_SIZE + 127) / 255;
+ CARD32 i = ((CvtR8G8B8toY15(p) >> 7) * DITHER_SIZE + 127) / 255;
+ CARD32 d = orderedDither[y&(DITHER_DIM-1)][x&(DITHER_DIM-1)];
+ /* Set mask from dithered alpha value */
+ SetBit(mskline, x, a > d);
+ /* Set src from dithered intensity value */
+ SetBit(srcline, x, a > d && i <= d);
+ }
+ }
+ srcline += stride;
+ mskline += stride;
+ }
+ /*
+ * Dither to white and black if the cursor has more than two colors
+ */
+ if (ncolor > 2)
+ {
+ twocolor[0] = 0xff000000;
+ twocolor[1] = 0xffffffff;
+ }
+ else
+ {
+ xfree (argbbits);
+ argbbits = 0;
+ }
+
+#define GetByte(p,s) (((p) >> (s)) & 0xff)
+#define GetColor(p,s) (GetByte(p,s) | (GetByte(p,s) << 8))
+
+ cm.width = width;
+ cm.height = height;
+ cm.xhot = stuff->x;
+ cm.yhot = stuff->y;
+
+ /*
+ * This cursor uses RENDER, so we make sure
+ * that it is allocated in a way that allows
+ * the mi and dix layers to handle it but we
+ * later create it on the server by mirror-
+ * ing the RENDER operation we got from the
+ * client.
+ */
+
+ saveRealizeCursor = pScreen -> RealizeCursor;
+
+ pScreen -> RealizeCursor = nxagentCursorSaveRenderInfo;
+
+ pCursor = AllocCursorARGB (srcbits, mskbits, argbbits, &cm,
+ GetColor(twocolor[0], 16),
+ GetColor(twocolor[0], 8),
+ GetColor(twocolor[0], 0),
+ GetColor(twocolor[1], 16),
+ GetColor(twocolor[1], 8),
+ GetColor(twocolor[1], 0));
+
+ pScreen -> RealizeCursor = saveRealizeCursor;
+
+ /*
+ * Store into the private data members the
+ * information needed to recreate it at
+ * reconnection. This is done in two steps
+ * as in the first step we don't have the
+ * picture info.
+ */
+
+ if (pCursor == NULL)
+ {
+ return BadAlloc;
+ }
+
+ nxagentCursorPostSaveRenderInfo(pCursor, pScreen, pSrc, stuff -> x, stuff -> y);
+
+ nxagentRenderRealizeCursor(pScreen, pCursor);
+
+ if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+ return (client->noClientException);
+ return BadAlloc;
+}
+
+static int
+ProcRenderSetPictureTransform (ClientPtr client)
+{
+ REQUEST(xRenderSetPictureTransformReq);
+ PicturePtr pPicture;
+ int result;
+
+ REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
+ VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ result = SetPictureTransform (pPicture, (PictTransform *) &stuff->transform);
+
+ nxagentSetPictureTransform(pPicture, &stuff->transform);
+
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+static int
+ProcRenderQueryFilters (ClientPtr client)
+{
+ REQUEST (xRenderQueryFiltersReq);
+ DrawablePtr pDrawable;
+ xRenderQueryFiltersReply *reply;
+ int nbytesName;
+ int nnames;
+ ScreenPtr pScreen;
+ PictureScreenPtr ps;
+ int i, j;
+ int len;
+ int total_bytes;
+ INT16 *aliases;
+ char *names;
+
+ REQUEST_SIZE_MATCH(xRenderQueryFiltersReq);
+ SECURITY_VERIFY_DRAWABLE(pDrawable, stuff->drawable, client, SecurityReadAccess);
+
+ pScreen = pDrawable->pScreen;
+ nbytesName = 0;
+ nnames = 0;
+ ps = GetPictureScreenIfSet(pScreen);
+ if (ps)
+ {
+ for (i = 0; i < ps->nfilters; i++)
+ nbytesName += 1 + strlen (ps->filters[i].name);
+ for (i = 0; i < ps->nfilterAliases; i++)
+ nbytesName += 1 + strlen (ps->filterAliases[i].alias);
+ nnames = ps->nfilters + ps->nfilterAliases;
+ }
+ len = ((nnames + 1) >> 1) + ((nbytesName + 3) >> 2);
+ total_bytes = sizeof (xRenderQueryFiltersReply) + (len << 2);
+ reply = (xRenderQueryFiltersReply *) xalloc (total_bytes);
+ if (!reply)
+ return BadAlloc;
+ aliases = (INT16 *) (reply + 1);
+ names = (char *) (aliases + ((nnames + 1) & ~1));
+
+ reply->type = X_Reply;
+ reply->sequenceNumber = client->sequence;
+ reply->length = len;
+ reply->numAliases = nnames;
+ reply->numFilters = nnames;
+ if (ps)
+ {
+
+ /* fill in alias values */
+ for (i = 0; i < ps->nfilters; i++)
+ aliases[i] = FilterAliasNone;
+ for (i = 0; i < ps->nfilterAliases; i++)
+ {
+ for (j = 0; j < ps->nfilters; j++)
+ if (ps->filterAliases[i].filter_id == ps->filters[j].id)
+ break;
+ if (j == ps->nfilters)
+ {
+ for (j = 0; j < ps->nfilterAliases; j++)
+ if (ps->filterAliases[i].filter_id ==
+ ps->filterAliases[j].alias_id)
+ {
+ break;
+ }
+ if (j == ps->nfilterAliases)
+ j = FilterAliasNone;
+ else
+ j = j + ps->nfilters;
+ }
+ aliases[i + ps->nfilters] = j;
+ }
+
+ /* fill in filter names */
+ for (i = 0; i < ps->nfilters; i++)
+ {
+ j = strlen (ps->filters[i].name);
+ *names++ = j;
+ strncpy (names, ps->filters[i].name, j);
+ names += j;
+ }
+
+ /* fill in filter alias names */
+ for (i = 0; i < ps->nfilterAliases; i++)
+ {
+ j = strlen (ps->filterAliases[i].alias);
+ *names++ = j;
+ strncpy (names, ps->filterAliases[i].alias, j);
+ names += j;
+ }
+ }
+
+ if (client->swapped)
+ {
+ register int n;
+
+ for (i = 0; i < (int)reply->numAliases; i++)
+ {
+ swaps (&aliases[i], n);
+ }
+ swaps(&reply->sequenceNumber, n);
+ swapl(&reply->length, n);
+ swapl(&reply->numAliases, n);
+ swapl(&reply->numFilters, n);
+ }
+ WriteToClient(client, total_bytes, (char *) reply);
+ xfree (reply);
+
+ return(client->noClientException);
+}
+
+static int
+ProcRenderSetPictureFilter (ClientPtr client)
+{
+ REQUEST (xRenderSetPictureFilterReq);
+ PicturePtr pPicture;
+ int result;
+ xFixed *params;
+ int nparams;
+ char *name;
+
+ REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
+ VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ name = (char *) (stuff + 1);
+ params = (xFixed *) (name + ((stuff->nbytes + 3) & ~3));
+ nparams = ((xFixed *) stuff + client->req_len) - params;
+ result = SetPictureFilter (pPicture, name, stuff->nbytes, params, nparams);
+
+ nxagentSetPictureFilter(pPicture, name, stuff->nbytes, params, nparams);
+
+ return result;
+}
+
+static int
+ProcRenderCreateAnimCursor (ClientPtr client)
+{
+ REQUEST(xRenderCreateAnimCursorReq);
+ CursorPtr *cursors;
+ CARD32 *deltas;
+ CursorPtr pCursor;
+ int ncursor;
+ xAnimCursorElt *elt;
+ int i;
+ int ret;
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq);
+ LEGAL_NEW_RESOURCE(stuff->cid, client);
+ if (client->req_len & 1)
+ return BadLength;
+ ncursor = (client->req_len - (SIZEOF(xRenderCreateAnimCursorReq) >> 2)) >> 1;
+ cursors = xalloc (ncursor * (sizeof (CursorPtr) + sizeof (CARD32)));
+ if (!cursors)
+ return BadAlloc;
+ deltas = (CARD32 *) (cursors + ncursor);
+ elt = (xAnimCursorElt *) (stuff + 1);
+ for (i = 0; i < ncursor; i++)
+ {
+ cursors[i] = (CursorPtr)SecurityLookupIDByType(client, elt->cursor,
+ RT_CURSOR, SecurityReadAccess);
+ if (!cursors[i])
+ {
+ xfree (cursors);
+ client->errorValue = elt->cursor;
+ return BadCursor;
+ }
+ deltas[i] = elt->delay;
+ elt++;
+ }
+ ret = AnimCursorCreate (cursors, deltas, ncursor, &pCursor);
+ xfree (cursors);
+ if (ret != Success)
+ return ret;
+
+ nxagentAnimCursorBits = pCursor -> bits;
+
+ for (i = 0; i < MAXSCREENS; i++)
+ {
+ pCursor -> devPriv[i] = NULL;
+ }
+
+ if (AddResource (stuff->cid, RT_CURSOR, (pointer)pCursor))
+ return client->noClientException;
+ return BadAlloc;
+}
+
+static int
+ProcRenderAddTraps (ClientPtr client)
+{
+ int ntraps;
+ PicturePtr pPicture;
+ REQUEST(xRenderAddTrapsReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq);
+ VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pPicture->pDrawable)
+ return BadDrawable;
+ ntraps = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
+ if (ntraps % sizeof (xTrap))
+ return BadLength;
+ ntraps /= sizeof (xTrap);
+ if (ntraps)
+ AddTraps (pPicture,
+ stuff->xOff, stuff->yOff,
+ ntraps, (xTrap *) &stuff[1]);
+ return client->noClientException;
+}
+
+static int ProcRenderCreateSolidFill(ClientPtr client)
+{
+ PicturePtr pPicture;
+ int error = 0;
+ REQUEST(xRenderCreateSolidFillReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
+
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+ pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error);
+ if (!pPicture)
+ return error;
+ if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+ return BadAlloc;
+ return Success;
+}
+
+static int ProcRenderCreateLinearGradient (ClientPtr client)
+{
+ PicturePtr pPicture;
+ int len;
+ int error = 0;
+ xFixed *stops;
+ xRenderColor *colors;
+ REQUEST(xRenderCreateLinearGradientReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
+
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ stops = (xFixed *)(stuff + 1);
+ colors = (xRenderColor *)(stops + stuff->nStops);
+
+ pPicture = CreateLinearGradientPicture (stuff->pid, &stuff->p1, &stuff->p2,
+ stuff->nStops, stops, colors, &error);
+ if (!pPicture)
+ return error;
+ if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+ return BadAlloc;
+ return Success;
+}
+
+static int ProcRenderCreateRadialGradient (ClientPtr client)
+{
+ PicturePtr pPicture;
+ int len;
+ int error = 0;
+ xFixed *stops;
+ xRenderColor *colors;
+ REQUEST(xRenderCreateRadialGradientReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
+
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ stops = (xFixed *)(stuff + 1);
+ colors = (xRenderColor *)(stops + stuff->nStops);
+
+ pPicture = CreateRadialGradientPicture (stuff->pid, &stuff->inner, &stuff->outer,
+ stuff->inner_radius, stuff->outer_radius,
+ stuff->nStops, stops, colors, &error);
+ if (!pPicture)
+ return error;
+ if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+ return BadAlloc;
+ return Success;
+}
+
+static int ProcRenderCreateConicalGradient (ClientPtr client)
+{
+ PicturePtr pPicture;
+ int len;
+ int error = 0;
+ xFixed *stops;
+ xRenderColor *colors;
+ REQUEST(xRenderCreateConicalGradientReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
+
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ stops = (xFixed *)(stuff + 1);
+ colors = (xRenderColor *)(stops + stuff->nStops);
+
+ pPicture = CreateConicalGradientPicture (stuff->pid, &stuff->center, stuff->angle,
+ stuff->nStops, stops, colors, &error);
+ if (!pPicture)
+ return error;
+ if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+ return BadAlloc;
+ return Success;
+}
+
+
+static int
+ProcRenderDispatch (ClientPtr client)
+{
+ int result;
+
+ REQUEST(xReq);
+
+ /*
+ * Let the client fail if we are
+ * hiding the RENDER extension.
+ */
+
+ if (nxagentRenderTrap)
+ {
+ return BadRequest;
+ }
+
+ if (stuff->data < RenderNumberRequests)
+ {
+ #ifdef TEST
+ fprintf(stderr, "ProcRenderDispatch: Request [%s] OPCODE#%d.\n",
+ nxagentRenderRequestLiteral[stuff->data], stuff->data);
+ #endif
+
+ /*
+ * Set the nxagentGCTrap flag while
+ * dispatching a render operation to
+ * avoid reentrancy in GCOps.c.
+ */
+
+ nxagentGCTrap = 1;
+
+ result = (*ProcRenderVector[stuff->data]) (client);
+
+ nxagentGCTrap = 0;
+
+ return result;
+ }
+ else
+ return BadRequest;
+}
+
+static int
+SProcRenderQueryVersion (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderQueryVersionReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->majorVersion, n);
+ swapl(&stuff->minorVersion, n);
+ return (*ProcRenderVector[stuff->renderReqType])(client);
+}
+
+static int
+SProcRenderQueryPictFormats (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderQueryPictFormatsReq);
+ swaps(&stuff->length, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryPictIndexValues (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderQueryPictIndexValuesReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->format, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryDithers (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+SProcRenderCreatePicture (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderCreatePictureReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->pid, n);
+ swapl(&stuff->drawable, n);
+ swapl(&stuff->format, n);
+ swapl(&stuff->mask, n);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderChangePicture (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderChangePictureReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->picture, n);
+ swapl(&stuff->mask, n);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderSetPictureClipRectangles (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderSetPictureClipRectanglesReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->picture, n);
+ SwapRestS(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderFreePicture (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderFreePictureReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->picture, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderComposite (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderCompositeReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->src, n);
+ swapl(&stuff->mask, n);
+ swapl(&stuff->dst, n);
+ swaps(&stuff->xSrc, n);
+ swaps(&stuff->ySrc, n);
+ swaps(&stuff->xMask, n);
+ swaps(&stuff->yMask, n);
+ swaps(&stuff->xDst, n);
+ swaps(&stuff->yDst, n);
+ swaps(&stuff->width, n);
+ swaps(&stuff->height, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderScale (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderScaleReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->src, n);
+ swapl(&stuff->dst, n);
+ swapl(&stuff->colorScale, n);
+ swapl(&stuff->alphaScale, n);
+ swaps(&stuff->xSrc, n);
+ swaps(&stuff->ySrc, n);
+ swaps(&stuff->xDst, n);
+ swaps(&stuff->yDst, n);
+ swaps(&stuff->width, n);
+ swaps(&stuff->height, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTrapezoids (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderTrapezoidsReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
+ swaps (&stuff->length, n);
+ swapl (&stuff->src, n);
+ swapl (&stuff->dst, n);
+ swapl (&stuff->maskFormat, n);
+ swaps (&stuff->xSrc, n);
+ swaps (&stuff->ySrc, n);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriangles (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderTrianglesReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+ swaps (&stuff->length, n);
+ swapl (&stuff->src, n);
+ swapl (&stuff->dst, n);
+ swapl (&stuff->maskFormat, n);
+ swaps (&stuff->xSrc, n);
+ swaps (&stuff->ySrc, n);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriStrip (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderTriStripReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTriStripReq);
+ swaps (&stuff->length, n);
+ swapl (&stuff->src, n);
+ swapl (&stuff->dst, n);
+ swapl (&stuff->maskFormat, n);
+ swaps (&stuff->xSrc, n);
+ swaps (&stuff->ySrc, n);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriFan (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderTriFanReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTriFanReq);
+ swaps (&stuff->length, n);
+ swapl (&stuff->src, n);
+ swapl (&stuff->dst, n);
+ swapl (&stuff->maskFormat, n);
+ swaps (&stuff->xSrc, n);
+ swaps (&stuff->ySrc, n);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderColorTrapezoids (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+SProcRenderColorTriangles (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+SProcRenderTransform (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+SProcRenderCreateGlyphSet (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderCreateGlyphSetReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->gsid, n);
+ swapl(&stuff->format, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderReferenceGlyphSet (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderReferenceGlyphSetReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->gsid, n);
+ swapl(&stuff->existing, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderFreeGlyphSet (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderFreeGlyphSetReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->glyphset, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderAddGlyphs (ClientPtr client)
+{
+ register int n;
+ register unsigned int i;
+ CARD32 *gids;
+ void *end;
+ xGlyphInfo *gi;
+ REQUEST(xRenderAddGlyphsReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->glyphset, n);
+ swapl(&stuff->nglyphs, n);
+ if (stuff->nglyphs & 0xe0000000)
+ return BadLength;
+ end = (CARD8 *) stuff + (client->req_len << 2);
+ gids = (CARD32 *) (stuff + 1);
+ gi = (xGlyphInfo *) (gids + stuff->nglyphs);
+ if ((char *) end - (char *) (gids + stuff->nglyphs) < 0)
+ return BadLength;
+ if ((char *) end - (char *) (gi + stuff->nglyphs) < 0)
+ return BadLength;
+ for (i = 0; i < stuff->nglyphs; i++)
+ {
+ swapl (&gids[i], n);
+ swaps (&gi[i].width, n);
+ swaps (&gi[i].height, n);
+ swaps (&gi[i].x, n);
+ swaps (&gi[i].y, n);
+ swaps (&gi[i].xOff, n);
+ swaps (&gi[i].yOff, n);
+ }
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderAddGlyphsFromPicture (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+SProcRenderFreeGlyphs (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderFreeGlyphsReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->glyphset, n);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCompositeGlyphs (ClientPtr client)
+{
+ register int n;
+ xGlyphElt *elt;
+ CARD8 *buffer;
+ CARD8 *end;
+ int space;
+ int i;
+ int size;
+
+ REQUEST(xRenderCompositeGlyphsReq);
+
+ switch (stuff->renderReqType) {
+ default: size = 1; break;
+ case X_RenderCompositeGlyphs16: size = 2; break;
+ case X_RenderCompositeGlyphs32: size = 4; break;
+ }
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->src, n);
+ swapl(&stuff->dst, n);
+ swapl(&stuff->maskFormat, n);
+ swapl(&stuff->glyphset, n);
+ swaps(&stuff->xSrc, n);
+ swaps(&stuff->ySrc, n);
+ buffer = (CARD8 *) (stuff + 1);
+ end = (CARD8 *) stuff + (client->req_len << 2);
+ while (buffer + sizeof (xGlyphElt) < end)
+ {
+ elt = (xGlyphElt *) buffer;
+ buffer += sizeof (xGlyphElt);
+
+ swaps (&elt->deltax, n);
+ swaps (&elt->deltay, n);
+
+ i = elt->len;
+ if (i == 0xff)
+ {
+ swapl (buffer, n);
+ buffer += 4;
+ }
+ else
+ {
+ space = size * i;
+ switch (size) {
+ case 1:
+ buffer += i;
+ break;
+ case 2:
+ while (i--)
+ {
+ swaps (buffer, n);
+ buffer += 2;
+ }
+ break;
+ case 4:
+ while (i--)
+ {
+ swapl (buffer, n);
+ buffer += 4;
+ }
+ break;
+ }
+ if (space & 3)
+ buffer += 4 - (space & 3);
+ }
+ }
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderFillRectangles (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderFillRectanglesReq);
+
+ REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->dst, n);
+ swaps(&stuff->color.red, n);
+ swaps(&stuff->color.green, n);
+ swaps(&stuff->color.blue, n);
+ swaps(&stuff->color.alpha, n);
+ SwapRestS(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateCursor (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderCreateCursorReq);
+ REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->cid, n);
+ swapl(&stuff->src, n);
+ swaps(&stuff->x, n);
+ swaps(&stuff->y, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderSetPictureTransform (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderSetPictureTransformReq);
+ REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->picture, n);
+ swapl(&stuff->transform.matrix11, n);
+ swapl(&stuff->transform.matrix12, n);
+ swapl(&stuff->transform.matrix13, n);
+ swapl(&stuff->transform.matrix21, n);
+ swapl(&stuff->transform.matrix22, n);
+ swapl(&stuff->transform.matrix23, n);
+ swapl(&stuff->transform.matrix31, n);
+ swapl(&stuff->transform.matrix32, n);
+ swapl(&stuff->transform.matrix33, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryFilters (ClientPtr client)
+{
+ register int n;
+ REQUEST (xRenderQueryFiltersReq);
+ REQUEST_SIZE_MATCH (xRenderQueryFiltersReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->drawable, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderSetPictureFilter (ClientPtr client)
+{
+ register int n;
+ REQUEST (xRenderSetPictureFilterReq);
+ REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->picture, n);
+ swaps(&stuff->nbytes, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateAnimCursor (ClientPtr client)
+{
+ register int n;
+ REQUEST (xRenderCreateAnimCursorReq);
+ REQUEST_AT_LEAST_SIZE (xRenderCreateAnimCursorReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->cid, n);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderAddTraps (ClientPtr client)
+{
+ register int n;
+ REQUEST (xRenderAddTrapsReq);
+ REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->picture, n);
+ swaps(&stuff->xOff, n);
+ swaps(&stuff->yOff, n);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateSolidFill(ClientPtr client)
+{
+ register int n;
+ REQUEST (xRenderCreateSolidFillReq);
+ REQUEST_AT_LEAST_SIZE (xRenderCreateSolidFillReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->pid, n);
+ swaps(&stuff->color.alpha, n);
+ swaps(&stuff->color.red, n);
+ swaps(&stuff->color.green, n);
+ swaps(&stuff->color.blue, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static void swapStops(void *stuff, int n)
+{
+ int i;
+ CARD32 *stops;
+ CARD16 *colors;
+ stops = (CARD32 *)(stuff);
+ for (i = 0; i < n; ++i) {
+ swapl(stops, n);
+ ++stops;
+ }
+ colors = (CARD16 *)(stops);
+ for (i = 0; i < 4*n; ++i) {
+ swaps(stops, n);
+ ++stops;
+ }
+}
+
+static int
+SProcRenderCreateLinearGradient (ClientPtr client)
+{
+ register int n;
+ int len;
+ REQUEST (xRenderCreateLinearGradientReq);
+ REQUEST_AT_LEAST_SIZE (xRenderCreateLinearGradientReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->pid, n);
+ swapl(&stuff->p1.x, n);
+ swapl(&stuff->p1.y, n);
+ swapl(&stuff->p2.x, n);
+ swapl(&stuff->p2.y, n);
+ swapl(&stuff->nStops, n);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ swapStops(stuff+1, stuff->nStops);
+
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateRadialGradient (ClientPtr client)
+{
+ register int n;
+ int len;
+ REQUEST (xRenderCreateRadialGradientReq);
+ REQUEST_AT_LEAST_SIZE (xRenderCreateRadialGradientReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->pid, n);
+ swapl(&stuff->inner.x, n);
+ swapl(&stuff->inner.y, n);
+ swapl(&stuff->outer.x, n);
+ swapl(&stuff->outer.y, n);
+ swapl(&stuff->inner_radius, n);
+ swapl(&stuff->outer_radius, n);
+ swapl(&stuff->nStops, n);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ swapStops(stuff+1, stuff->nStops);
+
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateConicalGradient (ClientPtr client)
+{
+ register int n;
+ int len;
+ REQUEST (xRenderCreateConicalGradientReq);
+ REQUEST_AT_LEAST_SIZE (xRenderCreateConicalGradientReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->pid, n);
+ swapl(&stuff->center.x, n);
+ swapl(&stuff->center.y, n);
+ swapl(&stuff->angle, n);
+ swapl(&stuff->nStops, n);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ swapStops(stuff+1, stuff->nStops);
+
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderDispatch (ClientPtr client)
+{
+ int result;
+
+ REQUEST(xReq);
+
+ /*
+ * Let the client fail if we are
+ * hiding the RENDER extension.
+ */
+
+ if (nxagentRenderTrap)
+ {
+ return BadRequest;
+ }
+
+ if (stuff->data < RenderNumberRequests)
+ {
+ /*
+ * Set the nxagentGCTrap flag while
+ * dispatching a render operation to
+ * avoid reentrancy in GCOps.c.
+ */
+
+ nxagentGCTrap = 1;
+
+ result = (*SProcRenderVector[stuff->data]) (client);
+
+ nxagentGCTrap = 0;
+
+ return result;
+ }
+ else
+ return BadRequest;
+}
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+
+#define VERIFY_XIN_PICTURE(pPicture, pid, client, mode, err) {\
+ pPicture = SecurityLookupIDByType(client, pid, XRT_PICTURE, mode);\
+ if (!pPicture) { \
+ client->errorValue = pid; \
+ return err; \
+ } \
+}
+
+#define VERIFY_XIN_ALPHA(pPicture, pid, client, mode, err) {\
+ if (pid == None) \
+ pPicture = 0; \
+ else { \
+ VERIFY_XIN_PICTURE(pPicture, pid, client, mode, err); \
+ } \
+} \
+
+int (*PanoramiXSaveRenderVector[RenderNumberRequests])(ClientPtr);
+
+unsigned long XRT_PICTURE;
+
+static int
+PanoramiXRenderCreatePicture (ClientPtr client)
+{
+ REQUEST(xRenderCreatePictureReq);
+ PanoramiXRes *refDraw, *newPict;
+ int result = Success, j;
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
+ if(!(refDraw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+ return BadDrawable;
+ if(!(newPict = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes))))
+ return BadAlloc;
+ newPict->type = XRT_PICTURE;
+ newPict->info[0].id = stuff->pid;
+
+ if (refDraw->type == XRT_WINDOW &&
+ stuff->drawable == WindowTable[0]->drawable.id)
+ {
+ newPict->u.pict.root = TRUE;
+ }
+ else
+ newPict->u.pict.root = FALSE;
+
+ for(j = 1; j < PanoramiXNumScreens; j++)
+ newPict->info[j].id = FakeClientID(client->index);
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->pid = newPict->info[j].id;
+ stuff->drawable = refDraw->info[j].id;
+ result = (*PanoramiXSaveRenderVector[X_RenderCreatePicture]) (client);
+ if(result != Success) break;
+ }
+
+ if (result == Success)
+ AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
+ else
+ xfree(newPict);
+
+ return (result);
+}
+
+static int
+PanoramiXRenderChangePicture (ClientPtr client)
+{
+ PanoramiXRes *pict;
+ int result = Success, j;
+ REQUEST(xRenderChangePictureReq);
+
+ REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
+
+ VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->picture = pict->info[j].id;
+ result = (*PanoramiXSaveRenderVector[X_RenderChangePicture]) (client);
+ if(result != Success) break;
+ }
+
+ return (result);
+}
+
+static int
+PanoramiXRenderSetPictureClipRectangles (ClientPtr client)
+{
+ REQUEST(xRenderSetPictureClipRectanglesReq);
+ int result = Success, j;
+ PanoramiXRes *pict;
+
+ REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
+
+ VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->picture = pict->info[j].id;
+ result = (*PanoramiXSaveRenderVector[X_RenderSetPictureClipRectangles]) (client);
+ if(result != Success) break;
+ }
+
+ return (result);
+}
+
+static int
+PanoramiXRenderSetPictureTransform (ClientPtr client)
+{
+ REQUEST(xRenderSetPictureTransformReq);
+ int result = Success, j;
+ PanoramiXRes *pict;
+
+ REQUEST_AT_LEAST_SIZE(xRenderSetPictureTransformReq);
+
+ VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->picture = pict->info[j].id;
+ result = (*PanoramiXSaveRenderVector[X_RenderSetPictureTransform]) (client);
+ if(result != Success) break;
+ }
+
+ return (result);
+}
+
+static int
+PanoramiXRenderSetPictureFilter (ClientPtr client)
+{
+ REQUEST(xRenderSetPictureFilterReq);
+ int result = Success, j;
+ PanoramiXRes *pict;
+
+ REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq);
+
+ VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->picture = pict->info[j].id;
+ result = (*PanoramiXSaveRenderVector[X_RenderSetPictureFilter]) (client);
+ if(result != Success) break;
+ }
+
+ return (result);
+}
+
+static int
+PanoramiXRenderFreePicture (ClientPtr client)
+{
+ PanoramiXRes *pict;
+ int result = Success, j;
+ REQUEST(xRenderFreePictureReq);
+
+ REQUEST_SIZE_MATCH(xRenderFreePictureReq);
+
+ client->errorValue = stuff->picture;
+
+ VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityDestroyAccess,
+ RenderErrBase + BadPicture);
+
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->picture = pict->info[j].id;
+ result = (*PanoramiXSaveRenderVector[X_RenderFreePicture]) (client);
+ if(result != Success) break;
+ }
+
+ /* Since ProcRenderFreePicture is using FreeResource, it will free
+ our resource for us on the last pass through the loop above */
+
+ return (result);
+}
+
+static int
+PanoramiXRenderComposite (ClientPtr client)
+{
+ PanoramiXRes *src, *msk, *dst;
+ int result = Success, j;
+ xRenderCompositeReq orig;
+ REQUEST(xRenderCompositeReq);
+
+ REQUEST_SIZE_MATCH(xRenderCompositeReq);
+
+ VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_XIN_ALPHA (msk, stuff->mask, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ orig = *stuff;
+
+ FOR_NSCREENS_FORWARD(j) {
+ stuff->src = src->info[j].id;
+ if (src->u.pict.root)
+ {
+ stuff->xSrc = orig.xSrc - panoramiXdataPtr[j].x;
+ stuff->ySrc = orig.ySrc - panoramiXdataPtr[j].y;
+ }
+ stuff->dst = dst->info[j].id;
+ if (dst->u.pict.root)
+ {
+ stuff->xDst = orig.xDst - panoramiXdataPtr[j].x;
+ stuff->yDst = orig.yDst - panoramiXdataPtr[j].y;
+ }
+ if (msk)
+ {
+ stuff->mask = msk->info[j].id;
+ if (msk->u.pict.root)
+ {
+ stuff->xMask = orig.xMask - panoramiXdataPtr[j].x;
+ stuff->yMask = orig.yMask - panoramiXdataPtr[j].y;
+ }
+ }
+ result = (*PanoramiXSaveRenderVector[X_RenderComposite]) (client);
+ if(result != Success) break;
+ }
+
+ return result;
+}
+
+static int
+PanoramiXRenderCompositeGlyphs (ClientPtr client)
+{
+ PanoramiXRes *src, *dst;
+ int result = Success, j;
+ REQUEST(xRenderCompositeGlyphsReq);
+ xGlyphElt origElt, *elt;
+ INT16 xSrc, ySrc;
+
+ REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
+ VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ if (client->req_len << 2 >= (sizeof (xRenderCompositeGlyphsReq) +
+ sizeof (xGlyphElt)))
+ {
+ elt = (xGlyphElt *) (stuff + 1);
+ origElt = *elt;
+ xSrc = stuff->xSrc;
+ ySrc = stuff->ySrc;
+ FOR_NSCREENS_FORWARD(j) {
+ stuff->src = src->info[j].id;
+ if (src->u.pict.root)
+ {
+ stuff->xSrc = xSrc - panoramiXdataPtr[j].x;
+ stuff->ySrc = ySrc - panoramiXdataPtr[j].y;
+ }
+ stuff->dst = dst->info[j].id;
+ if (dst->u.pict.root)
+ {
+ elt->deltax = origElt.deltax - panoramiXdataPtr[j].x;
+ elt->deltay = origElt.deltay - panoramiXdataPtr[j].y;
+ }
+ result = (*PanoramiXSaveRenderVector[stuff->renderReqType]) (client);
+ if(result != Success) break;
+ }
+ }
+
+ return result;
+}
+
+static int
+PanoramiXRenderFillRectangles (ClientPtr client)
+{
+ PanoramiXRes *dst;
+ int result = Success, j;
+ REQUEST(xRenderFillRectanglesReq);
+ char *extra;
+ int extra_len;
+
+ REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ extra_len = (client->req_len << 2) - sizeof (xRenderFillRectanglesReq);
+ if (extra_len &&
+ (extra = (char *) ALLOCATE_LOCAL (extra_len)))
+ {
+ memcpy (extra, stuff + 1, extra_len);
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ if (dst->u.pict.root)
+ {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ xRectangle *rects = (xRectangle *) (stuff + 1);
+ int i = extra_len / sizeof (xRectangle);
+
+ while (i--)
+ {
+ rects->x -= x_off;
+ rects->y -= y_off;
+ rects++;
+ }
+ }
+ }
+ stuff->dst = dst->info[j].id;
+ result = (*PanoramiXSaveRenderVector[X_RenderFillRectangles]) (client);
+ if(result != Success) break;
+ }
+ DEALLOCATE_LOCAL(extra);
+ }
+
+ return result;
+}
+
+static int
+PanoramiXRenderTrapezoids(ClientPtr client)
+{
+ PanoramiXRes *src, *dst;
+ int result = Success, j;
+ REQUEST(xRenderTrapezoidsReq);
+ char *extra;
+ int extra_len;
+
+ REQUEST_AT_LEAST_SIZE (xRenderTrapezoidsReq);
+
+ VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ extra_len = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq);
+
+ if (extra_len &&
+ (extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+ memcpy (extra, stuff + 1, extra_len);
+
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ if (dst->u.pict.root) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ xTrapezoid *trap = (xTrapezoid *) (stuff + 1);
+ int i = extra_len / sizeof (xTrapezoid);
+
+ while (i--) {
+ trap->top -= y_off;
+ trap->bottom -= y_off;
+ trap->left.p1.x -= x_off;
+ trap->left.p1.y -= y_off;
+ trap->left.p2.x -= x_off;
+ trap->left.p2.y -= y_off;
+ trap->right.p1.x -= x_off;
+ trap->right.p1.y -= y_off;
+ trap->right.p2.x -= x_off;
+ trap->right.p2.y -= y_off;
+ trap++;
+ }
+ }
+ }
+
+ stuff->src = src->info[j].id;
+ stuff->dst = dst->info[j].id;
+ result =
+ (*PanoramiXSaveRenderVector[X_RenderTrapezoids]) (client);
+
+ if(result != Success) break;
+ }
+
+ DEALLOCATE_LOCAL(extra);
+ }
+
+ return result;
+}
+
+static int
+PanoramiXRenderTriangles(ClientPtr client)
+{
+ PanoramiXRes *src, *dst;
+ int result = Success, j;
+ REQUEST(xRenderTrianglesReq);
+ char *extra;
+ int extra_len;
+
+ REQUEST_AT_LEAST_SIZE (xRenderTrianglesReq);
+
+ VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ extra_len = (client->req_len << 2) - sizeof (xRenderTrianglesReq);
+
+ if (extra_len &&
+ (extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+ memcpy (extra, stuff + 1, extra_len);
+
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ if (dst->u.pict.root) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ xTriangle *tri = (xTriangle *) (stuff + 1);
+ int i = extra_len / sizeof (xTriangle);
+
+ while (i--) {
+ tri->p1.x -= x_off;
+ tri->p1.y -= y_off;
+ tri->p2.x -= x_off;
+ tri->p2.y -= y_off;
+ tri->p3.x -= x_off;
+ tri->p3.y -= y_off;
+ tri++;
+ }
+ }
+ }
+
+ stuff->src = src->info[j].id;
+ stuff->dst = dst->info[j].id;
+ result =
+ (*PanoramiXSaveRenderVector[X_RenderTriangles]) (client);
+
+ if(result != Success) break;
+ }
+
+ DEALLOCATE_LOCAL(extra);
+ }
+
+ return result;
+}
+
+static int
+PanoramiXRenderTriStrip(ClientPtr client)
+{
+ PanoramiXRes *src, *dst;
+ int result = Success, j;
+ REQUEST(xRenderTriStripReq);
+ char *extra;
+ int extra_len;
+
+ REQUEST_AT_LEAST_SIZE (xRenderTriStripReq);
+
+ VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ extra_len = (client->req_len << 2) - sizeof (xRenderTriStripReq);
+
+ if (extra_len &&
+ (extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+ memcpy (extra, stuff + 1, extra_len);
+
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ if (dst->u.pict.root) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ xPointFixed *fixed = (xPointFixed *) (stuff + 1);
+ int i = extra_len / sizeof (xPointFixed);
+
+ while (i--) {
+ fixed->x -= x_off;
+ fixed->y -= y_off;
+ fixed++;
+ }
+ }
+ }
+
+ stuff->src = src->info[j].id;
+ stuff->dst = dst->info[j].id;
+ result =
+ (*PanoramiXSaveRenderVector[X_RenderTriStrip]) (client);
+
+ if(result != Success) break;
+ }
+
+ DEALLOCATE_LOCAL(extra);
+ }
+
+ return result;
+}
+
+static int
+PanoramiXRenderTriFan(ClientPtr client)
+{
+ PanoramiXRes *src, *dst;
+ int result = Success, j;
+ REQUEST(xRenderTriFanReq);
+ char *extra;
+ int extra_len;
+
+ REQUEST_AT_LEAST_SIZE (xRenderTriFanReq);
+
+ VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ extra_len = (client->req_len << 2) - sizeof (xRenderTriFanReq);
+
+ if (extra_len &&
+ (extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+ memcpy (extra, stuff + 1, extra_len);
+
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ if (dst->u.pict.root) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ xPointFixed *fixed = (xPointFixed *) (stuff + 1);
+ int i = extra_len / sizeof (xPointFixed);
+
+ while (i--) {
+ fixed->x -= x_off;
+ fixed->y -= y_off;
+ fixed++;
+ }
+ }
+ }
+
+ stuff->src = src->info[j].id;
+ stuff->dst = dst->info[j].id;
+ result =
+ (*PanoramiXSaveRenderVector[X_RenderTriFan]) (client);
+
+ if(result != Success) break;
+ }
+
+ DEALLOCATE_LOCAL(extra);
+ }
+
+ return result;
+}
+
+#if 0 /* Not implemented yet */
+
+static int
+PanoramiXRenderColorTrapezoids(ClientPtr client)
+{
+ PanoramiXRes *src, *dst;
+ int result = Success, j;
+ REQUEST(xRenderColorTrapezoidsReq);
+ char *extra;
+ int extra_len;
+
+ REQUEST_AT_LEAST_SIZE (xRenderColorTrapezoidsReq);
+
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ extra_len = (client->req_len << 2) - sizeof (xRenderColorTrapezoidsReq);
+
+ if (extra_len &&
+ (extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+ memcpy (extra, stuff + 1, extra_len);
+
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ if (dst->u.pict.root) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ ....;
+ }
+ }
+
+ stuff->dst = dst->info[j].id;
+ result =
+ (*PanoramiXSaveRenderVector[X_RenderColorTrapezoids]) (client);
+
+ if(result != Success) break;
+ }
+
+ DEALLOCATE_LOCAL(extra);
+ }
+
+ return result;
+}
+
+static int
+PanoramiXRenderColorTriangles(ClientPtr client)
+{
+ PanoramiXRes *src, *dst;
+ int result = Success, j;
+ REQUEST(xRenderColorTrianglesReq);
+ char *extra;
+ int extra_len;
+
+ REQUEST_AT_LEAST_SIZE (xRenderColorTrianglesReq);
+
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ extra_len = (client->req_len << 2) - sizeof (xRenderColorTrianglesReq);
+
+ if (extra_len &&
+ (extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+ memcpy (extra, stuff + 1, extra_len);
+
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ if (dst->u.pict.root) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ ....;
+ }
+ }
+
+ stuff->dst = dst->info[j].id;
+ result =
+ (*PanoramiXSaveRenderVector[X_RenderColorTriangles]) (client);
+
+ if(result != Success) break;
+ }
+
+ DEALLOCATE_LOCAL(extra);
+ }
+
+ return result;
+}
+
+#endif
+
+static int
+PanoramiXRenderAddTraps (ClientPtr client)
+{
+ PanoramiXRes *picture;
+ int result = Success, j;
+ REQUEST(xRenderAddTrapsReq);
+ char *extra;
+ int extra_len;
+ INT16 x_off, y_off;
+
+ REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq);
+ VERIFY_XIN_PICTURE (picture, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ extra_len = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
+ if (extra_len &&
+ (extra = (char *) ALLOCATE_LOCAL (extra_len)))
+ {
+ memcpy (extra, stuff + 1, extra_len);
+ x_off = stuff->xOff;
+ y_off = stuff->yOff;
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ stuff->picture = picture->info[j].id;
+
+ if (picture->u.pict.root)
+ {
+ stuff->xOff = x_off + panoramiXdataPtr[j].x;
+ stuff->yOff = y_off + panoramiXdataPtr[j].y;
+ }
+ result = (*PanoramiXSaveRenderVector[X_RenderAddTraps]) (client);
+ if(result != Success) break;
+ }
+ DEALLOCATE_LOCAL(extra);
+ }
+
+ return result;
+}
+
+void
+PanoramiXRenderInit (void)
+{
+ int i;
+
+ XRT_PICTURE = CreateNewResourceType (XineramaDeleteResource);
+ for (i = 0; i < RenderNumberRequests; i++)
+ PanoramiXSaveRenderVector[i] = ProcRenderVector[i];
+ /*
+ * Stuff in Xinerama aware request processing hooks
+ */
+ ProcRenderVector[X_RenderCreatePicture] = PanoramiXRenderCreatePicture;
+ ProcRenderVector[X_RenderChangePicture] = PanoramiXRenderChangePicture;
+ ProcRenderVector[X_RenderSetPictureTransform] = PanoramiXRenderSetPictureTransform;
+ ProcRenderVector[X_RenderSetPictureFilter] = PanoramiXRenderSetPictureFilter;
+ ProcRenderVector[X_RenderSetPictureClipRectangles] = PanoramiXRenderSetPictureClipRectangles;
+ ProcRenderVector[X_RenderFreePicture] = PanoramiXRenderFreePicture;
+ ProcRenderVector[X_RenderComposite] = PanoramiXRenderComposite;
+ ProcRenderVector[X_RenderCompositeGlyphs8] = PanoramiXRenderCompositeGlyphs;
+ ProcRenderVector[X_RenderCompositeGlyphs16] = PanoramiXRenderCompositeGlyphs;
+ ProcRenderVector[X_RenderCompositeGlyphs32] = PanoramiXRenderCompositeGlyphs;
+ ProcRenderVector[X_RenderFillRectangles] = PanoramiXRenderFillRectangles;
+
+ ProcRenderVector[X_RenderTrapezoids] = PanoramiXRenderTrapezoids;
+ ProcRenderVector[X_RenderTriangles] = PanoramiXRenderTriangles;
+ ProcRenderVector[X_RenderTriStrip] = PanoramiXRenderTriStrip;
+ ProcRenderVector[X_RenderTriFan] = PanoramiXRenderTriFan;
+ ProcRenderVector[X_RenderAddTraps] = PanoramiXRenderAddTraps;
+}
+
+void
+PanoramiXRenderReset (void)
+{
+ int i;
+ for (i = 0; i < RenderNumberRequests; i++)
+ ProcRenderVector[i] = PanoramiXSaveRenderVector[i];
+}
+
+#endif /* PANORAMIX */
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.X.original
new file mode 100644
index 000000000..d2759ab10
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.X.original
@@ -0,0 +1,3306 @@
+/* $XdotOrg: xc/programs/Xserver/render/render.c,v 1.12 2005/08/28 19:47:39 ajax Exp $ */
+/*
+ * $XFree86: xc/programs/Xserver/render/render.c,v 1.27tsi Exp $
+ *
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#define NEED_REPLIES
+#define NEED_EVENTS
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#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 "colormapst.h"
+#include "extnsionst.h"
+#include "servermd.h"
+#include <X11/extensions/render.h>
+#include <X11/extensions/renderproto.h>
+#include "picturestr.h"
+#include "glyphstr.h"
+#include <X11/Xfuncproto.h>
+#include "cursorstr.h"
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#endif
+
+#if !defined(UINT32_MAX)
+#define UINT32_MAX 0xffffffffU
+#endif
+
+static int ProcRenderQueryVersion (ClientPtr pClient);
+static int ProcRenderQueryPictFormats (ClientPtr pClient);
+static int ProcRenderQueryPictIndexValues (ClientPtr pClient);
+static int ProcRenderQueryDithers (ClientPtr pClient);
+static int ProcRenderCreatePicture (ClientPtr pClient);
+static int ProcRenderChangePicture (ClientPtr pClient);
+static int ProcRenderSetPictureClipRectangles (ClientPtr pClient);
+static int ProcRenderFreePicture (ClientPtr pClient);
+static int ProcRenderComposite (ClientPtr pClient);
+static int ProcRenderScale (ClientPtr pClient);
+static int ProcRenderTrapezoids (ClientPtr pClient);
+static int ProcRenderTriangles (ClientPtr pClient);
+static int ProcRenderTriStrip (ClientPtr pClient);
+static int ProcRenderTriFan (ClientPtr pClient);
+static int ProcRenderColorTrapezoids (ClientPtr pClient);
+static int ProcRenderColorTriangles (ClientPtr pClient);
+static int ProcRenderTransform (ClientPtr pClient);
+static int ProcRenderCreateGlyphSet (ClientPtr pClient);
+static int ProcRenderReferenceGlyphSet (ClientPtr pClient);
+static int ProcRenderFreeGlyphSet (ClientPtr pClient);
+static int ProcRenderAddGlyphs (ClientPtr pClient);
+static int ProcRenderAddGlyphsFromPicture (ClientPtr pClient);
+static int ProcRenderFreeGlyphs (ClientPtr pClient);
+static int ProcRenderCompositeGlyphs (ClientPtr pClient);
+static int ProcRenderFillRectangles (ClientPtr pClient);
+static int ProcRenderCreateCursor (ClientPtr pClient);
+static int ProcRenderSetPictureTransform (ClientPtr pClient);
+static int ProcRenderQueryFilters (ClientPtr pClient);
+static int ProcRenderSetPictureFilter (ClientPtr pClient);
+static int ProcRenderCreateAnimCursor (ClientPtr pClient);
+static int ProcRenderAddTraps (ClientPtr pClient);
+static int ProcRenderCreateSolidFill (ClientPtr pClient);
+static int ProcRenderCreateLinearGradient (ClientPtr pClient);
+static int ProcRenderCreateRadialGradient (ClientPtr pClient);
+static int ProcRenderCreateConicalGradient (ClientPtr pClient);
+
+static int ProcRenderDispatch (ClientPtr pClient);
+
+static int SProcRenderQueryVersion (ClientPtr pClient);
+static int SProcRenderQueryPictFormats (ClientPtr pClient);
+static int SProcRenderQueryPictIndexValues (ClientPtr pClient);
+static int SProcRenderQueryDithers (ClientPtr pClient);
+static int SProcRenderCreatePicture (ClientPtr pClient);
+static int SProcRenderChangePicture (ClientPtr pClient);
+static int SProcRenderSetPictureClipRectangles (ClientPtr pClient);
+static int SProcRenderFreePicture (ClientPtr pClient);
+static int SProcRenderComposite (ClientPtr pClient);
+static int SProcRenderScale (ClientPtr pClient);
+static int SProcRenderTrapezoids (ClientPtr pClient);
+static int SProcRenderTriangles (ClientPtr pClient);
+static int SProcRenderTriStrip (ClientPtr pClient);
+static int SProcRenderTriFan (ClientPtr pClient);
+static int SProcRenderColorTrapezoids (ClientPtr pClient);
+static int SProcRenderColorTriangles (ClientPtr pClient);
+static int SProcRenderTransform (ClientPtr pClient);
+static int SProcRenderCreateGlyphSet (ClientPtr pClient);
+static int SProcRenderReferenceGlyphSet (ClientPtr pClient);
+static int SProcRenderFreeGlyphSet (ClientPtr pClient);
+static int SProcRenderAddGlyphs (ClientPtr pClient);
+static int SProcRenderAddGlyphsFromPicture (ClientPtr pClient);
+static int SProcRenderFreeGlyphs (ClientPtr pClient);
+static int SProcRenderCompositeGlyphs (ClientPtr pClient);
+static int SProcRenderFillRectangles (ClientPtr pClient);
+static int SProcRenderCreateCursor (ClientPtr pClient);
+static int SProcRenderSetPictureTransform (ClientPtr pClient);
+static int SProcRenderQueryFilters (ClientPtr pClient);
+static int SProcRenderSetPictureFilter (ClientPtr pClient);
+static int SProcRenderCreateAnimCursor (ClientPtr pClient);
+static int SProcRenderAddTraps (ClientPtr pClient);
+static int SProcRenderCreateSolidFill (ClientPtr pClient);
+static int SProcRenderCreateLinearGradient (ClientPtr pClient);
+static int SProcRenderCreateRadialGradient (ClientPtr pClient);
+static int SProcRenderCreateConicalGradient (ClientPtr pClient);
+
+static int SProcRenderDispatch (ClientPtr pClient);
+
+int (*ProcRenderVector[RenderNumberRequests])(ClientPtr) = {
+ ProcRenderQueryVersion,
+ ProcRenderQueryPictFormats,
+ ProcRenderQueryPictIndexValues,
+ ProcRenderQueryDithers,
+ ProcRenderCreatePicture,
+ ProcRenderChangePicture,
+ ProcRenderSetPictureClipRectangles,
+ ProcRenderFreePicture,
+ ProcRenderComposite,
+ ProcRenderScale,
+ ProcRenderTrapezoids,
+ ProcRenderTriangles,
+ ProcRenderTriStrip,
+ ProcRenderTriFan,
+ ProcRenderColorTrapezoids,
+ ProcRenderColorTriangles,
+ ProcRenderTransform,
+ ProcRenderCreateGlyphSet,
+ ProcRenderReferenceGlyphSet,
+ ProcRenderFreeGlyphSet,
+ ProcRenderAddGlyphs,
+ ProcRenderAddGlyphsFromPicture,
+ ProcRenderFreeGlyphs,
+ ProcRenderCompositeGlyphs,
+ ProcRenderCompositeGlyphs,
+ ProcRenderCompositeGlyphs,
+ ProcRenderFillRectangles,
+ ProcRenderCreateCursor,
+ ProcRenderSetPictureTransform,
+ ProcRenderQueryFilters,
+ ProcRenderSetPictureFilter,
+ ProcRenderCreateAnimCursor,
+ ProcRenderAddTraps,
+ ProcRenderCreateSolidFill,
+ ProcRenderCreateLinearGradient,
+ ProcRenderCreateRadialGradient,
+ ProcRenderCreateConicalGradient
+};
+
+int (*SProcRenderVector[RenderNumberRequests])(ClientPtr) = {
+ SProcRenderQueryVersion,
+ SProcRenderQueryPictFormats,
+ SProcRenderQueryPictIndexValues,
+ SProcRenderQueryDithers,
+ SProcRenderCreatePicture,
+ SProcRenderChangePicture,
+ SProcRenderSetPictureClipRectangles,
+ SProcRenderFreePicture,
+ SProcRenderComposite,
+ SProcRenderScale,
+ SProcRenderTrapezoids,
+ SProcRenderTriangles,
+ SProcRenderTriStrip,
+ SProcRenderTriFan,
+ SProcRenderColorTrapezoids,
+ SProcRenderColorTriangles,
+ SProcRenderTransform,
+ SProcRenderCreateGlyphSet,
+ SProcRenderReferenceGlyphSet,
+ SProcRenderFreeGlyphSet,
+ SProcRenderAddGlyphs,
+ SProcRenderAddGlyphsFromPicture,
+ SProcRenderFreeGlyphs,
+ SProcRenderCompositeGlyphs,
+ SProcRenderCompositeGlyphs,
+ SProcRenderCompositeGlyphs,
+ SProcRenderFillRectangles,
+ SProcRenderCreateCursor,
+ SProcRenderSetPictureTransform,
+ SProcRenderQueryFilters,
+ SProcRenderSetPictureFilter,
+ SProcRenderCreateAnimCursor,
+ SProcRenderAddTraps,
+ SProcRenderCreateSolidFill,
+ SProcRenderCreateLinearGradient,
+ SProcRenderCreateRadialGradient,
+ SProcRenderCreateConicalGradient
+};
+
+static void
+RenderResetProc (ExtensionEntry *extEntry);
+
+#if 0
+static CARD8 RenderReqCode;
+#endif
+int RenderErrBase;
+int RenderClientPrivateIndex;
+
+typedef struct _RenderClient {
+ int major_version;
+ int minor_version;
+} RenderClientRec, *RenderClientPtr;
+
+#define GetRenderClient(pClient) ((RenderClientPtr) (pClient)->devPrivates[RenderClientPrivateIndex].ptr)
+
+static void
+RenderClientCallback (CallbackListPtr *list,
+ pointer closure,
+ pointer data)
+{
+ NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
+ ClientPtr pClient = clientinfo->client;
+ RenderClientPtr pRenderClient = GetRenderClient (pClient);
+
+ pRenderClient->major_version = 0;
+ pRenderClient->minor_version = 0;
+}
+
+void
+RenderExtensionInit (void)
+{
+ ExtensionEntry *extEntry;
+
+ if (!PictureType)
+ return;
+ if (!PictureFinishInit ())
+ return;
+ RenderClientPrivateIndex = AllocateClientPrivateIndex ();
+ if (!AllocateClientPrivate (RenderClientPrivateIndex,
+ sizeof (RenderClientRec)))
+ return;
+ if (!AddCallback (&ClientStateCallback, RenderClientCallback, 0))
+ return;
+
+ extEntry = AddExtension (RENDER_NAME, 0, RenderNumberErrors,
+ ProcRenderDispatch, SProcRenderDispatch,
+ RenderResetProc, StandardMinorOpcode);
+ if (!extEntry)
+ return;
+#if 0
+ RenderReqCode = (CARD8) extEntry->base;
+#endif
+ RenderErrBase = extEntry->errorBase;
+}
+
+static void
+RenderResetProc (ExtensionEntry *extEntry)
+{
+ ResetPicturePrivateIndex();
+ ResetGlyphSetPrivateIndex();
+}
+
+static int
+ProcRenderQueryVersion (ClientPtr client)
+{
+ RenderClientPtr pRenderClient = GetRenderClient (client);
+ xRenderQueryVersionReply rep;
+ register int n;
+ REQUEST(xRenderQueryVersionReq);
+
+ pRenderClient->major_version = stuff->majorVersion;
+ pRenderClient->minor_version = stuff->minorVersion;
+
+ REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = RENDER_MAJOR;
+ rep.minorVersion = RENDER_MINOR;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.majorVersion, n);
+ swapl(&rep.minorVersion, n);
+ }
+ WriteToClient(client, sizeof(xRenderQueryVersionReply), (char *)&rep);
+ return (client->noClientException);
+}
+
+#if 0
+static int
+VisualDepth (ScreenPtr pScreen, VisualPtr pVisual)
+{
+ DepthPtr pDepth;
+ int d, v;
+
+ for (d = 0; d < pScreen->numDepths; d++)
+ {
+ pDepth = pScreen->allowedDepths + d;
+ for (v = 0; v < pDepth->numVids; v++)
+ {
+ if (pDepth->vids[v] == pVisual->vid)
+ return pDepth->depth;
+ }
+ }
+ return 0;
+}
+#endif
+
+static VisualPtr
+findVisual (ScreenPtr pScreen, VisualID vid)
+{
+ VisualPtr pVisual;
+ int v;
+
+ for (v = 0; v < pScreen->numVisuals; v++)
+ {
+ pVisual = pScreen->visuals + v;
+ if (pVisual->vid == vid)
+ return pVisual;
+ }
+ return 0;
+}
+
+extern char *ConnectionInfo;
+
+static int
+ProcRenderQueryPictFormats (ClientPtr client)
+{
+ RenderClientPtr pRenderClient = GetRenderClient (client);
+ xRenderQueryPictFormatsReply *reply;
+ xPictScreen *pictScreen;
+ xPictDepth *pictDepth;
+ xPictVisual *pictVisual;
+ xPictFormInfo *pictForm;
+ CARD32 *pictSubpixel;
+ ScreenPtr pScreen;
+ VisualPtr pVisual;
+ DepthPtr pDepth;
+ int v, d;
+ PictureScreenPtr ps;
+ PictFormatPtr pFormat;
+ int nformat;
+ int ndepth;
+ int nvisual;
+ int rlength;
+ int s;
+ int n;
+ int numScreens;
+ int numSubpixel;
+/* REQUEST(xRenderQueryPictFormatsReq); */
+
+ REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
+
+#ifdef PANORAMIX
+ if (noPanoramiXExtension)
+ numScreens = screenInfo.numScreens;
+ else
+ numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
+#else
+ numScreens = screenInfo.numScreens;
+#endif
+ ndepth = nformat = nvisual = 0;
+ for (s = 0; s < numScreens; s++)
+ {
+ pScreen = screenInfo.screens[s];
+ for (d = 0; d < pScreen->numDepths; d++)
+ {
+ pDepth = pScreen->allowedDepths + d;
+ ++ndepth;
+
+ for (v = 0; v < pDepth->numVids; v++)
+ {
+ pVisual = findVisual (pScreen, pDepth->vids[v]);
+ if (pVisual && PictureMatchVisual (pScreen, pDepth->depth, pVisual))
+ ++nvisual;
+ }
+ }
+ ps = GetPictureScreenIfSet(pScreen);
+ if (ps)
+ nformat += ps->nformats;
+ }
+ if (pRenderClient->major_version == 0 && pRenderClient->minor_version < 6)
+ numSubpixel = 0;
+ else
+ numSubpixel = numScreens;
+
+ rlength = (sizeof (xRenderQueryPictFormatsReply) +
+ nformat * sizeof (xPictFormInfo) +
+ numScreens * sizeof (xPictScreen) +
+ ndepth * sizeof (xPictDepth) +
+ nvisual * sizeof (xPictVisual) +
+ numSubpixel * sizeof (CARD32));
+ reply = (xRenderQueryPictFormatsReply *) xalloc (rlength);
+ if (!reply)
+ return BadAlloc;
+ reply->type = X_Reply;
+ reply->sequenceNumber = client->sequence;
+ reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+ reply->numFormats = nformat;
+ reply->numScreens = numScreens;
+ reply->numDepths = ndepth;
+ reply->numVisuals = nvisual;
+ reply->numSubpixel = numSubpixel;
+
+ pictForm = (xPictFormInfo *) (reply + 1);
+
+ for (s = 0; s < numScreens; s++)
+ {
+ pScreen = screenInfo.screens[s];
+ ps = GetPictureScreenIfSet(pScreen);
+ if (ps)
+ {
+ for (nformat = 0, pFormat = ps->formats;
+ nformat < ps->nformats;
+ nformat++, pFormat++)
+ {
+ pictForm->id = pFormat->id;
+ pictForm->type = pFormat->type;
+ pictForm->depth = pFormat->depth;
+ pictForm->direct.red = pFormat->direct.red;
+ pictForm->direct.redMask = pFormat->direct.redMask;
+ pictForm->direct.green = pFormat->direct.green;
+ pictForm->direct.greenMask = pFormat->direct.greenMask;
+ pictForm->direct.blue = pFormat->direct.blue;
+ pictForm->direct.blueMask = pFormat->direct.blueMask;
+ pictForm->direct.alpha = pFormat->direct.alpha;
+ pictForm->direct.alphaMask = pFormat->direct.alphaMask;
+ if (pFormat->type == PictTypeIndexed && pFormat->index.pColormap)
+ pictForm->colormap = pFormat->index.pColormap->mid;
+ else
+ pictForm->colormap = None;
+ if (client->swapped)
+ {
+ swapl (&pictForm->id, n);
+ swaps (&pictForm->direct.red, n);
+ swaps (&pictForm->direct.redMask, n);
+ swaps (&pictForm->direct.green, n);
+ swaps (&pictForm->direct.greenMask, n);
+ swaps (&pictForm->direct.blue, n);
+ swaps (&pictForm->direct.blueMask, n);
+ swaps (&pictForm->direct.alpha, n);
+ swaps (&pictForm->direct.alphaMask, n);
+ swapl (&pictForm->colormap, n);
+ }
+ pictForm++;
+ }
+ }
+ }
+
+ pictScreen = (xPictScreen *) pictForm;
+ for (s = 0; s < numScreens; s++)
+ {
+ pScreen = screenInfo.screens[s];
+ pictDepth = (xPictDepth *) (pictScreen + 1);
+ ndepth = 0;
+ for (d = 0; d < pScreen->numDepths; d++)
+ {
+ pictVisual = (xPictVisual *) (pictDepth + 1);
+ pDepth = pScreen->allowedDepths + d;
+
+ nvisual = 0;
+ for (v = 0; v < pDepth->numVids; v++)
+ {
+ pVisual = findVisual (pScreen, pDepth->vids[v]);
+ if (pVisual && (pFormat = PictureMatchVisual (pScreen,
+ pDepth->depth,
+ pVisual)))
+ {
+ pictVisual->visual = pVisual->vid;
+ pictVisual->format = pFormat->id;
+ if (client->swapped)
+ {
+ swapl (&pictVisual->visual, n);
+ swapl (&pictVisual->format, n);
+ }
+ pictVisual++;
+ nvisual++;
+ }
+ }
+ pictDepth->depth = pDepth->depth;
+ pictDepth->nPictVisuals = nvisual;
+ if (client->swapped)
+ {
+ swaps (&pictDepth->nPictVisuals, n);
+ }
+ ndepth++;
+ pictDepth = (xPictDepth *) pictVisual;
+ }
+ pictScreen->nDepth = ndepth;
+ ps = GetPictureScreenIfSet(pScreen);
+ if (ps)
+ pictScreen->fallback = ps->fallback->id;
+ else
+ pictScreen->fallback = 0;
+ if (client->swapped)
+ {
+ swapl (&pictScreen->nDepth, n);
+ swapl (&pictScreen->fallback, n);
+ }
+ pictScreen = (xPictScreen *) pictDepth;
+ }
+ pictSubpixel = (CARD32 *) pictScreen;
+
+ for (s = 0; s < numSubpixel; s++)
+ {
+ pScreen = screenInfo.screens[s];
+ ps = GetPictureScreenIfSet(pScreen);
+ if (ps)
+ *pictSubpixel = ps->subpixel;
+ else
+ *pictSubpixel = SubPixelUnknown;
+ if (client->swapped)
+ {
+ swapl (pictSubpixel, n);
+ }
+ ++pictSubpixel;
+ }
+
+ if (client->swapped)
+ {
+ swaps (&reply->sequenceNumber, n);
+ swapl (&reply->length, n);
+ swapl (&reply->numFormats, n);
+ swapl (&reply->numScreens, n);
+ swapl (&reply->numDepths, n);
+ swapl (&reply->numVisuals, n);
+ swapl (&reply->numSubpixel, n);
+ }
+ WriteToClient(client, rlength, (char *) reply);
+ xfree (reply);
+ return client->noClientException;
+}
+
+static int
+ProcRenderQueryPictIndexValues (ClientPtr client)
+{
+ PictFormatPtr pFormat;
+ int num;
+ int rlength;
+ int i, n;
+ REQUEST(xRenderQueryPictIndexValuesReq);
+ xRenderQueryPictIndexValuesReply *reply;
+ xIndexValue *values;
+
+ REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq);
+
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->format,
+ PictFormatType,
+ SecurityReadAccess);
+
+ if (!pFormat)
+ {
+ client->errorValue = stuff->format;
+ return RenderErrBase + BadPictFormat;
+ }
+ if (pFormat->type != PictTypeIndexed)
+ {
+ client->errorValue = stuff->format;
+ return BadMatch;
+ }
+ num = pFormat->index.nvalues;
+ rlength = (sizeof (xRenderQueryPictIndexValuesReply) +
+ num * sizeof(xIndexValue));
+ reply = (xRenderQueryPictIndexValuesReply *) xalloc (rlength);
+ if (!reply)
+ return BadAlloc;
+
+ reply->type = X_Reply;
+ reply->sequenceNumber = client->sequence;
+ reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+ reply->numIndexValues = num;
+
+ values = (xIndexValue *) (reply + 1);
+
+ memcpy (reply + 1, pFormat->index.pValues, num * sizeof (xIndexValue));
+
+ if (client->swapped)
+ {
+ for (i = 0; i < num; i++)
+ {
+ swapl (&values[i].pixel, n);
+ swaps (&values[i].red, n);
+ swaps (&values[i].green, n);
+ swaps (&values[i].blue, n);
+ swaps (&values[i].alpha, n);
+ }
+ swaps (&reply->sequenceNumber, n);
+ swapl (&reply->length, n);
+ swapl (&reply->numIndexValues, n);
+ }
+
+ WriteToClient(client, rlength, (char *) reply);
+ xfree(reply);
+ return (client->noClientException);
+}
+
+static int
+ProcRenderQueryDithers (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+ProcRenderCreatePicture (ClientPtr client)
+{
+ PicturePtr pPicture;
+ DrawablePtr pDrawable;
+ PictFormatPtr pFormat;
+ int len;
+ int error;
+ REQUEST(xRenderCreatePictureReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
+
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+ SECURITY_VERIFY_DRAWABLE(pDrawable, stuff->drawable, client,
+ SecurityWriteAccess);
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->format,
+ PictFormatType,
+ SecurityReadAccess);
+ if (!pFormat)
+ {
+ client->errorValue = stuff->format;
+ return RenderErrBase + BadPictFormat;
+ }
+ if (pFormat->depth != pDrawable->depth)
+ return BadMatch;
+ len = client->req_len - (sizeof(xRenderCreatePictureReq) >> 2);
+ if (Ones(stuff->mask) != len)
+ return BadLength;
+
+ pPicture = CreatePicture (stuff->pid,
+ pDrawable,
+ pFormat,
+ stuff->mask,
+ (XID *) (stuff + 1),
+ client,
+ &error);
+ if (!pPicture)
+ return error;
+ if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+ return BadAlloc;
+ return Success;
+}
+
+static int
+ProcRenderChangePicture (ClientPtr client)
+{
+ PicturePtr pPicture;
+ REQUEST(xRenderChangePictureReq);
+ int len;
+
+ REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
+ VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ len = client->req_len - (sizeof(xRenderChangePictureReq) >> 2);
+ if (Ones(stuff->mask) != len)
+ return BadLength;
+
+ return ChangePicture (pPicture, stuff->mask, (XID *) (stuff + 1),
+ (DevUnion *) 0, client);
+}
+
+static int
+ProcRenderSetPictureClipRectangles (ClientPtr client)
+{
+ REQUEST(xRenderSetPictureClipRectanglesReq);
+ PicturePtr pPicture;
+ int nr;
+ int result;
+
+ REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
+ VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pPicture->pDrawable)
+ return BadDrawable;
+
+ nr = (client->req_len << 2) - sizeof(xRenderChangePictureReq);
+ if (nr & 4)
+ return BadLength;
+ nr >>= 3;
+ result = SetPictureClipRects (pPicture,
+ stuff->xOrigin, stuff->yOrigin,
+ nr, (xRectangle *) &stuff[1]);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+static int
+ProcRenderFreePicture (ClientPtr client)
+{
+ PicturePtr pPicture;
+ REQUEST(xRenderFreePictureReq);
+
+ REQUEST_SIZE_MATCH(xRenderFreePictureReq);
+
+ VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityDestroyAccess,
+ RenderErrBase + BadPicture);
+ FreeResource (stuff->picture, RT_NONE);
+ return(client->noClientException);
+}
+
+static Bool
+PictOpValid (CARD8 op)
+{
+ if (/*PictOpMinimum <= op && */ op <= PictOpMaximum)
+ return TRUE;
+ if (PictOpDisjointMinimum <= op && op <= PictOpDisjointMaximum)
+ return TRUE;
+ if (PictOpConjointMinimum <= op && op <= PictOpConjointMaximum)
+ return TRUE;
+ return FALSE;
+}
+
+static int
+ProcRenderComposite (ClientPtr client)
+{
+ PicturePtr pSrc, pMask, pDst;
+ REQUEST(xRenderCompositeReq);
+
+ REQUEST_SIZE_MATCH(xRenderCompositeReq);
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_ALPHA (pMask, stuff->mask, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) ||
+ (pMask && pMask->pDrawable && pSrc->pDrawable->pScreen != pMask->pDrawable->pScreen))
+ return BadMatch;
+ CompositePicture (stuff->op,
+ pSrc,
+ pMask,
+ pDst,
+ stuff->xSrc,
+ stuff->ySrc,
+ stuff->xMask,
+ stuff->yMask,
+ stuff->xDst,
+ stuff->yDst,
+ stuff->width,
+ stuff->height);
+ return Success;
+}
+
+static int
+ProcRenderScale (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+ProcRenderTrapezoids (ClientPtr client)
+{
+ int ntraps;
+ PicturePtr pSrc, pDst;
+ PictFormatPtr pFormat;
+ REQUEST(xRenderTrapezoidsReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+ return BadMatch;
+ if (stuff->maskFormat)
+ {
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->maskFormat,
+ PictFormatType,
+ SecurityReadAccess);
+ if (!pFormat)
+ {
+ client->errorValue = stuff->maskFormat;
+ return RenderErrBase + BadPictFormat;
+ }
+ }
+ else
+ pFormat = 0;
+ ntraps = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq);
+ if (ntraps % sizeof (xTrapezoid))
+ return BadLength;
+ ntraps /= sizeof (xTrapezoid);
+ if (ntraps)
+ CompositeTrapezoids (stuff->op, pSrc, pDst, pFormat,
+ stuff->xSrc, stuff->ySrc,
+ ntraps, (xTrapezoid *) &stuff[1]);
+ return client->noClientException;
+}
+
+static int
+ProcRenderTriangles (ClientPtr client)
+{
+ int ntris;
+ PicturePtr pSrc, pDst;
+ PictFormatPtr pFormat;
+ REQUEST(xRenderTrianglesReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+ return BadMatch;
+ if (stuff->maskFormat)
+ {
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->maskFormat,
+ PictFormatType,
+ SecurityReadAccess);
+ if (!pFormat)
+ {
+ client->errorValue = stuff->maskFormat;
+ return RenderErrBase + BadPictFormat;
+ }
+ }
+ else
+ pFormat = 0;
+ ntris = (client->req_len << 2) - sizeof (xRenderTrianglesReq);
+ if (ntris % sizeof (xTriangle))
+ return BadLength;
+ ntris /= sizeof (xTriangle);
+ if (ntris)
+ CompositeTriangles (stuff->op, pSrc, pDst, pFormat,
+ stuff->xSrc, stuff->ySrc,
+ ntris, (xTriangle *) &stuff[1]);
+ return client->noClientException;
+}
+
+static int
+ProcRenderTriStrip (ClientPtr client)
+{
+ int npoints;
+ PicturePtr pSrc, pDst;
+ PictFormatPtr pFormat;
+ REQUEST(xRenderTrianglesReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+ return BadMatch;
+ if (stuff->maskFormat)
+ {
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->maskFormat,
+ PictFormatType,
+ SecurityReadAccess);
+ if (!pFormat)
+ {
+ client->errorValue = stuff->maskFormat;
+ return RenderErrBase + BadPictFormat;
+ }
+ }
+ else
+ pFormat = 0;
+ npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq));
+ if (npoints & 4)
+ return(BadLength);
+ npoints >>= 3;
+ if (npoints >= 3)
+ CompositeTriStrip (stuff->op, pSrc, pDst, pFormat,
+ stuff->xSrc, stuff->ySrc,
+ npoints, (xPointFixed *) &stuff[1]);
+ return client->noClientException;
+}
+
+static int
+ProcRenderTriFan (ClientPtr client)
+{
+ int npoints;
+ PicturePtr pSrc, pDst;
+ PictFormatPtr pFormat;
+ REQUEST(xRenderTrianglesReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+ return BadMatch;
+ if (stuff->maskFormat)
+ {
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->maskFormat,
+ PictFormatType,
+ SecurityReadAccess);
+ if (!pFormat)
+ {
+ client->errorValue = stuff->maskFormat;
+ return RenderErrBase + BadPictFormat;
+ }
+ }
+ else
+ pFormat = 0;
+ npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq));
+ if (npoints & 4)
+ return(BadLength);
+ npoints >>= 3;
+ if (npoints >= 3)
+ CompositeTriFan (stuff->op, pSrc, pDst, pFormat,
+ stuff->xSrc, stuff->ySrc,
+ npoints, (xPointFixed *) &stuff[1]);
+ return client->noClientException;
+}
+
+static int
+ProcRenderColorTrapezoids (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+ProcRenderColorTriangles (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+ProcRenderTransform (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+ProcRenderCreateGlyphSet (ClientPtr client)
+{
+ GlyphSetPtr glyphSet;
+ PictFormatPtr format;
+ int f;
+ REQUEST(xRenderCreateGlyphSetReq);
+
+ REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
+
+ LEGAL_NEW_RESOURCE(stuff->gsid, client);
+ format = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->format,
+ PictFormatType,
+ SecurityReadAccess);
+ if (!format)
+ {
+ client->errorValue = stuff->format;
+ return RenderErrBase + BadPictFormat;
+ }
+ switch (format->depth) {
+ case 1:
+ f = GlyphFormat1;
+ break;
+ case 4:
+ f = GlyphFormat4;
+ break;
+ case 8:
+ f = GlyphFormat8;
+ break;
+ case 16:
+ f = GlyphFormat16;
+ break;
+ case 32:
+ f = GlyphFormat32;
+ break;
+ default:
+ return BadMatch;
+ }
+ if (format->type != PictTypeDirect)
+ return BadMatch;
+ glyphSet = AllocateGlyphSet (f, format);
+ if (!glyphSet)
+ return BadAlloc;
+ if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
+ return BadAlloc;
+ return Success;
+}
+
+static int
+ProcRenderReferenceGlyphSet (ClientPtr client)
+{
+ GlyphSetPtr glyphSet;
+ REQUEST(xRenderReferenceGlyphSetReq);
+
+ REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);
+
+ LEGAL_NEW_RESOURCE(stuff->gsid, client);
+
+ glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ stuff->existing,
+ GlyphSetType,
+ SecurityWriteAccess);
+ if (!glyphSet)
+ {
+ client->errorValue = stuff->existing;
+ return RenderErrBase + BadGlyphSet;
+ }
+ glyphSet->refcnt++;
+ if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
+ return BadAlloc;
+ return client->noClientException;
+}
+
+#define NLOCALDELTA 64
+#define NLOCALGLYPH 256
+
+static int
+ProcRenderFreeGlyphSet (ClientPtr client)
+{
+ GlyphSetPtr glyphSet;
+ REQUEST(xRenderFreeGlyphSetReq);
+
+ REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
+ glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ stuff->glyphset,
+ GlyphSetType,
+ SecurityDestroyAccess);
+ if (!glyphSet)
+ {
+ client->errorValue = stuff->glyphset;
+ return RenderErrBase + BadGlyphSet;
+ }
+ FreeResource (stuff->glyphset, RT_NONE);
+ return client->noClientException;
+}
+
+typedef struct _GlyphNew {
+ Glyph id;
+ GlyphPtr glyph;
+} GlyphNewRec, *GlyphNewPtr;
+
+static int
+ProcRenderAddGlyphs (ClientPtr client)
+{
+ GlyphSetPtr glyphSet;
+ REQUEST(xRenderAddGlyphsReq);
+ GlyphNewRec glyphsLocal[NLOCALGLYPH];
+ GlyphNewPtr glyphsBase, glyphs;
+ GlyphPtr glyph;
+ int remain, nglyphs;
+ CARD32 *gids;
+ xGlyphInfo *gi;
+ CARD8 *bits;
+ int size;
+ int err = BadAlloc;
+
+ REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
+ glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ stuff->glyphset,
+ GlyphSetType,
+ SecurityWriteAccess);
+ if (!glyphSet)
+ {
+ client->errorValue = stuff->glyphset;
+ return RenderErrBase + BadGlyphSet;
+ }
+
+ nglyphs = stuff->nglyphs;
+ if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec))
+ return BadAlloc;
+
+ if (nglyphs <= NLOCALGLYPH)
+ glyphsBase = glyphsLocal;
+ else
+ {
+ glyphsBase = (GlyphNewPtr) Xalloc (nglyphs * sizeof (GlyphNewRec));
+ if (!glyphsBase)
+ return BadAlloc;
+ }
+
+ remain = (client->req_len << 2) - sizeof (xRenderAddGlyphsReq);
+
+ glyphs = glyphsBase;
+
+ gids = (CARD32 *) (stuff + 1);
+ gi = (xGlyphInfo *) (gids + nglyphs);
+ bits = (CARD8 *) (gi + nglyphs);
+ remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs;
+ while (remain >= 0 && nglyphs)
+ {
+ glyph = AllocateGlyph (gi, glyphSet->fdepth);
+ if (!glyph)
+ {
+ err = BadAlloc;
+ goto bail;
+ }
+
+ glyphs->glyph = glyph;
+ glyphs->id = *gids;
+
+ size = glyph->size - sizeof (xGlyphInfo);
+ if (remain < size)
+ break;
+ memcpy ((CARD8 *) (glyph + 1), bits, size);
+
+ if (size & 3)
+ size += 4 - (size & 3);
+ bits += size;
+ remain -= size;
+ gi++;
+ gids++;
+ glyphs++;
+ nglyphs--;
+ }
+ if (nglyphs || remain)
+ {
+ err = BadLength;
+ goto bail;
+ }
+ nglyphs = stuff->nglyphs;
+ if (!ResizeGlyphSet (glyphSet, nglyphs))
+ {
+ err = BadAlloc;
+ goto bail;
+ }
+ glyphs = glyphsBase;
+ while (nglyphs--) {
+ AddGlyph (glyphSet, glyphs->glyph, glyphs->id);
+ glyphs++;
+ }
+
+ if (glyphsBase != glyphsLocal)
+ Xfree (glyphsBase);
+ return client->noClientException;
+bail:
+ while (glyphs != glyphsBase)
+ {
+ --glyphs;
+ xfree (glyphs->glyph);
+ }
+ if (glyphsBase != glyphsLocal)
+ Xfree (glyphsBase);
+ return err;
+}
+
+static int
+ProcRenderAddGlyphsFromPicture (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+ProcRenderFreeGlyphs (ClientPtr client)
+{
+ REQUEST(xRenderFreeGlyphsReq);
+ GlyphSetPtr glyphSet;
+ int nglyph;
+ CARD32 *gids;
+ CARD32 glyph;
+
+ REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
+ glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ stuff->glyphset,
+ GlyphSetType,
+ SecurityWriteAccess);
+ if (!glyphSet)
+ {
+ client->errorValue = stuff->glyphset;
+ return RenderErrBase + BadGlyphSet;
+ }
+ nglyph = ((client->req_len << 2) - sizeof (xRenderFreeGlyphsReq)) >> 2;
+ gids = (CARD32 *) (stuff + 1);
+ while (nglyph-- > 0)
+ {
+ glyph = *gids++;
+ if (!DeleteGlyph (glyphSet, glyph))
+ {
+ client->errorValue = glyph;
+ return RenderErrBase + BadGlyph;
+ }
+ }
+ return client->noClientException;
+}
+
+static int
+ProcRenderCompositeGlyphs (ClientPtr client)
+{
+ GlyphSetPtr glyphSet;
+ GlyphSet gs;
+ PicturePtr pSrc, pDst;
+ PictFormatPtr pFormat;
+ GlyphListRec listsLocal[NLOCALDELTA];
+ GlyphListPtr lists, listsBase;
+ GlyphPtr glyphsLocal[NLOCALGLYPH];
+ Glyph glyph;
+ GlyphPtr *glyphs, *glyphsBase;
+ xGlyphElt *elt;
+ CARD8 *buffer, *end;
+ int nglyph;
+ int nlist;
+ int space;
+ int size;
+ int n;
+
+ REQUEST(xRenderCompositeGlyphsReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
+
+ switch (stuff->renderReqType) {
+ default: size = 1; break;
+ case X_RenderCompositeGlyphs16: size = 2; break;
+ case X_RenderCompositeGlyphs32: size = 4; break;
+ }
+
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+ return BadMatch;
+ if (stuff->maskFormat)
+ {
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->maskFormat,
+ PictFormatType,
+ SecurityReadAccess);
+ if (!pFormat)
+ {
+ client->errorValue = stuff->maskFormat;
+ return RenderErrBase + BadPictFormat;
+ }
+ }
+ else
+ pFormat = 0;
+
+ glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ stuff->glyphset,
+ GlyphSetType,
+ SecurityReadAccess);
+ if (!glyphSet)
+ {
+ client->errorValue = stuff->glyphset;
+ return RenderErrBase + BadGlyphSet;
+ }
+
+ buffer = (CARD8 *) (stuff + 1);
+ end = (CARD8 *) stuff + (client->req_len << 2);
+ nglyph = 0;
+ nlist = 0;
+ while (buffer + sizeof (xGlyphElt) < end)
+ {
+ elt = (xGlyphElt *) buffer;
+ buffer += sizeof (xGlyphElt);
+
+ if (elt->len == 0xff)
+ {
+ buffer += 4;
+ }
+ else
+ {
+ nlist++;
+ nglyph += elt->len;
+ space = size * elt->len;
+ if (space & 3)
+ space += 4 - (space & 3);
+ buffer += space;
+ }
+ }
+ if (nglyph <= NLOCALGLYPH)
+ glyphsBase = glyphsLocal;
+ else
+ {
+ glyphsBase = (GlyphPtr *) ALLOCATE_LOCAL (nglyph * sizeof (GlyphPtr));
+ if (!glyphsBase)
+ return BadAlloc;
+ }
+ if (nlist <= NLOCALDELTA)
+ listsBase = listsLocal;
+ else
+ {
+ listsBase = (GlyphListPtr) ALLOCATE_LOCAL (nlist * sizeof (GlyphListRec));
+ if (!listsBase)
+ return BadAlloc;
+ }
+ buffer = (CARD8 *) (stuff + 1);
+ glyphs = glyphsBase;
+ lists = listsBase;
+ while (buffer + sizeof (xGlyphElt) < end)
+ {
+ elt = (xGlyphElt *) buffer;
+ buffer += sizeof (xGlyphElt);
+
+ if (elt->len == 0xff)
+ {
+ if (buffer + sizeof (GlyphSet) < end)
+ {
+ memcpy(&gs, buffer, sizeof(GlyphSet));
+ glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ gs,
+ GlyphSetType,
+ SecurityReadAccess);
+ if (!glyphSet)
+ {
+ client->errorValue = gs;
+ if (glyphsBase != glyphsLocal)
+ DEALLOCATE_LOCAL (glyphsBase);
+ if (listsBase != listsLocal)
+ DEALLOCATE_LOCAL (listsBase);
+ return RenderErrBase + BadGlyphSet;
+ }
+ }
+ buffer += 4;
+ }
+ else
+ {
+ lists->xOff = elt->deltax;
+ lists->yOff = elt->deltay;
+ lists->format = glyphSet->format;
+ lists->len = 0;
+ n = elt->len;
+ while (n--)
+ {
+ if (buffer + size <= end)
+ {
+ switch (size) {
+ case 1:
+ glyph = *((CARD8 *)buffer); break;
+ case 2:
+ glyph = *((CARD16 *)buffer); break;
+ case 4:
+ default:
+ glyph = *((CARD32 *)buffer); break;
+ }
+ if ((*glyphs = FindGlyph (glyphSet, glyph)))
+ {
+ lists->len++;
+ glyphs++;
+ }
+ }
+ buffer += size;
+ }
+ space = size * elt->len;
+ if (space & 3)
+ buffer += 4 - (space & 3);
+ lists++;
+ }
+ }
+ if (buffer > end)
+ return BadLength;
+
+ CompositeGlyphs (stuff->op,
+ pSrc,
+ pDst,
+ pFormat,
+ stuff->xSrc,
+ stuff->ySrc,
+ nlist,
+ listsBase,
+ glyphsBase);
+
+ if (glyphsBase != glyphsLocal)
+ DEALLOCATE_LOCAL (glyphsBase);
+ if (listsBase != listsLocal)
+ DEALLOCATE_LOCAL (listsBase);
+
+ return client->noClientException;
+}
+
+static int
+ProcRenderFillRectangles (ClientPtr client)
+{
+ PicturePtr pDst;
+ int things;
+ REQUEST(xRenderFillRectanglesReq);
+
+ REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+
+ things = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq);
+ if (things & 4)
+ return(BadLength);
+ things >>= 3;
+
+ CompositeRects (stuff->op,
+ pDst,
+ &stuff->color,
+ things,
+ (xRectangle *) &stuff[1]);
+
+ return client->noClientException;
+}
+
+static void
+SetBit (unsigned char *line, int x, int bit)
+{
+ unsigned char mask;
+
+ if (screenInfo.bitmapBitOrder == LSBFirst)
+ mask = (1 << (x & 7));
+ else
+ mask = (0x80 >> (x & 7));
+ /* XXX assumes byte order is host byte order */
+ line += (x >> 3);
+ if (bit)
+ *line |= mask;
+ else
+ *line &= ~mask;
+}
+
+#define DITHER_DIM 2
+
+static CARD32 orderedDither[DITHER_DIM][DITHER_DIM] = {
+ { 1, 3, },
+ { 4, 2, },
+};
+
+#define DITHER_SIZE ((sizeof orderedDither / sizeof orderedDither[0][0]) + 1)
+
+static int
+ProcRenderCreateCursor (ClientPtr client)
+{
+ REQUEST(xRenderCreateCursorReq);
+ PicturePtr pSrc;
+ ScreenPtr pScreen;
+ unsigned short width, height;
+ CARD32 *argbbits, *argb;
+ unsigned char *srcbits, *srcline;
+ unsigned char *mskbits, *mskline;
+ int stride;
+ int x, y;
+ int nbytes_mono;
+ CursorMetricRec cm;
+ CursorPtr pCursor;
+ CARD32 twocolor[3];
+ int ncolor;
+
+ REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
+ LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+ VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ if (!pSrc->pDrawable)
+ return BadDrawable;
+ pScreen = pSrc->pDrawable->pScreen;
+ width = pSrc->pDrawable->width;
+ height = pSrc->pDrawable->height;
+ if ( stuff->x > width
+ || stuff->y > height )
+ return (BadMatch);
+ argbbits = xalloc (width * height * sizeof (CARD32));
+ if (!argbbits)
+ return (BadAlloc);
+
+ stride = BitmapBytePad(width);
+ nbytes_mono = stride*height;
+ srcbits = (unsigned char *)xalloc(nbytes_mono);
+ if (!srcbits)
+ {
+ xfree (argbbits);
+ return (BadAlloc);
+ }
+ mskbits = (unsigned char *)xalloc(nbytes_mono);
+ if (!mskbits)
+ {
+ xfree(argbbits);
+ xfree(srcbits);
+ return (BadAlloc);
+ }
+ bzero ((char *) mskbits, nbytes_mono);
+ bzero ((char *) srcbits, nbytes_mono);
+
+ if (pSrc->format == PICT_a8r8g8b8)
+ {
+ (*pScreen->GetImage) (pSrc->pDrawable,
+ 0, 0, width, height, ZPixmap,
+ 0xffffffff, (pointer) argbbits);
+ }
+ else
+ {
+ PixmapPtr pPixmap;
+ PicturePtr pPicture;
+ PictFormatPtr pFormat;
+ int error;
+
+ pFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8);
+ if (!pFormat)
+ {
+ xfree (argbbits);
+ xfree (srcbits);
+ xfree (mskbits);
+ return (BadImplementation);
+ }
+ pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32);
+ if (!pPixmap)
+ {
+ xfree (argbbits);
+ xfree (srcbits);
+ xfree (mskbits);
+ return (BadAlloc);
+ }
+ pPicture = CreatePicture (0, &pPixmap->drawable, pFormat, 0, 0,
+ client, &error);
+ if (!pPicture)
+ {
+ xfree (argbbits);
+ xfree (srcbits);
+ xfree (mskbits);
+ return error;
+ }
+ (*pScreen->DestroyPixmap) (pPixmap);
+ CompositePicture (PictOpSrc,
+ pSrc, 0, pPicture,
+ 0, 0, 0, 0, 0, 0, width, height);
+ (*pScreen->GetImage) (pPicture->pDrawable,
+ 0, 0, width, height, ZPixmap,
+ 0xffffffff, (pointer) argbbits);
+ FreePicture (pPicture, 0);
+ }
+ /*
+ * Check whether the cursor can be directly supported by
+ * the core cursor code
+ */
+ ncolor = 0;
+ argb = argbbits;
+ for (y = 0; ncolor <= 2 && y < height; y++)
+ {
+ for (x = 0; ncolor <= 2 && x < width; x++)
+ {
+ CARD32 p = *argb++;
+ CARD32 a = (p >> 24);
+
+ if (a == 0) /* transparent */
+ continue;
+ if (a == 0xff) /* opaque */
+ {
+ int n;
+ for (n = 0; n < ncolor; n++)
+ if (p == twocolor[n])
+ break;
+ if (n == ncolor)
+ twocolor[ncolor++] = p;
+ }
+ else
+ ncolor = 3;
+ }
+ }
+
+ /*
+ * Convert argb image to two plane cursor
+ */
+ srcline = srcbits;
+ mskline = mskbits;
+ argb = argbbits;
+ for (y = 0; y < height; y++)
+ {
+ for (x = 0; x < width; x++)
+ {
+ CARD32 p = *argb++;
+
+ if (ncolor <= 2)
+ {
+ CARD32 a = ((p >> 24));
+
+ SetBit (mskline, x, a != 0);
+ SetBit (srcline, x, a != 0 && p == twocolor[0]);
+ }
+ else
+ {
+ CARD32 a = ((p >> 24) * DITHER_SIZE + 127) / 255;
+ CARD32 i = ((CvtR8G8B8toY15(p) >> 7) * DITHER_SIZE + 127) / 255;
+ CARD32 d = orderedDither[y&(DITHER_DIM-1)][x&(DITHER_DIM-1)];
+ /* Set mask from dithered alpha value */
+ SetBit(mskline, x, a > d);
+ /* Set src from dithered intensity value */
+ SetBit(srcline, x, a > d && i <= d);
+ }
+ }
+ srcline += stride;
+ mskline += stride;
+ }
+ /*
+ * Dither to white and black if the cursor has more than two colors
+ */
+ if (ncolor > 2)
+ {
+ twocolor[0] = 0xff000000;
+ twocolor[1] = 0xffffffff;
+ }
+ else
+ {
+ xfree (argbbits);
+ argbbits = 0;
+ }
+
+#define GetByte(p,s) (((p) >> (s)) & 0xff)
+#define GetColor(p,s) (GetByte(p,s) | (GetByte(p,s) << 8))
+
+ cm.width = width;
+ cm.height = height;
+ cm.xhot = stuff->x;
+ cm.yhot = stuff->y;
+ pCursor = AllocCursorARGB (srcbits, mskbits, argbbits, &cm,
+ GetColor(twocolor[0], 16),
+ GetColor(twocolor[0], 8),
+ GetColor(twocolor[0], 0),
+ GetColor(twocolor[1], 16),
+ GetColor(twocolor[1], 8),
+ GetColor(twocolor[1], 0));
+ if (pCursor && AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+ return (client->noClientException);
+ return BadAlloc;
+}
+
+static int
+ProcRenderSetPictureTransform (ClientPtr client)
+{
+ REQUEST(xRenderSetPictureTransformReq);
+ PicturePtr pPicture;
+ int result;
+
+ REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
+ VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ result = SetPictureTransform (pPicture, (PictTransform *) &stuff->transform);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+static int
+ProcRenderQueryFilters (ClientPtr client)
+{
+ REQUEST (xRenderQueryFiltersReq);
+ DrawablePtr pDrawable;
+ xRenderQueryFiltersReply *reply;
+ int nbytesName;
+ int nnames;
+ ScreenPtr pScreen;
+ PictureScreenPtr ps;
+ int i, j;
+ int len;
+ int total_bytes;
+ INT16 *aliases;
+ char *names;
+
+ REQUEST_SIZE_MATCH(xRenderQueryFiltersReq);
+ SECURITY_VERIFY_DRAWABLE(pDrawable, stuff->drawable, client, SecurityReadAccess);
+
+ pScreen = pDrawable->pScreen;
+ nbytesName = 0;
+ nnames = 0;
+ ps = GetPictureScreenIfSet(pScreen);
+ if (ps)
+ {
+ for (i = 0; i < ps->nfilters; i++)
+ nbytesName += 1 + strlen (ps->filters[i].name);
+ for (i = 0; i < ps->nfilterAliases; i++)
+ nbytesName += 1 + strlen (ps->filterAliases[i].alias);
+ nnames = ps->nfilters + ps->nfilterAliases;
+ }
+ len = ((nnames + 1) >> 1) + ((nbytesName + 3) >> 2);
+ total_bytes = sizeof (xRenderQueryFiltersReply) + (len << 2);
+ reply = (xRenderQueryFiltersReply *) xalloc (total_bytes);
+ if (!reply)
+ return BadAlloc;
+ aliases = (INT16 *) (reply + 1);
+ names = (char *) (aliases + ((nnames + 1) & ~1));
+
+ reply->type = X_Reply;
+ reply->sequenceNumber = client->sequence;
+ reply->length = len;
+ reply->numAliases = nnames;
+ reply->numFilters = nnames;
+ if (ps)
+ {
+
+ /* fill in alias values */
+ for (i = 0; i < ps->nfilters; i++)
+ aliases[i] = FilterAliasNone;
+ for (i = 0; i < ps->nfilterAliases; i++)
+ {
+ for (j = 0; j < ps->nfilters; j++)
+ if (ps->filterAliases[i].filter_id == ps->filters[j].id)
+ break;
+ if (j == ps->nfilters)
+ {
+ for (j = 0; j < ps->nfilterAliases; j++)
+ if (ps->filterAliases[i].filter_id ==
+ ps->filterAliases[j].alias_id)
+ {
+ break;
+ }
+ if (j == ps->nfilterAliases)
+ j = FilterAliasNone;
+ else
+ j = j + ps->nfilters;
+ }
+ aliases[i + ps->nfilters] = j;
+ }
+
+ /* fill in filter names */
+ for (i = 0; i < ps->nfilters; i++)
+ {
+ j = strlen (ps->filters[i].name);
+ *names++ = j;
+ strncpy (names, ps->filters[i].name, j);
+ names += j;
+ }
+
+ /* fill in filter alias names */
+ for (i = 0; i < ps->nfilterAliases; i++)
+ {
+ j = strlen (ps->filterAliases[i].alias);
+ *names++ = j;
+ strncpy (names, ps->filterAliases[i].alias, j);
+ names += j;
+ }
+ }
+
+ if (client->swapped)
+ {
+ register int n;
+
+ for (i = 0; i < reply->numAliases; i++)
+ {
+ swaps (&aliases[i], n);
+ }
+ swaps(&reply->sequenceNumber, n);
+ swapl(&reply->length, n);
+ swapl(&reply->numAliases, n);
+ swapl(&reply->numFilters, n);
+ }
+ WriteToClient(client, total_bytes, (char *) reply);
+ xfree (reply);
+
+ return(client->noClientException);
+}
+
+static int
+ProcRenderSetPictureFilter (ClientPtr client)
+{
+ REQUEST (xRenderSetPictureFilterReq);
+ PicturePtr pPicture;
+ int result;
+ xFixed *params;
+ int nparams;
+ char *name;
+
+ REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
+ VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ name = (char *) (stuff + 1);
+ params = (xFixed *) (name + ((stuff->nbytes + 3) & ~3));
+ nparams = ((xFixed *) stuff + client->req_len) - params;
+ result = SetPictureFilter (pPicture, name, stuff->nbytes, params, nparams);
+ return result;
+}
+
+static int
+ProcRenderCreateAnimCursor (ClientPtr client)
+{
+ REQUEST(xRenderCreateAnimCursorReq);
+ CursorPtr *cursors;
+ CARD32 *deltas;
+ CursorPtr pCursor;
+ int ncursor;
+ xAnimCursorElt *elt;
+ int i;
+ int ret;
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq);
+ LEGAL_NEW_RESOURCE(stuff->cid, client);
+ if (client->req_len & 1)
+ return BadLength;
+ ncursor = (client->req_len - (SIZEOF(xRenderCreateAnimCursorReq) >> 2)) >> 1;
+ cursors = xalloc (ncursor * (sizeof (CursorPtr) + sizeof (CARD32)));
+ if (!cursors)
+ return BadAlloc;
+ deltas = (CARD32 *) (cursors + ncursor);
+ elt = (xAnimCursorElt *) (stuff + 1);
+ for (i = 0; i < ncursor; i++)
+ {
+ cursors[i] = (CursorPtr)SecurityLookupIDByType(client, elt->cursor,
+ RT_CURSOR, SecurityReadAccess);
+ if (!cursors[i])
+ {
+ xfree (cursors);
+ client->errorValue = elt->cursor;
+ return BadCursor;
+ }
+ deltas[i] = elt->delay;
+ elt++;
+ }
+ ret = AnimCursorCreate (cursors, deltas, ncursor, &pCursor);
+ xfree (cursors);
+ if (ret != Success)
+ return ret;
+
+ if (AddResource (stuff->cid, RT_CURSOR, (pointer)pCursor))
+ return client->noClientException;
+ return BadAlloc;
+}
+
+static int
+ProcRenderAddTraps (ClientPtr client)
+{
+ int ntraps;
+ PicturePtr pPicture;
+ REQUEST(xRenderAddTrapsReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq);
+ VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pPicture->pDrawable)
+ return BadDrawable;
+ ntraps = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
+ if (ntraps % sizeof (xTrap))
+ return BadLength;
+ ntraps /= sizeof (xTrap);
+ if (ntraps)
+ AddTraps (pPicture,
+ stuff->xOff, stuff->yOff,
+ ntraps, (xTrap *) &stuff[1]);
+ return client->noClientException;
+}
+
+static int ProcRenderCreateSolidFill(ClientPtr client)
+{
+ PicturePtr pPicture;
+ int error = 0;
+ REQUEST(xRenderCreateSolidFillReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
+
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+ pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error);
+ if (!pPicture)
+ return error;
+ if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+ return BadAlloc;
+ return Success;
+}
+
+static int ProcRenderCreateLinearGradient (ClientPtr client)
+{
+ PicturePtr pPicture;
+ int len;
+ int error = 0;
+ xFixed *stops;
+ xRenderColor *colors;
+ REQUEST(xRenderCreateLinearGradientReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
+
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ stops = (xFixed *)(stuff + 1);
+ colors = (xRenderColor *)(stops + stuff->nStops);
+
+ pPicture = CreateLinearGradientPicture (stuff->pid, &stuff->p1, &stuff->p2,
+ stuff->nStops, stops, colors, &error);
+ if (!pPicture)
+ return error;
+ if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+ return BadAlloc;
+ return Success;
+}
+
+static int ProcRenderCreateRadialGradient (ClientPtr client)
+{
+ PicturePtr pPicture;
+ int len;
+ int error = 0;
+ xFixed *stops;
+ xRenderColor *colors;
+ REQUEST(xRenderCreateRadialGradientReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
+
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ stops = (xFixed *)(stuff + 1);
+ colors = (xRenderColor *)(stops + stuff->nStops);
+
+ pPicture = CreateRadialGradientPicture (stuff->pid, &stuff->inner, &stuff->outer,
+ stuff->inner_radius, stuff->outer_radius,
+ stuff->nStops, stops, colors, &error);
+ if (!pPicture)
+ return error;
+ if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+ return BadAlloc;
+ return Success;
+}
+
+static int ProcRenderCreateConicalGradient (ClientPtr client)
+{
+ PicturePtr pPicture;
+ int len;
+ int error = 0;
+ xFixed *stops;
+ xRenderColor *colors;
+ REQUEST(xRenderCreateConicalGradientReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
+
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ stops = (xFixed *)(stuff + 1);
+ colors = (xRenderColor *)(stops + stuff->nStops);
+
+ pPicture = CreateConicalGradientPicture (stuff->pid, &stuff->center, stuff->angle,
+ stuff->nStops, stops, colors, &error);
+ if (!pPicture)
+ return error;
+ if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+ return BadAlloc;
+ return Success;
+}
+
+
+static int
+ProcRenderDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+
+ if (stuff->data < RenderNumberRequests)
+ return (*ProcRenderVector[stuff->data]) (client);
+ else
+ return BadRequest;
+}
+
+static int
+SProcRenderQueryVersion (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderQueryVersionReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->majorVersion, n);
+ swapl(&stuff->minorVersion, n);
+ return (*ProcRenderVector[stuff->renderReqType])(client);
+}
+
+static int
+SProcRenderQueryPictFormats (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderQueryPictFormatsReq);
+ swaps(&stuff->length, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryPictIndexValues (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderQueryPictIndexValuesReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->format, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryDithers (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+SProcRenderCreatePicture (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderCreatePictureReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->pid, n);
+ swapl(&stuff->drawable, n);
+ swapl(&stuff->format, n);
+ swapl(&stuff->mask, n);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderChangePicture (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderChangePictureReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->picture, n);
+ swapl(&stuff->mask, n);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderSetPictureClipRectangles (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderSetPictureClipRectanglesReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->picture, n);
+ SwapRestS(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderFreePicture (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderFreePictureReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->picture, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderComposite (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderCompositeReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->src, n);
+ swapl(&stuff->mask, n);
+ swapl(&stuff->dst, n);
+ swaps(&stuff->xSrc, n);
+ swaps(&stuff->ySrc, n);
+ swaps(&stuff->xMask, n);
+ swaps(&stuff->yMask, n);
+ swaps(&stuff->xDst, n);
+ swaps(&stuff->yDst, n);
+ swaps(&stuff->width, n);
+ swaps(&stuff->height, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderScale (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderScaleReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->src, n);
+ swapl(&stuff->dst, n);
+ swapl(&stuff->colorScale, n);
+ swapl(&stuff->alphaScale, n);
+ swaps(&stuff->xSrc, n);
+ swaps(&stuff->ySrc, n);
+ swaps(&stuff->xDst, n);
+ swaps(&stuff->yDst, n);
+ swaps(&stuff->width, n);
+ swaps(&stuff->height, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTrapezoids (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderTrapezoidsReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
+ swaps (&stuff->length, n);
+ swapl (&stuff->src, n);
+ swapl (&stuff->dst, n);
+ swapl (&stuff->maskFormat, n);
+ swaps (&stuff->xSrc, n);
+ swaps (&stuff->ySrc, n);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriangles (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderTrianglesReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+ swaps (&stuff->length, n);
+ swapl (&stuff->src, n);
+ swapl (&stuff->dst, n);
+ swapl (&stuff->maskFormat, n);
+ swaps (&stuff->xSrc, n);
+ swaps (&stuff->ySrc, n);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriStrip (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderTriStripReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTriStripReq);
+ swaps (&stuff->length, n);
+ swapl (&stuff->src, n);
+ swapl (&stuff->dst, n);
+ swapl (&stuff->maskFormat, n);
+ swaps (&stuff->xSrc, n);
+ swaps (&stuff->ySrc, n);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriFan (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderTriFanReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTriFanReq);
+ swaps (&stuff->length, n);
+ swapl (&stuff->src, n);
+ swapl (&stuff->dst, n);
+ swapl (&stuff->maskFormat, n);
+ swaps (&stuff->xSrc, n);
+ swaps (&stuff->ySrc, n);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderColorTrapezoids (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+SProcRenderColorTriangles (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+SProcRenderTransform (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+SProcRenderCreateGlyphSet (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderCreateGlyphSetReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->gsid, n);
+ swapl(&stuff->format, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderReferenceGlyphSet (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderReferenceGlyphSetReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->gsid, n);
+ swapl(&stuff->existing, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderFreeGlyphSet (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderFreeGlyphSetReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->glyphset, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderAddGlyphs (ClientPtr client)
+{
+ register int n;
+ register int i;
+ CARD32 *gids;
+ void *end;
+ xGlyphInfo *gi;
+ REQUEST(xRenderAddGlyphsReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->glyphset, n);
+ swapl(&stuff->nglyphs, n);
+ if (stuff->nglyphs & 0xe0000000)
+ return BadLength;
+ end = (CARD8 *) stuff + (client->req_len << 2);
+ gids = (CARD32 *) (stuff + 1);
+ gi = (xGlyphInfo *) (gids + stuff->nglyphs);
+ if ((char *) end - (char *) (gids + stuff->nglyphs) < 0)
+ return BadLength;
+ if ((char *) end - (char *) (gi + stuff->nglyphs) < 0)
+ return BadLength;
+ for (i = 0; i < stuff->nglyphs; i++)
+ {
+ swapl (&gids[i], n);
+ swaps (&gi[i].width, n);
+ swaps (&gi[i].height, n);
+ swaps (&gi[i].x, n);
+ swaps (&gi[i].y, n);
+ swaps (&gi[i].xOff, n);
+ swaps (&gi[i].yOff, n);
+ }
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderAddGlyphsFromPicture (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+SProcRenderFreeGlyphs (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderFreeGlyphsReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->glyphset, n);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCompositeGlyphs (ClientPtr client)
+{
+ register int n;
+ xGlyphElt *elt;
+ CARD8 *buffer;
+ CARD8 *end;
+ int space;
+ int i;
+ int size;
+
+ REQUEST(xRenderCompositeGlyphsReq);
+
+ switch (stuff->renderReqType) {
+ default: size = 1; break;
+ case X_RenderCompositeGlyphs16: size = 2; break;
+ case X_RenderCompositeGlyphs32: size = 4; break;
+ }
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->src, n);
+ swapl(&stuff->dst, n);
+ swapl(&stuff->maskFormat, n);
+ swapl(&stuff->glyphset, n);
+ swaps(&stuff->xSrc, n);
+ swaps(&stuff->ySrc, n);
+ buffer = (CARD8 *) (stuff + 1);
+ end = (CARD8 *) stuff + (client->req_len << 2);
+ while (buffer + sizeof (xGlyphElt) < end)
+ {
+ elt = (xGlyphElt *) buffer;
+ buffer += sizeof (xGlyphElt);
+
+ swaps (&elt->deltax, n);
+ swaps (&elt->deltay, n);
+
+ i = elt->len;
+ if (i == 0xff)
+ {
+ swapl (buffer, n);
+ buffer += 4;
+ }
+ else
+ {
+ space = size * i;
+ switch (size) {
+ case 1:
+ buffer += i;
+ break;
+ case 2:
+ while (i--)
+ {
+ swaps (buffer, n);
+ buffer += 2;
+ }
+ break;
+ case 4:
+ while (i--)
+ {
+ swapl (buffer, n);
+ buffer += 4;
+ }
+ break;
+ }
+ if (space & 3)
+ buffer += 4 - (space & 3);
+ }
+ }
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderFillRectangles (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderFillRectanglesReq);
+
+ REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->dst, n);
+ swaps(&stuff->color.red, n);
+ swaps(&stuff->color.green, n);
+ swaps(&stuff->color.blue, n);
+ swaps(&stuff->color.alpha, n);
+ SwapRestS(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateCursor (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderCreateCursorReq);
+ REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->cid, n);
+ swapl(&stuff->src, n);
+ swaps(&stuff->x, n);
+ swaps(&stuff->y, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderSetPictureTransform (ClientPtr client)
+{
+ register int n;
+ REQUEST(xRenderSetPictureTransformReq);
+ REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->picture, n);
+ swapl(&stuff->transform.matrix11, n);
+ swapl(&stuff->transform.matrix12, n);
+ swapl(&stuff->transform.matrix13, n);
+ swapl(&stuff->transform.matrix21, n);
+ swapl(&stuff->transform.matrix22, n);
+ swapl(&stuff->transform.matrix23, n);
+ swapl(&stuff->transform.matrix31, n);
+ swapl(&stuff->transform.matrix32, n);
+ swapl(&stuff->transform.matrix33, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryFilters (ClientPtr client)
+{
+ register int n;
+ REQUEST (xRenderQueryFiltersReq);
+ REQUEST_SIZE_MATCH (xRenderQueryFiltersReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->drawable, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderSetPictureFilter (ClientPtr client)
+{
+ register int n;
+ REQUEST (xRenderSetPictureFilterReq);
+ REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->picture, n);
+ swaps(&stuff->nbytes, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateAnimCursor (ClientPtr client)
+{
+ register int n;
+ REQUEST (xRenderCreateAnimCursorReq);
+ REQUEST_AT_LEAST_SIZE (xRenderCreateAnimCursorReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->cid, n);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderAddTraps (ClientPtr client)
+{
+ register int n;
+ REQUEST (xRenderAddTrapsReq);
+ REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->picture, n);
+ swaps(&stuff->xOff, n);
+ swaps(&stuff->yOff, n);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateSolidFill(ClientPtr client)
+{
+ register int n;
+ REQUEST (xRenderCreateSolidFillReq);
+ REQUEST_AT_LEAST_SIZE (xRenderCreateSolidFillReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->pid, n);
+ swaps(&stuff->color.alpha, n);
+ swaps(&stuff->color.red, n);
+ swaps(&stuff->color.green, n);
+ swaps(&stuff->color.blue, n);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static void swapStops(void *stuff, int n)
+{
+ int i;
+ CARD32 *stops;
+ CARD16 *colors;
+ stops = (CARD32 *)(stuff);
+ for (i = 0; i < n; ++i) {
+ swapl(stops, n);
+ ++stops;
+ }
+ colors = (CARD16 *)(stops);
+ for (i = 0; i < 4*n; ++i) {
+ swaps(stops, n);
+ ++stops;
+ }
+}
+
+static int
+SProcRenderCreateLinearGradient (ClientPtr client)
+{
+ register int n;
+ int len;
+ REQUEST (xRenderCreateLinearGradientReq);
+ REQUEST_AT_LEAST_SIZE (xRenderCreateLinearGradientReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->pid, n);
+ swapl(&stuff->p1.x, n);
+ swapl(&stuff->p1.y, n);
+ swapl(&stuff->p2.x, n);
+ swapl(&stuff->p2.y, n);
+ swapl(&stuff->nStops, n);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ swapStops(stuff+1, stuff->nStops);
+
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateRadialGradient (ClientPtr client)
+{
+ register int n;
+ int len;
+ REQUEST (xRenderCreateRadialGradientReq);
+ REQUEST_AT_LEAST_SIZE (xRenderCreateRadialGradientReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->pid, n);
+ swapl(&stuff->inner.x, n);
+ swapl(&stuff->inner.y, n);
+ swapl(&stuff->outer.x, n);
+ swapl(&stuff->outer.y, n);
+ swapl(&stuff->inner_radius, n);
+ swapl(&stuff->outer_radius, n);
+ swapl(&stuff->nStops, n);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ swapStops(stuff+1, stuff->nStops);
+
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateConicalGradient (ClientPtr client)
+{
+ register int n;
+ int len;
+ REQUEST (xRenderCreateConicalGradientReq);
+ REQUEST_AT_LEAST_SIZE (xRenderCreateConicalGradientReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->pid, n);
+ swapl(&stuff->center.x, n);
+ swapl(&stuff->center.y, n);
+ swapl(&stuff->angle, n);
+ swapl(&stuff->nStops, n);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ swapStops(stuff+1, stuff->nStops);
+
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+
+ if (stuff->data < RenderNumberRequests)
+ return (*SProcRenderVector[stuff->data]) (client);
+ else
+ return BadRequest;
+}
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+
+#define VERIFY_XIN_PICTURE(pPicture, pid, client, mode, err) {\
+ pPicture = SecurityLookupIDByType(client, pid, XRT_PICTURE, mode);\
+ if (!pPicture) { \
+ client->errorValue = pid; \
+ return err; \
+ } \
+}
+
+#define VERIFY_XIN_ALPHA(pPicture, pid, client, mode, err) {\
+ if (pid == None) \
+ pPicture = 0; \
+ else { \
+ VERIFY_XIN_PICTURE(pPicture, pid, client, mode, err); \
+ } \
+} \
+
+int (*PanoramiXSaveRenderVector[RenderNumberRequests])(ClientPtr);
+
+unsigned long XRT_PICTURE;
+
+static int
+PanoramiXRenderCreatePicture (ClientPtr client)
+{
+ REQUEST(xRenderCreatePictureReq);
+ PanoramiXRes *refDraw, *newPict;
+ int result = Success, j;
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
+ if(!(refDraw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+ return BadDrawable;
+ if(!(newPict = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes))))
+ return BadAlloc;
+ newPict->type = XRT_PICTURE;
+ newPict->info[0].id = stuff->pid;
+
+ if (refDraw->type == XRT_WINDOW &&
+ stuff->drawable == WindowTable[0]->drawable.id)
+ {
+ newPict->u.pict.root = TRUE;
+ }
+ else
+ newPict->u.pict.root = FALSE;
+
+ for(j = 1; j < PanoramiXNumScreens; j++)
+ newPict->info[j].id = FakeClientID(client->index);
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->pid = newPict->info[j].id;
+ stuff->drawable = refDraw->info[j].id;
+ result = (*PanoramiXSaveRenderVector[X_RenderCreatePicture]) (client);
+ if(result != Success) break;
+ }
+
+ if (result == Success)
+ AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
+ else
+ xfree(newPict);
+
+ return (result);
+}
+
+static int
+PanoramiXRenderChangePicture (ClientPtr client)
+{
+ PanoramiXRes *pict;
+ int result = Success, j;
+ REQUEST(xRenderChangePictureReq);
+
+ REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
+
+ VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->picture = pict->info[j].id;
+ result = (*PanoramiXSaveRenderVector[X_RenderChangePicture]) (client);
+ if(result != Success) break;
+ }
+
+ return (result);
+}
+
+static int
+PanoramiXRenderSetPictureClipRectangles (ClientPtr client)
+{
+ REQUEST(xRenderSetPictureClipRectanglesReq);
+ int result = Success, j;
+ PanoramiXRes *pict;
+
+ REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
+
+ VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->picture = pict->info[j].id;
+ result = (*PanoramiXSaveRenderVector[X_RenderSetPictureClipRectangles]) (client);
+ if(result != Success) break;
+ }
+
+ return (result);
+}
+
+static int
+PanoramiXRenderSetPictureTransform (ClientPtr client)
+{
+ REQUEST(xRenderSetPictureTransformReq);
+ int result = Success, j;
+ PanoramiXRes *pict;
+
+ REQUEST_AT_LEAST_SIZE(xRenderSetPictureTransformReq);
+
+ VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->picture = pict->info[j].id;
+ result = (*PanoramiXSaveRenderVector[X_RenderSetPictureTransform]) (client);
+ if(result != Success) break;
+ }
+
+ return (result);
+}
+
+static int
+PanoramiXRenderSetPictureFilter (ClientPtr client)
+{
+ REQUEST(xRenderSetPictureFilterReq);
+ int result = Success, j;
+ PanoramiXRes *pict;
+
+ REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq);
+
+ VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->picture = pict->info[j].id;
+ result = (*PanoramiXSaveRenderVector[X_RenderSetPictureFilter]) (client);
+ if(result != Success) break;
+ }
+
+ return (result);
+}
+
+static int
+PanoramiXRenderFreePicture (ClientPtr client)
+{
+ PanoramiXRes *pict;
+ int result = Success, j;
+ REQUEST(xRenderFreePictureReq);
+
+ REQUEST_SIZE_MATCH(xRenderFreePictureReq);
+
+ client->errorValue = stuff->picture;
+
+ VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityDestroyAccess,
+ RenderErrBase + BadPicture);
+
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->picture = pict->info[j].id;
+ result = (*PanoramiXSaveRenderVector[X_RenderFreePicture]) (client);
+ if(result != Success) break;
+ }
+
+ /* Since ProcRenderFreePicture is using FreeResource, it will free
+ our resource for us on the last pass through the loop above */
+
+ return (result);
+}
+
+static int
+PanoramiXRenderComposite (ClientPtr client)
+{
+ PanoramiXRes *src, *msk, *dst;
+ int result = Success, j;
+ xRenderCompositeReq orig;
+ REQUEST(xRenderCompositeReq);
+
+ REQUEST_SIZE_MATCH(xRenderCompositeReq);
+
+ VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_XIN_ALPHA (msk, stuff->mask, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ orig = *stuff;
+
+ FOR_NSCREENS_FORWARD(j) {
+ stuff->src = src->info[j].id;
+ if (src->u.pict.root)
+ {
+ stuff->xSrc = orig.xSrc - panoramiXdataPtr[j].x;
+ stuff->ySrc = orig.ySrc - panoramiXdataPtr[j].y;
+ }
+ stuff->dst = dst->info[j].id;
+ if (dst->u.pict.root)
+ {
+ stuff->xDst = orig.xDst - panoramiXdataPtr[j].x;
+ stuff->yDst = orig.yDst - panoramiXdataPtr[j].y;
+ }
+ if (msk)
+ {
+ stuff->mask = msk->info[j].id;
+ if (msk->u.pict.root)
+ {
+ stuff->xMask = orig.xMask - panoramiXdataPtr[j].x;
+ stuff->yMask = orig.yMask - panoramiXdataPtr[j].y;
+ }
+ }
+ result = (*PanoramiXSaveRenderVector[X_RenderComposite]) (client);
+ if(result != Success) break;
+ }
+
+ return result;
+}
+
+static int
+PanoramiXRenderCompositeGlyphs (ClientPtr client)
+{
+ PanoramiXRes *src, *dst;
+ int result = Success, j;
+ REQUEST(xRenderCompositeGlyphsReq);
+ xGlyphElt origElt, *elt;
+ INT16 xSrc, ySrc;
+
+ REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
+ VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ if (client->req_len << 2 >= (sizeof (xRenderCompositeGlyphsReq) +
+ sizeof (xGlyphElt)))
+ {
+ elt = (xGlyphElt *) (stuff + 1);
+ origElt = *elt;
+ xSrc = stuff->xSrc;
+ ySrc = stuff->ySrc;
+ FOR_NSCREENS_FORWARD(j) {
+ stuff->src = src->info[j].id;
+ if (src->u.pict.root)
+ {
+ stuff->xSrc = xSrc - panoramiXdataPtr[j].x;
+ stuff->ySrc = ySrc - panoramiXdataPtr[j].y;
+ }
+ stuff->dst = dst->info[j].id;
+ if (dst->u.pict.root)
+ {
+ elt->deltax = origElt.deltax - panoramiXdataPtr[j].x;
+ elt->deltay = origElt.deltay - panoramiXdataPtr[j].y;
+ }
+ result = (*PanoramiXSaveRenderVector[stuff->renderReqType]) (client);
+ if(result != Success) break;
+ }
+ }
+
+ return result;
+}
+
+static int
+PanoramiXRenderFillRectangles (ClientPtr client)
+{
+ PanoramiXRes *dst;
+ int result = Success, j;
+ REQUEST(xRenderFillRectanglesReq);
+ char *extra;
+ int extra_len;
+
+ REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ extra_len = (client->req_len << 2) - sizeof (xRenderFillRectanglesReq);
+ if (extra_len &&
+ (extra = (char *) ALLOCATE_LOCAL (extra_len)))
+ {
+ memcpy (extra, stuff + 1, extra_len);
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ if (dst->u.pict.root)
+ {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ xRectangle *rects = (xRectangle *) (stuff + 1);
+ int i = extra_len / sizeof (xRectangle);
+
+ while (i--)
+ {
+ rects->x -= x_off;
+ rects->y -= y_off;
+ rects++;
+ }
+ }
+ }
+ stuff->dst = dst->info[j].id;
+ result = (*PanoramiXSaveRenderVector[X_RenderFillRectangles]) (client);
+ if(result != Success) break;
+ }
+ DEALLOCATE_LOCAL(extra);
+ }
+
+ return result;
+}
+
+static int
+PanoramiXRenderTrapezoids(ClientPtr client)
+{
+ PanoramiXRes *src, *dst;
+ int result = Success, j;
+ REQUEST(xRenderTrapezoidsReq);
+ char *extra;
+ int extra_len;
+
+ REQUEST_AT_LEAST_SIZE (xRenderTrapezoidsReq);
+
+ VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ extra_len = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq);
+
+ if (extra_len &&
+ (extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+ memcpy (extra, stuff + 1, extra_len);
+
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ if (dst->u.pict.root) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ xTrapezoid *trap = (xTrapezoid *) (stuff + 1);
+ int i = extra_len / sizeof (xTrapezoid);
+
+ while (i--) {
+ trap->top -= y_off;
+ trap->bottom -= y_off;
+ trap->left.p1.x -= x_off;
+ trap->left.p1.y -= y_off;
+ trap->left.p2.x -= x_off;
+ trap->left.p2.y -= y_off;
+ trap->right.p1.x -= x_off;
+ trap->right.p1.y -= y_off;
+ trap->right.p2.x -= x_off;
+ trap->right.p2.y -= y_off;
+ trap++;
+ }
+ }
+ }
+
+ stuff->src = src->info[j].id;
+ stuff->dst = dst->info[j].id;
+ result =
+ (*PanoramiXSaveRenderVector[X_RenderTrapezoids]) (client);
+
+ if(result != Success) break;
+ }
+
+ DEALLOCATE_LOCAL(extra);
+ }
+
+ return result;
+}
+
+static int
+PanoramiXRenderTriangles(ClientPtr client)
+{
+ PanoramiXRes *src, *dst;
+ int result = Success, j;
+ REQUEST(xRenderTrianglesReq);
+ char *extra;
+ int extra_len;
+
+ REQUEST_AT_LEAST_SIZE (xRenderTrianglesReq);
+
+ VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ extra_len = (client->req_len << 2) - sizeof (xRenderTrianglesReq);
+
+ if (extra_len &&
+ (extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+ memcpy (extra, stuff + 1, extra_len);
+
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ if (dst->u.pict.root) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ xTriangle *tri = (xTriangle *) (stuff + 1);
+ int i = extra_len / sizeof (xTriangle);
+
+ while (i--) {
+ tri->p1.x -= x_off;
+ tri->p1.y -= y_off;
+ tri->p2.x -= x_off;
+ tri->p2.y -= y_off;
+ tri->p3.x -= x_off;
+ tri->p3.y -= y_off;
+ tri++;
+ }
+ }
+ }
+
+ stuff->src = src->info[j].id;
+ stuff->dst = dst->info[j].id;
+ result =
+ (*PanoramiXSaveRenderVector[X_RenderTriangles]) (client);
+
+ if(result != Success) break;
+ }
+
+ DEALLOCATE_LOCAL(extra);
+ }
+
+ return result;
+}
+
+static int
+PanoramiXRenderTriStrip(ClientPtr client)
+{
+ PanoramiXRes *src, *dst;
+ int result = Success, j;
+ REQUEST(xRenderTriStripReq);
+ char *extra;
+ int extra_len;
+
+ REQUEST_AT_LEAST_SIZE (xRenderTriStripReq);
+
+ VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ extra_len = (client->req_len << 2) - sizeof (xRenderTriStripReq);
+
+ if (extra_len &&
+ (extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+ memcpy (extra, stuff + 1, extra_len);
+
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ if (dst->u.pict.root) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ xPointFixed *fixed = (xPointFixed *) (stuff + 1);
+ int i = extra_len / sizeof (xPointFixed);
+
+ while (i--) {
+ fixed->x -= x_off;
+ fixed->y -= y_off;
+ fixed++;
+ }
+ }
+ }
+
+ stuff->src = src->info[j].id;
+ stuff->dst = dst->info[j].id;
+ result =
+ (*PanoramiXSaveRenderVector[X_RenderTriStrip]) (client);
+
+ if(result != Success) break;
+ }
+
+ DEALLOCATE_LOCAL(extra);
+ }
+
+ return result;
+}
+
+static int
+PanoramiXRenderTriFan(ClientPtr client)
+{
+ PanoramiXRes *src, *dst;
+ int result = Success, j;
+ REQUEST(xRenderTriFanReq);
+ char *extra;
+ int extra_len;
+
+ REQUEST_AT_LEAST_SIZE (xRenderTriFanReq);
+
+ VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ extra_len = (client->req_len << 2) - sizeof (xRenderTriFanReq);
+
+ if (extra_len &&
+ (extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+ memcpy (extra, stuff + 1, extra_len);
+
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ if (dst->u.pict.root) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ xPointFixed *fixed = (xPointFixed *) (stuff + 1);
+ int i = extra_len / sizeof (xPointFixed);
+
+ while (i--) {
+ fixed->x -= x_off;
+ fixed->y -= y_off;
+ fixed++;
+ }
+ }
+ }
+
+ stuff->src = src->info[j].id;
+ stuff->dst = dst->info[j].id;
+ result =
+ (*PanoramiXSaveRenderVector[X_RenderTriFan]) (client);
+
+ if(result != Success) break;
+ }
+
+ DEALLOCATE_LOCAL(extra);
+ }
+
+ return result;
+}
+
+#if 0 /* Not implemented yet */
+
+static int
+PanoramiXRenderColorTrapezoids(ClientPtr client)
+{
+ PanoramiXRes *src, *dst;
+ int result = Success, j;
+ REQUEST(xRenderColorTrapezoidsReq);
+ char *extra;
+ int extra_len;
+
+ REQUEST_AT_LEAST_SIZE (xRenderColorTrapezoidsReq);
+
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ extra_len = (client->req_len << 2) - sizeof (xRenderColorTrapezoidsReq);
+
+ if (extra_len &&
+ (extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+ memcpy (extra, stuff + 1, extra_len);
+
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ if (dst->u.pict.root) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ ....;
+ }
+ }
+
+ stuff->dst = dst->info[j].id;
+ result =
+ (*PanoramiXSaveRenderVector[X_RenderColorTrapezoids]) (client);
+
+ if(result != Success) break;
+ }
+
+ DEALLOCATE_LOCAL(extra);
+ }
+
+ return result;
+}
+
+static int
+PanoramiXRenderColorTriangles(ClientPtr client)
+{
+ PanoramiXRes *src, *dst;
+ int result = Success, j;
+ REQUEST(xRenderColorTrianglesReq);
+ char *extra;
+ int extra_len;
+
+ REQUEST_AT_LEAST_SIZE (xRenderColorTrianglesReq);
+
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+
+ extra_len = (client->req_len << 2) - sizeof (xRenderColorTrianglesReq);
+
+ if (extra_len &&
+ (extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+ memcpy (extra, stuff + 1, extra_len);
+
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ if (dst->u.pict.root) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ ....;
+ }
+ }
+
+ stuff->dst = dst->info[j].id;
+ result =
+ (*PanoramiXSaveRenderVector[X_RenderColorTriangles]) (client);
+
+ if(result != Success) break;
+ }
+
+ DEALLOCATE_LOCAL(extra);
+ }
+
+ return result;
+}
+
+#endif
+
+static int
+PanoramiXRenderAddTraps (ClientPtr client)
+{
+ PanoramiXRes *picture;
+ int result = Success, j;
+ REQUEST(xRenderAddTrapsReq);
+ char *extra;
+ int extra_len;
+ INT16 x_off, y_off;
+
+ REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq);
+ VERIFY_XIN_PICTURE (picture, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ extra_len = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
+ if (extra_len &&
+ (extra = (char *) ALLOCATE_LOCAL (extra_len)))
+ {
+ memcpy (extra, stuff + 1, extra_len);
+ x_off = stuff->xOff;
+ y_off = stuff->yOff;
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ stuff->picture = picture->info[j].id;
+
+ if (picture->u.pict.root)
+ {
+ stuff->xOff = x_off + panoramiXdataPtr[j].x;
+ stuff->yOff = y_off + panoramiXdataPtr[j].y;
+ }
+ result = (*PanoramiXSaveRenderVector[X_RenderAddTraps]) (client);
+ if(result != Success) break;
+ }
+ DEALLOCATE_LOCAL(extra);
+ }
+
+ return result;
+}
+
+void
+PanoramiXRenderInit (void)
+{
+ int i;
+
+ XRT_PICTURE = CreateNewResourceType (XineramaDeleteResource);
+ for (i = 0; i < RenderNumberRequests; i++)
+ PanoramiXSaveRenderVector[i] = ProcRenderVector[i];
+ /*
+ * Stuff in Xinerama aware request processing hooks
+ */
+ ProcRenderVector[X_RenderCreatePicture] = PanoramiXRenderCreatePicture;
+ ProcRenderVector[X_RenderChangePicture] = PanoramiXRenderChangePicture;
+ ProcRenderVector[X_RenderSetPictureTransform] = PanoramiXRenderSetPictureTransform;
+ ProcRenderVector[X_RenderSetPictureFilter] = PanoramiXRenderSetPictureFilter;
+ ProcRenderVector[X_RenderSetPictureClipRectangles] = PanoramiXRenderSetPictureClipRectangles;
+ ProcRenderVector[X_RenderFreePicture] = PanoramiXRenderFreePicture;
+ ProcRenderVector[X_RenderComposite] = PanoramiXRenderComposite;
+ ProcRenderVector[X_RenderCompositeGlyphs8] = PanoramiXRenderCompositeGlyphs;
+ ProcRenderVector[X_RenderCompositeGlyphs16] = PanoramiXRenderCompositeGlyphs;
+ ProcRenderVector[X_RenderCompositeGlyphs32] = PanoramiXRenderCompositeGlyphs;
+ ProcRenderVector[X_RenderFillRectangles] = PanoramiXRenderFillRectangles;
+
+ ProcRenderVector[X_RenderTrapezoids] = PanoramiXRenderTrapezoids;
+ ProcRenderVector[X_RenderTriangles] = PanoramiXRenderTriangles;
+ ProcRenderVector[X_RenderTriStrip] = PanoramiXRenderTriStrip;
+ ProcRenderVector[X_RenderTriFan] = PanoramiXRenderTriFan;
+ ProcRenderVector[X_RenderAddTraps] = PanoramiXRenderAddTraps;
+}
+
+void
+PanoramiXRenderReset (void)
+{
+ int i;
+ for (i = 0; i < RenderNumberRequests; i++)
+ ProcRenderVector[i] = PanoramiXSaveRenderVector[i];
+}
+
+#endif /* PANORAMIX */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c
new file mode 100644
index 000000000..9af5c4187
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c
@@ -0,0 +1,1173 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/************************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+********************************************************/
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+/* $Xorg: resource.c,v 1.5 2001/02/09 02:04:40 xorgcvs Exp $ */
+/* $XdotOrg: xc/programs/Xserver/dix/resource.c,v 1.8 2005/07/03 08:53:38 daniels Exp $ */
+/* $TOG: resource.c /main/41 1998/02/09 14:20:31 kaleb $ */
+
+/* Routines to manage various kinds of resources:
+ *
+ * CreateNewResourceType, CreateNewResourceClass, InitClientResources,
+ * FakeClientID, AddResource, FreeResource, FreeClientResources,
+ * FreeAllResources, LookupIDByType, LookupIDByClass, GetXIDRange
+ */
+
+/*
+ * A resource ID is a 32 bit quantity, the upper 2 bits of which are
+ * off-limits for client-visible resources. The next 8 bits are
+ * used as client ID, and the low 22 bits come from the client.
+ * A resource ID is "hashed" by extracting and xoring subfields
+ * (varying with the size of the hash table).
+ *
+ * It is sometimes necessary for the server to create an ID that looks
+ * like it belongs to a client. This ID, however, must not be one
+ * the client actually can create, or we have the potential for conflict.
+ * The 31st bit of the ID is reserved for the server's use for this
+ * purpose. By setting CLIENT_ID(id) to the client, the SERVER_BIT to
+ * 1, and an otherwise arbitrary ID in the low 22 bits, we can create a
+ * resource "owned" by the client.
+ */
+/* $XFree86: xc/programs/Xserver/dix/resource.c,v 3.13 2003/09/24 02:43:13 dawes Exp $ */
+
+#define NEED_EVENTS
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "misc.h"
+#include "os.h"
+#include "resource.h"
+#include "dixstruct.h"
+#include "opaque.h"
+#include "windowstr.h"
+#include "dixfont.h"
+#include "colormap.h"
+#include "inputstr.h"
+#include "dixevents.h"
+#include "dixgrabs.h"
+#include "cursor.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#include <assert.h>
+
+#ifdef NXAGENT_SERVER
+
+#include "Agent.h"
+#include "Font.h"
+#include "Pixmaps.h"
+#include "GCs.h"
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+#endif
+
+static void RebuildTable(
+ int /*client*/
+);
+
+#define SERVER_MINID 32
+
+#define INITBUCKETS 64
+#define INITHASHSIZE 6
+#define MAXHASHSIZE 11
+
+typedef struct _Resource {
+ struct _Resource *next;
+ XID id;
+ RESTYPE type;
+ pointer value;
+} ResourceRec, *ResourcePtr;
+#define NullResource ((ResourcePtr)NULL)
+
+typedef struct _ClientResource {
+ ResourcePtr *resources;
+ int elements;
+ int buckets;
+ int hashsize; /* log(2)(buckets) */
+ XID fakeID;
+ XID endFakeID;
+ XID expectID;
+} ClientResourceRec;
+
+RESTYPE lastResourceType;
+static RESTYPE lastResourceClass;
+RESTYPE TypeMask;
+
+static DeleteType *DeleteFuncs = (DeleteType *)NULL;
+
+#ifdef XResExtension
+
+Atom * ResourceNames = NULL;
+
+void RegisterResourceName (RESTYPE type, char *name)
+{
+ ResourceNames[type & TypeMask] = MakeAtom(name, strlen(name), TRUE);
+}
+
+#endif
+
+RESTYPE
+CreateNewResourceType(DeleteType deleteFunc)
+{
+ RESTYPE next = lastResourceType + 1;
+ DeleteType *funcs;
+
+ if (next & lastResourceClass)
+ return 0;
+ funcs = (DeleteType *)xrealloc(DeleteFuncs,
+ (next + 1) * sizeof(DeleteType));
+ if (!funcs)
+ return 0;
+
+#ifdef XResExtension
+ {
+ Atom *newnames;
+ newnames = xrealloc(ResourceNames, (next + 1) * sizeof(Atom));
+ if(!newnames)
+ return 0;
+ ResourceNames = newnames;
+ ResourceNames[next] = 0;
+ }
+#endif
+
+ lastResourceType = next;
+ DeleteFuncs = funcs;
+ DeleteFuncs[next] = deleteFunc;
+ return next;
+}
+
+RESTYPE
+CreateNewResourceClass()
+{
+ RESTYPE next = lastResourceClass >> 1;
+
+ if (next & lastResourceType)
+ return 0;
+ lastResourceClass = next;
+ TypeMask = next - 1;
+ return next;
+}
+
+ClientResourceRec clientTable[MAXCLIENTS];
+
+/*****************
+ * InitClientResources
+ * When a new client is created, call this to allocate space
+ * in resource table
+ *****************/
+
+Bool
+InitClientResources(ClientPtr client)
+{
+ register int i, j;
+
+ if (client == serverClient)
+ {
+ lastResourceType = RT_LASTPREDEF;
+ lastResourceClass = RC_LASTPREDEF;
+ TypeMask = RC_LASTPREDEF - 1;
+ if (DeleteFuncs)
+ xfree(DeleteFuncs);
+ DeleteFuncs = (DeleteType *)xalloc((lastResourceType + 1) *
+ sizeof(DeleteType));
+ if (!DeleteFuncs)
+ return FALSE;
+ DeleteFuncs[RT_NONE & TypeMask] = (DeleteType)NoopDDA;
+ DeleteFuncs[RT_WINDOW & TypeMask] = DeleteWindow;
+ DeleteFuncs[RT_PIXMAP & TypeMask] = dixDestroyPixmap;
+ DeleteFuncs[RT_GC & TypeMask] = FreeGC;
+ DeleteFuncs[RT_FONT & TypeMask] = CloseFont;
+ DeleteFuncs[RT_CURSOR & TypeMask] = FreeCursor;
+ DeleteFuncs[RT_COLORMAP & TypeMask] = FreeColormap;
+ DeleteFuncs[RT_CMAPENTRY & TypeMask] = FreeClientPixels;
+ DeleteFuncs[RT_OTHERCLIENT & TypeMask] = OtherClientGone;
+ DeleteFuncs[RT_PASSIVEGRAB & TypeMask] = DeletePassiveGrab;
+
+#ifdef XResExtension
+ if(ResourceNames)
+ xfree(ResourceNames);
+ ResourceNames = xalloc((lastResourceType + 1) * sizeof(Atom));
+ if(!ResourceNames)
+ return FALSE;
+#endif
+ }
+ clientTable[i = client->index].resources =
+ (ResourcePtr *)xalloc(INITBUCKETS*sizeof(ResourcePtr));
+ if (!clientTable[i].resources)
+ return FALSE;
+ clientTable[i].buckets = INITBUCKETS;
+ clientTable[i].elements = 0;
+ clientTable[i].hashsize = INITHASHSIZE;
+ /* Many IDs allocated from the server client are visible to clients,
+ * so we don't use the SERVER_BIT for them, but we have to start
+ * past the magic value constants used in the protocol. For normal
+ * clients, we can start from zero, with SERVER_BIT set.
+ */
+ clientTable[i].fakeID = client->clientAsMask |
+ (client->index ? SERVER_BIT : SERVER_MINID);
+ clientTable[i].endFakeID = (clientTable[i].fakeID | RESOURCE_ID_MASK) + 1;
+ clientTable[i].expectID = client->clientAsMask;
+ for (j=0; j<INITBUCKETS; j++)
+ {
+ clientTable[i].resources[j] = NullResource;
+ }
+ return TRUE;
+}
+
+
+static int
+Hash(int client, register XID id)
+{
+ id &= RESOURCE_ID_MASK;
+ switch (clientTable[client].hashsize)
+ {
+ case 6:
+ return ((int)(0x03F & (id ^ (id>>6) ^ (id>>12))));
+ case 7:
+ return ((int)(0x07F & (id ^ (id>>7) ^ (id>>13))));
+ case 8:
+ return ((int)(0x0FF & (id ^ (id>>8) ^ (id>>16))));
+ case 9:
+ return ((int)(0x1FF & (id ^ (id>>9))));
+ case 10:
+ return ((int)(0x3FF & (id ^ (id>>10))));
+ case 11:
+ return ((int)(0x7FF & (id ^ (id>>11))));
+ }
+ return -1;
+}
+
+static XID
+AvailableID(
+ register int client,
+ register XID id,
+ register XID maxid,
+ register XID goodid)
+{
+ register ResourcePtr res;
+
+ if ((goodid >= id) && (goodid <= maxid))
+ return goodid;
+ for (; id <= maxid; id++)
+ {
+ res = clientTable[client].resources[Hash(client, id)];
+ while (res && (res->id != id))
+ res = res->next;
+ if (!res)
+ return id;
+ }
+ return 0;
+}
+
+void
+GetXIDRange(int client, Bool server, XID *minp, XID *maxp)
+{
+ register XID id, maxid;
+ register ResourcePtr *resp;
+ register ResourcePtr res;
+ register int i;
+ XID goodid;
+
+ id = (Mask)client << CLIENTOFFSET;
+ if (server)
+ id |= client ? SERVER_BIT : SERVER_MINID;
+ maxid = id | RESOURCE_ID_MASK;
+ goodid = 0;
+ for (resp = clientTable[client].resources, i = clientTable[client].buckets;
+ --i >= 0;)
+ {
+ for (res = *resp++; res; res = res->next)
+ {
+ if ((res->id < id) || (res->id > maxid))
+ continue;
+ if (((res->id - id) >= (maxid - res->id)) ?
+ (goodid = AvailableID(client, id, res->id - 1, goodid)) :
+ !(goodid = AvailableID(client, res->id + 1, maxid, goodid)))
+ maxid = res->id - 1;
+ else
+ id = res->id + 1;
+ }
+ }
+ if (id > maxid)
+ id = maxid = 0;
+ *minp = id;
+ *maxp = maxid;
+}
+
+/**
+ * GetXIDList is called by the XC-MISC extension's MiscGetXIDList function.
+ * This function tries to find count unused XIDs for the given client. It
+ * puts the IDs in the array pids and returns the number found, which should
+ * almost always be the number requested.
+ *
+ * The circumstances that lead to a call to this function are very rare.
+ * Xlib must run out of IDs while trying to generate a request that wants
+ * multiple ID's, like the Multi-buffering CreateImageBuffers request.
+ *
+ * No rocket science in the implementation; just iterate over all
+ * possible IDs for the given client and pick the first count IDs
+ * that aren't in use. A more efficient algorithm could probably be
+ * invented, but this will be used so rarely that this should suffice.
+ */
+
+unsigned int
+GetXIDList(ClientPtr pClient, unsigned count, XID *pids)
+{
+ unsigned int found = 0;
+ XID id = pClient->clientAsMask;
+ XID maxid;
+
+ maxid = id | RESOURCE_ID_MASK;
+ while ( (found < count) && (id <= maxid) )
+ {
+ if (!LookupIDByClass(id, RC_ANY))
+ {
+ pids[found++] = id;
+ }
+ id++;
+ }
+ return found;
+}
+
+/*
+ * Return the next usable fake client ID.
+ *
+ * Normally this is just the next one in line, but if we've used the last
+ * in the range, we need to find a new range of safe IDs to avoid
+ * over-running another client.
+ */
+
+XID
+FakeClientID(register int client)
+{
+ XID id, maxid;
+
+ id = clientTable[client].fakeID++;
+ if (id != clientTable[client].endFakeID)
+ return id;
+ GetXIDRange(client, TRUE, &id, &maxid);
+ if (!id) {
+ if (!client)
+ FatalError("FakeClientID: server internal ids exhausted\n");
+ MarkClientException(clients[client]);
+ id = ((Mask)client << CLIENTOFFSET) | (SERVER_BIT * 3);
+ maxid = id | RESOURCE_ID_MASK;
+ }
+ clientTable[client].fakeID = id + 1;
+ clientTable[client].endFakeID = maxid + 1;
+ return id;
+}
+
+#ifdef NXAGENT_SERVER
+
+int nxagentFindClientResource(int client, RESTYPE type, pointer value)
+{
+ ResourcePtr pResource;
+ ResourcePtr *resources;
+
+ int i;
+
+ for (i = 0; i < clientTable[client].buckets; i++)
+ {
+ resources = clientTable[client].resources;
+
+ for (pResource = resources[i]; pResource; pResource = pResource -> next)
+ {
+ if (pResource -> type == type && pResource -> value == value)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentFindClientResource: Found resource [%p] type [%lu] "
+ "for client [%d].\n", (void *) value,
+ pResource -> type, client);
+ #endif
+
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+int nxagentSwitchResourceType(int client, RESTYPE type, pointer value)
+{
+ ResourcePtr pResource;
+ ResourcePtr *resources;
+
+ RESTYPE internalType = 0;
+
+ int i;
+
+ if (type == RT_PIXMAP)
+ {
+ internalType = RT_NX_PIXMAP;
+ }
+ else if (type == RT_GC)
+ {
+ internalType = RT_NX_GC;
+ }
+ else if (type == RT_FONT)
+ {
+ internalType = RT_NX_FONT;
+ }
+ else
+ {
+ return 0;
+ }
+
+ if (client == serverClient -> index)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSwitchResourceType: Requesting client is [%d]. Skipping the resource switch.\n",
+ client);
+ #endif
+
+ return 0;
+ }
+
+ for (i = 0; i < clientTable[serverClient -> index].buckets; i++)
+ {
+ resources = clientTable[serverClient -> index].resources;
+
+ for (pResource = resources[i]; pResource; pResource = pResource -> next)
+ {
+ if (pResource -> type == internalType &&
+ pResource -> value == value)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSwitchResourceType: Changing resource [%p] type from [%lu] to "
+ "[%lu] for server client [%d].\n", (void *) value,
+ (unsigned long) pResource -> type, (unsigned long) type, serverClient -> index);
+ #endif
+
+ FreeResource(pResource -> id, RT_NONE);
+
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+#endif
+
+Bool
+AddResource(XID id, RESTYPE type, pointer value)
+{
+ int client;
+ register ClientResourceRec *rrec;
+ register ResourcePtr res, *head;
+
+ client = CLIENT_ID(id);
+ rrec = &clientTable[client];
+ if (!rrec->buckets)
+ {
+ ErrorF("AddResource(%lx, %lx, %lx), client=%d \n",
+ (unsigned long)id, type, (unsigned long)value, client);
+ FatalError("client not in use\n");
+ }
+
+#ifdef NXAGENT_SERVER
+
+ nxagentSwitchResourceType(client, type, value);
+
+ #ifdef TEST
+ fprintf(stderr, "AddResource: Adding resource for client [%d] type [%lu] value [%p] id [%lu].\n",
+ client, (unsigned long) type, (void *) value, (unsigned long) id);
+ #endif
+
+#endif
+
+ if ((rrec->elements >= 4*rrec->buckets) &&
+ (rrec->hashsize < MAXHASHSIZE))
+ RebuildTable(client);
+ head = &rrec->resources[Hash(client, id)];
+ res = (ResourcePtr)xalloc(sizeof(ResourceRec));
+ if (!res)
+ {
+ (*DeleteFuncs[type & TypeMask])(value, id);
+ return FALSE;
+ }
+ res->next = *head;
+ res->id = id;
+ res->type = type;
+ res->value = value;
+ *head = res;
+ rrec->elements++;
+ if (!(id & SERVER_BIT) && (id >= rrec->expectID))
+ rrec->expectID = id + 1;
+ return TRUE;
+}
+
+static void
+RebuildTable(int client)
+{
+ register int j;
+ register ResourcePtr res, next;
+ ResourcePtr **tails, *resources;
+ register ResourcePtr **tptr, *rptr;
+
+ /*
+ * For now, preserve insertion order, since some ddx layers depend
+ * on resources being free in the opposite order they are added.
+ */
+
+ j = 2 * clientTable[client].buckets;
+ tails = (ResourcePtr **)ALLOCATE_LOCAL(j * sizeof(ResourcePtr *));
+ if (!tails)
+ return;
+ resources = (ResourcePtr *)xalloc(j * sizeof(ResourcePtr));
+ if (!resources)
+ {
+ DEALLOCATE_LOCAL(tails);
+ return;
+ }
+ for (rptr = resources, tptr = tails; --j >= 0; rptr++, tptr++)
+ {
+ *rptr = NullResource;
+ *tptr = rptr;
+ }
+ clientTable[client].hashsize++;
+ for (j = clientTable[client].buckets,
+ rptr = clientTable[client].resources;
+ --j >= 0;
+ rptr++)
+ {
+ for (res = *rptr; res; res = next)
+ {
+ next = res->next;
+ res->next = NullResource;
+ tptr = &tails[Hash(client, res->id)];
+ **tptr = res;
+ *tptr = &res->next;
+ }
+ }
+ DEALLOCATE_LOCAL(tails);
+ clientTable[client].buckets *= 2;
+ xfree(clientTable[client].resources);
+ clientTable[client].resources = resources;
+}
+
+void
+FreeResource(XID id, RESTYPE skipDeleteFuncType)
+{
+ int cid;
+ register ResourcePtr res;
+ register ResourcePtr *prev, *head;
+ register int *eltptr;
+ int elements;
+ Bool gotOne = FALSE;
+
+#ifdef NXAGENT_SERVER
+
+ #ifdef TEST
+ fprintf(stderr, "FreeResource: Freeing resource id [%lu].\n", (unsigned long) id);
+ #endif
+
+#endif
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+ {
+ head = &clientTable[cid].resources[Hash(cid, id)];
+ eltptr = &clientTable[cid].elements;
+
+ prev = head;
+ while ( (res = *prev) )
+ {
+ if (res->id == id)
+ {
+ RESTYPE rtype = res->type;
+ *prev = res->next;
+ elements = --*eltptr;
+ if (rtype & RC_CACHED)
+ FlushClientCaches(res->id);
+ if (rtype != skipDeleteFuncType)
+ (*DeleteFuncs[rtype & TypeMask])(res->value, res->id);
+ xfree(res);
+ if (*eltptr != elements)
+ prev = head; /* prev may no longer be valid */
+ gotOne = TRUE;
+ }
+ else
+ prev = &res->next;
+ }
+ if(clients[cid] && (id == clients[cid]->lastDrawableID))
+ {
+ clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
+ clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
+ }
+ }
+ if (!gotOne)
+ ErrorF("Freeing resource id=%lX which isn't there.\n",
+ (unsigned long)id);
+}
+
+
+void
+FreeResourceByType(XID id, RESTYPE type, Bool skipFree)
+{
+ int cid;
+ register ResourcePtr res;
+ register ResourcePtr *prev, *head;
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+ {
+ head = &clientTable[cid].resources[Hash(cid, id)];
+
+ prev = head;
+ while ( (res = *prev) )
+ {
+ if (res->id == id && res->type == type)
+ {
+ *prev = res->next;
+ if (type & RC_CACHED)
+ FlushClientCaches(res->id);
+ if (!skipFree)
+ (*DeleteFuncs[type & TypeMask])(res->value, res->id);
+ xfree(res);
+ break;
+ }
+ else
+ prev = &res->next;
+ }
+ if(clients[cid] && (id == clients[cid]->lastDrawableID))
+ {
+ clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
+ clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
+ }
+ }
+}
+
+/*
+ * Change the value associated with a resource id. Caller
+ * is responsible for "doing the right thing" with the old
+ * data
+ */
+
+Bool
+ChangeResourceValue (XID id, RESTYPE rtype, pointer value)
+{
+ int cid;
+ register ResourcePtr res;
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+ {
+ res = clientTable[cid].resources[Hash(cid, id)];
+
+ for (; res; res = res->next)
+ if ((res->id == id) && (res->type == rtype))
+ {
+ if (rtype & RC_CACHED)
+ FlushClientCaches(res->id);
+ res->value = value;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/* Note: if func adds or deletes resources, then func can get called
+ * more than once for some resources. If func adds new resources,
+ * func might or might not get called for them. func cannot both
+ * add and delete an equal number of resources!
+ */
+
+void
+FindClientResourcesByType(
+ ClientPtr client,
+ RESTYPE type,
+ FindResType func,
+ pointer cdata
+){
+ register ResourcePtr *resources;
+ register ResourcePtr this, next;
+ int i, elements;
+ register int *eltptr;
+
+ #ifdef NXAGENT_SERVER
+ register ResourcePtr **resptr;
+ #endif
+
+ if (!client)
+ client = serverClient;
+
+/*
+ * If func triggers a resource table
+ * rebuild then restart the loop.
+ */
+
+#ifdef NXAGENT_SERVER
+RestartLoop:
+#endif
+
+ resources = clientTable[client->index].resources;
+
+ #ifdef NXAGENT_SERVER
+ resptr = &clientTable[client->index].resources;
+ #endif
+
+ eltptr = &clientTable[client->index].elements;
+ for (i = 0; i < clientTable[client->index].buckets; i++)
+ {
+ for (this = resources[i]; this; this = next)
+ {
+ next = this->next;
+ if (!type || this->type == type) {
+ elements = *eltptr;
+ (*func)(this->value, this->id, cdata);
+ #ifdef NXAGENT_SERVER
+ if (*resptr != resources)
+ goto RestartLoop;
+ #endif
+ if (*eltptr != elements)
+ next = resources[i]; /* start over */
+ }
+ }
+ }
+}
+
+void
+FindAllClientResources(
+ ClientPtr client,
+ FindAllRes func,
+ pointer cdata
+){
+ register ResourcePtr *resources;
+ register ResourcePtr this, next;
+ int i, elements;
+ register int *eltptr;
+
+ #ifdef NXAGENT_SERVER
+ register ResourcePtr **resptr;
+ #endif
+
+ if (!client)
+ client = serverClient;
+
+/*
+ * If func triggers a resource table
+ * rebuild then restart the loop.
+ */
+
+#ifdef NXAGENT_SERVER
+RestartLoop:
+#endif
+
+ resources = clientTable[client->index].resources;
+
+ #ifdef NXAGENT_SERVER
+ resptr = &clientTable[client->index].resources;
+ #endif
+
+ eltptr = &clientTable[client->index].elements;
+ for (i = 0; i < clientTable[client->index].buckets; i++)
+ {
+ for (this = resources[i]; this; this = next)
+ {
+ next = this->next;
+ elements = *eltptr;
+ (*func)(this->value, this->id, this->type, cdata);
+ #ifdef NXAGENT_SERVER
+ if (*resptr != resources)
+ goto RestartLoop;
+ #endif
+ if (*eltptr != elements)
+ next = resources[i]; /* start over */
+ }
+ }
+}
+
+
+pointer
+LookupClientResourceComplex(
+ ClientPtr client,
+ RESTYPE type,
+ FindComplexResType func,
+ pointer cdata
+){
+ ResourcePtr *resources;
+ ResourcePtr this;
+ int i;
+
+ #ifdef NXAGENT_SERVER
+ ResourcePtr **resptr;
+ Bool res;
+ #endif
+
+ if (!client)
+ client = serverClient;
+
+/*
+ * If func triggers a resource table
+ * rebuild then restart the loop.
+ */
+
+#ifdef NXAGENT_SERVER
+RestartLoop:
+#endif
+
+ resources = clientTable[client->index].resources;
+
+ #ifdef NXAGENT_SERVER
+ resptr = &clientTable[client->index].resources;
+ #endif
+
+ for (i = 0; i < clientTable[client->index].buckets; i++) {
+ for (this = resources[i]; this; this = this->next) {
+ if (!type || this->type == type) {
+ #ifdef NXAGENT_SERVER
+ res = (*func)(this->value, this->id, cdata);
+
+ if (*resptr != resources)
+ goto RestartLoop;
+
+ if (res)
+ return this->value;
+ #else
+ if((*func)(this->value, this->id, cdata))
+ return this->value;
+ #endif
+ }
+ }
+ }
+ return NULL;
+}
+
+
+void
+FreeClientNeverRetainResources(ClientPtr client)
+{
+ ResourcePtr *resources;
+ ResourcePtr this;
+ ResourcePtr *prev;
+ int j;
+
+ if (!client)
+ return;
+
+ resources = clientTable[client->index].resources;
+ for (j=0; j < clientTable[client->index].buckets; j++)
+ {
+ prev = &resources[j];
+ while ( (this = *prev) )
+ {
+ RESTYPE rtype = this->type;
+ if (rtype & RC_NEVERRETAIN)
+ {
+ *prev = this->next;
+ if (rtype & RC_CACHED)
+ FlushClientCaches(this->id);
+ (*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
+ xfree(this);
+ }
+ else
+ prev = &this->next;
+ }
+ }
+}
+
+void
+FreeClientResources(ClientPtr client)
+{
+ register ResourcePtr *resources;
+ register ResourcePtr this;
+ int j;
+
+ /* This routine shouldn't be called with a null client, but just in
+ case ... */
+
+ if (!client)
+ return;
+
+ HandleSaveSet(client);
+
+ resources = clientTable[client->index].resources;
+ for (j=0; j < clientTable[client->index].buckets; j++)
+ {
+ /* It may seem silly to update the head of this resource list as
+ we delete the members, since the entire list will be deleted any way,
+ but there are some resource deletion functions "FreeClientPixels" for
+ one which do a LookupID on another resource id (a Colormap id in this
+ case), so the resource list must be kept valid up to the point that
+ it is deleted, so every time we delete a resource, we must update the
+ head, just like in FreeResource. I hope that this doesn't slow down
+ mass deletion appreciably. PRH */
+
+ ResourcePtr *head;
+
+ head = &resources[j];
+
+ for (this = *head; this; this = *head)
+ {
+ RESTYPE rtype = this->type;
+ *head = this->next;
+ if (rtype & RC_CACHED)
+ FlushClientCaches(this->id);
+ (*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
+ xfree(this);
+ }
+ }
+ xfree(clientTable[client->index].resources);
+ clientTable[client->index].resources = NULL;
+ clientTable[client->index].buckets = 0;
+}
+
+void
+FreeAllResources()
+{
+ int i;
+
+ for (i = currentMaxClients; --i >= 0; )
+ {
+ if (clientTable[i].buckets)
+ FreeClientResources(clients[i]);
+ }
+}
+
+Bool
+LegalNewID(XID id, register ClientPtr client)
+{
+
+#ifdef PANORAMIX
+ XID minid, maxid;
+
+ if (!noPanoramiXExtension) {
+ minid = client->clientAsMask | (client->index ?
+ SERVER_BIT : SERVER_MINID);
+ maxid = (clientTable[client->index].fakeID | RESOURCE_ID_MASK) + 1;
+ if ((id >= minid) && (id <= maxid))
+ return TRUE;
+ }
+#endif /* PANORAMIX */
+ return ((client->clientAsMask == (id & ~RESOURCE_ID_MASK)) &&
+ ((clientTable[client->index].expectID <= id) ||
+ !LookupIDByClass(id, RC_ANY)));
+}
+
+#ifdef XCSECURITY
+
+/* SecurityLookupIDByType and SecurityLookupIDByClass:
+ * These are the heart of the resource ID security system. They take
+ * two additional arguments compared to the old LookupID functions:
+ * the client doing the lookup, and the access mode (see resource.h).
+ * The resource is returned if it exists and the client is allowed access,
+ * else NULL is returned.
+ */
+
+pointer
+SecurityLookupIDByType(ClientPtr client, XID id, RESTYPE rtype, Mask mode)
+{
+ int cid;
+ register ResourcePtr res;
+ pointer retval = NULL;
+
+ assert(client == NullClient ||
+ (client->index <= currentMaxClients && clients[client->index] == client));
+ assert( (rtype & TypeMask) <= lastResourceType);
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+ clientTable[cid].buckets)
+ {
+ res = clientTable[cid].resources[Hash(cid, id)];
+
+ for (; res; res = res->next)
+ if ((res->id == id) && (res->type == rtype))
+ {
+ retval = res->value;
+ break;
+ }
+ }
+ if (retval && client && client->CheckAccess)
+ retval = (* client->CheckAccess)(client, id, rtype, mode, retval);
+ return retval;
+}
+
+
+pointer
+SecurityLookupIDByClass(ClientPtr client, XID id, RESTYPE classes, Mask mode)
+{
+ int cid;
+ register ResourcePtr res = NULL;
+ pointer retval = NULL;
+
+ assert(client == NullClient ||
+ (client->index <= currentMaxClients && clients[client->index] == client));
+ assert (classes >= lastResourceClass);
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+ clientTable[cid].buckets)
+ {
+ res = clientTable[cid].resources[Hash(cid, id)];
+
+ for (; res; res = res->next)
+ if ((res->id == id) && (res->type & classes))
+ {
+ retval = res->value;
+ break;
+ }
+ }
+ if (retval && client && client->CheckAccess)
+ retval = (* client->CheckAccess)(client, id, res->type, mode, retval);
+ return retval;
+}
+
+/* We can't replace the LookupIDByType and LookupIDByClass functions with
+ * macros because of compatibility with loadable servers.
+ */
+
+pointer
+LookupIDByType(XID id, RESTYPE rtype)
+{
+ return SecurityLookupIDByType(NullClient, id, rtype,
+ SecurityUnknownAccess);
+}
+
+pointer
+LookupIDByClass(XID id, RESTYPE classes)
+{
+ return SecurityLookupIDByClass(NullClient, id, classes,
+ SecurityUnknownAccess);
+}
+
+#else /* not XCSECURITY */
+
+/*
+ * LookupIDByType returns the object with the given id and type, else NULL.
+ */
+pointer
+LookupIDByType(XID id, RESTYPE rtype)
+{
+ int cid;
+ register ResourcePtr res;
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+ clientTable[cid].buckets)
+ {
+ res = clientTable[cid].resources[Hash(cid, id)];
+
+ for (; res; res = res->next)
+ if ((res->id == id) && (res->type == rtype))
+ return res->value;
+ }
+ return (pointer)NULL;
+}
+
+/*
+ * LookupIDByClass returns the object with the given id and any one of the
+ * given classes, else NULL.
+ */
+pointer
+LookupIDByClass(XID id, RESTYPE classes)
+{
+ int cid;
+ register ResourcePtr res;
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+ clientTable[cid].buckets)
+ {
+ res = clientTable[cid].resources[Hash(cid, id)];
+
+ for (; res; res = res->next)
+ if ((res->id == id) && (res->type & classes))
+ return res->value;
+ }
+ return (pointer)NULL;
+}
+
+#endif /* XCSECURITY */
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original
new file mode 100644
index 000000000..9af5c4187
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original
@@ -0,0 +1,1173 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/************************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+********************************************************/
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+/* $Xorg: resource.c,v 1.5 2001/02/09 02:04:40 xorgcvs Exp $ */
+/* $XdotOrg: xc/programs/Xserver/dix/resource.c,v 1.8 2005/07/03 08:53:38 daniels Exp $ */
+/* $TOG: resource.c /main/41 1998/02/09 14:20:31 kaleb $ */
+
+/* Routines to manage various kinds of resources:
+ *
+ * CreateNewResourceType, CreateNewResourceClass, InitClientResources,
+ * FakeClientID, AddResource, FreeResource, FreeClientResources,
+ * FreeAllResources, LookupIDByType, LookupIDByClass, GetXIDRange
+ */
+
+/*
+ * A resource ID is a 32 bit quantity, the upper 2 bits of which are
+ * off-limits for client-visible resources. The next 8 bits are
+ * used as client ID, and the low 22 bits come from the client.
+ * A resource ID is "hashed" by extracting and xoring subfields
+ * (varying with the size of the hash table).
+ *
+ * It is sometimes necessary for the server to create an ID that looks
+ * like it belongs to a client. This ID, however, must not be one
+ * the client actually can create, or we have the potential for conflict.
+ * The 31st bit of the ID is reserved for the server's use for this
+ * purpose. By setting CLIENT_ID(id) to the client, the SERVER_BIT to
+ * 1, and an otherwise arbitrary ID in the low 22 bits, we can create a
+ * resource "owned" by the client.
+ */
+/* $XFree86: xc/programs/Xserver/dix/resource.c,v 3.13 2003/09/24 02:43:13 dawes Exp $ */
+
+#define NEED_EVENTS
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "misc.h"
+#include "os.h"
+#include "resource.h"
+#include "dixstruct.h"
+#include "opaque.h"
+#include "windowstr.h"
+#include "dixfont.h"
+#include "colormap.h"
+#include "inputstr.h"
+#include "dixevents.h"
+#include "dixgrabs.h"
+#include "cursor.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#include <assert.h>
+
+#ifdef NXAGENT_SERVER
+
+#include "Agent.h"
+#include "Font.h"
+#include "Pixmaps.h"
+#include "GCs.h"
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+#endif
+
+static void RebuildTable(
+ int /*client*/
+);
+
+#define SERVER_MINID 32
+
+#define INITBUCKETS 64
+#define INITHASHSIZE 6
+#define MAXHASHSIZE 11
+
+typedef struct _Resource {
+ struct _Resource *next;
+ XID id;
+ RESTYPE type;
+ pointer value;
+} ResourceRec, *ResourcePtr;
+#define NullResource ((ResourcePtr)NULL)
+
+typedef struct _ClientResource {
+ ResourcePtr *resources;
+ int elements;
+ int buckets;
+ int hashsize; /* log(2)(buckets) */
+ XID fakeID;
+ XID endFakeID;
+ XID expectID;
+} ClientResourceRec;
+
+RESTYPE lastResourceType;
+static RESTYPE lastResourceClass;
+RESTYPE TypeMask;
+
+static DeleteType *DeleteFuncs = (DeleteType *)NULL;
+
+#ifdef XResExtension
+
+Atom * ResourceNames = NULL;
+
+void RegisterResourceName (RESTYPE type, char *name)
+{
+ ResourceNames[type & TypeMask] = MakeAtom(name, strlen(name), TRUE);
+}
+
+#endif
+
+RESTYPE
+CreateNewResourceType(DeleteType deleteFunc)
+{
+ RESTYPE next = lastResourceType + 1;
+ DeleteType *funcs;
+
+ if (next & lastResourceClass)
+ return 0;
+ funcs = (DeleteType *)xrealloc(DeleteFuncs,
+ (next + 1) * sizeof(DeleteType));
+ if (!funcs)
+ return 0;
+
+#ifdef XResExtension
+ {
+ Atom *newnames;
+ newnames = xrealloc(ResourceNames, (next + 1) * sizeof(Atom));
+ if(!newnames)
+ return 0;
+ ResourceNames = newnames;
+ ResourceNames[next] = 0;
+ }
+#endif
+
+ lastResourceType = next;
+ DeleteFuncs = funcs;
+ DeleteFuncs[next] = deleteFunc;
+ return next;
+}
+
+RESTYPE
+CreateNewResourceClass()
+{
+ RESTYPE next = lastResourceClass >> 1;
+
+ if (next & lastResourceType)
+ return 0;
+ lastResourceClass = next;
+ TypeMask = next - 1;
+ return next;
+}
+
+ClientResourceRec clientTable[MAXCLIENTS];
+
+/*****************
+ * InitClientResources
+ * When a new client is created, call this to allocate space
+ * in resource table
+ *****************/
+
+Bool
+InitClientResources(ClientPtr client)
+{
+ register int i, j;
+
+ if (client == serverClient)
+ {
+ lastResourceType = RT_LASTPREDEF;
+ lastResourceClass = RC_LASTPREDEF;
+ TypeMask = RC_LASTPREDEF - 1;
+ if (DeleteFuncs)
+ xfree(DeleteFuncs);
+ DeleteFuncs = (DeleteType *)xalloc((lastResourceType + 1) *
+ sizeof(DeleteType));
+ if (!DeleteFuncs)
+ return FALSE;
+ DeleteFuncs[RT_NONE & TypeMask] = (DeleteType)NoopDDA;
+ DeleteFuncs[RT_WINDOW & TypeMask] = DeleteWindow;
+ DeleteFuncs[RT_PIXMAP & TypeMask] = dixDestroyPixmap;
+ DeleteFuncs[RT_GC & TypeMask] = FreeGC;
+ DeleteFuncs[RT_FONT & TypeMask] = CloseFont;
+ DeleteFuncs[RT_CURSOR & TypeMask] = FreeCursor;
+ DeleteFuncs[RT_COLORMAP & TypeMask] = FreeColormap;
+ DeleteFuncs[RT_CMAPENTRY & TypeMask] = FreeClientPixels;
+ DeleteFuncs[RT_OTHERCLIENT & TypeMask] = OtherClientGone;
+ DeleteFuncs[RT_PASSIVEGRAB & TypeMask] = DeletePassiveGrab;
+
+#ifdef XResExtension
+ if(ResourceNames)
+ xfree(ResourceNames);
+ ResourceNames = xalloc((lastResourceType + 1) * sizeof(Atom));
+ if(!ResourceNames)
+ return FALSE;
+#endif
+ }
+ clientTable[i = client->index].resources =
+ (ResourcePtr *)xalloc(INITBUCKETS*sizeof(ResourcePtr));
+ if (!clientTable[i].resources)
+ return FALSE;
+ clientTable[i].buckets = INITBUCKETS;
+ clientTable[i].elements = 0;
+ clientTable[i].hashsize = INITHASHSIZE;
+ /* Many IDs allocated from the server client are visible to clients,
+ * so we don't use the SERVER_BIT for them, but we have to start
+ * past the magic value constants used in the protocol. For normal
+ * clients, we can start from zero, with SERVER_BIT set.
+ */
+ clientTable[i].fakeID = client->clientAsMask |
+ (client->index ? SERVER_BIT : SERVER_MINID);
+ clientTable[i].endFakeID = (clientTable[i].fakeID | RESOURCE_ID_MASK) + 1;
+ clientTable[i].expectID = client->clientAsMask;
+ for (j=0; j<INITBUCKETS; j++)
+ {
+ clientTable[i].resources[j] = NullResource;
+ }
+ return TRUE;
+}
+
+
+static int
+Hash(int client, register XID id)
+{
+ id &= RESOURCE_ID_MASK;
+ switch (clientTable[client].hashsize)
+ {
+ case 6:
+ return ((int)(0x03F & (id ^ (id>>6) ^ (id>>12))));
+ case 7:
+ return ((int)(0x07F & (id ^ (id>>7) ^ (id>>13))));
+ case 8:
+ return ((int)(0x0FF & (id ^ (id>>8) ^ (id>>16))));
+ case 9:
+ return ((int)(0x1FF & (id ^ (id>>9))));
+ case 10:
+ return ((int)(0x3FF & (id ^ (id>>10))));
+ case 11:
+ return ((int)(0x7FF & (id ^ (id>>11))));
+ }
+ return -1;
+}
+
+static XID
+AvailableID(
+ register int client,
+ register XID id,
+ register XID maxid,
+ register XID goodid)
+{
+ register ResourcePtr res;
+
+ if ((goodid >= id) && (goodid <= maxid))
+ return goodid;
+ for (; id <= maxid; id++)
+ {
+ res = clientTable[client].resources[Hash(client, id)];
+ while (res && (res->id != id))
+ res = res->next;
+ if (!res)
+ return id;
+ }
+ return 0;
+}
+
+void
+GetXIDRange(int client, Bool server, XID *minp, XID *maxp)
+{
+ register XID id, maxid;
+ register ResourcePtr *resp;
+ register ResourcePtr res;
+ register int i;
+ XID goodid;
+
+ id = (Mask)client << CLIENTOFFSET;
+ if (server)
+ id |= client ? SERVER_BIT : SERVER_MINID;
+ maxid = id | RESOURCE_ID_MASK;
+ goodid = 0;
+ for (resp = clientTable[client].resources, i = clientTable[client].buckets;
+ --i >= 0;)
+ {
+ for (res = *resp++; res; res = res->next)
+ {
+ if ((res->id < id) || (res->id > maxid))
+ continue;
+ if (((res->id - id) >= (maxid - res->id)) ?
+ (goodid = AvailableID(client, id, res->id - 1, goodid)) :
+ !(goodid = AvailableID(client, res->id + 1, maxid, goodid)))
+ maxid = res->id - 1;
+ else
+ id = res->id + 1;
+ }
+ }
+ if (id > maxid)
+ id = maxid = 0;
+ *minp = id;
+ *maxp = maxid;
+}
+
+/**
+ * GetXIDList is called by the XC-MISC extension's MiscGetXIDList function.
+ * This function tries to find count unused XIDs for the given client. It
+ * puts the IDs in the array pids and returns the number found, which should
+ * almost always be the number requested.
+ *
+ * The circumstances that lead to a call to this function are very rare.
+ * Xlib must run out of IDs while trying to generate a request that wants
+ * multiple ID's, like the Multi-buffering CreateImageBuffers request.
+ *
+ * No rocket science in the implementation; just iterate over all
+ * possible IDs for the given client and pick the first count IDs
+ * that aren't in use. A more efficient algorithm could probably be
+ * invented, but this will be used so rarely that this should suffice.
+ */
+
+unsigned int
+GetXIDList(ClientPtr pClient, unsigned count, XID *pids)
+{
+ unsigned int found = 0;
+ XID id = pClient->clientAsMask;
+ XID maxid;
+
+ maxid = id | RESOURCE_ID_MASK;
+ while ( (found < count) && (id <= maxid) )
+ {
+ if (!LookupIDByClass(id, RC_ANY))
+ {
+ pids[found++] = id;
+ }
+ id++;
+ }
+ return found;
+}
+
+/*
+ * Return the next usable fake client ID.
+ *
+ * Normally this is just the next one in line, but if we've used the last
+ * in the range, we need to find a new range of safe IDs to avoid
+ * over-running another client.
+ */
+
+XID
+FakeClientID(register int client)
+{
+ XID id, maxid;
+
+ id = clientTable[client].fakeID++;
+ if (id != clientTable[client].endFakeID)
+ return id;
+ GetXIDRange(client, TRUE, &id, &maxid);
+ if (!id) {
+ if (!client)
+ FatalError("FakeClientID: server internal ids exhausted\n");
+ MarkClientException(clients[client]);
+ id = ((Mask)client << CLIENTOFFSET) | (SERVER_BIT * 3);
+ maxid = id | RESOURCE_ID_MASK;
+ }
+ clientTable[client].fakeID = id + 1;
+ clientTable[client].endFakeID = maxid + 1;
+ return id;
+}
+
+#ifdef NXAGENT_SERVER
+
+int nxagentFindClientResource(int client, RESTYPE type, pointer value)
+{
+ ResourcePtr pResource;
+ ResourcePtr *resources;
+
+ int i;
+
+ for (i = 0; i < clientTable[client].buckets; i++)
+ {
+ resources = clientTable[client].resources;
+
+ for (pResource = resources[i]; pResource; pResource = pResource -> next)
+ {
+ if (pResource -> type == type && pResource -> value == value)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentFindClientResource: Found resource [%p] type [%lu] "
+ "for client [%d].\n", (void *) value,
+ pResource -> type, client);
+ #endif
+
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+int nxagentSwitchResourceType(int client, RESTYPE type, pointer value)
+{
+ ResourcePtr pResource;
+ ResourcePtr *resources;
+
+ RESTYPE internalType = 0;
+
+ int i;
+
+ if (type == RT_PIXMAP)
+ {
+ internalType = RT_NX_PIXMAP;
+ }
+ else if (type == RT_GC)
+ {
+ internalType = RT_NX_GC;
+ }
+ else if (type == RT_FONT)
+ {
+ internalType = RT_NX_FONT;
+ }
+ else
+ {
+ return 0;
+ }
+
+ if (client == serverClient -> index)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSwitchResourceType: Requesting client is [%d]. Skipping the resource switch.\n",
+ client);
+ #endif
+
+ return 0;
+ }
+
+ for (i = 0; i < clientTable[serverClient -> index].buckets; i++)
+ {
+ resources = clientTable[serverClient -> index].resources;
+
+ for (pResource = resources[i]; pResource; pResource = pResource -> next)
+ {
+ if (pResource -> type == internalType &&
+ pResource -> value == value)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSwitchResourceType: Changing resource [%p] type from [%lu] to "
+ "[%lu] for server client [%d].\n", (void *) value,
+ (unsigned long) pResource -> type, (unsigned long) type, serverClient -> index);
+ #endif
+
+ FreeResource(pResource -> id, RT_NONE);
+
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+#endif
+
+Bool
+AddResource(XID id, RESTYPE type, pointer value)
+{
+ int client;
+ register ClientResourceRec *rrec;
+ register ResourcePtr res, *head;
+
+ client = CLIENT_ID(id);
+ rrec = &clientTable[client];
+ if (!rrec->buckets)
+ {
+ ErrorF("AddResource(%lx, %lx, %lx), client=%d \n",
+ (unsigned long)id, type, (unsigned long)value, client);
+ FatalError("client not in use\n");
+ }
+
+#ifdef NXAGENT_SERVER
+
+ nxagentSwitchResourceType(client, type, value);
+
+ #ifdef TEST
+ fprintf(stderr, "AddResource: Adding resource for client [%d] type [%lu] value [%p] id [%lu].\n",
+ client, (unsigned long) type, (void *) value, (unsigned long) id);
+ #endif
+
+#endif
+
+ if ((rrec->elements >= 4*rrec->buckets) &&
+ (rrec->hashsize < MAXHASHSIZE))
+ RebuildTable(client);
+ head = &rrec->resources[Hash(client, id)];
+ res = (ResourcePtr)xalloc(sizeof(ResourceRec));
+ if (!res)
+ {
+ (*DeleteFuncs[type & TypeMask])(value, id);
+ return FALSE;
+ }
+ res->next = *head;
+ res->id = id;
+ res->type = type;
+ res->value = value;
+ *head = res;
+ rrec->elements++;
+ if (!(id & SERVER_BIT) && (id >= rrec->expectID))
+ rrec->expectID = id + 1;
+ return TRUE;
+}
+
+static void
+RebuildTable(int client)
+{
+ register int j;
+ register ResourcePtr res, next;
+ ResourcePtr **tails, *resources;
+ register ResourcePtr **tptr, *rptr;
+
+ /*
+ * For now, preserve insertion order, since some ddx layers depend
+ * on resources being free in the opposite order they are added.
+ */
+
+ j = 2 * clientTable[client].buckets;
+ tails = (ResourcePtr **)ALLOCATE_LOCAL(j * sizeof(ResourcePtr *));
+ if (!tails)
+ return;
+ resources = (ResourcePtr *)xalloc(j * sizeof(ResourcePtr));
+ if (!resources)
+ {
+ DEALLOCATE_LOCAL(tails);
+ return;
+ }
+ for (rptr = resources, tptr = tails; --j >= 0; rptr++, tptr++)
+ {
+ *rptr = NullResource;
+ *tptr = rptr;
+ }
+ clientTable[client].hashsize++;
+ for (j = clientTable[client].buckets,
+ rptr = clientTable[client].resources;
+ --j >= 0;
+ rptr++)
+ {
+ for (res = *rptr; res; res = next)
+ {
+ next = res->next;
+ res->next = NullResource;
+ tptr = &tails[Hash(client, res->id)];
+ **tptr = res;
+ *tptr = &res->next;
+ }
+ }
+ DEALLOCATE_LOCAL(tails);
+ clientTable[client].buckets *= 2;
+ xfree(clientTable[client].resources);
+ clientTable[client].resources = resources;
+}
+
+void
+FreeResource(XID id, RESTYPE skipDeleteFuncType)
+{
+ int cid;
+ register ResourcePtr res;
+ register ResourcePtr *prev, *head;
+ register int *eltptr;
+ int elements;
+ Bool gotOne = FALSE;
+
+#ifdef NXAGENT_SERVER
+
+ #ifdef TEST
+ fprintf(stderr, "FreeResource: Freeing resource id [%lu].\n", (unsigned long) id);
+ #endif
+
+#endif
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+ {
+ head = &clientTable[cid].resources[Hash(cid, id)];
+ eltptr = &clientTable[cid].elements;
+
+ prev = head;
+ while ( (res = *prev) )
+ {
+ if (res->id == id)
+ {
+ RESTYPE rtype = res->type;
+ *prev = res->next;
+ elements = --*eltptr;
+ if (rtype & RC_CACHED)
+ FlushClientCaches(res->id);
+ if (rtype != skipDeleteFuncType)
+ (*DeleteFuncs[rtype & TypeMask])(res->value, res->id);
+ xfree(res);
+ if (*eltptr != elements)
+ prev = head; /* prev may no longer be valid */
+ gotOne = TRUE;
+ }
+ else
+ prev = &res->next;
+ }
+ if(clients[cid] && (id == clients[cid]->lastDrawableID))
+ {
+ clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
+ clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
+ }
+ }
+ if (!gotOne)
+ ErrorF("Freeing resource id=%lX which isn't there.\n",
+ (unsigned long)id);
+}
+
+
+void
+FreeResourceByType(XID id, RESTYPE type, Bool skipFree)
+{
+ int cid;
+ register ResourcePtr res;
+ register ResourcePtr *prev, *head;
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+ {
+ head = &clientTable[cid].resources[Hash(cid, id)];
+
+ prev = head;
+ while ( (res = *prev) )
+ {
+ if (res->id == id && res->type == type)
+ {
+ *prev = res->next;
+ if (type & RC_CACHED)
+ FlushClientCaches(res->id);
+ if (!skipFree)
+ (*DeleteFuncs[type & TypeMask])(res->value, res->id);
+ xfree(res);
+ break;
+ }
+ else
+ prev = &res->next;
+ }
+ if(clients[cid] && (id == clients[cid]->lastDrawableID))
+ {
+ clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
+ clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
+ }
+ }
+}
+
+/*
+ * Change the value associated with a resource id. Caller
+ * is responsible for "doing the right thing" with the old
+ * data
+ */
+
+Bool
+ChangeResourceValue (XID id, RESTYPE rtype, pointer value)
+{
+ int cid;
+ register ResourcePtr res;
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+ {
+ res = clientTable[cid].resources[Hash(cid, id)];
+
+ for (; res; res = res->next)
+ if ((res->id == id) && (res->type == rtype))
+ {
+ if (rtype & RC_CACHED)
+ FlushClientCaches(res->id);
+ res->value = value;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/* Note: if func adds or deletes resources, then func can get called
+ * more than once for some resources. If func adds new resources,
+ * func might or might not get called for them. func cannot both
+ * add and delete an equal number of resources!
+ */
+
+void
+FindClientResourcesByType(
+ ClientPtr client,
+ RESTYPE type,
+ FindResType func,
+ pointer cdata
+){
+ register ResourcePtr *resources;
+ register ResourcePtr this, next;
+ int i, elements;
+ register int *eltptr;
+
+ #ifdef NXAGENT_SERVER
+ register ResourcePtr **resptr;
+ #endif
+
+ if (!client)
+ client = serverClient;
+
+/*
+ * If func triggers a resource table
+ * rebuild then restart the loop.
+ */
+
+#ifdef NXAGENT_SERVER
+RestartLoop:
+#endif
+
+ resources = clientTable[client->index].resources;
+
+ #ifdef NXAGENT_SERVER
+ resptr = &clientTable[client->index].resources;
+ #endif
+
+ eltptr = &clientTable[client->index].elements;
+ for (i = 0; i < clientTable[client->index].buckets; i++)
+ {
+ for (this = resources[i]; this; this = next)
+ {
+ next = this->next;
+ if (!type || this->type == type) {
+ elements = *eltptr;
+ (*func)(this->value, this->id, cdata);
+ #ifdef NXAGENT_SERVER
+ if (*resptr != resources)
+ goto RestartLoop;
+ #endif
+ if (*eltptr != elements)
+ next = resources[i]; /* start over */
+ }
+ }
+ }
+}
+
+void
+FindAllClientResources(
+ ClientPtr client,
+ FindAllRes func,
+ pointer cdata
+){
+ register ResourcePtr *resources;
+ register ResourcePtr this, next;
+ int i, elements;
+ register int *eltptr;
+
+ #ifdef NXAGENT_SERVER
+ register ResourcePtr **resptr;
+ #endif
+
+ if (!client)
+ client = serverClient;
+
+/*
+ * If func triggers a resource table
+ * rebuild then restart the loop.
+ */
+
+#ifdef NXAGENT_SERVER
+RestartLoop:
+#endif
+
+ resources = clientTable[client->index].resources;
+
+ #ifdef NXAGENT_SERVER
+ resptr = &clientTable[client->index].resources;
+ #endif
+
+ eltptr = &clientTable[client->index].elements;
+ for (i = 0; i < clientTable[client->index].buckets; i++)
+ {
+ for (this = resources[i]; this; this = next)
+ {
+ next = this->next;
+ elements = *eltptr;
+ (*func)(this->value, this->id, this->type, cdata);
+ #ifdef NXAGENT_SERVER
+ if (*resptr != resources)
+ goto RestartLoop;
+ #endif
+ if (*eltptr != elements)
+ next = resources[i]; /* start over */
+ }
+ }
+}
+
+
+pointer
+LookupClientResourceComplex(
+ ClientPtr client,
+ RESTYPE type,
+ FindComplexResType func,
+ pointer cdata
+){
+ ResourcePtr *resources;
+ ResourcePtr this;
+ int i;
+
+ #ifdef NXAGENT_SERVER
+ ResourcePtr **resptr;
+ Bool res;
+ #endif
+
+ if (!client)
+ client = serverClient;
+
+/*
+ * If func triggers a resource table
+ * rebuild then restart the loop.
+ */
+
+#ifdef NXAGENT_SERVER
+RestartLoop:
+#endif
+
+ resources = clientTable[client->index].resources;
+
+ #ifdef NXAGENT_SERVER
+ resptr = &clientTable[client->index].resources;
+ #endif
+
+ for (i = 0; i < clientTable[client->index].buckets; i++) {
+ for (this = resources[i]; this; this = this->next) {
+ if (!type || this->type == type) {
+ #ifdef NXAGENT_SERVER
+ res = (*func)(this->value, this->id, cdata);
+
+ if (*resptr != resources)
+ goto RestartLoop;
+
+ if (res)
+ return this->value;
+ #else
+ if((*func)(this->value, this->id, cdata))
+ return this->value;
+ #endif
+ }
+ }
+ }
+ return NULL;
+}
+
+
+void
+FreeClientNeverRetainResources(ClientPtr client)
+{
+ ResourcePtr *resources;
+ ResourcePtr this;
+ ResourcePtr *prev;
+ int j;
+
+ if (!client)
+ return;
+
+ resources = clientTable[client->index].resources;
+ for (j=0; j < clientTable[client->index].buckets; j++)
+ {
+ prev = &resources[j];
+ while ( (this = *prev) )
+ {
+ RESTYPE rtype = this->type;
+ if (rtype & RC_NEVERRETAIN)
+ {
+ *prev = this->next;
+ if (rtype & RC_CACHED)
+ FlushClientCaches(this->id);
+ (*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
+ xfree(this);
+ }
+ else
+ prev = &this->next;
+ }
+ }
+}
+
+void
+FreeClientResources(ClientPtr client)
+{
+ register ResourcePtr *resources;
+ register ResourcePtr this;
+ int j;
+
+ /* This routine shouldn't be called with a null client, but just in
+ case ... */
+
+ if (!client)
+ return;
+
+ HandleSaveSet(client);
+
+ resources = clientTable[client->index].resources;
+ for (j=0; j < clientTable[client->index].buckets; j++)
+ {
+ /* It may seem silly to update the head of this resource list as
+ we delete the members, since the entire list will be deleted any way,
+ but there are some resource deletion functions "FreeClientPixels" for
+ one which do a LookupID on another resource id (a Colormap id in this
+ case), so the resource list must be kept valid up to the point that
+ it is deleted, so every time we delete a resource, we must update the
+ head, just like in FreeResource. I hope that this doesn't slow down
+ mass deletion appreciably. PRH */
+
+ ResourcePtr *head;
+
+ head = &resources[j];
+
+ for (this = *head; this; this = *head)
+ {
+ RESTYPE rtype = this->type;
+ *head = this->next;
+ if (rtype & RC_CACHED)
+ FlushClientCaches(this->id);
+ (*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
+ xfree(this);
+ }
+ }
+ xfree(clientTable[client->index].resources);
+ clientTable[client->index].resources = NULL;
+ clientTable[client->index].buckets = 0;
+}
+
+void
+FreeAllResources()
+{
+ int i;
+
+ for (i = currentMaxClients; --i >= 0; )
+ {
+ if (clientTable[i].buckets)
+ FreeClientResources(clients[i]);
+ }
+}
+
+Bool
+LegalNewID(XID id, register ClientPtr client)
+{
+
+#ifdef PANORAMIX
+ XID minid, maxid;
+
+ if (!noPanoramiXExtension) {
+ minid = client->clientAsMask | (client->index ?
+ SERVER_BIT : SERVER_MINID);
+ maxid = (clientTable[client->index].fakeID | RESOURCE_ID_MASK) + 1;
+ if ((id >= minid) && (id <= maxid))
+ return TRUE;
+ }
+#endif /* PANORAMIX */
+ return ((client->clientAsMask == (id & ~RESOURCE_ID_MASK)) &&
+ ((clientTable[client->index].expectID <= id) ||
+ !LookupIDByClass(id, RC_ANY)));
+}
+
+#ifdef XCSECURITY
+
+/* SecurityLookupIDByType and SecurityLookupIDByClass:
+ * These are the heart of the resource ID security system. They take
+ * two additional arguments compared to the old LookupID functions:
+ * the client doing the lookup, and the access mode (see resource.h).
+ * The resource is returned if it exists and the client is allowed access,
+ * else NULL is returned.
+ */
+
+pointer
+SecurityLookupIDByType(ClientPtr client, XID id, RESTYPE rtype, Mask mode)
+{
+ int cid;
+ register ResourcePtr res;
+ pointer retval = NULL;
+
+ assert(client == NullClient ||
+ (client->index <= currentMaxClients && clients[client->index] == client));
+ assert( (rtype & TypeMask) <= lastResourceType);
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+ clientTable[cid].buckets)
+ {
+ res = clientTable[cid].resources[Hash(cid, id)];
+
+ for (; res; res = res->next)
+ if ((res->id == id) && (res->type == rtype))
+ {
+ retval = res->value;
+ break;
+ }
+ }
+ if (retval && client && client->CheckAccess)
+ retval = (* client->CheckAccess)(client, id, rtype, mode, retval);
+ return retval;
+}
+
+
+pointer
+SecurityLookupIDByClass(ClientPtr client, XID id, RESTYPE classes, Mask mode)
+{
+ int cid;
+ register ResourcePtr res = NULL;
+ pointer retval = NULL;
+
+ assert(client == NullClient ||
+ (client->index <= currentMaxClients && clients[client->index] == client));
+ assert (classes >= lastResourceClass);
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+ clientTable[cid].buckets)
+ {
+ res = clientTable[cid].resources[Hash(cid, id)];
+
+ for (; res; res = res->next)
+ if ((res->id == id) && (res->type & classes))
+ {
+ retval = res->value;
+ break;
+ }
+ }
+ if (retval && client && client->CheckAccess)
+ retval = (* client->CheckAccess)(client, id, res->type, mode, retval);
+ return retval;
+}
+
+/* We can't replace the LookupIDByType and LookupIDByClass functions with
+ * macros because of compatibility with loadable servers.
+ */
+
+pointer
+LookupIDByType(XID id, RESTYPE rtype)
+{
+ return SecurityLookupIDByType(NullClient, id, rtype,
+ SecurityUnknownAccess);
+}
+
+pointer
+LookupIDByClass(XID id, RESTYPE classes)
+{
+ return SecurityLookupIDByClass(NullClient, id, classes,
+ SecurityUnknownAccess);
+}
+
+#else /* not XCSECURITY */
+
+/*
+ * LookupIDByType returns the object with the given id and type, else NULL.
+ */
+pointer
+LookupIDByType(XID id, RESTYPE rtype)
+{
+ int cid;
+ register ResourcePtr res;
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+ clientTable[cid].buckets)
+ {
+ res = clientTable[cid].resources[Hash(cid, id)];
+
+ for (; res; res = res->next)
+ if ((res->id == id) && (res->type == rtype))
+ return res->value;
+ }
+ return (pointer)NULL;
+}
+
+/*
+ * LookupIDByClass returns the object with the given id and any one of the
+ * given classes, else NULL.
+ */
+pointer
+LookupIDByClass(XID id, RESTYPE classes)
+{
+ int cid;
+ register ResourcePtr res;
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+ clientTable[cid].buckets)
+ {
+ res = clientTable[cid].resources[Hash(cid, id)];
+
+ for (; res; res = res->next)
+ if ((res->id == id) && (res->type & classes))
+ return res->value;
+ }
+ return (pointer)NULL;
+}
+
+#endif /* XCSECURITY */
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.X.original
new file mode 100644
index 000000000..e12bc7b67
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.X.original
@@ -0,0 +1,954 @@
+/************************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+********************************************************/
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+/* $Xorg: resource.c,v 1.5 2001/02/09 02:04:40 xorgcvs Exp $ */
+/* $XdotOrg: xc/programs/Xserver/dix/resource.c,v 1.8 2005/07/03 08:53:38 daniels Exp $ */
+/* $TOG: resource.c /main/41 1998/02/09 14:20:31 kaleb $ */
+
+/* Routines to manage various kinds of resources:
+ *
+ * CreateNewResourceType, CreateNewResourceClass, InitClientResources,
+ * FakeClientID, AddResource, FreeResource, FreeClientResources,
+ * FreeAllResources, LookupIDByType, LookupIDByClass, GetXIDRange
+ */
+
+/*
+ * A resource ID is a 32 bit quantity, the upper 2 bits of which are
+ * off-limits for client-visible resources. The next 8 bits are
+ * used as client ID, and the low 22 bits come from the client.
+ * A resource ID is "hashed" by extracting and xoring subfields
+ * (varying with the size of the hash table).
+ *
+ * It is sometimes necessary for the server to create an ID that looks
+ * like it belongs to a client. This ID, however, must not be one
+ * the client actually can create, or we have the potential for conflict.
+ * The 31st bit of the ID is reserved for the server's use for this
+ * purpose. By setting CLIENT_ID(id) to the client, the SERVER_BIT to
+ * 1, and an otherwise arbitrary ID in the low 22 bits, we can create a
+ * resource "owned" by the client.
+ */
+/* $XFree86: xc/programs/Xserver/dix/resource.c,v 3.13 2003/09/24 02:43:13 dawes Exp $ */
+
+#define NEED_EVENTS
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "misc.h"
+#include "os.h"
+#include "resource.h"
+#include "dixstruct.h"
+#include "opaque.h"
+#include "windowstr.h"
+#include "dixfont.h"
+#include "colormap.h"
+#include "inputstr.h"
+#include "dixevents.h"
+#include "dixgrabs.h"
+#include "cursor.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#include <assert.h>
+
+static void RebuildTable(
+ int /*client*/
+);
+
+#define SERVER_MINID 32
+
+#define INITBUCKETS 64
+#define INITHASHSIZE 6
+#define MAXHASHSIZE 11
+
+typedef struct _Resource {
+ struct _Resource *next;
+ XID id;
+ RESTYPE type;
+ pointer value;
+} ResourceRec, *ResourcePtr;
+#define NullResource ((ResourcePtr)NULL)
+
+typedef struct _ClientResource {
+ ResourcePtr *resources;
+ int elements;
+ int buckets;
+ int hashsize; /* log(2)(buckets) */
+ XID fakeID;
+ XID endFakeID;
+ XID expectID;
+} ClientResourceRec;
+
+RESTYPE lastResourceType;
+static RESTYPE lastResourceClass;
+RESTYPE TypeMask;
+
+static DeleteType *DeleteFuncs = (DeleteType *)NULL;
+
+#ifdef XResExtension
+
+Atom * ResourceNames = NULL;
+
+void RegisterResourceName (RESTYPE type, char *name)
+{
+ ResourceNames[type & TypeMask] = MakeAtom(name, strlen(name), TRUE);
+}
+
+#endif
+
+RESTYPE
+CreateNewResourceType(DeleteType deleteFunc)
+{
+ RESTYPE next = lastResourceType + 1;
+ DeleteType *funcs;
+
+ if (next & lastResourceClass)
+ return 0;
+ funcs = (DeleteType *)xrealloc(DeleteFuncs,
+ (next + 1) * sizeof(DeleteType));
+ if (!funcs)
+ return 0;
+
+#ifdef XResExtension
+ {
+ Atom *newnames;
+ newnames = xrealloc(ResourceNames, (next + 1) * sizeof(Atom));
+ if(!newnames)
+ return 0;
+ ResourceNames = newnames;
+ ResourceNames[next] = 0;
+ }
+#endif
+
+ lastResourceType = next;
+ DeleteFuncs = funcs;
+ DeleteFuncs[next] = deleteFunc;
+ return next;
+}
+
+RESTYPE
+CreateNewResourceClass()
+{
+ RESTYPE next = lastResourceClass >> 1;
+
+ if (next & lastResourceType)
+ return 0;
+ lastResourceClass = next;
+ TypeMask = next - 1;
+ return next;
+}
+
+ClientResourceRec clientTable[MAXCLIENTS];
+
+/*****************
+ * InitClientResources
+ * When a new client is created, call this to allocate space
+ * in resource table
+ *****************/
+
+Bool
+InitClientResources(ClientPtr client)
+{
+ register int i, j;
+
+ if (client == serverClient)
+ {
+ lastResourceType = RT_LASTPREDEF;
+ lastResourceClass = RC_LASTPREDEF;
+ TypeMask = RC_LASTPREDEF - 1;
+ if (DeleteFuncs)
+ xfree(DeleteFuncs);
+ DeleteFuncs = (DeleteType *)xalloc((lastResourceType + 1) *
+ sizeof(DeleteType));
+ if (!DeleteFuncs)
+ return FALSE;
+ DeleteFuncs[RT_NONE & TypeMask] = (DeleteType)NoopDDA;
+ DeleteFuncs[RT_WINDOW & TypeMask] = DeleteWindow;
+ DeleteFuncs[RT_PIXMAP & TypeMask] = dixDestroyPixmap;
+ DeleteFuncs[RT_GC & TypeMask] = FreeGC;
+ DeleteFuncs[RT_FONT & TypeMask] = CloseFont;
+ DeleteFuncs[RT_CURSOR & TypeMask] = FreeCursor;
+ DeleteFuncs[RT_COLORMAP & TypeMask] = FreeColormap;
+ DeleteFuncs[RT_CMAPENTRY & TypeMask] = FreeClientPixels;
+ DeleteFuncs[RT_OTHERCLIENT & TypeMask] = OtherClientGone;
+ DeleteFuncs[RT_PASSIVEGRAB & TypeMask] = DeletePassiveGrab;
+
+#ifdef XResExtension
+ if(ResourceNames)
+ xfree(ResourceNames);
+ ResourceNames = xalloc((lastResourceType + 1) * sizeof(Atom));
+ if(!ResourceNames)
+ return FALSE;
+#endif
+ }
+ clientTable[i = client->index].resources =
+ (ResourcePtr *)xalloc(INITBUCKETS*sizeof(ResourcePtr));
+ if (!clientTable[i].resources)
+ return FALSE;
+ clientTable[i].buckets = INITBUCKETS;
+ clientTable[i].elements = 0;
+ clientTable[i].hashsize = INITHASHSIZE;
+ /* Many IDs allocated from the server client are visible to clients,
+ * so we don't use the SERVER_BIT for them, but we have to start
+ * past the magic value constants used in the protocol. For normal
+ * clients, we can start from zero, with SERVER_BIT set.
+ */
+ clientTable[i].fakeID = client->clientAsMask |
+ (client->index ? SERVER_BIT : SERVER_MINID);
+ clientTable[i].endFakeID = (clientTable[i].fakeID | RESOURCE_ID_MASK) + 1;
+ clientTable[i].expectID = client->clientAsMask;
+ for (j=0; j<INITBUCKETS; j++)
+ {
+ clientTable[i].resources[j] = NullResource;
+ }
+ return TRUE;
+}
+
+
+static int
+Hash(int client, register XID id)
+{
+ id &= RESOURCE_ID_MASK;
+ switch (clientTable[client].hashsize)
+ {
+ case 6:
+ return ((int)(0x03F & (id ^ (id>>6) ^ (id>>12))));
+ case 7:
+ return ((int)(0x07F & (id ^ (id>>7) ^ (id>>13))));
+ case 8:
+ return ((int)(0x0FF & (id ^ (id>>8) ^ (id>>16))));
+ case 9:
+ return ((int)(0x1FF & (id ^ (id>>9))));
+ case 10:
+ return ((int)(0x3FF & (id ^ (id>>10))));
+ case 11:
+ return ((int)(0x7FF & (id ^ (id>>11))));
+ }
+ return -1;
+}
+
+static XID
+AvailableID(
+ register int client,
+ register XID id,
+ register XID maxid,
+ register XID goodid)
+{
+ register ResourcePtr res;
+
+ if ((goodid >= id) && (goodid <= maxid))
+ return goodid;
+ for (; id <= maxid; id++)
+ {
+ res = clientTable[client].resources[Hash(client, id)];
+ while (res && (res->id != id))
+ res = res->next;
+ if (!res)
+ return id;
+ }
+ return 0;
+}
+
+void
+GetXIDRange(int client, Bool server, XID *minp, XID *maxp)
+{
+ register XID id, maxid;
+ register ResourcePtr *resp;
+ register ResourcePtr res;
+ register int i;
+ XID goodid;
+
+ id = (Mask)client << CLIENTOFFSET;
+ if (server)
+ id |= client ? SERVER_BIT : SERVER_MINID;
+ maxid = id | RESOURCE_ID_MASK;
+ goodid = 0;
+ for (resp = clientTable[client].resources, i = clientTable[client].buckets;
+ --i >= 0;)
+ {
+ for (res = *resp++; res; res = res->next)
+ {
+ if ((res->id < id) || (res->id > maxid))
+ continue;
+ if (((res->id - id) >= (maxid - res->id)) ?
+ (goodid = AvailableID(client, id, res->id - 1, goodid)) :
+ !(goodid = AvailableID(client, res->id + 1, maxid, goodid)))
+ maxid = res->id - 1;
+ else
+ id = res->id + 1;
+ }
+ }
+ if (id > maxid)
+ id = maxid = 0;
+ *minp = id;
+ *maxp = maxid;
+}
+
+/**
+ * GetXIDList is called by the XC-MISC extension's MiscGetXIDList function.
+ * This function tries to find count unused XIDs for the given client. It
+ * puts the IDs in the array pids and returns the number found, which should
+ * almost always be the number requested.
+ *
+ * The circumstances that lead to a call to this function are very rare.
+ * Xlib must run out of IDs while trying to generate a request that wants
+ * multiple ID's, like the Multi-buffering CreateImageBuffers request.
+ *
+ * No rocket science in the implementation; just iterate over all
+ * possible IDs for the given client and pick the first count IDs
+ * that aren't in use. A more efficient algorithm could probably be
+ * invented, but this will be used so rarely that this should suffice.
+ */
+
+unsigned int
+GetXIDList(ClientPtr pClient, unsigned count, XID *pids)
+{
+ unsigned int found = 0;
+ XID id = pClient->clientAsMask;
+ XID maxid;
+
+ maxid = id | RESOURCE_ID_MASK;
+ while ( (found < count) && (id <= maxid) )
+ {
+ if (!LookupIDByClass(id, RC_ANY))
+ {
+ pids[found++] = id;
+ }
+ id++;
+ }
+ return found;
+}
+
+/*
+ * Return the next usable fake client ID.
+ *
+ * Normally this is just the next one in line, but if we've used the last
+ * in the range, we need to find a new range of safe IDs to avoid
+ * over-running another client.
+ */
+
+XID
+FakeClientID(register int client)
+{
+ XID id, maxid;
+
+ id = clientTable[client].fakeID++;
+ if (id != clientTable[client].endFakeID)
+ return id;
+ GetXIDRange(client, TRUE, &id, &maxid);
+ if (!id) {
+ if (!client)
+ FatalError("FakeClientID: server internal ids exhausted\n");
+ MarkClientException(clients[client]);
+ id = ((Mask)client << CLIENTOFFSET) | (SERVER_BIT * 3);
+ maxid = id | RESOURCE_ID_MASK;
+ }
+ clientTable[client].fakeID = id + 1;
+ clientTable[client].endFakeID = maxid + 1;
+ return id;
+}
+
+Bool
+AddResource(XID id, RESTYPE type, pointer value)
+{
+ int client;
+ register ClientResourceRec *rrec;
+ register ResourcePtr res, *head;
+
+ client = CLIENT_ID(id);
+ rrec = &clientTable[client];
+ if (!rrec->buckets)
+ {
+ ErrorF("AddResource(%lx, %lx, %lx), client=%d \n",
+ (unsigned long)id, type, (unsigned long)value, client);
+ FatalError("client not in use\n");
+ }
+ if ((rrec->elements >= 4*rrec->buckets) &&
+ (rrec->hashsize < MAXHASHSIZE))
+ RebuildTable(client);
+ head = &rrec->resources[Hash(client, id)];
+ res = (ResourcePtr)xalloc(sizeof(ResourceRec));
+ if (!res)
+ {
+ (*DeleteFuncs[type & TypeMask])(value, id);
+ return FALSE;
+ }
+ res->next = *head;
+ res->id = id;
+ res->type = type;
+ res->value = value;
+ *head = res;
+ rrec->elements++;
+ if (!(id & SERVER_BIT) && (id >= rrec->expectID))
+ rrec->expectID = id + 1;
+ return TRUE;
+}
+
+static void
+RebuildTable(int client)
+{
+ register int j;
+ register ResourcePtr res, next;
+ ResourcePtr **tails, *resources;
+ register ResourcePtr **tptr, *rptr;
+
+ /*
+ * For now, preserve insertion order, since some ddx layers depend
+ * on resources being free in the opposite order they are added.
+ */
+
+ j = 2 * clientTable[client].buckets;
+ tails = (ResourcePtr **)ALLOCATE_LOCAL(j * sizeof(ResourcePtr *));
+ if (!tails)
+ return;
+ resources = (ResourcePtr *)xalloc(j * sizeof(ResourcePtr));
+ if (!resources)
+ {
+ DEALLOCATE_LOCAL(tails);
+ return;
+ }
+ for (rptr = resources, tptr = tails; --j >= 0; rptr++, tptr++)
+ {
+ *rptr = NullResource;
+ *tptr = rptr;
+ }
+ clientTable[client].hashsize++;
+ for (j = clientTable[client].buckets,
+ rptr = clientTable[client].resources;
+ --j >= 0;
+ rptr++)
+ {
+ for (res = *rptr; res; res = next)
+ {
+ next = res->next;
+ res->next = NullResource;
+ tptr = &tails[Hash(client, res->id)];
+ **tptr = res;
+ *tptr = &res->next;
+ }
+ }
+ DEALLOCATE_LOCAL(tails);
+ clientTable[client].buckets *= 2;
+ xfree(clientTable[client].resources);
+ clientTable[client].resources = resources;
+}
+
+void
+FreeResource(XID id, RESTYPE skipDeleteFuncType)
+{
+ int cid;
+ register ResourcePtr res;
+ register ResourcePtr *prev, *head;
+ register int *eltptr;
+ int elements;
+ Bool gotOne = FALSE;
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+ {
+ head = &clientTable[cid].resources[Hash(cid, id)];
+ eltptr = &clientTable[cid].elements;
+
+ prev = head;
+ while ( (res = *prev) )
+ {
+ if (res->id == id)
+ {
+ RESTYPE rtype = res->type;
+ *prev = res->next;
+ elements = --*eltptr;
+ if (rtype & RC_CACHED)
+ FlushClientCaches(res->id);
+ if (rtype != skipDeleteFuncType)
+ (*DeleteFuncs[rtype & TypeMask])(res->value, res->id);
+ xfree(res);
+ if (*eltptr != elements)
+ prev = head; /* prev may no longer be valid */
+ gotOne = TRUE;
+ }
+ else
+ prev = &res->next;
+ }
+ if(clients[cid] && (id == clients[cid]->lastDrawableID))
+ {
+ clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
+ clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
+ }
+ }
+ if (!gotOne)
+ ErrorF("Freeing resource id=%lX which isn't there.\n",
+ (unsigned long)id);
+}
+
+
+void
+FreeResourceByType(XID id, RESTYPE type, Bool skipFree)
+{
+ int cid;
+ register ResourcePtr res;
+ register ResourcePtr *prev, *head;
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+ {
+ head = &clientTable[cid].resources[Hash(cid, id)];
+
+ prev = head;
+ while ( (res = *prev) )
+ {
+ if (res->id == id && res->type == type)
+ {
+ *prev = res->next;
+ if (type & RC_CACHED)
+ FlushClientCaches(res->id);
+ if (!skipFree)
+ (*DeleteFuncs[type & TypeMask])(res->value, res->id);
+ xfree(res);
+ break;
+ }
+ else
+ prev = &res->next;
+ }
+ if(clients[cid] && (id == clients[cid]->lastDrawableID))
+ {
+ clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
+ clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
+ }
+ }
+}
+
+/*
+ * Change the value associated with a resource id. Caller
+ * is responsible for "doing the right thing" with the old
+ * data
+ */
+
+Bool
+ChangeResourceValue (XID id, RESTYPE rtype, pointer value)
+{
+ int cid;
+ register ResourcePtr res;
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+ {
+ res = clientTable[cid].resources[Hash(cid, id)];
+
+ for (; res; res = res->next)
+ if ((res->id == id) && (res->type == rtype))
+ {
+ if (rtype & RC_CACHED)
+ FlushClientCaches(res->id);
+ res->value = value;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/* Note: if func adds or deletes resources, then func can get called
+ * more than once for some resources. If func adds new resources,
+ * func might or might not get called for them. func cannot both
+ * add and delete an equal number of resources!
+ */
+
+void
+FindClientResourcesByType(
+ ClientPtr client,
+ RESTYPE type,
+ FindResType func,
+ pointer cdata
+){
+ register ResourcePtr *resources;
+ register ResourcePtr this, next;
+ int i, elements;
+ register int *eltptr;
+
+ if (!client)
+ client = serverClient;
+
+ resources = clientTable[client->index].resources;
+ eltptr = &clientTable[client->index].elements;
+ for (i = 0; i < clientTable[client->index].buckets; i++)
+ {
+ for (this = resources[i]; this; this = next)
+ {
+ next = this->next;
+ if (!type || this->type == type) {
+ elements = *eltptr;
+ (*func)(this->value, this->id, cdata);
+ if (*eltptr != elements)
+ next = resources[i]; /* start over */
+ }
+ }
+ }
+}
+
+void
+FindAllClientResources(
+ ClientPtr client,
+ FindAllRes func,
+ pointer cdata
+){
+ register ResourcePtr *resources;
+ register ResourcePtr this, next;
+ int i, elements;
+ register int *eltptr;
+
+ if (!client)
+ client = serverClient;
+
+ resources = clientTable[client->index].resources;
+ eltptr = &clientTable[client->index].elements;
+ for (i = 0; i < clientTable[client->index].buckets; i++)
+ {
+ for (this = resources[i]; this; this = next)
+ {
+ next = this->next;
+ elements = *eltptr;
+ (*func)(this->value, this->id, this->type, cdata);
+ if (*eltptr != elements)
+ next = resources[i]; /* start over */
+ }
+ }
+}
+
+
+pointer
+LookupClientResourceComplex(
+ ClientPtr client,
+ RESTYPE type,
+ FindComplexResType func,
+ pointer cdata
+){
+ ResourcePtr *resources;
+ ResourcePtr this;
+ int i;
+
+ if (!client)
+ client = serverClient;
+
+ resources = clientTable[client->index].resources;
+ for (i = 0; i < clientTable[client->index].buckets; i++) {
+ for (this = resources[i]; this; this = this->next) {
+ if (!type || this->type == type) {
+ if((*func)(this->value, this->id, cdata))
+ return this->value;
+ }
+ }
+ }
+ return NULL;
+}
+
+
+void
+FreeClientNeverRetainResources(ClientPtr client)
+{
+ ResourcePtr *resources;
+ ResourcePtr this;
+ ResourcePtr *prev;
+ int j;
+
+ if (!client)
+ return;
+
+ resources = clientTable[client->index].resources;
+ for (j=0; j < clientTable[client->index].buckets; j++)
+ {
+ prev = &resources[j];
+ while ( (this = *prev) )
+ {
+ RESTYPE rtype = this->type;
+ if (rtype & RC_NEVERRETAIN)
+ {
+ *prev = this->next;
+ if (rtype & RC_CACHED)
+ FlushClientCaches(this->id);
+ (*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
+ xfree(this);
+ }
+ else
+ prev = &this->next;
+ }
+ }
+}
+
+void
+FreeClientResources(ClientPtr client)
+{
+ register ResourcePtr *resources;
+ register ResourcePtr this;
+ int j;
+
+ /* This routine shouldn't be called with a null client, but just in
+ case ... */
+
+ if (!client)
+ return;
+
+ HandleSaveSet(client);
+
+ resources = clientTable[client->index].resources;
+ for (j=0; j < clientTable[client->index].buckets; j++)
+ {
+ /* It may seem silly to update the head of this resource list as
+ we delete the members, since the entire list will be deleted any way,
+ but there are some resource deletion functions "FreeClientPixels" for
+ one which do a LookupID on another resource id (a Colormap id in this
+ case), so the resource list must be kept valid up to the point that
+ it is deleted, so every time we delete a resource, we must update the
+ head, just like in FreeResource. I hope that this doesn't slow down
+ mass deletion appreciably. PRH */
+
+ ResourcePtr *head;
+
+ head = &resources[j];
+
+ for (this = *head; this; this = *head)
+ {
+ RESTYPE rtype = this->type;
+ *head = this->next;
+ if (rtype & RC_CACHED)
+ FlushClientCaches(this->id);
+ (*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
+ xfree(this);
+ }
+ }
+ xfree(clientTable[client->index].resources);
+ clientTable[client->index].resources = NULL;
+ clientTable[client->index].buckets = 0;
+}
+
+void
+FreeAllResources()
+{
+ int i;
+
+ for (i = currentMaxClients; --i >= 0; )
+ {
+ if (clientTable[i].buckets)
+ FreeClientResources(clients[i]);
+ }
+}
+
+Bool
+LegalNewID(XID id, register ClientPtr client)
+{
+
+#ifdef PANORAMIX
+ XID minid, maxid;
+
+ if (!noPanoramiXExtension) {
+ minid = client->clientAsMask | (client->index ?
+ SERVER_BIT : SERVER_MINID);
+ maxid = (clientTable[client->index].fakeID | RESOURCE_ID_MASK) + 1;
+ if ((id >= minid) && (id <= maxid))
+ return TRUE;
+ }
+#endif /* PANORAMIX */
+ return ((client->clientAsMask == (id & ~RESOURCE_ID_MASK)) &&
+ ((clientTable[client->index].expectID <= id) ||
+ !LookupIDByClass(id, RC_ANY)));
+}
+
+#ifdef XCSECURITY
+
+/* SecurityLookupIDByType and SecurityLookupIDByClass:
+ * These are the heart of the resource ID security system. They take
+ * two additional arguments compared to the old LookupID functions:
+ * the client doing the lookup, and the access mode (see resource.h).
+ * The resource is returned if it exists and the client is allowed access,
+ * else NULL is returned.
+ */
+
+pointer
+SecurityLookupIDByType(ClientPtr client, XID id, RESTYPE rtype, Mask mode)
+{
+ int cid;
+ register ResourcePtr res;
+ pointer retval = NULL;
+
+ assert(client == NullClient ||
+ (client->index <= currentMaxClients && clients[client->index] == client));
+ assert( (rtype & TypeMask) <= lastResourceType);
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+ clientTable[cid].buckets)
+ {
+ res = clientTable[cid].resources[Hash(cid, id)];
+
+ for (; res; res = res->next)
+ if ((res->id == id) && (res->type == rtype))
+ {
+ retval = res->value;
+ break;
+ }
+ }
+ if (retval && client && client->CheckAccess)
+ retval = (* client->CheckAccess)(client, id, rtype, mode, retval);
+ return retval;
+}
+
+
+pointer
+SecurityLookupIDByClass(ClientPtr client, XID id, RESTYPE classes, Mask mode)
+{
+ int cid;
+ register ResourcePtr res = NULL;
+ pointer retval = NULL;
+
+ assert(client == NullClient ||
+ (client->index <= currentMaxClients && clients[client->index] == client));
+ assert (classes >= lastResourceClass);
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+ clientTable[cid].buckets)
+ {
+ res = clientTable[cid].resources[Hash(cid, id)];
+
+ for (; res; res = res->next)
+ if ((res->id == id) && (res->type & classes))
+ {
+ retval = res->value;
+ break;
+ }
+ }
+ if (retval && client && client->CheckAccess)
+ retval = (* client->CheckAccess)(client, id, res->type, mode, retval);
+ return retval;
+}
+
+/* We can't replace the LookupIDByType and LookupIDByClass functions with
+ * macros because of compatibility with loadable servers.
+ */
+
+pointer
+LookupIDByType(XID id, RESTYPE rtype)
+{
+ return SecurityLookupIDByType(NullClient, id, rtype,
+ SecurityUnknownAccess);
+}
+
+pointer
+LookupIDByClass(XID id, RESTYPE classes)
+{
+ return SecurityLookupIDByClass(NullClient, id, classes,
+ SecurityUnknownAccess);
+}
+
+#else /* not XCSECURITY */
+
+/*
+ * LookupIDByType returns the object with the given id and type, else NULL.
+ */
+pointer
+LookupIDByType(XID id, RESTYPE rtype)
+{
+ int cid;
+ register ResourcePtr res;
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+ clientTable[cid].buckets)
+ {
+ res = clientTable[cid].resources[Hash(cid, id)];
+
+ for (; res; res = res->next)
+ if ((res->id == id) && (res->type == rtype))
+ return res->value;
+ }
+ return (pointer)NULL;
+}
+
+/*
+ * LookupIDByClass returns the object with the given id and any one of the
+ * given classes, else NULL.
+ */
+pointer
+LookupIDByClass(XID id, RESTYPE classes)
+{
+ int cid;
+ register ResourcePtr res;
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+ clientTable[cid].buckets)
+ {
+ res = clientTable[cid].resources[Hash(cid, id)];
+
+ for (; res; res = res->next)
+ if ((res->id == id) && (res->type & classes))
+ return res->value;
+ }
+ return (pointer)NULL;
+}
+
+#endif /* XCSECURITY */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
new file mode 100644
index 000000000..3aecaf229
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
@@ -0,0 +1,1455 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/Xext/shm.c,v 3.41 2003/12/17 23:28:56 alanh Exp $ */
+/************************************************************
+
+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 */
+
+/* $Xorg: shm.c,v 1.4 2001/02/09 02:04:33 xorgcvs Exp $ */
+
+#define SHM
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <sys/types.h>
+#ifndef Lynx
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#else
+#include <ipc.h>
+#include <shm.h>
+#endif
+#include <unistd.h>
+#include <sys/stat.h>
+#define NEED_REPLIES
+#define NEED_EVENTS
+#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"
+#define _XSHM_SERVER_
+#include <X11/extensions/shmstr.h>
+#include <X11/Xfuncproto.h>
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#endif
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+#include "modinit.h"
+
+#include "Trap.h"
+#include "Agent.h"
+#include "Drawable.h"
+#include "Pixmaps.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+#ifdef TEST
+#include "Literals.h"
+#endif
+
+extern void fbGetImage(DrawablePtr pDrw, int x, int y, int w, int h,
+ unsigned int format, unsigned long planeMask, char *d);
+
+extern void fbPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
+ int x, int y, int w, int h, int leftPad, int format,
+ char *pImage);
+
+typedef struct _ShmDesc {
+ struct _ShmDesc *next;
+ int shmid;
+ int refcnt;
+ char *addr;
+ Bool writable;
+ unsigned long size;
+} ShmDescRec, *ShmDescPtr;
+
+static void miShmPutImage(XSHM_PUT_IMAGE_ARGS);
+static void fbShmPutImage(XSHM_PUT_IMAGE_ARGS);
+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 DISPATCH_PROC(ProcShmAttach);
+static DISPATCH_PROC(ProcShmCreatePixmap);
+static DISPATCH_PROC(ProcShmDetach);
+static DISPATCH_PROC(ProcShmDispatch);
+static DISPATCH_PROC(ProcShmGetImage);
+static DISPATCH_PROC(ProcShmPutImage);
+static DISPATCH_PROC(ProcShmQueryVersion);
+static DISPATCH_PROC(SProcShmAttach);
+static DISPATCH_PROC(SProcShmCreatePixmap);
+static DISPATCH_PROC(SProcShmDetach);
+static DISPATCH_PROC(SProcShmDispatch);
+static DISPATCH_PROC(SProcShmGetImage);
+static DISPATCH_PROC(SProcShmPutImage);
+static DISPATCH_PROC(SProcShmQueryVersion);
+
+static unsigned char ShmReqCode;
+int ShmCompletionCode;
+int BadShmSegCode;
+RESTYPE ShmSegType;
+static ShmDescPtr Shmsegs;
+static Bool sharedPixmaps;
+static int pixmapFormat;
+static int shmPixFormat[MAXSCREENS];
+static ShmFuncsPtr shmFuncs[MAXSCREENS];
+static DestroyPixmapProcPtr destroyPixmap[MAXSCREENS];
+#ifdef PIXPRIV
+static int shmPixmapPrivate;
+#endif
+static ShmFuncs miFuncs = {NULL, miShmPutImage};
+static ShmFuncs fbFuncs = {fbShmCreatePixmap, fbShmPutImage};
+
+#define VERIFY_SHMSEG(shmseg,shmdesc,client) \
+{ \
+ shmdesc = (ShmDescPtr)LookupIDByType(shmseg, ShmSegType); \
+ if (!shmdesc) \
+ { \
+ client->errorValue = shmseg; \
+ return BadShmSegCode; \
+ } \
+}
+
+#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__)
+#include <sys/signal.h>
+
+static Bool badSysCall = FALSE;
+
+static void
+SigSysHandler(signo)
+int signo;
+{
+ badSysCall = TRUE;
+}
+
+static Bool CheckForShmSyscall()
+{
+ 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, (struct shmid_ds *)NULL);
+ }
+ else
+ {
+ /* Allocation failed */
+ badSysCall = TRUE;
+ }
+ signal(SIGSYS, oldHandler);
+ return(!badSysCall);
+}
+
+#define MUST_CHECK_FOR_SHM_SYSCALL
+
+#endif
+
+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 (nxagentOption(SharedMemory) == False)
+ {
+ return;
+ }
+
+ sharedPixmaps = xFalse;
+ pixmapFormat = 0;
+ {
+ sharedPixmaps = nxagentOption(SharedPixmaps);
+ pixmapFormat = shmPixFormat[0];
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ if (!shmFuncs[i])
+ {
+ #ifdef TEST
+ fprintf(stderr, "ShmExtensionInit: Registering shmFuncs as miFuncs.\n");
+ #endif
+ shmFuncs[i] = &miFuncs;
+ }
+ if (!shmFuncs[i]->CreatePixmap)
+ sharedPixmaps = xFalse;
+ if (shmPixFormat[i] && (shmPixFormat[i] != pixmapFormat))
+ {
+ sharedPixmaps = xFalse;
+ pixmapFormat = 0;
+ }
+ }
+ if (!pixmapFormat)
+ pixmapFormat = ZPixmap;
+ if (sharedPixmaps)
+ {
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ destroyPixmap[i] = screenInfo.screens[i]->DestroyPixmap;
+ screenInfo.screens[i]->DestroyPixmap = ShmDestroyPixmap;
+ }
+#ifdef PIXPRIV
+ shmPixmapPrivate = AllocatePixmapPrivateIndex();
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ if (!AllocatePixmapPrivate(screenInfo.screens[i],
+ shmPixmapPrivate, 0))
+ return;
+ }
+#endif
+ }
+ }
+ ShmSegType = CreateNewResourceType(ShmDetachSegment);
+ if (ShmSegType &&
+ (extEntry = AddExtension(SHMNAME, ShmNumberEvents, ShmNumberErrors,
+ ProcShmDispatch, SProcShmDispatch,
+ ShmResetProc, StandardMinorOpcode)))
+ {
+ ShmReqCode = (unsigned char)extEntry->base;
+ ShmCompletionCode = extEntry->eventBase;
+ BadShmSegCode = extEntry->errorBase;
+ EventSwapVector[ShmCompletionCode] = (EventSwapPtr) SShmCompletionEvent;
+ }
+}
+
+/*ARGSUSED*/
+static void
+ShmResetProc (extEntry)
+ExtensionEntry *extEntry;
+{
+ int i;
+
+ for (i = 0; i < MAXSCREENS; i++)
+ {
+ shmFuncs[i] = (ShmFuncsPtr)NULL;
+ shmPixFormat[i] = 0;
+ }
+}
+
+void
+ShmRegisterFuncs(
+ ScreenPtr pScreen,
+ ShmFuncsPtr funcs)
+{
+ shmFuncs[pScreen->myNum] = funcs;
+}
+
+void
+ShmSetPixmapFormat(
+ ScreenPtr pScreen,
+ int format)
+{
+ shmPixFormat[pScreen->myNum] = format;
+}
+
+static Bool
+ShmDestroyPixmap (PixmapPtr pPixmap)
+{
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ Bool ret;
+ if (pPixmap->refcnt == 1)
+ {
+ ShmDescPtr shmdesc;
+#ifdef PIXPRIV
+ shmdesc = (ShmDescPtr) pPixmap->devPrivates[shmPixmapPrivate].ptr;
+#else
+ char *base = (char *) pPixmap->devPrivate.ptr;
+
+ if (base != (pointer) (pPixmap + 1))
+ {
+ for (shmdesc = Shmsegs; shmdesc; shmdesc = shmdesc->next)
+ {
+ if (shmdesc->addr <= base && base <= shmdesc->addr + shmdesc->size)
+ break;
+ }
+ }
+ else
+ shmdesc = 0;
+#endif
+ if (shmdesc)
+ ShmDetachSegment ((pointer) shmdesc, pPixmap->drawable.id);
+ }
+
+ pScreen->DestroyPixmap = destroyPixmap[pScreen->myNum];
+ ret = (*pScreen->DestroyPixmap) (pPixmap);
+ destroyPixmap[pScreen->myNum] = pScreen->DestroyPixmap;
+ pScreen->DestroyPixmap = ShmDestroyPixmap;
+ return ret;
+}
+
+void
+ShmRegisterFbFuncs(pScreen)
+ ScreenPtr pScreen;
+{
+ #ifdef TEST
+ fprintf(stderr, "ShmRegisterFbFuncs: Registering shmFuncs as fbFuncs.\n");
+ #endif
+ shmFuncs[pScreen->myNum] = &fbFuncs;
+}
+
+static int
+ProcShmQueryVersion(client)
+ register ClientPtr client;
+{
+ xShmQueryVersionReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xShmQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.sharedPixmaps = sharedPixmaps;
+ rep.pixmapFormat = pixmapFormat;
+ rep.majorVersion = SHM_MAJOR_VERSION;
+ rep.minorVersion = 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 (client->noClientException);
+}
+
+/*
+ * Simulate the access() system call for a shared memory segement,
+ * using the credentials from the client if available
+ */
+static int
+shm_access(ClientPtr client, struct ipc_perm *perm, int readonly)
+{
+ int uid, gid;
+ mode_t mask;
+
+ if (LocalClientCred(client, &uid, &gid) != -1) {
+
+ /* User id 0 always gets access */
+ if (uid == 0) {
+ return 0;
+ }
+ /* Check the owner */
+ if (perm->uid == uid || perm->cuid == uid) {
+ mask = S_IRUSR;
+ if (!readonly) {
+ mask |= S_IWUSR;
+ }
+ return (perm->mode & mask) == mask ? 0 : -1;
+ }
+ /* Check the group */
+ if (perm->gid == gid || perm->cgid == gid) {
+ mask = S_IRGRP;
+ if (!readonly) {
+ mask |= S_IWGRP;
+ }
+ return (perm->mode & mask) == mask ? 0 : -1;
+ }
+ }
+ /* Otherwise, check everyone else */
+ mask = S_IROTH;
+ if (!readonly) {
+ mask |= S_IWOTH;
+ }
+ return (perm->mode & mask) == mask ? 0 : -1;
+}
+
+static int
+ProcShmAttach(client)
+ register ClientPtr client;
+{
+ struct shmid_ds 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 = (ShmDescPtr) xalloc(sizeof(ShmDescRec));
+ if (!shmdesc)
+ return BadAlloc;
+ shmdesc->addr = shmat(stuff->shmid, 0,
+ stuff->readOnly ? SHM_RDONLY : 0);
+ if ((shmdesc->addr == ((char *)-1)) ||
+ shmctl(stuff->shmid, IPC_STAT, &buf))
+ {
+ xfree(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, &(buf.shm_perm), stuff->readOnly) == -1) {
+ shmdt(shmdesc->addr);
+ xfree(shmdesc);
+ return BadAccess;
+ }
+
+ shmdesc->shmid = stuff->shmid;
+ shmdesc->refcnt = 1;
+ shmdesc->writable = !stuff->readOnly;
+ shmdesc->size = buf.shm_segsz;
+ shmdesc->next = Shmsegs;
+ Shmsegs = shmdesc;
+ }
+ if (!AddResource(stuff->shmseg, ShmSegType, (pointer)shmdesc))
+ return BadAlloc;
+ return(client->noClientException);
+}
+
+/*ARGSUSED*/
+static int
+ShmDetachSegment(value, shmseg)
+ 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;
+ xfree(shmdesc);
+ return Success;
+}
+
+static int
+ProcShmDetach(client)
+ register ClientPtr client;
+{
+ ShmDescPtr shmdesc;
+ REQUEST(xShmDetachReq);
+
+ REQUEST_SIZE_MATCH(xShmDetachReq);
+ VERIFY_SHMSEG(stuff->shmseg, shmdesc, client);
+ FreeResource(stuff->shmseg, RT_NONE);
+ return(client->noClientException);
+}
+
+static void
+miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
+ DrawablePtr dst;
+ GCPtr pGC;
+ int depth, w, h, sx, sy, sw, sh, dx, dy;
+ unsigned int format;
+ char *data;
+{
+ PixmapPtr pmap;
+ GCPtr putGC;
+
+ nxagentShmTrap = 0;
+ putGC = GetScratchGC(depth, dst->pScreen);
+ if (!putGC)
+ {
+ nxagentShmTrap = 1;
+ return;
+ }
+ pmap = (*dst->pScreen->CreatePixmap)(dst->pScreen, sw, sh, depth);
+ if (!pmap)
+ {
+ nxagentShmTrap = 1;
+ FreeScratchGC(putGC);
+ return;
+ }
+ ValidateGC((DrawablePtr)pmap, putGC);
+ (*putGC->ops->PutImage)((DrawablePtr)pmap, putGC, depth, -sx, -sy, w, h, 0,
+ (format == XYPixmap) ? XYPixmap : ZPixmap, data);
+ FreeScratchGC(putGC);
+ if (format == XYBitmap)
+ (void)(*pGC->ops->CopyPlane)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
+ dx, dy, 1L);
+ else
+ (void)(*pGC->ops->CopyArea)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
+ dx, dy);
+ (*pmap->drawable.pScreen->DestroyPixmap)(pmap);
+ nxagentShmTrap = 1;
+}
+
+static void
+fbShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
+ DrawablePtr dst;
+ GCPtr pGC;
+ int depth, w, h, sx, sy, sw, sh, dx, dy;
+ unsigned int format;
+ char *data;
+{
+ int length;
+ char *newdata;
+ extern int nxagentImageLength(int, int, int, int, int);
+
+ #ifdef TEST
+ fprintf(stderr, "fbShmPutImage: Called with drawable at [%p] GC at [%p] data at [%p].\n",
+ (void *) dst, (void *) pGC, (void *) data);
+ #endif
+
+ if ((format == ZPixmap) || (depth == 1))
+ {
+ PixmapPtr pPixmap;
+
+ pPixmap = GetScratchPixmapHeader(dst->pScreen, w, h, depth,
+ BitsPerPixel(depth), PixmapBytePad(w, depth), (pointer)data);
+ if (!pPixmap)
+ return;
+ if (format == XYBitmap)
+ (void)(*pGC->ops->CopyPlane)((DrawablePtr)pPixmap, dst, pGC,
+ sx, sy, sw, sh, dx, dy, 1L);
+ else
+ (void)(*pGC->ops->CopyArea)((DrawablePtr)pPixmap, dst, pGC,
+ sx, sy, sw, sh, dx, dy);
+
+ /*
+ * We updated the internal framebuffer,
+ * now we want to go on the real X.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "fbShmPutImage: Realizing the PutImage with depth [%d] "
+ " format [%d] w [%d] h [%d] sx [%d] sy [%d] sw [%d] "
+ " sh [%d] dx [%d].\n", depth, format, w, h,
+ sx, sy, sw, sh, dx);
+ #endif
+
+ length = nxagentImageLength(sw, sh, format, 0, depth);
+
+ if ((newdata = xalloc(length)) != NULL)
+ {
+ fbGetImage((DrawablePtr) pPixmap, sx, sy, sw, sh, format, AllPlanes, newdata);
+ (*pGC->ops->PutImage)(dst, pGC, depth, dx, dy, sw, sh, 0, format, newdata);
+
+ xfree(newdata);
+ }
+ else
+ {
+ #ifdef WARNING
+ fprintf(stderr, "fbShmPutImage: WARNING! Data allocation failed.\n");
+ #endif
+ }
+
+ FreeScratchPixmapHeader(pPixmap);
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "fbShmPutImage: Calling miShmPutImage().\n");
+ #endif
+ miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy,
+ data);
+ }
+}
+
+
+#ifdef PANORAMIX
+static int
+ProcPanoramiXShmPutImage(register ClientPtr client)
+{
+ int j, result = 0, orig_x, orig_y;
+ PanoramiXRes *draw, *gc;
+ Bool sendEvent, isRoot;
+
+ REQUEST(xShmPutImageReq);
+ REQUEST_SIZE_MATCH(xShmPutImageReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+ return BadDrawable;
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, SecurityReadAccess)))
+ return BadGC;
+
+ 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 - panoramiXdataPtr[j].x;
+ stuff->dstY = orig_y - panoramiXdataPtr[j].y;
+ }
+ result = ProcShmPutImage(client);
+ if(result != client->noClientException) break;
+ }
+ return(result);
+}
+
+static int
+ProcPanoramiXShmGetImage(ClientPtr client)
+{
+ PanoramiXRes *draw;
+ DrawablePtr drawables[MAXSCREENS];
+ DrawablePtr pDraw;
+ xShmGetImageReply xgi;
+ ShmDescPtr shmdesc;
+ int i, x, y, w, h, format;
+ 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);
+ }
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+ return BadDrawable;
+
+ if (draw->type == XRT_PIXMAP)
+ return ProcShmGetImage(client);
+
+ VERIFY_DRAWABLE(pDraw, stuff->drawable, client);
+
+ 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 */
+ panoramiXdataPtr[0].x + pDraw->x + x < 0 ||
+ panoramiXdataPtr[0].x + pDraw->x + x + w > PanoramiXPixWidth ||
+ panoramiXdataPtr[0].y + pDraw->y + y < 0 ||
+ panoramiXdataPtr[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++)
+ VERIFY_DRAWABLE(drawables[i], draw->info[i].id, client);
+
+ 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;
+ }
+ }
+ }
+
+ if (client->swapped) {
+ register 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(client->noClientException);
+}
+
+static int
+ProcPanoramiXShmCreatePixmap(
+ register ClientPtr client)
+{
+ ScreenPtr pScreen = NULL;
+ PixmapPtr pMap = NULL;
+ DrawablePtr pDraw;
+ DepthPtr pDepth;
+ int i, j, result;
+ ShmDescPtr shmdesc;
+ REQUEST(xShmCreatePixmapReq);
+ PanoramiXRes *newPix;
+
+ REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+ client->errorValue = stuff->pid;
+ if (!sharedPixmaps)
+ return BadImplementation;
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+ VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
+ VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+ if (!stuff->width || !stuff->height)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ 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:
+ VERIFY_SHMSIZE(shmdesc, stuff->offset,
+ PixmapBytePad(stuff->width, stuff->depth) * stuff->height,
+ client);
+
+ if(!(newPix = (PanoramiXRes *) xalloc(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 = (client->noClientException);
+
+ FOR_NSCREENS(j) {
+ pScreen = screenInfo.screens[j];
+
+ pMap = (*shmFuncs[j]->CreatePixmap)(pScreen,
+ stuff->width, stuff->height, stuff->depth,
+ shmdesc->addr + stuff->offset);
+
+ if (pMap) {
+#ifdef PIXPRIV
+ pMap->devPrivates[shmPixmapPrivate].ptr = (pointer) shmdesc;
+#endif
+ 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);
+ }
+ xfree(newPix);
+ } else
+ AddResource(stuff->pid, XRT_PIXMAP, newPix);
+
+ return result;
+}
+
+#endif
+
+static int
+ProcShmPutImage(client)
+ register ClientPtr client;
+{
+ register GCPtr pGC;
+ register DrawablePtr pDraw;
+ long length;
+ ShmDescPtr shmdesc;
+ REQUEST(xShmPutImageReq);
+
+ REQUEST_SIZE_MATCH(xShmPutImageReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ 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;
+ }
+
+ VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
+ client);
+ 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;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "ProcShmPutImage: Format [%d] srcX [%d] srcY [%d], "
+ "totalWidth [%d] totalHeight [%d]\n", stuff->format, stuff->srcX,
+ stuff->srcY, stuff->totalWidth, stuff->totalHeight);
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "ProcShmPutImage: Calling (*shmFuncs[pDraw->pScreen->myNum]->PutImage)().\n");
+ #endif
+
+ (*shmFuncs[pDraw->pScreen->myNum]->PutImage)(
+ 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.sequenceNumber = client->sequence;
+ ev.minorEvent = X_ShmPutImage;
+ ev.majorEvent = ShmReqCode;
+ ev.shmseg = stuff->shmseg;
+ ev.offset = stuff->offset;
+ WriteEventsToClient(client, 1, (xEvent *) &ev);
+ }
+
+ return (client->noClientException);
+}
+
+
+
+static int
+ProcShmGetImage(client)
+ register ClientPtr client;
+{
+ register DrawablePtr pDraw;
+ long lenPer = 0, length;
+ Mask plane = 0;
+ xShmGetImageReply xgi;
+ ShmDescPtr shmdesc;
+ int n;
+
+ REQUEST(xShmGetImageReq);
+
+ REQUEST_SIZE_MATCH(xShmGetImageReq);
+ if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap))
+ {
+ client->errorValue = stuff->format;
+ return(BadValue);
+ }
+ VERIFY_DRAWABLE(pDraw, stuff->drawable, client);
+ 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(client->noClientException);
+}
+
+static PixmapPtr
+fbShmCreatePixmap (pScreen, width, height, depth, addr)
+ ScreenPtr pScreen;
+ int width;
+ int height;
+ int depth;
+ char *addr;
+{
+ register PixmapPtr pPixmap;
+
+ nxagentShmPixmapTrap = 1;
+
+ pPixmap = (*pScreen->CreatePixmap)(pScreen, width, height, depth);
+
+ if (!pPixmap)
+ {
+ nxagentShmPixmapTrap = 0;
+
+ return NullPixmap;
+ }
+
+ #ifdef TEST
+ fprintf(stderr,"fbShmCreatePixmap: Width [%d] Height [%d] Depth [%d]\n", width, height, depth);
+ #endif
+
+ if (!(*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth,
+ BitsPerPixel(depth), PixmapBytePad(width, depth), (pointer)addr))
+ {
+ #ifdef WARNING
+ fprintf(stderr,"fbShmCreatePixmap: Return Null Pixmap.\n");
+ #endif
+
+ (*pScreen->DestroyPixmap)(pPixmap);
+
+ nxagentShmPixmapTrap = 0;
+
+ return NullPixmap;
+ }
+
+ nxagentShmPixmapTrap = 0;
+
+ return pPixmap;
+}
+
+static int
+ProcShmCreatePixmap(client)
+ register ClientPtr client;
+{
+ PixmapPtr pMap;
+ register DrawablePtr pDraw;
+ DepthPtr pDepth;
+ register int i;
+ ShmDescPtr shmdesc;
+ REQUEST(xShmCreatePixmapReq);
+
+ REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+ client->errorValue = stuff->pid;
+ if (!sharedPixmaps)
+ return BadImplementation;
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+ VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
+ VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+ if (!stuff->width || !stuff->height)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ 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:
+ VERIFY_SHMSIZE(shmdesc, stuff->offset,
+ PixmapBytePad(stuff->width, stuff->depth) * stuff->height,
+ client);
+ pMap = (*shmFuncs[pDraw->pScreen->myNum]->CreatePixmap)(
+ pDraw->pScreen, stuff->width,
+ stuff->height, stuff->depth,
+ shmdesc->addr + stuff->offset);
+ if (pMap)
+ {
+#ifdef PIXPRIV
+ pMap->devPrivates[shmPixmapPrivate].ptr = (pointer) shmdesc;
+#endif
+ shmdesc->refcnt++;
+ pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pMap->drawable.id = stuff->pid;
+ if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
+ {
+ return(client->noClientException);
+ }
+ }
+ return (BadAlloc);
+}
+
+static int
+ProcShmDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+
+ #ifdef TEST
+ fprintf(stderr, "ProcShmDispatch: Going to execute operation [%d] for client [%d].\n",
+ stuff -> data, client -> index);
+
+ if (stuff->data <= X_ShmCreatePixmap)
+ {
+ fprintf(stderr, "ProcShmDispatch: Request [%s] OPCODE#%d.\n",
+ nxagentShmRequestLiteral[stuff->data], stuff->data);
+ }
+ #endif
+
+ switch (stuff->data)
+ {
+ case X_ShmQueryVersion:
+ return ProcShmQueryVersion(client);
+ case X_ShmAttach:
+ return ProcShmAttach(client);
+ case X_ShmDetach:
+ return ProcShmDetach(client);
+ case X_ShmPutImage:
+ {
+ int result;
+
+ #ifdef TEST
+ fprintf(stderr, "ProcShmDispatch: Going to execute ProcShmPutImage() for client [%d].\n",
+ client -> index);
+ #endif
+
+ nxagentShmTrap = 1;
+
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ {
+ result = ProcPanoramiXShmPutImage(client);
+
+ nxagentShmTrap = 0;
+
+ return result;
+ }
+#endif
+
+ result = ProcShmPutImage(client);
+
+ nxagentShmTrap = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "ProcShmDispatch: Returning from ProcShmPutImage() for client [%d].\n",
+ client -> index);
+ #endif
+
+ return result;
+ }
+ 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(from, to)
+ xShmCompletionEvent *from, *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(client)
+ register ClientPtr client;
+{
+ register int n;
+ REQUEST(xShmQueryVersionReq);
+
+ swaps(&stuff->length, n);
+ return ProcShmQueryVersion(client);
+}
+
+static int
+SProcShmAttach(client)
+ ClientPtr client;
+{
+ register 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(client)
+ ClientPtr client;
+{
+ register int n;
+ REQUEST(xShmDetachReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xShmDetachReq);
+ swapl(&stuff->shmseg, n);
+ return ProcShmDetach(client);
+}
+
+static int
+SProcShmPutImage(client)
+ ClientPtr client;
+{
+ register 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(client)
+ ClientPtr client;
+{
+ register 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(client)
+ ClientPtr client;
+{
+ register 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 (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+
+ #ifdef TEST
+ fprintf(stderr, "SProcShmDispatch: Going to execute operation [%d] for client [%d].\n",
+ stuff -> data, client -> index);
+ #endif
+
+ switch (stuff->data)
+ {
+ case X_ShmQueryVersion:
+ return SProcShmQueryVersion(client);
+ case X_ShmAttach:
+ return SProcShmAttach(client);
+ case X_ShmDetach:
+ return SProcShmDetach(client);
+ case X_ShmPutImage:
+ {
+ int result;
+
+ #ifdef TEST
+ fprintf(stderr, "SProcShmDispatch: Going to execute SProcShmPutImage() for client [%d].\n",
+ client -> index);
+ #endif
+
+ nxagentShmTrap = 1;
+
+ result = SProcShmPutImage(client);
+
+ nxagentShmTrap = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "SProcShmDispatch: Returning from SProcShmPutImage() for client [%d].\n",
+ client -> index);
+ #endif
+
+ return result;
+ }
+ case X_ShmGetImage:
+ return SProcShmGetImage(client);
+ case X_ShmCreatePixmap:
+ return SProcShmCreatePixmap(client);
+ default:
+ return BadRequest;
+ }
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
new file mode 100644
index 000000000..3aecaf229
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
@@ -0,0 +1,1455 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/Xext/shm.c,v 3.41 2003/12/17 23:28:56 alanh Exp $ */
+/************************************************************
+
+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 */
+
+/* $Xorg: shm.c,v 1.4 2001/02/09 02:04:33 xorgcvs Exp $ */
+
+#define SHM
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <sys/types.h>
+#ifndef Lynx
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#else
+#include <ipc.h>
+#include <shm.h>
+#endif
+#include <unistd.h>
+#include <sys/stat.h>
+#define NEED_REPLIES
+#define NEED_EVENTS
+#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"
+#define _XSHM_SERVER_
+#include <X11/extensions/shmstr.h>
+#include <X11/Xfuncproto.h>
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#endif
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+#include "modinit.h"
+
+#include "Trap.h"
+#include "Agent.h"
+#include "Drawable.h"
+#include "Pixmaps.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+#ifdef TEST
+#include "Literals.h"
+#endif
+
+extern void fbGetImage(DrawablePtr pDrw, int x, int y, int w, int h,
+ unsigned int format, unsigned long planeMask, char *d);
+
+extern void fbPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
+ int x, int y, int w, int h, int leftPad, int format,
+ char *pImage);
+
+typedef struct _ShmDesc {
+ struct _ShmDesc *next;
+ int shmid;
+ int refcnt;
+ char *addr;
+ Bool writable;
+ unsigned long size;
+} ShmDescRec, *ShmDescPtr;
+
+static void miShmPutImage(XSHM_PUT_IMAGE_ARGS);
+static void fbShmPutImage(XSHM_PUT_IMAGE_ARGS);
+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 DISPATCH_PROC(ProcShmAttach);
+static DISPATCH_PROC(ProcShmCreatePixmap);
+static DISPATCH_PROC(ProcShmDetach);
+static DISPATCH_PROC(ProcShmDispatch);
+static DISPATCH_PROC(ProcShmGetImage);
+static DISPATCH_PROC(ProcShmPutImage);
+static DISPATCH_PROC(ProcShmQueryVersion);
+static DISPATCH_PROC(SProcShmAttach);
+static DISPATCH_PROC(SProcShmCreatePixmap);
+static DISPATCH_PROC(SProcShmDetach);
+static DISPATCH_PROC(SProcShmDispatch);
+static DISPATCH_PROC(SProcShmGetImage);
+static DISPATCH_PROC(SProcShmPutImage);
+static DISPATCH_PROC(SProcShmQueryVersion);
+
+static unsigned char ShmReqCode;
+int ShmCompletionCode;
+int BadShmSegCode;
+RESTYPE ShmSegType;
+static ShmDescPtr Shmsegs;
+static Bool sharedPixmaps;
+static int pixmapFormat;
+static int shmPixFormat[MAXSCREENS];
+static ShmFuncsPtr shmFuncs[MAXSCREENS];
+static DestroyPixmapProcPtr destroyPixmap[MAXSCREENS];
+#ifdef PIXPRIV
+static int shmPixmapPrivate;
+#endif
+static ShmFuncs miFuncs = {NULL, miShmPutImage};
+static ShmFuncs fbFuncs = {fbShmCreatePixmap, fbShmPutImage};
+
+#define VERIFY_SHMSEG(shmseg,shmdesc,client) \
+{ \
+ shmdesc = (ShmDescPtr)LookupIDByType(shmseg, ShmSegType); \
+ if (!shmdesc) \
+ { \
+ client->errorValue = shmseg; \
+ return BadShmSegCode; \
+ } \
+}
+
+#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__)
+#include <sys/signal.h>
+
+static Bool badSysCall = FALSE;
+
+static void
+SigSysHandler(signo)
+int signo;
+{
+ badSysCall = TRUE;
+}
+
+static Bool CheckForShmSyscall()
+{
+ 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, (struct shmid_ds *)NULL);
+ }
+ else
+ {
+ /* Allocation failed */
+ badSysCall = TRUE;
+ }
+ signal(SIGSYS, oldHandler);
+ return(!badSysCall);
+}
+
+#define MUST_CHECK_FOR_SHM_SYSCALL
+
+#endif
+
+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 (nxagentOption(SharedMemory) == False)
+ {
+ return;
+ }
+
+ sharedPixmaps = xFalse;
+ pixmapFormat = 0;
+ {
+ sharedPixmaps = nxagentOption(SharedPixmaps);
+ pixmapFormat = shmPixFormat[0];
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ if (!shmFuncs[i])
+ {
+ #ifdef TEST
+ fprintf(stderr, "ShmExtensionInit: Registering shmFuncs as miFuncs.\n");
+ #endif
+ shmFuncs[i] = &miFuncs;
+ }
+ if (!shmFuncs[i]->CreatePixmap)
+ sharedPixmaps = xFalse;
+ if (shmPixFormat[i] && (shmPixFormat[i] != pixmapFormat))
+ {
+ sharedPixmaps = xFalse;
+ pixmapFormat = 0;
+ }
+ }
+ if (!pixmapFormat)
+ pixmapFormat = ZPixmap;
+ if (sharedPixmaps)
+ {
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ destroyPixmap[i] = screenInfo.screens[i]->DestroyPixmap;
+ screenInfo.screens[i]->DestroyPixmap = ShmDestroyPixmap;
+ }
+#ifdef PIXPRIV
+ shmPixmapPrivate = AllocatePixmapPrivateIndex();
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ if (!AllocatePixmapPrivate(screenInfo.screens[i],
+ shmPixmapPrivate, 0))
+ return;
+ }
+#endif
+ }
+ }
+ ShmSegType = CreateNewResourceType(ShmDetachSegment);
+ if (ShmSegType &&
+ (extEntry = AddExtension(SHMNAME, ShmNumberEvents, ShmNumberErrors,
+ ProcShmDispatch, SProcShmDispatch,
+ ShmResetProc, StandardMinorOpcode)))
+ {
+ ShmReqCode = (unsigned char)extEntry->base;
+ ShmCompletionCode = extEntry->eventBase;
+ BadShmSegCode = extEntry->errorBase;
+ EventSwapVector[ShmCompletionCode] = (EventSwapPtr) SShmCompletionEvent;
+ }
+}
+
+/*ARGSUSED*/
+static void
+ShmResetProc (extEntry)
+ExtensionEntry *extEntry;
+{
+ int i;
+
+ for (i = 0; i < MAXSCREENS; i++)
+ {
+ shmFuncs[i] = (ShmFuncsPtr)NULL;
+ shmPixFormat[i] = 0;
+ }
+}
+
+void
+ShmRegisterFuncs(
+ ScreenPtr pScreen,
+ ShmFuncsPtr funcs)
+{
+ shmFuncs[pScreen->myNum] = funcs;
+}
+
+void
+ShmSetPixmapFormat(
+ ScreenPtr pScreen,
+ int format)
+{
+ shmPixFormat[pScreen->myNum] = format;
+}
+
+static Bool
+ShmDestroyPixmap (PixmapPtr pPixmap)
+{
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ Bool ret;
+ if (pPixmap->refcnt == 1)
+ {
+ ShmDescPtr shmdesc;
+#ifdef PIXPRIV
+ shmdesc = (ShmDescPtr) pPixmap->devPrivates[shmPixmapPrivate].ptr;
+#else
+ char *base = (char *) pPixmap->devPrivate.ptr;
+
+ if (base != (pointer) (pPixmap + 1))
+ {
+ for (shmdesc = Shmsegs; shmdesc; shmdesc = shmdesc->next)
+ {
+ if (shmdesc->addr <= base && base <= shmdesc->addr + shmdesc->size)
+ break;
+ }
+ }
+ else
+ shmdesc = 0;
+#endif
+ if (shmdesc)
+ ShmDetachSegment ((pointer) shmdesc, pPixmap->drawable.id);
+ }
+
+ pScreen->DestroyPixmap = destroyPixmap[pScreen->myNum];
+ ret = (*pScreen->DestroyPixmap) (pPixmap);
+ destroyPixmap[pScreen->myNum] = pScreen->DestroyPixmap;
+ pScreen->DestroyPixmap = ShmDestroyPixmap;
+ return ret;
+}
+
+void
+ShmRegisterFbFuncs(pScreen)
+ ScreenPtr pScreen;
+{
+ #ifdef TEST
+ fprintf(stderr, "ShmRegisterFbFuncs: Registering shmFuncs as fbFuncs.\n");
+ #endif
+ shmFuncs[pScreen->myNum] = &fbFuncs;
+}
+
+static int
+ProcShmQueryVersion(client)
+ register ClientPtr client;
+{
+ xShmQueryVersionReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xShmQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.sharedPixmaps = sharedPixmaps;
+ rep.pixmapFormat = pixmapFormat;
+ rep.majorVersion = SHM_MAJOR_VERSION;
+ rep.minorVersion = 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 (client->noClientException);
+}
+
+/*
+ * Simulate the access() system call for a shared memory segement,
+ * using the credentials from the client if available
+ */
+static int
+shm_access(ClientPtr client, struct ipc_perm *perm, int readonly)
+{
+ int uid, gid;
+ mode_t mask;
+
+ if (LocalClientCred(client, &uid, &gid) != -1) {
+
+ /* User id 0 always gets access */
+ if (uid == 0) {
+ return 0;
+ }
+ /* Check the owner */
+ if (perm->uid == uid || perm->cuid == uid) {
+ mask = S_IRUSR;
+ if (!readonly) {
+ mask |= S_IWUSR;
+ }
+ return (perm->mode & mask) == mask ? 0 : -1;
+ }
+ /* Check the group */
+ if (perm->gid == gid || perm->cgid == gid) {
+ mask = S_IRGRP;
+ if (!readonly) {
+ mask |= S_IWGRP;
+ }
+ return (perm->mode & mask) == mask ? 0 : -1;
+ }
+ }
+ /* Otherwise, check everyone else */
+ mask = S_IROTH;
+ if (!readonly) {
+ mask |= S_IWOTH;
+ }
+ return (perm->mode & mask) == mask ? 0 : -1;
+}
+
+static int
+ProcShmAttach(client)
+ register ClientPtr client;
+{
+ struct shmid_ds 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 = (ShmDescPtr) xalloc(sizeof(ShmDescRec));
+ if (!shmdesc)
+ return BadAlloc;
+ shmdesc->addr = shmat(stuff->shmid, 0,
+ stuff->readOnly ? SHM_RDONLY : 0);
+ if ((shmdesc->addr == ((char *)-1)) ||
+ shmctl(stuff->shmid, IPC_STAT, &buf))
+ {
+ xfree(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, &(buf.shm_perm), stuff->readOnly) == -1) {
+ shmdt(shmdesc->addr);
+ xfree(shmdesc);
+ return BadAccess;
+ }
+
+ shmdesc->shmid = stuff->shmid;
+ shmdesc->refcnt = 1;
+ shmdesc->writable = !stuff->readOnly;
+ shmdesc->size = buf.shm_segsz;
+ shmdesc->next = Shmsegs;
+ Shmsegs = shmdesc;
+ }
+ if (!AddResource(stuff->shmseg, ShmSegType, (pointer)shmdesc))
+ return BadAlloc;
+ return(client->noClientException);
+}
+
+/*ARGSUSED*/
+static int
+ShmDetachSegment(value, shmseg)
+ 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;
+ xfree(shmdesc);
+ return Success;
+}
+
+static int
+ProcShmDetach(client)
+ register ClientPtr client;
+{
+ ShmDescPtr shmdesc;
+ REQUEST(xShmDetachReq);
+
+ REQUEST_SIZE_MATCH(xShmDetachReq);
+ VERIFY_SHMSEG(stuff->shmseg, shmdesc, client);
+ FreeResource(stuff->shmseg, RT_NONE);
+ return(client->noClientException);
+}
+
+static void
+miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
+ DrawablePtr dst;
+ GCPtr pGC;
+ int depth, w, h, sx, sy, sw, sh, dx, dy;
+ unsigned int format;
+ char *data;
+{
+ PixmapPtr pmap;
+ GCPtr putGC;
+
+ nxagentShmTrap = 0;
+ putGC = GetScratchGC(depth, dst->pScreen);
+ if (!putGC)
+ {
+ nxagentShmTrap = 1;
+ return;
+ }
+ pmap = (*dst->pScreen->CreatePixmap)(dst->pScreen, sw, sh, depth);
+ if (!pmap)
+ {
+ nxagentShmTrap = 1;
+ FreeScratchGC(putGC);
+ return;
+ }
+ ValidateGC((DrawablePtr)pmap, putGC);
+ (*putGC->ops->PutImage)((DrawablePtr)pmap, putGC, depth, -sx, -sy, w, h, 0,
+ (format == XYPixmap) ? XYPixmap : ZPixmap, data);
+ FreeScratchGC(putGC);
+ if (format == XYBitmap)
+ (void)(*pGC->ops->CopyPlane)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
+ dx, dy, 1L);
+ else
+ (void)(*pGC->ops->CopyArea)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
+ dx, dy);
+ (*pmap->drawable.pScreen->DestroyPixmap)(pmap);
+ nxagentShmTrap = 1;
+}
+
+static void
+fbShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
+ DrawablePtr dst;
+ GCPtr pGC;
+ int depth, w, h, sx, sy, sw, sh, dx, dy;
+ unsigned int format;
+ char *data;
+{
+ int length;
+ char *newdata;
+ extern int nxagentImageLength(int, int, int, int, int);
+
+ #ifdef TEST
+ fprintf(stderr, "fbShmPutImage: Called with drawable at [%p] GC at [%p] data at [%p].\n",
+ (void *) dst, (void *) pGC, (void *) data);
+ #endif
+
+ if ((format == ZPixmap) || (depth == 1))
+ {
+ PixmapPtr pPixmap;
+
+ pPixmap = GetScratchPixmapHeader(dst->pScreen, w, h, depth,
+ BitsPerPixel(depth), PixmapBytePad(w, depth), (pointer)data);
+ if (!pPixmap)
+ return;
+ if (format == XYBitmap)
+ (void)(*pGC->ops->CopyPlane)((DrawablePtr)pPixmap, dst, pGC,
+ sx, sy, sw, sh, dx, dy, 1L);
+ else
+ (void)(*pGC->ops->CopyArea)((DrawablePtr)pPixmap, dst, pGC,
+ sx, sy, sw, sh, dx, dy);
+
+ /*
+ * We updated the internal framebuffer,
+ * now we want to go on the real X.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "fbShmPutImage: Realizing the PutImage with depth [%d] "
+ " format [%d] w [%d] h [%d] sx [%d] sy [%d] sw [%d] "
+ " sh [%d] dx [%d].\n", depth, format, w, h,
+ sx, sy, sw, sh, dx);
+ #endif
+
+ length = nxagentImageLength(sw, sh, format, 0, depth);
+
+ if ((newdata = xalloc(length)) != NULL)
+ {
+ fbGetImage((DrawablePtr) pPixmap, sx, sy, sw, sh, format, AllPlanes, newdata);
+ (*pGC->ops->PutImage)(dst, pGC, depth, dx, dy, sw, sh, 0, format, newdata);
+
+ xfree(newdata);
+ }
+ else
+ {
+ #ifdef WARNING
+ fprintf(stderr, "fbShmPutImage: WARNING! Data allocation failed.\n");
+ #endif
+ }
+
+ FreeScratchPixmapHeader(pPixmap);
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "fbShmPutImage: Calling miShmPutImage().\n");
+ #endif
+ miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy,
+ data);
+ }
+}
+
+
+#ifdef PANORAMIX
+static int
+ProcPanoramiXShmPutImage(register ClientPtr client)
+{
+ int j, result = 0, orig_x, orig_y;
+ PanoramiXRes *draw, *gc;
+ Bool sendEvent, isRoot;
+
+ REQUEST(xShmPutImageReq);
+ REQUEST_SIZE_MATCH(xShmPutImageReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+ return BadDrawable;
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, SecurityReadAccess)))
+ return BadGC;
+
+ 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 - panoramiXdataPtr[j].x;
+ stuff->dstY = orig_y - panoramiXdataPtr[j].y;
+ }
+ result = ProcShmPutImage(client);
+ if(result != client->noClientException) break;
+ }
+ return(result);
+}
+
+static int
+ProcPanoramiXShmGetImage(ClientPtr client)
+{
+ PanoramiXRes *draw;
+ DrawablePtr drawables[MAXSCREENS];
+ DrawablePtr pDraw;
+ xShmGetImageReply xgi;
+ ShmDescPtr shmdesc;
+ int i, x, y, w, h, format;
+ 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);
+ }
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+ return BadDrawable;
+
+ if (draw->type == XRT_PIXMAP)
+ return ProcShmGetImage(client);
+
+ VERIFY_DRAWABLE(pDraw, stuff->drawable, client);
+
+ 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 */
+ panoramiXdataPtr[0].x + pDraw->x + x < 0 ||
+ panoramiXdataPtr[0].x + pDraw->x + x + w > PanoramiXPixWidth ||
+ panoramiXdataPtr[0].y + pDraw->y + y < 0 ||
+ panoramiXdataPtr[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++)
+ VERIFY_DRAWABLE(drawables[i], draw->info[i].id, client);
+
+ 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;
+ }
+ }
+ }
+
+ if (client->swapped) {
+ register 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(client->noClientException);
+}
+
+static int
+ProcPanoramiXShmCreatePixmap(
+ register ClientPtr client)
+{
+ ScreenPtr pScreen = NULL;
+ PixmapPtr pMap = NULL;
+ DrawablePtr pDraw;
+ DepthPtr pDepth;
+ int i, j, result;
+ ShmDescPtr shmdesc;
+ REQUEST(xShmCreatePixmapReq);
+ PanoramiXRes *newPix;
+
+ REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+ client->errorValue = stuff->pid;
+ if (!sharedPixmaps)
+ return BadImplementation;
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+ VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
+ VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+ if (!stuff->width || !stuff->height)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ 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:
+ VERIFY_SHMSIZE(shmdesc, stuff->offset,
+ PixmapBytePad(stuff->width, stuff->depth) * stuff->height,
+ client);
+
+ if(!(newPix = (PanoramiXRes *) xalloc(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 = (client->noClientException);
+
+ FOR_NSCREENS(j) {
+ pScreen = screenInfo.screens[j];
+
+ pMap = (*shmFuncs[j]->CreatePixmap)(pScreen,
+ stuff->width, stuff->height, stuff->depth,
+ shmdesc->addr + stuff->offset);
+
+ if (pMap) {
+#ifdef PIXPRIV
+ pMap->devPrivates[shmPixmapPrivate].ptr = (pointer) shmdesc;
+#endif
+ 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);
+ }
+ xfree(newPix);
+ } else
+ AddResource(stuff->pid, XRT_PIXMAP, newPix);
+
+ return result;
+}
+
+#endif
+
+static int
+ProcShmPutImage(client)
+ register ClientPtr client;
+{
+ register GCPtr pGC;
+ register DrawablePtr pDraw;
+ long length;
+ ShmDescPtr shmdesc;
+ REQUEST(xShmPutImageReq);
+
+ REQUEST_SIZE_MATCH(xShmPutImageReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ 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;
+ }
+
+ VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
+ client);
+ 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;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "ProcShmPutImage: Format [%d] srcX [%d] srcY [%d], "
+ "totalWidth [%d] totalHeight [%d]\n", stuff->format, stuff->srcX,
+ stuff->srcY, stuff->totalWidth, stuff->totalHeight);
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "ProcShmPutImage: Calling (*shmFuncs[pDraw->pScreen->myNum]->PutImage)().\n");
+ #endif
+
+ (*shmFuncs[pDraw->pScreen->myNum]->PutImage)(
+ 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.sequenceNumber = client->sequence;
+ ev.minorEvent = X_ShmPutImage;
+ ev.majorEvent = ShmReqCode;
+ ev.shmseg = stuff->shmseg;
+ ev.offset = stuff->offset;
+ WriteEventsToClient(client, 1, (xEvent *) &ev);
+ }
+
+ return (client->noClientException);
+}
+
+
+
+static int
+ProcShmGetImage(client)
+ register ClientPtr client;
+{
+ register DrawablePtr pDraw;
+ long lenPer = 0, length;
+ Mask plane = 0;
+ xShmGetImageReply xgi;
+ ShmDescPtr shmdesc;
+ int n;
+
+ REQUEST(xShmGetImageReq);
+
+ REQUEST_SIZE_MATCH(xShmGetImageReq);
+ if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap))
+ {
+ client->errorValue = stuff->format;
+ return(BadValue);
+ }
+ VERIFY_DRAWABLE(pDraw, stuff->drawable, client);
+ 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(client->noClientException);
+}
+
+static PixmapPtr
+fbShmCreatePixmap (pScreen, width, height, depth, addr)
+ ScreenPtr pScreen;
+ int width;
+ int height;
+ int depth;
+ char *addr;
+{
+ register PixmapPtr pPixmap;
+
+ nxagentShmPixmapTrap = 1;
+
+ pPixmap = (*pScreen->CreatePixmap)(pScreen, width, height, depth);
+
+ if (!pPixmap)
+ {
+ nxagentShmPixmapTrap = 0;
+
+ return NullPixmap;
+ }
+
+ #ifdef TEST
+ fprintf(stderr,"fbShmCreatePixmap: Width [%d] Height [%d] Depth [%d]\n", width, height, depth);
+ #endif
+
+ if (!(*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth,
+ BitsPerPixel(depth), PixmapBytePad(width, depth), (pointer)addr))
+ {
+ #ifdef WARNING
+ fprintf(stderr,"fbShmCreatePixmap: Return Null Pixmap.\n");
+ #endif
+
+ (*pScreen->DestroyPixmap)(pPixmap);
+
+ nxagentShmPixmapTrap = 0;
+
+ return NullPixmap;
+ }
+
+ nxagentShmPixmapTrap = 0;
+
+ return pPixmap;
+}
+
+static int
+ProcShmCreatePixmap(client)
+ register ClientPtr client;
+{
+ PixmapPtr pMap;
+ register DrawablePtr pDraw;
+ DepthPtr pDepth;
+ register int i;
+ ShmDescPtr shmdesc;
+ REQUEST(xShmCreatePixmapReq);
+
+ REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+ client->errorValue = stuff->pid;
+ if (!sharedPixmaps)
+ return BadImplementation;
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+ VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
+ VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+ if (!stuff->width || !stuff->height)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ 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:
+ VERIFY_SHMSIZE(shmdesc, stuff->offset,
+ PixmapBytePad(stuff->width, stuff->depth) * stuff->height,
+ client);
+ pMap = (*shmFuncs[pDraw->pScreen->myNum]->CreatePixmap)(
+ pDraw->pScreen, stuff->width,
+ stuff->height, stuff->depth,
+ shmdesc->addr + stuff->offset);
+ if (pMap)
+ {
+#ifdef PIXPRIV
+ pMap->devPrivates[shmPixmapPrivate].ptr = (pointer) shmdesc;
+#endif
+ shmdesc->refcnt++;
+ pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pMap->drawable.id = stuff->pid;
+ if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
+ {
+ return(client->noClientException);
+ }
+ }
+ return (BadAlloc);
+}
+
+static int
+ProcShmDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+
+ #ifdef TEST
+ fprintf(stderr, "ProcShmDispatch: Going to execute operation [%d] for client [%d].\n",
+ stuff -> data, client -> index);
+
+ if (stuff->data <= X_ShmCreatePixmap)
+ {
+ fprintf(stderr, "ProcShmDispatch: Request [%s] OPCODE#%d.\n",
+ nxagentShmRequestLiteral[stuff->data], stuff->data);
+ }
+ #endif
+
+ switch (stuff->data)
+ {
+ case X_ShmQueryVersion:
+ return ProcShmQueryVersion(client);
+ case X_ShmAttach:
+ return ProcShmAttach(client);
+ case X_ShmDetach:
+ return ProcShmDetach(client);
+ case X_ShmPutImage:
+ {
+ int result;
+
+ #ifdef TEST
+ fprintf(stderr, "ProcShmDispatch: Going to execute ProcShmPutImage() for client [%d].\n",
+ client -> index);
+ #endif
+
+ nxagentShmTrap = 1;
+
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ {
+ result = ProcPanoramiXShmPutImage(client);
+
+ nxagentShmTrap = 0;
+
+ return result;
+ }
+#endif
+
+ result = ProcShmPutImage(client);
+
+ nxagentShmTrap = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "ProcShmDispatch: Returning from ProcShmPutImage() for client [%d].\n",
+ client -> index);
+ #endif
+
+ return result;
+ }
+ 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(from, to)
+ xShmCompletionEvent *from, *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(client)
+ register ClientPtr client;
+{
+ register int n;
+ REQUEST(xShmQueryVersionReq);
+
+ swaps(&stuff->length, n);
+ return ProcShmQueryVersion(client);
+}
+
+static int
+SProcShmAttach(client)
+ ClientPtr client;
+{
+ register 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(client)
+ ClientPtr client;
+{
+ register int n;
+ REQUEST(xShmDetachReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xShmDetachReq);
+ swapl(&stuff->shmseg, n);
+ return ProcShmDetach(client);
+}
+
+static int
+SProcShmPutImage(client)
+ ClientPtr client;
+{
+ register 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(client)
+ ClientPtr client;
+{
+ register 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(client)
+ ClientPtr client;
+{
+ register 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 (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+
+ #ifdef TEST
+ fprintf(stderr, "SProcShmDispatch: Going to execute operation [%d] for client [%d].\n",
+ stuff -> data, client -> index);
+ #endif
+
+ switch (stuff->data)
+ {
+ case X_ShmQueryVersion:
+ return SProcShmQueryVersion(client);
+ case X_ShmAttach:
+ return SProcShmAttach(client);
+ case X_ShmDetach:
+ return SProcShmDetach(client);
+ case X_ShmPutImage:
+ {
+ int result;
+
+ #ifdef TEST
+ fprintf(stderr, "SProcShmDispatch: Going to execute SProcShmPutImage() for client [%d].\n",
+ client -> index);
+ #endif
+
+ nxagentShmTrap = 1;
+
+ result = SProcShmPutImage(client);
+
+ nxagentShmTrap = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "SProcShmDispatch: Returning from SProcShmPutImage() for client [%d].\n",
+ client -> index);
+ #endif
+
+ return result;
+ }
+ case X_ShmGetImage:
+ return SProcShmGetImage(client);
+ case X_ShmCreatePixmap:
+ return SProcShmCreatePixmap(client);
+ default:
+ return BadRequest;
+ }
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.X.original
new file mode 100644
index 000000000..806008c60
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.X.original
@@ -0,0 +1,1267 @@
+/* $XFree86: xc/programs/Xserver/Xext/shm.c,v 3.41 2003/12/17 23:28:56 alanh Exp $ */
+/************************************************************
+
+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 */
+
+/* $Xorg: shm.c,v 1.4 2001/02/09 02:04:33 xorgcvs Exp $ */
+
+#define SHM
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <sys/types.h>
+#ifndef Lynx
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#else
+#include <ipc.h>
+#include <shm.h>
+#endif
+#include <unistd.h>
+#include <sys/stat.h>
+#define NEED_REPLIES
+#define NEED_EVENTS
+#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"
+#define _XSHM_SERVER_
+#include <X11/extensions/shmstr.h>
+#include <X11/Xfuncproto.h>
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#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;
+
+static void miShmPutImage(XSHM_PUT_IMAGE_ARGS);
+static void fbShmPutImage(XSHM_PUT_IMAGE_ARGS);
+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 DISPATCH_PROC(ProcShmAttach);
+static DISPATCH_PROC(ProcShmCreatePixmap);
+static DISPATCH_PROC(ProcShmDetach);
+static DISPATCH_PROC(ProcShmDispatch);
+static DISPATCH_PROC(ProcShmGetImage);
+static DISPATCH_PROC(ProcShmPutImage);
+static DISPATCH_PROC(ProcShmQueryVersion);
+static DISPATCH_PROC(SProcShmAttach);
+static DISPATCH_PROC(SProcShmCreatePixmap);
+static DISPATCH_PROC(SProcShmDetach);
+static DISPATCH_PROC(SProcShmDispatch);
+static DISPATCH_PROC(SProcShmGetImage);
+static DISPATCH_PROC(SProcShmPutImage);
+static DISPATCH_PROC(SProcShmQueryVersion);
+
+static unsigned char ShmReqCode;
+int ShmCompletionCode;
+int BadShmSegCode;
+RESTYPE ShmSegType;
+static ShmDescPtr Shmsegs;
+static Bool sharedPixmaps;
+static int pixmapFormat;
+static int shmPixFormat[MAXSCREENS];
+static ShmFuncsPtr shmFuncs[MAXSCREENS];
+static DestroyPixmapProcPtr destroyPixmap[MAXSCREENS];
+#ifdef PIXPRIV
+static int shmPixmapPrivate;
+#endif
+static ShmFuncs miFuncs = {NULL, miShmPutImage};
+static ShmFuncs fbFuncs = {fbShmCreatePixmap, fbShmPutImage};
+
+#define VERIFY_SHMSEG(shmseg,shmdesc,client) \
+{ \
+ shmdesc = (ShmDescPtr)LookupIDByType(shmseg, ShmSegType); \
+ if (!shmdesc) \
+ { \
+ client->errorValue = shmseg; \
+ return BadShmSegCode; \
+ } \
+}
+
+#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__)
+#include <sys/signal.h>
+
+static Bool badSysCall = FALSE;
+
+static void
+SigSysHandler(signo)
+int signo;
+{
+ badSysCall = TRUE;
+}
+
+static Bool CheckForShmSyscall()
+{
+ 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, (struct shmid_ds *)NULL);
+ }
+ else
+ {
+ /* Allocation failed */
+ badSysCall = TRUE;
+ }
+ signal(SIGSYS, oldHandler);
+ return(!badSysCall);
+}
+
+#define MUST_CHECK_FOR_SHM_SYSCALL
+
+#endif
+
+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
+
+ sharedPixmaps = xFalse;
+ pixmapFormat = 0;
+ {
+ sharedPixmaps = xTrue;
+ pixmapFormat = shmPixFormat[0];
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ if (!shmFuncs[i])
+ shmFuncs[i] = &miFuncs;
+ if (!shmFuncs[i]->CreatePixmap)
+ sharedPixmaps = xFalse;
+ if (shmPixFormat[i] && (shmPixFormat[i] != pixmapFormat))
+ {
+ sharedPixmaps = xFalse;
+ pixmapFormat = 0;
+ }
+ }
+ if (!pixmapFormat)
+ pixmapFormat = ZPixmap;
+ if (sharedPixmaps)
+ {
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ destroyPixmap[i] = screenInfo.screens[i]->DestroyPixmap;
+ screenInfo.screens[i]->DestroyPixmap = ShmDestroyPixmap;
+ }
+#ifdef PIXPRIV
+ shmPixmapPrivate = AllocatePixmapPrivateIndex();
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ if (!AllocatePixmapPrivate(screenInfo.screens[i],
+ shmPixmapPrivate, 0))
+ return;
+ }
+#endif
+ }
+ }
+ ShmSegType = CreateNewResourceType(ShmDetachSegment);
+ if (ShmSegType &&
+ (extEntry = AddExtension(SHMNAME, ShmNumberEvents, ShmNumberErrors,
+ ProcShmDispatch, SProcShmDispatch,
+ ShmResetProc, StandardMinorOpcode)))
+ {
+ ShmReqCode = (unsigned char)extEntry->base;
+ ShmCompletionCode = extEntry->eventBase;
+ BadShmSegCode = extEntry->errorBase;
+ EventSwapVector[ShmCompletionCode] = (EventSwapPtr) SShmCompletionEvent;
+ }
+}
+
+/*ARGSUSED*/
+static void
+ShmResetProc (extEntry)
+ExtensionEntry *extEntry;
+{
+ int i;
+
+ for (i = 0; i < MAXSCREENS; i++)
+ {
+ shmFuncs[i] = (ShmFuncsPtr)NULL;
+ shmPixFormat[i] = 0;
+ }
+}
+
+void
+ShmRegisterFuncs(
+ ScreenPtr pScreen,
+ ShmFuncsPtr funcs)
+{
+ shmFuncs[pScreen->myNum] = funcs;
+}
+
+void
+ShmSetPixmapFormat(
+ ScreenPtr pScreen,
+ int format)
+{
+ shmPixFormat[pScreen->myNum] = format;
+}
+
+static Bool
+ShmDestroyPixmap (PixmapPtr pPixmap)
+{
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ Bool ret;
+ if (pPixmap->refcnt == 1)
+ {
+ ShmDescPtr shmdesc;
+#ifdef PIXPRIV
+ shmdesc = (ShmDescPtr) pPixmap->devPrivates[shmPixmapPrivate].ptr;
+#else
+ char *base = (char *) pPixmap->devPrivate.ptr;
+
+ if (base != (pointer) (pPixmap + 1))
+ {
+ for (shmdesc = Shmsegs; shmdesc; shmdesc = shmdesc->next)
+ {
+ if (shmdesc->addr <= base && base <= shmdesc->addr + shmdesc->size)
+ break;
+ }
+ }
+ else
+ shmdesc = 0;
+#endif
+ if (shmdesc)
+ ShmDetachSegment ((pointer) shmdesc, pPixmap->drawable.id);
+ }
+
+ pScreen->DestroyPixmap = destroyPixmap[pScreen->myNum];
+ ret = (*pScreen->DestroyPixmap) (pPixmap);
+ destroyPixmap[pScreen->myNum] = pScreen->DestroyPixmap;
+ pScreen->DestroyPixmap = ShmDestroyPixmap;
+ return ret;
+}
+
+void
+ShmRegisterFbFuncs(pScreen)
+ ScreenPtr pScreen;
+{
+ shmFuncs[pScreen->myNum] = &fbFuncs;
+}
+
+static int
+ProcShmQueryVersion(client)
+ register ClientPtr client;
+{
+ xShmQueryVersionReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xShmQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.sharedPixmaps = sharedPixmaps;
+ rep.pixmapFormat = pixmapFormat;
+ rep.majorVersion = SHM_MAJOR_VERSION;
+ rep.minorVersion = 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 (client->noClientException);
+}
+
+/*
+ * Simulate the access() system call for a shared memory segement,
+ * using the credentials from the client if available
+ */
+static int
+shm_access(ClientPtr client, struct ipc_perm *perm, int readonly)
+{
+ int uid, gid;
+ mode_t mask;
+
+ if (LocalClientCred(client, &uid, &gid) != -1) {
+
+ /* User id 0 always gets access */
+ if (uid == 0) {
+ return 0;
+ }
+ /* Check the owner */
+ if (perm->uid == uid || perm->cuid == uid) {
+ mask = S_IRUSR;
+ if (!readonly) {
+ mask |= S_IWUSR;
+ }
+ return (perm->mode & mask) == mask ? 0 : -1;
+ }
+ /* Check the group */
+ if (perm->gid == gid || perm->cgid == gid) {
+ mask = S_IRGRP;
+ if (!readonly) {
+ mask |= S_IWGRP;
+ }
+ return (perm->mode & mask) == mask ? 0 : -1;
+ }
+ }
+ /* Otherwise, check everyone else */
+ mask = S_IROTH;
+ if (!readonly) {
+ mask |= S_IWOTH;
+ }
+ return (perm->mode & mask) == mask ? 0 : -1;
+}
+
+static int
+ProcShmAttach(client)
+ register ClientPtr client;
+{
+ struct shmid_ds 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 = (ShmDescPtr) xalloc(sizeof(ShmDescRec));
+ if (!shmdesc)
+ return BadAlloc;
+ shmdesc->addr = shmat(stuff->shmid, 0,
+ stuff->readOnly ? SHM_RDONLY : 0);
+ if ((shmdesc->addr == ((char *)-1)) ||
+ shmctl(stuff->shmid, IPC_STAT, &buf))
+ {
+ xfree(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, &(buf.shm_perm), stuff->readOnly) == -1) {
+ shmdt(shmdesc->addr);
+ xfree(shmdesc);
+ return BadAccess;
+ }
+
+ shmdesc->shmid = stuff->shmid;
+ shmdesc->refcnt = 1;
+ shmdesc->writable = !stuff->readOnly;
+ shmdesc->size = buf.shm_segsz;
+ shmdesc->next = Shmsegs;
+ Shmsegs = shmdesc;
+ }
+ if (!AddResource(stuff->shmseg, ShmSegType, (pointer)shmdesc))
+ return BadAlloc;
+ return(client->noClientException);
+}
+
+/*ARGSUSED*/
+static int
+ShmDetachSegment(value, shmseg)
+ 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;
+ xfree(shmdesc);
+ return Success;
+}
+
+static int
+ProcShmDetach(client)
+ register ClientPtr client;
+{
+ ShmDescPtr shmdesc;
+ REQUEST(xShmDetachReq);
+
+ REQUEST_SIZE_MATCH(xShmDetachReq);
+ VERIFY_SHMSEG(stuff->shmseg, shmdesc, client);
+ FreeResource(stuff->shmseg, RT_NONE);
+ return(client->noClientException);
+}
+
+static void
+miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
+ DrawablePtr dst;
+ GCPtr pGC;
+ int depth, w, h, sx, sy, sw, sh, dx, dy;
+ unsigned int format;
+ char *data;
+{
+ PixmapPtr pmap;
+ GCPtr putGC;
+
+ putGC = GetScratchGC(depth, dst->pScreen);
+ if (!putGC)
+ return;
+ pmap = (*dst->pScreen->CreatePixmap)(dst->pScreen, sw, sh, depth);
+ if (!pmap)
+ {
+ FreeScratchGC(putGC);
+ return;
+ }
+ ValidateGC((DrawablePtr)pmap, putGC);
+ (*putGC->ops->PutImage)((DrawablePtr)pmap, putGC, depth, -sx, -sy, w, h, 0,
+ (format == XYPixmap) ? XYPixmap : ZPixmap, data);
+ FreeScratchGC(putGC);
+ if (format == XYBitmap)
+ (void)(*pGC->ops->CopyPlane)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
+ dx, dy, 1L);
+ else
+ (void)(*pGC->ops->CopyArea)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
+ dx, dy);
+ (*pmap->drawable.pScreen->DestroyPixmap)(pmap);
+}
+
+static void
+fbShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
+ DrawablePtr dst;
+ GCPtr pGC;
+ int depth, w, h, sx, sy, sw, sh, dx, dy;
+ unsigned int format;
+ char *data;
+{
+ if ((format == ZPixmap) || (depth == 1))
+ {
+ PixmapPtr pPixmap;
+
+ pPixmap = GetScratchPixmapHeader(dst->pScreen, w, h, depth,
+ BitsPerPixel(depth), PixmapBytePad(w, depth), (pointer)data);
+ if (!pPixmap)
+ return;
+ if (format == XYBitmap)
+ (void)(*pGC->ops->CopyPlane)((DrawablePtr)pPixmap, dst, pGC,
+ sx, sy, sw, sh, dx, dy, 1L);
+ else
+ (void)(*pGC->ops->CopyArea)((DrawablePtr)pPixmap, dst, pGC,
+ sx, sy, sw, sh, dx, dy);
+ FreeScratchPixmapHeader(pPixmap);
+ }
+ else
+ miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy,
+ data);
+}
+
+
+#ifdef PANORAMIX
+static int
+ProcPanoramiXShmPutImage(register ClientPtr client)
+{
+ int j, result = 0, orig_x, orig_y;
+ PanoramiXRes *draw, *gc;
+ Bool sendEvent, isRoot;
+
+ REQUEST(xShmPutImageReq);
+ REQUEST_SIZE_MATCH(xShmPutImageReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+ return BadDrawable;
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, SecurityReadAccess)))
+ return BadGC;
+
+ 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 - panoramiXdataPtr[j].x;
+ stuff->dstY = orig_y - panoramiXdataPtr[j].y;
+ }
+ result = ProcShmPutImage(client);
+ if(result != client->noClientException) break;
+ }
+ return(result);
+}
+
+static int
+ProcPanoramiXShmGetImage(ClientPtr client)
+{
+ PanoramiXRes *draw;
+ DrawablePtr drawables[MAXSCREENS];
+ DrawablePtr pDraw;
+ xShmGetImageReply xgi;
+ ShmDescPtr shmdesc;
+ int i, x, y, w, h, format;
+ 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);
+ }
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+ return BadDrawable;
+
+ if (draw->type == XRT_PIXMAP)
+ return ProcShmGetImage(client);
+
+ VERIFY_DRAWABLE(pDraw, stuff->drawable, client);
+
+ 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 */
+ panoramiXdataPtr[0].x + pDraw->x + x < 0 ||
+ panoramiXdataPtr[0].x + pDraw->x + x + w > PanoramiXPixWidth ||
+ panoramiXdataPtr[0].y + pDraw->y + y < 0 ||
+ panoramiXdataPtr[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++)
+ VERIFY_DRAWABLE(drawables[i], draw->info[i].id, client);
+
+ 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;
+ }
+ }
+ }
+
+ if (client->swapped) {
+ register 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(client->noClientException);
+}
+
+static int
+ProcPanoramiXShmCreatePixmap(
+ register ClientPtr client)
+{
+ ScreenPtr pScreen = NULL;
+ PixmapPtr pMap = NULL;
+ DrawablePtr pDraw;
+ DepthPtr pDepth;
+ int i, j, result;
+ ShmDescPtr shmdesc;
+ REQUEST(xShmCreatePixmapReq);
+ PanoramiXRes *newPix;
+
+ REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+ client->errorValue = stuff->pid;
+ if (!sharedPixmaps)
+ return BadImplementation;
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+ VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
+ VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+ if (!stuff->width || !stuff->height)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ 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:
+ VERIFY_SHMSIZE(shmdesc, stuff->offset,
+ PixmapBytePad(stuff->width, stuff->depth) * stuff->height,
+ client);
+
+ if(!(newPix = (PanoramiXRes *) xalloc(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 = (client->noClientException);
+
+ FOR_NSCREENS(j) {
+ pScreen = screenInfo.screens[j];
+
+ pMap = (*shmFuncs[j]->CreatePixmap)(pScreen,
+ stuff->width, stuff->height, stuff->depth,
+ shmdesc->addr + stuff->offset);
+
+ if (pMap) {
+#ifdef PIXPRIV
+ pMap->devPrivates[shmPixmapPrivate].ptr = (pointer) shmdesc;
+#endif
+ 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);
+ }
+ xfree(newPix);
+ } else
+ AddResource(stuff->pid, XRT_PIXMAP, newPix);
+
+ return result;
+}
+
+#endif
+
+static int
+ProcShmPutImage(client)
+ register ClientPtr client;
+{
+ register GCPtr pGC;
+ register DrawablePtr pDraw;
+ long length;
+ ShmDescPtr shmdesc;
+ REQUEST(xShmPutImageReq);
+
+ REQUEST_SIZE_MATCH(xShmPutImageReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ 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;
+ }
+
+ VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
+ client);
+ 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
+ (*shmFuncs[pDraw->pScreen->myNum]->PutImage)(
+ 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.sequenceNumber = client->sequence;
+ ev.minorEvent = X_ShmPutImage;
+ ev.majorEvent = ShmReqCode;
+ ev.shmseg = stuff->shmseg;
+ ev.offset = stuff->offset;
+ WriteEventsToClient(client, 1, (xEvent *) &ev);
+ }
+
+ return (client->noClientException);
+}
+
+
+
+static int
+ProcShmGetImage(client)
+ register ClientPtr client;
+{
+ register DrawablePtr pDraw;
+ long lenPer = 0, length;
+ Mask plane = 0;
+ xShmGetImageReply xgi;
+ ShmDescPtr shmdesc;
+ int n;
+
+ REQUEST(xShmGetImageReq);
+
+ REQUEST_SIZE_MATCH(xShmGetImageReq);
+ if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap))
+ {
+ client->errorValue = stuff->format;
+ return(BadValue);
+ }
+ VERIFY_DRAWABLE(pDraw, stuff->drawable, client);
+ 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(client->noClientException);
+}
+
+static PixmapPtr
+fbShmCreatePixmap (pScreen, width, height, depth, addr)
+ ScreenPtr pScreen;
+ int width;
+ int height;
+ int depth;
+ char *addr;
+{
+ register PixmapPtr pPixmap;
+
+ pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth);
+ 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(client)
+ register ClientPtr client;
+{
+ PixmapPtr pMap;
+ register DrawablePtr pDraw;
+ DepthPtr pDepth;
+ register int i;
+ ShmDescPtr shmdesc;
+ REQUEST(xShmCreatePixmapReq);
+
+ REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+ client->errorValue = stuff->pid;
+ if (!sharedPixmaps)
+ return BadImplementation;
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+ VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
+ VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+ if (!stuff->width || !stuff->height)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ 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:
+ VERIFY_SHMSIZE(shmdesc, stuff->offset,
+ PixmapBytePad(stuff->width, stuff->depth) * stuff->height,
+ client);
+ pMap = (*shmFuncs[pDraw->pScreen->myNum]->CreatePixmap)(
+ pDraw->pScreen, stuff->width,
+ stuff->height, stuff->depth,
+ shmdesc->addr + stuff->offset);
+ if (pMap)
+ {
+#ifdef PIXPRIV
+ pMap->devPrivates[shmPixmapPrivate].ptr = (pointer) shmdesc;
+#endif
+ shmdesc->refcnt++;
+ pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pMap->drawable.id = stuff->pid;
+ if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
+ {
+ return(client->noClientException);
+ }
+ }
+ return (BadAlloc);
+}
+
+static int
+ProcShmDispatch (client)
+ register 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(from, to)
+ xShmCompletionEvent *from, *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(client)
+ register ClientPtr client;
+{
+ register int n;
+ REQUEST(xShmQueryVersionReq);
+
+ swaps(&stuff->length, n);
+ return ProcShmQueryVersion(client);
+}
+
+static int
+SProcShmAttach(client)
+ ClientPtr client;
+{
+ register 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(client)
+ ClientPtr client;
+{
+ register int n;
+ REQUEST(xShmDetachReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xShmDetachReq);
+ swapl(&stuff->shmseg, n);
+ return ProcShmDetach(client);
+}
+
+static int
+SProcShmPutImage(client)
+ ClientPtr client;
+{
+ register 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(client)
+ ClientPtr client;
+{
+ register 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(client)
+ ClientPtr client;
+{
+ register 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 (client)
+ register 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;
+ }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c
new file mode 100644
index 000000000..7ba468ac0
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c
@@ -0,0 +1,4174 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/* $XdotOrg: xc/programs/Xserver/dix/window.c,v 1.12 2005/07/03 08:53:38 daniels Exp $ */
+/* $Xorg: window.c,v 1.4 2001/02/09 02:04:41 xorgcvs Exp $ */
+/*
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+*/
+
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/window.c,v 3.36 2003/11/14 23:52:50 torrey Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+#include "selection.h"
+#ifdef PANORAMIX
+#include "../../Xext/panoramiX.h"
+#include "../../Xext/panoramiXsrv.h"
+#endif
+#include "dixevents.h"
+#include "globals.h"
+
+#ifdef XAPPGROUP
+#include <X11/extensions/Xagsrv.h>
+#endif
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+
+#include "Screen.h"
+#include "Options.h"
+#include "Atoms.h"
+#include "Clipboard.h"
+#include "Splash.h"
+#include "Rootless.h"
+#include "Composite.h"
+#include "Drawable.h"
+#include "Colormap.h"
+
+extern Bool nxagentWMIsRunning;
+extern Bool nxagentScreenTrap;
+
+/******
+ * Window stuff for server
+ *
+ * CreateRootWindow, CreateWindow, ChangeWindowAttributes,
+ * GetWindowAttributes, DeleteWindow, DestroySubWindows,
+ * HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows,
+ * UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow,
+ *
+ ******/
+
+int screenIsSaved = SCREEN_SAVER_OFF;
+
+ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
+
+#if 0
+extern void DeleteWindowFromAnyEvents();
+extern Mask EventMaskForClient();
+extern void WindowHasNewCursor();
+extern void RecalculateDeliverableEvents();
+#endif
+
+static Bool TileScreenSaver(int i, int kind);
+
+
+#define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \
+ CWDontPropagate | CWOverrideRedirect | CWCursor )
+
+#define BOXES_OVERLAP(b1, b2) \
+ (!( ((b1)->x2 <= (b2)->x1) || \
+ ( ((b1)->x1 >= (b2)->x2)) || \
+ ( ((b1)->y2 <= (b2)->y1)) || \
+ ( ((b1)->y1 >= (b2)->y2)) ) )
+
+#define RedirectSend(pWin) \
+ ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureRedirectMask)
+
+#define SubSend(pWin) \
+ ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask)
+
+#define StrSend(pWin) \
+ ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask)
+
+#define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
+
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+int numSaveUndersViewable = 0;
+int deltaSaveUndersViewable = 0;
+
+WindowPtr nxagentRootTileWindow;
+
+/*
+ * This block used the DEBUG symbol.
+ */
+
+#ifdef WINDOW_TREE_DEBUG
+/******
+ * PrintWindowTree
+ * For debugging only
+ ******/
+
+int
+PrintChildren(WindowPtr p1, int indent)
+{
+ WindowPtr p2;
+ int i;
+
+ while (p1)
+ {
+ p2 = p1->firstChild;
+ for (i=0; i<indent; i++) ErrorF( " ");
+ ErrorF( "%x\n", p1->drawable.id);
+ miPrintRegion(&p1->clipList);
+ PrintChildren(p2, indent+4);
+ p1 = p1->nextSib;
+ }
+}
+
+PrintWindowTree()
+{
+ int i;
+ WindowPtr pWin, p1;
+
+ for (i=0; i<screenInfo.numScreens; i++)
+ {
+ ErrorF( "WINDOW %d\n", i);
+ pWin = WindowTable[i];
+ miPrintRegion(&pWin->clipList);
+ p1 = pWin->firstChild;
+ PrintChildren(p1, 4);
+ }
+}
+#endif
+
+int
+TraverseTree(register WindowPtr pWin, VisitWindowProcPtr func, pointer data)
+{
+ register int result;
+ register WindowPtr pChild;
+
+ if (!(pChild = pWin))
+ return(WT_NOMATCH);
+ while (1)
+ {
+ result = (* func)(pChild, data);
+ if (result == WT_STOPWALKING)
+ return(WT_STOPWALKING);
+ if ((result == WT_WALKCHILDREN) && pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ break;
+ pChild = pChild->nextSib;
+ }
+ return(WT_NOMATCH);
+}
+
+/*****
+ * WalkTree
+ * Walk the window tree, for SCREEN, preforming FUNC(pWin, data) on
+ * each window. If FUNC returns WT_WALKCHILDREN, traverse the children,
+ * if it returns WT_DONTWALKCHILDREN, dont. If it returns WT_STOPWALKING
+ * exit WalkTree. Does depth-first traverse.
+ *****/
+
+int
+WalkTree(ScreenPtr pScreen, VisitWindowProcPtr func, pointer data)
+{
+ return(TraverseTree(WindowTable[pScreen->myNum], func, data));
+}
+
+/* hack for forcing backing store on all windows */
+int defaultBackingStore = NotUseful;
+/* hack to force no backing store */
+Bool disableBackingStore = FALSE;
+Bool enableBackingStore = FALSE;
+/* hack to force no save unders */
+Bool disableSaveUnders = FALSE;
+
+static void
+SetWindowToDefaults(register WindowPtr pWin)
+{
+ pWin->prevSib = NullWindow;
+ pWin->firstChild = NullWindow;
+ pWin->lastChild = NullWindow;
+
+ pWin->valdata = (ValidatePtr)NULL;
+ pWin->optional = (WindowOptPtr)NULL;
+ pWin->cursorIsNone = TRUE;
+
+ pWin->backingStore = NotUseful;
+ pWin->DIXsaveUnder = FALSE;
+ pWin->backStorage = (pointer) NULL;
+
+ pWin->mapped = FALSE; /* off */
+ pWin->realized = FALSE; /* off */
+ pWin->viewable = FALSE;
+ pWin->visibility = VisibilityNotViewable;
+ pWin->overrideRedirect = FALSE;
+ pWin->saveUnder = FALSE;
+
+ pWin->bitGravity = ForgetGravity;
+ pWin->winGravity = NorthWestGravity;
+
+ pWin->eventMask = 0;
+ pWin->deliverableEvents = 0;
+ pWin->dontPropagate = 0;
+ pWin->forcedBS = FALSE;
+#ifdef NEED_DBE_BUF_BITS
+ pWin->srcBuffer = DBE_FRONT_BUFFER;
+ pWin->dstBuffer = DBE_FRONT_BUFFER;
+#endif
+#ifdef COMPOSITE
+ pWin->redirectDraw = 0;
+#endif
+}
+
+#ifdef NXAGENT_SERVER
+
+void nxagentClearSplash(WindowPtr pW)
+{
+ int w, h;
+ ScreenPtr pScreen;
+
+ w = pW->drawable.width;
+ h = pW->drawable.height;
+
+ pScreen = pW->drawable.pScreen;
+
+ if (pW->backgroundState == BackgroundPixmap)
+ {
+ (*pScreen->DestroyPixmap)(pW->background.pixmap);
+ }
+
+ pW->backgroundState = BackgroundPixel;
+ pW->background.pixel = nxagentLogoBlack;
+
+ (*pScreen->ChangeWindowAttributes)(pW, CWBackPixmap|CWBackPixel);
+}
+
+static void
+#if NeedFunctionPrototypes
+MakeRootTile(WindowPtr pWin)
+#else
+MakeRootTile(pWin)
+ WindowPtr pWin;
+#endif
+{
+ nxagentRootTileWindow = pWin;
+}
+
+#else /* NXAGENT_SERVER */
+
+static void
+MakeRootTile(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ GCPtr pGC;
+ unsigned char back[128];
+ int len = BitmapBytePad(sizeof(long));
+ register unsigned char *from, *to;
+ register int i, j;
+
+ pWin->background.pixmap = (*pScreen->CreatePixmap)(pScreen, 4, 4,
+ pScreen->rootDepth);
+
+ pWin->backgroundState = BackgroundPixmap;
+ pGC = GetScratchGC(pScreen->rootDepth, pScreen);
+ if (!pWin->background.pixmap || !pGC)
+ FatalError("could not create root tile");
+
+ {
+ CARD32 attributes[2];
+
+ attributes[0] = pScreen->whitePixel;
+ attributes[1] = pScreen->blackPixel;
+
+ (void)ChangeGC(pGC, GCForeground | GCBackground, attributes);
+ }
+
+ ValidateGC((DrawablePtr)pWin->background.pixmap, pGC);
+
+ from = (screenInfo.bitmapBitOrder == LSBFirst) ? _back_lsb : _back_msb;
+ to = back;
+
+ for (i = 4; i > 0; i--, from++)
+ for (j = len; j > 0; j--)
+ *to++ = *from;
+
+ if (blackRoot)
+ bzero(back, sizeof(back));
+
+ (*pGC->ops->PutImage)((DrawablePtr)pWin->background.pixmap, pGC, 1,
+ 0, 0, len, 4, 0, XYBitmap, (char *)back);
+
+ FreeScratchGC(pGC);
+
+}
+
+#endif /* NXAGENT_SERVER */
+
+WindowPtr
+AllocateWindow(ScreenPtr pScreen)
+{
+ WindowPtr pWin;
+ register char *ptr;
+ register DevUnion *ppriv;
+ register unsigned *sizes;
+ register unsigned size;
+ register int i;
+
+ pWin = (WindowPtr)xalloc(pScreen->totalWindowSize);
+ if (pWin)
+ {
+ ppriv = (DevUnion *)(pWin + 1);
+ pWin->devPrivates = ppriv;
+ sizes = pScreen->WindowPrivateSizes;
+ ptr = (char *)(ppriv + pScreen->WindowPrivateLen);
+ for (i = pScreen->WindowPrivateLen; --i >= 0; ppriv++, sizes++)
+ {
+ if ( (size = *sizes) )
+ {
+ ppriv->ptr = (pointer)ptr;
+ ptr += size;
+ }
+ else
+ ppriv->ptr = (pointer)NULL;
+ }
+ }
+ return pWin;
+}
+
+/*****
+ * CreateRootWindow
+ * Makes a window at initialization time for specified screen
+ *****/
+
+Bool
+CreateRootWindow(ScreenPtr pScreen)
+{
+ WindowPtr pWin;
+ BoxRec box;
+ PixmapFormatRec *format;
+
+ pWin = AllocateWindow(pScreen);
+ if (!pWin)
+ return FALSE;
+
+ savedScreenInfo[pScreen->myNum].pWindow = NULL;
+ savedScreenInfo[pScreen->myNum].wid = FakeClientID(0);
+ savedScreenInfo[pScreen->myNum].ExternalScreenSaver = NULL;
+ screenIsSaved = SCREEN_SAVER_OFF;
+
+ WindowTable[pScreen->myNum] = pWin;
+
+ pWin->drawable.pScreen = pScreen;
+ pWin->drawable.type = DRAWABLE_WINDOW;
+
+ pWin->drawable.depth = pScreen->rootDepth;
+ for (format = screenInfo.formats;
+ format->depth != pScreen->rootDepth;
+ format++)
+ ;
+ pWin->drawable.bitsPerPixel = format->bitsPerPixel;
+
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+ pWin->parent = NullWindow;
+ SetWindowToDefaults(pWin);
+
+ pWin->optional = (WindowOptRec *) xalloc (sizeof (WindowOptRec));
+ if (!pWin->optional)
+ return FALSE;
+
+ pWin->optional->dontPropagateMask = 0;
+ pWin->optional->otherEventMasks = 0;
+ pWin->optional->otherClients = NULL;
+ pWin->optional->passiveGrabs = NULL;
+ pWin->optional->userProps = NULL;
+ pWin->optional->backingBitPlanes = ~0L;
+ pWin->optional->backingPixel = 0;
+#ifdef SHAPE
+ pWin->optional->boundingShape = NULL;
+ pWin->optional->clipShape = NULL;
+ pWin->optional->inputShape = NULL;
+#endif
+#ifdef XINPUT
+ pWin->optional->inputMasks = NULL;
+#endif
+ pWin->optional->colormap = pScreen->defColormap;
+ pWin->optional->visual = pScreen->rootVisual;
+
+ pWin->nextSib = NullWindow;
+
+ pWin->drawable.id = FakeClientID(0);
+
+ pWin->origin.x = pWin->origin.y = 0;
+ pWin->drawable.height = pScreen->height;
+ pWin->drawable.width = pScreen->width;
+ pWin->drawable.x = pWin->drawable.y = 0;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pScreen->width;
+ box.y2 = pScreen->height;
+ REGION_INIT(pScreen, &pWin->clipList, &box, 1);
+ REGION_INIT(pScreen, &pWin->winSize, &box, 1);
+ REGION_INIT(pScreen, &pWin->borderSize, &box, 1);
+ REGION_INIT(pScreen, &pWin->borderClip, &box, 1);
+
+ pWin->drawable.class = InputOutput;
+ pWin->optional->visual = pScreen->rootVisual;
+
+ pWin->backgroundState = BackgroundPixel;
+ pWin->background.pixel = pScreen->whitePixel;
+
+ pWin->borderIsPixel = TRUE;
+ pWin->border.pixel = pScreen->blackPixel;
+ pWin->borderWidth = 0;
+
+ if (!AddResource(pWin->drawable.id, RT_WINDOW, (pointer)pWin))
+ return FALSE;
+
+ if (disableBackingStore)
+ {
+ pScreen -> backingStoreSupport = NotUseful;
+ }
+
+ if (enableBackingStore)
+ {
+ pScreen -> backingStoreSupport = Always;
+ }
+
+ pScreen->saveUnderSupport = False;
+
+#ifdef DO_SAVE_UNDERS
+ if ((pScreen->backingStoreSupport != NotUseful) &&
+ (pScreen->saveUnderSupport == NotUseful))
+ {
+ /*
+ * If the screen has backing-store but no save-unders, let the
+ * clients know we can support save-unders using backing-store.
+ */
+ pScreen->saveUnderSupport = USE_DIX_SAVE_UNDERS;
+ }
+#endif /* DO_SAVE_UNDERS */
+
+ if (disableSaveUnders)
+ pScreen->saveUnderSupport = NotUseful;
+
+ return TRUE;
+}
+
+#ifdef NXAGENT_SERVER
+
+void
+InitRootWindow(WindowPtr pWin)
+{
+ ScreenPtr pScreen;
+
+ #ifdef TEST
+ fprintf(stderr, "InitRootWindow: Called for window at [%p][%ld] with parent [%p].\n",
+ (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
+ #endif
+
+ if (nxagentOption(Rootless))
+ {
+ #ifdef TEST
+ fprintf(stderr, "InitRootWindow: Assigned agent root to window at [%p][%ld] with parent [%p].\n",
+ (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
+ #endif
+
+ nxagentRootlessWindow = pWin;
+ }
+
+ pScreen = pWin->drawable.pScreen;
+
+ /*
+ * A root window is created for each screen by main
+ * and the pointer is saved in WindowTable as in the
+ * following snippet:
+ *
+ * for (i = 0; i < screenInfo.numScreens; i++)
+ * InitRootWindow(WindowTable[i]);
+ *
+ * Our root window on the real display was already
+ * created at the time the screen was opened, so it
+ * is unclear how this window (or the other window,
+ * if you prefer) fits in the big picture.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "InitRootWindow: Going to create window as root at [%p][%ld] with parent [%p].\n",
+ (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
+ #endif
+
+ if (!(*pScreen->CreateWindow)(pWin))
+ return; /* XXX */
+
+ #ifdef TEST
+ fprintf(stderr, "InitRootWindow: Created window as root at [%p][%ld] with parent [%p].\n",
+ (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
+ #endif
+
+ (*pScreen->PositionWindow)(pWin, 0, 0);
+
+ pWin->cursorIsNone = FALSE;
+ pWin->optional->cursor = rootCursor;
+ rootCursor->refcnt++;
+ pWin->backingStore = defaultBackingStore;
+ pWin->forcedBS = (defaultBackingStore != NotUseful);
+
+ #ifdef NXAGENT_SPLASH
+ /* We SHOULD check for an error value here XXX */
+ pWin -> background.pixel = pScreen -> blackPixel;
+ (*pScreen->ChangeWindowAttributes)(pWin,
+ CWBackPixel|CWBorderPixel|CWCursor|CWBackingStore);
+ #else
+ (*pScreen->ChangeWindowAttributes)(pWin,
+ CWBackPixmap|CWBorderPixel|CWCursor|CWBackingStore);
+ #endif
+
+ MakeRootTile(pWin);
+
+ /*
+ * Map both the root and the default agent window.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "InitRootWindow: Mapping default windows.\n");
+ #endif
+
+ nxagentInitAtoms(pWin);
+
+ nxagentInitClipboard(pWin);
+
+ nxagentMapDefaultWindows();
+
+ nxagentRedirectDefaultWindows();
+
+ #ifdef NXAGENT_ARTSD
+ {
+ char artsd_port[10];
+ int nPort;
+ extern void nxagentPropagateArtsdProperties(ScreenPtr pScreen, char *port);
+ nPort = atoi(display) + 7000;
+ sprintf(artsd_port,"%d", nPort);
+ nxagentPropagateArtsdProperties(pScreen, artsd_port);
+ }
+ #endif
+}
+
+#else /* NXAGENT_SERVER */
+
+void
+InitRootWindow(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ if (!(*pScreen->CreateWindow)(pWin))
+ return; /* XXX */
+ (*pScreen->PositionWindow)(pWin, 0, 0);
+
+ pWin->cursorIsNone = FALSE;
+ pWin->optional->cursor = rootCursor;
+ rootCursor->refcnt++;
+ MakeRootTile(pWin);
+ pWin->backingStore = defaultBackingStore;
+ pWin->forcedBS = (defaultBackingStore != NotUseful);
+ /* We SHOULD check for an error value here XXX */
+ (*pScreen->ChangeWindowAttributes)(pWin,
+ CWBackPixmap|CWBorderPixel|CWCursor|CWBackingStore);
+
+ MapWindow(pWin, serverClient);
+}
+
+#endif /* NXAGENT_SERVER */
+
+/* Set the region to the intersection of the rectangle and the
+ * window's winSize. The window is typically the parent of the
+ * window from which the region came.
+ */
+
+void
+ClippedRegionFromBox(register WindowPtr pWin, RegionPtr Rgn,
+ register int x, register int y,
+ register int w, register int h)
+{
+#ifndef NXAGENT_SERVER
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+#endif /* NXAGENT_SERVER */
+ BoxRec box;
+
+ box = *(REGION_EXTENTS(pScreen, &pWin->winSize));
+ /* we do these calculations to avoid overflows */
+ if (x > box.x1)
+ box.x1 = x;
+ if (y > box.y1)
+ box.y1 = y;
+ x += w;
+ if (x < box.x2)
+ box.x2 = x;
+ y += h;
+ if (y < box.y2)
+ box.y2 = y;
+ if (box.x1 > box.x2)
+ box.x2 = box.x1;
+ if (box.y1 > box.y2)
+ box.y2 = box.y1;
+ REGION_RESET(pScreen, Rgn, &box);
+ REGION_INTERSECT(pScreen, Rgn, Rgn, &pWin->winSize);
+}
+
+WindowPtr
+RealChildHead(register WindowPtr pWin)
+{
+ if (!pWin->parent &&
+ (screenIsSaved == SCREEN_SAVER_ON) &&
+ (HasSaverWindow (pWin->drawable.pScreen->myNum)))
+ return (pWin->firstChild);
+ else
+ return (NullWindow);
+}
+
+/*****
+ * CreateWindow
+ * Makes a window in response to client request
+ *****/
+
+WindowPtr
+CreateWindow(Window wid, register WindowPtr pParent, int x, int y, unsigned w,
+ unsigned h, unsigned bw, unsigned class, register Mask vmask, XID *vlist,
+ int depth, ClientPtr client, VisualID visual, int *error)
+{
+ register WindowPtr pWin;
+ WindowPtr pHead;
+ register ScreenPtr pScreen;
+ xEvent event;
+ int idepth, ivisual;
+ Bool fOK;
+ DepthPtr pDepth;
+ PixmapFormatRec *format;
+ register WindowOptPtr ancwopt;
+
+ if (class == CopyFromParent)
+ class = pParent->drawable.class;
+
+ if ((class != InputOutput) && (class != InputOnly))
+ {
+ *error = BadValue;
+ client->errorValue = class;
+ return NullWindow;
+ }
+
+ if ((class != InputOnly) && (pParent->drawable.class == InputOnly))
+ {
+ *error = BadMatch;
+ return NullWindow;
+ }
+
+ if ((class == InputOnly) && ((bw != 0) || (depth != 0)))
+ {
+ *error = BadMatch;
+ return NullWindow;
+ }
+
+ pScreen = pParent->drawable.pScreen;
+ if ((class == InputOutput) && (depth == 0))
+ depth = pParent->drawable.depth;
+ ancwopt = pParent->optional;
+ if (!ancwopt)
+ ancwopt = FindWindowWithOptional(pParent)->optional;
+ if (visual == CopyFromParent) {
+#ifdef XAPPGROUP
+ VisualID ag_visual;
+
+ if (client->appgroup && !pParent->parent &&
+ (ag_visual = XagRootVisual (client)))
+ visual = ag_visual;
+ else
+#endif
+ visual = ancwopt->visual;
+ }
+
+ /* Find out if the depth and visual are acceptable for this Screen */
+ if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth))
+ {
+ fOK = FALSE;
+ for(idepth = 0; idepth < pScreen->numDepths; idepth++)
+ {
+ pDepth = (DepthPtr) &pScreen->allowedDepths[idepth];
+ if ((depth == pDepth->depth) || (depth == 0))
+ {
+ for (ivisual = 0; ivisual < pDepth->numVids; ivisual++)
+ {
+ if (visual == pDepth->vids[ivisual])
+ {
+ fOK = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ if (fOK == FALSE)
+ {
+ *error = BadMatch;
+ return NullWindow;
+ }
+ }
+
+ if (((vmask & (CWBorderPixmap | CWBorderPixel)) == 0) &&
+ (class != InputOnly) &&
+ (depth != pParent->drawable.depth))
+ {
+ *error = BadMatch;
+ return NullWindow;
+ }
+
+ if (((vmask & CWColormap) == 0) &&
+ (class != InputOnly) &&
+ ((visual != ancwopt->visual) || (ancwopt->colormap == None)))
+ {
+ *error = BadMatch;
+ return NullWindow;
+ }
+
+ pWin = AllocateWindow(pScreen);
+ if (!pWin)
+ {
+ *error = BadAlloc;
+ return NullWindow;
+ }
+ pWin->drawable = pParent->drawable;
+ pWin->drawable.depth = depth;
+ if (depth == pParent->drawable.depth)
+ pWin->drawable.bitsPerPixel = pParent->drawable.bitsPerPixel;
+ else
+ {
+ for (format = screenInfo.formats; format->depth != depth; format++)
+ ;
+ pWin->drawable.bitsPerPixel = format->bitsPerPixel;
+ }
+ if (class == InputOnly)
+ pWin->drawable.type = (short) UNDRAWABLE_WINDOW;
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+ pWin->drawable.id = wid;
+ pWin->drawable.class = class;
+
+ pWin->parent = pParent;
+ SetWindowToDefaults(pWin);
+
+ if (visual != ancwopt->visual)
+ {
+ if (!MakeWindowOptional (pWin))
+ {
+ xfree (pWin);
+ *error = BadAlloc;
+ return NullWindow;
+ }
+ pWin->optional->visual = visual;
+ pWin->optional->colormap = None;
+ }
+
+ pWin->borderWidth = bw;
+#ifdef XCSECURITY
+ /* can't let untrusted clients have background None windows;
+ * they make it too easy to steal window contents
+ */
+ if (client->trustLevel != XSecurityClientTrusted)
+ {
+ pWin->backgroundState = BackgroundPixel;
+ pWin->background.pixel = 0;
+ }
+ else
+#endif
+ pWin->backgroundState = None;
+
+ pWin->borderIsPixel = pParent->borderIsPixel;
+ pWin->border = pParent->border;
+ if (pWin->borderIsPixel == FALSE)
+ pWin->border.pixmap->refcnt++;
+
+ pWin->origin.x = x + (int)bw;
+ pWin->origin.y = y + (int)bw;
+ pWin->drawable.width = w;
+ pWin->drawable.height = h;
+ pWin->drawable.x = pParent->drawable.x + x + (int)bw;
+ pWin->drawable.y = pParent->drawable.y + y + (int)bw;
+
+ /* set up clip list correctly for unobscured WindowPtr */
+ REGION_NULL(pScreen, &pWin->clipList);
+ REGION_NULL(pScreen, &pWin->borderClip);
+ REGION_NULL(pScreen, &pWin->winSize);
+ REGION_NULL(pScreen, &pWin->borderSize);
+
+ pHead = RealChildHead(pParent);
+ if (pHead)
+ {
+ pWin->nextSib = pHead->nextSib;
+ if (pHead->nextSib)
+ pHead->nextSib->prevSib = pWin;
+ else
+ pParent->lastChild = pWin;
+ pHead->nextSib = pWin;
+ pWin->prevSib = pHead;
+ }
+ else
+ {
+ pWin->nextSib = pParent->firstChild;
+ if (pParent->firstChild)
+ pParent->firstChild->prevSib = pWin;
+ else
+ pParent->lastChild = pWin;
+ pParent->firstChild = pWin;
+ }
+
+ SetWinSize (pWin);
+ SetBorderSize (pWin);
+
+ /* We SHOULD check for an error value here XXX */
+ if (!(*pScreen->CreateWindow)(pWin))
+ {
+ *error = BadAlloc;
+ DeleteWindow(pWin, None);
+ return NullWindow;
+ }
+ /* We SHOULD check for an error value here XXX */
+ (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
+
+ if (!(vmask & CWEventMask))
+ RecalculateDeliverableEvents(pWin);
+
+ if (vmask)
+ *error = ChangeWindowAttributes(pWin, vmask, vlist, wClient (pWin));
+ else
+ *error = Success;
+
+ if (*error != Success)
+ {
+ DeleteWindow(pWin, None);
+ return NullWindow;
+ }
+ if (!(vmask & CWBackingStore) && (defaultBackingStore != NotUseful))
+ {
+ XID value = defaultBackingStore;
+ (void)ChangeWindowAttributes(pWin, CWBackingStore, &value, wClient (pWin));
+ pWin->forcedBS = TRUE;
+ }
+
+ if (SubSend(pParent))
+ {
+ event.u.u.type = CreateNotify;
+ event.u.createNotify.window = wid;
+ event.u.createNotify.parent = pParent->drawable.id;
+ event.u.createNotify.x = x;
+ event.u.createNotify.y = y;
+ event.u.createNotify.width = w;
+ event.u.createNotify.height = h;
+ event.u.createNotify.borderWidth = bw;
+ event.u.createNotify.override = pWin->overrideRedirect;
+ DeliverEvents(pParent, &event, 1, NullWindow);
+ }
+ return pWin;
+}
+
+static void
+FreeWindowResources(register WindowPtr pWin)
+{
+ register ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ DeleteWindowFromAnySaveSet(pWin);
+ DeleteWindowFromAnySelections(pWin);
+ DeleteWindowFromAnyEvents(pWin, TRUE);
+ REGION_UNINIT(pScreen, &pWin->clipList);
+ REGION_UNINIT(pScreen, &pWin->winSize);
+ REGION_UNINIT(pScreen, &pWin->borderClip);
+ REGION_UNINIT(pScreen, &pWin->borderSize);
+#ifdef SHAPE
+ if (wBoundingShape (pWin))
+ REGION_DESTROY(pScreen, wBoundingShape (pWin));
+ if (wClipShape (pWin))
+ REGION_DESTROY(pScreen, wClipShape (pWin));
+ if (wInputShape (pWin))
+ REGION_DESTROY(pScreen, wInputShape (pWin));
+#endif
+ if (pWin->borderIsPixel == FALSE)
+ (*pScreen->DestroyPixmap)(pWin->border.pixmap);
+ if (pWin->backgroundState == BackgroundPixmap)
+ (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+
+ DeleteAllWindowProperties(pWin);
+ /* We SHOULD check for an error value here XXX */
+ (*pScreen->DestroyWindow)(pWin);
+ DisposeWindowOptional (pWin);
+}
+
+static void
+CrushTree(WindowPtr pWin)
+{
+ register WindowPtr pChild, pSib, pParent;
+ UnrealizeWindowProcPtr UnrealizeWindow;
+ xEvent event;
+
+ if (!(pChild = pWin->firstChild))
+ return;
+ UnrealizeWindow = pWin->drawable.pScreen->UnrealizeWindow;
+ while (1)
+ {
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ while (1)
+ {
+ pParent = pChild->parent;
+ if (SubStrSend(pChild, pParent))
+ {
+ event.u.u.type = DestroyNotify;
+ event.u.destroyNotify.window = pChild->drawable.id;
+ DeliverEvents(pChild, &event, 1, NullWindow);
+ }
+ FreeResource(pChild->drawable.id, RT_WINDOW);
+ pSib = pChild->nextSib;
+#ifdef DO_SAVE_UNDERS
+ if (pChild->saveUnder && pChild->viewable)
+ deltaSaveUndersViewable--;
+#endif
+ pChild->viewable = FALSE;
+ if (pChild->realized)
+ {
+ pChild->realized = FALSE;
+ (*UnrealizeWindow)(pChild);
+ }
+ FreeWindowResources(pChild);
+ xfree(pChild);
+ if ( (pChild = pSib) )
+ break;
+ pChild = pParent;
+ pChild->firstChild = NullWindow;
+ pChild->lastChild = NullWindow;
+ if (pChild == pWin)
+ return;
+ }
+ }
+}
+
+/*****
+ * DeleteWindow
+ * Deletes child of window then window itself
+ * If wid is None, don't send any events
+ *****/
+
+int
+DeleteWindow(pointer value, XID wid)
+ {
+ register WindowPtr pParent;
+ register WindowPtr pWin = (WindowPtr)value;
+ xEvent event;
+
+ UnmapWindow(pWin, FALSE);
+
+ CrushTree(pWin);
+
+ pParent = pWin->parent;
+ if (wid && pParent && SubStrSend(pWin, pParent))
+ {
+ event.u.u.type = DestroyNotify;
+ event.u.destroyNotify.window = pWin->drawable.id;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ }
+
+ FreeWindowResources(pWin);
+ if (pParent)
+ {
+ if (pParent->firstChild == pWin)
+ pParent->firstChild = pWin->nextSib;
+ if (pParent->lastChild == pWin)
+ pParent->lastChild = pWin->prevSib;
+ if (pWin->nextSib)
+ pWin->nextSib->prevSib = pWin->prevSib;
+ if (pWin->prevSib)
+ pWin->prevSib->nextSib = pWin->nextSib;
+ }
+
+ if (pWin -> optional &&
+ pWin -> optional -> colormap &&
+ pWin -> parent)
+ {
+ nxagentSetInstalledColormapWindows(pWin -> drawable.pScreen);
+ }
+
+ xfree(pWin);
+ return Success;
+}
+
+void
+DestroySubwindows(register WindowPtr pWin, ClientPtr client)
+{
+ /* XXX
+ * The protocol is quite clear that each window should be
+ * destroyed in turn, however, unmapping all of the first
+ * eliminates most of the calls to ValidateTree. So,
+ * this implementation is incorrect in that all of the
+ * UnmapNotifies occur before all of the DestroyNotifies.
+ * If you care, simply delete the call to UnmapSubwindows.
+ */
+ UnmapSubwindows(pWin);
+ while (pWin->lastChild)
+ FreeResource(pWin->lastChild->drawable.id, RT_NONE);
+}
+
+#define DeviceEventMasks (KeyPressMask | KeyReleaseMask | ButtonPressMask | \
+ ButtonReleaseMask | PointerMotionMask)
+
+/*****
+ * ChangeWindowAttributes
+ *
+ * The value-mask specifies which attributes are to be changed; the
+ * value-list contains one value for each one bit in the mask, from least
+ * to most significant bit in the mask.
+ *****/
+
+int
+ChangeWindowAttributes(register WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
+{
+ register Mask index2;
+ register XID *pVlist;
+ PixmapPtr pPixmap;
+ Pixmap pixID;
+ CursorPtr pCursor, pOldCursor;
+ Cursor cursorID;
+ WindowPtr pChild;
+ Colormap cmap;
+ ColormapPtr pCmap;
+ xEvent xE;
+ int result;
+ register ScreenPtr pScreen;
+ Mask vmaskCopy = 0;
+ register Mask tmask;
+ unsigned int val;
+ int error;
+ Bool checkOptional = FALSE;
+ Bool borderRelative = FALSE;
+ WindowPtr pLayerWin;
+
+ if ((pWin->drawable.class == InputOnly) && (vmask & (~INPUTONLY_LEGAL_MASK)))
+ return BadMatch;
+
+ error = Success;
+ pScreen = pWin->drawable.pScreen;
+ pVlist = vlist;
+ tmask = vmask;
+ while (tmask)
+ {
+ index2 = (Mask) lowbit (tmask);
+ tmask &= ~index2;
+ switch (index2)
+ {
+ case CWBackPixmap:
+ pixID = (Pixmap )*pVlist;
+ pVlist++;
+ if (pWin->backgroundState == ParentRelative)
+ borderRelative = TRUE;
+ if (pixID == None)
+ {
+#ifdef XCSECURITY
+ /* can't let untrusted clients have background None windows */
+ if (client->trustLevel == XSecurityClientTrusted)
+ {
+#endif
+ if (pWin->backgroundState == BackgroundPixmap)
+ (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+ if (!pWin->parent)
+ MakeRootTile(pWin);
+ else
+ pWin->backgroundState = None;
+#ifdef XCSECURITY
+ }
+ else
+ { /* didn't change the background to None, so don't tell ddx */
+ index2 = 0;
+ }
+#endif
+ }
+ else if (pixID == ParentRelative)
+ {
+ if (pWin->parent &&
+ pWin->drawable.depth != pWin->parent->drawable.depth)
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ if (pWin->backgroundState == BackgroundPixmap)
+ (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+ if (!pWin->parent)
+ MakeRootTile(pWin);
+ else
+ pWin->backgroundState = ParentRelative;
+ borderRelative = TRUE;
+ /* Note that the parent's backgroundTile's refcnt is NOT
+ * incremented. */
+ }
+ else
+ {
+ pPixmap = (PixmapPtr)SecurityLookupIDByType(client, pixID,
+ RT_PIXMAP, SecurityReadAccess);
+ if (pPixmap != (PixmapPtr) NULL)
+ {
+ if ((pPixmap->drawable.depth != pWin->drawable.depth) ||
+ (pPixmap->drawable.pScreen != pScreen))
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ if (pWin->backgroundState == BackgroundPixmap)
+ (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+ pWin->backgroundState = BackgroundPixmap;
+ pWin->background.pixmap = pPixmap;
+ pPixmap->refcnt++;
+ }
+ else
+ {
+ error = BadPixmap;
+ client->errorValue = pixID;
+ goto PatchUp;
+ }
+ }
+ break;
+ case CWBackPixel:
+ if (pWin->backgroundState == ParentRelative)
+ borderRelative = TRUE;
+ if (pWin->backgroundState == BackgroundPixmap)
+ (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+ pWin->backgroundState = BackgroundPixel;
+ pWin->background.pixel = (CARD32 ) *pVlist;
+ /* background pixel overrides background pixmap,
+ so don't let the ddx layer see both bits */
+ vmaskCopy &= ~CWBackPixmap;
+ pVlist++;
+ break;
+ case CWBorderPixmap:
+ pixID = (Pixmap ) *pVlist;
+ pVlist++;
+ if (pixID == CopyFromParent)
+ {
+ if (!pWin->parent ||
+ (pWin->drawable.depth != pWin->parent->drawable.depth))
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ if (pWin->borderIsPixel == FALSE)
+ (*pScreen->DestroyPixmap)(pWin->border.pixmap);
+ pWin->border = pWin->parent->border;
+ if ((pWin->borderIsPixel = pWin->parent->borderIsPixel) == TRUE)
+ {
+ index2 = CWBorderPixel;
+ }
+ else
+ {
+ pWin->parent->border.pixmap->refcnt++;
+ }
+ }
+ else
+ {
+ pPixmap = (PixmapPtr)SecurityLookupIDByType(client, pixID,
+ RT_PIXMAP, SecurityReadAccess);
+ if (pPixmap)
+ {
+ if ((pPixmap->drawable.depth != pWin->drawable.depth) ||
+ (pPixmap->drawable.pScreen != pScreen))
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ if (pWin->borderIsPixel == FALSE)
+ (*pScreen->DestroyPixmap)(pWin->border.pixmap);
+ pWin->borderIsPixel = FALSE;
+ pWin->border.pixmap = pPixmap;
+ pPixmap->refcnt++;
+ }
+ else
+ {
+ error = BadPixmap;
+ client->errorValue = pixID;
+ goto PatchUp;
+ }
+ }
+ break;
+ case CWBorderPixel:
+ if (pWin->borderIsPixel == FALSE)
+ (*pScreen->DestroyPixmap)(pWin->border.pixmap);
+ pWin->borderIsPixel = TRUE;
+ pWin->border.pixel = (CARD32) *pVlist;
+ /* border pixel overrides border pixmap,
+ so don't let the ddx layer see both bits */
+ vmaskCopy &= ~CWBorderPixmap;
+ pVlist++;
+ break;
+ case CWBitGravity:
+ val = (CARD8 )*pVlist;
+ pVlist++;
+ if (val > StaticGravity)
+ {
+ error = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ pWin->bitGravity = val;
+ break;
+ case CWWinGravity:
+ val = (CARD8 )*pVlist;
+ pVlist++;
+ if (val > StaticGravity)
+ {
+ error = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ pWin->winGravity = val;
+ break;
+ case CWBackingStore:
+ val = (CARD8 )*pVlist;
+ pVlist++;
+ if ((val != NotUseful) && (val != WhenMapped) && (val != Always))
+ {
+ error = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ pWin->backingStore = val;
+
+ #ifdef TEST
+ fprintf(stderr, "ChangeWindowAttributes: Changed backing store value to %d for window at %p.\n",
+ val, (void*)pWin);
+ #endif
+
+ pWin->forcedBS = FALSE;
+ break;
+ case CWBackingPlanes:
+ if (pWin->optional || ((CARD32)*pVlist != (CARD32)~0L)) {
+ if (!pWin->optional && !MakeWindowOptional (pWin))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ pWin->optional->backingBitPlanes = (CARD32) *pVlist;
+ if ((CARD32)*pVlist == (CARD32)~0L)
+ checkOptional = TRUE;
+ }
+ pVlist++;
+ break;
+ case CWBackingPixel:
+ if (pWin->optional || (CARD32) *pVlist) {
+ if (!pWin->optional && !MakeWindowOptional (pWin))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ pWin->optional->backingPixel = (CARD32) *pVlist;
+ if (!*pVlist)
+ checkOptional = TRUE;
+ }
+ pVlist++;
+ break;
+ case CWSaveUnder:
+ val = (BOOL) *pVlist;
+ pVlist++;
+ if ((val != xTrue) && (val != xFalse))
+ {
+ error = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+#ifdef DO_SAVE_UNDERS
+ if (pWin->parent && (pWin->saveUnder != val) && (pWin->viewable) &&
+ DO_SAVE_UNDERS(pWin))
+ {
+ /*
+ * Re-check all siblings and inferiors for obscurity or
+ * exposition (hee hee).
+ */
+ if (pWin->saveUnder)
+ deltaSaveUndersViewable--;
+ else
+ deltaSaveUndersViewable++;
+ pWin->saveUnder = val;
+
+ if (pWin->firstChild)
+ {
+ pLayerWin = (*pScreen->GetLayerWindow)(pWin);
+ if ((*pScreen->ChangeSaveUnder)(pLayerWin->parent, pWin->nextSib))
+ (*pScreen->PostChangeSaveUnder)(pLayerWin->parent,
+ pWin->nextSib);
+ }
+ else
+ {
+ if ((*pScreen->ChangeSaveUnder)(pWin, pWin->nextSib))
+ (*pScreen->PostChangeSaveUnder)(pWin,
+ pWin->nextSib);
+ }
+ }
+ else
+ {
+ /* If we're changing the saveUnder attribute of the root
+ * window, all we do is set pWin->saveUnder so that
+ * GetWindowAttributes returns the right value. We don't
+ * do the "normal" save-under processing (as above).
+ * Hope that doesn't cause any problems.
+ */
+ pWin->saveUnder = val;
+ }
+#else
+ pWin->saveUnder = val;
+#endif /* DO_SAVE_UNDERS */
+ break;
+ case CWEventMask:
+ /*
+ * TODO: Some applications like java bean shell
+ * don' t work if they cannot monitor the root
+ * window for Structure Redirect events. However
+ * this doesn't seem to be the best solution, since
+ * also an X server with a window manager running,
+ * doesn't allow to monitor for those events, but
+ * the java bean shell works flawlessy on this
+ * server.
+ *
+ * if (nxagentCheckIllegalRootMonitoring(pWin, (Mask)*pVlist))
+ * {
+ * return BadAccess;
+ * }
+ */
+
+ result = EventSelectForWindow(pWin, client, (Mask )*pVlist);
+ if (result)
+ {
+ error = result;
+ goto PatchUp;
+ }
+ pVlist++;
+ break;
+ case CWDontPropagate:
+ result = EventSuppressForWindow(pWin, client, (Mask )*pVlist,
+ &checkOptional);
+ if (result)
+ {
+ error = result;
+ goto PatchUp;
+ }
+ pVlist++;
+ break;
+ case CWOverrideRedirect:
+ val = (BOOL ) *pVlist;
+ pVlist++;
+ if ((val != xTrue) && (val != xFalse))
+ {
+ error = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ pWin->overrideRedirect = val;
+ break;
+ case CWColormap:
+ cmap = (Colormap) *pVlist;
+ pVlist++;
+ if (cmap == CopyFromParent)
+ {
+#ifdef XAPPGROUP
+ Colormap ag_colormap;
+ ClientPtr win_owner;
+
+ /*
+ * win_owner == client for CreateWindow, other clients
+ * can ChangeWindowAttributes
+ */
+ win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+
+ if ( win_owner && win_owner->appgroup &&
+ !pWin->parent->parent &&
+ (ag_colormap = XagDefaultColormap (win_owner)))
+ cmap = ag_colormap;
+ else
+#endif
+ if (pWin->parent &&
+ (!pWin->optional ||
+ pWin->optional->visual == wVisual (pWin->parent)))
+ {
+ cmap = wColormap (pWin->parent);
+ }
+ else
+ cmap = None;
+ }
+ if (cmap == None)
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ pCmap = (ColormapPtr)SecurityLookupIDByType(client, cmap,
+ RT_COLORMAP, SecurityReadAccess);
+ if (!pCmap)
+ {
+ error = BadColor;
+ client->errorValue = cmap;
+ goto PatchUp;
+ }
+ if (pCmap->pVisual->vid != wVisual (pWin) ||
+ pCmap->pScreen != pScreen)
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ if (cmap != wColormap (pWin))
+ {
+ if (!pWin->optional)
+ {
+ if (!MakeWindowOptional (pWin))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ }
+ else if (pWin->parent && cmap == wColormap (pWin->parent))
+ checkOptional = TRUE;
+
+ /*
+ * propagate the original colormap to any children
+ * inheriting it
+ */
+
+ for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+ {
+ if (!pChild->optional && !MakeWindowOptional (pChild))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ }
+
+ pWin->optional->colormap = cmap;
+
+ /*
+ * check on any children now matching the new colormap
+ */
+
+ for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+ {
+ if (pChild->optional->colormap == cmap)
+ CheckWindowOptionalNeed (pChild);
+ }
+
+ xE.u.u.type = ColormapNotify;
+ xE.u.colormap.window = pWin->drawable.id;
+ xE.u.colormap.colormap = cmap;
+ xE.u.colormap.new = xTrue;
+ xE.u.colormap.state = IsMapInstalled(cmap, pWin);
+ DeliverEvents(pWin, &xE, 1, NullWindow);
+ }
+ break;
+ case CWCursor:
+ cursorID = (Cursor ) *pVlist;
+ pVlist++;
+ /*
+ * install the new
+ */
+ if ( cursorID == None)
+ {
+ if (pWin == WindowTable[pWin->drawable.pScreen->myNum])
+ pCursor = rootCursor;
+ else
+ pCursor = (CursorPtr) None;
+ }
+ else
+ {
+ pCursor = (CursorPtr)SecurityLookupIDByType(client, cursorID,
+ RT_CURSOR, SecurityReadAccess);
+ if (!pCursor)
+ {
+ error = BadCursor;
+ client->errorValue = cursorID;
+ goto PatchUp;
+ }
+ }
+
+ if (pCursor != wCursor (pWin))
+ {
+ /*
+ * patch up child windows so they don't lose cursors.
+ */
+
+ for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+ {
+ if (!pChild->optional && !pChild->cursorIsNone &&
+ !MakeWindowOptional (pChild))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ }
+
+ pOldCursor = 0;
+ if (pCursor == (CursorPtr) None)
+ {
+ pWin->cursorIsNone = TRUE;
+ if (pWin->optional)
+ {
+ pOldCursor = pWin->optional->cursor;
+ pWin->optional->cursor = (CursorPtr) None;
+ checkOptional = TRUE;
+ }
+ } else {
+ if (!pWin->optional)
+ {
+ if (!MakeWindowOptional (pWin))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ }
+ else if (pWin->parent && pCursor == wCursor (pWin->parent))
+ checkOptional = TRUE;
+ pOldCursor = pWin->optional->cursor;
+ pWin->optional->cursor = pCursor;
+ pCursor->refcnt++;
+ pWin->cursorIsNone = FALSE;
+ /*
+ * check on any children now matching the new cursor
+ */
+
+ for (pChild=pWin->firstChild; pChild; pChild=pChild->nextSib)
+ {
+ if (pChild->optional &&
+ (pChild->optional->cursor == pCursor))
+ CheckWindowOptionalNeed (pChild);
+ }
+ }
+
+ if (pWin->realized)
+ WindowHasNewCursor( pWin);
+
+ /* Can't free cursor until here - old cursor
+ * is needed in WindowHasNewCursor
+ */
+ if (pOldCursor)
+ FreeCursor (pOldCursor, (Cursor)0);
+ }
+ break;
+ default:
+ error = BadValue;
+ client->errorValue = vmask;
+ goto PatchUp;
+ }
+ vmaskCopy |= index2;
+ }
+PatchUp:
+ if (checkOptional)
+ CheckWindowOptionalNeed (pWin);
+
+ /* We SHOULD check for an error value here XXX */
+ (*pScreen->ChangeWindowAttributes)(pWin, vmaskCopy);
+
+ /*
+ If the border contents have changed, redraw the border.
+ Note that this has to be done AFTER pScreen->ChangeWindowAttributes
+ for the tile to be rotated, and the correct function selected.
+ */
+ if (((vmaskCopy & (CWBorderPixel | CWBorderPixmap)) || borderRelative)
+ && pWin->viewable && HasBorder (pWin))
+ {
+ RegionRec exposed;
+
+ REGION_NULL(pScreen, &exposed);
+ REGION_SUBTRACT(pScreen, &exposed, &pWin->borderClip, &pWin->winSize);
+ (*pWin->drawable.pScreen->PaintWindowBorder)(pWin, &exposed, PW_BORDER);
+ REGION_UNINIT(pScreen, &exposed);
+ }
+ return error;
+}
+
+
+/*****
+ * GetWindowAttributes
+ * Notice that this is different than ChangeWindowAttributes
+ *****/
+
+void
+GetWindowAttributes(register WindowPtr pWin, ClientPtr client, xGetWindowAttributesReply *wa)
+{
+ wa->type = X_Reply;
+ wa->bitGravity = pWin->bitGravity;
+ wa->winGravity = pWin->winGravity;
+ if (pWin->forcedBS && pWin->backingStore != Always)
+ wa->backingStore = NotUseful;
+ else
+ wa->backingStore = pWin->backingStore;
+ wa->length = (sizeof(xGetWindowAttributesReply) -
+ sizeof(xGenericReply)) >> 2;
+ wa->sequenceNumber = client->sequence;
+ wa->backingBitPlanes = wBackingBitPlanes (pWin);
+ wa->backingPixel = wBackingPixel (pWin);
+ wa->saveUnder = (BOOL)pWin->saveUnder;
+ wa->override = pWin->overrideRedirect;
+ if (!pWin->mapped)
+ wa->mapState = IsUnmapped;
+ else if (pWin->realized)
+ wa->mapState = IsViewable;
+ else
+ wa->mapState = IsUnviewable;
+
+ wa->colormap = wColormap (pWin);
+ wa->mapInstalled = (wa->colormap == None) ? xFalse
+ : IsMapInstalled(wa->colormap, pWin);
+
+ wa->yourEventMask = EventMaskForClient(pWin, client);
+ wa->allEventMasks = pWin->eventMask | wOtherEventMasks (pWin);
+ wa->doNotPropagateMask = wDontPropagateMask (pWin);
+ wa->class = pWin->drawable.class;
+ wa->visualID = wVisual (pWin);
+}
+
+
+WindowPtr
+MoveWindowInStack(register WindowPtr pWin, register WindowPtr pNextSib)
+{
+ register WindowPtr pParent = pWin->parent;
+ WindowPtr pFirstChange = pWin; /* highest window where list changes */
+
+ if (pWin->nextSib != pNextSib)
+ {
+ WindowPtr pOldNextSib = pWin->nextSib;
+
+ if (!pNextSib) /* move to bottom */
+ {
+ if (pParent->firstChild == pWin)
+ pParent->firstChild = pWin->nextSib;
+ /* if (pWin->nextSib) */ /* is always True: pNextSib == NULL
+ * and pWin->nextSib != pNextSib
+ * therefore pWin->nextSib != NULL */
+ pFirstChange = pWin->nextSib;
+ pWin->nextSib->prevSib = pWin->prevSib;
+ if (pWin->prevSib)
+ pWin->prevSib->nextSib = pWin->nextSib;
+ pParent->lastChild->nextSib = pWin;
+ pWin->prevSib = pParent->lastChild;
+ pWin->nextSib = NullWindow;
+ pParent->lastChild = pWin;
+ }
+ else if (pParent->firstChild == pNextSib) /* move to top */
+ {
+ pFirstChange = pWin;
+ if (pParent->lastChild == pWin)
+ pParent->lastChild = pWin->prevSib;
+ if (pWin->nextSib)
+ pWin->nextSib->prevSib = pWin->prevSib;
+ if (pWin->prevSib)
+ pWin->prevSib->nextSib = pWin->nextSib;
+ pWin->nextSib = pParent->firstChild;
+ pWin->prevSib = (WindowPtr ) NULL;
+ pNextSib->prevSib = pWin;
+ pParent->firstChild = pWin;
+ }
+ else /* move in middle of list */
+ {
+ WindowPtr pOldNext = pWin->nextSib;
+
+ pFirstChange = NullWindow;
+ if (pParent->firstChild == pWin)
+ pFirstChange = pParent->firstChild = pWin->nextSib;
+ if (pParent->lastChild == pWin) {
+ pFirstChange = pWin;
+ pParent->lastChild = pWin->prevSib;
+ }
+ if (pWin->nextSib)
+ pWin->nextSib->prevSib = pWin->prevSib;
+ if (pWin->prevSib)
+ pWin->prevSib->nextSib = pWin->nextSib;
+ pWin->nextSib = pNextSib;
+ pWin->prevSib = pNextSib->prevSib;
+ if (pNextSib->prevSib)
+ pNextSib->prevSib->nextSib = pWin;
+ pNextSib->prevSib = pWin;
+ if (!pFirstChange) { /* do we know it yet? */
+ pFirstChange = pParent->firstChild; /* no, search from top */
+ while ((pFirstChange != pWin) && (pFirstChange != pOldNext))
+ pFirstChange = pFirstChange->nextSib;
+ }
+ }
+ if(pWin->drawable.pScreen->RestackWindow)
+ (*pWin->drawable.pScreen->RestackWindow)(pWin, pOldNextSib);
+ }
+
+#ifdef ROOTLESS
+ /*
+ * In rootless mode we can't optimize away window restacks.
+ * There may be non-X windows around, so even if the window
+ * is in the correct position from X's point of view,
+ * the underlying window system may want to reorder it.
+ */
+ else if (pWin->drawable.pScreen->RestackWindow)
+ (*pWin->drawable.pScreen->RestackWindow)(pWin, pWin->nextSib);
+#endif
+
+ return( pFirstChange );
+}
+
+RegionPtr
+CreateUnclippedWinSize (register WindowPtr pWin)
+{
+ RegionPtr pRgn;
+ BoxRec box;
+
+ box.x1 = pWin->drawable.x;
+ box.y1 = pWin->drawable.y;
+ box.x2 = pWin->drawable.x + (int) pWin->drawable.width;
+ box.y2 = pWin->drawable.y + (int) pWin->drawable.height;
+ pRgn = REGION_CREATE(pWin->drawable.pScreen, &box, 1);
+#ifdef SHAPE
+ if (wBoundingShape (pWin) || wClipShape (pWin)) {
+#ifndef NXAGENT_SERVER
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+#endif /* NXAGENT_SERVER */
+ REGION_TRANSLATE(pScreen, pRgn, - pWin->drawable.x,
+ - pWin->drawable.y);
+ if (wBoundingShape (pWin))
+ REGION_INTERSECT(pScreen, pRgn, pRgn, wBoundingShape (pWin));
+ if (wClipShape (pWin))
+ REGION_INTERSECT(pScreen, pRgn, pRgn, wClipShape (pWin));
+ REGION_TRANSLATE(pScreen, pRgn, pWin->drawable.x, pWin->drawable.y);
+ }
+#endif
+ return pRgn;
+}
+
+void
+SetWinSize (register WindowPtr pWin)
+{
+#ifdef COMPOSITE
+ if (pWin->redirectDraw)
+ {
+ BoxRec box;
+
+ box.x1 = pWin->drawable.x;
+ box.y1 = pWin->drawable.y;
+ box.x2 = pWin->drawable.x + pWin->drawable.width;
+ box.y2 = pWin->drawable.y + pWin->drawable.height;
+ REGION_RESET (pScreen, &pWin->winSize, &box);
+ }
+ else
+#endif
+ ClippedRegionFromBox(pWin->parent, &pWin->winSize,
+ pWin->drawable.x, pWin->drawable.y,
+ (int)pWin->drawable.width,
+ (int)pWin->drawable.height);
+#ifdef SHAPE
+ if (wBoundingShape (pWin) || wClipShape (pWin)) {
+#ifndef NXAGENT_SERVER
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+#endif /* NXAGENT_SERVER */
+ REGION_TRANSLATE(pScreen, &pWin->winSize, - pWin->drawable.x,
+ - pWin->drawable.y);
+ if (wBoundingShape (pWin))
+ REGION_INTERSECT(pScreen, &pWin->winSize, &pWin->winSize,
+ wBoundingShape (pWin));
+ if (wClipShape (pWin))
+ REGION_INTERSECT(pScreen, &pWin->winSize, &pWin->winSize,
+ wClipShape (pWin));
+ REGION_TRANSLATE(pScreen, &pWin->winSize, pWin->drawable.x,
+ pWin->drawable.y);
+ }
+#endif
+}
+
+void
+SetBorderSize (register WindowPtr pWin)
+{
+ int bw;
+
+ if (HasBorder (pWin)) {
+ bw = wBorderWidth (pWin);
+#ifdef COMPOSITE
+ if (pWin->redirectDraw)
+ {
+ BoxRec box;
+
+ box.x1 = pWin->drawable.x - bw;
+ box.y1 = pWin->drawable.y - bw;
+ box.x2 = pWin->drawable.x + pWin->drawable.width + bw;
+ box.y2 = pWin->drawable.y + pWin->drawable.height + bw;
+ REGION_RESET (pScreen, &pWin->borderSize, &box);
+ }
+ else
+#endif
+ ClippedRegionFromBox(pWin->parent, &pWin->borderSize,
+ pWin->drawable.x - bw, pWin->drawable.y - bw,
+ (int)(pWin->drawable.width + (bw<<1)),
+ (int)(pWin->drawable.height + (bw<<1)));
+#ifdef SHAPE
+ if (wBoundingShape (pWin)) {
+#ifndef NXAGENT_SERVER
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+#endif /* NXAGENT_SERVER */
+ REGION_TRANSLATE(pScreen, &pWin->borderSize, - pWin->drawable.x,
+ - pWin->drawable.y);
+ REGION_INTERSECT(pScreen, &pWin->borderSize, &pWin->borderSize,
+ wBoundingShape (pWin));
+ REGION_TRANSLATE(pScreen, &pWin->borderSize, pWin->drawable.x,
+ pWin->drawable.y);
+ REGION_UNION(pScreen, &pWin->borderSize, &pWin->borderSize,
+ &pWin->winSize);
+ }
+#endif
+ } else {
+ REGION_COPY(pWin->drawable.pScreen, &pWin->borderSize,
+ &pWin->winSize);
+ }
+}
+
+/**
+ *
+ * \param x,y new window position
+ * \param oldx,oldy old window position
+ * \param destx,desty position relative to gravity
+ */
+
+void
+GravityTranslate (register int x, register int y, int oldx, int oldy,
+ int dw, int dh, unsigned gravity,
+ register int *destx, register int *desty)
+{
+ switch (gravity) {
+ case NorthGravity:
+ *destx = x + dw / 2;
+ *desty = y;
+ break;
+ case NorthEastGravity:
+ *destx = x + dw;
+ *desty = y;
+ break;
+ case WestGravity:
+ *destx = x;
+ *desty = y + dh / 2;
+ break;
+ case CenterGravity:
+ *destx = x + dw / 2;
+ *desty = y + dh / 2;
+ break;
+ case EastGravity:
+ *destx = x + dw;
+ *desty = y + dh / 2;
+ break;
+ case SouthWestGravity:
+ *destx = x;
+ *desty = y + dh;
+ break;
+ case SouthGravity:
+ *destx = x + dw / 2;
+ *desty = y + dh;
+ break;
+ case SouthEastGravity:
+ *destx = x + dw;
+ *desty = y + dh;
+ break;
+ case StaticGravity:
+ *destx = oldx;
+ *desty = oldy;
+ break;
+ default:
+ *destx = x;
+ *desty = y;
+ break;
+ }
+}
+
+/* XXX need to retile border on each window with ParentRelative origin */
+void
+ResizeChildrenWinSize(register WindowPtr pWin, int dx, int dy, int dw, int dh)
+{
+ register ScreenPtr pScreen;
+ register WindowPtr pSib, pChild;
+ Bool resized = (dw || dh);
+
+ pScreen = pWin->drawable.pScreen;
+
+ for (pSib = pWin->firstChild; pSib; pSib = pSib->nextSib)
+ {
+ if (resized && (pSib->winGravity > NorthWestGravity))
+ {
+ int cwsx, cwsy;
+
+ cwsx = pSib->origin.x;
+ cwsy = pSib->origin.y;
+ GravityTranslate (cwsx, cwsy, cwsx - dx, cwsy - dy, dw, dh,
+ pSib->winGravity, &cwsx, &cwsy);
+ if (cwsx != pSib->origin.x || cwsy != pSib->origin.y)
+ {
+ xEvent event;
+
+ event.u.u.type = GravityNotify;
+ event.u.gravity.window = pSib->drawable.id;
+ event.u.gravity.x = cwsx - wBorderWidth (pSib);
+ event.u.gravity.y = cwsy - wBorderWidth (pSib);
+ DeliverEvents (pSib, &event, 1, NullWindow);
+ pSib->origin.x = cwsx;
+ pSib->origin.y = cwsy;
+ }
+ }
+ pSib->drawable.x = pWin->drawable.x + pSib->origin.x;
+ pSib->drawable.y = pWin->drawable.y + pSib->origin.y;
+ SetWinSize (pSib);
+ SetBorderSize (pSib);
+
+ /*
+ * Don't force X to move children. It will position them
+ * according with gravity.
+ *
+ * (*pScreen->PositionWindow)(pSib, pSib->drawable.x, pSib->drawable.y);
+ */
+
+ /*
+ * Update pSib privates, as this window is moved by X.
+ */
+
+ nxagentAddConfiguredWindow(pSib, CW_Update);
+
+ if ( (pChild = pSib->firstChild) )
+ {
+ while (1)
+ {
+ pChild->drawable.x = pChild->parent->drawable.x +
+ pChild->origin.x;
+ pChild->drawable.y = pChild->parent->drawable.y +
+ pChild->origin.y;
+ SetWinSize (pChild);
+ SetBorderSize (pChild);
+
+ (*pScreen->PositionWindow)(pChild, pChild->drawable.x,
+ pChild->drawable.y);
+
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ while (!pChild->nextSib && (pChild != pSib))
+ pChild = pChild->parent;
+ if (pChild == pSib)
+ break;
+ pChild = pChild->nextSib;
+ }
+ }
+ }
+}
+
+#define GET_INT16(m, f) \
+ if (m & mask) \
+ { \
+ f = (INT16) *pVlist;\
+ pVlist++; \
+ }
+#define GET_CARD16(m, f) \
+ if (m & mask) \
+ { \
+ f = (CARD16) *pVlist;\
+ pVlist++;\
+ }
+
+#define GET_CARD8(m, f) \
+ if (m & mask) \
+ { \
+ f = (CARD8) *pVlist;\
+ pVlist++;\
+ }
+
+#define ChangeMask ((Mask)(CWX | CWY | CWWidth | CWHeight))
+
+#define IllegalInputOnlyConfigureMask (CWBorderWidth)
+
+/*
+ * IsSiblingAboveMe
+ * returns Above if pSib above pMe in stack or Below otherwise
+ */
+
+static int
+IsSiblingAboveMe(
+ register WindowPtr pMe,
+ register WindowPtr pSib)
+{
+ register WindowPtr pWin;
+
+ pWin = pMe->parent->firstChild;
+ while (pWin)
+ {
+ if (pWin == pSib)
+ return(Above);
+ else if (pWin == pMe)
+ return(Below);
+ pWin = pWin->nextSib;
+ }
+ return(Below);
+}
+
+static BoxPtr
+WindowExtents(
+ register WindowPtr pWin,
+ register BoxPtr pBox)
+{
+ pBox->x1 = pWin->drawable.x - wBorderWidth (pWin);
+ pBox->y1 = pWin->drawable.y - wBorderWidth (pWin);
+ pBox->x2 = pWin->drawable.x + (int)pWin->drawable.width
+ + wBorderWidth (pWin);
+ pBox->y2 = pWin->drawable.y + (int)pWin->drawable.height
+ + wBorderWidth (pWin);
+ return(pBox);
+}
+
+#ifdef SHAPE
+#define IS_SHAPED(pWin) (wBoundingShape (pWin) != (RegionPtr) NULL)
+
+static RegionPtr
+MakeBoundingRegion (
+ register WindowPtr pWin,
+ BoxPtr pBox)
+{
+ RegionPtr pRgn;
+#ifndef NXAGENT_SERVER
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+#endif /* NXAGENT_SERVER */
+ pRgn = REGION_CREATE(pScreen, pBox, 1);
+ if (wBoundingShape (pWin)) {
+ REGION_TRANSLATE(pScreen, pRgn, -pWin->origin.x,
+ -pWin->origin.y);
+ REGION_INTERSECT(pScreen, pRgn, pRgn, wBoundingShape (pWin));
+ REGION_TRANSLATE(pScreen, pRgn, pWin->origin.x,
+ pWin->origin.y);
+ }
+ return pRgn;
+}
+
+static Bool
+ShapeOverlap (
+ WindowPtr pWin,
+ BoxPtr pWinBox,
+ WindowPtr pSib,
+ BoxPtr pSibBox)
+{
+ RegionPtr pWinRgn, pSibRgn;
+ register ScreenPtr pScreen;
+ Bool ret;
+
+ if (!IS_SHAPED(pWin) && !IS_SHAPED(pSib))
+ return TRUE;
+ pScreen = pWin->drawable.pScreen;
+ pWinRgn = MakeBoundingRegion (pWin, pWinBox);
+ pSibRgn = MakeBoundingRegion (pSib, pSibBox);
+ REGION_INTERSECT(pScreen, pWinRgn, pWinRgn, pSibRgn);
+ ret = REGION_NOTEMPTY(pScreen, pWinRgn);
+ REGION_DESTROY(pScreen, pWinRgn);
+ REGION_DESTROY(pScreen, pSibRgn);
+ return ret;
+}
+#endif
+
+static Bool
+AnyWindowOverlapsMe(
+ WindowPtr pWin,
+ WindowPtr pHead,
+ register BoxPtr box)
+{
+ register WindowPtr pSib;
+ BoxRec sboxrec;
+ register BoxPtr sbox;
+
+ for (pSib = pWin->prevSib; pSib != pHead; pSib = pSib->prevSib)
+ {
+ if (pSib->mapped)
+ {
+ sbox = WindowExtents(pSib, &sboxrec);
+ if (BOXES_OVERLAP(sbox, box)
+#ifdef SHAPE
+ && ShapeOverlap (pWin, box, pSib, sbox)
+#endif
+ )
+ return(TRUE);
+ }
+ }
+ return(FALSE);
+}
+
+static Bool
+IOverlapAnyWindow(
+ WindowPtr pWin,
+ register BoxPtr box)
+{
+ register WindowPtr pSib;
+ BoxRec sboxrec;
+ register BoxPtr sbox;
+
+ for (pSib = pWin->nextSib; pSib; pSib = pSib->nextSib)
+ {
+ if (pSib->mapped)
+ {
+ sbox = WindowExtents(pSib, &sboxrec);
+ if (BOXES_OVERLAP(sbox, box)
+#ifdef SHAPE
+ && ShapeOverlap (pWin, box, pSib, sbox)
+#endif
+ )
+ return(TRUE);
+ }
+ }
+ return(FALSE);
+}
+
+/*
+ * WhereDoIGoInTheStack()
+ * Given pWin and pSib and the relationshipe smode, return
+ * the window that pWin should go ABOVE.
+ * If a pSib is specified:
+ * Above: pWin is placed just above pSib
+ * Below: pWin is placed just below pSib
+ * TopIf: if pSib occludes pWin, then pWin is placed
+ * at the top of the stack
+ * BottomIf: if pWin occludes pSib, then pWin is
+ * placed at the bottom of the stack
+ * Opposite: if pSib occludes pWin, then pWin is placed at the
+ * top of the stack, else if pWin occludes pSib, then
+ * pWin is placed at the bottom of the stack
+ *
+ * If pSib is NULL:
+ * Above: pWin is placed at the top of the stack
+ * Below: pWin is placed at the bottom of the stack
+ * TopIf: if any sibling occludes pWin, then pWin is placed at
+ * the top of the stack
+ * BottomIf: if pWin occludes any sibline, then pWin is placed at
+ * the bottom of the stack
+ * Opposite: if any sibling occludes pWin, then pWin is placed at
+ * the top of the stack, else if pWin occludes any
+ * sibling, then pWin is placed at the bottom of the stack
+ *
+ */
+
+static WindowPtr
+WhereDoIGoInTheStack(
+ register WindowPtr pWin,
+ register WindowPtr pSib,
+ short x,
+ short y,
+ unsigned short w,
+ unsigned short h,
+ int smode)
+{
+ BoxRec box;
+ register ScreenPtr pScreen;
+ WindowPtr pHead, pFirst;
+
+ if ((pWin == pWin->parent->firstChild) &&
+ (pWin == pWin->parent->lastChild))
+ return((WindowPtr ) NULL);
+ pHead = RealChildHead(pWin->parent);
+ pFirst = pHead ? pHead->nextSib : pWin->parent->firstChild;
+ pScreen = pWin->drawable.pScreen;
+ box.x1 = x;
+ box.y1 = y;
+ box.x2 = x + (int)w;
+ box.y2 = y + (int)h;
+ switch (smode)
+ {
+ case Above:
+ if (pSib)
+ return(pSib);
+ else if (pWin == pFirst)
+ return(pWin->nextSib);
+ else
+ return(pFirst);
+ case Below:
+ if (pSib)
+ if (pSib->nextSib != pWin)
+ return(pSib->nextSib);
+ else
+ return(pWin->nextSib);
+ else
+ return NullWindow;
+ case TopIf:
+ if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+ return(pWin->nextSib);
+ else if (pSib)
+ {
+ if ((IsSiblingAboveMe(pWin, pSib) == Above) &&
+ (RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT))
+ return(pFirst);
+ else
+ return(pWin->nextSib);
+ }
+ else if (AnyWindowOverlapsMe(pWin, pHead, &box))
+ return(pFirst);
+ else
+ return(pWin->nextSib);
+ case BottomIf:
+ if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+ return(pWin->nextSib);
+ else if (pSib)
+ {
+ if ((IsSiblingAboveMe(pWin, pSib) == Below) &&
+ (RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT))
+ return NullWindow;
+ else
+ return(pWin->nextSib);
+ }
+ else if (IOverlapAnyWindow(pWin, &box))
+ return NullWindow;
+ else
+ return(pWin->nextSib);
+ case Opposite:
+ if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+ return(pWin->nextSib);
+ else if (pSib)
+ {
+ if (RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT)
+ {
+ if (IsSiblingAboveMe(pWin, pSib) == Above)
+ return(pFirst);
+ else
+ return NullWindow;
+ }
+ else
+ return(pWin->nextSib);
+ }
+ else if (AnyWindowOverlapsMe(pWin, pHead, &box))
+ {
+ /* If I'm occluded, I can't possibly be the first child
+ * if (pWin == pWin->parent->firstChild)
+ * return pWin->nextSib;
+ */
+ return(pFirst);
+ }
+ else if (IOverlapAnyWindow(pWin, &box))
+ return NullWindow;
+ else
+ return pWin->nextSib;
+ default:
+ {
+ ErrorF("Internal error in ConfigureWindow, smode == %d\n",smode );
+ return pWin->nextSib;
+ }
+ }
+}
+
+static void
+ReflectStackChange(
+ register WindowPtr pWin,
+ register WindowPtr pSib,
+ VTKind kind)
+{
+/* Note that pSib might be NULL */
+
+ Bool WasViewable = (Bool)pWin->viewable;
+ Bool anyMarked;
+ WindowPtr pFirstChange;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ /* if this is a root window, can't be restacked */
+ if (!pWin->parent)
+ return;
+
+ pFirstChange = MoveWindowInStack(pWin, pSib);
+
+ if (WasViewable)
+ {
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
+ &pLayerWin);
+ if (pLayerWin != pWin) pFirstChange = pLayerWin;
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pFirstChange);
+ }
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked)
+ {
+ (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, kind);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pFirstChange);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pWin->drawable.pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange, kind);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+}
+
+/*****
+ * ConfigureWindow
+ *****/
+
+int
+ConfigureWindow(register WindowPtr pWin, register Mask mask, XID *vlist, ClientPtr client)
+{
+#define RESTACK_WIN 0
+#define MOVE_WIN 1
+#define RESIZE_WIN 2
+#define REBORDER_WIN 3
+ register WindowPtr pSib = NullWindow;
+ register WindowPtr pParent = pWin->parent;
+ Window sibwid = 0;
+ Mask index2, tmask;
+ register XID *pVlist;
+ short x, y, beforeX, beforeY;
+ unsigned short w = pWin->drawable.width,
+ h = pWin->drawable.height,
+ bw = pWin->borderWidth;
+ int action, smode = Above;
+#ifdef XAPPGROUP
+ ClientPtr win_owner;
+ ClientPtr ag_leader = NULL;
+#endif
+ xEvent event;
+
+ if ((pWin->drawable.class == InputOnly) && (mask & IllegalInputOnlyConfigureMask))
+ return(BadMatch);
+
+ if ((mask & CWSibling) && !(mask & CWStackMode))
+ return(BadMatch);
+
+ pVlist = vlist;
+
+ if (pParent)
+ {
+ x = pWin->drawable.x - pParent->drawable.x - (int)bw;
+ y = pWin->drawable.y - pParent->drawable.y - (int)bw;
+ }
+ else
+ {
+ x = pWin->drawable.x;
+ y = pWin->drawable.y;
+ }
+ beforeX = x;
+ beforeY = y;
+ action = RESTACK_WIN;
+ if ((mask & (CWX | CWY)) && (!(mask & (CWHeight | CWWidth))))
+ {
+ GET_INT16(CWX, x);
+ GET_INT16(CWY, y);
+ action = MOVE_WIN;
+ }
+ /* or should be resized */
+ else if (mask & (CWX | CWY | CWWidth | CWHeight))
+ {
+ GET_INT16(CWX, x);
+ GET_INT16(CWY, y);
+ GET_CARD16(CWWidth, w);
+ GET_CARD16 (CWHeight, h);
+ if (!w || !h)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ action = RESIZE_WIN;
+ }
+ tmask = mask & ~ChangeMask;
+ while (tmask)
+ {
+ index2 = (Mask)lowbit (tmask);
+ tmask &= ~index2;
+ switch (index2)
+ {
+ case CWBorderWidth:
+ GET_CARD16(CWBorderWidth, bw);
+ break;
+ case CWSibling:
+ sibwid = (Window ) *pVlist;
+ pVlist++;
+ pSib = (WindowPtr )SecurityLookupIDByType(client, sibwid,
+ RT_WINDOW, SecurityReadAccess);
+ if (!pSib)
+ {
+ client->errorValue = sibwid;
+ return(BadWindow);
+ }
+ if (pSib->parent != pParent)
+ return(BadMatch);
+ if (pSib == pWin)
+ return(BadMatch);
+ break;
+ case CWStackMode:
+ GET_CARD8(CWStackMode, smode);
+ if ((smode != TopIf) && (smode != BottomIf) &&
+ (smode != Opposite) && (smode != Above) && (smode != Below))
+ {
+ client->errorValue = smode;
+ return(BadValue);
+ }
+ break;
+ default:
+ client->errorValue = mask;
+ return(BadValue);
+ }
+ }
+ /* root really can't be reconfigured, so just return */
+ if (!pParent)
+ return Success;
+
+ /* Figure out if the window should be moved. Doesnt
+ make the changes to the window if event sent */
+
+ #ifdef TEST
+ if (nxagentWindowTopLevel(pWin))
+ {
+
+ fprintf(stderr, "ConfigureWindow: pWin [%p] mask [%lu] client [%p]\n",
+ pWin, mask, client);
+
+ fprintf(stderr, "ConfigureWindow: x [%d] y [%d] w [%d] h [%d] CWStackMode [%d] "
+ "smode [%d] pSib [%p]\n",
+ x, y, w, h, (mask & CWStackMode) ? 1 : 0, smode, pSib);
+ }
+ #endif
+
+ if (nxagentOption(Rootless) && nxagentWindowTopLevel(pWin) &&
+ pWin -> overrideRedirect == 0 &&
+ nxagentScreenTrap == 0)
+ {
+ nxagentConfigureRootlessWindow(pWin, x, y, w, h, bw, pSib, smode, mask);
+
+ return Success;
+ }
+
+ if (mask & CWStackMode)
+ pSib = WhereDoIGoInTheStack(pWin, pSib, pParent->drawable.x + x,
+ pParent->drawable.y + y,
+ w + (bw << 1), h + (bw << 1), smode);
+ else
+ pSib = pWin->nextSib;
+
+#ifdef XAPPGROUP
+ win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+ ag_leader = XagLeader (win_owner);
+#endif
+
+ if ((!pWin->overrideRedirect) &&
+ (RedirectSend(pParent)
+#ifdef XAPPGROUP
+ || (win_owner->appgroup && ag_leader &&
+ XagIsControlledRoot (client, pParent))
+#endif
+ ))
+ {
+ event.u.u.type = ConfigureRequest;
+ event.u.configureRequest.window = pWin->drawable.id;
+ if (mask & CWSibling)
+ event.u.configureRequest.sibling = sibwid;
+ else
+ event.u.configureRequest.sibling = None;
+ if (mask & CWStackMode)
+ event.u.u.detail = smode;
+ else
+ event.u.u.detail = Above;
+ event.u.configureRequest.x = x;
+ event.u.configureRequest.y = y;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
+ event.u.configureRequest.x += panoramiXdataPtr[0].x;
+ event.u.configureRequest.y += panoramiXdataPtr[0].y;
+ }
+#endif
+ event.u.configureRequest.width = w;
+ event.u.configureRequest.height = h;
+ event.u.configureRequest.borderWidth = bw;
+ event.u.configureRequest.valueMask = mask;
+#ifdef XAPPGROUP
+ /* make sure if the ag_leader maps the window it goes to the wm */
+ if (ag_leader && ag_leader != client &&
+ XagIsControlledRoot (client, pParent)) {
+ event.u.configureRequest.parent = XagId (win_owner);
+ (void) TryClientEvents (ag_leader, &event, 1,
+ NoEventMask, NoEventMask, NullGrab);
+ return Success;
+ }
+#endif
+ event.u.configureRequest.parent = pParent->drawable.id;
+ if (MaybeDeliverEventsToClient(pParent, &event, 1,
+ SubstructureRedirectMask, client) == 1)
+ return(Success);
+ }
+ if (action == RESIZE_WIN)
+ {
+ Bool size_change = (w != pWin->drawable.width)
+ || (h != pWin->drawable.height);
+ if (size_change && ((pWin->eventMask|wOtherEventMasks(pWin)) & ResizeRedirectMask))
+ {
+ xEvent eventT;
+ eventT.u.u.type = ResizeRequest;
+ eventT.u.resizeRequest.window = pWin->drawable.id;
+ eventT.u.resizeRequest.width = w;
+ eventT.u.resizeRequest.height = h;
+ if (MaybeDeliverEventsToClient(pWin, &eventT, 1,
+ ResizeRedirectMask, client) == 1)
+ {
+ /* if event is delivered, leave the actual size alone. */
+ w = pWin->drawable.width;
+ h = pWin->drawable.height;
+ size_change = FALSE;
+ }
+ }
+ if (!size_change)
+ {
+ if (mask & (CWX | CWY))
+ action = MOVE_WIN;
+ else if (mask & (CWStackMode | CWBorderWidth))
+ action = RESTACK_WIN;
+ else /* really nothing to do */
+ return(Success) ;
+ }
+ }
+
+ if (action == RESIZE_WIN)
+ /* we've already checked whether there's really a size change */
+ goto ActuallyDoSomething;
+ if ((mask & CWX) && (x != beforeX))
+ goto ActuallyDoSomething;
+ if ((mask & CWY) && (y != beforeY))
+ goto ActuallyDoSomething;
+ if ((mask & CWBorderWidth) && (bw != wBorderWidth (pWin)))
+ goto ActuallyDoSomething;
+ if (mask & CWStackMode)
+ {
+#ifndef ROOTLESS
+ /* See above for why we always reorder in rootless mode. */
+ if (pWin->nextSib != pSib)
+#endif
+ goto ActuallyDoSomething;
+ }
+ return(Success);
+
+ActuallyDoSomething:
+ if (SubStrSend(pWin, pParent))
+ {
+ event.u.u.type = ConfigureNotify;
+ event.u.configureNotify.window = pWin->drawable.id;
+ if (pSib)
+ event.u.configureNotify.aboveSibling = pSib->drawable.id;
+ else
+ event.u.configureNotify.aboveSibling = None;
+ event.u.configureNotify.x = x;
+ event.u.configureNotify.y = y;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
+ event.u.configureNotify.x += panoramiXdataPtr[0].x;
+ event.u.configureNotify.y += panoramiXdataPtr[0].y;
+ }
+#endif
+ event.u.configureNotify.width = w;
+ event.u.configureNotify.height = h;
+ event.u.configureNotify.borderWidth = bw;
+ event.u.configureNotify.override = pWin->overrideRedirect;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ }
+ if (mask & CWBorderWidth)
+ {
+ if (action == RESTACK_WIN)
+ {
+ action = MOVE_WIN;
+ pWin->borderWidth = bw;
+ }
+ else if ((action == MOVE_WIN) &&
+ (beforeX + wBorderWidth (pWin) == x + (int)bw) &&
+ (beforeY + wBorderWidth (pWin) == y + (int)bw))
+ {
+ action = REBORDER_WIN;
+ (*pWin->drawable.pScreen->ChangeBorderWidth)(pWin, bw);
+ }
+ else
+ pWin->borderWidth = bw;
+ }
+ if (action == MOVE_WIN)
+ (*pWin->drawable.pScreen->MoveWindow)(pWin, x, y, pSib,
+ (mask & CWBorderWidth) ? VTOther : VTMove);
+ else if (action == RESIZE_WIN)
+ (*pWin->drawable.pScreen->ResizeWindow)(pWin, x, y, w, h, pSib);
+ else if (mask & CWStackMode)
+ ReflectStackChange(pWin, pSib, VTOther);
+
+ if (action != RESTACK_WIN)
+ CheckCursorConfinement(pWin);
+
+ nxagentFlushConfigureWindow();
+
+ return(Success);
+#undef RESTACK_WIN
+#undef MOVE_WIN
+#undef RESIZE_WIN
+#undef REBORDER_WIN
+}
+
+
+/******
+ *
+ * CirculateWindow
+ * For RaiseLowest, raises the lowest mapped child (if any) that is
+ * obscured by another child to the top of the stack. For LowerHighest,
+ * lowers the highest mapped child (if any) that is obscuring another
+ * child to the bottom of the stack. Exposure processing is performed
+ *
+ ******/
+
+int
+CirculateWindow(WindowPtr pParent, int direction, ClientPtr client)
+{
+ register WindowPtr pWin, pHead, pFirst;
+ xEvent event;
+ BoxRec box;
+
+ #ifdef TEST
+ fprintf(stderr, "CirculateWindow: pParent [%p] direction [%d] client [%p]\n",
+ pParent, direction, client);
+ #endif
+
+ /*
+ * if (nxagentOption(Rootless) && nxagentWMIsRunning &&
+ * nxagentWindowTopLevel(pWin) && pWin -> overrideRedirect == 0)
+ * {
+ * nxagentCirculateRootlessWindows(direction);
+ * return Success;
+ * }
+ */
+
+ pHead = RealChildHead(pParent);
+ pFirst = pHead ? pHead->nextSib : pParent->firstChild;
+ if (direction == RaiseLowest)
+ {
+ for (pWin = pParent->lastChild;
+ (pWin != pHead) &&
+ !(pWin->mapped &&
+ AnyWindowOverlapsMe(pWin, pHead, WindowExtents(pWin, &box)));
+ pWin = pWin->prevSib) ;
+ if (pWin == pHead)
+ return Success;
+ }
+ else
+ {
+ for (pWin = pFirst;
+ pWin &&
+ !(pWin->mapped &&
+ IOverlapAnyWindow(pWin, WindowExtents(pWin, &box)));
+ pWin = pWin->nextSib) ;
+ if (!pWin)
+ return Success;
+ }
+
+ event.u.circulate.window = pWin->drawable.id;
+ event.u.circulate.parent = pParent->drawable.id;
+ event.u.circulate.event = pParent->drawable.id;
+ if (direction == RaiseLowest)
+ event.u.circulate.place = PlaceOnTop;
+ else
+ event.u.circulate.place = PlaceOnBottom;
+
+ if (RedirectSend(pParent))
+ {
+ event.u.u.type = CirculateRequest;
+ if (MaybeDeliverEventsToClient(pParent, &event, 1,
+ SubstructureRedirectMask, client) == 1)
+ return(Success);
+ }
+
+ event.u.u.type = CirculateNotify;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ ReflectStackChange(pWin,
+ (direction == RaiseLowest) ? pFirst : NullWindow,
+ VTStack);
+
+ return(Success);
+}
+
+static int
+CompareWIDs(
+ WindowPtr pWin,
+ pointer value) /* must conform to VisitWindowProcPtr */
+{
+ Window *wid = (Window *)value;
+
+ if (pWin->drawable.id == *wid)
+ return(WT_STOPWALKING);
+ else
+ return(WT_WALKCHILDREN);
+}
+
+/*****
+ * ReparentWindow
+ *****/
+
+int
+ReparentWindow(register WindowPtr pWin, register WindowPtr pParent,
+ int x, int y, ClientPtr client)
+{
+ WindowPtr pPrev, pPriorParent;
+ Bool WasMapped = (Bool)(pWin->mapped);
+ xEvent event;
+ int bw = wBorderWidth (pWin);
+ register ScreenPtr pScreen;
+
+ pScreen = pWin->drawable.pScreen;
+ if (TraverseTree(pWin, CompareWIDs, (pointer)&pParent->drawable.id) == WT_STOPWALKING)
+ return(BadMatch);
+ if (!MakeWindowOptional(pWin))
+ return(BadAlloc);
+
+ if (WasMapped)
+ UnmapWindow(pWin, FALSE);
+
+ event.u.u.type = ReparentNotify;
+ event.u.reparent.window = pWin->drawable.id;
+ event.u.reparent.parent = pParent->drawable.id;
+ event.u.reparent.x = x;
+ event.u.reparent.y = y;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && !pParent->parent) {
+ event.u.reparent.x += panoramiXdataPtr[0].x;
+ event.u.reparent.y += panoramiXdataPtr[0].y;
+ }
+#endif
+ event.u.reparent.override = pWin->overrideRedirect;
+ DeliverEvents(pWin, &event, 1, pParent);
+
+ /* take out of sibling chain */
+
+ pPriorParent = pPrev = pWin->parent;
+ if (pPrev->firstChild == pWin)
+ pPrev->firstChild = pWin->nextSib;
+ if (pPrev->lastChild == pWin)
+ pPrev->lastChild = pWin->prevSib;
+
+ if (pWin->nextSib)
+ pWin->nextSib->prevSib = pWin->prevSib;
+ if (pWin->prevSib)
+ pWin->prevSib->nextSib = pWin->nextSib;
+
+ /* insert at begining of pParent */
+ pWin->parent = pParent;
+ pPrev = RealChildHead(pParent);
+
+ if (pWin->parent == WindowTable[0])
+ {
+ nxagentSetTopLevelEventMask(pWin);
+ }
+
+ if (pPrev)
+ {
+ pWin->nextSib = pPrev->nextSib;
+ if (pPrev->nextSib)
+ pPrev->nextSib->prevSib = pWin;
+ else
+ pParent->lastChild = pWin;
+ pPrev->nextSib = pWin;
+ pWin->prevSib = pPrev;
+ }
+ else
+ {
+ pWin->nextSib = pParent->firstChild;
+ pWin->prevSib = NullWindow;
+ if (pParent->firstChild)
+ pParent->firstChild->prevSib = pWin;
+ else
+ pParent->lastChild = pWin;
+ pParent->firstChild = pWin;
+ }
+
+ pWin->origin.x = x + bw;
+ pWin->origin.y = y + bw;
+ pWin->drawable.x = x + bw + pParent->drawable.x;
+ pWin->drawable.y = y + bw + pParent->drawable.y;
+
+ /* clip to parent */
+ SetWinSize (pWin);
+ SetBorderSize (pWin);
+
+ if (pScreen->ReparentWindow)
+ (*pScreen->ReparentWindow)(pWin, pPriorParent);
+
+ (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
+
+ ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
+
+ CheckWindowOptionalNeed(pWin);
+
+ if (WasMapped)
+ MapWindow(pWin, client);
+ RecalculateDeliverableEvents(pWin);
+ return(Success);
+}
+
+static void
+RealizeTree(WindowPtr pWin)
+{
+ register WindowPtr pChild;
+ RealizeWindowProcPtr Realize;
+
+ Realize = pWin->drawable.pScreen->RealizeWindow;
+ pChild = pWin;
+ while (1)
+ {
+ if (pChild->mapped)
+ {
+ pChild->realized = TRUE;
+#ifdef DO_SAVE_UNDERS
+ if (pChild->saveUnder)
+ deltaSaveUndersViewable++;
+#endif
+ pChild->viewable = (pChild->drawable.class == InputOutput);
+ (* Realize)(pChild);
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ return;
+ pChild = pChild->nextSib;
+ }
+}
+
+/*****
+ * MapWindow
+ * If some other client has selected SubStructureReDirect on the parent
+ * and override-redirect is xFalse, then a MapRequest event is generated,
+ * but the window remains unmapped. Otherwise, the window is mapped and a
+ * MapNotify event is generated.
+ *****/
+
+int
+MapWindow(register WindowPtr pWin, ClientPtr client)
+{
+ register ScreenPtr pScreen;
+
+ register WindowPtr pParent;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ #ifdef TEST
+ if (nxagentWindowTopLevel(pWin))
+ {
+ fprintf(stderr, "MapWindow: pWin [%p] client [%p]\n", pWin, client);
+ }
+ #endif
+
+ if (pWin->mapped)
+ return(Success);
+
+#ifdef XCSECURITY
+ /* don't let an untrusted client map a child-of-trusted-window, InputOnly
+ * window; too easy to steal device input
+ */
+ if ( (client->trustLevel != XSecurityClientTrusted) &&
+ (pWin->drawable.class == InputOnly) &&
+ (wClient(pWin->parent)->trustLevel == XSecurityClientTrusted) )
+ return Success;
+#endif
+
+ pScreen = pWin->drawable.pScreen;
+ if ( (pParent = pWin->parent) )
+ {
+ xEvent event;
+ Bool anyMarked;
+#ifdef XAPPGROUP
+ ClientPtr win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+ ClientPtr ag_leader = XagLeader (win_owner);
+#endif
+
+ if ((!pWin->overrideRedirect) &&
+ (RedirectSend(pParent)
+#ifdef XAPPGROUP
+ || (win_owner->appgroup && ag_leader &&
+ XagIsControlledRoot (client, pParent))
+#endif
+ ))
+ {
+ event.u.u.type = MapRequest;
+ event.u.mapRequest.window = pWin->drawable.id;
+#ifdef XAPPGROUP
+ /* make sure if the ag_leader maps the window it goes to the wm */
+ if (ag_leader && ag_leader != client &&
+ XagIsControlledRoot (client, pParent)) {
+ event.u.mapRequest.parent = XagId (win_owner);
+ (void) TryClientEvents (ag_leader, &event, 1,
+ NoEventMask, NoEventMask, NullGrab);
+ return Success;
+ }
+#endif
+ event.u.mapRequest.parent = pParent->drawable.id;
+
+ if (MaybeDeliverEventsToClient(pParent, &event, 1,
+ SubstructureRedirectMask, client) == 1)
+ return(Success);
+ }
+
+ pWin->mapped = TRUE;
+ if (SubStrSend(pWin, pParent))
+ {
+ event.u.u.type = MapNotify;
+ event.u.mapNotify.window = pWin->drawable.id;
+ event.u.mapNotify.override = pWin->overrideRedirect;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ }
+
+ if (!pParent->realized)
+ return(Success);
+ RealizeTree(pWin);
+ if (pWin->viewable)
+ {
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ &pLayerWin);
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib);
+ }
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked)
+ {
+ (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
+ }
+ WindowsRestructured ();
+ }
+ else
+ {
+ RegionRec temp;
+
+ pWin->mapped = TRUE;
+ pWin->realized = TRUE; /* for roots */
+ pWin->viewable = pWin->drawable.class == InputOutput;
+ /* We SHOULD check for an error value here XXX */
+ (*pScreen->RealizeWindow)(pWin);
+ if (pScreen->ClipNotify)
+ (*pScreen->ClipNotify) (pWin, 0, 0);
+ if (pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(NullWindow, pWin, VTMap);
+ REGION_NULL(pScreen, &temp);
+ REGION_COPY(pScreen, &temp, &pWin->clipList);
+ (*pScreen->WindowExposures) (pWin, &temp, NullRegion);
+ REGION_UNINIT(pScreen, &temp);
+ }
+
+ nxagentFlushConfigureWindow();
+
+ return(Success);
+}
+
+
+/*****
+ * MapSubwindows
+ * Performs a MapWindow all unmapped children of the window, in top
+ * to bottom stacking order.
+ *****/
+
+void
+MapSubwindows(register WindowPtr pParent, ClientPtr client)
+{
+ register WindowPtr pWin;
+ WindowPtr pFirstMapped = NullWindow;
+#ifdef DO_SAVE_UNDERS
+ WindowPtr pFirstSaveUndered = NullWindow;
+#endif
+ register ScreenPtr pScreen;
+ register Mask parentRedirect;
+ register Mask parentNotify;
+ xEvent event;
+ Bool anyMarked;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ pScreen = pParent->drawable.pScreen;
+ parentRedirect = RedirectSend(pParent);
+ parentNotify = SubSend(pParent);
+ anyMarked = FALSE;
+ for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib)
+ {
+ if (!pWin->mapped)
+ {
+ if (parentRedirect && !pWin->overrideRedirect)
+ {
+ event.u.u.type = MapRequest;
+ event.u.mapRequest.window = pWin->drawable.id;
+ event.u.mapRequest.parent = pParent->drawable.id;
+
+ if (MaybeDeliverEventsToClient(pParent, &event, 1,
+ SubstructureRedirectMask, client) == 1)
+ continue;
+ }
+
+ pWin->mapped = TRUE;
+ if (parentNotify || StrSend(pWin))
+ {
+ event.u.u.type = MapNotify;
+ event.u.mapNotify.window = pWin->drawable.id;
+ event.u.mapNotify.override = pWin->overrideRedirect;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ }
+
+ if (!pFirstMapped)
+ pFirstMapped = pWin;
+ if (pParent->realized)
+ {
+ RealizeTree(pWin);
+ if (pWin->viewable)
+ {
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ (WindowPtr *)NULL);
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = TRUE;
+ }
+#endif /* DO_SAVE_UNDERS */
+ }
+ }
+ }
+ }
+
+ if (pFirstMapped)
+ {
+ pLayerWin = (*pScreen->GetLayerWindow)(pParent);
+ if (pLayerWin->parent != pParent) {
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pLayerWin,
+ pLayerWin,
+ (WindowPtr *)NULL);
+ pFirstMapped = pLayerWin;
+ }
+ if (anyMarked)
+ {
+#ifdef DO_SAVE_UNDERS
+ if (pLayerWin->parent != pParent)
+ {
+ if (dosave || (DO_SAVE_UNDERS(pLayerWin)))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin,
+ pLayerWin);
+ }
+ }
+ else if (dosave)
+ {
+ dosave = FALSE;
+ for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib)
+ {
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave |= (*pScreen->ChangeSaveUnder)(pWin,
+ pWin->nextSib);
+ if (dosave && !pFirstSaveUndered)
+ pFirstSaveUndered = pWin;
+ }
+ }
+ }
+#endif /* DO_SAVE_UNDERS */
+ (*pScreen->ValidateTree)(pLayerWin->parent, pFirstMapped, VTMap);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin,
+ pFirstSaveUndered->nextSib);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstMapped,
+ VTMap);
+ WindowsRestructured ();
+ }
+}
+
+static void
+UnrealizeTree(
+ WindowPtr pWin,
+ Bool fromConfigure)
+{
+ register WindowPtr pChild;
+ UnrealizeWindowProcPtr Unrealize;
+ MarkUnrealizedWindowProcPtr MarkUnrealizedWindow;
+
+ Unrealize = pWin->drawable.pScreen->UnrealizeWindow;
+ MarkUnrealizedWindow = pWin->drawable.pScreen->MarkUnrealizedWindow;
+ pChild = pWin;
+ while (1)
+ {
+ if (pChild->realized)
+ {
+ pChild->realized = FALSE;
+ pChild->visibility = VisibilityNotViewable;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && !pChild->drawable.pScreen->myNum) {
+ PanoramiXRes *win;
+ win = (PanoramiXRes*)LookupIDByType(pChild->drawable.id,
+ XRT_WINDOW);
+ if(win)
+ win->u.win.visibility = VisibilityNotViewable;
+ }
+#endif
+ (* Unrealize)(pChild);
+ DeleteWindowFromAnyEvents(pChild, FALSE);
+ if (pChild->viewable)
+ {
+#ifdef DO_SAVE_UNDERS
+ if (pChild->saveUnder)
+ deltaSaveUndersViewable--;
+#endif
+ pChild->viewable = FALSE;
+ if (pChild->backStorage)
+ (*pChild->drawable.pScreen->SaveDoomedAreas)(
+ pChild, &pChild->clipList, 0, 0);
+ (* MarkUnrealizedWindow)(pChild, pWin, fromConfigure);
+ pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ }
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ return;
+ pChild = pChild->nextSib;
+ }
+}
+
+/*****
+ * UnmapWindow
+ * If the window is already unmapped, this request has no effect.
+ * Otherwise, the window is unmapped and an UnMapNotify event is
+ * generated. Cannot unmap a root window.
+ *****/
+
+int
+UnmapWindow(register WindowPtr pWin, Bool fromConfigure)
+{
+ register WindowPtr pParent;
+ xEvent event;
+ Bool wasRealized = (Bool)pWin->realized;
+ Bool wasViewable = (Bool)pWin->viewable;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ WindowPtr pLayerWin = pWin;
+
+ #ifdef TEST
+ if (nxagentWindowTopLevel(pWin))
+ {
+ fprintf(stderr, "UnmapWindow: pWin [%p] fromConfigure [%d]\n", pWin,
+ fromConfigure);
+ }
+ #endif
+
+ if ((!pWin->mapped) || (!(pParent = pWin->parent)))
+ return(Success);
+ if (SubStrSend(pWin, pParent))
+ {
+ event.u.u.type = UnmapNotify;
+ event.u.unmapNotify.window = pWin->drawable.id;
+ event.u.unmapNotify.fromConfigure = fromConfigure;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ }
+ if (wasViewable && !fromConfigure)
+ {
+ pWin->valdata = UnmapValData;
+ (*pScreen->MarkOverlappedWindows)(pWin, pWin->nextSib, &pLayerWin);
+ (*pScreen->MarkWindow)(pLayerWin->parent);
+ }
+ pWin->mapped = FALSE;
+ if (wasRealized)
+ UnrealizeTree(pWin, fromConfigure);
+ if (wasViewable)
+ {
+ if (!fromConfigure)
+ {
+ (*pScreen->ValidateTree)(pLayerWin->parent, pWin, VTUnmap);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ if ( (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib) )
+ {
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+ }
+ }
+ pWin->DIXsaveUnder = FALSE;
+#endif /* DO_SAVE_UNDERS */
+ if (!fromConfigure && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pWin, VTUnmap);
+ }
+ if (wasRealized && !fromConfigure)
+ WindowsRestructured ();
+ return(Success);
+}
+
+/*****
+ * UnmapSubwindows
+ * Performs an UnmapWindow request with the specified mode on all mapped
+ * children of the window, in bottom to top stacking order.
+ *****/
+
+void
+UnmapSubwindows(register WindowPtr pWin)
+{
+ register WindowPtr pChild, pHead;
+ xEvent event;
+ Bool wasRealized = (Bool)pWin->realized;
+ Bool wasViewable = (Bool)pWin->viewable;
+ Bool anyMarked = FALSE;
+ Mask parentNotify;
+ WindowPtr pLayerWin = NULL;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ if (!pWin->firstChild)
+ return;
+ parentNotify = SubSend(pWin);
+ pHead = RealChildHead(pWin);
+
+ if (wasViewable)
+ pLayerWin = (*pScreen->GetLayerWindow)(pWin);
+
+ for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+ {
+ if (pChild->mapped)
+ {
+ if (parentNotify || StrSend(pChild))
+ {
+ event.u.u.type = UnmapNotify;
+ event.u.unmapNotify.window = pChild->drawable.id;
+ event.u.unmapNotify.fromConfigure = xFalse;
+ DeliverEvents(pChild, &event, 1, NullWindow);
+ }
+ if (pChild->viewable)
+ {
+ pChild->valdata = UnmapValData;
+ anyMarked = TRUE;
+ }
+ pChild->mapped = FALSE;
+ if (pChild->realized)
+ UnrealizeTree(pChild, FALSE);
+ if (wasViewable)
+ {
+#ifdef DO_SAVE_UNDERS
+ pChild->DIXsaveUnder = FALSE;
+#endif /* DO_SAVE_UNDERS */
+ if (pChild->backStorage)
+ (*pScreen->SaveDoomedAreas)(
+ pChild, &pChild->clipList, 0, 0);
+ }
+ }
+ }
+ if (wasViewable)
+ {
+ if (anyMarked)
+ {
+ if (pLayerWin->parent == pWin)
+ (*pScreen->MarkWindow)(pWin);
+ else
+ {
+ WindowPtr ptmp;
+ (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
+ (WindowPtr *)NULL);
+ (*pScreen->MarkWindow)(pLayerWin->parent);
+
+ /* Windows between pWin and pLayerWin may not have been marked */
+ ptmp = pWin;
+
+ while (ptmp != pLayerWin->parent)
+ {
+ (*pScreen->MarkWindow)(ptmp);
+ ptmp = ptmp->parent;
+ }
+ pHead = pWin->firstChild;
+ }
+ (*pScreen->ValidateTree)(pLayerWin->parent, pHead, VTUnmap);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ if ( (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin))
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
+ }
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pHead, VTUnmap);
+ }
+ if (wasRealized)
+ WindowsRestructured ();
+}
+
+
+void
+HandleSaveSet(register ClientPtr client)
+{
+ register WindowPtr pParent, pWin;
+ register int j;
+
+ for (j=0; j<client->numSaved; j++)
+ {
+ pWin = SaveSetWindow(client->saveSet[j]);
+#ifdef XFIXES
+ if (SaveSetToRoot(client->saveSet[j]))
+ pParent = WindowTable[pWin->drawable.pScreen->myNum];
+ else
+#endif
+ {
+ pParent = pWin->parent;
+ while (pParent && (wClient (pParent) == client))
+ pParent = pParent->parent;
+ }
+ if (pParent)
+ {
+ if (pParent != pWin->parent)
+ {
+ ReparentWindow(pWin, pParent,
+ pWin->drawable.x - wBorderWidth (pWin) - pParent->drawable.x,
+ pWin->drawable.y - wBorderWidth (pWin) - pParent->drawable.y,
+ client);
+ if(!pWin->realized && pWin->mapped)
+ pWin->mapped = FALSE;
+ }
+#ifdef XFIXES
+ if (SaveSetRemap (client->saveSet[j]))
+#endif
+ MapWindow(pWin, client);
+ }
+ }
+ xfree(client->saveSet);
+ client->numSaved = 0;
+ client->saveSet = (SaveSetElt *)NULL;
+}
+
+/**
+ *
+ * \param x,y in root
+ * \param box "return" value
+ */
+Bool
+VisibleBoundingBoxFromPoint(register WindowPtr pWin, int x, int y, BoxPtr box)
+{
+ if (!pWin->realized)
+ return (FALSE);
+ if (POINT_IN_REGION(pWin->drawable.pScreen, &pWin->clipList, x, y, box))
+ return(TRUE);
+ return(FALSE);
+}
+
+/**
+ *
+ * \param x,y in root
+ */
+Bool
+PointInWindowIsVisible(register WindowPtr pWin, int x, int y)
+{
+ BoxRec box;
+
+ if (!pWin->realized)
+ return (FALSE);
+ if (POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderClip,
+ x, y, &box)
+ && (!wInputShape(pWin) ||
+ POINT_IN_REGION(pWin->drawable.pScreen,
+ wInputShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box)))
+ return(TRUE);
+ return(FALSE);
+}
+
+
+RegionPtr
+NotClippedByChildren(register WindowPtr pWin)
+{
+ register ScreenPtr pScreen;
+ RegionPtr pReg;
+
+ pScreen = pWin->drawable.pScreen;
+ pReg = REGION_CREATE(pScreen, NullBox, 1);
+ if (pWin->parent ||
+ screenIsSaved != SCREEN_SAVER_ON ||
+ !HasSaverWindow (pWin->drawable.pScreen->myNum))
+ {
+ REGION_INTERSECT(pScreen, pReg, &pWin->borderClip, &pWin->winSize);
+ }
+ return(pReg);
+}
+
+void
+SendVisibilityNotify(WindowPtr pWin)
+{
+ xEvent event;
+#ifndef NO_XINERAMA_PORT
+ unsigned int visibility = pWin->visibility;
+#endif
+#ifdef PANORAMIX
+ /* This is not quite correct yet, but it's close */
+ if(!noPanoramiXExtension) {
+ PanoramiXRes *win;
+ WindowPtr pWin2;
+ int i, Scrnum;
+
+ Scrnum = pWin->drawable.pScreen->myNum;
+
+ win = PanoramiXFindIDByScrnum(XRT_WINDOW, pWin->drawable.id, Scrnum);
+
+ if(!win || (win->u.win.visibility == visibility))
+ return;
+
+ switch(visibility) {
+ case VisibilityUnobscured:
+ for(i = 0; i < PanoramiXNumScreens; i++) {
+ if(i == Scrnum) continue;
+
+ pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW);
+
+ if (pWin2) {
+ if(pWin2->visibility == VisibilityPartiallyObscured)
+ return;
+
+ if(!i) pWin = pWin2;
+ }
+ }
+ break;
+ case VisibilityPartiallyObscured:
+ if(Scrnum) {
+ pWin2 = (WindowPtr)LookupIDByType(win->info[0].id, RT_WINDOW);
+ if (pWin2) pWin = pWin2;
+ }
+ break;
+ case VisibilityFullyObscured:
+ for(i = 0; i < PanoramiXNumScreens; i++) {
+ if(i == Scrnum) continue;
+
+ pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW);
+
+ if (pWin2) {
+ if(pWin2->visibility != VisibilityFullyObscured)
+ return;
+
+ if(!i) pWin = pWin2;
+ }
+ }
+ break;
+ }
+
+ win->u.win.visibility = visibility;
+ }
+#endif
+
+ event.u.u.type = VisibilityNotify;
+ event.u.visibility.window = pWin->drawable.id;
+ event.u.visibility.state = visibility;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+}
+
+
+#define RANDOM_WIDTH 32
+
+#ifndef NOLOGOHACK
+static void DrawLogo(
+ WindowPtr pWin
+);
+#endif
+
+void
+SaveScreens(int on, int mode)
+{
+ int i;
+ int what;
+ int type;
+
+ if (on == SCREEN_SAVER_FORCER)
+ {
+ UpdateCurrentTimeIf();
+ lastDeviceEventTime = currentTime;
+ if (mode == ScreenSaverReset)
+ what = SCREEN_SAVER_OFF;
+ else
+ what = SCREEN_SAVER_ON;
+ type = what;
+ }
+ else
+ {
+ what = on;
+ type = what;
+ if (what == screenIsSaved)
+ type = SCREEN_SAVER_CYCLE;
+ }
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ if (on == SCREEN_SAVER_FORCER)
+ (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i], on);
+ if (savedScreenInfo[i].ExternalScreenSaver)
+ {
+ if (nxagentOption(Timeout) != 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "SaveScreens: An external screen-saver handler is installed. "
+ "Ignoring it to let the auto-disconnect feature work.\n");
+ #endif
+ }
+ else
+ {
+ if ((*savedScreenInfo[i].ExternalScreenSaver)
+ (screenInfo.screens[i], type, on == SCREEN_SAVER_FORCER))
+ continue;
+ }
+ }
+ if (type == screenIsSaved)
+ continue;
+ switch (type) {
+ case SCREEN_SAVER_OFF:
+ if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
+ {
+ (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
+ what);
+ }
+ else if (HasSaverWindow (i))
+ {
+ savedScreenInfo[i].pWindow = NullWindow;
+ FreeResource(savedScreenInfo[i].wid, RT_NONE);
+ }
+ break;
+ case SCREEN_SAVER_CYCLE:
+ if (savedScreenInfo[i].blanked == SCREEN_IS_TILED)
+ {
+ WindowPtr pWin = savedScreenInfo[i].pWindow;
+ /* make it look like screen saver is off, so that
+ * NotClippedByChildren will compute a clip list
+ * for the root window, so miPaintWindow works
+ */
+ screenIsSaved = SCREEN_SAVER_OFF;
+#ifndef NOLOGOHACK
+ if (logoScreenSaver)
+ (*pWin->drawable.pScreen->ClearToBackground)(pWin, 0, 0, 0, 0, FALSE);
+#endif
+ (*pWin->drawable.pScreen->MoveWindow)(pWin,
+ (short)(-(rand() % RANDOM_WIDTH)),
+ (short)(-(rand() % RANDOM_WIDTH)),
+ pWin->nextSib, VTMove);
+#ifndef NOLOGOHACK
+ if (logoScreenSaver)
+ DrawLogo(pWin);
+#endif
+ screenIsSaved = SCREEN_SAVER_ON;
+ }
+ /*
+ * Call the DDX saver in case it wants to do something
+ * at cycle time
+ */
+ else if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
+ {
+ (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
+ type);
+ }
+ break;
+ case SCREEN_SAVER_ON:
+ if (ScreenSaverBlanking != DontPreferBlanking)
+ {
+ if ((* screenInfo.screens[i]->SaveScreen)
+ (screenInfo.screens[i], what))
+ {
+ savedScreenInfo[i].blanked = SCREEN_IS_BLANKED;
+ continue;
+ }
+ if ((ScreenSaverAllowExposures != DontAllowExposures) &&
+ TileScreenSaver(i, SCREEN_IS_BLACK))
+ {
+ savedScreenInfo[i].blanked = SCREEN_IS_BLACK;
+ continue;
+ }
+ }
+ if ((ScreenSaverAllowExposures != DontAllowExposures) &&
+ TileScreenSaver(i, SCREEN_IS_TILED))
+ {
+ savedScreenInfo[i].blanked = SCREEN_IS_TILED;
+ }
+ else
+ savedScreenInfo[i].blanked = SCREEN_ISNT_SAVED;
+ break;
+ }
+ }
+ screenIsSaved = what;
+ if (mode == ScreenSaverReset)
+ SetScreenSaverTimer();
+}
+
+static Bool
+TileScreenSaver(int i, int kind)
+{
+ int j;
+ int result;
+ XID attributes[3];
+ Mask mask;
+ WindowPtr pWin;
+ CursorMetricRec cm;
+ unsigned char *srcbits, *mskbits;
+ CursorPtr cursor;
+ XID cursorID = 0;
+ int attri;
+
+ mask = 0;
+ attri = 0;
+ switch (kind) {
+ case SCREEN_IS_TILED:
+ switch (WindowTable[i]->backgroundState) {
+ case BackgroundPixel:
+ attributes[attri++] = WindowTable[i]->background.pixel;
+ mask |= CWBackPixel;
+ break;
+ case BackgroundPixmap:
+ attributes[attri++] = None;
+ mask |= CWBackPixmap;
+ break;
+ default:
+ break;
+ }
+ break;
+ case SCREEN_IS_BLACK:
+ attributes[attri++] = WindowTable[i]->drawable.pScreen->blackPixel;
+ mask |= CWBackPixel;
+ break;
+ }
+ mask |= CWOverrideRedirect;
+ attributes[attri++] = xTrue;
+
+ /*
+ * create a blank cursor
+ */
+
+ cm.width=16;
+ cm.height=16;
+ cm.xhot=8;
+ cm.yhot=8;
+ srcbits = (unsigned char *)xalloc( BitmapBytePad(32)*16);
+ mskbits = (unsigned char *)xalloc( BitmapBytePad(32)*16);
+ if (!srcbits || !mskbits)
+ {
+ xfree(srcbits);
+ xfree(mskbits);
+ cursor = 0;
+ }
+ else
+ {
+ for (j=0; j<BitmapBytePad(32)*16; j++)
+ srcbits[j] = mskbits[j] = 0x0;
+ cursor = AllocCursor(srcbits, mskbits, &cm, 0, 0, 0, 0, 0, 0);
+ if (cursor)
+ {
+ cursorID = FakeClientID(0);
+ if (AddResource (cursorID, RT_CURSOR, (pointer) cursor))
+ {
+ attributes[attri] = cursorID;
+ mask |= CWCursor;
+ }
+ else
+ cursor = 0;
+ }
+ else
+ {
+ xfree (srcbits);
+ xfree (mskbits);
+ }
+ }
+
+ pWin = savedScreenInfo[i].pWindow =
+ CreateWindow(savedScreenInfo[i].wid,
+ WindowTable[i],
+ -RANDOM_WIDTH, -RANDOM_WIDTH,
+ (unsigned short)screenInfo.screens[i]->width + RANDOM_WIDTH,
+ (unsigned short)screenInfo.screens[i]->height + RANDOM_WIDTH,
+ 0, InputOutput, mask, attributes, 0, serverClient,
+ wVisual (WindowTable[i]), &result);
+
+ if (cursor)
+ FreeResource (cursorID, RT_NONE);
+
+ if (!pWin)
+ return FALSE;
+
+ if (!AddResource(pWin->drawable.id, RT_WINDOW,
+ (pointer)savedScreenInfo[i].pWindow))
+ return FALSE;
+
+ if (mask & CWBackPixmap)
+ {
+ MakeRootTile (pWin);
+ (*pWin->drawable.pScreen->ChangeWindowAttributes)(pWin, CWBackPixmap);
+ }
+ MapWindow(pWin, serverClient);
+#ifndef NOLOGOHACK
+ if (kind == SCREEN_IS_TILED && logoScreenSaver)
+ DrawLogo(pWin);
+#endif
+ return TRUE;
+}
+
+/*
+ * FindWindowWithOptional
+ *
+ * search ancestors of the given window for an entry containing
+ * a WindowOpt structure. Assumptions: some parent will
+ * contain the structure.
+ */
+
+WindowPtr
+FindWindowWithOptional (register WindowPtr w)
+{
+ do
+ w = w->parent;
+ while (!w->optional);
+ return w;
+}
+
+/*
+ * CheckWindowOptionalNeed
+ *
+ * check each optional entry in the given window to see if
+ * the value is satisfied by the default rules. If so,
+ * release the optional record
+ */
+
+void
+CheckWindowOptionalNeed (register WindowPtr w)
+{
+ register WindowOptPtr optional;
+ register WindowOptPtr parentOptional;
+
+ if (!w->parent)
+ return;
+ optional = w->optional;
+ if (optional->dontPropagateMask != DontPropagateMasks[w->dontPropagate])
+ return;
+ if (optional->otherEventMasks != 0)
+ return;
+ if (optional->otherClients != NULL)
+ return;
+ if (optional->passiveGrabs != NULL)
+ return;
+ if (optional->userProps != NULL)
+ return;
+ if (optional->backingBitPlanes != ~0L)
+ return;
+ if (optional->backingPixel != 0)
+ return;
+#ifdef SHAPE
+ if (optional->boundingShape != NULL)
+ return;
+ if (optional->clipShape != NULL)
+ return;
+ if (optional->inputShape != NULL)
+ return;
+#endif
+#ifdef XINPUT
+ if (optional->inputMasks != NULL)
+ return;
+#endif
+ parentOptional = FindWindowWithOptional(w)->optional;
+ if (optional->visual != parentOptional->visual)
+ return;
+ if (optional->cursor != None &&
+ (optional->cursor != parentOptional->cursor ||
+ w->parent->cursorIsNone))
+ return;
+ if (optional->colormap != parentOptional->colormap)
+ return;
+ DisposeWindowOptional (w);
+}
+
+/*
+ * MakeWindowOptional
+ *
+ * create an optional record and initialize it with the default
+ * values.
+ */
+
+Bool
+MakeWindowOptional (register WindowPtr pWin)
+{
+ register WindowOptPtr optional;
+ register WindowOptPtr parentOptional;
+
+ if (pWin->optional)
+ return TRUE;
+ optional = (WindowOptPtr) xalloc (sizeof (WindowOptRec));
+ if (!optional)
+ return FALSE;
+ optional->dontPropagateMask = DontPropagateMasks[pWin->dontPropagate];
+ optional->otherEventMasks = 0;
+ optional->otherClients = NULL;
+ optional->passiveGrabs = NULL;
+ optional->userProps = NULL;
+ optional->backingBitPlanes = ~0L;
+ optional->backingPixel = 0;
+#ifdef SHAPE
+ optional->boundingShape = NULL;
+ optional->clipShape = NULL;
+ optional->inputShape = NULL;
+#endif
+#ifdef XINPUT
+ optional->inputMasks = NULL;
+#endif
+ parentOptional = FindWindowWithOptional(pWin)->optional;
+ optional->visual = parentOptional->visual;
+ if (!pWin->cursorIsNone)
+ {
+ optional->cursor = parentOptional->cursor;
+ optional->cursor->refcnt++;
+ }
+ else
+ {
+ optional->cursor = None;
+ }
+ optional->colormap = parentOptional->colormap;
+ pWin->optional = optional;
+ return TRUE;
+}
+
+void
+DisposeWindowOptional (register WindowPtr pWin)
+{
+ if (!pWin->optional)
+ return;
+ /*
+ * everything is peachy. Delete the optional record
+ * and clean up
+ */
+ /*
+ * TOG changed this code to:
+ *
+ * if (pWin->cursorIsNone == FALSE)
+ * FreeCursor (pWin->optional->cursor, (Cursor)0);
+ * pWin->cursorIsNone = TRUE;
+ *
+ * This is blatently wrong; windows without optionals can have
+ * two different cursor values, either None or sharing their
+ * parents cursor. This difference is controlled by the
+ * cursorIsNone value; when TRUE, the window has no cursor,
+ * when false, it shares its cursor with its parent; TOG
+ * made it impossible for a window to have a cursor without
+ * an optional record.
+ */
+ if (pWin->optional->cursor)
+ {
+ FreeCursor (pWin->optional->cursor, (Cursor)0);
+ pWin->cursorIsNone = FALSE;
+ }
+ else
+ pWin->cursorIsNone = TRUE;
+/* FIXME
+ There is an error when disposing ClientResources on Agent exit
+ this xfree is not valid in some window at exit
+*/
+
+ xfree (pWin->optional);
+ pWin->optional = NULL;
+}
+
+#ifndef NOLOGOHACK
+static void
+DrawLogo(WindowPtr pWin)
+{
+ DrawablePtr pDraw;
+ ScreenPtr pScreen;
+ int x, y;
+ unsigned int width, height, size;
+ GC *pGC;
+ int thin, gap, d31;
+ DDXPointRec poly[4];
+ ChangeGCVal fore[2], back[2];
+ xrgb rgb[2];
+ BITS32 fmask, bmask;
+ ColormapPtr cmap;
+
+ pDraw = (DrawablePtr)pWin;
+ pScreen = pDraw->pScreen;
+ x = -pWin->origin.x;
+ y = -pWin->origin.y;
+ width = pScreen->width;
+ height = pScreen->height;
+ pGC = GetScratchGC(pScreen->rootDepth, pScreen);
+ if (!pGC)
+ return;
+
+ if ((rand() % 100) <= 17) /* make the probability for white fairly low */
+ fore[0].val = pScreen->whitePixel;
+ else
+ fore[0].val = pScreen->blackPixel;
+ if ((pWin->backgroundState == BackgroundPixel) &&
+ (cmap = (ColormapPtr)LookupIDByType(wColormap (pWin), RT_COLORMAP))) {
+ Pixel querypixels[2];
+
+ querypixels[0] = fore[0].val;
+ querypixels[1] = pWin->background.pixel;
+ QueryColors(cmap, 2, querypixels, rgb);
+ if ((rgb[0].red == rgb[1].red) &&
+ (rgb[0].green == rgb[1].green) &&
+ (rgb[0].blue == rgb[1].blue)) {
+ if (fore[0].val == pScreen->blackPixel)
+ fore[0].val = pScreen->whitePixel;
+ else
+ fore[0].val = pScreen->blackPixel;
+ }
+ }
+ fore[1].val = FillSolid;
+ fmask = GCForeground|GCFillStyle;
+ if (pWin->backgroundState == BackgroundPixel) {
+ back[0].val = pWin->background.pixel;
+ back[1].val = FillSolid;
+ bmask = GCForeground|GCFillStyle;
+ } else {
+ back[0].val = 0;
+ back[1].val = 0;
+ dixChangeGC(NullClient, pGC, GCTileStipXOrigin|GCTileStipYOrigin,
+ NULL, back);
+ back[0].val = FillTiled;
+ back[1].ptr = pWin->background.pixmap;
+ bmask = GCFillStyle|GCTile;
+ }
+
+ /* should be the same as the reference function XmuDrawLogo() */
+
+ size = width;
+ if (height < width)
+ size = height;
+ size = RANDOM_WIDTH + rand() % (size - RANDOM_WIDTH);
+ size &= ~1;
+ x += rand() % (width - size);
+ y += rand() % (height - size);
+
+/*
+ * Draw what will be the thin strokes.
+ *
+ * -----
+ * / /
+ * / /
+ * / /
+ * / /
+ * /____/
+ * d
+ *
+ * Point d is 9/44 (~1/5) of the way across.
+ */
+
+ thin = (size / 11);
+ if (thin < 1) thin = 1;
+ gap = (thin+3) / 4;
+ d31 = thin + thin + gap;
+ poly[0].x = x + size; poly[0].y = y;
+ poly[1].x = x + size-d31; poly[1].y = y;
+ poly[2].x = x + 0; poly[2].y = y + size;
+ poly[3].x = x + d31; poly[3].y = y + size;
+ dixChangeGC(NullClient, pGC, fmask, NULL, fore);
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase area not needed for lower thin stroke.
+ *
+ * ------
+ * / /
+ * / __ /
+ * / / /
+ * / / /
+ * /__/__/
+ */
+
+ poly[0].x = x + d31/2; poly[0].y = y + size;
+ poly[1].x = x + size / 2; poly[1].y = y + size/2;
+ poly[2].x = x + (size/2)+(d31-(d31/2)); poly[2].y = y + size/2;
+ poly[3].x = x + d31; poly[3].y = y + size;
+ dixChangeGC(NullClient, pGC, bmask, NULL, back);
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase area not needed for upper thin stroke.
+ *
+ * ------
+ * / / /
+ * /--/ /
+ * / /
+ * / /
+ * /_____/
+ */
+
+ poly[0].x = x + size - d31/2; poly[0].y = y;
+ poly[1].x = x + size / 2; poly[1].y = y + size/2;
+ poly[2].x = x + (size/2)-(d31-(d31/2)); poly[2].y = y + size/2;
+ poly[3].x = x + size - d31; poly[3].y = y;
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Draw thick stroke.
+ * Point b is 1/4 of the way across.
+ *
+ * b
+ * -----
+ * \ \
+ * \ \
+ * \ \
+ * \ \
+ * \____\
+ */
+
+ poly[0].x = x; poly[0].y = y;
+ poly[1].x = x + size/4; poly[1].y = y;
+ poly[2].x = x + size; poly[2].y = y + size;
+ poly[3].x = x + size - size/4; poly[3].y = y + size;
+ dixChangeGC(NullClient, pGC, fmask, NULL, fore);
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase to create gap.
+ *
+ * /
+ * /
+ * /
+ * /
+ * /
+ */
+
+ poly[0].x = x + size- thin; poly[0].y = y;
+ poly[1].x = x + size-( thin+gap); poly[1].y = y;
+ poly[2].x = x + thin; poly[2].y = y + size;
+ poly[3].x = x + thin + gap; poly[3].y = y + size;
+ dixChangeGC(NullClient, pGC, bmask, NULL, back);
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+ FreeScratchGC(pGC);
+}
+
+#endif
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original
new file mode 100644
index 000000000..7ba468ac0
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original
@@ -0,0 +1,4174 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/* $XdotOrg: xc/programs/Xserver/dix/window.c,v 1.12 2005/07/03 08:53:38 daniels Exp $ */
+/* $Xorg: window.c,v 1.4 2001/02/09 02:04:41 xorgcvs Exp $ */
+/*
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+*/
+
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/window.c,v 3.36 2003/11/14 23:52:50 torrey Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+#include "selection.h"
+#ifdef PANORAMIX
+#include "../../Xext/panoramiX.h"
+#include "../../Xext/panoramiXsrv.h"
+#endif
+#include "dixevents.h"
+#include "globals.h"
+
+#ifdef XAPPGROUP
+#include <X11/extensions/Xagsrv.h>
+#endif
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+
+#include "Screen.h"
+#include "Options.h"
+#include "Atoms.h"
+#include "Clipboard.h"
+#include "Splash.h"
+#include "Rootless.h"
+#include "Composite.h"
+#include "Drawable.h"
+#include "Colormap.h"
+
+extern Bool nxagentWMIsRunning;
+extern Bool nxagentScreenTrap;
+
+/******
+ * Window stuff for server
+ *
+ * CreateRootWindow, CreateWindow, ChangeWindowAttributes,
+ * GetWindowAttributes, DeleteWindow, DestroySubWindows,
+ * HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows,
+ * UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow,
+ *
+ ******/
+
+int screenIsSaved = SCREEN_SAVER_OFF;
+
+ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
+
+#if 0
+extern void DeleteWindowFromAnyEvents();
+extern Mask EventMaskForClient();
+extern void WindowHasNewCursor();
+extern void RecalculateDeliverableEvents();
+#endif
+
+static Bool TileScreenSaver(int i, int kind);
+
+
+#define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \
+ CWDontPropagate | CWOverrideRedirect | CWCursor )
+
+#define BOXES_OVERLAP(b1, b2) \
+ (!( ((b1)->x2 <= (b2)->x1) || \
+ ( ((b1)->x1 >= (b2)->x2)) || \
+ ( ((b1)->y2 <= (b2)->y1)) || \
+ ( ((b1)->y1 >= (b2)->y2)) ) )
+
+#define RedirectSend(pWin) \
+ ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureRedirectMask)
+
+#define SubSend(pWin) \
+ ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask)
+
+#define StrSend(pWin) \
+ ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask)
+
+#define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
+
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+int numSaveUndersViewable = 0;
+int deltaSaveUndersViewable = 0;
+
+WindowPtr nxagentRootTileWindow;
+
+/*
+ * This block used the DEBUG symbol.
+ */
+
+#ifdef WINDOW_TREE_DEBUG
+/******
+ * PrintWindowTree
+ * For debugging only
+ ******/
+
+int
+PrintChildren(WindowPtr p1, int indent)
+{
+ WindowPtr p2;
+ int i;
+
+ while (p1)
+ {
+ p2 = p1->firstChild;
+ for (i=0; i<indent; i++) ErrorF( " ");
+ ErrorF( "%x\n", p1->drawable.id);
+ miPrintRegion(&p1->clipList);
+ PrintChildren(p2, indent+4);
+ p1 = p1->nextSib;
+ }
+}
+
+PrintWindowTree()
+{
+ int i;
+ WindowPtr pWin, p1;
+
+ for (i=0; i<screenInfo.numScreens; i++)
+ {
+ ErrorF( "WINDOW %d\n", i);
+ pWin = WindowTable[i];
+ miPrintRegion(&pWin->clipList);
+ p1 = pWin->firstChild;
+ PrintChildren(p1, 4);
+ }
+}
+#endif
+
+int
+TraverseTree(register WindowPtr pWin, VisitWindowProcPtr func, pointer data)
+{
+ register int result;
+ register WindowPtr pChild;
+
+ if (!(pChild = pWin))
+ return(WT_NOMATCH);
+ while (1)
+ {
+ result = (* func)(pChild, data);
+ if (result == WT_STOPWALKING)
+ return(WT_STOPWALKING);
+ if ((result == WT_WALKCHILDREN) && pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ break;
+ pChild = pChild->nextSib;
+ }
+ return(WT_NOMATCH);
+}
+
+/*****
+ * WalkTree
+ * Walk the window tree, for SCREEN, preforming FUNC(pWin, data) on
+ * each window. If FUNC returns WT_WALKCHILDREN, traverse the children,
+ * if it returns WT_DONTWALKCHILDREN, dont. If it returns WT_STOPWALKING
+ * exit WalkTree. Does depth-first traverse.
+ *****/
+
+int
+WalkTree(ScreenPtr pScreen, VisitWindowProcPtr func, pointer data)
+{
+ return(TraverseTree(WindowTable[pScreen->myNum], func, data));
+}
+
+/* hack for forcing backing store on all windows */
+int defaultBackingStore = NotUseful;
+/* hack to force no backing store */
+Bool disableBackingStore = FALSE;
+Bool enableBackingStore = FALSE;
+/* hack to force no save unders */
+Bool disableSaveUnders = FALSE;
+
+static void
+SetWindowToDefaults(register WindowPtr pWin)
+{
+ pWin->prevSib = NullWindow;
+ pWin->firstChild = NullWindow;
+ pWin->lastChild = NullWindow;
+
+ pWin->valdata = (ValidatePtr)NULL;
+ pWin->optional = (WindowOptPtr)NULL;
+ pWin->cursorIsNone = TRUE;
+
+ pWin->backingStore = NotUseful;
+ pWin->DIXsaveUnder = FALSE;
+ pWin->backStorage = (pointer) NULL;
+
+ pWin->mapped = FALSE; /* off */
+ pWin->realized = FALSE; /* off */
+ pWin->viewable = FALSE;
+ pWin->visibility = VisibilityNotViewable;
+ pWin->overrideRedirect = FALSE;
+ pWin->saveUnder = FALSE;
+
+ pWin->bitGravity = ForgetGravity;
+ pWin->winGravity = NorthWestGravity;
+
+ pWin->eventMask = 0;
+ pWin->deliverableEvents = 0;
+ pWin->dontPropagate = 0;
+ pWin->forcedBS = FALSE;
+#ifdef NEED_DBE_BUF_BITS
+ pWin->srcBuffer = DBE_FRONT_BUFFER;
+ pWin->dstBuffer = DBE_FRONT_BUFFER;
+#endif
+#ifdef COMPOSITE
+ pWin->redirectDraw = 0;
+#endif
+}
+
+#ifdef NXAGENT_SERVER
+
+void nxagentClearSplash(WindowPtr pW)
+{
+ int w, h;
+ ScreenPtr pScreen;
+
+ w = pW->drawable.width;
+ h = pW->drawable.height;
+
+ pScreen = pW->drawable.pScreen;
+
+ if (pW->backgroundState == BackgroundPixmap)
+ {
+ (*pScreen->DestroyPixmap)(pW->background.pixmap);
+ }
+
+ pW->backgroundState = BackgroundPixel;
+ pW->background.pixel = nxagentLogoBlack;
+
+ (*pScreen->ChangeWindowAttributes)(pW, CWBackPixmap|CWBackPixel);
+}
+
+static void
+#if NeedFunctionPrototypes
+MakeRootTile(WindowPtr pWin)
+#else
+MakeRootTile(pWin)
+ WindowPtr pWin;
+#endif
+{
+ nxagentRootTileWindow = pWin;
+}
+
+#else /* NXAGENT_SERVER */
+
+static void
+MakeRootTile(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ GCPtr pGC;
+ unsigned char back[128];
+ int len = BitmapBytePad(sizeof(long));
+ register unsigned char *from, *to;
+ register int i, j;
+
+ pWin->background.pixmap = (*pScreen->CreatePixmap)(pScreen, 4, 4,
+ pScreen->rootDepth);
+
+ pWin->backgroundState = BackgroundPixmap;
+ pGC = GetScratchGC(pScreen->rootDepth, pScreen);
+ if (!pWin->background.pixmap || !pGC)
+ FatalError("could not create root tile");
+
+ {
+ CARD32 attributes[2];
+
+ attributes[0] = pScreen->whitePixel;
+ attributes[1] = pScreen->blackPixel;
+
+ (void)ChangeGC(pGC, GCForeground | GCBackground, attributes);
+ }
+
+ ValidateGC((DrawablePtr)pWin->background.pixmap, pGC);
+
+ from = (screenInfo.bitmapBitOrder == LSBFirst) ? _back_lsb : _back_msb;
+ to = back;
+
+ for (i = 4; i > 0; i--, from++)
+ for (j = len; j > 0; j--)
+ *to++ = *from;
+
+ if (blackRoot)
+ bzero(back, sizeof(back));
+
+ (*pGC->ops->PutImage)((DrawablePtr)pWin->background.pixmap, pGC, 1,
+ 0, 0, len, 4, 0, XYBitmap, (char *)back);
+
+ FreeScratchGC(pGC);
+
+}
+
+#endif /* NXAGENT_SERVER */
+
+WindowPtr
+AllocateWindow(ScreenPtr pScreen)
+{
+ WindowPtr pWin;
+ register char *ptr;
+ register DevUnion *ppriv;
+ register unsigned *sizes;
+ register unsigned size;
+ register int i;
+
+ pWin = (WindowPtr)xalloc(pScreen->totalWindowSize);
+ if (pWin)
+ {
+ ppriv = (DevUnion *)(pWin + 1);
+ pWin->devPrivates = ppriv;
+ sizes = pScreen->WindowPrivateSizes;
+ ptr = (char *)(ppriv + pScreen->WindowPrivateLen);
+ for (i = pScreen->WindowPrivateLen; --i >= 0; ppriv++, sizes++)
+ {
+ if ( (size = *sizes) )
+ {
+ ppriv->ptr = (pointer)ptr;
+ ptr += size;
+ }
+ else
+ ppriv->ptr = (pointer)NULL;
+ }
+ }
+ return pWin;
+}
+
+/*****
+ * CreateRootWindow
+ * Makes a window at initialization time for specified screen
+ *****/
+
+Bool
+CreateRootWindow(ScreenPtr pScreen)
+{
+ WindowPtr pWin;
+ BoxRec box;
+ PixmapFormatRec *format;
+
+ pWin = AllocateWindow(pScreen);
+ if (!pWin)
+ return FALSE;
+
+ savedScreenInfo[pScreen->myNum].pWindow = NULL;
+ savedScreenInfo[pScreen->myNum].wid = FakeClientID(0);
+ savedScreenInfo[pScreen->myNum].ExternalScreenSaver = NULL;
+ screenIsSaved = SCREEN_SAVER_OFF;
+
+ WindowTable[pScreen->myNum] = pWin;
+
+ pWin->drawable.pScreen = pScreen;
+ pWin->drawable.type = DRAWABLE_WINDOW;
+
+ pWin->drawable.depth = pScreen->rootDepth;
+ for (format = screenInfo.formats;
+ format->depth != pScreen->rootDepth;
+ format++)
+ ;
+ pWin->drawable.bitsPerPixel = format->bitsPerPixel;
+
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+ pWin->parent = NullWindow;
+ SetWindowToDefaults(pWin);
+
+ pWin->optional = (WindowOptRec *) xalloc (sizeof (WindowOptRec));
+ if (!pWin->optional)
+ return FALSE;
+
+ pWin->optional->dontPropagateMask = 0;
+ pWin->optional->otherEventMasks = 0;
+ pWin->optional->otherClients = NULL;
+ pWin->optional->passiveGrabs = NULL;
+ pWin->optional->userProps = NULL;
+ pWin->optional->backingBitPlanes = ~0L;
+ pWin->optional->backingPixel = 0;
+#ifdef SHAPE
+ pWin->optional->boundingShape = NULL;
+ pWin->optional->clipShape = NULL;
+ pWin->optional->inputShape = NULL;
+#endif
+#ifdef XINPUT
+ pWin->optional->inputMasks = NULL;
+#endif
+ pWin->optional->colormap = pScreen->defColormap;
+ pWin->optional->visual = pScreen->rootVisual;
+
+ pWin->nextSib = NullWindow;
+
+ pWin->drawable.id = FakeClientID(0);
+
+ pWin->origin.x = pWin->origin.y = 0;
+ pWin->drawable.height = pScreen->height;
+ pWin->drawable.width = pScreen->width;
+ pWin->drawable.x = pWin->drawable.y = 0;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pScreen->width;
+ box.y2 = pScreen->height;
+ REGION_INIT(pScreen, &pWin->clipList, &box, 1);
+ REGION_INIT(pScreen, &pWin->winSize, &box, 1);
+ REGION_INIT(pScreen, &pWin->borderSize, &box, 1);
+ REGION_INIT(pScreen, &pWin->borderClip, &box, 1);
+
+ pWin->drawable.class = InputOutput;
+ pWin->optional->visual = pScreen->rootVisual;
+
+ pWin->backgroundState = BackgroundPixel;
+ pWin->background.pixel = pScreen->whitePixel;
+
+ pWin->borderIsPixel = TRUE;
+ pWin->border.pixel = pScreen->blackPixel;
+ pWin->borderWidth = 0;
+
+ if (!AddResource(pWin->drawable.id, RT_WINDOW, (pointer)pWin))
+ return FALSE;
+
+ if (disableBackingStore)
+ {
+ pScreen -> backingStoreSupport = NotUseful;
+ }
+
+ if (enableBackingStore)
+ {
+ pScreen -> backingStoreSupport = Always;
+ }
+
+ pScreen->saveUnderSupport = False;
+
+#ifdef DO_SAVE_UNDERS
+ if ((pScreen->backingStoreSupport != NotUseful) &&
+ (pScreen->saveUnderSupport == NotUseful))
+ {
+ /*
+ * If the screen has backing-store but no save-unders, let the
+ * clients know we can support save-unders using backing-store.
+ */
+ pScreen->saveUnderSupport = USE_DIX_SAVE_UNDERS;
+ }
+#endif /* DO_SAVE_UNDERS */
+
+ if (disableSaveUnders)
+ pScreen->saveUnderSupport = NotUseful;
+
+ return TRUE;
+}
+
+#ifdef NXAGENT_SERVER
+
+void
+InitRootWindow(WindowPtr pWin)
+{
+ ScreenPtr pScreen;
+
+ #ifdef TEST
+ fprintf(stderr, "InitRootWindow: Called for window at [%p][%ld] with parent [%p].\n",
+ (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
+ #endif
+
+ if (nxagentOption(Rootless))
+ {
+ #ifdef TEST
+ fprintf(stderr, "InitRootWindow: Assigned agent root to window at [%p][%ld] with parent [%p].\n",
+ (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
+ #endif
+
+ nxagentRootlessWindow = pWin;
+ }
+
+ pScreen = pWin->drawable.pScreen;
+
+ /*
+ * A root window is created for each screen by main
+ * and the pointer is saved in WindowTable as in the
+ * following snippet:
+ *
+ * for (i = 0; i < screenInfo.numScreens; i++)
+ * InitRootWindow(WindowTable[i]);
+ *
+ * Our root window on the real display was already
+ * created at the time the screen was opened, so it
+ * is unclear how this window (or the other window,
+ * if you prefer) fits in the big picture.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "InitRootWindow: Going to create window as root at [%p][%ld] with parent [%p].\n",
+ (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
+ #endif
+
+ if (!(*pScreen->CreateWindow)(pWin))
+ return; /* XXX */
+
+ #ifdef TEST
+ fprintf(stderr, "InitRootWindow: Created window as root at [%p][%ld] with parent [%p].\n",
+ (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
+ #endif
+
+ (*pScreen->PositionWindow)(pWin, 0, 0);
+
+ pWin->cursorIsNone = FALSE;
+ pWin->optional->cursor = rootCursor;
+ rootCursor->refcnt++;
+ pWin->backingStore = defaultBackingStore;
+ pWin->forcedBS = (defaultBackingStore != NotUseful);
+
+ #ifdef NXAGENT_SPLASH
+ /* We SHOULD check for an error value here XXX */
+ pWin -> background.pixel = pScreen -> blackPixel;
+ (*pScreen->ChangeWindowAttributes)(pWin,
+ CWBackPixel|CWBorderPixel|CWCursor|CWBackingStore);
+ #else
+ (*pScreen->ChangeWindowAttributes)(pWin,
+ CWBackPixmap|CWBorderPixel|CWCursor|CWBackingStore);
+ #endif
+
+ MakeRootTile(pWin);
+
+ /*
+ * Map both the root and the default agent window.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "InitRootWindow: Mapping default windows.\n");
+ #endif
+
+ nxagentInitAtoms(pWin);
+
+ nxagentInitClipboard(pWin);
+
+ nxagentMapDefaultWindows();
+
+ nxagentRedirectDefaultWindows();
+
+ #ifdef NXAGENT_ARTSD
+ {
+ char artsd_port[10];
+ int nPort;
+ extern void nxagentPropagateArtsdProperties(ScreenPtr pScreen, char *port);
+ nPort = atoi(display) + 7000;
+ sprintf(artsd_port,"%d", nPort);
+ nxagentPropagateArtsdProperties(pScreen, artsd_port);
+ }
+ #endif
+}
+
+#else /* NXAGENT_SERVER */
+
+void
+InitRootWindow(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ if (!(*pScreen->CreateWindow)(pWin))
+ return; /* XXX */
+ (*pScreen->PositionWindow)(pWin, 0, 0);
+
+ pWin->cursorIsNone = FALSE;
+ pWin->optional->cursor = rootCursor;
+ rootCursor->refcnt++;
+ MakeRootTile(pWin);
+ pWin->backingStore = defaultBackingStore;
+ pWin->forcedBS = (defaultBackingStore != NotUseful);
+ /* We SHOULD check for an error value here XXX */
+ (*pScreen->ChangeWindowAttributes)(pWin,
+ CWBackPixmap|CWBorderPixel|CWCursor|CWBackingStore);
+
+ MapWindow(pWin, serverClient);
+}
+
+#endif /* NXAGENT_SERVER */
+
+/* Set the region to the intersection of the rectangle and the
+ * window's winSize. The window is typically the parent of the
+ * window from which the region came.
+ */
+
+void
+ClippedRegionFromBox(register WindowPtr pWin, RegionPtr Rgn,
+ register int x, register int y,
+ register int w, register int h)
+{
+#ifndef NXAGENT_SERVER
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+#endif /* NXAGENT_SERVER */
+ BoxRec box;
+
+ box = *(REGION_EXTENTS(pScreen, &pWin->winSize));
+ /* we do these calculations to avoid overflows */
+ if (x > box.x1)
+ box.x1 = x;
+ if (y > box.y1)
+ box.y1 = y;
+ x += w;
+ if (x < box.x2)
+ box.x2 = x;
+ y += h;
+ if (y < box.y2)
+ box.y2 = y;
+ if (box.x1 > box.x2)
+ box.x2 = box.x1;
+ if (box.y1 > box.y2)
+ box.y2 = box.y1;
+ REGION_RESET(pScreen, Rgn, &box);
+ REGION_INTERSECT(pScreen, Rgn, Rgn, &pWin->winSize);
+}
+
+WindowPtr
+RealChildHead(register WindowPtr pWin)
+{
+ if (!pWin->parent &&
+ (screenIsSaved == SCREEN_SAVER_ON) &&
+ (HasSaverWindow (pWin->drawable.pScreen->myNum)))
+ return (pWin->firstChild);
+ else
+ return (NullWindow);
+}
+
+/*****
+ * CreateWindow
+ * Makes a window in response to client request
+ *****/
+
+WindowPtr
+CreateWindow(Window wid, register WindowPtr pParent, int x, int y, unsigned w,
+ unsigned h, unsigned bw, unsigned class, register Mask vmask, XID *vlist,
+ int depth, ClientPtr client, VisualID visual, int *error)
+{
+ register WindowPtr pWin;
+ WindowPtr pHead;
+ register ScreenPtr pScreen;
+ xEvent event;
+ int idepth, ivisual;
+ Bool fOK;
+ DepthPtr pDepth;
+ PixmapFormatRec *format;
+ register WindowOptPtr ancwopt;
+
+ if (class == CopyFromParent)
+ class = pParent->drawable.class;
+
+ if ((class != InputOutput) && (class != InputOnly))
+ {
+ *error = BadValue;
+ client->errorValue = class;
+ return NullWindow;
+ }
+
+ if ((class != InputOnly) && (pParent->drawable.class == InputOnly))
+ {
+ *error = BadMatch;
+ return NullWindow;
+ }
+
+ if ((class == InputOnly) && ((bw != 0) || (depth != 0)))
+ {
+ *error = BadMatch;
+ return NullWindow;
+ }
+
+ pScreen = pParent->drawable.pScreen;
+ if ((class == InputOutput) && (depth == 0))
+ depth = pParent->drawable.depth;
+ ancwopt = pParent->optional;
+ if (!ancwopt)
+ ancwopt = FindWindowWithOptional(pParent)->optional;
+ if (visual == CopyFromParent) {
+#ifdef XAPPGROUP
+ VisualID ag_visual;
+
+ if (client->appgroup && !pParent->parent &&
+ (ag_visual = XagRootVisual (client)))
+ visual = ag_visual;
+ else
+#endif
+ visual = ancwopt->visual;
+ }
+
+ /* Find out if the depth and visual are acceptable for this Screen */
+ if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth))
+ {
+ fOK = FALSE;
+ for(idepth = 0; idepth < pScreen->numDepths; idepth++)
+ {
+ pDepth = (DepthPtr) &pScreen->allowedDepths[idepth];
+ if ((depth == pDepth->depth) || (depth == 0))
+ {
+ for (ivisual = 0; ivisual < pDepth->numVids; ivisual++)
+ {
+ if (visual == pDepth->vids[ivisual])
+ {
+ fOK = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ if (fOK == FALSE)
+ {
+ *error = BadMatch;
+ return NullWindow;
+ }
+ }
+
+ if (((vmask & (CWBorderPixmap | CWBorderPixel)) == 0) &&
+ (class != InputOnly) &&
+ (depth != pParent->drawable.depth))
+ {
+ *error = BadMatch;
+ return NullWindow;
+ }
+
+ if (((vmask & CWColormap) == 0) &&
+ (class != InputOnly) &&
+ ((visual != ancwopt->visual) || (ancwopt->colormap == None)))
+ {
+ *error = BadMatch;
+ return NullWindow;
+ }
+
+ pWin = AllocateWindow(pScreen);
+ if (!pWin)
+ {
+ *error = BadAlloc;
+ return NullWindow;
+ }
+ pWin->drawable = pParent->drawable;
+ pWin->drawable.depth = depth;
+ if (depth == pParent->drawable.depth)
+ pWin->drawable.bitsPerPixel = pParent->drawable.bitsPerPixel;
+ else
+ {
+ for (format = screenInfo.formats; format->depth != depth; format++)
+ ;
+ pWin->drawable.bitsPerPixel = format->bitsPerPixel;
+ }
+ if (class == InputOnly)
+ pWin->drawable.type = (short) UNDRAWABLE_WINDOW;
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+ pWin->drawable.id = wid;
+ pWin->drawable.class = class;
+
+ pWin->parent = pParent;
+ SetWindowToDefaults(pWin);
+
+ if (visual != ancwopt->visual)
+ {
+ if (!MakeWindowOptional (pWin))
+ {
+ xfree (pWin);
+ *error = BadAlloc;
+ return NullWindow;
+ }
+ pWin->optional->visual = visual;
+ pWin->optional->colormap = None;
+ }
+
+ pWin->borderWidth = bw;
+#ifdef XCSECURITY
+ /* can't let untrusted clients have background None windows;
+ * they make it too easy to steal window contents
+ */
+ if (client->trustLevel != XSecurityClientTrusted)
+ {
+ pWin->backgroundState = BackgroundPixel;
+ pWin->background.pixel = 0;
+ }
+ else
+#endif
+ pWin->backgroundState = None;
+
+ pWin->borderIsPixel = pParent->borderIsPixel;
+ pWin->border = pParent->border;
+ if (pWin->borderIsPixel == FALSE)
+ pWin->border.pixmap->refcnt++;
+
+ pWin->origin.x = x + (int)bw;
+ pWin->origin.y = y + (int)bw;
+ pWin->drawable.width = w;
+ pWin->drawable.height = h;
+ pWin->drawable.x = pParent->drawable.x + x + (int)bw;
+ pWin->drawable.y = pParent->drawable.y + y + (int)bw;
+
+ /* set up clip list correctly for unobscured WindowPtr */
+ REGION_NULL(pScreen, &pWin->clipList);
+ REGION_NULL(pScreen, &pWin->borderClip);
+ REGION_NULL(pScreen, &pWin->winSize);
+ REGION_NULL(pScreen, &pWin->borderSize);
+
+ pHead = RealChildHead(pParent);
+ if (pHead)
+ {
+ pWin->nextSib = pHead->nextSib;
+ if (pHead->nextSib)
+ pHead->nextSib->prevSib = pWin;
+ else
+ pParent->lastChild = pWin;
+ pHead->nextSib = pWin;
+ pWin->prevSib = pHead;
+ }
+ else
+ {
+ pWin->nextSib = pParent->firstChild;
+ if (pParent->firstChild)
+ pParent->firstChild->prevSib = pWin;
+ else
+ pParent->lastChild = pWin;
+ pParent->firstChild = pWin;
+ }
+
+ SetWinSize (pWin);
+ SetBorderSize (pWin);
+
+ /* We SHOULD check for an error value here XXX */
+ if (!(*pScreen->CreateWindow)(pWin))
+ {
+ *error = BadAlloc;
+ DeleteWindow(pWin, None);
+ return NullWindow;
+ }
+ /* We SHOULD check for an error value here XXX */
+ (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
+
+ if (!(vmask & CWEventMask))
+ RecalculateDeliverableEvents(pWin);
+
+ if (vmask)
+ *error = ChangeWindowAttributes(pWin, vmask, vlist, wClient (pWin));
+ else
+ *error = Success;
+
+ if (*error != Success)
+ {
+ DeleteWindow(pWin, None);
+ return NullWindow;
+ }
+ if (!(vmask & CWBackingStore) && (defaultBackingStore != NotUseful))
+ {
+ XID value = defaultBackingStore;
+ (void)ChangeWindowAttributes(pWin, CWBackingStore, &value, wClient (pWin));
+ pWin->forcedBS = TRUE;
+ }
+
+ if (SubSend(pParent))
+ {
+ event.u.u.type = CreateNotify;
+ event.u.createNotify.window = wid;
+ event.u.createNotify.parent = pParent->drawable.id;
+ event.u.createNotify.x = x;
+ event.u.createNotify.y = y;
+ event.u.createNotify.width = w;
+ event.u.createNotify.height = h;
+ event.u.createNotify.borderWidth = bw;
+ event.u.createNotify.override = pWin->overrideRedirect;
+ DeliverEvents(pParent, &event, 1, NullWindow);
+ }
+ return pWin;
+}
+
+static void
+FreeWindowResources(register WindowPtr pWin)
+{
+ register ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ DeleteWindowFromAnySaveSet(pWin);
+ DeleteWindowFromAnySelections(pWin);
+ DeleteWindowFromAnyEvents(pWin, TRUE);
+ REGION_UNINIT(pScreen, &pWin->clipList);
+ REGION_UNINIT(pScreen, &pWin->winSize);
+ REGION_UNINIT(pScreen, &pWin->borderClip);
+ REGION_UNINIT(pScreen, &pWin->borderSize);
+#ifdef SHAPE
+ if (wBoundingShape (pWin))
+ REGION_DESTROY(pScreen, wBoundingShape (pWin));
+ if (wClipShape (pWin))
+ REGION_DESTROY(pScreen, wClipShape (pWin));
+ if (wInputShape (pWin))
+ REGION_DESTROY(pScreen, wInputShape (pWin));
+#endif
+ if (pWin->borderIsPixel == FALSE)
+ (*pScreen->DestroyPixmap)(pWin->border.pixmap);
+ if (pWin->backgroundState == BackgroundPixmap)
+ (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+
+ DeleteAllWindowProperties(pWin);
+ /* We SHOULD check for an error value here XXX */
+ (*pScreen->DestroyWindow)(pWin);
+ DisposeWindowOptional (pWin);
+}
+
+static void
+CrushTree(WindowPtr pWin)
+{
+ register WindowPtr pChild, pSib, pParent;
+ UnrealizeWindowProcPtr UnrealizeWindow;
+ xEvent event;
+
+ if (!(pChild = pWin->firstChild))
+ return;
+ UnrealizeWindow = pWin->drawable.pScreen->UnrealizeWindow;
+ while (1)
+ {
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ while (1)
+ {
+ pParent = pChild->parent;
+ if (SubStrSend(pChild, pParent))
+ {
+ event.u.u.type = DestroyNotify;
+ event.u.destroyNotify.window = pChild->drawable.id;
+ DeliverEvents(pChild, &event, 1, NullWindow);
+ }
+ FreeResource(pChild->drawable.id, RT_WINDOW);
+ pSib = pChild->nextSib;
+#ifdef DO_SAVE_UNDERS
+ if (pChild->saveUnder && pChild->viewable)
+ deltaSaveUndersViewable--;
+#endif
+ pChild->viewable = FALSE;
+ if (pChild->realized)
+ {
+ pChild->realized = FALSE;
+ (*UnrealizeWindow)(pChild);
+ }
+ FreeWindowResources(pChild);
+ xfree(pChild);
+ if ( (pChild = pSib) )
+ break;
+ pChild = pParent;
+ pChild->firstChild = NullWindow;
+ pChild->lastChild = NullWindow;
+ if (pChild == pWin)
+ return;
+ }
+ }
+}
+
+/*****
+ * DeleteWindow
+ * Deletes child of window then window itself
+ * If wid is None, don't send any events
+ *****/
+
+int
+DeleteWindow(pointer value, XID wid)
+ {
+ register WindowPtr pParent;
+ register WindowPtr pWin = (WindowPtr)value;
+ xEvent event;
+
+ UnmapWindow(pWin, FALSE);
+
+ CrushTree(pWin);
+
+ pParent = pWin->parent;
+ if (wid && pParent && SubStrSend(pWin, pParent))
+ {
+ event.u.u.type = DestroyNotify;
+ event.u.destroyNotify.window = pWin->drawable.id;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ }
+
+ FreeWindowResources(pWin);
+ if (pParent)
+ {
+ if (pParent->firstChild == pWin)
+ pParent->firstChild = pWin->nextSib;
+ if (pParent->lastChild == pWin)
+ pParent->lastChild = pWin->prevSib;
+ if (pWin->nextSib)
+ pWin->nextSib->prevSib = pWin->prevSib;
+ if (pWin->prevSib)
+ pWin->prevSib->nextSib = pWin->nextSib;
+ }
+
+ if (pWin -> optional &&
+ pWin -> optional -> colormap &&
+ pWin -> parent)
+ {
+ nxagentSetInstalledColormapWindows(pWin -> drawable.pScreen);
+ }
+
+ xfree(pWin);
+ return Success;
+}
+
+void
+DestroySubwindows(register WindowPtr pWin, ClientPtr client)
+{
+ /* XXX
+ * The protocol is quite clear that each window should be
+ * destroyed in turn, however, unmapping all of the first
+ * eliminates most of the calls to ValidateTree. So,
+ * this implementation is incorrect in that all of the
+ * UnmapNotifies occur before all of the DestroyNotifies.
+ * If you care, simply delete the call to UnmapSubwindows.
+ */
+ UnmapSubwindows(pWin);
+ while (pWin->lastChild)
+ FreeResource(pWin->lastChild->drawable.id, RT_NONE);
+}
+
+#define DeviceEventMasks (KeyPressMask | KeyReleaseMask | ButtonPressMask | \
+ ButtonReleaseMask | PointerMotionMask)
+
+/*****
+ * ChangeWindowAttributes
+ *
+ * The value-mask specifies which attributes are to be changed; the
+ * value-list contains one value for each one bit in the mask, from least
+ * to most significant bit in the mask.
+ *****/
+
+int
+ChangeWindowAttributes(register WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
+{
+ register Mask index2;
+ register XID *pVlist;
+ PixmapPtr pPixmap;
+ Pixmap pixID;
+ CursorPtr pCursor, pOldCursor;
+ Cursor cursorID;
+ WindowPtr pChild;
+ Colormap cmap;
+ ColormapPtr pCmap;
+ xEvent xE;
+ int result;
+ register ScreenPtr pScreen;
+ Mask vmaskCopy = 0;
+ register Mask tmask;
+ unsigned int val;
+ int error;
+ Bool checkOptional = FALSE;
+ Bool borderRelative = FALSE;
+ WindowPtr pLayerWin;
+
+ if ((pWin->drawable.class == InputOnly) && (vmask & (~INPUTONLY_LEGAL_MASK)))
+ return BadMatch;
+
+ error = Success;
+ pScreen = pWin->drawable.pScreen;
+ pVlist = vlist;
+ tmask = vmask;
+ while (tmask)
+ {
+ index2 = (Mask) lowbit (tmask);
+ tmask &= ~index2;
+ switch (index2)
+ {
+ case CWBackPixmap:
+ pixID = (Pixmap )*pVlist;
+ pVlist++;
+ if (pWin->backgroundState == ParentRelative)
+ borderRelative = TRUE;
+ if (pixID == None)
+ {
+#ifdef XCSECURITY
+ /* can't let untrusted clients have background None windows */
+ if (client->trustLevel == XSecurityClientTrusted)
+ {
+#endif
+ if (pWin->backgroundState == BackgroundPixmap)
+ (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+ if (!pWin->parent)
+ MakeRootTile(pWin);
+ else
+ pWin->backgroundState = None;
+#ifdef XCSECURITY
+ }
+ else
+ { /* didn't change the background to None, so don't tell ddx */
+ index2 = 0;
+ }
+#endif
+ }
+ else if (pixID == ParentRelative)
+ {
+ if (pWin->parent &&
+ pWin->drawable.depth != pWin->parent->drawable.depth)
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ if (pWin->backgroundState == BackgroundPixmap)
+ (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+ if (!pWin->parent)
+ MakeRootTile(pWin);
+ else
+ pWin->backgroundState = ParentRelative;
+ borderRelative = TRUE;
+ /* Note that the parent's backgroundTile's refcnt is NOT
+ * incremented. */
+ }
+ else
+ {
+ pPixmap = (PixmapPtr)SecurityLookupIDByType(client, pixID,
+ RT_PIXMAP, SecurityReadAccess);
+ if (pPixmap != (PixmapPtr) NULL)
+ {
+ if ((pPixmap->drawable.depth != pWin->drawable.depth) ||
+ (pPixmap->drawable.pScreen != pScreen))
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ if (pWin->backgroundState == BackgroundPixmap)
+ (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+ pWin->backgroundState = BackgroundPixmap;
+ pWin->background.pixmap = pPixmap;
+ pPixmap->refcnt++;
+ }
+ else
+ {
+ error = BadPixmap;
+ client->errorValue = pixID;
+ goto PatchUp;
+ }
+ }
+ break;
+ case CWBackPixel:
+ if (pWin->backgroundState == ParentRelative)
+ borderRelative = TRUE;
+ if (pWin->backgroundState == BackgroundPixmap)
+ (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+ pWin->backgroundState = BackgroundPixel;
+ pWin->background.pixel = (CARD32 ) *pVlist;
+ /* background pixel overrides background pixmap,
+ so don't let the ddx layer see both bits */
+ vmaskCopy &= ~CWBackPixmap;
+ pVlist++;
+ break;
+ case CWBorderPixmap:
+ pixID = (Pixmap ) *pVlist;
+ pVlist++;
+ if (pixID == CopyFromParent)
+ {
+ if (!pWin->parent ||
+ (pWin->drawable.depth != pWin->parent->drawable.depth))
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ if (pWin->borderIsPixel == FALSE)
+ (*pScreen->DestroyPixmap)(pWin->border.pixmap);
+ pWin->border = pWin->parent->border;
+ if ((pWin->borderIsPixel = pWin->parent->borderIsPixel) == TRUE)
+ {
+ index2 = CWBorderPixel;
+ }
+ else
+ {
+ pWin->parent->border.pixmap->refcnt++;
+ }
+ }
+ else
+ {
+ pPixmap = (PixmapPtr)SecurityLookupIDByType(client, pixID,
+ RT_PIXMAP, SecurityReadAccess);
+ if (pPixmap)
+ {
+ if ((pPixmap->drawable.depth != pWin->drawable.depth) ||
+ (pPixmap->drawable.pScreen != pScreen))
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ if (pWin->borderIsPixel == FALSE)
+ (*pScreen->DestroyPixmap)(pWin->border.pixmap);
+ pWin->borderIsPixel = FALSE;
+ pWin->border.pixmap = pPixmap;
+ pPixmap->refcnt++;
+ }
+ else
+ {
+ error = BadPixmap;
+ client->errorValue = pixID;
+ goto PatchUp;
+ }
+ }
+ break;
+ case CWBorderPixel:
+ if (pWin->borderIsPixel == FALSE)
+ (*pScreen->DestroyPixmap)(pWin->border.pixmap);
+ pWin->borderIsPixel = TRUE;
+ pWin->border.pixel = (CARD32) *pVlist;
+ /* border pixel overrides border pixmap,
+ so don't let the ddx layer see both bits */
+ vmaskCopy &= ~CWBorderPixmap;
+ pVlist++;
+ break;
+ case CWBitGravity:
+ val = (CARD8 )*pVlist;
+ pVlist++;
+ if (val > StaticGravity)
+ {
+ error = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ pWin->bitGravity = val;
+ break;
+ case CWWinGravity:
+ val = (CARD8 )*pVlist;
+ pVlist++;
+ if (val > StaticGravity)
+ {
+ error = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ pWin->winGravity = val;
+ break;
+ case CWBackingStore:
+ val = (CARD8 )*pVlist;
+ pVlist++;
+ if ((val != NotUseful) && (val != WhenMapped) && (val != Always))
+ {
+ error = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ pWin->backingStore = val;
+
+ #ifdef TEST
+ fprintf(stderr, "ChangeWindowAttributes: Changed backing store value to %d for window at %p.\n",
+ val, (void*)pWin);
+ #endif
+
+ pWin->forcedBS = FALSE;
+ break;
+ case CWBackingPlanes:
+ if (pWin->optional || ((CARD32)*pVlist != (CARD32)~0L)) {
+ if (!pWin->optional && !MakeWindowOptional (pWin))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ pWin->optional->backingBitPlanes = (CARD32) *pVlist;
+ if ((CARD32)*pVlist == (CARD32)~0L)
+ checkOptional = TRUE;
+ }
+ pVlist++;
+ break;
+ case CWBackingPixel:
+ if (pWin->optional || (CARD32) *pVlist) {
+ if (!pWin->optional && !MakeWindowOptional (pWin))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ pWin->optional->backingPixel = (CARD32) *pVlist;
+ if (!*pVlist)
+ checkOptional = TRUE;
+ }
+ pVlist++;
+ break;
+ case CWSaveUnder:
+ val = (BOOL) *pVlist;
+ pVlist++;
+ if ((val != xTrue) && (val != xFalse))
+ {
+ error = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+#ifdef DO_SAVE_UNDERS
+ if (pWin->parent && (pWin->saveUnder != val) && (pWin->viewable) &&
+ DO_SAVE_UNDERS(pWin))
+ {
+ /*
+ * Re-check all siblings and inferiors for obscurity or
+ * exposition (hee hee).
+ */
+ if (pWin->saveUnder)
+ deltaSaveUndersViewable--;
+ else
+ deltaSaveUndersViewable++;
+ pWin->saveUnder = val;
+
+ if (pWin->firstChild)
+ {
+ pLayerWin = (*pScreen->GetLayerWindow)(pWin);
+ if ((*pScreen->ChangeSaveUnder)(pLayerWin->parent, pWin->nextSib))
+ (*pScreen->PostChangeSaveUnder)(pLayerWin->parent,
+ pWin->nextSib);
+ }
+ else
+ {
+ if ((*pScreen->ChangeSaveUnder)(pWin, pWin->nextSib))
+ (*pScreen->PostChangeSaveUnder)(pWin,
+ pWin->nextSib);
+ }
+ }
+ else
+ {
+ /* If we're changing the saveUnder attribute of the root
+ * window, all we do is set pWin->saveUnder so that
+ * GetWindowAttributes returns the right value. We don't
+ * do the "normal" save-under processing (as above).
+ * Hope that doesn't cause any problems.
+ */
+ pWin->saveUnder = val;
+ }
+#else
+ pWin->saveUnder = val;
+#endif /* DO_SAVE_UNDERS */
+ break;
+ case CWEventMask:
+ /*
+ * TODO: Some applications like java bean shell
+ * don' t work if they cannot monitor the root
+ * window for Structure Redirect events. However
+ * this doesn't seem to be the best solution, since
+ * also an X server with a window manager running,
+ * doesn't allow to monitor for those events, but
+ * the java bean shell works flawlessy on this
+ * server.
+ *
+ * if (nxagentCheckIllegalRootMonitoring(pWin, (Mask)*pVlist))
+ * {
+ * return BadAccess;
+ * }
+ */
+
+ result = EventSelectForWindow(pWin, client, (Mask )*pVlist);
+ if (result)
+ {
+ error = result;
+ goto PatchUp;
+ }
+ pVlist++;
+ break;
+ case CWDontPropagate:
+ result = EventSuppressForWindow(pWin, client, (Mask )*pVlist,
+ &checkOptional);
+ if (result)
+ {
+ error = result;
+ goto PatchUp;
+ }
+ pVlist++;
+ break;
+ case CWOverrideRedirect:
+ val = (BOOL ) *pVlist;
+ pVlist++;
+ if ((val != xTrue) && (val != xFalse))
+ {
+ error = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ pWin->overrideRedirect = val;
+ break;
+ case CWColormap:
+ cmap = (Colormap) *pVlist;
+ pVlist++;
+ if (cmap == CopyFromParent)
+ {
+#ifdef XAPPGROUP
+ Colormap ag_colormap;
+ ClientPtr win_owner;
+
+ /*
+ * win_owner == client for CreateWindow, other clients
+ * can ChangeWindowAttributes
+ */
+ win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+
+ if ( win_owner && win_owner->appgroup &&
+ !pWin->parent->parent &&
+ (ag_colormap = XagDefaultColormap (win_owner)))
+ cmap = ag_colormap;
+ else
+#endif
+ if (pWin->parent &&
+ (!pWin->optional ||
+ pWin->optional->visual == wVisual (pWin->parent)))
+ {
+ cmap = wColormap (pWin->parent);
+ }
+ else
+ cmap = None;
+ }
+ if (cmap == None)
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ pCmap = (ColormapPtr)SecurityLookupIDByType(client, cmap,
+ RT_COLORMAP, SecurityReadAccess);
+ if (!pCmap)
+ {
+ error = BadColor;
+ client->errorValue = cmap;
+ goto PatchUp;
+ }
+ if (pCmap->pVisual->vid != wVisual (pWin) ||
+ pCmap->pScreen != pScreen)
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ if (cmap != wColormap (pWin))
+ {
+ if (!pWin->optional)
+ {
+ if (!MakeWindowOptional (pWin))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ }
+ else if (pWin->parent && cmap == wColormap (pWin->parent))
+ checkOptional = TRUE;
+
+ /*
+ * propagate the original colormap to any children
+ * inheriting it
+ */
+
+ for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+ {
+ if (!pChild->optional && !MakeWindowOptional (pChild))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ }
+
+ pWin->optional->colormap = cmap;
+
+ /*
+ * check on any children now matching the new colormap
+ */
+
+ for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+ {
+ if (pChild->optional->colormap == cmap)
+ CheckWindowOptionalNeed (pChild);
+ }
+
+ xE.u.u.type = ColormapNotify;
+ xE.u.colormap.window = pWin->drawable.id;
+ xE.u.colormap.colormap = cmap;
+ xE.u.colormap.new = xTrue;
+ xE.u.colormap.state = IsMapInstalled(cmap, pWin);
+ DeliverEvents(pWin, &xE, 1, NullWindow);
+ }
+ break;
+ case CWCursor:
+ cursorID = (Cursor ) *pVlist;
+ pVlist++;
+ /*
+ * install the new
+ */
+ if ( cursorID == None)
+ {
+ if (pWin == WindowTable[pWin->drawable.pScreen->myNum])
+ pCursor = rootCursor;
+ else
+ pCursor = (CursorPtr) None;
+ }
+ else
+ {
+ pCursor = (CursorPtr)SecurityLookupIDByType(client, cursorID,
+ RT_CURSOR, SecurityReadAccess);
+ if (!pCursor)
+ {
+ error = BadCursor;
+ client->errorValue = cursorID;
+ goto PatchUp;
+ }
+ }
+
+ if (pCursor != wCursor (pWin))
+ {
+ /*
+ * patch up child windows so they don't lose cursors.
+ */
+
+ for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+ {
+ if (!pChild->optional && !pChild->cursorIsNone &&
+ !MakeWindowOptional (pChild))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ }
+
+ pOldCursor = 0;
+ if (pCursor == (CursorPtr) None)
+ {
+ pWin->cursorIsNone = TRUE;
+ if (pWin->optional)
+ {
+ pOldCursor = pWin->optional->cursor;
+ pWin->optional->cursor = (CursorPtr) None;
+ checkOptional = TRUE;
+ }
+ } else {
+ if (!pWin->optional)
+ {
+ if (!MakeWindowOptional (pWin))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ }
+ else if (pWin->parent && pCursor == wCursor (pWin->parent))
+ checkOptional = TRUE;
+ pOldCursor = pWin->optional->cursor;
+ pWin->optional->cursor = pCursor;
+ pCursor->refcnt++;
+ pWin->cursorIsNone = FALSE;
+ /*
+ * check on any children now matching the new cursor
+ */
+
+ for (pChild=pWin->firstChild; pChild; pChild=pChild->nextSib)
+ {
+ if (pChild->optional &&
+ (pChild->optional->cursor == pCursor))
+ CheckWindowOptionalNeed (pChild);
+ }
+ }
+
+ if (pWin->realized)
+ WindowHasNewCursor( pWin);
+
+ /* Can't free cursor until here - old cursor
+ * is needed in WindowHasNewCursor
+ */
+ if (pOldCursor)
+ FreeCursor (pOldCursor, (Cursor)0);
+ }
+ break;
+ default:
+ error = BadValue;
+ client->errorValue = vmask;
+ goto PatchUp;
+ }
+ vmaskCopy |= index2;
+ }
+PatchUp:
+ if (checkOptional)
+ CheckWindowOptionalNeed (pWin);
+
+ /* We SHOULD check for an error value here XXX */
+ (*pScreen->ChangeWindowAttributes)(pWin, vmaskCopy);
+
+ /*
+ If the border contents have changed, redraw the border.
+ Note that this has to be done AFTER pScreen->ChangeWindowAttributes
+ for the tile to be rotated, and the correct function selected.
+ */
+ if (((vmaskCopy & (CWBorderPixel | CWBorderPixmap)) || borderRelative)
+ && pWin->viewable && HasBorder (pWin))
+ {
+ RegionRec exposed;
+
+ REGION_NULL(pScreen, &exposed);
+ REGION_SUBTRACT(pScreen, &exposed, &pWin->borderClip, &pWin->winSize);
+ (*pWin->drawable.pScreen->PaintWindowBorder)(pWin, &exposed, PW_BORDER);
+ REGION_UNINIT(pScreen, &exposed);
+ }
+ return error;
+}
+
+
+/*****
+ * GetWindowAttributes
+ * Notice that this is different than ChangeWindowAttributes
+ *****/
+
+void
+GetWindowAttributes(register WindowPtr pWin, ClientPtr client, xGetWindowAttributesReply *wa)
+{
+ wa->type = X_Reply;
+ wa->bitGravity = pWin->bitGravity;
+ wa->winGravity = pWin->winGravity;
+ if (pWin->forcedBS && pWin->backingStore != Always)
+ wa->backingStore = NotUseful;
+ else
+ wa->backingStore = pWin->backingStore;
+ wa->length = (sizeof(xGetWindowAttributesReply) -
+ sizeof(xGenericReply)) >> 2;
+ wa->sequenceNumber = client->sequence;
+ wa->backingBitPlanes = wBackingBitPlanes (pWin);
+ wa->backingPixel = wBackingPixel (pWin);
+ wa->saveUnder = (BOOL)pWin->saveUnder;
+ wa->override = pWin->overrideRedirect;
+ if (!pWin->mapped)
+ wa->mapState = IsUnmapped;
+ else if (pWin->realized)
+ wa->mapState = IsViewable;
+ else
+ wa->mapState = IsUnviewable;
+
+ wa->colormap = wColormap (pWin);
+ wa->mapInstalled = (wa->colormap == None) ? xFalse
+ : IsMapInstalled(wa->colormap, pWin);
+
+ wa->yourEventMask = EventMaskForClient(pWin, client);
+ wa->allEventMasks = pWin->eventMask | wOtherEventMasks (pWin);
+ wa->doNotPropagateMask = wDontPropagateMask (pWin);
+ wa->class = pWin->drawable.class;
+ wa->visualID = wVisual (pWin);
+}
+
+
+WindowPtr
+MoveWindowInStack(register WindowPtr pWin, register WindowPtr pNextSib)
+{
+ register WindowPtr pParent = pWin->parent;
+ WindowPtr pFirstChange = pWin; /* highest window where list changes */
+
+ if (pWin->nextSib != pNextSib)
+ {
+ WindowPtr pOldNextSib = pWin->nextSib;
+
+ if (!pNextSib) /* move to bottom */
+ {
+ if (pParent->firstChild == pWin)
+ pParent->firstChild = pWin->nextSib;
+ /* if (pWin->nextSib) */ /* is always True: pNextSib == NULL
+ * and pWin->nextSib != pNextSib
+ * therefore pWin->nextSib != NULL */
+ pFirstChange = pWin->nextSib;
+ pWin->nextSib->prevSib = pWin->prevSib;
+ if (pWin->prevSib)
+ pWin->prevSib->nextSib = pWin->nextSib;
+ pParent->lastChild->nextSib = pWin;
+ pWin->prevSib = pParent->lastChild;
+ pWin->nextSib = NullWindow;
+ pParent->lastChild = pWin;
+ }
+ else if (pParent->firstChild == pNextSib) /* move to top */
+ {
+ pFirstChange = pWin;
+ if (pParent->lastChild == pWin)
+ pParent->lastChild = pWin->prevSib;
+ if (pWin->nextSib)
+ pWin->nextSib->prevSib = pWin->prevSib;
+ if (pWin->prevSib)
+ pWin->prevSib->nextSib = pWin->nextSib;
+ pWin->nextSib = pParent->firstChild;
+ pWin->prevSib = (WindowPtr ) NULL;
+ pNextSib->prevSib = pWin;
+ pParent->firstChild = pWin;
+ }
+ else /* move in middle of list */
+ {
+ WindowPtr pOldNext = pWin->nextSib;
+
+ pFirstChange = NullWindow;
+ if (pParent->firstChild == pWin)
+ pFirstChange = pParent->firstChild = pWin->nextSib;
+ if (pParent->lastChild == pWin) {
+ pFirstChange = pWin;
+ pParent->lastChild = pWin->prevSib;
+ }
+ if (pWin->nextSib)
+ pWin->nextSib->prevSib = pWin->prevSib;
+ if (pWin->prevSib)
+ pWin->prevSib->nextSib = pWin->nextSib;
+ pWin->nextSib = pNextSib;
+ pWin->prevSib = pNextSib->prevSib;
+ if (pNextSib->prevSib)
+ pNextSib->prevSib->nextSib = pWin;
+ pNextSib->prevSib = pWin;
+ if (!pFirstChange) { /* do we know it yet? */
+ pFirstChange = pParent->firstChild; /* no, search from top */
+ while ((pFirstChange != pWin) && (pFirstChange != pOldNext))
+ pFirstChange = pFirstChange->nextSib;
+ }
+ }
+ if(pWin->drawable.pScreen->RestackWindow)
+ (*pWin->drawable.pScreen->RestackWindow)(pWin, pOldNextSib);
+ }
+
+#ifdef ROOTLESS
+ /*
+ * In rootless mode we can't optimize away window restacks.
+ * There may be non-X windows around, so even if the window
+ * is in the correct position from X's point of view,
+ * the underlying window system may want to reorder it.
+ */
+ else if (pWin->drawable.pScreen->RestackWindow)
+ (*pWin->drawable.pScreen->RestackWindow)(pWin, pWin->nextSib);
+#endif
+
+ return( pFirstChange );
+}
+
+RegionPtr
+CreateUnclippedWinSize (register WindowPtr pWin)
+{
+ RegionPtr pRgn;
+ BoxRec box;
+
+ box.x1 = pWin->drawable.x;
+ box.y1 = pWin->drawable.y;
+ box.x2 = pWin->drawable.x + (int) pWin->drawable.width;
+ box.y2 = pWin->drawable.y + (int) pWin->drawable.height;
+ pRgn = REGION_CREATE(pWin->drawable.pScreen, &box, 1);
+#ifdef SHAPE
+ if (wBoundingShape (pWin) || wClipShape (pWin)) {
+#ifndef NXAGENT_SERVER
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+#endif /* NXAGENT_SERVER */
+ REGION_TRANSLATE(pScreen, pRgn, - pWin->drawable.x,
+ - pWin->drawable.y);
+ if (wBoundingShape (pWin))
+ REGION_INTERSECT(pScreen, pRgn, pRgn, wBoundingShape (pWin));
+ if (wClipShape (pWin))
+ REGION_INTERSECT(pScreen, pRgn, pRgn, wClipShape (pWin));
+ REGION_TRANSLATE(pScreen, pRgn, pWin->drawable.x, pWin->drawable.y);
+ }
+#endif
+ return pRgn;
+}
+
+void
+SetWinSize (register WindowPtr pWin)
+{
+#ifdef COMPOSITE
+ if (pWin->redirectDraw)
+ {
+ BoxRec box;
+
+ box.x1 = pWin->drawable.x;
+ box.y1 = pWin->drawable.y;
+ box.x2 = pWin->drawable.x + pWin->drawable.width;
+ box.y2 = pWin->drawable.y + pWin->drawable.height;
+ REGION_RESET (pScreen, &pWin->winSize, &box);
+ }
+ else
+#endif
+ ClippedRegionFromBox(pWin->parent, &pWin->winSize,
+ pWin->drawable.x, pWin->drawable.y,
+ (int)pWin->drawable.width,
+ (int)pWin->drawable.height);
+#ifdef SHAPE
+ if (wBoundingShape (pWin) || wClipShape (pWin)) {
+#ifndef NXAGENT_SERVER
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+#endif /* NXAGENT_SERVER */
+ REGION_TRANSLATE(pScreen, &pWin->winSize, - pWin->drawable.x,
+ - pWin->drawable.y);
+ if (wBoundingShape (pWin))
+ REGION_INTERSECT(pScreen, &pWin->winSize, &pWin->winSize,
+ wBoundingShape (pWin));
+ if (wClipShape (pWin))
+ REGION_INTERSECT(pScreen, &pWin->winSize, &pWin->winSize,
+ wClipShape (pWin));
+ REGION_TRANSLATE(pScreen, &pWin->winSize, pWin->drawable.x,
+ pWin->drawable.y);
+ }
+#endif
+}
+
+void
+SetBorderSize (register WindowPtr pWin)
+{
+ int bw;
+
+ if (HasBorder (pWin)) {
+ bw = wBorderWidth (pWin);
+#ifdef COMPOSITE
+ if (pWin->redirectDraw)
+ {
+ BoxRec box;
+
+ box.x1 = pWin->drawable.x - bw;
+ box.y1 = pWin->drawable.y - bw;
+ box.x2 = pWin->drawable.x + pWin->drawable.width + bw;
+ box.y2 = pWin->drawable.y + pWin->drawable.height + bw;
+ REGION_RESET (pScreen, &pWin->borderSize, &box);
+ }
+ else
+#endif
+ ClippedRegionFromBox(pWin->parent, &pWin->borderSize,
+ pWin->drawable.x - bw, pWin->drawable.y - bw,
+ (int)(pWin->drawable.width + (bw<<1)),
+ (int)(pWin->drawable.height + (bw<<1)));
+#ifdef SHAPE
+ if (wBoundingShape (pWin)) {
+#ifndef NXAGENT_SERVER
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+#endif /* NXAGENT_SERVER */
+ REGION_TRANSLATE(pScreen, &pWin->borderSize, - pWin->drawable.x,
+ - pWin->drawable.y);
+ REGION_INTERSECT(pScreen, &pWin->borderSize, &pWin->borderSize,
+ wBoundingShape (pWin));
+ REGION_TRANSLATE(pScreen, &pWin->borderSize, pWin->drawable.x,
+ pWin->drawable.y);
+ REGION_UNION(pScreen, &pWin->borderSize, &pWin->borderSize,
+ &pWin->winSize);
+ }
+#endif
+ } else {
+ REGION_COPY(pWin->drawable.pScreen, &pWin->borderSize,
+ &pWin->winSize);
+ }
+}
+
+/**
+ *
+ * \param x,y new window position
+ * \param oldx,oldy old window position
+ * \param destx,desty position relative to gravity
+ */
+
+void
+GravityTranslate (register int x, register int y, int oldx, int oldy,
+ int dw, int dh, unsigned gravity,
+ register int *destx, register int *desty)
+{
+ switch (gravity) {
+ case NorthGravity:
+ *destx = x + dw / 2;
+ *desty = y;
+ break;
+ case NorthEastGravity:
+ *destx = x + dw;
+ *desty = y;
+ break;
+ case WestGravity:
+ *destx = x;
+ *desty = y + dh / 2;
+ break;
+ case CenterGravity:
+ *destx = x + dw / 2;
+ *desty = y + dh / 2;
+ break;
+ case EastGravity:
+ *destx = x + dw;
+ *desty = y + dh / 2;
+ break;
+ case SouthWestGravity:
+ *destx = x;
+ *desty = y + dh;
+ break;
+ case SouthGravity:
+ *destx = x + dw / 2;
+ *desty = y + dh;
+ break;
+ case SouthEastGravity:
+ *destx = x + dw;
+ *desty = y + dh;
+ break;
+ case StaticGravity:
+ *destx = oldx;
+ *desty = oldy;
+ break;
+ default:
+ *destx = x;
+ *desty = y;
+ break;
+ }
+}
+
+/* XXX need to retile border on each window with ParentRelative origin */
+void
+ResizeChildrenWinSize(register WindowPtr pWin, int dx, int dy, int dw, int dh)
+{
+ register ScreenPtr pScreen;
+ register WindowPtr pSib, pChild;
+ Bool resized = (dw || dh);
+
+ pScreen = pWin->drawable.pScreen;
+
+ for (pSib = pWin->firstChild; pSib; pSib = pSib->nextSib)
+ {
+ if (resized && (pSib->winGravity > NorthWestGravity))
+ {
+ int cwsx, cwsy;
+
+ cwsx = pSib->origin.x;
+ cwsy = pSib->origin.y;
+ GravityTranslate (cwsx, cwsy, cwsx - dx, cwsy - dy, dw, dh,
+ pSib->winGravity, &cwsx, &cwsy);
+ if (cwsx != pSib->origin.x || cwsy != pSib->origin.y)
+ {
+ xEvent event;
+
+ event.u.u.type = GravityNotify;
+ event.u.gravity.window = pSib->drawable.id;
+ event.u.gravity.x = cwsx - wBorderWidth (pSib);
+ event.u.gravity.y = cwsy - wBorderWidth (pSib);
+ DeliverEvents (pSib, &event, 1, NullWindow);
+ pSib->origin.x = cwsx;
+ pSib->origin.y = cwsy;
+ }
+ }
+ pSib->drawable.x = pWin->drawable.x + pSib->origin.x;
+ pSib->drawable.y = pWin->drawable.y + pSib->origin.y;
+ SetWinSize (pSib);
+ SetBorderSize (pSib);
+
+ /*
+ * Don't force X to move children. It will position them
+ * according with gravity.
+ *
+ * (*pScreen->PositionWindow)(pSib, pSib->drawable.x, pSib->drawable.y);
+ */
+
+ /*
+ * Update pSib privates, as this window is moved by X.
+ */
+
+ nxagentAddConfiguredWindow(pSib, CW_Update);
+
+ if ( (pChild = pSib->firstChild) )
+ {
+ while (1)
+ {
+ pChild->drawable.x = pChild->parent->drawable.x +
+ pChild->origin.x;
+ pChild->drawable.y = pChild->parent->drawable.y +
+ pChild->origin.y;
+ SetWinSize (pChild);
+ SetBorderSize (pChild);
+
+ (*pScreen->PositionWindow)(pChild, pChild->drawable.x,
+ pChild->drawable.y);
+
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ while (!pChild->nextSib && (pChild != pSib))
+ pChild = pChild->parent;
+ if (pChild == pSib)
+ break;
+ pChild = pChild->nextSib;
+ }
+ }
+ }
+}
+
+#define GET_INT16(m, f) \
+ if (m & mask) \
+ { \
+ f = (INT16) *pVlist;\
+ pVlist++; \
+ }
+#define GET_CARD16(m, f) \
+ if (m & mask) \
+ { \
+ f = (CARD16) *pVlist;\
+ pVlist++;\
+ }
+
+#define GET_CARD8(m, f) \
+ if (m & mask) \
+ { \
+ f = (CARD8) *pVlist;\
+ pVlist++;\
+ }
+
+#define ChangeMask ((Mask)(CWX | CWY | CWWidth | CWHeight))
+
+#define IllegalInputOnlyConfigureMask (CWBorderWidth)
+
+/*
+ * IsSiblingAboveMe
+ * returns Above if pSib above pMe in stack or Below otherwise
+ */
+
+static int
+IsSiblingAboveMe(
+ register WindowPtr pMe,
+ register WindowPtr pSib)
+{
+ register WindowPtr pWin;
+
+ pWin = pMe->parent->firstChild;
+ while (pWin)
+ {
+ if (pWin == pSib)
+ return(Above);
+ else if (pWin == pMe)
+ return(Below);
+ pWin = pWin->nextSib;
+ }
+ return(Below);
+}
+
+static BoxPtr
+WindowExtents(
+ register WindowPtr pWin,
+ register BoxPtr pBox)
+{
+ pBox->x1 = pWin->drawable.x - wBorderWidth (pWin);
+ pBox->y1 = pWin->drawable.y - wBorderWidth (pWin);
+ pBox->x2 = pWin->drawable.x + (int)pWin->drawable.width
+ + wBorderWidth (pWin);
+ pBox->y2 = pWin->drawable.y + (int)pWin->drawable.height
+ + wBorderWidth (pWin);
+ return(pBox);
+}
+
+#ifdef SHAPE
+#define IS_SHAPED(pWin) (wBoundingShape (pWin) != (RegionPtr) NULL)
+
+static RegionPtr
+MakeBoundingRegion (
+ register WindowPtr pWin,
+ BoxPtr pBox)
+{
+ RegionPtr pRgn;
+#ifndef NXAGENT_SERVER
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+#endif /* NXAGENT_SERVER */
+ pRgn = REGION_CREATE(pScreen, pBox, 1);
+ if (wBoundingShape (pWin)) {
+ REGION_TRANSLATE(pScreen, pRgn, -pWin->origin.x,
+ -pWin->origin.y);
+ REGION_INTERSECT(pScreen, pRgn, pRgn, wBoundingShape (pWin));
+ REGION_TRANSLATE(pScreen, pRgn, pWin->origin.x,
+ pWin->origin.y);
+ }
+ return pRgn;
+}
+
+static Bool
+ShapeOverlap (
+ WindowPtr pWin,
+ BoxPtr pWinBox,
+ WindowPtr pSib,
+ BoxPtr pSibBox)
+{
+ RegionPtr pWinRgn, pSibRgn;
+ register ScreenPtr pScreen;
+ Bool ret;
+
+ if (!IS_SHAPED(pWin) && !IS_SHAPED(pSib))
+ return TRUE;
+ pScreen = pWin->drawable.pScreen;
+ pWinRgn = MakeBoundingRegion (pWin, pWinBox);
+ pSibRgn = MakeBoundingRegion (pSib, pSibBox);
+ REGION_INTERSECT(pScreen, pWinRgn, pWinRgn, pSibRgn);
+ ret = REGION_NOTEMPTY(pScreen, pWinRgn);
+ REGION_DESTROY(pScreen, pWinRgn);
+ REGION_DESTROY(pScreen, pSibRgn);
+ return ret;
+}
+#endif
+
+static Bool
+AnyWindowOverlapsMe(
+ WindowPtr pWin,
+ WindowPtr pHead,
+ register BoxPtr box)
+{
+ register WindowPtr pSib;
+ BoxRec sboxrec;
+ register BoxPtr sbox;
+
+ for (pSib = pWin->prevSib; pSib != pHead; pSib = pSib->prevSib)
+ {
+ if (pSib->mapped)
+ {
+ sbox = WindowExtents(pSib, &sboxrec);
+ if (BOXES_OVERLAP(sbox, box)
+#ifdef SHAPE
+ && ShapeOverlap (pWin, box, pSib, sbox)
+#endif
+ )
+ return(TRUE);
+ }
+ }
+ return(FALSE);
+}
+
+static Bool
+IOverlapAnyWindow(
+ WindowPtr pWin,
+ register BoxPtr box)
+{
+ register WindowPtr pSib;
+ BoxRec sboxrec;
+ register BoxPtr sbox;
+
+ for (pSib = pWin->nextSib; pSib; pSib = pSib->nextSib)
+ {
+ if (pSib->mapped)
+ {
+ sbox = WindowExtents(pSib, &sboxrec);
+ if (BOXES_OVERLAP(sbox, box)
+#ifdef SHAPE
+ && ShapeOverlap (pWin, box, pSib, sbox)
+#endif
+ )
+ return(TRUE);
+ }
+ }
+ return(FALSE);
+}
+
+/*
+ * WhereDoIGoInTheStack()
+ * Given pWin and pSib and the relationshipe smode, return
+ * the window that pWin should go ABOVE.
+ * If a pSib is specified:
+ * Above: pWin is placed just above pSib
+ * Below: pWin is placed just below pSib
+ * TopIf: if pSib occludes pWin, then pWin is placed
+ * at the top of the stack
+ * BottomIf: if pWin occludes pSib, then pWin is
+ * placed at the bottom of the stack
+ * Opposite: if pSib occludes pWin, then pWin is placed at the
+ * top of the stack, else if pWin occludes pSib, then
+ * pWin is placed at the bottom of the stack
+ *
+ * If pSib is NULL:
+ * Above: pWin is placed at the top of the stack
+ * Below: pWin is placed at the bottom of the stack
+ * TopIf: if any sibling occludes pWin, then pWin is placed at
+ * the top of the stack
+ * BottomIf: if pWin occludes any sibline, then pWin is placed at
+ * the bottom of the stack
+ * Opposite: if any sibling occludes pWin, then pWin is placed at
+ * the top of the stack, else if pWin occludes any
+ * sibling, then pWin is placed at the bottom of the stack
+ *
+ */
+
+static WindowPtr
+WhereDoIGoInTheStack(
+ register WindowPtr pWin,
+ register WindowPtr pSib,
+ short x,
+ short y,
+ unsigned short w,
+ unsigned short h,
+ int smode)
+{
+ BoxRec box;
+ register ScreenPtr pScreen;
+ WindowPtr pHead, pFirst;
+
+ if ((pWin == pWin->parent->firstChild) &&
+ (pWin == pWin->parent->lastChild))
+ return((WindowPtr ) NULL);
+ pHead = RealChildHead(pWin->parent);
+ pFirst = pHead ? pHead->nextSib : pWin->parent->firstChild;
+ pScreen = pWin->drawable.pScreen;
+ box.x1 = x;
+ box.y1 = y;
+ box.x2 = x + (int)w;
+ box.y2 = y + (int)h;
+ switch (smode)
+ {
+ case Above:
+ if (pSib)
+ return(pSib);
+ else if (pWin == pFirst)
+ return(pWin->nextSib);
+ else
+ return(pFirst);
+ case Below:
+ if (pSib)
+ if (pSib->nextSib != pWin)
+ return(pSib->nextSib);
+ else
+ return(pWin->nextSib);
+ else
+ return NullWindow;
+ case TopIf:
+ if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+ return(pWin->nextSib);
+ else if (pSib)
+ {
+ if ((IsSiblingAboveMe(pWin, pSib) == Above) &&
+ (RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT))
+ return(pFirst);
+ else
+ return(pWin->nextSib);
+ }
+ else if (AnyWindowOverlapsMe(pWin, pHead, &box))
+ return(pFirst);
+ else
+ return(pWin->nextSib);
+ case BottomIf:
+ if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+ return(pWin->nextSib);
+ else if (pSib)
+ {
+ if ((IsSiblingAboveMe(pWin, pSib) == Below) &&
+ (RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT))
+ return NullWindow;
+ else
+ return(pWin->nextSib);
+ }
+ else if (IOverlapAnyWindow(pWin, &box))
+ return NullWindow;
+ else
+ return(pWin->nextSib);
+ case Opposite:
+ if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+ return(pWin->nextSib);
+ else if (pSib)
+ {
+ if (RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT)
+ {
+ if (IsSiblingAboveMe(pWin, pSib) == Above)
+ return(pFirst);
+ else
+ return NullWindow;
+ }
+ else
+ return(pWin->nextSib);
+ }
+ else if (AnyWindowOverlapsMe(pWin, pHead, &box))
+ {
+ /* If I'm occluded, I can't possibly be the first child
+ * if (pWin == pWin->parent->firstChild)
+ * return pWin->nextSib;
+ */
+ return(pFirst);
+ }
+ else if (IOverlapAnyWindow(pWin, &box))
+ return NullWindow;
+ else
+ return pWin->nextSib;
+ default:
+ {
+ ErrorF("Internal error in ConfigureWindow, smode == %d\n",smode );
+ return pWin->nextSib;
+ }
+ }
+}
+
+static void
+ReflectStackChange(
+ register WindowPtr pWin,
+ register WindowPtr pSib,
+ VTKind kind)
+{
+/* Note that pSib might be NULL */
+
+ Bool WasViewable = (Bool)pWin->viewable;
+ Bool anyMarked;
+ WindowPtr pFirstChange;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ /* if this is a root window, can't be restacked */
+ if (!pWin->parent)
+ return;
+
+ pFirstChange = MoveWindowInStack(pWin, pSib);
+
+ if (WasViewable)
+ {
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
+ &pLayerWin);
+ if (pLayerWin != pWin) pFirstChange = pLayerWin;
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pFirstChange);
+ }
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked)
+ {
+ (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, kind);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pFirstChange);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pWin->drawable.pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange, kind);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+}
+
+/*****
+ * ConfigureWindow
+ *****/
+
+int
+ConfigureWindow(register WindowPtr pWin, register Mask mask, XID *vlist, ClientPtr client)
+{
+#define RESTACK_WIN 0
+#define MOVE_WIN 1
+#define RESIZE_WIN 2
+#define REBORDER_WIN 3
+ register WindowPtr pSib = NullWindow;
+ register WindowPtr pParent = pWin->parent;
+ Window sibwid = 0;
+ Mask index2, tmask;
+ register XID *pVlist;
+ short x, y, beforeX, beforeY;
+ unsigned short w = pWin->drawable.width,
+ h = pWin->drawable.height,
+ bw = pWin->borderWidth;
+ int action, smode = Above;
+#ifdef XAPPGROUP
+ ClientPtr win_owner;
+ ClientPtr ag_leader = NULL;
+#endif
+ xEvent event;
+
+ if ((pWin->drawable.class == InputOnly) && (mask & IllegalInputOnlyConfigureMask))
+ return(BadMatch);
+
+ if ((mask & CWSibling) && !(mask & CWStackMode))
+ return(BadMatch);
+
+ pVlist = vlist;
+
+ if (pParent)
+ {
+ x = pWin->drawable.x - pParent->drawable.x - (int)bw;
+ y = pWin->drawable.y - pParent->drawable.y - (int)bw;
+ }
+ else
+ {
+ x = pWin->drawable.x;
+ y = pWin->drawable.y;
+ }
+ beforeX = x;
+ beforeY = y;
+ action = RESTACK_WIN;
+ if ((mask & (CWX | CWY)) && (!(mask & (CWHeight | CWWidth))))
+ {
+ GET_INT16(CWX, x);
+ GET_INT16(CWY, y);
+ action = MOVE_WIN;
+ }
+ /* or should be resized */
+ else if (mask & (CWX | CWY | CWWidth | CWHeight))
+ {
+ GET_INT16(CWX, x);
+ GET_INT16(CWY, y);
+ GET_CARD16(CWWidth, w);
+ GET_CARD16 (CWHeight, h);
+ if (!w || !h)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ action = RESIZE_WIN;
+ }
+ tmask = mask & ~ChangeMask;
+ while (tmask)
+ {
+ index2 = (Mask)lowbit (tmask);
+ tmask &= ~index2;
+ switch (index2)
+ {
+ case CWBorderWidth:
+ GET_CARD16(CWBorderWidth, bw);
+ break;
+ case CWSibling:
+ sibwid = (Window ) *pVlist;
+ pVlist++;
+ pSib = (WindowPtr )SecurityLookupIDByType(client, sibwid,
+ RT_WINDOW, SecurityReadAccess);
+ if (!pSib)
+ {
+ client->errorValue = sibwid;
+ return(BadWindow);
+ }
+ if (pSib->parent != pParent)
+ return(BadMatch);
+ if (pSib == pWin)
+ return(BadMatch);
+ break;
+ case CWStackMode:
+ GET_CARD8(CWStackMode, smode);
+ if ((smode != TopIf) && (smode != BottomIf) &&
+ (smode != Opposite) && (smode != Above) && (smode != Below))
+ {
+ client->errorValue = smode;
+ return(BadValue);
+ }
+ break;
+ default:
+ client->errorValue = mask;
+ return(BadValue);
+ }
+ }
+ /* root really can't be reconfigured, so just return */
+ if (!pParent)
+ return Success;
+
+ /* Figure out if the window should be moved. Doesnt
+ make the changes to the window if event sent */
+
+ #ifdef TEST
+ if (nxagentWindowTopLevel(pWin))
+ {
+
+ fprintf(stderr, "ConfigureWindow: pWin [%p] mask [%lu] client [%p]\n",
+ pWin, mask, client);
+
+ fprintf(stderr, "ConfigureWindow: x [%d] y [%d] w [%d] h [%d] CWStackMode [%d] "
+ "smode [%d] pSib [%p]\n",
+ x, y, w, h, (mask & CWStackMode) ? 1 : 0, smode, pSib);
+ }
+ #endif
+
+ if (nxagentOption(Rootless) && nxagentWindowTopLevel(pWin) &&
+ pWin -> overrideRedirect == 0 &&
+ nxagentScreenTrap == 0)
+ {
+ nxagentConfigureRootlessWindow(pWin, x, y, w, h, bw, pSib, smode, mask);
+
+ return Success;
+ }
+
+ if (mask & CWStackMode)
+ pSib = WhereDoIGoInTheStack(pWin, pSib, pParent->drawable.x + x,
+ pParent->drawable.y + y,
+ w + (bw << 1), h + (bw << 1), smode);
+ else
+ pSib = pWin->nextSib;
+
+#ifdef XAPPGROUP
+ win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+ ag_leader = XagLeader (win_owner);
+#endif
+
+ if ((!pWin->overrideRedirect) &&
+ (RedirectSend(pParent)
+#ifdef XAPPGROUP
+ || (win_owner->appgroup && ag_leader &&
+ XagIsControlledRoot (client, pParent))
+#endif
+ ))
+ {
+ event.u.u.type = ConfigureRequest;
+ event.u.configureRequest.window = pWin->drawable.id;
+ if (mask & CWSibling)
+ event.u.configureRequest.sibling = sibwid;
+ else
+ event.u.configureRequest.sibling = None;
+ if (mask & CWStackMode)
+ event.u.u.detail = smode;
+ else
+ event.u.u.detail = Above;
+ event.u.configureRequest.x = x;
+ event.u.configureRequest.y = y;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
+ event.u.configureRequest.x += panoramiXdataPtr[0].x;
+ event.u.configureRequest.y += panoramiXdataPtr[0].y;
+ }
+#endif
+ event.u.configureRequest.width = w;
+ event.u.configureRequest.height = h;
+ event.u.configureRequest.borderWidth = bw;
+ event.u.configureRequest.valueMask = mask;
+#ifdef XAPPGROUP
+ /* make sure if the ag_leader maps the window it goes to the wm */
+ if (ag_leader && ag_leader != client &&
+ XagIsControlledRoot (client, pParent)) {
+ event.u.configureRequest.parent = XagId (win_owner);
+ (void) TryClientEvents (ag_leader, &event, 1,
+ NoEventMask, NoEventMask, NullGrab);
+ return Success;
+ }
+#endif
+ event.u.configureRequest.parent = pParent->drawable.id;
+ if (MaybeDeliverEventsToClient(pParent, &event, 1,
+ SubstructureRedirectMask, client) == 1)
+ return(Success);
+ }
+ if (action == RESIZE_WIN)
+ {
+ Bool size_change = (w != pWin->drawable.width)
+ || (h != pWin->drawable.height);
+ if (size_change && ((pWin->eventMask|wOtherEventMasks(pWin)) & ResizeRedirectMask))
+ {
+ xEvent eventT;
+ eventT.u.u.type = ResizeRequest;
+ eventT.u.resizeRequest.window = pWin->drawable.id;
+ eventT.u.resizeRequest.width = w;
+ eventT.u.resizeRequest.height = h;
+ if (MaybeDeliverEventsToClient(pWin, &eventT, 1,
+ ResizeRedirectMask, client) == 1)
+ {
+ /* if event is delivered, leave the actual size alone. */
+ w = pWin->drawable.width;
+ h = pWin->drawable.height;
+ size_change = FALSE;
+ }
+ }
+ if (!size_change)
+ {
+ if (mask & (CWX | CWY))
+ action = MOVE_WIN;
+ else if (mask & (CWStackMode | CWBorderWidth))
+ action = RESTACK_WIN;
+ else /* really nothing to do */
+ return(Success) ;
+ }
+ }
+
+ if (action == RESIZE_WIN)
+ /* we've already checked whether there's really a size change */
+ goto ActuallyDoSomething;
+ if ((mask & CWX) && (x != beforeX))
+ goto ActuallyDoSomething;
+ if ((mask & CWY) && (y != beforeY))
+ goto ActuallyDoSomething;
+ if ((mask & CWBorderWidth) && (bw != wBorderWidth (pWin)))
+ goto ActuallyDoSomething;
+ if (mask & CWStackMode)
+ {
+#ifndef ROOTLESS
+ /* See above for why we always reorder in rootless mode. */
+ if (pWin->nextSib != pSib)
+#endif
+ goto ActuallyDoSomething;
+ }
+ return(Success);
+
+ActuallyDoSomething:
+ if (SubStrSend(pWin, pParent))
+ {
+ event.u.u.type = ConfigureNotify;
+ event.u.configureNotify.window = pWin->drawable.id;
+ if (pSib)
+ event.u.configureNotify.aboveSibling = pSib->drawable.id;
+ else
+ event.u.configureNotify.aboveSibling = None;
+ event.u.configureNotify.x = x;
+ event.u.configureNotify.y = y;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
+ event.u.configureNotify.x += panoramiXdataPtr[0].x;
+ event.u.configureNotify.y += panoramiXdataPtr[0].y;
+ }
+#endif
+ event.u.configureNotify.width = w;
+ event.u.configureNotify.height = h;
+ event.u.configureNotify.borderWidth = bw;
+ event.u.configureNotify.override = pWin->overrideRedirect;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ }
+ if (mask & CWBorderWidth)
+ {
+ if (action == RESTACK_WIN)
+ {
+ action = MOVE_WIN;
+ pWin->borderWidth = bw;
+ }
+ else if ((action == MOVE_WIN) &&
+ (beforeX + wBorderWidth (pWin) == x + (int)bw) &&
+ (beforeY + wBorderWidth (pWin) == y + (int)bw))
+ {
+ action = REBORDER_WIN;
+ (*pWin->drawable.pScreen->ChangeBorderWidth)(pWin, bw);
+ }
+ else
+ pWin->borderWidth = bw;
+ }
+ if (action == MOVE_WIN)
+ (*pWin->drawable.pScreen->MoveWindow)(pWin, x, y, pSib,
+ (mask & CWBorderWidth) ? VTOther : VTMove);
+ else if (action == RESIZE_WIN)
+ (*pWin->drawable.pScreen->ResizeWindow)(pWin, x, y, w, h, pSib);
+ else if (mask & CWStackMode)
+ ReflectStackChange(pWin, pSib, VTOther);
+
+ if (action != RESTACK_WIN)
+ CheckCursorConfinement(pWin);
+
+ nxagentFlushConfigureWindow();
+
+ return(Success);
+#undef RESTACK_WIN
+#undef MOVE_WIN
+#undef RESIZE_WIN
+#undef REBORDER_WIN
+}
+
+
+/******
+ *
+ * CirculateWindow
+ * For RaiseLowest, raises the lowest mapped child (if any) that is
+ * obscured by another child to the top of the stack. For LowerHighest,
+ * lowers the highest mapped child (if any) that is obscuring another
+ * child to the bottom of the stack. Exposure processing is performed
+ *
+ ******/
+
+int
+CirculateWindow(WindowPtr pParent, int direction, ClientPtr client)
+{
+ register WindowPtr pWin, pHead, pFirst;
+ xEvent event;
+ BoxRec box;
+
+ #ifdef TEST
+ fprintf(stderr, "CirculateWindow: pParent [%p] direction [%d] client [%p]\n",
+ pParent, direction, client);
+ #endif
+
+ /*
+ * if (nxagentOption(Rootless) && nxagentWMIsRunning &&
+ * nxagentWindowTopLevel(pWin) && pWin -> overrideRedirect == 0)
+ * {
+ * nxagentCirculateRootlessWindows(direction);
+ * return Success;
+ * }
+ */
+
+ pHead = RealChildHead(pParent);
+ pFirst = pHead ? pHead->nextSib : pParent->firstChild;
+ if (direction == RaiseLowest)
+ {
+ for (pWin = pParent->lastChild;
+ (pWin != pHead) &&
+ !(pWin->mapped &&
+ AnyWindowOverlapsMe(pWin, pHead, WindowExtents(pWin, &box)));
+ pWin = pWin->prevSib) ;
+ if (pWin == pHead)
+ return Success;
+ }
+ else
+ {
+ for (pWin = pFirst;
+ pWin &&
+ !(pWin->mapped &&
+ IOverlapAnyWindow(pWin, WindowExtents(pWin, &box)));
+ pWin = pWin->nextSib) ;
+ if (!pWin)
+ return Success;
+ }
+
+ event.u.circulate.window = pWin->drawable.id;
+ event.u.circulate.parent = pParent->drawable.id;
+ event.u.circulate.event = pParent->drawable.id;
+ if (direction == RaiseLowest)
+ event.u.circulate.place = PlaceOnTop;
+ else
+ event.u.circulate.place = PlaceOnBottom;
+
+ if (RedirectSend(pParent))
+ {
+ event.u.u.type = CirculateRequest;
+ if (MaybeDeliverEventsToClient(pParent, &event, 1,
+ SubstructureRedirectMask, client) == 1)
+ return(Success);
+ }
+
+ event.u.u.type = CirculateNotify;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ ReflectStackChange(pWin,
+ (direction == RaiseLowest) ? pFirst : NullWindow,
+ VTStack);
+
+ return(Success);
+}
+
+static int
+CompareWIDs(
+ WindowPtr pWin,
+ pointer value) /* must conform to VisitWindowProcPtr */
+{
+ Window *wid = (Window *)value;
+
+ if (pWin->drawable.id == *wid)
+ return(WT_STOPWALKING);
+ else
+ return(WT_WALKCHILDREN);
+}
+
+/*****
+ * ReparentWindow
+ *****/
+
+int
+ReparentWindow(register WindowPtr pWin, register WindowPtr pParent,
+ int x, int y, ClientPtr client)
+{
+ WindowPtr pPrev, pPriorParent;
+ Bool WasMapped = (Bool)(pWin->mapped);
+ xEvent event;
+ int bw = wBorderWidth (pWin);
+ register ScreenPtr pScreen;
+
+ pScreen = pWin->drawable.pScreen;
+ if (TraverseTree(pWin, CompareWIDs, (pointer)&pParent->drawable.id) == WT_STOPWALKING)
+ return(BadMatch);
+ if (!MakeWindowOptional(pWin))
+ return(BadAlloc);
+
+ if (WasMapped)
+ UnmapWindow(pWin, FALSE);
+
+ event.u.u.type = ReparentNotify;
+ event.u.reparent.window = pWin->drawable.id;
+ event.u.reparent.parent = pParent->drawable.id;
+ event.u.reparent.x = x;
+ event.u.reparent.y = y;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && !pParent->parent) {
+ event.u.reparent.x += panoramiXdataPtr[0].x;
+ event.u.reparent.y += panoramiXdataPtr[0].y;
+ }
+#endif
+ event.u.reparent.override = pWin->overrideRedirect;
+ DeliverEvents(pWin, &event, 1, pParent);
+
+ /* take out of sibling chain */
+
+ pPriorParent = pPrev = pWin->parent;
+ if (pPrev->firstChild == pWin)
+ pPrev->firstChild = pWin->nextSib;
+ if (pPrev->lastChild == pWin)
+ pPrev->lastChild = pWin->prevSib;
+
+ if (pWin->nextSib)
+ pWin->nextSib->prevSib = pWin->prevSib;
+ if (pWin->prevSib)
+ pWin->prevSib->nextSib = pWin->nextSib;
+
+ /* insert at begining of pParent */
+ pWin->parent = pParent;
+ pPrev = RealChildHead(pParent);
+
+ if (pWin->parent == WindowTable[0])
+ {
+ nxagentSetTopLevelEventMask(pWin);
+ }
+
+ if (pPrev)
+ {
+ pWin->nextSib = pPrev->nextSib;
+ if (pPrev->nextSib)
+ pPrev->nextSib->prevSib = pWin;
+ else
+ pParent->lastChild = pWin;
+ pPrev->nextSib = pWin;
+ pWin->prevSib = pPrev;
+ }
+ else
+ {
+ pWin->nextSib = pParent->firstChild;
+ pWin->prevSib = NullWindow;
+ if (pParent->firstChild)
+ pParent->firstChild->prevSib = pWin;
+ else
+ pParent->lastChild = pWin;
+ pParent->firstChild = pWin;
+ }
+
+ pWin->origin.x = x + bw;
+ pWin->origin.y = y + bw;
+ pWin->drawable.x = x + bw + pParent->drawable.x;
+ pWin->drawable.y = y + bw + pParent->drawable.y;
+
+ /* clip to parent */
+ SetWinSize (pWin);
+ SetBorderSize (pWin);
+
+ if (pScreen->ReparentWindow)
+ (*pScreen->ReparentWindow)(pWin, pPriorParent);
+
+ (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
+
+ ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
+
+ CheckWindowOptionalNeed(pWin);
+
+ if (WasMapped)
+ MapWindow(pWin, client);
+ RecalculateDeliverableEvents(pWin);
+ return(Success);
+}
+
+static void
+RealizeTree(WindowPtr pWin)
+{
+ register WindowPtr pChild;
+ RealizeWindowProcPtr Realize;
+
+ Realize = pWin->drawable.pScreen->RealizeWindow;
+ pChild = pWin;
+ while (1)
+ {
+ if (pChild->mapped)
+ {
+ pChild->realized = TRUE;
+#ifdef DO_SAVE_UNDERS
+ if (pChild->saveUnder)
+ deltaSaveUndersViewable++;
+#endif
+ pChild->viewable = (pChild->drawable.class == InputOutput);
+ (* Realize)(pChild);
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ return;
+ pChild = pChild->nextSib;
+ }
+}
+
+/*****
+ * MapWindow
+ * If some other client has selected SubStructureReDirect on the parent
+ * and override-redirect is xFalse, then a MapRequest event is generated,
+ * but the window remains unmapped. Otherwise, the window is mapped and a
+ * MapNotify event is generated.
+ *****/
+
+int
+MapWindow(register WindowPtr pWin, ClientPtr client)
+{
+ register ScreenPtr pScreen;
+
+ register WindowPtr pParent;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ #ifdef TEST
+ if (nxagentWindowTopLevel(pWin))
+ {
+ fprintf(stderr, "MapWindow: pWin [%p] client [%p]\n", pWin, client);
+ }
+ #endif
+
+ if (pWin->mapped)
+ return(Success);
+
+#ifdef XCSECURITY
+ /* don't let an untrusted client map a child-of-trusted-window, InputOnly
+ * window; too easy to steal device input
+ */
+ if ( (client->trustLevel != XSecurityClientTrusted) &&
+ (pWin->drawable.class == InputOnly) &&
+ (wClient(pWin->parent)->trustLevel == XSecurityClientTrusted) )
+ return Success;
+#endif
+
+ pScreen = pWin->drawable.pScreen;
+ if ( (pParent = pWin->parent) )
+ {
+ xEvent event;
+ Bool anyMarked;
+#ifdef XAPPGROUP
+ ClientPtr win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+ ClientPtr ag_leader = XagLeader (win_owner);
+#endif
+
+ if ((!pWin->overrideRedirect) &&
+ (RedirectSend(pParent)
+#ifdef XAPPGROUP
+ || (win_owner->appgroup && ag_leader &&
+ XagIsControlledRoot (client, pParent))
+#endif
+ ))
+ {
+ event.u.u.type = MapRequest;
+ event.u.mapRequest.window = pWin->drawable.id;
+#ifdef XAPPGROUP
+ /* make sure if the ag_leader maps the window it goes to the wm */
+ if (ag_leader && ag_leader != client &&
+ XagIsControlledRoot (client, pParent)) {
+ event.u.mapRequest.parent = XagId (win_owner);
+ (void) TryClientEvents (ag_leader, &event, 1,
+ NoEventMask, NoEventMask, NullGrab);
+ return Success;
+ }
+#endif
+ event.u.mapRequest.parent = pParent->drawable.id;
+
+ if (MaybeDeliverEventsToClient(pParent, &event, 1,
+ SubstructureRedirectMask, client) == 1)
+ return(Success);
+ }
+
+ pWin->mapped = TRUE;
+ if (SubStrSend(pWin, pParent))
+ {
+ event.u.u.type = MapNotify;
+ event.u.mapNotify.window = pWin->drawable.id;
+ event.u.mapNotify.override = pWin->overrideRedirect;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ }
+
+ if (!pParent->realized)
+ return(Success);
+ RealizeTree(pWin);
+ if (pWin->viewable)
+ {
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ &pLayerWin);
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib);
+ }
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked)
+ {
+ (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
+ }
+ WindowsRestructured ();
+ }
+ else
+ {
+ RegionRec temp;
+
+ pWin->mapped = TRUE;
+ pWin->realized = TRUE; /* for roots */
+ pWin->viewable = pWin->drawable.class == InputOutput;
+ /* We SHOULD check for an error value here XXX */
+ (*pScreen->RealizeWindow)(pWin);
+ if (pScreen->ClipNotify)
+ (*pScreen->ClipNotify) (pWin, 0, 0);
+ if (pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(NullWindow, pWin, VTMap);
+ REGION_NULL(pScreen, &temp);
+ REGION_COPY(pScreen, &temp, &pWin->clipList);
+ (*pScreen->WindowExposures) (pWin, &temp, NullRegion);
+ REGION_UNINIT(pScreen, &temp);
+ }
+
+ nxagentFlushConfigureWindow();
+
+ return(Success);
+}
+
+
+/*****
+ * MapSubwindows
+ * Performs a MapWindow all unmapped children of the window, in top
+ * to bottom stacking order.
+ *****/
+
+void
+MapSubwindows(register WindowPtr pParent, ClientPtr client)
+{
+ register WindowPtr pWin;
+ WindowPtr pFirstMapped = NullWindow;
+#ifdef DO_SAVE_UNDERS
+ WindowPtr pFirstSaveUndered = NullWindow;
+#endif
+ register ScreenPtr pScreen;
+ register Mask parentRedirect;
+ register Mask parentNotify;
+ xEvent event;
+ Bool anyMarked;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ pScreen = pParent->drawable.pScreen;
+ parentRedirect = RedirectSend(pParent);
+ parentNotify = SubSend(pParent);
+ anyMarked = FALSE;
+ for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib)
+ {
+ if (!pWin->mapped)
+ {
+ if (parentRedirect && !pWin->overrideRedirect)
+ {
+ event.u.u.type = MapRequest;
+ event.u.mapRequest.window = pWin->drawable.id;
+ event.u.mapRequest.parent = pParent->drawable.id;
+
+ if (MaybeDeliverEventsToClient(pParent, &event, 1,
+ SubstructureRedirectMask, client) == 1)
+ continue;
+ }
+
+ pWin->mapped = TRUE;
+ if (parentNotify || StrSend(pWin))
+ {
+ event.u.u.type = MapNotify;
+ event.u.mapNotify.window = pWin->drawable.id;
+ event.u.mapNotify.override = pWin->overrideRedirect;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ }
+
+ if (!pFirstMapped)
+ pFirstMapped = pWin;
+ if (pParent->realized)
+ {
+ RealizeTree(pWin);
+ if (pWin->viewable)
+ {
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ (WindowPtr *)NULL);
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = TRUE;
+ }
+#endif /* DO_SAVE_UNDERS */
+ }
+ }
+ }
+ }
+
+ if (pFirstMapped)
+ {
+ pLayerWin = (*pScreen->GetLayerWindow)(pParent);
+ if (pLayerWin->parent != pParent) {
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pLayerWin,
+ pLayerWin,
+ (WindowPtr *)NULL);
+ pFirstMapped = pLayerWin;
+ }
+ if (anyMarked)
+ {
+#ifdef DO_SAVE_UNDERS
+ if (pLayerWin->parent != pParent)
+ {
+ if (dosave || (DO_SAVE_UNDERS(pLayerWin)))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin,
+ pLayerWin);
+ }
+ }
+ else if (dosave)
+ {
+ dosave = FALSE;
+ for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib)
+ {
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave |= (*pScreen->ChangeSaveUnder)(pWin,
+ pWin->nextSib);
+ if (dosave && !pFirstSaveUndered)
+ pFirstSaveUndered = pWin;
+ }
+ }
+ }
+#endif /* DO_SAVE_UNDERS */
+ (*pScreen->ValidateTree)(pLayerWin->parent, pFirstMapped, VTMap);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin,
+ pFirstSaveUndered->nextSib);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstMapped,
+ VTMap);
+ WindowsRestructured ();
+ }
+}
+
+static void
+UnrealizeTree(
+ WindowPtr pWin,
+ Bool fromConfigure)
+{
+ register WindowPtr pChild;
+ UnrealizeWindowProcPtr Unrealize;
+ MarkUnrealizedWindowProcPtr MarkUnrealizedWindow;
+
+ Unrealize = pWin->drawable.pScreen->UnrealizeWindow;
+ MarkUnrealizedWindow = pWin->drawable.pScreen->MarkUnrealizedWindow;
+ pChild = pWin;
+ while (1)
+ {
+ if (pChild->realized)
+ {
+ pChild->realized = FALSE;
+ pChild->visibility = VisibilityNotViewable;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && !pChild->drawable.pScreen->myNum) {
+ PanoramiXRes *win;
+ win = (PanoramiXRes*)LookupIDByType(pChild->drawable.id,
+ XRT_WINDOW);
+ if(win)
+ win->u.win.visibility = VisibilityNotViewable;
+ }
+#endif
+ (* Unrealize)(pChild);
+ DeleteWindowFromAnyEvents(pChild, FALSE);
+ if (pChild->viewable)
+ {
+#ifdef DO_SAVE_UNDERS
+ if (pChild->saveUnder)
+ deltaSaveUndersViewable--;
+#endif
+ pChild->viewable = FALSE;
+ if (pChild->backStorage)
+ (*pChild->drawable.pScreen->SaveDoomedAreas)(
+ pChild, &pChild->clipList, 0, 0);
+ (* MarkUnrealizedWindow)(pChild, pWin, fromConfigure);
+ pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ }
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ return;
+ pChild = pChild->nextSib;
+ }
+}
+
+/*****
+ * UnmapWindow
+ * If the window is already unmapped, this request has no effect.
+ * Otherwise, the window is unmapped and an UnMapNotify event is
+ * generated. Cannot unmap a root window.
+ *****/
+
+int
+UnmapWindow(register WindowPtr pWin, Bool fromConfigure)
+{
+ register WindowPtr pParent;
+ xEvent event;
+ Bool wasRealized = (Bool)pWin->realized;
+ Bool wasViewable = (Bool)pWin->viewable;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ WindowPtr pLayerWin = pWin;
+
+ #ifdef TEST
+ if (nxagentWindowTopLevel(pWin))
+ {
+ fprintf(stderr, "UnmapWindow: pWin [%p] fromConfigure [%d]\n", pWin,
+ fromConfigure);
+ }
+ #endif
+
+ if ((!pWin->mapped) || (!(pParent = pWin->parent)))
+ return(Success);
+ if (SubStrSend(pWin, pParent))
+ {
+ event.u.u.type = UnmapNotify;
+ event.u.unmapNotify.window = pWin->drawable.id;
+ event.u.unmapNotify.fromConfigure = fromConfigure;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ }
+ if (wasViewable && !fromConfigure)
+ {
+ pWin->valdata = UnmapValData;
+ (*pScreen->MarkOverlappedWindows)(pWin, pWin->nextSib, &pLayerWin);
+ (*pScreen->MarkWindow)(pLayerWin->parent);
+ }
+ pWin->mapped = FALSE;
+ if (wasRealized)
+ UnrealizeTree(pWin, fromConfigure);
+ if (wasViewable)
+ {
+ if (!fromConfigure)
+ {
+ (*pScreen->ValidateTree)(pLayerWin->parent, pWin, VTUnmap);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ if ( (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib) )
+ {
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+ }
+ }
+ pWin->DIXsaveUnder = FALSE;
+#endif /* DO_SAVE_UNDERS */
+ if (!fromConfigure && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pWin, VTUnmap);
+ }
+ if (wasRealized && !fromConfigure)
+ WindowsRestructured ();
+ return(Success);
+}
+
+/*****
+ * UnmapSubwindows
+ * Performs an UnmapWindow request with the specified mode on all mapped
+ * children of the window, in bottom to top stacking order.
+ *****/
+
+void
+UnmapSubwindows(register WindowPtr pWin)
+{
+ register WindowPtr pChild, pHead;
+ xEvent event;
+ Bool wasRealized = (Bool)pWin->realized;
+ Bool wasViewable = (Bool)pWin->viewable;
+ Bool anyMarked = FALSE;
+ Mask parentNotify;
+ WindowPtr pLayerWin = NULL;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ if (!pWin->firstChild)
+ return;
+ parentNotify = SubSend(pWin);
+ pHead = RealChildHead(pWin);
+
+ if (wasViewable)
+ pLayerWin = (*pScreen->GetLayerWindow)(pWin);
+
+ for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+ {
+ if (pChild->mapped)
+ {
+ if (parentNotify || StrSend(pChild))
+ {
+ event.u.u.type = UnmapNotify;
+ event.u.unmapNotify.window = pChild->drawable.id;
+ event.u.unmapNotify.fromConfigure = xFalse;
+ DeliverEvents(pChild, &event, 1, NullWindow);
+ }
+ if (pChild->viewable)
+ {
+ pChild->valdata = UnmapValData;
+ anyMarked = TRUE;
+ }
+ pChild->mapped = FALSE;
+ if (pChild->realized)
+ UnrealizeTree(pChild, FALSE);
+ if (wasViewable)
+ {
+#ifdef DO_SAVE_UNDERS
+ pChild->DIXsaveUnder = FALSE;
+#endif /* DO_SAVE_UNDERS */
+ if (pChild->backStorage)
+ (*pScreen->SaveDoomedAreas)(
+ pChild, &pChild->clipList, 0, 0);
+ }
+ }
+ }
+ if (wasViewable)
+ {
+ if (anyMarked)
+ {
+ if (pLayerWin->parent == pWin)
+ (*pScreen->MarkWindow)(pWin);
+ else
+ {
+ WindowPtr ptmp;
+ (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
+ (WindowPtr *)NULL);
+ (*pScreen->MarkWindow)(pLayerWin->parent);
+
+ /* Windows between pWin and pLayerWin may not have been marked */
+ ptmp = pWin;
+
+ while (ptmp != pLayerWin->parent)
+ {
+ (*pScreen->MarkWindow)(ptmp);
+ ptmp = ptmp->parent;
+ }
+ pHead = pWin->firstChild;
+ }
+ (*pScreen->ValidateTree)(pLayerWin->parent, pHead, VTUnmap);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ if ( (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin))
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
+ }
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pHead, VTUnmap);
+ }
+ if (wasRealized)
+ WindowsRestructured ();
+}
+
+
+void
+HandleSaveSet(register ClientPtr client)
+{
+ register WindowPtr pParent, pWin;
+ register int j;
+
+ for (j=0; j<client->numSaved; j++)
+ {
+ pWin = SaveSetWindow(client->saveSet[j]);
+#ifdef XFIXES
+ if (SaveSetToRoot(client->saveSet[j]))
+ pParent = WindowTable[pWin->drawable.pScreen->myNum];
+ else
+#endif
+ {
+ pParent = pWin->parent;
+ while (pParent && (wClient (pParent) == client))
+ pParent = pParent->parent;
+ }
+ if (pParent)
+ {
+ if (pParent != pWin->parent)
+ {
+ ReparentWindow(pWin, pParent,
+ pWin->drawable.x - wBorderWidth (pWin) - pParent->drawable.x,
+ pWin->drawable.y - wBorderWidth (pWin) - pParent->drawable.y,
+ client);
+ if(!pWin->realized && pWin->mapped)
+ pWin->mapped = FALSE;
+ }
+#ifdef XFIXES
+ if (SaveSetRemap (client->saveSet[j]))
+#endif
+ MapWindow(pWin, client);
+ }
+ }
+ xfree(client->saveSet);
+ client->numSaved = 0;
+ client->saveSet = (SaveSetElt *)NULL;
+}
+
+/**
+ *
+ * \param x,y in root
+ * \param box "return" value
+ */
+Bool
+VisibleBoundingBoxFromPoint(register WindowPtr pWin, int x, int y, BoxPtr box)
+{
+ if (!pWin->realized)
+ return (FALSE);
+ if (POINT_IN_REGION(pWin->drawable.pScreen, &pWin->clipList, x, y, box))
+ return(TRUE);
+ return(FALSE);
+}
+
+/**
+ *
+ * \param x,y in root
+ */
+Bool
+PointInWindowIsVisible(register WindowPtr pWin, int x, int y)
+{
+ BoxRec box;
+
+ if (!pWin->realized)
+ return (FALSE);
+ if (POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderClip,
+ x, y, &box)
+ && (!wInputShape(pWin) ||
+ POINT_IN_REGION(pWin->drawable.pScreen,
+ wInputShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box)))
+ return(TRUE);
+ return(FALSE);
+}
+
+
+RegionPtr
+NotClippedByChildren(register WindowPtr pWin)
+{
+ register ScreenPtr pScreen;
+ RegionPtr pReg;
+
+ pScreen = pWin->drawable.pScreen;
+ pReg = REGION_CREATE(pScreen, NullBox, 1);
+ if (pWin->parent ||
+ screenIsSaved != SCREEN_SAVER_ON ||
+ !HasSaverWindow (pWin->drawable.pScreen->myNum))
+ {
+ REGION_INTERSECT(pScreen, pReg, &pWin->borderClip, &pWin->winSize);
+ }
+ return(pReg);
+}
+
+void
+SendVisibilityNotify(WindowPtr pWin)
+{
+ xEvent event;
+#ifndef NO_XINERAMA_PORT
+ unsigned int visibility = pWin->visibility;
+#endif
+#ifdef PANORAMIX
+ /* This is not quite correct yet, but it's close */
+ if(!noPanoramiXExtension) {
+ PanoramiXRes *win;
+ WindowPtr pWin2;
+ int i, Scrnum;
+
+ Scrnum = pWin->drawable.pScreen->myNum;
+
+ win = PanoramiXFindIDByScrnum(XRT_WINDOW, pWin->drawable.id, Scrnum);
+
+ if(!win || (win->u.win.visibility == visibility))
+ return;
+
+ switch(visibility) {
+ case VisibilityUnobscured:
+ for(i = 0; i < PanoramiXNumScreens; i++) {
+ if(i == Scrnum) continue;
+
+ pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW);
+
+ if (pWin2) {
+ if(pWin2->visibility == VisibilityPartiallyObscured)
+ return;
+
+ if(!i) pWin = pWin2;
+ }
+ }
+ break;
+ case VisibilityPartiallyObscured:
+ if(Scrnum) {
+ pWin2 = (WindowPtr)LookupIDByType(win->info[0].id, RT_WINDOW);
+ if (pWin2) pWin = pWin2;
+ }
+ break;
+ case VisibilityFullyObscured:
+ for(i = 0; i < PanoramiXNumScreens; i++) {
+ if(i == Scrnum) continue;
+
+ pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW);
+
+ if (pWin2) {
+ if(pWin2->visibility != VisibilityFullyObscured)
+ return;
+
+ if(!i) pWin = pWin2;
+ }
+ }
+ break;
+ }
+
+ win->u.win.visibility = visibility;
+ }
+#endif
+
+ event.u.u.type = VisibilityNotify;
+ event.u.visibility.window = pWin->drawable.id;
+ event.u.visibility.state = visibility;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+}
+
+
+#define RANDOM_WIDTH 32
+
+#ifndef NOLOGOHACK
+static void DrawLogo(
+ WindowPtr pWin
+);
+#endif
+
+void
+SaveScreens(int on, int mode)
+{
+ int i;
+ int what;
+ int type;
+
+ if (on == SCREEN_SAVER_FORCER)
+ {
+ UpdateCurrentTimeIf();
+ lastDeviceEventTime = currentTime;
+ if (mode == ScreenSaverReset)
+ what = SCREEN_SAVER_OFF;
+ else
+ what = SCREEN_SAVER_ON;
+ type = what;
+ }
+ else
+ {
+ what = on;
+ type = what;
+ if (what == screenIsSaved)
+ type = SCREEN_SAVER_CYCLE;
+ }
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ if (on == SCREEN_SAVER_FORCER)
+ (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i], on);
+ if (savedScreenInfo[i].ExternalScreenSaver)
+ {
+ if (nxagentOption(Timeout) != 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "SaveScreens: An external screen-saver handler is installed. "
+ "Ignoring it to let the auto-disconnect feature work.\n");
+ #endif
+ }
+ else
+ {
+ if ((*savedScreenInfo[i].ExternalScreenSaver)
+ (screenInfo.screens[i], type, on == SCREEN_SAVER_FORCER))
+ continue;
+ }
+ }
+ if (type == screenIsSaved)
+ continue;
+ switch (type) {
+ case SCREEN_SAVER_OFF:
+ if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
+ {
+ (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
+ what);
+ }
+ else if (HasSaverWindow (i))
+ {
+ savedScreenInfo[i].pWindow = NullWindow;
+ FreeResource(savedScreenInfo[i].wid, RT_NONE);
+ }
+ break;
+ case SCREEN_SAVER_CYCLE:
+ if (savedScreenInfo[i].blanked == SCREEN_IS_TILED)
+ {
+ WindowPtr pWin = savedScreenInfo[i].pWindow;
+ /* make it look like screen saver is off, so that
+ * NotClippedByChildren will compute a clip list
+ * for the root window, so miPaintWindow works
+ */
+ screenIsSaved = SCREEN_SAVER_OFF;
+#ifndef NOLOGOHACK
+ if (logoScreenSaver)
+ (*pWin->drawable.pScreen->ClearToBackground)(pWin, 0, 0, 0, 0, FALSE);
+#endif
+ (*pWin->drawable.pScreen->MoveWindow)(pWin,
+ (short)(-(rand() % RANDOM_WIDTH)),
+ (short)(-(rand() % RANDOM_WIDTH)),
+ pWin->nextSib, VTMove);
+#ifndef NOLOGOHACK
+ if (logoScreenSaver)
+ DrawLogo(pWin);
+#endif
+ screenIsSaved = SCREEN_SAVER_ON;
+ }
+ /*
+ * Call the DDX saver in case it wants to do something
+ * at cycle time
+ */
+ else if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
+ {
+ (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
+ type);
+ }
+ break;
+ case SCREEN_SAVER_ON:
+ if (ScreenSaverBlanking != DontPreferBlanking)
+ {
+ if ((* screenInfo.screens[i]->SaveScreen)
+ (screenInfo.screens[i], what))
+ {
+ savedScreenInfo[i].blanked = SCREEN_IS_BLANKED;
+ continue;
+ }
+ if ((ScreenSaverAllowExposures != DontAllowExposures) &&
+ TileScreenSaver(i, SCREEN_IS_BLACK))
+ {
+ savedScreenInfo[i].blanked = SCREEN_IS_BLACK;
+ continue;
+ }
+ }
+ if ((ScreenSaverAllowExposures != DontAllowExposures) &&
+ TileScreenSaver(i, SCREEN_IS_TILED))
+ {
+ savedScreenInfo[i].blanked = SCREEN_IS_TILED;
+ }
+ else
+ savedScreenInfo[i].blanked = SCREEN_ISNT_SAVED;
+ break;
+ }
+ }
+ screenIsSaved = what;
+ if (mode == ScreenSaverReset)
+ SetScreenSaverTimer();
+}
+
+static Bool
+TileScreenSaver(int i, int kind)
+{
+ int j;
+ int result;
+ XID attributes[3];
+ Mask mask;
+ WindowPtr pWin;
+ CursorMetricRec cm;
+ unsigned char *srcbits, *mskbits;
+ CursorPtr cursor;
+ XID cursorID = 0;
+ int attri;
+
+ mask = 0;
+ attri = 0;
+ switch (kind) {
+ case SCREEN_IS_TILED:
+ switch (WindowTable[i]->backgroundState) {
+ case BackgroundPixel:
+ attributes[attri++] = WindowTable[i]->background.pixel;
+ mask |= CWBackPixel;
+ break;
+ case BackgroundPixmap:
+ attributes[attri++] = None;
+ mask |= CWBackPixmap;
+ break;
+ default:
+ break;
+ }
+ break;
+ case SCREEN_IS_BLACK:
+ attributes[attri++] = WindowTable[i]->drawable.pScreen->blackPixel;
+ mask |= CWBackPixel;
+ break;
+ }
+ mask |= CWOverrideRedirect;
+ attributes[attri++] = xTrue;
+
+ /*
+ * create a blank cursor
+ */
+
+ cm.width=16;
+ cm.height=16;
+ cm.xhot=8;
+ cm.yhot=8;
+ srcbits = (unsigned char *)xalloc( BitmapBytePad(32)*16);
+ mskbits = (unsigned char *)xalloc( BitmapBytePad(32)*16);
+ if (!srcbits || !mskbits)
+ {
+ xfree(srcbits);
+ xfree(mskbits);
+ cursor = 0;
+ }
+ else
+ {
+ for (j=0; j<BitmapBytePad(32)*16; j++)
+ srcbits[j] = mskbits[j] = 0x0;
+ cursor = AllocCursor(srcbits, mskbits, &cm, 0, 0, 0, 0, 0, 0);
+ if (cursor)
+ {
+ cursorID = FakeClientID(0);
+ if (AddResource (cursorID, RT_CURSOR, (pointer) cursor))
+ {
+ attributes[attri] = cursorID;
+ mask |= CWCursor;
+ }
+ else
+ cursor = 0;
+ }
+ else
+ {
+ xfree (srcbits);
+ xfree (mskbits);
+ }
+ }
+
+ pWin = savedScreenInfo[i].pWindow =
+ CreateWindow(savedScreenInfo[i].wid,
+ WindowTable[i],
+ -RANDOM_WIDTH, -RANDOM_WIDTH,
+ (unsigned short)screenInfo.screens[i]->width + RANDOM_WIDTH,
+ (unsigned short)screenInfo.screens[i]->height + RANDOM_WIDTH,
+ 0, InputOutput, mask, attributes, 0, serverClient,
+ wVisual (WindowTable[i]), &result);
+
+ if (cursor)
+ FreeResource (cursorID, RT_NONE);
+
+ if (!pWin)
+ return FALSE;
+
+ if (!AddResource(pWin->drawable.id, RT_WINDOW,
+ (pointer)savedScreenInfo[i].pWindow))
+ return FALSE;
+
+ if (mask & CWBackPixmap)
+ {
+ MakeRootTile (pWin);
+ (*pWin->drawable.pScreen->ChangeWindowAttributes)(pWin, CWBackPixmap);
+ }
+ MapWindow(pWin, serverClient);
+#ifndef NOLOGOHACK
+ if (kind == SCREEN_IS_TILED && logoScreenSaver)
+ DrawLogo(pWin);
+#endif
+ return TRUE;
+}
+
+/*
+ * FindWindowWithOptional
+ *
+ * search ancestors of the given window for an entry containing
+ * a WindowOpt structure. Assumptions: some parent will
+ * contain the structure.
+ */
+
+WindowPtr
+FindWindowWithOptional (register WindowPtr w)
+{
+ do
+ w = w->parent;
+ while (!w->optional);
+ return w;
+}
+
+/*
+ * CheckWindowOptionalNeed
+ *
+ * check each optional entry in the given window to see if
+ * the value is satisfied by the default rules. If so,
+ * release the optional record
+ */
+
+void
+CheckWindowOptionalNeed (register WindowPtr w)
+{
+ register WindowOptPtr optional;
+ register WindowOptPtr parentOptional;
+
+ if (!w->parent)
+ return;
+ optional = w->optional;
+ if (optional->dontPropagateMask != DontPropagateMasks[w->dontPropagate])
+ return;
+ if (optional->otherEventMasks != 0)
+ return;
+ if (optional->otherClients != NULL)
+ return;
+ if (optional->passiveGrabs != NULL)
+ return;
+ if (optional->userProps != NULL)
+ return;
+ if (optional->backingBitPlanes != ~0L)
+ return;
+ if (optional->backingPixel != 0)
+ return;
+#ifdef SHAPE
+ if (optional->boundingShape != NULL)
+ return;
+ if (optional->clipShape != NULL)
+ return;
+ if (optional->inputShape != NULL)
+ return;
+#endif
+#ifdef XINPUT
+ if (optional->inputMasks != NULL)
+ return;
+#endif
+ parentOptional = FindWindowWithOptional(w)->optional;
+ if (optional->visual != parentOptional->visual)
+ return;
+ if (optional->cursor != None &&
+ (optional->cursor != parentOptional->cursor ||
+ w->parent->cursorIsNone))
+ return;
+ if (optional->colormap != parentOptional->colormap)
+ return;
+ DisposeWindowOptional (w);
+}
+
+/*
+ * MakeWindowOptional
+ *
+ * create an optional record and initialize it with the default
+ * values.
+ */
+
+Bool
+MakeWindowOptional (register WindowPtr pWin)
+{
+ register WindowOptPtr optional;
+ register WindowOptPtr parentOptional;
+
+ if (pWin->optional)
+ return TRUE;
+ optional = (WindowOptPtr) xalloc (sizeof (WindowOptRec));
+ if (!optional)
+ return FALSE;
+ optional->dontPropagateMask = DontPropagateMasks[pWin->dontPropagate];
+ optional->otherEventMasks = 0;
+ optional->otherClients = NULL;
+ optional->passiveGrabs = NULL;
+ optional->userProps = NULL;
+ optional->backingBitPlanes = ~0L;
+ optional->backingPixel = 0;
+#ifdef SHAPE
+ optional->boundingShape = NULL;
+ optional->clipShape = NULL;
+ optional->inputShape = NULL;
+#endif
+#ifdef XINPUT
+ optional->inputMasks = NULL;
+#endif
+ parentOptional = FindWindowWithOptional(pWin)->optional;
+ optional->visual = parentOptional->visual;
+ if (!pWin->cursorIsNone)
+ {
+ optional->cursor = parentOptional->cursor;
+ optional->cursor->refcnt++;
+ }
+ else
+ {
+ optional->cursor = None;
+ }
+ optional->colormap = parentOptional->colormap;
+ pWin->optional = optional;
+ return TRUE;
+}
+
+void
+DisposeWindowOptional (register WindowPtr pWin)
+{
+ if (!pWin->optional)
+ return;
+ /*
+ * everything is peachy. Delete the optional record
+ * and clean up
+ */
+ /*
+ * TOG changed this code to:
+ *
+ * if (pWin->cursorIsNone == FALSE)
+ * FreeCursor (pWin->optional->cursor, (Cursor)0);
+ * pWin->cursorIsNone = TRUE;
+ *
+ * This is blatently wrong; windows without optionals can have
+ * two different cursor values, either None or sharing their
+ * parents cursor. This difference is controlled by the
+ * cursorIsNone value; when TRUE, the window has no cursor,
+ * when false, it shares its cursor with its parent; TOG
+ * made it impossible for a window to have a cursor without
+ * an optional record.
+ */
+ if (pWin->optional->cursor)
+ {
+ FreeCursor (pWin->optional->cursor, (Cursor)0);
+ pWin->cursorIsNone = FALSE;
+ }
+ else
+ pWin->cursorIsNone = TRUE;
+/* FIXME
+ There is an error when disposing ClientResources on Agent exit
+ this xfree is not valid in some window at exit
+*/
+
+ xfree (pWin->optional);
+ pWin->optional = NULL;
+}
+
+#ifndef NOLOGOHACK
+static void
+DrawLogo(WindowPtr pWin)
+{
+ DrawablePtr pDraw;
+ ScreenPtr pScreen;
+ int x, y;
+ unsigned int width, height, size;
+ GC *pGC;
+ int thin, gap, d31;
+ DDXPointRec poly[4];
+ ChangeGCVal fore[2], back[2];
+ xrgb rgb[2];
+ BITS32 fmask, bmask;
+ ColormapPtr cmap;
+
+ pDraw = (DrawablePtr)pWin;
+ pScreen = pDraw->pScreen;
+ x = -pWin->origin.x;
+ y = -pWin->origin.y;
+ width = pScreen->width;
+ height = pScreen->height;
+ pGC = GetScratchGC(pScreen->rootDepth, pScreen);
+ if (!pGC)
+ return;
+
+ if ((rand() % 100) <= 17) /* make the probability for white fairly low */
+ fore[0].val = pScreen->whitePixel;
+ else
+ fore[0].val = pScreen->blackPixel;
+ if ((pWin->backgroundState == BackgroundPixel) &&
+ (cmap = (ColormapPtr)LookupIDByType(wColormap (pWin), RT_COLORMAP))) {
+ Pixel querypixels[2];
+
+ querypixels[0] = fore[0].val;
+ querypixels[1] = pWin->background.pixel;
+ QueryColors(cmap, 2, querypixels, rgb);
+ if ((rgb[0].red == rgb[1].red) &&
+ (rgb[0].green == rgb[1].green) &&
+ (rgb[0].blue == rgb[1].blue)) {
+ if (fore[0].val == pScreen->blackPixel)
+ fore[0].val = pScreen->whitePixel;
+ else
+ fore[0].val = pScreen->blackPixel;
+ }
+ }
+ fore[1].val = FillSolid;
+ fmask = GCForeground|GCFillStyle;
+ if (pWin->backgroundState == BackgroundPixel) {
+ back[0].val = pWin->background.pixel;
+ back[1].val = FillSolid;
+ bmask = GCForeground|GCFillStyle;
+ } else {
+ back[0].val = 0;
+ back[1].val = 0;
+ dixChangeGC(NullClient, pGC, GCTileStipXOrigin|GCTileStipYOrigin,
+ NULL, back);
+ back[0].val = FillTiled;
+ back[1].ptr = pWin->background.pixmap;
+ bmask = GCFillStyle|GCTile;
+ }
+
+ /* should be the same as the reference function XmuDrawLogo() */
+
+ size = width;
+ if (height < width)
+ size = height;
+ size = RANDOM_WIDTH + rand() % (size - RANDOM_WIDTH);
+ size &= ~1;
+ x += rand() % (width - size);
+ y += rand() % (height - size);
+
+/*
+ * Draw what will be the thin strokes.
+ *
+ * -----
+ * / /
+ * / /
+ * / /
+ * / /
+ * /____/
+ * d
+ *
+ * Point d is 9/44 (~1/5) of the way across.
+ */
+
+ thin = (size / 11);
+ if (thin < 1) thin = 1;
+ gap = (thin+3) / 4;
+ d31 = thin + thin + gap;
+ poly[0].x = x + size; poly[0].y = y;
+ poly[1].x = x + size-d31; poly[1].y = y;
+ poly[2].x = x + 0; poly[2].y = y + size;
+ poly[3].x = x + d31; poly[3].y = y + size;
+ dixChangeGC(NullClient, pGC, fmask, NULL, fore);
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase area not needed for lower thin stroke.
+ *
+ * ------
+ * / /
+ * / __ /
+ * / / /
+ * / / /
+ * /__/__/
+ */
+
+ poly[0].x = x + d31/2; poly[0].y = y + size;
+ poly[1].x = x + size / 2; poly[1].y = y + size/2;
+ poly[2].x = x + (size/2)+(d31-(d31/2)); poly[2].y = y + size/2;
+ poly[3].x = x + d31; poly[3].y = y + size;
+ dixChangeGC(NullClient, pGC, bmask, NULL, back);
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase area not needed for upper thin stroke.
+ *
+ * ------
+ * / / /
+ * /--/ /
+ * / /
+ * / /
+ * /_____/
+ */
+
+ poly[0].x = x + size - d31/2; poly[0].y = y;
+ poly[1].x = x + size / 2; poly[1].y = y + size/2;
+ poly[2].x = x + (size/2)-(d31-(d31/2)); poly[2].y = y + size/2;
+ poly[3].x = x + size - d31; poly[3].y = y;
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Draw thick stroke.
+ * Point b is 1/4 of the way across.
+ *
+ * b
+ * -----
+ * \ \
+ * \ \
+ * \ \
+ * \ \
+ * \____\
+ */
+
+ poly[0].x = x; poly[0].y = y;
+ poly[1].x = x + size/4; poly[1].y = y;
+ poly[2].x = x + size; poly[2].y = y + size;
+ poly[3].x = x + size - size/4; poly[3].y = y + size;
+ dixChangeGC(NullClient, pGC, fmask, NULL, fore);
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase to create gap.
+ *
+ * /
+ * /
+ * /
+ * /
+ * /
+ */
+
+ poly[0].x = x + size- thin; poly[0].y = y;
+ poly[1].x = x + size-( thin+gap); poly[1].y = y;
+ poly[2].x = x + thin; poly[2].y = y + size;
+ poly[3].x = x + thin + gap; poly[3].y = y + size;
+ dixChangeGC(NullClient, pGC, bmask, NULL, back);
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+ FreeScratchGC(pGC);
+}
+
+#endif
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.X.original
new file mode 100644
index 000000000..c060f4a23
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.X.original
@@ -0,0 +1,3853 @@
+/* $XdotOrg: xc/programs/Xserver/dix/window.c,v 1.12 2005/07/03 08:53:38 daniels Exp $ */
+/* $Xorg: window.c,v 1.4 2001/02/09 02:04:41 xorgcvs Exp $ */
+/*
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+*/
+
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/window.c,v 3.36 2003/11/14 23:52:50 torrey Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#include "dixevents.h"
+#include "globals.h"
+
+#ifdef XAPPGROUP
+#include <X11/extensions/Xagsrv.h>
+#endif
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+
+/******
+ * Window stuff for server
+ *
+ * CreateRootWindow, CreateWindow, ChangeWindowAttributes,
+ * GetWindowAttributes, DeleteWindow, DestroySubWindows,
+ * HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows,
+ * UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow,
+ *
+ ******/
+
+static unsigned char _back_lsb[4] = {0x88, 0x22, 0x44, 0x11};
+static unsigned char _back_msb[4] = {0x11, 0x44, 0x22, 0x88};
+
+int screenIsSaved = SCREEN_SAVER_OFF;
+
+ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
+
+#if 0
+extern void DeleteWindowFromAnyEvents();
+extern Mask EventMaskForClient();
+extern void WindowHasNewCursor();
+extern void RecalculateDeliverableEvents();
+#endif
+
+static Bool TileScreenSaver(int i, int kind);
+
+
+#define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \
+ CWDontPropagate | CWOverrideRedirect | CWCursor )
+
+#define BOXES_OVERLAP(b1, b2) \
+ (!( ((b1)->x2 <= (b2)->x1) || \
+ ( ((b1)->x1 >= (b2)->x2)) || \
+ ( ((b1)->y2 <= (b2)->y1)) || \
+ ( ((b1)->y1 >= (b2)->y2)) ) )
+
+#define RedirectSend(pWin) \
+ ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureRedirectMask)
+
+#define SubSend(pWin) \
+ ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask)
+
+#define StrSend(pWin) \
+ ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask)
+
+#define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
+
+
+int numSaveUndersViewable = 0;
+int deltaSaveUndersViewable = 0;
+
+#ifdef DEBUG
+/******
+ * PrintWindowTree
+ * For debugging only
+ ******/
+
+int
+PrintChildren(WindowPtr p1, int indent)
+{
+ WindowPtr p2;
+ int i;
+
+ while (p1)
+ {
+ p2 = p1->firstChild;
+ for (i=0; i<indent; i++) ErrorF( " ");
+ ErrorF( "%x\n", p1->drawable.id);
+ miPrintRegion(&p1->clipList);
+ PrintChildren(p2, indent+4);
+ p1 = p1->nextSib;
+ }
+}
+
+PrintWindowTree()
+{
+ int i;
+ WindowPtr pWin, p1;
+
+ for (i=0; i<screenInfo.numScreens; i++)
+ {
+ ErrorF( "WINDOW %d\n", i);
+ pWin = WindowTable[i];
+ miPrintRegion(&pWin->clipList);
+ p1 = pWin->firstChild;
+ PrintChildren(p1, 4);
+ }
+}
+#endif
+
+int
+TraverseTree(register WindowPtr pWin, VisitWindowProcPtr func, pointer data)
+{
+ register int result;
+ register WindowPtr pChild;
+
+ if (!(pChild = pWin))
+ return(WT_NOMATCH);
+ while (1)
+ {
+ result = (* func)(pChild, data);
+ if (result == WT_STOPWALKING)
+ return(WT_STOPWALKING);
+ if ((result == WT_WALKCHILDREN) && pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ break;
+ pChild = pChild->nextSib;
+ }
+ return(WT_NOMATCH);
+}
+
+/*****
+ * WalkTree
+ * Walk the window tree, for SCREEN, preforming FUNC(pWin, data) on
+ * each window. If FUNC returns WT_WALKCHILDREN, traverse the children,
+ * if it returns WT_DONTWALKCHILDREN, dont. If it returns WT_STOPWALKING
+ * exit WalkTree. Does depth-first traverse.
+ *****/
+
+int
+WalkTree(ScreenPtr pScreen, VisitWindowProcPtr func, pointer data)
+{
+ return(TraverseTree(WindowTable[pScreen->myNum], func, data));
+}
+
+/* hack for forcing backing store on all windows */
+int defaultBackingStore = NotUseful;
+/* hack to force no backing store */
+Bool disableBackingStore = FALSE;
+Bool enableBackingStore = FALSE;
+/* hack to force no save unders */
+Bool disableSaveUnders = FALSE;
+
+static void
+SetWindowToDefaults(register WindowPtr pWin)
+{
+ pWin->prevSib = NullWindow;
+ pWin->firstChild = NullWindow;
+ pWin->lastChild = NullWindow;
+
+ pWin->valdata = (ValidatePtr)NULL;
+ pWin->optional = (WindowOptPtr)NULL;
+ pWin->cursorIsNone = TRUE;
+
+ pWin->backingStore = NotUseful;
+ pWin->DIXsaveUnder = FALSE;
+ pWin->backStorage = (pointer) NULL;
+
+ pWin->mapped = FALSE; /* off */
+ pWin->realized = FALSE; /* off */
+ pWin->viewable = FALSE;
+ pWin->visibility = VisibilityNotViewable;
+ pWin->overrideRedirect = FALSE;
+ pWin->saveUnder = FALSE;
+
+ pWin->bitGravity = ForgetGravity;
+ pWin->winGravity = NorthWestGravity;
+
+ pWin->eventMask = 0;
+ pWin->deliverableEvents = 0;
+ pWin->dontPropagate = 0;
+ pWin->forcedBS = FALSE;
+#ifdef NEED_DBE_BUF_BITS
+ pWin->srcBuffer = DBE_FRONT_BUFFER;
+ pWin->dstBuffer = DBE_FRONT_BUFFER;
+#endif
+#ifdef COMPOSITE
+ pWin->redirectDraw = 0;
+#endif
+}
+
+static void
+MakeRootTile(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ GCPtr pGC;
+ unsigned char back[128];
+ int len = BitmapBytePad(sizeof(long));
+ register unsigned char *from, *to;
+ register int i, j;
+
+ pWin->background.pixmap = (*pScreen->CreatePixmap)(pScreen, 4, 4,
+ pScreen->rootDepth);
+
+ pWin->backgroundState = BackgroundPixmap;
+ pGC = GetScratchGC(pScreen->rootDepth, pScreen);
+ if (!pWin->background.pixmap || !pGC)
+ FatalError("could not create root tile");
+
+ {
+ CARD32 attributes[2];
+
+ attributes[0] = pScreen->whitePixel;
+ attributes[1] = pScreen->blackPixel;
+
+ (void)ChangeGC(pGC, GCForeground | GCBackground, attributes);
+ }
+
+ ValidateGC((DrawablePtr)pWin->background.pixmap, pGC);
+
+ from = (screenInfo.bitmapBitOrder == LSBFirst) ? _back_lsb : _back_msb;
+ to = back;
+
+ for (i = 4; i > 0; i--, from++)
+ for (j = len; j > 0; j--)
+ *to++ = *from;
+
+ if (blackRoot)
+ bzero(back, sizeof(back));
+
+ (*pGC->ops->PutImage)((DrawablePtr)pWin->background.pixmap, pGC, 1,
+ 0, 0, len, 4, 0, XYBitmap, (char *)back);
+
+ FreeScratchGC(pGC);
+
+}
+
+WindowPtr
+AllocateWindow(ScreenPtr pScreen)
+{
+ WindowPtr pWin;
+ register char *ptr;
+ register DevUnion *ppriv;
+ register unsigned *sizes;
+ register unsigned size;
+ register int i;
+
+ pWin = (WindowPtr)xalloc(pScreen->totalWindowSize);
+ if (pWin)
+ {
+ ppriv = (DevUnion *)(pWin + 1);
+ pWin->devPrivates = ppriv;
+ sizes = pScreen->WindowPrivateSizes;
+ ptr = (char *)(ppriv + pScreen->WindowPrivateLen);
+ for (i = pScreen->WindowPrivateLen; --i >= 0; ppriv++, sizes++)
+ {
+ if ( (size = *sizes) )
+ {
+ ppriv->ptr = (pointer)ptr;
+ ptr += size;
+ }
+ else
+ ppriv->ptr = (pointer)NULL;
+ }
+ }
+ return pWin;
+}
+
+/*****
+ * CreateRootWindow
+ * Makes a window at initialization time for specified screen
+ *****/
+
+Bool
+CreateRootWindow(ScreenPtr pScreen)
+{
+ WindowPtr pWin;
+ BoxRec box;
+ PixmapFormatRec *format;
+
+ pWin = AllocateWindow(pScreen);
+ if (!pWin)
+ return FALSE;
+
+ savedScreenInfo[pScreen->myNum].pWindow = NULL;
+ savedScreenInfo[pScreen->myNum].wid = FakeClientID(0);
+ savedScreenInfo[pScreen->myNum].ExternalScreenSaver = NULL;
+ screenIsSaved = SCREEN_SAVER_OFF;
+
+ WindowTable[pScreen->myNum] = pWin;
+
+ pWin->drawable.pScreen = pScreen;
+ pWin->drawable.type = DRAWABLE_WINDOW;
+
+ pWin->drawable.depth = pScreen->rootDepth;
+ for (format = screenInfo.formats;
+ format->depth != pScreen->rootDepth;
+ format++)
+ ;
+ pWin->drawable.bitsPerPixel = format->bitsPerPixel;
+
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+ pWin->parent = NullWindow;
+ SetWindowToDefaults(pWin);
+
+ pWin->optional = (WindowOptRec *) xalloc (sizeof (WindowOptRec));
+ if (!pWin->optional)
+ return FALSE;
+
+ pWin->optional->dontPropagateMask = 0;
+ pWin->optional->otherEventMasks = 0;
+ pWin->optional->otherClients = NULL;
+ pWin->optional->passiveGrabs = NULL;
+ pWin->optional->userProps = NULL;
+ pWin->optional->backingBitPlanes = ~0L;
+ pWin->optional->backingPixel = 0;
+#ifdef SHAPE
+ pWin->optional->boundingShape = NULL;
+ pWin->optional->clipShape = NULL;
+ pWin->optional->inputShape = NULL;
+#endif
+#ifdef XINPUT
+ pWin->optional->inputMasks = NULL;
+#endif
+ pWin->optional->colormap = pScreen->defColormap;
+ pWin->optional->visual = pScreen->rootVisual;
+
+ pWin->nextSib = NullWindow;
+
+ pWin->drawable.id = FakeClientID(0);
+
+ pWin->origin.x = pWin->origin.y = 0;
+ pWin->drawable.height = pScreen->height;
+ pWin->drawable.width = pScreen->width;
+ pWin->drawable.x = pWin->drawable.y = 0;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pScreen->width;
+ box.y2 = pScreen->height;
+ REGION_INIT(pScreen, &pWin->clipList, &box, 1);
+ REGION_INIT(pScreen, &pWin->winSize, &box, 1);
+ REGION_INIT(pScreen, &pWin->borderSize, &box, 1);
+ REGION_INIT(pScreen, &pWin->borderClip, &box, 1);
+
+ pWin->drawable.class = InputOutput;
+ pWin->optional->visual = pScreen->rootVisual;
+
+ pWin->backgroundState = BackgroundPixel;
+ pWin->background.pixel = pScreen->whitePixel;
+
+ pWin->borderIsPixel = TRUE;
+ pWin->border.pixel = pScreen->blackPixel;
+ pWin->borderWidth = 0;
+
+ if (!AddResource(pWin->drawable.id, RT_WINDOW, (pointer)pWin))
+ return FALSE;
+
+ if (disableBackingStore)
+ pScreen->backingStoreSupport = NotUseful;
+ if (enableBackingStore)
+ pScreen->backingStoreSupport = Always;
+
+#ifdef DO_SAVE_UNDERS
+ if ((pScreen->backingStoreSupport != NotUseful) &&
+ (pScreen->saveUnderSupport == NotUseful))
+ {
+ /*
+ * If the screen has backing-store but no save-unders, let the
+ * clients know we can support save-unders using backing-store.
+ */
+ pScreen->saveUnderSupport = USE_DIX_SAVE_UNDERS;
+ }
+#endif /* DO_SAVE_UNDERS */
+
+ if (disableSaveUnders)
+ pScreen->saveUnderSupport = NotUseful;
+
+ return TRUE;
+}
+
+void
+InitRootWindow(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ if (!(*pScreen->CreateWindow)(pWin))
+ return; /* XXX */
+ (*pScreen->PositionWindow)(pWin, 0, 0);
+
+ pWin->cursorIsNone = FALSE;
+ pWin->optional->cursor = rootCursor;
+ rootCursor->refcnt++;
+ MakeRootTile(pWin);
+ pWin->backingStore = defaultBackingStore;
+ pWin->forcedBS = (defaultBackingStore != NotUseful);
+ /* We SHOULD check for an error value here XXX */
+ (*pScreen->ChangeWindowAttributes)(pWin,
+ CWBackPixmap|CWBorderPixel|CWCursor|CWBackingStore);
+
+ MapWindow(pWin, serverClient);
+}
+
+/* Set the region to the intersection of the rectangle and the
+ * window's winSize. The window is typically the parent of the
+ * window from which the region came.
+ */
+
+void
+ClippedRegionFromBox(register WindowPtr pWin, RegionPtr Rgn,
+ register int x, register int y,
+ register int w, register int h)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ BoxRec box;
+
+ box = *(REGION_EXTENTS(pScreen, &pWin->winSize));
+ /* we do these calculations to avoid overflows */
+ if (x > box.x1)
+ box.x1 = x;
+ if (y > box.y1)
+ box.y1 = y;
+ x += w;
+ if (x < box.x2)
+ box.x2 = x;
+ y += h;
+ if (y < box.y2)
+ box.y2 = y;
+ if (box.x1 > box.x2)
+ box.x2 = box.x1;
+ if (box.y1 > box.y2)
+ box.y2 = box.y1;
+ REGION_RESET(pScreen, Rgn, &box);
+ REGION_INTERSECT(pScreen, Rgn, Rgn, &pWin->winSize);
+}
+
+WindowPtr
+RealChildHead(register WindowPtr pWin)
+{
+ if (!pWin->parent &&
+ (screenIsSaved == SCREEN_SAVER_ON) &&
+ (HasSaverWindow (pWin->drawable.pScreen->myNum)))
+ return (pWin->firstChild);
+ else
+ return (NullWindow);
+}
+
+/*****
+ * CreateWindow
+ * Makes a window in response to client request
+ *****/
+
+WindowPtr
+CreateWindow(Window wid, register WindowPtr pParent, int x, int y, unsigned w,
+ unsigned h, unsigned bw, unsigned class, register Mask vmask, XID *vlist,
+ int depth, ClientPtr client, VisualID visual, int *error)
+{
+ register WindowPtr pWin;
+ WindowPtr pHead;
+ register ScreenPtr pScreen;
+ xEvent event;
+ int idepth, ivisual;
+ Bool fOK;
+ DepthPtr pDepth;
+ PixmapFormatRec *format;
+ register WindowOptPtr ancwopt;
+
+ if (class == CopyFromParent)
+ class = pParent->drawable.class;
+
+ if ((class != InputOutput) && (class != InputOnly))
+ {
+ *error = BadValue;
+ client->errorValue = class;
+ return NullWindow;
+ }
+
+ if ((class != InputOnly) && (pParent->drawable.class == InputOnly))
+ {
+ *error = BadMatch;
+ return NullWindow;
+ }
+
+ if ((class == InputOnly) && ((bw != 0) || (depth != 0)))
+ {
+ *error = BadMatch;
+ return NullWindow;
+ }
+
+ pScreen = pParent->drawable.pScreen;
+ if ((class == InputOutput) && (depth == 0))
+ depth = pParent->drawable.depth;
+ ancwopt = pParent->optional;
+ if (!ancwopt)
+ ancwopt = FindWindowWithOptional(pParent)->optional;
+ if (visual == CopyFromParent) {
+#ifdef XAPPGROUP
+ VisualID ag_visual;
+
+ if (client->appgroup && !pParent->parent &&
+ (ag_visual = XagRootVisual (client)))
+ visual = ag_visual;
+ else
+#endif
+ visual = ancwopt->visual;
+ }
+
+ /* Find out if the depth and visual are acceptable for this Screen */
+ if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth))
+ {
+ fOK = FALSE;
+ for(idepth = 0; idepth < pScreen->numDepths; idepth++)
+ {
+ pDepth = (DepthPtr) &pScreen->allowedDepths[idepth];
+ if ((depth == pDepth->depth) || (depth == 0))
+ {
+ for (ivisual = 0; ivisual < pDepth->numVids; ivisual++)
+ {
+ if (visual == pDepth->vids[ivisual])
+ {
+ fOK = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ if (fOK == FALSE)
+ {
+ *error = BadMatch;
+ return NullWindow;
+ }
+ }
+
+ if (((vmask & (CWBorderPixmap | CWBorderPixel)) == 0) &&
+ (class != InputOnly) &&
+ (depth != pParent->drawable.depth))
+ {
+ *error = BadMatch;
+ return NullWindow;
+ }
+
+ if (((vmask & CWColormap) == 0) &&
+ (class != InputOnly) &&
+ ((visual != ancwopt->visual) || (ancwopt->colormap == None)))
+ {
+ *error = BadMatch;
+ return NullWindow;
+ }
+
+ pWin = AllocateWindow(pScreen);
+ if (!pWin)
+ {
+ *error = BadAlloc;
+ return NullWindow;
+ }
+ pWin->drawable = pParent->drawable;
+ pWin->drawable.depth = depth;
+ if (depth == pParent->drawable.depth)
+ pWin->drawable.bitsPerPixel = pParent->drawable.bitsPerPixel;
+ else
+ {
+ for (format = screenInfo.formats; format->depth != depth; format++)
+ ;
+ pWin->drawable.bitsPerPixel = format->bitsPerPixel;
+ }
+ if (class == InputOnly)
+ pWin->drawable.type = (short) UNDRAWABLE_WINDOW;
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+ pWin->drawable.id = wid;
+ pWin->drawable.class = class;
+
+ pWin->parent = pParent;
+ SetWindowToDefaults(pWin);
+
+ if (visual != ancwopt->visual)
+ {
+ if (!MakeWindowOptional (pWin))
+ {
+ xfree (pWin);
+ *error = BadAlloc;
+ return NullWindow;
+ }
+ pWin->optional->visual = visual;
+ pWin->optional->colormap = None;
+ }
+
+ pWin->borderWidth = bw;
+#ifdef XCSECURITY
+ /* can't let untrusted clients have background None windows;
+ * they make it too easy to steal window contents
+ */
+ if (client->trustLevel != XSecurityClientTrusted)
+ {
+ pWin->backgroundState = BackgroundPixel;
+ pWin->background.pixel = 0;
+ }
+ else
+#endif
+ pWin->backgroundState = None;
+
+ pWin->borderIsPixel = pParent->borderIsPixel;
+ pWin->border = pParent->border;
+ if (pWin->borderIsPixel == FALSE)
+ pWin->border.pixmap->refcnt++;
+
+ pWin->origin.x = x + (int)bw;
+ pWin->origin.y = y + (int)bw;
+ pWin->drawable.width = w;
+ pWin->drawable.height = h;
+ pWin->drawable.x = pParent->drawable.x + x + (int)bw;
+ pWin->drawable.y = pParent->drawable.y + y + (int)bw;
+
+ /* set up clip list correctly for unobscured WindowPtr */
+ REGION_NULL(pScreen, &pWin->clipList);
+ REGION_NULL(pScreen, &pWin->borderClip);
+ REGION_NULL(pScreen, &pWin->winSize);
+ REGION_NULL(pScreen, &pWin->borderSize);
+
+ pHead = RealChildHead(pParent);
+ if (pHead)
+ {
+ pWin->nextSib = pHead->nextSib;
+ if (pHead->nextSib)
+ pHead->nextSib->prevSib = pWin;
+ else
+ pParent->lastChild = pWin;
+ pHead->nextSib = pWin;
+ pWin->prevSib = pHead;
+ }
+ else
+ {
+ pWin->nextSib = pParent->firstChild;
+ if (pParent->firstChild)
+ pParent->firstChild->prevSib = pWin;
+ else
+ pParent->lastChild = pWin;
+ pParent->firstChild = pWin;
+ }
+
+ SetWinSize (pWin);
+ SetBorderSize (pWin);
+
+ /* We SHOULD check for an error value here XXX */
+ if (!(*pScreen->CreateWindow)(pWin))
+ {
+ *error = BadAlloc;
+ DeleteWindow(pWin, None);
+ return NullWindow;
+ }
+ /* We SHOULD check for an error value here XXX */
+ (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
+
+ if (!(vmask & CWEventMask))
+ RecalculateDeliverableEvents(pWin);
+
+ if (vmask)
+ *error = ChangeWindowAttributes(pWin, vmask, vlist, wClient (pWin));
+ else
+ *error = Success;
+
+ if (*error != Success)
+ {
+ DeleteWindow(pWin, None);
+ return NullWindow;
+ }
+ if (!(vmask & CWBackingStore) && (defaultBackingStore != NotUseful))
+ {
+ XID value = defaultBackingStore;
+ (void)ChangeWindowAttributes(pWin, CWBackingStore, &value, wClient (pWin));
+ pWin->forcedBS = TRUE;
+ }
+
+ if (SubSend(pParent))
+ {
+ event.u.u.type = CreateNotify;
+ event.u.createNotify.window = wid;
+ event.u.createNotify.parent = pParent->drawable.id;
+ event.u.createNotify.x = x;
+ event.u.createNotify.y = y;
+ event.u.createNotify.width = w;
+ event.u.createNotify.height = h;
+ event.u.createNotify.borderWidth = bw;
+ event.u.createNotify.override = pWin->overrideRedirect;
+ DeliverEvents(pParent, &event, 1, NullWindow);
+ }
+ return pWin;
+}
+
+static void
+FreeWindowResources(register WindowPtr pWin)
+{
+ register ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ DeleteWindowFromAnySaveSet(pWin);
+ DeleteWindowFromAnySelections(pWin);
+ DeleteWindowFromAnyEvents(pWin, TRUE);
+ REGION_UNINIT(pScreen, &pWin->clipList);
+ REGION_UNINIT(pScreen, &pWin->winSize);
+ REGION_UNINIT(pScreen, &pWin->borderClip);
+ REGION_UNINIT(pScreen, &pWin->borderSize);
+#ifdef SHAPE
+ if (wBoundingShape (pWin))
+ REGION_DESTROY(pScreen, wBoundingShape (pWin));
+ if (wClipShape (pWin))
+ REGION_DESTROY(pScreen, wClipShape (pWin));
+ if (wInputShape (pWin))
+ REGION_DESTROY(pScreen, wInputShape (pWin));
+#endif
+ if (pWin->borderIsPixel == FALSE)
+ (*pScreen->DestroyPixmap)(pWin->border.pixmap);
+ if (pWin->backgroundState == BackgroundPixmap)
+ (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+
+ DeleteAllWindowProperties(pWin);
+ /* We SHOULD check for an error value here XXX */
+ (*pScreen->DestroyWindow)(pWin);
+ DisposeWindowOptional (pWin);
+}
+
+static void
+CrushTree(WindowPtr pWin)
+{
+ register WindowPtr pChild, pSib, pParent;
+ UnrealizeWindowProcPtr UnrealizeWindow;
+ xEvent event;
+
+ if (!(pChild = pWin->firstChild))
+ return;
+ UnrealizeWindow = pWin->drawable.pScreen->UnrealizeWindow;
+ while (1)
+ {
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ while (1)
+ {
+ pParent = pChild->parent;
+ if (SubStrSend(pChild, pParent))
+ {
+ event.u.u.type = DestroyNotify;
+ event.u.destroyNotify.window = pChild->drawable.id;
+ DeliverEvents(pChild, &event, 1, NullWindow);
+ }
+ FreeResource(pChild->drawable.id, RT_WINDOW);
+ pSib = pChild->nextSib;
+#ifdef DO_SAVE_UNDERS
+ if (pChild->saveUnder && pChild->viewable)
+ deltaSaveUndersViewable--;
+#endif
+ pChild->viewable = FALSE;
+ if (pChild->realized)
+ {
+ pChild->realized = FALSE;
+ (*UnrealizeWindow)(pChild);
+ }
+ FreeWindowResources(pChild);
+ xfree(pChild);
+ if ( (pChild = pSib) )
+ break;
+ pChild = pParent;
+ pChild->firstChild = NullWindow;
+ pChild->lastChild = NullWindow;
+ if (pChild == pWin)
+ return;
+ }
+ }
+}
+
+/*****
+ * DeleteWindow
+ * Deletes child of window then window itself
+ * If wid is None, don't send any events
+ *****/
+
+int
+DeleteWindow(pointer value, XID wid)
+ {
+ register WindowPtr pParent;
+ register WindowPtr pWin = (WindowPtr)value;
+ xEvent event;
+
+ UnmapWindow(pWin, FALSE);
+
+ CrushTree(pWin);
+
+ pParent = pWin->parent;
+ if (wid && pParent && SubStrSend(pWin, pParent))
+ {
+ event.u.u.type = DestroyNotify;
+ event.u.destroyNotify.window = pWin->drawable.id;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ }
+
+ FreeWindowResources(pWin);
+ if (pParent)
+ {
+ if (pParent->firstChild == pWin)
+ pParent->firstChild = pWin->nextSib;
+ if (pParent->lastChild == pWin)
+ pParent->lastChild = pWin->prevSib;
+ if (pWin->nextSib)
+ pWin->nextSib->prevSib = pWin->prevSib;
+ if (pWin->prevSib)
+ pWin->prevSib->nextSib = pWin->nextSib;
+ }
+ xfree(pWin);
+ return Success;
+}
+
+void
+DestroySubwindows(register WindowPtr pWin, ClientPtr client)
+{
+ /* XXX
+ * The protocol is quite clear that each window should be
+ * destroyed in turn, however, unmapping all of the first
+ * eliminates most of the calls to ValidateTree. So,
+ * this implementation is incorrect in that all of the
+ * UnmapNotifies occur before all of the DestroyNotifies.
+ * If you care, simply delete the call to UnmapSubwindows.
+ */
+ UnmapSubwindows(pWin);
+ while (pWin->lastChild)
+ FreeResource(pWin->lastChild->drawable.id, RT_NONE);
+}
+
+#define DeviceEventMasks (KeyPressMask | KeyReleaseMask | ButtonPressMask | \
+ ButtonReleaseMask | PointerMotionMask)
+
+/*****
+ * ChangeWindowAttributes
+ *
+ * The value-mask specifies which attributes are to be changed; the
+ * value-list contains one value for each one bit in the mask, from least
+ * to most significant bit in the mask.
+ *****/
+
+int
+ChangeWindowAttributes(register WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
+{
+ register Mask index2;
+ register XID *pVlist;
+ PixmapPtr pPixmap;
+ Pixmap pixID;
+ CursorPtr pCursor, pOldCursor;
+ Cursor cursorID;
+ WindowPtr pChild;
+ Colormap cmap;
+ ColormapPtr pCmap;
+ xEvent xE;
+ int result;
+ register ScreenPtr pScreen;
+ Mask vmaskCopy = 0;
+ register Mask tmask;
+ unsigned int val;
+ int error;
+ Bool checkOptional = FALSE;
+ Bool borderRelative = FALSE;
+ WindowPtr pLayerWin;
+
+ if ((pWin->drawable.class == InputOnly) && (vmask & (~INPUTONLY_LEGAL_MASK)))
+ return BadMatch;
+
+ error = Success;
+ pScreen = pWin->drawable.pScreen;
+ pVlist = vlist;
+ tmask = vmask;
+ while (tmask)
+ {
+ index2 = (Mask) lowbit (tmask);
+ tmask &= ~index2;
+ switch (index2)
+ {
+ case CWBackPixmap:
+ pixID = (Pixmap )*pVlist;
+ pVlist++;
+ if (pWin->backgroundState == ParentRelative)
+ borderRelative = TRUE;
+ if (pixID == None)
+ {
+#ifdef XCSECURITY
+ /* can't let untrusted clients have background None windows */
+ if (client->trustLevel == XSecurityClientTrusted)
+ {
+#endif
+ if (pWin->backgroundState == BackgroundPixmap)
+ (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+ if (!pWin->parent)
+ MakeRootTile(pWin);
+ else
+ pWin->backgroundState = None;
+#ifdef XCSECURITY
+ }
+ else
+ { /* didn't change the background to None, so don't tell ddx */
+ index2 = 0;
+ }
+#endif
+ }
+ else if (pixID == ParentRelative)
+ {
+ if (pWin->parent &&
+ pWin->drawable.depth != pWin->parent->drawable.depth)
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ if (pWin->backgroundState == BackgroundPixmap)
+ (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+ if (!pWin->parent)
+ MakeRootTile(pWin);
+ else
+ pWin->backgroundState = ParentRelative;
+ borderRelative = TRUE;
+ /* Note that the parent's backgroundTile's refcnt is NOT
+ * incremented. */
+ }
+ else
+ {
+ pPixmap = (PixmapPtr)SecurityLookupIDByType(client, pixID,
+ RT_PIXMAP, SecurityReadAccess);
+ if (pPixmap != (PixmapPtr) NULL)
+ {
+ if ((pPixmap->drawable.depth != pWin->drawable.depth) ||
+ (pPixmap->drawable.pScreen != pScreen))
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ if (pWin->backgroundState == BackgroundPixmap)
+ (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+ pWin->backgroundState = BackgroundPixmap;
+ pWin->background.pixmap = pPixmap;
+ pPixmap->refcnt++;
+ }
+ else
+ {
+ error = BadPixmap;
+ client->errorValue = pixID;
+ goto PatchUp;
+ }
+ }
+ break;
+ case CWBackPixel:
+ if (pWin->backgroundState == ParentRelative)
+ borderRelative = TRUE;
+ if (pWin->backgroundState == BackgroundPixmap)
+ (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+ pWin->backgroundState = BackgroundPixel;
+ pWin->background.pixel = (CARD32 ) *pVlist;
+ /* background pixel overrides background pixmap,
+ so don't let the ddx layer see both bits */
+ vmaskCopy &= ~CWBackPixmap;
+ pVlist++;
+ break;
+ case CWBorderPixmap:
+ pixID = (Pixmap ) *pVlist;
+ pVlist++;
+ if (pixID == CopyFromParent)
+ {
+ if (!pWin->parent ||
+ (pWin->drawable.depth != pWin->parent->drawable.depth))
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ if (pWin->borderIsPixel == FALSE)
+ (*pScreen->DestroyPixmap)(pWin->border.pixmap);
+ pWin->border = pWin->parent->border;
+ if ((pWin->borderIsPixel = pWin->parent->borderIsPixel) == TRUE)
+ {
+ index2 = CWBorderPixel;
+ }
+ else
+ {
+ pWin->parent->border.pixmap->refcnt++;
+ }
+ }
+ else
+ {
+ pPixmap = (PixmapPtr)SecurityLookupIDByType(client, pixID,
+ RT_PIXMAP, SecurityReadAccess);
+ if (pPixmap)
+ {
+ if ((pPixmap->drawable.depth != pWin->drawable.depth) ||
+ (pPixmap->drawable.pScreen != pScreen))
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ if (pWin->borderIsPixel == FALSE)
+ (*pScreen->DestroyPixmap)(pWin->border.pixmap);
+ pWin->borderIsPixel = FALSE;
+ pWin->border.pixmap = pPixmap;
+ pPixmap->refcnt++;
+ }
+ else
+ {
+ error = BadPixmap;
+ client->errorValue = pixID;
+ goto PatchUp;
+ }
+ }
+ break;
+ case CWBorderPixel:
+ if (pWin->borderIsPixel == FALSE)
+ (*pScreen->DestroyPixmap)(pWin->border.pixmap);
+ pWin->borderIsPixel = TRUE;
+ pWin->border.pixel = (CARD32) *pVlist;
+ /* border pixel overrides border pixmap,
+ so don't let the ddx layer see both bits */
+ vmaskCopy &= ~CWBorderPixmap;
+ pVlist++;
+ break;
+ case CWBitGravity:
+ val = (CARD8 )*pVlist;
+ pVlist++;
+ if (val > StaticGravity)
+ {
+ error = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ pWin->bitGravity = val;
+ break;
+ case CWWinGravity:
+ val = (CARD8 )*pVlist;
+ pVlist++;
+ if (val > StaticGravity)
+ {
+ error = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ pWin->winGravity = val;
+ break;
+ case CWBackingStore:
+ val = (CARD8 )*pVlist;
+ pVlist++;
+ if ((val != NotUseful) && (val != WhenMapped) && (val != Always))
+ {
+ error = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ pWin->backingStore = val;
+ pWin->forcedBS = FALSE;
+ break;
+ case CWBackingPlanes:
+ if (pWin->optional || ((CARD32)*pVlist != (CARD32)~0L)) {
+ if (!pWin->optional && !MakeWindowOptional (pWin))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ pWin->optional->backingBitPlanes = (CARD32) *pVlist;
+ if ((CARD32)*pVlist == (CARD32)~0L)
+ checkOptional = TRUE;
+ }
+ pVlist++;
+ break;
+ case CWBackingPixel:
+ if (pWin->optional || (CARD32) *pVlist) {
+ if (!pWin->optional && !MakeWindowOptional (pWin))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ pWin->optional->backingPixel = (CARD32) *pVlist;
+ if (!*pVlist)
+ checkOptional = TRUE;
+ }
+ pVlist++;
+ break;
+ case CWSaveUnder:
+ val = (BOOL) *pVlist;
+ pVlist++;
+ if ((val != xTrue) && (val != xFalse))
+ {
+ error = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+#ifdef DO_SAVE_UNDERS
+ if (pWin->parent && (pWin->saveUnder != val) && (pWin->viewable) &&
+ DO_SAVE_UNDERS(pWin))
+ {
+ /*
+ * Re-check all siblings and inferiors for obscurity or
+ * exposition (hee hee).
+ */
+ if (pWin->saveUnder)
+ deltaSaveUndersViewable--;
+ else
+ deltaSaveUndersViewable++;
+ pWin->saveUnder = val;
+
+ if (pWin->firstChild)
+ {
+ pLayerWin = (*pScreen->GetLayerWindow)(pWin);
+ if ((*pScreen->ChangeSaveUnder)(pLayerWin->parent, pWin->nextSib))
+ (*pScreen->PostChangeSaveUnder)(pLayerWin->parent,
+ pWin->nextSib);
+ }
+ else
+ {
+ if ((*pScreen->ChangeSaveUnder)(pWin, pWin->nextSib))
+ (*pScreen->PostChangeSaveUnder)(pWin,
+ pWin->nextSib);
+ }
+ }
+ else
+ {
+ /* If we're changing the saveUnder attribute of the root
+ * window, all we do is set pWin->saveUnder so that
+ * GetWindowAttributes returns the right value. We don't
+ * do the "normal" save-under processing (as above).
+ * Hope that doesn't cause any problems.
+ */
+ pWin->saveUnder = val;
+ }
+#else
+ pWin->saveUnder = val;
+#endif /* DO_SAVE_UNDERS */
+ break;
+ case CWEventMask:
+ result = EventSelectForWindow(pWin, client, (Mask )*pVlist);
+ if (result)
+ {
+ error = result;
+ goto PatchUp;
+ }
+ pVlist++;
+ break;
+ case CWDontPropagate:
+ result = EventSuppressForWindow(pWin, client, (Mask )*pVlist,
+ &checkOptional);
+ if (result)
+ {
+ error = result;
+ goto PatchUp;
+ }
+ pVlist++;
+ break;
+ case CWOverrideRedirect:
+ val = (BOOL ) *pVlist;
+ pVlist++;
+ if ((val != xTrue) && (val != xFalse))
+ {
+ error = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ pWin->overrideRedirect = val;
+ break;
+ case CWColormap:
+ cmap = (Colormap) *pVlist;
+ pVlist++;
+ if (cmap == CopyFromParent)
+ {
+#ifdef XAPPGROUP
+ Colormap ag_colormap;
+ ClientPtr win_owner;
+
+ /*
+ * win_owner == client for CreateWindow, other clients
+ * can ChangeWindowAttributes
+ */
+ win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+
+ if ( win_owner && win_owner->appgroup &&
+ !pWin->parent->parent &&
+ (ag_colormap = XagDefaultColormap (win_owner)))
+ cmap = ag_colormap;
+ else
+#endif
+ if (pWin->parent &&
+ (!pWin->optional ||
+ pWin->optional->visual == wVisual (pWin->parent)))
+ {
+ cmap = wColormap (pWin->parent);
+ }
+ else
+ cmap = None;
+ }
+ if (cmap == None)
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ pCmap = (ColormapPtr)SecurityLookupIDByType(client, cmap,
+ RT_COLORMAP, SecurityReadAccess);
+ if (!pCmap)
+ {
+ error = BadColor;
+ client->errorValue = cmap;
+ goto PatchUp;
+ }
+ if (pCmap->pVisual->vid != wVisual (pWin) ||
+ pCmap->pScreen != pScreen)
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ if (cmap != wColormap (pWin))
+ {
+ if (!pWin->optional)
+ {
+ if (!MakeWindowOptional (pWin))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ }
+ else if (pWin->parent && cmap == wColormap (pWin->parent))
+ checkOptional = TRUE;
+
+ /*
+ * propagate the original colormap to any children
+ * inheriting it
+ */
+
+ for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+ {
+ if (!pChild->optional && !MakeWindowOptional (pChild))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ }
+
+ pWin->optional->colormap = cmap;
+
+ /*
+ * check on any children now matching the new colormap
+ */
+
+ for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+ {
+ if (pChild->optional->colormap == cmap)
+ CheckWindowOptionalNeed (pChild);
+ }
+
+ xE.u.u.type = ColormapNotify;
+ xE.u.colormap.window = pWin->drawable.id;
+ xE.u.colormap.colormap = cmap;
+ xE.u.colormap.new = xTrue;
+ xE.u.colormap.state = IsMapInstalled(cmap, pWin);
+ DeliverEvents(pWin, &xE, 1, NullWindow);
+ }
+ break;
+ case CWCursor:
+ cursorID = (Cursor ) *pVlist;
+ pVlist++;
+ /*
+ * install the new
+ */
+ if ( cursorID == None)
+ {
+ if (pWin == WindowTable[pWin->drawable.pScreen->myNum])
+ pCursor = rootCursor;
+ else
+ pCursor = (CursorPtr) None;
+ }
+ else
+ {
+ pCursor = (CursorPtr)SecurityLookupIDByType(client, cursorID,
+ RT_CURSOR, SecurityReadAccess);
+ if (!pCursor)
+ {
+ error = BadCursor;
+ client->errorValue = cursorID;
+ goto PatchUp;
+ }
+ }
+
+ if (pCursor != wCursor (pWin))
+ {
+ /*
+ * patch up child windows so they don't lose cursors.
+ */
+
+ for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+ {
+ if (!pChild->optional && !pChild->cursorIsNone &&
+ !MakeWindowOptional (pChild))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ }
+
+ pOldCursor = 0;
+ if (pCursor == (CursorPtr) None)
+ {
+ pWin->cursorIsNone = TRUE;
+ if (pWin->optional)
+ {
+ pOldCursor = pWin->optional->cursor;
+ pWin->optional->cursor = (CursorPtr) None;
+ checkOptional = TRUE;
+ }
+ } else {
+ if (!pWin->optional)
+ {
+ if (!MakeWindowOptional (pWin))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ }
+ else if (pWin->parent && pCursor == wCursor (pWin->parent))
+ checkOptional = TRUE;
+ pOldCursor = pWin->optional->cursor;
+ pWin->optional->cursor = pCursor;
+ pCursor->refcnt++;
+ pWin->cursorIsNone = FALSE;
+ /*
+ * check on any children now matching the new cursor
+ */
+
+ for (pChild=pWin->firstChild; pChild; pChild=pChild->nextSib)
+ {
+ if (pChild->optional &&
+ (pChild->optional->cursor == pCursor))
+ CheckWindowOptionalNeed (pChild);
+ }
+ }
+
+ if (pWin->realized)
+ WindowHasNewCursor( pWin);
+
+ /* Can't free cursor until here - old cursor
+ * is needed in WindowHasNewCursor
+ */
+ if (pOldCursor)
+ FreeCursor (pOldCursor, (Cursor)0);
+ }
+ break;
+ default:
+ error = BadValue;
+ client->errorValue = vmask;
+ goto PatchUp;
+ }
+ vmaskCopy |= index2;
+ }
+PatchUp:
+ if (checkOptional)
+ CheckWindowOptionalNeed (pWin);
+
+ /* We SHOULD check for an error value here XXX */
+ (*pScreen->ChangeWindowAttributes)(pWin, vmaskCopy);
+
+ /*
+ If the border contents have changed, redraw the border.
+ Note that this has to be done AFTER pScreen->ChangeWindowAttributes
+ for the tile to be rotated, and the correct function selected.
+ */
+ if (((vmaskCopy & (CWBorderPixel | CWBorderPixmap)) || borderRelative)
+ && pWin->viewable && HasBorder (pWin))
+ {
+ RegionRec exposed;
+
+ REGION_NULL(pScreen, &exposed);
+ REGION_SUBTRACT(pScreen, &exposed, &pWin->borderClip, &pWin->winSize);
+ (*pWin->drawable.pScreen->PaintWindowBorder)(pWin, &exposed, PW_BORDER);
+ REGION_UNINIT(pScreen, &exposed);
+ }
+ return error;
+}
+
+
+/*****
+ * GetWindowAttributes
+ * Notice that this is different than ChangeWindowAttributes
+ *****/
+
+void
+GetWindowAttributes(register WindowPtr pWin, ClientPtr client, xGetWindowAttributesReply *wa)
+{
+ wa->type = X_Reply;
+ wa->bitGravity = pWin->bitGravity;
+ wa->winGravity = pWin->winGravity;
+ if (pWin->forcedBS && pWin->backingStore != Always)
+ wa->backingStore = NotUseful;
+ else
+ wa->backingStore = pWin->backingStore;
+ wa->length = (sizeof(xGetWindowAttributesReply) -
+ sizeof(xGenericReply)) >> 2;
+ wa->sequenceNumber = client->sequence;
+ wa->backingBitPlanes = wBackingBitPlanes (pWin);
+ wa->backingPixel = wBackingPixel (pWin);
+ wa->saveUnder = (BOOL)pWin->saveUnder;
+ wa->override = pWin->overrideRedirect;
+ if (!pWin->mapped)
+ wa->mapState = IsUnmapped;
+ else if (pWin->realized)
+ wa->mapState = IsViewable;
+ else
+ wa->mapState = IsUnviewable;
+
+ wa->colormap = wColormap (pWin);
+ wa->mapInstalled = (wa->colormap == None) ? xFalse
+ : IsMapInstalled(wa->colormap, pWin);
+
+ wa->yourEventMask = EventMaskForClient(pWin, client);
+ wa->allEventMasks = pWin->eventMask | wOtherEventMasks (pWin);
+ wa->doNotPropagateMask = wDontPropagateMask (pWin);
+ wa->class = pWin->drawable.class;
+ wa->visualID = wVisual (pWin);
+}
+
+
+WindowPtr
+MoveWindowInStack(register WindowPtr pWin, register WindowPtr pNextSib)
+{
+ register WindowPtr pParent = pWin->parent;
+ WindowPtr pFirstChange = pWin; /* highest window where list changes */
+
+ if (pWin->nextSib != pNextSib)
+ {
+ WindowPtr pOldNextSib = pWin->nextSib;
+
+ if (!pNextSib) /* move to bottom */
+ {
+ if (pParent->firstChild == pWin)
+ pParent->firstChild = pWin->nextSib;
+ /* if (pWin->nextSib) */ /* is always True: pNextSib == NULL
+ * and pWin->nextSib != pNextSib
+ * therefore pWin->nextSib != NULL */
+ pFirstChange = pWin->nextSib;
+ pWin->nextSib->prevSib = pWin->prevSib;
+ if (pWin->prevSib)
+ pWin->prevSib->nextSib = pWin->nextSib;
+ pParent->lastChild->nextSib = pWin;
+ pWin->prevSib = pParent->lastChild;
+ pWin->nextSib = NullWindow;
+ pParent->lastChild = pWin;
+ }
+ else if (pParent->firstChild == pNextSib) /* move to top */
+ {
+ pFirstChange = pWin;
+ if (pParent->lastChild == pWin)
+ pParent->lastChild = pWin->prevSib;
+ if (pWin->nextSib)
+ pWin->nextSib->prevSib = pWin->prevSib;
+ if (pWin->prevSib)
+ pWin->prevSib->nextSib = pWin->nextSib;
+ pWin->nextSib = pParent->firstChild;
+ pWin->prevSib = (WindowPtr ) NULL;
+ pNextSib->prevSib = pWin;
+ pParent->firstChild = pWin;
+ }
+ else /* move in middle of list */
+ {
+ WindowPtr pOldNext = pWin->nextSib;
+
+ pFirstChange = NullWindow;
+ if (pParent->firstChild == pWin)
+ pFirstChange = pParent->firstChild = pWin->nextSib;
+ if (pParent->lastChild == pWin) {
+ pFirstChange = pWin;
+ pParent->lastChild = pWin->prevSib;
+ }
+ if (pWin->nextSib)
+ pWin->nextSib->prevSib = pWin->prevSib;
+ if (pWin->prevSib)
+ pWin->prevSib->nextSib = pWin->nextSib;
+ pWin->nextSib = pNextSib;
+ pWin->prevSib = pNextSib->prevSib;
+ if (pNextSib->prevSib)
+ pNextSib->prevSib->nextSib = pWin;
+ pNextSib->prevSib = pWin;
+ if (!pFirstChange) { /* do we know it yet? */
+ pFirstChange = pParent->firstChild; /* no, search from top */
+ while ((pFirstChange != pWin) && (pFirstChange != pOldNext))
+ pFirstChange = pFirstChange->nextSib;
+ }
+ }
+ if(pWin->drawable.pScreen->RestackWindow)
+ (*pWin->drawable.pScreen->RestackWindow)(pWin, pOldNextSib);
+ }
+
+#ifdef ROOTLESS
+ /*
+ * In rootless mode we can't optimize away window restacks.
+ * There may be non-X windows around, so even if the window
+ * is in the correct position from X's point of view,
+ * the underlying window system may want to reorder it.
+ */
+ else if (pWin->drawable.pScreen->RestackWindow)
+ (*pWin->drawable.pScreen->RestackWindow)(pWin, pWin->nextSib);
+#endif
+
+ return( pFirstChange );
+}
+
+RegionPtr
+CreateUnclippedWinSize (register WindowPtr pWin)
+{
+ RegionPtr pRgn;
+ BoxRec box;
+
+ box.x1 = pWin->drawable.x;
+ box.y1 = pWin->drawable.y;
+ box.x2 = pWin->drawable.x + (int) pWin->drawable.width;
+ box.y2 = pWin->drawable.y + (int) pWin->drawable.height;
+ pRgn = REGION_CREATE(pWin->drawable.pScreen, &box, 1);
+#ifdef SHAPE
+ if (wBoundingShape (pWin) || wClipShape (pWin)) {
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ REGION_TRANSLATE(pScreen, pRgn, - pWin->drawable.x,
+ - pWin->drawable.y);
+ if (wBoundingShape (pWin))
+ REGION_INTERSECT(pScreen, pRgn, pRgn, wBoundingShape (pWin));
+ if (wClipShape (pWin))
+ REGION_INTERSECT(pScreen, pRgn, pRgn, wClipShape (pWin));
+ REGION_TRANSLATE(pScreen, pRgn, pWin->drawable.x, pWin->drawable.y);
+ }
+#endif
+ return pRgn;
+}
+
+void
+SetWinSize (register WindowPtr pWin)
+{
+#ifdef COMPOSITE
+ if (pWin->redirectDraw)
+ {
+ BoxRec box;
+
+ box.x1 = pWin->drawable.x;
+ box.y1 = pWin->drawable.y;
+ box.x2 = pWin->drawable.x + pWin->drawable.width;
+ box.y2 = pWin->drawable.y + pWin->drawable.height;
+ REGION_RESET (pScreen, &pWin->winSize, &box);
+ }
+ else
+#endif
+ ClippedRegionFromBox(pWin->parent, &pWin->winSize,
+ pWin->drawable.x, pWin->drawable.y,
+ (int)pWin->drawable.width,
+ (int)pWin->drawable.height);
+#ifdef SHAPE
+ if (wBoundingShape (pWin) || wClipShape (pWin)) {
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ REGION_TRANSLATE(pScreen, &pWin->winSize, - pWin->drawable.x,
+ - pWin->drawable.y);
+ if (wBoundingShape (pWin))
+ REGION_INTERSECT(pScreen, &pWin->winSize, &pWin->winSize,
+ wBoundingShape (pWin));
+ if (wClipShape (pWin))
+ REGION_INTERSECT(pScreen, &pWin->winSize, &pWin->winSize,
+ wClipShape (pWin));
+ REGION_TRANSLATE(pScreen, &pWin->winSize, pWin->drawable.x,
+ pWin->drawable.y);
+ }
+#endif
+}
+
+void
+SetBorderSize (register WindowPtr pWin)
+{
+ int bw;
+
+ if (HasBorder (pWin)) {
+ bw = wBorderWidth (pWin);
+#ifdef COMPOSITE
+ if (pWin->redirectDraw)
+ {
+ BoxRec box;
+
+ box.x1 = pWin->drawable.x - bw;
+ box.y1 = pWin->drawable.y - bw;
+ box.x2 = pWin->drawable.x + pWin->drawable.width + bw;
+ box.y2 = pWin->drawable.y + pWin->drawable.height + bw;
+ REGION_RESET (pScreen, &pWin->borderSize, &box);
+ }
+ else
+#endif
+ ClippedRegionFromBox(pWin->parent, &pWin->borderSize,
+ pWin->drawable.x - bw, pWin->drawable.y - bw,
+ (int)(pWin->drawable.width + (bw<<1)),
+ (int)(pWin->drawable.height + (bw<<1)));
+#ifdef SHAPE
+ if (wBoundingShape (pWin)) {
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ REGION_TRANSLATE(pScreen, &pWin->borderSize, - pWin->drawable.x,
+ - pWin->drawable.y);
+ REGION_INTERSECT(pScreen, &pWin->borderSize, &pWin->borderSize,
+ wBoundingShape (pWin));
+ REGION_TRANSLATE(pScreen, &pWin->borderSize, pWin->drawable.x,
+ pWin->drawable.y);
+ REGION_UNION(pScreen, &pWin->borderSize, &pWin->borderSize,
+ &pWin->winSize);
+ }
+#endif
+ } else {
+ REGION_COPY(pWin->drawable.pScreen, &pWin->borderSize,
+ &pWin->winSize);
+ }
+}
+
+/**
+ *
+ * \param x,y new window position
+ * \param oldx,oldy old window position
+ * \param destx,desty position relative to gravity
+ */
+
+void
+GravityTranslate (register int x, register int y, int oldx, int oldy,
+ int dw, int dh, unsigned gravity,
+ register int *destx, register int *desty)
+{
+ switch (gravity) {
+ case NorthGravity:
+ *destx = x + dw / 2;
+ *desty = y;
+ break;
+ case NorthEastGravity:
+ *destx = x + dw;
+ *desty = y;
+ break;
+ case WestGravity:
+ *destx = x;
+ *desty = y + dh / 2;
+ break;
+ case CenterGravity:
+ *destx = x + dw / 2;
+ *desty = y + dh / 2;
+ break;
+ case EastGravity:
+ *destx = x + dw;
+ *desty = y + dh / 2;
+ break;
+ case SouthWestGravity:
+ *destx = x;
+ *desty = y + dh;
+ break;
+ case SouthGravity:
+ *destx = x + dw / 2;
+ *desty = y + dh;
+ break;
+ case SouthEastGravity:
+ *destx = x + dw;
+ *desty = y + dh;
+ break;
+ case StaticGravity:
+ *destx = oldx;
+ *desty = oldy;
+ break;
+ default:
+ *destx = x;
+ *desty = y;
+ break;
+ }
+}
+
+/* XXX need to retile border on each window with ParentRelative origin */
+void
+ResizeChildrenWinSize(register WindowPtr pWin, int dx, int dy, int dw, int dh)
+{
+ register ScreenPtr pScreen;
+ register WindowPtr pSib, pChild;
+ Bool resized = (dw || dh);
+
+ pScreen = pWin->drawable.pScreen;
+
+ for (pSib = pWin->firstChild; pSib; pSib = pSib->nextSib)
+ {
+ if (resized && (pSib->winGravity > NorthWestGravity))
+ {
+ int cwsx, cwsy;
+
+ cwsx = pSib->origin.x;
+ cwsy = pSib->origin.y;
+ GravityTranslate (cwsx, cwsy, cwsx - dx, cwsy - dy, dw, dh,
+ pSib->winGravity, &cwsx, &cwsy);
+ if (cwsx != pSib->origin.x || cwsy != pSib->origin.y)
+ {
+ xEvent event;
+
+ event.u.u.type = GravityNotify;
+ event.u.gravity.window = pSib->drawable.id;
+ event.u.gravity.x = cwsx - wBorderWidth (pSib);
+ event.u.gravity.y = cwsy - wBorderWidth (pSib);
+ DeliverEvents (pSib, &event, 1, NullWindow);
+ pSib->origin.x = cwsx;
+ pSib->origin.y = cwsy;
+ }
+ }
+ pSib->drawable.x = pWin->drawable.x + pSib->origin.x;
+ pSib->drawable.y = pWin->drawable.y + pSib->origin.y;
+ SetWinSize (pSib);
+ SetBorderSize (pSib);
+ (*pScreen->PositionWindow)(pSib, pSib->drawable.x, pSib->drawable.y);
+
+ if ( (pChild = pSib->firstChild) )
+ {
+ while (1)
+ {
+ pChild->drawable.x = pChild->parent->drawable.x +
+ pChild->origin.x;
+ pChild->drawable.y = pChild->parent->drawable.y +
+ pChild->origin.y;
+ SetWinSize (pChild);
+ SetBorderSize (pChild);
+ (*pScreen->PositionWindow)(pChild,
+ pChild->drawable.x, pChild->drawable.y);
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ while (!pChild->nextSib && (pChild != pSib))
+ pChild = pChild->parent;
+ if (pChild == pSib)
+ break;
+ pChild = pChild->nextSib;
+ }
+ }
+ }
+}
+
+#define GET_INT16(m, f) \
+ if (m & mask) \
+ { \
+ f = (INT16) *pVlist;\
+ pVlist++; \
+ }
+#define GET_CARD16(m, f) \
+ if (m & mask) \
+ { \
+ f = (CARD16) *pVlist;\
+ pVlist++;\
+ }
+
+#define GET_CARD8(m, f) \
+ if (m & mask) \
+ { \
+ f = (CARD8) *pVlist;\
+ pVlist++;\
+ }
+
+#define ChangeMask ((Mask)(CWX | CWY | CWWidth | CWHeight))
+
+#define IllegalInputOnlyConfigureMask (CWBorderWidth)
+
+/*
+ * IsSiblingAboveMe
+ * returns Above if pSib above pMe in stack or Below otherwise
+ */
+
+static int
+IsSiblingAboveMe(
+ register WindowPtr pMe,
+ register WindowPtr pSib)
+{
+ register WindowPtr pWin;
+
+ pWin = pMe->parent->firstChild;
+ while (pWin)
+ {
+ if (pWin == pSib)
+ return(Above);
+ else if (pWin == pMe)
+ return(Below);
+ pWin = pWin->nextSib;
+ }
+ return(Below);
+}
+
+static BoxPtr
+WindowExtents(
+ register WindowPtr pWin,
+ register BoxPtr pBox)
+{
+ pBox->x1 = pWin->drawable.x - wBorderWidth (pWin);
+ pBox->y1 = pWin->drawable.y - wBorderWidth (pWin);
+ pBox->x2 = pWin->drawable.x + (int)pWin->drawable.width
+ + wBorderWidth (pWin);
+ pBox->y2 = pWin->drawable.y + (int)pWin->drawable.height
+ + wBorderWidth (pWin);
+ return(pBox);
+}
+
+#ifdef SHAPE
+#define IS_SHAPED(pWin) (wBoundingShape (pWin) != (RegionPtr) NULL)
+
+static RegionPtr
+MakeBoundingRegion (
+ register WindowPtr pWin,
+ BoxPtr pBox)
+{
+ RegionPtr pRgn;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ pRgn = REGION_CREATE(pScreen, pBox, 1);
+ if (wBoundingShape (pWin)) {
+ REGION_TRANSLATE(pScreen, pRgn, -pWin->origin.x,
+ -pWin->origin.y);
+ REGION_INTERSECT(pScreen, pRgn, pRgn, wBoundingShape (pWin));
+ REGION_TRANSLATE(pScreen, pRgn, pWin->origin.x,
+ pWin->origin.y);
+ }
+ return pRgn;
+}
+
+static Bool
+ShapeOverlap (
+ WindowPtr pWin,
+ BoxPtr pWinBox,
+ WindowPtr pSib,
+ BoxPtr pSibBox)
+{
+ RegionPtr pWinRgn, pSibRgn;
+ register ScreenPtr pScreen;
+ Bool ret;
+
+ if (!IS_SHAPED(pWin) && !IS_SHAPED(pSib))
+ return TRUE;
+ pScreen = pWin->drawable.pScreen;
+ pWinRgn = MakeBoundingRegion (pWin, pWinBox);
+ pSibRgn = MakeBoundingRegion (pSib, pSibBox);
+ REGION_INTERSECT(pScreen, pWinRgn, pWinRgn, pSibRgn);
+ ret = REGION_NOTEMPTY(pScreen, pWinRgn);
+ REGION_DESTROY(pScreen, pWinRgn);
+ REGION_DESTROY(pScreen, pSibRgn);
+ return ret;
+}
+#endif
+
+static Bool
+AnyWindowOverlapsMe(
+ WindowPtr pWin,
+ WindowPtr pHead,
+ register BoxPtr box)
+{
+ register WindowPtr pSib;
+ BoxRec sboxrec;
+ register BoxPtr sbox;
+
+ for (pSib = pWin->prevSib; pSib != pHead; pSib = pSib->prevSib)
+ {
+ if (pSib->mapped)
+ {
+ sbox = WindowExtents(pSib, &sboxrec);
+ if (BOXES_OVERLAP(sbox, box)
+#ifdef SHAPE
+ && ShapeOverlap (pWin, box, pSib, sbox)
+#endif
+ )
+ return(TRUE);
+ }
+ }
+ return(FALSE);
+}
+
+static Bool
+IOverlapAnyWindow(
+ WindowPtr pWin,
+ register BoxPtr box)
+{
+ register WindowPtr pSib;
+ BoxRec sboxrec;
+ register BoxPtr sbox;
+
+ for (pSib = pWin->nextSib; pSib; pSib = pSib->nextSib)
+ {
+ if (pSib->mapped)
+ {
+ sbox = WindowExtents(pSib, &sboxrec);
+ if (BOXES_OVERLAP(sbox, box)
+#ifdef SHAPE
+ && ShapeOverlap (pWin, box, pSib, sbox)
+#endif
+ )
+ return(TRUE);
+ }
+ }
+ return(FALSE);
+}
+
+/*
+ * WhereDoIGoInTheStack()
+ * Given pWin and pSib and the relationshipe smode, return
+ * the window that pWin should go ABOVE.
+ * If a pSib is specified:
+ * Above: pWin is placed just above pSib
+ * Below: pWin is placed just below pSib
+ * TopIf: if pSib occludes pWin, then pWin is placed
+ * at the top of the stack
+ * BottomIf: if pWin occludes pSib, then pWin is
+ * placed at the bottom of the stack
+ * Opposite: if pSib occludes pWin, then pWin is placed at the
+ * top of the stack, else if pWin occludes pSib, then
+ * pWin is placed at the bottom of the stack
+ *
+ * If pSib is NULL:
+ * Above: pWin is placed at the top of the stack
+ * Below: pWin is placed at the bottom of the stack
+ * TopIf: if any sibling occludes pWin, then pWin is placed at
+ * the top of the stack
+ * BottomIf: if pWin occludes any sibline, then pWin is placed at
+ * the bottom of the stack
+ * Opposite: if any sibling occludes pWin, then pWin is placed at
+ * the top of the stack, else if pWin occludes any
+ * sibling, then pWin is placed at the bottom of the stack
+ *
+ */
+
+static WindowPtr
+WhereDoIGoInTheStack(
+ register WindowPtr pWin,
+ register WindowPtr pSib,
+ short x,
+ short y,
+ unsigned short w,
+ unsigned short h,
+ int smode)
+{
+ BoxRec box;
+ register ScreenPtr pScreen;
+ WindowPtr pHead, pFirst;
+
+ if ((pWin == pWin->parent->firstChild) &&
+ (pWin == pWin->parent->lastChild))
+ return((WindowPtr ) NULL);
+ pHead = RealChildHead(pWin->parent);
+ pFirst = pHead ? pHead->nextSib : pWin->parent->firstChild;
+ pScreen = pWin->drawable.pScreen;
+ box.x1 = x;
+ box.y1 = y;
+ box.x2 = x + (int)w;
+ box.y2 = y + (int)h;
+ switch (smode)
+ {
+ case Above:
+ if (pSib)
+ return(pSib);
+ else if (pWin == pFirst)
+ return(pWin->nextSib);
+ else
+ return(pFirst);
+ case Below:
+ if (pSib)
+ if (pSib->nextSib != pWin)
+ return(pSib->nextSib);
+ else
+ return(pWin->nextSib);
+ else
+ return NullWindow;
+ case TopIf:
+ if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+ return(pWin->nextSib);
+ else if (pSib)
+ {
+ if ((IsSiblingAboveMe(pWin, pSib) == Above) &&
+ (RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT))
+ return(pFirst);
+ else
+ return(pWin->nextSib);
+ }
+ else if (AnyWindowOverlapsMe(pWin, pHead, &box))
+ return(pFirst);
+ else
+ return(pWin->nextSib);
+ case BottomIf:
+ if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+ return(pWin->nextSib);
+ else if (pSib)
+ {
+ if ((IsSiblingAboveMe(pWin, pSib) == Below) &&
+ (RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT))
+ return NullWindow;
+ else
+ return(pWin->nextSib);
+ }
+ else if (IOverlapAnyWindow(pWin, &box))
+ return NullWindow;
+ else
+ return(pWin->nextSib);
+ case Opposite:
+ if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+ return(pWin->nextSib);
+ else if (pSib)
+ {
+ if (RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT)
+ {
+ if (IsSiblingAboveMe(pWin, pSib) == Above)
+ return(pFirst);
+ else
+ return NullWindow;
+ }
+ else
+ return(pWin->nextSib);
+ }
+ else if (AnyWindowOverlapsMe(pWin, pHead, &box))
+ {
+ /* If I'm occluded, I can't possibly be the first child
+ * if (pWin == pWin->parent->firstChild)
+ * return pWin->nextSib;
+ */
+ return(pFirst);
+ }
+ else if (IOverlapAnyWindow(pWin, &box))
+ return NullWindow;
+ else
+ return pWin->nextSib;
+ default:
+ {
+ ErrorF("Internal error in ConfigureWindow, smode == %d\n",smode );
+ return pWin->nextSib;
+ }
+ }
+}
+
+static void
+ReflectStackChange(
+ register WindowPtr pWin,
+ register WindowPtr pSib,
+ VTKind kind)
+{
+/* Note that pSib might be NULL */
+
+ Bool WasViewable = (Bool)pWin->viewable;
+ Bool anyMarked;
+ WindowPtr pFirstChange;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ /* if this is a root window, can't be restacked */
+ if (!pWin->parent)
+ return;
+
+ pFirstChange = MoveWindowInStack(pWin, pSib);
+
+ if (WasViewable)
+ {
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
+ &pLayerWin);
+ if (pLayerWin != pWin) pFirstChange = pLayerWin;
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pFirstChange);
+ }
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked)
+ {
+ (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, kind);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pFirstChange);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pWin->drawable.pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange, kind);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+}
+
+/*****
+ * ConfigureWindow
+ *****/
+
+int
+ConfigureWindow(register WindowPtr pWin, register Mask mask, XID *vlist, ClientPtr client)
+{
+#define RESTACK_WIN 0
+#define MOVE_WIN 1
+#define RESIZE_WIN 2
+#define REBORDER_WIN 3
+ register WindowPtr pSib = NullWindow;
+ register WindowPtr pParent = pWin->parent;
+ Window sibwid = 0;
+ Mask index2, tmask;
+ register XID *pVlist;
+ short x, y, beforeX, beforeY;
+ unsigned short w = pWin->drawable.width,
+ h = pWin->drawable.height,
+ bw = pWin->borderWidth;
+ int action, smode = Above;
+#ifdef XAPPGROUP
+ ClientPtr win_owner;
+ ClientPtr ag_leader = NULL;
+#endif
+ xEvent event;
+
+ if ((pWin->drawable.class == InputOnly) && (mask & IllegalInputOnlyConfigureMask))
+ return(BadMatch);
+
+ if ((mask & CWSibling) && !(mask & CWStackMode))
+ return(BadMatch);
+
+ pVlist = vlist;
+
+ if (pParent)
+ {
+ x = pWin->drawable.x - pParent->drawable.x - (int)bw;
+ y = pWin->drawable.y - pParent->drawable.y - (int)bw;
+ }
+ else
+ {
+ x = pWin->drawable.x;
+ y = pWin->drawable.y;
+ }
+ beforeX = x;
+ beforeY = y;
+ action = RESTACK_WIN;
+ if ((mask & (CWX | CWY)) && (!(mask & (CWHeight | CWWidth))))
+ {
+ GET_INT16(CWX, x);
+ GET_INT16(CWY, y);
+ action = MOVE_WIN;
+ }
+ /* or should be resized */
+ else if (mask & (CWX | CWY | CWWidth | CWHeight))
+ {
+ GET_INT16(CWX, x);
+ GET_INT16(CWY, y);
+ GET_CARD16(CWWidth, w);
+ GET_CARD16 (CWHeight, h);
+ if (!w || !h)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ action = RESIZE_WIN;
+ }
+ tmask = mask & ~ChangeMask;
+ while (tmask)
+ {
+ index2 = (Mask)lowbit (tmask);
+ tmask &= ~index2;
+ switch (index2)
+ {
+ case CWBorderWidth:
+ GET_CARD16(CWBorderWidth, bw);
+ break;
+ case CWSibling:
+ sibwid = (Window ) *pVlist;
+ pVlist++;
+ pSib = (WindowPtr )SecurityLookupIDByType(client, sibwid,
+ RT_WINDOW, SecurityReadAccess);
+ if (!pSib)
+ {
+ client->errorValue = sibwid;
+ return(BadWindow);
+ }
+ if (pSib->parent != pParent)
+ return(BadMatch);
+ if (pSib == pWin)
+ return(BadMatch);
+ break;
+ case CWStackMode:
+ GET_CARD8(CWStackMode, smode);
+ if ((smode != TopIf) && (smode != BottomIf) &&
+ (smode != Opposite) && (smode != Above) && (smode != Below))
+ {
+ client->errorValue = smode;
+ return(BadValue);
+ }
+ break;
+ default:
+ client->errorValue = mask;
+ return(BadValue);
+ }
+ }
+ /* root really can't be reconfigured, so just return */
+ if (!pParent)
+ return Success;
+
+ /* Figure out if the window should be moved. Doesnt
+ make the changes to the window if event sent */
+
+ if (mask & CWStackMode)
+ pSib = WhereDoIGoInTheStack(pWin, pSib, pParent->drawable.x + x,
+ pParent->drawable.y + y,
+ w + (bw << 1), h + (bw << 1), smode);
+ else
+ pSib = pWin->nextSib;
+
+#ifdef XAPPGROUP
+ win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+ ag_leader = XagLeader (win_owner);
+#endif
+
+ if ((!pWin->overrideRedirect) &&
+ (RedirectSend(pParent)
+#ifdef XAPPGROUP
+ || (win_owner->appgroup && ag_leader &&
+ XagIsControlledRoot (client, pParent))
+#endif
+ ))
+ {
+ event.u.u.type = ConfigureRequest;
+ event.u.configureRequest.window = pWin->drawable.id;
+ if (mask & CWSibling)
+ event.u.configureRequest.sibling = sibwid;
+ else
+ event.u.configureRequest.sibling = None;
+ if (mask & CWStackMode)
+ event.u.u.detail = smode;
+ else
+ event.u.u.detail = Above;
+ event.u.configureRequest.x = x;
+ event.u.configureRequest.y = y;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
+ event.u.configureRequest.x += panoramiXdataPtr[0].x;
+ event.u.configureRequest.y += panoramiXdataPtr[0].y;
+ }
+#endif
+ event.u.configureRequest.width = w;
+ event.u.configureRequest.height = h;
+ event.u.configureRequest.borderWidth = bw;
+ event.u.configureRequest.valueMask = mask;
+#ifdef XAPPGROUP
+ /* make sure if the ag_leader maps the window it goes to the wm */
+ if (ag_leader && ag_leader != client &&
+ XagIsControlledRoot (client, pParent)) {
+ event.u.configureRequest.parent = XagId (win_owner);
+ (void) TryClientEvents (ag_leader, &event, 1,
+ NoEventMask, NoEventMask, NullGrab);
+ return Success;
+ }
+#endif
+ event.u.configureRequest.parent = pParent->drawable.id;
+ if (MaybeDeliverEventsToClient(pParent, &event, 1,
+ SubstructureRedirectMask, client) == 1)
+ return(Success);
+ }
+ if (action == RESIZE_WIN)
+ {
+ Bool size_change = (w != pWin->drawable.width)
+ || (h != pWin->drawable.height);
+ if (size_change && ((pWin->eventMask|wOtherEventMasks(pWin)) & ResizeRedirectMask))
+ {
+ xEvent eventT;
+ eventT.u.u.type = ResizeRequest;
+ eventT.u.resizeRequest.window = pWin->drawable.id;
+ eventT.u.resizeRequest.width = w;
+ eventT.u.resizeRequest.height = h;
+ if (MaybeDeliverEventsToClient(pWin, &eventT, 1,
+ ResizeRedirectMask, client) == 1)
+ {
+ /* if event is delivered, leave the actual size alone. */
+ w = pWin->drawable.width;
+ h = pWin->drawable.height;
+ size_change = FALSE;
+ }
+ }
+ if (!size_change)
+ {
+ if (mask & (CWX | CWY))
+ action = MOVE_WIN;
+ else if (mask & (CWStackMode | CWBorderWidth))
+ action = RESTACK_WIN;
+ else /* really nothing to do */
+ return(Success) ;
+ }
+ }
+
+ if (action == RESIZE_WIN)
+ /* we've already checked whether there's really a size change */
+ goto ActuallyDoSomething;
+ if ((mask & CWX) && (x != beforeX))
+ goto ActuallyDoSomething;
+ if ((mask & CWY) && (y != beforeY))
+ goto ActuallyDoSomething;
+ if ((mask & CWBorderWidth) && (bw != wBorderWidth (pWin)))
+ goto ActuallyDoSomething;
+ if (mask & CWStackMode)
+ {
+#ifndef ROOTLESS
+ /* See above for why we always reorder in rootless mode. */
+ if (pWin->nextSib != pSib)
+#endif
+ goto ActuallyDoSomething;
+ }
+ return(Success);
+
+ActuallyDoSomething:
+ if (SubStrSend(pWin, pParent))
+ {
+ event.u.u.type = ConfigureNotify;
+ event.u.configureNotify.window = pWin->drawable.id;
+ if (pSib)
+ event.u.configureNotify.aboveSibling = pSib->drawable.id;
+ else
+ event.u.configureNotify.aboveSibling = None;
+ event.u.configureNotify.x = x;
+ event.u.configureNotify.y = y;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
+ event.u.configureNotify.x += panoramiXdataPtr[0].x;
+ event.u.configureNotify.y += panoramiXdataPtr[0].y;
+ }
+#endif
+ event.u.configureNotify.width = w;
+ event.u.configureNotify.height = h;
+ event.u.configureNotify.borderWidth = bw;
+ event.u.configureNotify.override = pWin->overrideRedirect;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ }
+ if (mask & CWBorderWidth)
+ {
+ if (action == RESTACK_WIN)
+ {
+ action = MOVE_WIN;
+ pWin->borderWidth = bw;
+ }
+ else if ((action == MOVE_WIN) &&
+ (beforeX + wBorderWidth (pWin) == x + (int)bw) &&
+ (beforeY + wBorderWidth (pWin) == y + (int)bw))
+ {
+ action = REBORDER_WIN;
+ (*pWin->drawable.pScreen->ChangeBorderWidth)(pWin, bw);
+ }
+ else
+ pWin->borderWidth = bw;
+ }
+ if (action == MOVE_WIN)
+ (*pWin->drawable.pScreen->MoveWindow)(pWin, x, y, pSib,
+ (mask & CWBorderWidth) ? VTOther : VTMove);
+ else if (action == RESIZE_WIN)
+ (*pWin->drawable.pScreen->ResizeWindow)(pWin, x, y, w, h, pSib);
+ else if (mask & CWStackMode)
+ ReflectStackChange(pWin, pSib, VTOther);
+
+ if (action != RESTACK_WIN)
+ CheckCursorConfinement(pWin);
+ return(Success);
+#undef RESTACK_WIN
+#undef MOVE_WIN
+#undef RESIZE_WIN
+#undef REBORDER_WIN
+}
+
+
+/******
+ *
+ * CirculateWindow
+ * For RaiseLowest, raises the lowest mapped child (if any) that is
+ * obscured by another child to the top of the stack. For LowerHighest,
+ * lowers the highest mapped child (if any) that is obscuring another
+ * child to the bottom of the stack. Exposure processing is performed
+ *
+ ******/
+
+int
+CirculateWindow(WindowPtr pParent, int direction, ClientPtr client)
+{
+ register WindowPtr pWin, pHead, pFirst;
+ xEvent event;
+ BoxRec box;
+
+ pHead = RealChildHead(pParent);
+ pFirst = pHead ? pHead->nextSib : pParent->firstChild;
+ if (direction == RaiseLowest)
+ {
+ for (pWin = pParent->lastChild;
+ (pWin != pHead) &&
+ !(pWin->mapped &&
+ AnyWindowOverlapsMe(pWin, pHead, WindowExtents(pWin, &box)));
+ pWin = pWin->prevSib) ;
+ if (pWin == pHead)
+ return Success;
+ }
+ else
+ {
+ for (pWin = pFirst;
+ pWin &&
+ !(pWin->mapped &&
+ IOverlapAnyWindow(pWin, WindowExtents(pWin, &box)));
+ pWin = pWin->nextSib) ;
+ if (!pWin)
+ return Success;
+ }
+
+ event.u.circulate.window = pWin->drawable.id;
+ event.u.circulate.parent = pParent->drawable.id;
+ event.u.circulate.event = pParent->drawable.id;
+ if (direction == RaiseLowest)
+ event.u.circulate.place = PlaceOnTop;
+ else
+ event.u.circulate.place = PlaceOnBottom;
+
+ if (RedirectSend(pParent))
+ {
+ event.u.u.type = CirculateRequest;
+ if (MaybeDeliverEventsToClient(pParent, &event, 1,
+ SubstructureRedirectMask, client) == 1)
+ return(Success);
+ }
+
+ event.u.u.type = CirculateNotify;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ ReflectStackChange(pWin,
+ (direction == RaiseLowest) ? pFirst : NullWindow,
+ VTStack);
+
+ return(Success);
+}
+
+static int
+CompareWIDs(
+ WindowPtr pWin,
+ pointer value) /* must conform to VisitWindowProcPtr */
+{
+ Window *wid = (Window *)value;
+
+ if (pWin->drawable.id == *wid)
+ return(WT_STOPWALKING);
+ else
+ return(WT_WALKCHILDREN);
+}
+
+/*****
+ * ReparentWindow
+ *****/
+
+int
+ReparentWindow(register WindowPtr pWin, register WindowPtr pParent,
+ int x, int y, ClientPtr client)
+{
+ WindowPtr pPrev, pPriorParent;
+ Bool WasMapped = (Bool)(pWin->mapped);
+ xEvent event;
+ int bw = wBorderWidth (pWin);
+ register ScreenPtr pScreen;
+
+ pScreen = pWin->drawable.pScreen;
+ if (TraverseTree(pWin, CompareWIDs, (pointer)&pParent->drawable.id) == WT_STOPWALKING)
+ return(BadMatch);
+ if (!MakeWindowOptional(pWin))
+ return(BadAlloc);
+
+ if (WasMapped)
+ UnmapWindow(pWin, FALSE);
+
+ event.u.u.type = ReparentNotify;
+ event.u.reparent.window = pWin->drawable.id;
+ event.u.reparent.parent = pParent->drawable.id;
+ event.u.reparent.x = x;
+ event.u.reparent.y = y;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && !pParent->parent) {
+ event.u.reparent.x += panoramiXdataPtr[0].x;
+ event.u.reparent.y += panoramiXdataPtr[0].y;
+ }
+#endif
+ event.u.reparent.override = pWin->overrideRedirect;
+ DeliverEvents(pWin, &event, 1, pParent);
+
+ /* take out of sibling chain */
+
+ pPriorParent = pPrev = pWin->parent;
+ if (pPrev->firstChild == pWin)
+ pPrev->firstChild = pWin->nextSib;
+ if (pPrev->lastChild == pWin)
+ pPrev->lastChild = pWin->prevSib;
+
+ if (pWin->nextSib)
+ pWin->nextSib->prevSib = pWin->prevSib;
+ if (pWin->prevSib)
+ pWin->prevSib->nextSib = pWin->nextSib;
+
+ /* insert at begining of pParent */
+ pWin->parent = pParent;
+ pPrev = RealChildHead(pParent);
+ if (pPrev)
+ {
+ pWin->nextSib = pPrev->nextSib;
+ if (pPrev->nextSib)
+ pPrev->nextSib->prevSib = pWin;
+ else
+ pParent->lastChild = pWin;
+ pPrev->nextSib = pWin;
+ pWin->prevSib = pPrev;
+ }
+ else
+ {
+ pWin->nextSib = pParent->firstChild;
+ pWin->prevSib = NullWindow;
+ if (pParent->firstChild)
+ pParent->firstChild->prevSib = pWin;
+ else
+ pParent->lastChild = pWin;
+ pParent->firstChild = pWin;
+ }
+
+ pWin->origin.x = x + bw;
+ pWin->origin.y = y + bw;
+ pWin->drawable.x = x + bw + pParent->drawable.x;
+ pWin->drawable.y = y + bw + pParent->drawable.y;
+
+ /* clip to parent */
+ SetWinSize (pWin);
+ SetBorderSize (pWin);
+
+ if (pScreen->ReparentWindow)
+ (*pScreen->ReparentWindow)(pWin, pPriorParent);
+ (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
+ ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
+
+ CheckWindowOptionalNeed(pWin);
+
+ if (WasMapped)
+ MapWindow(pWin, client);
+ RecalculateDeliverableEvents(pWin);
+ return(Success);
+}
+
+static void
+RealizeTree(WindowPtr pWin)
+{
+ register WindowPtr pChild;
+ RealizeWindowProcPtr Realize;
+
+ Realize = pWin->drawable.pScreen->RealizeWindow;
+ pChild = pWin;
+ while (1)
+ {
+ if (pChild->mapped)
+ {
+ pChild->realized = TRUE;
+#ifdef DO_SAVE_UNDERS
+ if (pChild->saveUnder)
+ deltaSaveUndersViewable++;
+#endif
+ pChild->viewable = (pChild->drawable.class == InputOutput);
+ (* Realize)(pChild);
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ return;
+ pChild = pChild->nextSib;
+ }
+}
+
+/*****
+ * MapWindow
+ * If some other client has selected SubStructureReDirect on the parent
+ * and override-redirect is xFalse, then a MapRequest event is generated,
+ * but the window remains unmapped. Otherwise, the window is mapped and a
+ * MapNotify event is generated.
+ *****/
+
+int
+MapWindow(register WindowPtr pWin, ClientPtr client)
+{
+ register ScreenPtr pScreen;
+
+ register WindowPtr pParent;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ if (pWin->mapped)
+ return(Success);
+
+#ifdef XCSECURITY
+ /* don't let an untrusted client map a child-of-trusted-window, InputOnly
+ * window; too easy to steal device input
+ */
+ if ( (client->trustLevel != XSecurityClientTrusted) &&
+ (pWin->drawable.class == InputOnly) &&
+ (wClient(pWin->parent)->trustLevel == XSecurityClientTrusted) )
+ return Success;
+#endif
+
+ pScreen = pWin->drawable.pScreen;
+ if ( (pParent = pWin->parent) )
+ {
+ xEvent event;
+ Bool anyMarked;
+#ifdef XAPPGROUP
+ ClientPtr win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+ ClientPtr ag_leader = XagLeader (win_owner);
+#endif
+
+ if ((!pWin->overrideRedirect) &&
+ (RedirectSend(pParent)
+#ifdef XAPPGROUP
+ || (win_owner->appgroup && ag_leader &&
+ XagIsControlledRoot (client, pParent))
+#endif
+ ))
+ {
+ event.u.u.type = MapRequest;
+ event.u.mapRequest.window = pWin->drawable.id;
+#ifdef XAPPGROUP
+ /* make sure if the ag_leader maps the window it goes to the wm */
+ if (ag_leader && ag_leader != client &&
+ XagIsControlledRoot (client, pParent)) {
+ event.u.mapRequest.parent = XagId (win_owner);
+ (void) TryClientEvents (ag_leader, &event, 1,
+ NoEventMask, NoEventMask, NullGrab);
+ return Success;
+ }
+#endif
+ event.u.mapRequest.parent = pParent->drawable.id;
+
+ if (MaybeDeliverEventsToClient(pParent, &event, 1,
+ SubstructureRedirectMask, client) == 1)
+ return(Success);
+ }
+
+ pWin->mapped = TRUE;
+ if (SubStrSend(pWin, pParent))
+ {
+ event.u.u.type = MapNotify;
+ event.u.mapNotify.window = pWin->drawable.id;
+ event.u.mapNotify.override = pWin->overrideRedirect;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ }
+
+ if (!pParent->realized)
+ return(Success);
+ RealizeTree(pWin);
+ if (pWin->viewable)
+ {
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ &pLayerWin);
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib);
+ }
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked)
+ {
+ (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
+ }
+ WindowsRestructured ();
+ }
+ else
+ {
+ RegionRec temp;
+
+ pWin->mapped = TRUE;
+ pWin->realized = TRUE; /* for roots */
+ pWin->viewable = pWin->drawable.class == InputOutput;
+ /* We SHOULD check for an error value here XXX */
+ (*pScreen->RealizeWindow)(pWin);
+ if (pScreen->ClipNotify)
+ (*pScreen->ClipNotify) (pWin, 0, 0);
+ if (pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(NullWindow, pWin, VTMap);
+ REGION_NULL(pScreen, &temp);
+ REGION_COPY(pScreen, &temp, &pWin->clipList);
+ (*pScreen->WindowExposures) (pWin, &temp, NullRegion);
+ REGION_UNINIT(pScreen, &temp);
+ }
+
+ return(Success);
+}
+
+
+/*****
+ * MapSubwindows
+ * Performs a MapWindow all unmapped children of the window, in top
+ * to bottom stacking order.
+ *****/
+
+void
+MapSubwindows(register WindowPtr pParent, ClientPtr client)
+{
+ register WindowPtr pWin;
+ WindowPtr pFirstMapped = NullWindow;
+#ifdef DO_SAVE_UNDERS
+ WindowPtr pFirstSaveUndered = NullWindow;
+#endif
+ register ScreenPtr pScreen;
+ register Mask parentRedirect;
+ register Mask parentNotify;
+ xEvent event;
+ Bool anyMarked;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ pScreen = pParent->drawable.pScreen;
+ parentRedirect = RedirectSend(pParent);
+ parentNotify = SubSend(pParent);
+ anyMarked = FALSE;
+ for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib)
+ {
+ if (!pWin->mapped)
+ {
+ if (parentRedirect && !pWin->overrideRedirect)
+ {
+ event.u.u.type = MapRequest;
+ event.u.mapRequest.window = pWin->drawable.id;
+ event.u.mapRequest.parent = pParent->drawable.id;
+
+ if (MaybeDeliverEventsToClient(pParent, &event, 1,
+ SubstructureRedirectMask, client) == 1)
+ continue;
+ }
+
+ pWin->mapped = TRUE;
+ if (parentNotify || StrSend(pWin))
+ {
+ event.u.u.type = MapNotify;
+ event.u.mapNotify.window = pWin->drawable.id;
+ event.u.mapNotify.override = pWin->overrideRedirect;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ }
+
+ if (!pFirstMapped)
+ pFirstMapped = pWin;
+ if (pParent->realized)
+ {
+ RealizeTree(pWin);
+ if (pWin->viewable)
+ {
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ (WindowPtr *)NULL);
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = TRUE;
+ }
+#endif /* DO_SAVE_UNDERS */
+ }
+ }
+ }
+ }
+
+ if (pFirstMapped)
+ {
+ pLayerWin = (*pScreen->GetLayerWindow)(pParent);
+ if (pLayerWin->parent != pParent) {
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pLayerWin,
+ pLayerWin,
+ (WindowPtr *)NULL);
+ pFirstMapped = pLayerWin;
+ }
+ if (anyMarked)
+ {
+#ifdef DO_SAVE_UNDERS
+ if (pLayerWin->parent != pParent)
+ {
+ if (dosave || (DO_SAVE_UNDERS(pLayerWin)))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin,
+ pLayerWin);
+ }
+ }
+ else if (dosave)
+ {
+ dosave = FALSE;
+ for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib)
+ {
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave |= (*pScreen->ChangeSaveUnder)(pWin,
+ pWin->nextSib);
+ if (dosave && !pFirstSaveUndered)
+ pFirstSaveUndered = pWin;
+ }
+ }
+ }
+#endif /* DO_SAVE_UNDERS */
+ (*pScreen->ValidateTree)(pLayerWin->parent, pFirstMapped, VTMap);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin,
+ pFirstSaveUndered->nextSib);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstMapped,
+ VTMap);
+ WindowsRestructured ();
+ }
+}
+
+static void
+UnrealizeTree(
+ WindowPtr pWin,
+ Bool fromConfigure)
+{
+ register WindowPtr pChild;
+ UnrealizeWindowProcPtr Unrealize;
+ MarkUnrealizedWindowProcPtr MarkUnrealizedWindow;
+
+ Unrealize = pWin->drawable.pScreen->UnrealizeWindow;
+ MarkUnrealizedWindow = pWin->drawable.pScreen->MarkUnrealizedWindow;
+ pChild = pWin;
+ while (1)
+ {
+ if (pChild->realized)
+ {
+ pChild->realized = FALSE;
+ pChild->visibility = VisibilityNotViewable;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && !pChild->drawable.pScreen->myNum) {
+ PanoramiXRes *win;
+ win = (PanoramiXRes*)LookupIDByType(pChild->drawable.id,
+ XRT_WINDOW);
+ if(win)
+ win->u.win.visibility = VisibilityNotViewable;
+ }
+#endif
+ (* Unrealize)(pChild);
+ DeleteWindowFromAnyEvents(pChild, FALSE);
+ if (pChild->viewable)
+ {
+#ifdef DO_SAVE_UNDERS
+ if (pChild->saveUnder)
+ deltaSaveUndersViewable--;
+#endif
+ pChild->viewable = FALSE;
+ if (pChild->backStorage)
+ (*pChild->drawable.pScreen->SaveDoomedAreas)(
+ pChild, &pChild->clipList, 0, 0);
+ (* MarkUnrealizedWindow)(pChild, pWin, fromConfigure);
+ pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ }
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ return;
+ pChild = pChild->nextSib;
+ }
+}
+
+/*****
+ * UnmapWindow
+ * If the window is already unmapped, this request has no effect.
+ * Otherwise, the window is unmapped and an UnMapNotify event is
+ * generated. Cannot unmap a root window.
+ *****/
+
+int
+UnmapWindow(register WindowPtr pWin, Bool fromConfigure)
+{
+ register WindowPtr pParent;
+ xEvent event;
+ Bool wasRealized = (Bool)pWin->realized;
+ Bool wasViewable = (Bool)pWin->viewable;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ WindowPtr pLayerWin = pWin;
+
+ if ((!pWin->mapped) || (!(pParent = pWin->parent)))
+ return(Success);
+ if (SubStrSend(pWin, pParent))
+ {
+ event.u.u.type = UnmapNotify;
+ event.u.unmapNotify.window = pWin->drawable.id;
+ event.u.unmapNotify.fromConfigure = fromConfigure;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ }
+ if (wasViewable && !fromConfigure)
+ {
+ pWin->valdata = UnmapValData;
+ (*pScreen->MarkOverlappedWindows)(pWin, pWin->nextSib, &pLayerWin);
+ (*pScreen->MarkWindow)(pLayerWin->parent);
+ }
+ pWin->mapped = FALSE;
+ if (wasRealized)
+ UnrealizeTree(pWin, fromConfigure);
+ if (wasViewable)
+ {
+ if (!fromConfigure)
+ {
+ (*pScreen->ValidateTree)(pLayerWin->parent, pWin, VTUnmap);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ if ( (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib) )
+ {
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+ }
+ }
+ pWin->DIXsaveUnder = FALSE;
+#endif /* DO_SAVE_UNDERS */
+ if (!fromConfigure && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pWin, VTUnmap);
+ }
+ if (wasRealized && !fromConfigure)
+ WindowsRestructured ();
+ return(Success);
+}
+
+/*****
+ * UnmapSubwindows
+ * Performs an UnmapWindow request with the specified mode on all mapped
+ * children of the window, in bottom to top stacking order.
+ *****/
+
+void
+UnmapSubwindows(register WindowPtr pWin)
+{
+ register WindowPtr pChild, pHead;
+ xEvent event;
+ Bool wasRealized = (Bool)pWin->realized;
+ Bool wasViewable = (Bool)pWin->viewable;
+ Bool anyMarked = FALSE;
+ Mask parentNotify;
+ WindowPtr pLayerWin = NULL;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ if (!pWin->firstChild)
+ return;
+ parentNotify = SubSend(pWin);
+ pHead = RealChildHead(pWin);
+
+ if (wasViewable)
+ pLayerWin = (*pScreen->GetLayerWindow)(pWin);
+
+ for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+ {
+ if (pChild->mapped)
+ {
+ if (parentNotify || StrSend(pChild))
+ {
+ event.u.u.type = UnmapNotify;
+ event.u.unmapNotify.window = pChild->drawable.id;
+ event.u.unmapNotify.fromConfigure = xFalse;
+ DeliverEvents(pChild, &event, 1, NullWindow);
+ }
+ if (pChild->viewable)
+ {
+ pChild->valdata = UnmapValData;
+ anyMarked = TRUE;
+ }
+ pChild->mapped = FALSE;
+ if (pChild->realized)
+ UnrealizeTree(pChild, FALSE);
+ if (wasViewable)
+ {
+#ifdef DO_SAVE_UNDERS
+ pChild->DIXsaveUnder = FALSE;
+#endif /* DO_SAVE_UNDERS */
+ if (pChild->backStorage)
+ (*pScreen->SaveDoomedAreas)(
+ pChild, &pChild->clipList, 0, 0);
+ }
+ }
+ }
+ if (wasViewable)
+ {
+ if (anyMarked)
+ {
+ if (pLayerWin->parent == pWin)
+ (*pScreen->MarkWindow)(pWin);
+ else
+ {
+ WindowPtr ptmp;
+ (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
+ (WindowPtr *)NULL);
+ (*pScreen->MarkWindow)(pLayerWin->parent);
+
+ /* Windows between pWin and pLayerWin may not have been marked */
+ ptmp = pWin;
+
+ while (ptmp != pLayerWin->parent)
+ {
+ (*pScreen->MarkWindow)(ptmp);
+ ptmp = ptmp->parent;
+ }
+ pHead = pWin->firstChild;
+ }
+ (*pScreen->ValidateTree)(pLayerWin->parent, pHead, VTUnmap);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ if ( (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin))
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
+ }
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pHead, VTUnmap);
+ }
+ if (wasRealized)
+ WindowsRestructured ();
+}
+
+
+void
+HandleSaveSet(register ClientPtr client)
+{
+ register WindowPtr pParent, pWin;
+ register int j;
+
+ for (j=0; j<client->numSaved; j++)
+ {
+ pWin = SaveSetWindow(client->saveSet[j]);
+#ifdef XFIXES
+ if (SaveSetToRoot(client->saveSet[j]))
+ pParent = WindowTable[pWin->drawable.pScreen->myNum];
+ else
+#endif
+ {
+ pParent = pWin->parent;
+ while (pParent && (wClient (pParent) == client))
+ pParent = pParent->parent;
+ }
+ if (pParent)
+ {
+ if (pParent != pWin->parent)
+ {
+ ReparentWindow(pWin, pParent,
+ pWin->drawable.x - wBorderWidth (pWin) - pParent->drawable.x,
+ pWin->drawable.y - wBorderWidth (pWin) - pParent->drawable.y,
+ client);
+ if(!pWin->realized && pWin->mapped)
+ pWin->mapped = FALSE;
+ }
+#ifdef XFIXES
+ if (SaveSetRemap (client->saveSet[j]))
+#endif
+ MapWindow(pWin, client);
+ }
+ }
+ xfree(client->saveSet);
+ client->numSaved = 0;
+ client->saveSet = (SaveSetElt *)NULL;
+}
+
+/**
+ *
+ * \param x,y in root
+ * \param box "return" value
+ */
+Bool
+VisibleBoundingBoxFromPoint(register WindowPtr pWin, int x, int y, BoxPtr box)
+{
+ if (!pWin->realized)
+ return (FALSE);
+ if (POINT_IN_REGION(pWin->drawable.pScreen, &pWin->clipList, x, y, box))
+ return(TRUE);
+ return(FALSE);
+}
+
+/**
+ *
+ * \param x,y in root
+ */
+Bool
+PointInWindowIsVisible(register WindowPtr pWin, int x, int y)
+{
+ BoxRec box;
+
+ if (!pWin->realized)
+ return (FALSE);
+ if (POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderClip,
+ x, y, &box)
+ && (!wInputShape(pWin) ||
+ POINT_IN_REGION(pWin->drawable.pScreen,
+ wInputShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box)))
+ return(TRUE);
+ return(FALSE);
+}
+
+
+RegionPtr
+NotClippedByChildren(register WindowPtr pWin)
+{
+ register ScreenPtr pScreen;
+ RegionPtr pReg;
+
+ pScreen = pWin->drawable.pScreen;
+ pReg = REGION_CREATE(pScreen, NullBox, 1);
+ if (pWin->parent ||
+ screenIsSaved != SCREEN_SAVER_ON ||
+ !HasSaverWindow (pWin->drawable.pScreen->myNum))
+ {
+ REGION_INTERSECT(pScreen, pReg, &pWin->borderClip, &pWin->winSize);
+ }
+ return(pReg);
+}
+
+void
+SendVisibilityNotify(WindowPtr pWin)
+{
+ xEvent event;
+#ifndef NO_XINERAMA_PORT
+ unsigned int visibility = pWin->visibility;
+#endif
+#ifdef PANORAMIX
+ /* This is not quite correct yet, but it's close */
+ if(!noPanoramiXExtension) {
+ PanoramiXRes *win;
+ WindowPtr pWin2;
+ int i, Scrnum;
+
+ Scrnum = pWin->drawable.pScreen->myNum;
+
+ win = PanoramiXFindIDByScrnum(XRT_WINDOW, pWin->drawable.id, Scrnum);
+
+ if(!win || (win->u.win.visibility == visibility))
+ return;
+
+ switch(visibility) {
+ case VisibilityUnobscured:
+ for(i = 0; i < PanoramiXNumScreens; i++) {
+ if(i == Scrnum) continue;
+
+ pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW);
+
+ if (pWin2) {
+ if(pWin2->visibility == VisibilityPartiallyObscured)
+ return;
+
+ if(!i) pWin = pWin2;
+ }
+ }
+ break;
+ case VisibilityPartiallyObscured:
+ if(Scrnum) {
+ pWin2 = (WindowPtr)LookupIDByType(win->info[0].id, RT_WINDOW);
+ if (pWin2) pWin = pWin2;
+ }
+ break;
+ case VisibilityFullyObscured:
+ for(i = 0; i < PanoramiXNumScreens; i++) {
+ if(i == Scrnum) continue;
+
+ pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW);
+
+ if (pWin2) {
+ if(pWin2->visibility != VisibilityFullyObscured)
+ return;
+
+ if(!i) pWin = pWin2;
+ }
+ }
+ break;
+ }
+
+ win->u.win.visibility = visibility;
+ }
+#endif
+
+ event.u.u.type = VisibilityNotify;
+ event.u.visibility.window = pWin->drawable.id;
+ event.u.visibility.state = visibility;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+}
+
+
+#define RANDOM_WIDTH 32
+
+#ifndef NOLOGOHACK
+static void DrawLogo(
+ WindowPtr pWin
+);
+#endif
+
+void
+SaveScreens(int on, int mode)
+{
+ int i;
+ int what;
+ int type;
+
+ if (on == SCREEN_SAVER_FORCER)
+ {
+ UpdateCurrentTimeIf();
+ lastDeviceEventTime = currentTime;
+ if (mode == ScreenSaverReset)
+ what = SCREEN_SAVER_OFF;
+ else
+ what = SCREEN_SAVER_ON;
+ type = what;
+ }
+ else
+ {
+ what = on;
+ type = what;
+ if (what == screenIsSaved)
+ type = SCREEN_SAVER_CYCLE;
+ }
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ if (on == SCREEN_SAVER_FORCER)
+ (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i], on);
+ if (savedScreenInfo[i].ExternalScreenSaver)
+ {
+ if ((*savedScreenInfo[i].ExternalScreenSaver)
+ (screenInfo.screens[i], type, on == SCREEN_SAVER_FORCER))
+ continue;
+ }
+ if (type == screenIsSaved)
+ continue;
+ switch (type) {
+ case SCREEN_SAVER_OFF:
+ if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
+ {
+ (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
+ what);
+ }
+ else if (HasSaverWindow (i))
+ {
+ savedScreenInfo[i].pWindow = NullWindow;
+ FreeResource(savedScreenInfo[i].wid, RT_NONE);
+ }
+ break;
+ case SCREEN_SAVER_CYCLE:
+ if (savedScreenInfo[i].blanked == SCREEN_IS_TILED)
+ {
+ WindowPtr pWin = savedScreenInfo[i].pWindow;
+ /* make it look like screen saver is off, so that
+ * NotClippedByChildren will compute a clip list
+ * for the root window, so miPaintWindow works
+ */
+ screenIsSaved = SCREEN_SAVER_OFF;
+#ifndef NOLOGOHACK
+ if (logoScreenSaver)
+ (*pWin->drawable.pScreen->ClearToBackground)(pWin, 0, 0, 0, 0, FALSE);
+#endif
+ (*pWin->drawable.pScreen->MoveWindow)(pWin,
+ (short)(-(rand() % RANDOM_WIDTH)),
+ (short)(-(rand() % RANDOM_WIDTH)),
+ pWin->nextSib, VTMove);
+#ifndef NOLOGOHACK
+ if (logoScreenSaver)
+ DrawLogo(pWin);
+#endif
+ screenIsSaved = SCREEN_SAVER_ON;
+ }
+ /*
+ * Call the DDX saver in case it wants to do something
+ * at cycle time
+ */
+ else if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
+ {
+ (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
+ type);
+ }
+ break;
+ case SCREEN_SAVER_ON:
+ if (ScreenSaverBlanking != DontPreferBlanking)
+ {
+ if ((* screenInfo.screens[i]->SaveScreen)
+ (screenInfo.screens[i], what))
+ {
+ savedScreenInfo[i].blanked = SCREEN_IS_BLANKED;
+ continue;
+ }
+ if ((ScreenSaverAllowExposures != DontAllowExposures) &&
+ TileScreenSaver(i, SCREEN_IS_BLACK))
+ {
+ savedScreenInfo[i].blanked = SCREEN_IS_BLACK;
+ continue;
+ }
+ }
+ if ((ScreenSaverAllowExposures != DontAllowExposures) &&
+ TileScreenSaver(i, SCREEN_IS_TILED))
+ {
+ savedScreenInfo[i].blanked = SCREEN_IS_TILED;
+ }
+ else
+ savedScreenInfo[i].blanked = SCREEN_ISNT_SAVED;
+ break;
+ }
+ }
+ screenIsSaved = what;
+ if (mode == ScreenSaverReset)
+ SetScreenSaverTimer();
+}
+
+static Bool
+TileScreenSaver(int i, int kind)
+{
+ int j;
+ int result;
+ XID attributes[3];
+ Mask mask;
+ WindowPtr pWin;
+ CursorMetricRec cm;
+ unsigned char *srcbits, *mskbits;
+ CursorPtr cursor;
+ XID cursorID = 0;
+ int attri;
+
+ mask = 0;
+ attri = 0;
+ switch (kind) {
+ case SCREEN_IS_TILED:
+ switch (WindowTable[i]->backgroundState) {
+ case BackgroundPixel:
+ attributes[attri++] = WindowTable[i]->background.pixel;
+ mask |= CWBackPixel;
+ break;
+ case BackgroundPixmap:
+ attributes[attri++] = None;
+ mask |= CWBackPixmap;
+ break;
+ default:
+ break;
+ }
+ break;
+ case SCREEN_IS_BLACK:
+ attributes[attri++] = WindowTable[i]->drawable.pScreen->blackPixel;
+ mask |= CWBackPixel;
+ break;
+ }
+ mask |= CWOverrideRedirect;
+ attributes[attri++] = xTrue;
+
+ /*
+ * create a blank cursor
+ */
+
+ cm.width=16;
+ cm.height=16;
+ cm.xhot=8;
+ cm.yhot=8;
+ srcbits = (unsigned char *)xalloc( BitmapBytePad(32)*16);
+ mskbits = (unsigned char *)xalloc( BitmapBytePad(32)*16);
+ if (!srcbits || !mskbits)
+ {
+ xfree(srcbits);
+ xfree(mskbits);
+ cursor = 0;
+ }
+ else
+ {
+ for (j=0; j<BitmapBytePad(32)*16; j++)
+ srcbits[j] = mskbits[j] = 0x0;
+ cursor = AllocCursor(srcbits, mskbits, &cm, 0, 0, 0, 0, 0, 0);
+ if (cursor)
+ {
+ cursorID = FakeClientID(0);
+ if (AddResource (cursorID, RT_CURSOR, (pointer) cursor))
+ {
+ attributes[attri] = cursorID;
+ mask |= CWCursor;
+ }
+ else
+ cursor = 0;
+ }
+ else
+ {
+ xfree (srcbits);
+ xfree (mskbits);
+ }
+ }
+
+ pWin = savedScreenInfo[i].pWindow =
+ CreateWindow(savedScreenInfo[i].wid,
+ WindowTable[i],
+ -RANDOM_WIDTH, -RANDOM_WIDTH,
+ (unsigned short)screenInfo.screens[i]->width + RANDOM_WIDTH,
+ (unsigned short)screenInfo.screens[i]->height + RANDOM_WIDTH,
+ 0, InputOutput, mask, attributes, 0, serverClient,
+ wVisual (WindowTable[i]), &result);
+
+ if (cursor)
+ FreeResource (cursorID, RT_NONE);
+
+ if (!pWin)
+ return FALSE;
+
+ if (!AddResource(pWin->drawable.id, RT_WINDOW,
+ (pointer)savedScreenInfo[i].pWindow))
+ return FALSE;
+
+ if (mask & CWBackPixmap)
+ {
+ MakeRootTile (pWin);
+ (*pWin->drawable.pScreen->ChangeWindowAttributes)(pWin, CWBackPixmap);
+ }
+ MapWindow(pWin, serverClient);
+#ifndef NOLOGOHACK
+ if (kind == SCREEN_IS_TILED && logoScreenSaver)
+ DrawLogo(pWin);
+#endif
+ return TRUE;
+}
+
+/*
+ * FindWindowWithOptional
+ *
+ * search ancestors of the given window for an entry containing
+ * a WindowOpt structure. Assumptions: some parent will
+ * contain the structure.
+ */
+
+WindowPtr
+FindWindowWithOptional (register WindowPtr w)
+{
+ do
+ w = w->parent;
+ while (!w->optional);
+ return w;
+}
+
+/*
+ * CheckWindowOptionalNeed
+ *
+ * check each optional entry in the given window to see if
+ * the value is satisfied by the default rules. If so,
+ * release the optional record
+ */
+
+void
+CheckWindowOptionalNeed (register WindowPtr w)
+{
+ register WindowOptPtr optional;
+ register WindowOptPtr parentOptional;
+
+ if (!w->parent)
+ return;
+ optional = w->optional;
+ if (optional->dontPropagateMask != DontPropagateMasks[w->dontPropagate])
+ return;
+ if (optional->otherEventMasks != 0)
+ return;
+ if (optional->otherClients != NULL)
+ return;
+ if (optional->passiveGrabs != NULL)
+ return;
+ if (optional->userProps != NULL)
+ return;
+ if (optional->backingBitPlanes != ~0L)
+ return;
+ if (optional->backingPixel != 0)
+ return;
+#ifdef SHAPE
+ if (optional->boundingShape != NULL)
+ return;
+ if (optional->clipShape != NULL)
+ return;
+ if (optional->inputShape != NULL)
+ return;
+#endif
+#ifdef XINPUT
+ if (optional->inputMasks != NULL)
+ return;
+#endif
+ parentOptional = FindWindowWithOptional(w)->optional;
+ if (optional->visual != parentOptional->visual)
+ return;
+ if (optional->cursor != None &&
+ (optional->cursor != parentOptional->cursor ||
+ w->parent->cursorIsNone))
+ return;
+ if (optional->colormap != parentOptional->colormap)
+ return;
+ DisposeWindowOptional (w);
+}
+
+/*
+ * MakeWindowOptional
+ *
+ * create an optional record and initialize it with the default
+ * values.
+ */
+
+Bool
+MakeWindowOptional (register WindowPtr pWin)
+{
+ register WindowOptPtr optional;
+ register WindowOptPtr parentOptional;
+
+ if (pWin->optional)
+ return TRUE;
+ optional = (WindowOptPtr) xalloc (sizeof (WindowOptRec));
+ if (!optional)
+ return FALSE;
+ optional->dontPropagateMask = DontPropagateMasks[pWin->dontPropagate];
+ optional->otherEventMasks = 0;
+ optional->otherClients = NULL;
+ optional->passiveGrabs = NULL;
+ optional->userProps = NULL;
+ optional->backingBitPlanes = ~0L;
+ optional->backingPixel = 0;
+#ifdef SHAPE
+ optional->boundingShape = NULL;
+ optional->clipShape = NULL;
+ optional->inputShape = NULL;
+#endif
+#ifdef XINPUT
+ optional->inputMasks = NULL;
+#endif
+ parentOptional = FindWindowWithOptional(pWin)->optional;
+ optional->visual = parentOptional->visual;
+ if (!pWin->cursorIsNone)
+ {
+ optional->cursor = parentOptional->cursor;
+ optional->cursor->refcnt++;
+ }
+ else
+ {
+ optional->cursor = None;
+ }
+ optional->colormap = parentOptional->colormap;
+ pWin->optional = optional;
+ return TRUE;
+}
+
+void
+DisposeWindowOptional (register WindowPtr pWin)
+{
+ if (!pWin->optional)
+ return;
+ /*
+ * everything is peachy. Delete the optional record
+ * and clean up
+ */
+ /*
+ * TOG changed this code to:
+ *
+ * if (pWin->cursorIsNone == FALSE)
+ * FreeCursor (pWin->optional->cursor, (Cursor)0);
+ * pWin->cursorIsNone = TRUE;
+ *
+ * This is blatently wrong; windows without optionals can have
+ * two different cursor values, either None or sharing their
+ * parents cursor. This difference is controlled by the
+ * cursorIsNone value; when TRUE, the window has no cursor,
+ * when false, it shares its cursor with its parent; TOG
+ * made it impossible for a window to have a cursor without
+ * an optional record.
+ */
+ if (pWin->optional->cursor)
+ {
+ FreeCursor (pWin->optional->cursor, (Cursor)0);
+ pWin->cursorIsNone = FALSE;
+ }
+ else
+ pWin->cursorIsNone = TRUE;
+ xfree (pWin->optional);
+ pWin->optional = NULL;
+}
+
+#ifndef NOLOGOHACK
+static void
+DrawLogo(WindowPtr pWin)
+{
+ DrawablePtr pDraw;
+ ScreenPtr pScreen;
+ int x, y;
+ unsigned int width, height, size;
+ GC *pGC;
+ int thin, gap, d31;
+ DDXPointRec poly[4];
+ ChangeGCVal fore[2], back[2];
+ xrgb rgb[2];
+ BITS32 fmask, bmask;
+ ColormapPtr cmap;
+
+ pDraw = (DrawablePtr)pWin;
+ pScreen = pDraw->pScreen;
+ x = -pWin->origin.x;
+ y = -pWin->origin.y;
+ width = pScreen->width;
+ height = pScreen->height;
+ pGC = GetScratchGC(pScreen->rootDepth, pScreen);
+ if (!pGC)
+ return;
+
+ if ((rand() % 100) <= 17) /* make the probability for white fairly low */
+ fore[0].val = pScreen->whitePixel;
+ else
+ fore[0].val = pScreen->blackPixel;
+ if ((pWin->backgroundState == BackgroundPixel) &&
+ (cmap = (ColormapPtr)LookupIDByType(wColormap (pWin), RT_COLORMAP))) {
+ Pixel querypixels[2];
+
+ querypixels[0] = fore[0].val;
+ querypixels[1] = pWin->background.pixel;
+ QueryColors(cmap, 2, querypixels, rgb);
+ if ((rgb[0].red == rgb[1].red) &&
+ (rgb[0].green == rgb[1].green) &&
+ (rgb[0].blue == rgb[1].blue)) {
+ if (fore[0].val == pScreen->blackPixel)
+ fore[0].val = pScreen->whitePixel;
+ else
+ fore[0].val = pScreen->blackPixel;
+ }
+ }
+ fore[1].val = FillSolid;
+ fmask = GCForeground|GCFillStyle;
+ if (pWin->backgroundState == BackgroundPixel) {
+ back[0].val = pWin->background.pixel;
+ back[1].val = FillSolid;
+ bmask = GCForeground|GCFillStyle;
+ } else {
+ back[0].val = 0;
+ back[1].val = 0;
+ dixChangeGC(NullClient, pGC, GCTileStipXOrigin|GCTileStipYOrigin,
+ NULL, back);
+ back[0].val = FillTiled;
+ back[1].ptr = pWin->background.pixmap;
+ bmask = GCFillStyle|GCTile;
+ }
+
+ /* should be the same as the reference function XmuDrawLogo() */
+
+ size = width;
+ if (height < width)
+ size = height;
+ size = RANDOM_WIDTH + rand() % (size - RANDOM_WIDTH);
+ size &= ~1;
+ x += rand() % (width - size);
+ y += rand() % (height - size);
+
+/*
+ * Draw what will be the thin strokes.
+ *
+ * -----
+ * / /
+ * / /
+ * / /
+ * / /
+ * /____/
+ * d
+ *
+ * Point d is 9/44 (~1/5) of the way across.
+ */
+
+ thin = (size / 11);
+ if (thin < 1) thin = 1;
+ gap = (thin+3) / 4;
+ d31 = thin + thin + gap;
+ poly[0].x = x + size; poly[0].y = y;
+ poly[1].x = x + size-d31; poly[1].y = y;
+ poly[2].x = x + 0; poly[2].y = y + size;
+ poly[3].x = x + d31; poly[3].y = y + size;
+ dixChangeGC(NullClient, pGC, fmask, NULL, fore);
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase area not needed for lower thin stroke.
+ *
+ * ------
+ * / /
+ * / __ /
+ * / / /
+ * / / /
+ * /__/__/
+ */
+
+ poly[0].x = x + d31/2; poly[0].y = y + size;
+ poly[1].x = x + size / 2; poly[1].y = y + size/2;
+ poly[2].x = x + (size/2)+(d31-(d31/2)); poly[2].y = y + size/2;
+ poly[3].x = x + d31; poly[3].y = y + size;
+ dixChangeGC(NullClient, pGC, bmask, NULL, back);
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase area not needed for upper thin stroke.
+ *
+ * ------
+ * / / /
+ * /--/ /
+ * / /
+ * / /
+ * /_____/
+ */
+
+ poly[0].x = x + size - d31/2; poly[0].y = y;
+ poly[1].x = x + size / 2; poly[1].y = y + size/2;
+ poly[2].x = x + (size/2)-(d31-(d31/2)); poly[2].y = y + size/2;
+ poly[3].x = x + size - d31; poly[3].y = y;
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Draw thick stroke.
+ * Point b is 1/4 of the way across.
+ *
+ * b
+ * -----
+ * \ \
+ * \ \
+ * \ \
+ * \ \
+ * \____\
+ */
+
+ poly[0].x = x; poly[0].y = y;
+ poly[1].x = x + size/4; poly[1].y = y;
+ poly[2].x = x + size; poly[2].y = y + size;
+ poly[3].x = x + size - size/4; poly[3].y = y + size;
+ dixChangeGC(NullClient, pGC, fmask, NULL, fore);
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase to create gap.
+ *
+ * /
+ * /
+ * /
+ * /
+ * /
+ */
+
+ poly[0].x = x + size- thin; poly[0].y = y;
+ poly[1].x = x + size-( thin+gap); poly[1].y = y;
+ poly[2].x = x + thin; poly[2].y = y + size;
+ poly[3].x = x + thin + gap; poly[3].y = y + size;
+ dixChangeGC(NullClient, pGC, bmask, NULL, back);
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+ FreeScratchGC(pGC);
+}
+
+#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c
new file mode 100644
index 000000000..15fdd9ff3
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c
@@ -0,0 +1,2286 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/* $XdotOrg: xc/programs/Xserver/Xext/xvdisp.c,v 1.6 2005/07/03 08:53:36 daniels Exp $ */
+/***********************************************************
+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.
+
+******************************************************************/
+/* $XFree86: xc/programs/Xserver/Xext/xvdisp.c,v 1.27 2003/07/16 01:38:31 dawes Exp $ */
+
+/*
+** File:
+**
+** xvdisp.c --- Xv server extension dispatch module.
+**
+** Author:
+**
+** David Carver (Digital Workstation Engineering/Project Athena)
+**
+** Revisions:
+**
+** 11.06.91 Carver
+** - changed SetPortControl to SetPortAttribute
+** - changed GetPortControl to GetPortAttribute
+** - changed QueryBestSize
+**
+** 15.05.91 Carver
+** - version 2.0 upgrade
+**
+** 24.01.91 Carver
+** - version 1.4 upgrade
+**
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#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
+#define _XSHM_SERVER_
+#include <X11/extensions/shmstr.h>
+#endif
+
+#include "Trap.h"
+
+#undef TEST
+#undef DEBUG
+
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#endif
+
+#include "xvdisp.h"
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+
+unsigned long XvXRTPort;
+
+#ifdef MITSHM
+static int XineramaXvShmPutImage(ClientPtr);
+#endif
+static int XineramaXvPutImage(ClientPtr);
+static int XineramaXvPutVideo(ClientPtr);
+static int XineramaXvPutStill(ClientPtr);
+static int XineramaXvSetPortAttribute(ClientPtr);
+static int XineramaXvStopVideo(ClientPtr);
+#endif
+
+/* INTERNAL */
+
+static int ProcXvQueryExtension(ClientPtr);
+static int ProcXvQueryAdaptors(ClientPtr);
+static int ProcXvQueryEncodings(ClientPtr);
+static int ProcXvPutVideo(ClientPtr);
+static int ProcXvPutStill(ClientPtr);
+static int ProcXvGetVideo(ClientPtr);
+static int ProcXvGetStill(ClientPtr);
+static int ProcXvGrabPort(ClientPtr);
+static int ProcXvUngrabPort(ClientPtr);
+static int ProcXvSelectVideoNotify(ClientPtr);
+static int ProcXvSelectPortNotify(ClientPtr);
+static int ProcXvStopVideo(ClientPtr);
+static int ProcXvSetPortAttribute(ClientPtr);
+static int ProcXvGetPortAttribute(ClientPtr);
+static int ProcXvQueryBestSize(ClientPtr);
+static int ProcXvQueryPortAttributes(ClientPtr);
+static int ProcXvPutImage(ClientPtr);
+#ifdef MITSHM
+static int ProcXvShmPutImage(ClientPtr);
+#endif
+static int ProcXvQueryImageAttributes(ClientPtr);
+static int ProcXvListImageFormats(ClientPtr);
+
+static int SProcXvQueryExtension(ClientPtr);
+static int SProcXvQueryAdaptors(ClientPtr);
+static int SProcXvQueryEncodings(ClientPtr);
+static int SProcXvPutVideo(ClientPtr);
+static int SProcXvPutStill(ClientPtr);
+static int SProcXvGetVideo(ClientPtr);
+static int SProcXvGetStill(ClientPtr);
+static int SProcXvGrabPort(ClientPtr);
+static int SProcXvUngrabPort(ClientPtr);
+static int SProcXvSelectVideoNotify(ClientPtr);
+static int SProcXvSelectPortNotify(ClientPtr);
+static int SProcXvStopVideo(ClientPtr);
+static int SProcXvSetPortAttribute(ClientPtr);
+static int SProcXvGetPortAttribute(ClientPtr);
+static int SProcXvQueryBestSize(ClientPtr);
+static int SProcXvQueryPortAttributes(ClientPtr);
+static int SProcXvPutImage(ClientPtr);
+#ifdef MITSHM
+static int SProcXvShmPutImage(ClientPtr);
+#endif
+static int SProcXvQueryImageAttributes(ClientPtr);
+static int SProcXvListImageFormats(ClientPtr);
+
+static int SWriteQueryAdaptorsReply(ClientPtr, xvQueryAdaptorsReply *);
+static int SWriteQueryExtensionReply(ClientPtr, xvQueryExtensionReply *);
+static int SWriteQueryEncodingsReply(ClientPtr, xvQueryEncodingsReply *);
+static int SWriteAdaptorInfo(ClientPtr, xvAdaptorInfo *);
+static int SWriteEncodingInfo(ClientPtr, xvEncodingInfo *);
+static int SWriteFormat(ClientPtr, xvFormat *);
+static int SWriteAttributeInfo(ClientPtr, xvAttributeInfo *);
+static int SWriteGrabPortReply(ClientPtr, xvGrabPortReply *);
+static int SWriteGetPortAttributeReply(ClientPtr, xvGetPortAttributeReply *);
+static int SWriteQueryBestSizeReply(ClientPtr, xvQueryBestSizeReply *);
+static int SWriteQueryPortAttributesReply(
+ ClientPtr, xvQueryPortAttributesReply *);
+static int SWriteQueryImageAttributesReply(
+ ClientPtr, xvQueryImageAttributesReply*);
+static int SWriteListImageFormatsReply(ClientPtr, xvListImageFormatsReply*);
+static int SWriteImageFormatInfo(ClientPtr, xvImageFormatInfo*);
+
+#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
+
+/*
+** ProcXvDispatch
+**
+**
+**
+*/
+
+int
+ProcXvDispatch(ClientPtr client)
+{
+ int result;
+
+ REQUEST(xReq);
+
+ UpdateCurrentTime();
+
+ /*
+ * Report upstream that we are
+ * dispatching a XVideo operation.
+ */
+
+ nxagentXvTrap = 1;
+
+ #ifdef TEST
+ fprintf(stderr, "ProcXvDispatch: Going to dispatch XVideo operation [%d] for client [%d].\n",
+ stuff->data, client -> index);
+ #endif
+
+ switch (stuff->data)
+ {
+ case xv_QueryExtension: result = (ProcXvQueryExtension(client)); break;
+ case xv_QueryAdaptors: result = (ProcXvQueryAdaptors(client)); break;
+ case xv_QueryEncodings: result = (ProcXvQueryEncodings(client)); break;
+ case xv_PutVideo:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ result = (XineramaXvPutVideo(client)); break;
+ else
+#endif
+ result = (ProcXvPutVideo(client)); break;
+ case xv_PutStill:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ result = (XineramaXvPutStill(client)); break
+ else
+#endif
+ result = (ProcXvPutStill(client)); break;
+ case xv_GetVideo: result = (ProcXvGetVideo(client)); break;
+ case xv_GetStill: result = (ProcXvGetStill(client)); break;
+ case xv_GrabPort: result = (ProcXvGrabPort(client)); break;
+ case xv_UngrabPort: result = (ProcXvUngrabPort(client)); break;
+ case xv_SelectVideoNotify: result = (ProcXvSelectVideoNotify(client)); break;
+ case xv_SelectPortNotify: result = (ProcXvSelectPortNotify(client)); break;
+ case xv_StopVideo:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ result = (XineramaXvStopVideo(client)); break;
+ else
+#endif
+ result = (ProcXvStopVideo(client)); break;
+ case xv_SetPortAttribute:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ result = (XineramaXvSetPortAttribute(client)); break;
+ else
+#endif
+ result = (ProcXvSetPortAttribute(client)); break;
+ case xv_GetPortAttribute: result = (ProcXvGetPortAttribute(client)); break;
+ case xv_QueryBestSize: result = (ProcXvQueryBestSize(client)); break;
+ case xv_QueryPortAttributes: result = (ProcXvQueryPortAttributes(client)); break;
+ case xv_PutImage:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ result = (XineramaXvPutImage(client)); break;
+ else
+#endif
+ result = (ProcXvPutImage(client)); break;
+#ifdef MITSHM
+ case xv_ShmPutImage:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ result = (XineramaXvShmPutImage(client)); break;
+ else
+#endif
+ result = (ProcXvShmPutImage(client)); break;
+#endif
+ case xv_QueryImageAttributes: result = (ProcXvQueryImageAttributes(client)); break;
+ case xv_ListImageFormats: result = (ProcXvListImageFormats(client)); break;
+ default:
+ if (stuff->data < xvNumRequests)
+ {
+ SendErrorToClient(client, XvReqCode, stuff->data, 0,
+ BadImplementation);
+ result = (BadImplementation); break;
+ }
+ else
+ {
+ SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
+ result = (BadRequest); break;
+ }
+ }
+
+ nxagentXvTrap = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "ProcXvDispatch: Dispatched XVideo operation [%d] for client [%d].\n",
+ stuff->data, client -> index);
+ #endif
+
+ return result;
+}
+
+int
+SProcXvDispatch(ClientPtr client)
+{
+ int result;
+
+ REQUEST(xReq);
+
+ UpdateCurrentTime();
+
+ /*
+ * Report upstream that we are
+ * dispatching a XVideo operation.
+ */
+
+ nxagentXvTrap = 1;
+
+ #ifdef TEST
+ fprintf(stderr, "SProcXvDispatch: Going to dispatch XVideo operation [%d] for client [%d].\n",
+ stuff->data, client -> index);
+ #endif
+
+ switch (stuff->data)
+ {
+ case xv_QueryExtension: result = (SProcXvQueryExtension(client)); break;
+ case xv_QueryAdaptors: result = (SProcXvQueryAdaptors(client)); break;
+ case xv_QueryEncodings: result = (SProcXvQueryEncodings(client)); break;
+ case xv_PutVideo: result = (SProcXvPutVideo(client)); break;
+ case xv_PutStill: result = (SProcXvPutStill(client)); break;
+ case xv_GetVideo: result = (SProcXvGetVideo(client)); break;
+ case xv_GetStill: result = (SProcXvGetStill(client)); break;
+ case xv_GrabPort: result = (SProcXvGrabPort(client)); break;
+ case xv_UngrabPort: result = (SProcXvUngrabPort(client)); break;
+ case xv_SelectVideoNotify: result = (SProcXvSelectVideoNotify(client)); break;
+ case xv_SelectPortNotify: result = (SProcXvSelectPortNotify(client)); break;
+ case xv_StopVideo: result = (SProcXvStopVideo(client)); break;
+ case xv_SetPortAttribute: result = (SProcXvSetPortAttribute(client)); break;
+ case xv_GetPortAttribute: result = (SProcXvGetPortAttribute(client)); break;
+ case xv_QueryBestSize: result = (SProcXvQueryBestSize(client)); break;
+ case xv_QueryPortAttributes: result = (SProcXvQueryPortAttributes(client)); break;
+ case xv_PutImage: result = (SProcXvPutImage(client)); break;
+#ifdef MITSHM
+ case xv_ShmPutImage: result = (SProcXvShmPutImage(client)); break;
+#endif
+ case xv_QueryImageAttributes: result = (SProcXvQueryImageAttributes(client)); break;
+ case xv_ListImageFormats: result = (SProcXvListImageFormats(client)); break;
+ default:
+ if (stuff->data < xvNumRequests)
+ {
+ SendErrorToClient(client, XvReqCode, stuff->data, 0,
+ BadImplementation);
+ result = (BadImplementation); break;
+ }
+ else
+ {
+ SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
+ result = (BadRequest); break;
+ }
+ }
+
+ nxagentXvTrap = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "ProcXvDispatch: Dispatched XVideo operation [%d] for client [%d].\n",
+ stuff->data, client -> index);
+ #endif
+
+ return result;
+}
+
+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;
+ int na;
+ XvAdaptorPtr pa;
+ int nf;
+ XvFormatPtr pf;
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ XvScreenPtr pxvs;
+
+ REQUEST(xvQueryAdaptorsReq);
+ REQUEST_SIZE_MATCH(xvQueryAdaptorsReq);
+
+ if(!(pWin = (WindowPtr)LookupWindow(stuff->window, client) ))
+ {
+ client->errorValue = stuff->window;
+ return (BadWindow);
+ }
+
+ pScreen = pWin->drawable.pScreen;
+ pxvs = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr;
+
+ 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 += (strlen(pa->name) + 3) & ~3;
+ totalSize += pa->nFormats * sz_xvFormat;
+ pa++;
+ }
+
+ rep.length = totalSize >> 2;
+
+ _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 = strlen(pa->name);
+ ainfo.num_formats = pa->nFormats;
+
+ _WriteAdaptorInfo(client, &ainfo);
+
+ WriteToClient(client, ainfo.name_size, pa->name);
+
+ nf = pa->nFormats;
+ pf = pa->pFormats;
+ while (nf--)
+ {
+ format.depth = pf->depth;
+ format.visual = pf->visual;
+ _WriteFormat(client, &format);
+ pf++;
+ }
+
+ pa++;
+
+ }
+
+ return (client->noClientException);
+
+}
+
+static int
+ProcXvQueryEncodings(ClientPtr client)
+{
+ xvEncodingInfo einfo;
+ xvQueryEncodingsReply rep;
+ int totalSize;
+ XvPortPtr pPort;
+ int ne;
+ XvEncodingPtr pe;
+ int status;
+
+ REQUEST(xvQueryEncodingsReq);
+ REQUEST_SIZE_MATCH(xvQueryEncodingsReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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 += (strlen(pe->name) + 3) & ~3;
+ pe++;
+ }
+
+ rep.length = totalSize >> 2;
+
+ _WriteQueryEncodingsReply(client, &rep);
+
+ ne = pPort->pAdaptor->nEncodings;
+ pe = pPort->pAdaptor->pEncodings;
+ while (ne--)
+ {
+ einfo.encoding = pe->id;
+ einfo.name_size = 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, einfo.name_size, pe->name);
+ pe++;
+ }
+
+ return (client->noClientException);
+
+}
+
+static int
+ProcXvPutVideo(ClientPtr client)
+{
+ register DrawablePtr pDraw;
+ XvPortPtr pPort;
+ register GCPtr pGC;
+ int status;
+
+ REQUEST(xvPutVideoReq);
+ REQUEST_SIZE_MATCH(xvPutVideoReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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 = XVCALL(diMatchPort)(pPort, pDraw);
+ if (status != Success)
+ {
+ return status;
+ }
+
+ return XVCALL(diPutVideo)(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)
+{
+ register DrawablePtr pDraw;
+ XvPortPtr pPort;
+ register GCPtr pGC;
+ int status;
+
+ REQUEST(xvPutStillReq);
+ REQUEST_SIZE_MATCH(xvPutStillReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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 = XVCALL(diMatchPort)(pPort, pDraw);
+ if (status != Success)
+ {
+ return status;
+ }
+
+ return XVCALL(diPutStill)(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)
+{
+ register DrawablePtr pDraw;
+ XvPortPtr pPort;
+ register GCPtr pGC;
+ int status;
+
+ REQUEST(xvGetVideoReq);
+ REQUEST_SIZE_MATCH(xvGetVideoReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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 = XVCALL(diMatchPort)(pPort, pDraw);
+ if (status != Success)
+ {
+ return status;
+ }
+
+ return XVCALL(diGetVideo)(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)
+{
+ register DrawablePtr pDraw;
+ XvPortPtr pPort;
+ register GCPtr pGC;
+ int status;
+
+ REQUEST(xvGetStillReq);
+ REQUEST_SIZE_MATCH(xvGetStillReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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 = XVCALL(diMatchPort)(pPort, pDraw);
+ if (status != Success)
+ {
+ return status;
+ }
+
+ return XVCALL(diGetStill)(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)
+{
+ register DrawablePtr pDraw;
+ REQUEST(xvSelectVideoNotifyReq);
+ REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq);
+
+ if(!(pDraw = (DrawablePtr)LOOKUP_DRAWABLE(stuff->drawable, client) ))
+ {
+ client->errorValue = stuff->drawable;
+ return (BadWindow);
+ }
+
+ return XVCALL(diSelectVideoNotify)(client, pDraw, stuff->onoff);
+
+}
+
+static int
+ProcXvSelectPortNotify(ClientPtr client)
+{
+ int status;
+ XvPortPtr pPort;
+ REQUEST(xvSelectPortNotifyReq);
+ REQUEST_SIZE_MATCH(xvSelectPortNotifyReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ return XVCALL(diSelectPortNotify)(client, pPort, stuff->onoff);
+
+}
+
+static int
+ProcXvGrabPort(ClientPtr client)
+{
+ int result, status;
+ XvPortPtr pPort;
+ xvGrabPortReply rep;
+ REQUEST(xvGrabPortReq);
+ REQUEST_SIZE_MATCH(xvGrabPortReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ status = XVCALL(diGrabPort)(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);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ return XVCALL(diUngrabPort)(client, pPort, stuff->time);
+
+}
+
+
+static int
+ProcXvStopVideo(ClientPtr client)
+{
+ int status;
+ register DrawablePtr pDraw;
+ XvPortPtr pPort;
+ REQUEST(xvStopVideoReq);
+ REQUEST_SIZE_MATCH(xvStopVideoReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ if(!(pDraw = LOOKUP_DRAWABLE(stuff->drawable, client) ))
+ {
+ client->errorValue = stuff->drawable;
+ return (BadDrawable);
+ }
+
+ return XVCALL(diStopVideo)(client, pPort, pDraw);
+
+}
+
+static int
+ProcXvSetPortAttribute(ClientPtr client)
+{
+ int status;
+ XvPortPtr pPort;
+ REQUEST(xvSetPortAttributeReq);
+ REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ if (!ValidAtom(stuff->attribute))
+ {
+ client->errorValue = stuff->attribute;
+ return(BadAtom);
+ }
+
+ status = XVCALL(diSetPortAttribute)(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);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ if (!ValidAtom(stuff->attribute))
+ {
+ client->errorValue = stuff->attribute;
+ return(BadAtom);
+ }
+
+ status = XVCALL(diGetPortAttribute)(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);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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 < rep.num_attributes; i++, pAtt++)
+ {
+ rep.text_size += (strlen(pAtt->name) + 1 + 3) & ~3L;
+ }
+
+ rep.length = (rep.num_attributes * sz_xvAttributeInfo) + rep.text_size;
+ rep.length >>= 2;
+
+ _WriteQueryPortAttributesReply(client, &rep);
+
+ for(i = 0, pAtt = pPort->pAdaptor->pAttributes;
+ i < rep.num_attributes; 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 = (size + 3) & ~3L;
+
+ _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, pGC, client);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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 = XVCALL(diMatchPort)(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 = (size + 3) >> 2;
+
+ if((width < stuff->width) || (height < stuff->height))
+ return BadValue;
+
+ if(client->req_len < size)
+ return BadLength;
+
+ return XVCALL(diPutImage)(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 BadShmSegCode;
+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, pGC, client);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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 = XVCALL(diMatchPort)(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;
+
+ if(!(shmdesc = (ShmDescPtr)LookupIDByType(stuff->shmseg, ShmSegType)))
+ {
+ client->errorValue = stuff->shmseg;
+ return BadShmSegCode;
+ }
+
+ 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 = XVCALL(diPutImage)(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.sequenceNumber = client->sequence;
+ ev.minorEvent = xv_ShmPutImage;
+ ev.majorEvent = XvReqCode;
+ ev.shmseg = stuff->shmseg;
+ ev.offset = stuff->offset;
+ WriteEventsToClient(client, 1, (xEvent *) &ev);
+ }
+
+ return status;
+}
+#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;
+ REQUEST(xvQueryImageAttributesReq);
+
+ REQUEST_SIZE_MATCH(xvQueryImageAttributesReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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 = xalloc(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 = 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, rep.length);
+ WriteToClient(client, rep.length << 2, (char*)offsets);
+
+ xfree(offsets);
+
+ return Success;
+}
+
+static int
+ProcXvListImageFormats(ClientPtr client)
+{
+ XvPortPtr pPort;
+ XvImagePtr pImage;
+ int i;
+ xvListImageFormatsReply rep;
+ xvImageFormatInfo info;
+ REQUEST(xvListImageFormatsReq);
+
+ REQUEST_SIZE_MATCH(xvListImageFormatsReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.num_formats = pPort->pAdaptor->nImages;
+ rep.length = rep.num_formats * sz_xvImageFormatInfo >> 2;
+
+ _WriteListImageFormatsReply(client, &rep);
+
+ pImage = pPort->pAdaptor->pImages;
+
+ for(i = 0; i < rep.num_formats; 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;
+}
+
+
+
+/* Swapped Procs */
+
+static int
+SProcXvQueryExtension(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvQueryExtensionReq);
+ swaps(&stuff->length, n);
+ return ProcXvQueryExtension(client);
+}
+
+static int
+SProcXvQueryAdaptors(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvQueryAdaptorsReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ return ProcXvQueryAdaptors(client);
+}
+
+static int
+SProcXvQueryEncodings(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvQueryEncodingsReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->port, n);
+ return ProcXvQueryEncodings(client);
+}
+
+static int
+SProcXvGrabPort(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvGrabPortReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->port, n);
+ swapl(&stuff->time, n);
+ return ProcXvGrabPort(client);
+}
+
+static int
+SProcXvUngrabPort(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvUngrabPortReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->port, n);
+ swapl(&stuff->time, n);
+ return ProcXvUngrabPort(client);
+}
+
+static int
+SProcXvPutVideo(ClientPtr client)
+{
+ register 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 ProcXvPutVideo(client);
+}
+
+static int
+SProcXvPutStill(ClientPtr client)
+{
+ register 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 ProcXvPutStill(client);
+}
+
+static int
+SProcXvGetVideo(ClientPtr client)
+{
+ register 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 ProcXvGetVideo(client);
+}
+
+static int
+SProcXvGetStill(ClientPtr client)
+{
+ register 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 ProcXvGetStill(client);
+}
+
+static int
+SProcXvPutImage(ClientPtr client)
+{
+ register 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 ProcXvPutImage(client);
+}
+
+#ifdef MITSHM
+static int
+SProcXvShmPutImage(ClientPtr client)
+{
+ register 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);
+ 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->offset, n);
+ swaps(&stuff->width, n);
+ swaps(&stuff->height, n);
+ return ProcXvShmPutImage(client);
+}
+#endif
+
+
+static int
+SProcXvSelectVideoNotify(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvSelectVideoNotifyReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->drawable, n);
+ return ProcXvSelectVideoNotify(client);
+}
+
+static int
+SProcXvSelectPortNotify(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvSelectPortNotifyReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->port, n);
+ return ProcXvSelectPortNotify(client);
+}
+
+static int
+SProcXvStopVideo(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvStopVideoReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->port, n);
+ swapl(&stuff->drawable, n);
+ return ProcXvStopVideo(client);
+}
+
+static int
+SProcXvSetPortAttribute(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvSetPortAttributeReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->port, n);
+ swapl(&stuff->attribute, n);
+ return ProcXvSetPortAttribute(client);
+}
+
+static int
+SProcXvGetPortAttribute(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvGetPortAttributeReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->port, n);
+ swapl(&stuff->attribute, n);
+ return ProcXvGetPortAttribute(client);
+}
+
+static int
+SProcXvQueryBestSize(ClientPtr client)
+{
+ register 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 ProcXvQueryBestSize(client);
+}
+
+static int
+SProcXvQueryPortAttributes(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvQueryPortAttributesReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->port, n);
+ return ProcXvQueryPortAttributes(client);
+}
+
+static int
+SProcXvQueryImageAttributes(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvQueryImageAttributesReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->id, n);
+ swaps(&stuff->width, n);
+ swaps(&stuff->width, n);
+ return ProcXvQueryImageAttributes(client);
+}
+
+static int
+SProcXvListImageFormats(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvListImageFormatsReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->port, n);
+ return ProcXvListImageFormats(client);
+}
+
+
+static int
+SWriteQueryExtensionReply(
+ ClientPtr client,
+ xvQueryExtensionReply *rep
+){
+ register 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
+){
+ register 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
+){
+ register 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
+){
+ register 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
+){
+ register 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
+){
+ register char n;
+
+ swapl(&pFormat->visual, n);
+ (void)WriteToClient(client, sz_xvFormat, (char *)pFormat);
+
+ return Success;
+}
+
+static int
+SWriteAttributeInfo(
+ ClientPtr client,
+ xvAttributeInfo *pAtt
+){
+ register 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
+){
+ register 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
+){
+ register 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
+){
+ register 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
+){
+ register 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
+){
+ register 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
+){
+ register 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
+){
+ register char n;
+
+ swaps(&rep->sequenceNumber, n);
+ swapl(&rep->length, n);
+ swapl(&rep->num_formats, n);
+
+ (void)WriteToClient(client, sz_xvListImageFormatsReply, (char *)&rep);
+
+ return Success;
+}
+
+
+#ifdef PANORAMIX
+
+
+
+
+static int
+XineramaXvStopVideo(ClientPtr client)
+{
+ int result = Success, i;
+ PanoramiXRes *draw, *port;
+ REQUEST(xvStopVideoReq);
+ REQUEST_SIZE_MATCH(xvStopVideoReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+ return BadDrawable;
+
+ if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->port, XvXRTPort, SecurityReadAccess)))
+ return _XvBadPort;
+
+ 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 = Success, i;
+
+ REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
+
+ if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->port, XvXRTPort, SecurityReadAccess)))
+ return _XvBadPort;
+
+ 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 = Success, i, x, y;
+
+ REQUEST_SIZE_MATCH(xvShmPutImageReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+ return BadDrawable;
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, SecurityReadAccess)))
+ return BadGC;
+
+ if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->port, XvXRTPort, SecurityReadAccess)))
+ return _XvBadPort;
+
+ 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 -= panoramiXdataPtr[i].x;
+ stuff->drw_y -= panoramiXdataPtr[i].y;
+ }
+ stuff->send_event = (send_event && !i) ? 1 : 0;
+
+ result = ProcXvShmPutImage(client);
+ }
+ }
+ return result;
+}
+#endif
+
+static int
+XineramaXvPutImage(ClientPtr client)
+{
+ REQUEST(xvPutImageReq);
+ PanoramiXRes *draw, *gc, *port;
+ Bool isRoot;
+ int result = Success, i, x, y;
+
+ REQUEST_AT_LEAST_SIZE(xvPutImageReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+ return BadDrawable;
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, SecurityReadAccess)))
+ return BadGC;
+
+ if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->port, XvXRTPort, SecurityReadAccess)))
+ return _XvBadPort;
+
+ 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 -= panoramiXdataPtr[i].x;
+ stuff->drw_y -= panoramiXdataPtr[i].y;
+ }
+
+ result = ProcXvPutImage(client);
+ }
+ }
+ return result;
+}
+
+static int
+XineramaXvPutVideo(ClientPtr client)
+{
+ REQUEST(xvPutImageReq);
+ PanoramiXRes *draw, *gc, *port;
+ Bool isRoot;
+ int result = Success, i, x, y;
+
+ REQUEST_AT_LEAST_SIZE(xvPutVideoReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+ return BadDrawable;
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, SecurityReadAccess)))
+ return BadGC;
+
+ if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->port, XvXRTPort, SecurityReadAccess)))
+ return _XvBadPort;
+
+ 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 -= panoramiXdataPtr[i].x;
+ stuff->drw_y -= panoramiXdataPtr[i].y;
+ }
+
+ result = ProcXvPutVideo(client);
+ }
+ }
+ return result;
+}
+
+static int
+XineramaXvPutStill(ClientPtr client)
+{
+ REQUEST(xvPutImageReq);
+ PanoramiXRes *draw, *gc, *port;
+ Bool isRoot;
+ int result = Success, i, x, y;
+
+ REQUEST_AT_LEAST_SIZE(xvPutImageReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+ return BadDrawable;
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, SecurityReadAccess)))
+ return BadGC;
+
+ if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->port, XvXRTPort, SecurityReadAccess)))
+ return _XvBadPort;
+
+ 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 -= panoramiXdataPtr[i].x;
+ stuff->drw_y -= panoramiXdataPtr[i].y;
+ }
+
+ result = ProcXvPutStill(client);
+ }
+ }
+ return result;
+}
+
+
+void XineramifyXv(void)
+{
+ ScreenPtr pScreen, screen0 = screenInfo.screens[0];
+ XvScreenPtr xvsp0 = (XvScreenPtr)screen0->devPrivates[XvScreenIndex].ptr;
+ XvAdaptorPtr refAdapt, pAdapt;
+ XvAttributePtr pAttr;
+ XvScreenPtr xvsp;
+ Bool isOverlay, hasOverlay;
+ PanoramiXRes *port;
+ XvAdaptorPtr MatchingAdaptors[MAXSCREENS];
+ int i, j, k, l;
+
+ XvXRTPort = CreateNewResourceType(XineramaDeleteResource);
+
+ if(!xvsp0) return;
+
+ for(i = 0; i < xvsp0->nAdaptors; i++) {
+ refAdapt = xvsp0->pAdaptors + i;
+
+ bzero(MatchingAdaptors, sizeof(XvAdaptorPtr) * MAXSCREENS);
+
+ MatchingAdaptors[0] = refAdapt;
+
+ if(!(refAdapt->type & XvInputMask)) continue;
+
+ isOverlay = FALSE;
+ for(j = 0; j < refAdapt->nAttributes; j++) {
+ pAttr = refAdapt->pAttributes + j;
+ if(!strcmp(pAttr->name, "XV_COLORKEY")) {
+ isOverlay = TRUE;
+ break;
+ }
+ }
+
+ for(j = 1; j < PanoramiXNumScreens; j++) {
+ pScreen = screenInfo.screens[j];
+ xvsp = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr;
+
+ /* Do not try to go on if xv is not supported on this screen */
+ if (xvsp==NULL) continue ;
+
+ /* if the adaptor has the same name it's a perfect match */
+ for(k = 0; k < xvsp->nAdaptors; k++) {
+ pAdapt = xvsp->pAdaptors + k;
+ if(!strcmp(refAdapt->name, pAdapt->name)) {
+ MatchingAdaptors[j] = pAdapt;
+ break;
+ }
+ }
+ if(MatchingAdaptors[j]) continue; /* found it */
+
+ /* otherwise we only look for XvImage adaptors */
+ if(!(refAdapt->type & XvImageMask)) continue;
+ if(refAdapt->nImages <= 0) continue;
+
+ /* prefer overlay/overlay non-overlay/non-overlay pairing */
+ for(k = 0; k < xvsp->nAdaptors; k++) {
+ pAdapt = xvsp->pAdaptors + k;
+ if((pAdapt->type & XvImageMask) && (pAdapt->nImages > 0)) {
+ hasOverlay = FALSE;
+ for(l = 0; l < pAdapt->nAttributes; l++) {
+ if(!strcmp(pAdapt->name, "XV_COLORKEY")) {
+ hasOverlay = TRUE;
+ break;
+ }
+ }
+ if(isOverlay && hasOverlay) {
+ MatchingAdaptors[j] = pAdapt;
+ break;
+ }
+ else if(!isOverlay && !hasOverlay) {
+ MatchingAdaptors[j] = pAdapt;
+ break;
+ }
+ }
+ }
+
+ if(MatchingAdaptors[j]) continue; /* found it */
+
+ /* but we'll take any XvImage pairing if we can get it */
+
+ for(k = 0; k < xvsp->nAdaptors; k++) {
+ pAdapt = xvsp->pAdaptors + k;
+ if((pAdapt->type & XvImageMask) && (pAdapt->nImages > 0)) {
+ MatchingAdaptors[j] = pAdapt;
+ break;
+ }
+ }
+ }
+
+ /* now create a resource for each port */
+ for(j = 0; j < refAdapt->nPorts; j++) {
+ if(!(port = xalloc(sizeof(PanoramiXRes))))
+ break;
+ port->info[0].id = MatchingAdaptors[0]->base_id + j;
+ AddResource(port->info[0].id, XvXRTPort, port);
+
+ for(k = 1; 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;
+ }
+ }
+ }
+}
+
+#endif
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.NX.original
new file mode 100644
index 000000000..15fdd9ff3
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.NX.original
@@ -0,0 +1,2286 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of NoMachine S.r.l. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/* $XdotOrg: xc/programs/Xserver/Xext/xvdisp.c,v 1.6 2005/07/03 08:53:36 daniels Exp $ */
+/***********************************************************
+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.
+
+******************************************************************/
+/* $XFree86: xc/programs/Xserver/Xext/xvdisp.c,v 1.27 2003/07/16 01:38:31 dawes Exp $ */
+
+/*
+** File:
+**
+** xvdisp.c --- Xv server extension dispatch module.
+**
+** Author:
+**
+** David Carver (Digital Workstation Engineering/Project Athena)
+**
+** Revisions:
+**
+** 11.06.91 Carver
+** - changed SetPortControl to SetPortAttribute
+** - changed GetPortControl to GetPortAttribute
+** - changed QueryBestSize
+**
+** 15.05.91 Carver
+** - version 2.0 upgrade
+**
+** 24.01.91 Carver
+** - version 1.4 upgrade
+**
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#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
+#define _XSHM_SERVER_
+#include <X11/extensions/shmstr.h>
+#endif
+
+#include "Trap.h"
+
+#undef TEST
+#undef DEBUG
+
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#endif
+
+#include "xvdisp.h"
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+
+unsigned long XvXRTPort;
+
+#ifdef MITSHM
+static int XineramaXvShmPutImage(ClientPtr);
+#endif
+static int XineramaXvPutImage(ClientPtr);
+static int XineramaXvPutVideo(ClientPtr);
+static int XineramaXvPutStill(ClientPtr);
+static int XineramaXvSetPortAttribute(ClientPtr);
+static int XineramaXvStopVideo(ClientPtr);
+#endif
+
+/* INTERNAL */
+
+static int ProcXvQueryExtension(ClientPtr);
+static int ProcXvQueryAdaptors(ClientPtr);
+static int ProcXvQueryEncodings(ClientPtr);
+static int ProcXvPutVideo(ClientPtr);
+static int ProcXvPutStill(ClientPtr);
+static int ProcXvGetVideo(ClientPtr);
+static int ProcXvGetStill(ClientPtr);
+static int ProcXvGrabPort(ClientPtr);
+static int ProcXvUngrabPort(ClientPtr);
+static int ProcXvSelectVideoNotify(ClientPtr);
+static int ProcXvSelectPortNotify(ClientPtr);
+static int ProcXvStopVideo(ClientPtr);
+static int ProcXvSetPortAttribute(ClientPtr);
+static int ProcXvGetPortAttribute(ClientPtr);
+static int ProcXvQueryBestSize(ClientPtr);
+static int ProcXvQueryPortAttributes(ClientPtr);
+static int ProcXvPutImage(ClientPtr);
+#ifdef MITSHM
+static int ProcXvShmPutImage(ClientPtr);
+#endif
+static int ProcXvQueryImageAttributes(ClientPtr);
+static int ProcXvListImageFormats(ClientPtr);
+
+static int SProcXvQueryExtension(ClientPtr);
+static int SProcXvQueryAdaptors(ClientPtr);
+static int SProcXvQueryEncodings(ClientPtr);
+static int SProcXvPutVideo(ClientPtr);
+static int SProcXvPutStill(ClientPtr);
+static int SProcXvGetVideo(ClientPtr);
+static int SProcXvGetStill(ClientPtr);
+static int SProcXvGrabPort(ClientPtr);
+static int SProcXvUngrabPort(ClientPtr);
+static int SProcXvSelectVideoNotify(ClientPtr);
+static int SProcXvSelectPortNotify(ClientPtr);
+static int SProcXvStopVideo(ClientPtr);
+static int SProcXvSetPortAttribute(ClientPtr);
+static int SProcXvGetPortAttribute(ClientPtr);
+static int SProcXvQueryBestSize(ClientPtr);
+static int SProcXvQueryPortAttributes(ClientPtr);
+static int SProcXvPutImage(ClientPtr);
+#ifdef MITSHM
+static int SProcXvShmPutImage(ClientPtr);
+#endif
+static int SProcXvQueryImageAttributes(ClientPtr);
+static int SProcXvListImageFormats(ClientPtr);
+
+static int SWriteQueryAdaptorsReply(ClientPtr, xvQueryAdaptorsReply *);
+static int SWriteQueryExtensionReply(ClientPtr, xvQueryExtensionReply *);
+static int SWriteQueryEncodingsReply(ClientPtr, xvQueryEncodingsReply *);
+static int SWriteAdaptorInfo(ClientPtr, xvAdaptorInfo *);
+static int SWriteEncodingInfo(ClientPtr, xvEncodingInfo *);
+static int SWriteFormat(ClientPtr, xvFormat *);
+static int SWriteAttributeInfo(ClientPtr, xvAttributeInfo *);
+static int SWriteGrabPortReply(ClientPtr, xvGrabPortReply *);
+static int SWriteGetPortAttributeReply(ClientPtr, xvGetPortAttributeReply *);
+static int SWriteQueryBestSizeReply(ClientPtr, xvQueryBestSizeReply *);
+static int SWriteQueryPortAttributesReply(
+ ClientPtr, xvQueryPortAttributesReply *);
+static int SWriteQueryImageAttributesReply(
+ ClientPtr, xvQueryImageAttributesReply*);
+static int SWriteListImageFormatsReply(ClientPtr, xvListImageFormatsReply*);
+static int SWriteImageFormatInfo(ClientPtr, xvImageFormatInfo*);
+
+#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
+
+/*
+** ProcXvDispatch
+**
+**
+**
+*/
+
+int
+ProcXvDispatch(ClientPtr client)
+{
+ int result;
+
+ REQUEST(xReq);
+
+ UpdateCurrentTime();
+
+ /*
+ * Report upstream that we are
+ * dispatching a XVideo operation.
+ */
+
+ nxagentXvTrap = 1;
+
+ #ifdef TEST
+ fprintf(stderr, "ProcXvDispatch: Going to dispatch XVideo operation [%d] for client [%d].\n",
+ stuff->data, client -> index);
+ #endif
+
+ switch (stuff->data)
+ {
+ case xv_QueryExtension: result = (ProcXvQueryExtension(client)); break;
+ case xv_QueryAdaptors: result = (ProcXvQueryAdaptors(client)); break;
+ case xv_QueryEncodings: result = (ProcXvQueryEncodings(client)); break;
+ case xv_PutVideo:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ result = (XineramaXvPutVideo(client)); break;
+ else
+#endif
+ result = (ProcXvPutVideo(client)); break;
+ case xv_PutStill:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ result = (XineramaXvPutStill(client)); break
+ else
+#endif
+ result = (ProcXvPutStill(client)); break;
+ case xv_GetVideo: result = (ProcXvGetVideo(client)); break;
+ case xv_GetStill: result = (ProcXvGetStill(client)); break;
+ case xv_GrabPort: result = (ProcXvGrabPort(client)); break;
+ case xv_UngrabPort: result = (ProcXvUngrabPort(client)); break;
+ case xv_SelectVideoNotify: result = (ProcXvSelectVideoNotify(client)); break;
+ case xv_SelectPortNotify: result = (ProcXvSelectPortNotify(client)); break;
+ case xv_StopVideo:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ result = (XineramaXvStopVideo(client)); break;
+ else
+#endif
+ result = (ProcXvStopVideo(client)); break;
+ case xv_SetPortAttribute:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ result = (XineramaXvSetPortAttribute(client)); break;
+ else
+#endif
+ result = (ProcXvSetPortAttribute(client)); break;
+ case xv_GetPortAttribute: result = (ProcXvGetPortAttribute(client)); break;
+ case xv_QueryBestSize: result = (ProcXvQueryBestSize(client)); break;
+ case xv_QueryPortAttributes: result = (ProcXvQueryPortAttributes(client)); break;
+ case xv_PutImage:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ result = (XineramaXvPutImage(client)); break;
+ else
+#endif
+ result = (ProcXvPutImage(client)); break;
+#ifdef MITSHM
+ case xv_ShmPutImage:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ result = (XineramaXvShmPutImage(client)); break;
+ else
+#endif
+ result = (ProcXvShmPutImage(client)); break;
+#endif
+ case xv_QueryImageAttributes: result = (ProcXvQueryImageAttributes(client)); break;
+ case xv_ListImageFormats: result = (ProcXvListImageFormats(client)); break;
+ default:
+ if (stuff->data < xvNumRequests)
+ {
+ SendErrorToClient(client, XvReqCode, stuff->data, 0,
+ BadImplementation);
+ result = (BadImplementation); break;
+ }
+ else
+ {
+ SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
+ result = (BadRequest); break;
+ }
+ }
+
+ nxagentXvTrap = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "ProcXvDispatch: Dispatched XVideo operation [%d] for client [%d].\n",
+ stuff->data, client -> index);
+ #endif
+
+ return result;
+}
+
+int
+SProcXvDispatch(ClientPtr client)
+{
+ int result;
+
+ REQUEST(xReq);
+
+ UpdateCurrentTime();
+
+ /*
+ * Report upstream that we are
+ * dispatching a XVideo operation.
+ */
+
+ nxagentXvTrap = 1;
+
+ #ifdef TEST
+ fprintf(stderr, "SProcXvDispatch: Going to dispatch XVideo operation [%d] for client [%d].\n",
+ stuff->data, client -> index);
+ #endif
+
+ switch (stuff->data)
+ {
+ case xv_QueryExtension: result = (SProcXvQueryExtension(client)); break;
+ case xv_QueryAdaptors: result = (SProcXvQueryAdaptors(client)); break;
+ case xv_QueryEncodings: result = (SProcXvQueryEncodings(client)); break;
+ case xv_PutVideo: result = (SProcXvPutVideo(client)); break;
+ case xv_PutStill: result = (SProcXvPutStill(client)); break;
+ case xv_GetVideo: result = (SProcXvGetVideo(client)); break;
+ case xv_GetStill: result = (SProcXvGetStill(client)); break;
+ case xv_GrabPort: result = (SProcXvGrabPort(client)); break;
+ case xv_UngrabPort: result = (SProcXvUngrabPort(client)); break;
+ case xv_SelectVideoNotify: result = (SProcXvSelectVideoNotify(client)); break;
+ case xv_SelectPortNotify: result = (SProcXvSelectPortNotify(client)); break;
+ case xv_StopVideo: result = (SProcXvStopVideo(client)); break;
+ case xv_SetPortAttribute: result = (SProcXvSetPortAttribute(client)); break;
+ case xv_GetPortAttribute: result = (SProcXvGetPortAttribute(client)); break;
+ case xv_QueryBestSize: result = (SProcXvQueryBestSize(client)); break;
+ case xv_QueryPortAttributes: result = (SProcXvQueryPortAttributes(client)); break;
+ case xv_PutImage: result = (SProcXvPutImage(client)); break;
+#ifdef MITSHM
+ case xv_ShmPutImage: result = (SProcXvShmPutImage(client)); break;
+#endif
+ case xv_QueryImageAttributes: result = (SProcXvQueryImageAttributes(client)); break;
+ case xv_ListImageFormats: result = (SProcXvListImageFormats(client)); break;
+ default:
+ if (stuff->data < xvNumRequests)
+ {
+ SendErrorToClient(client, XvReqCode, stuff->data, 0,
+ BadImplementation);
+ result = (BadImplementation); break;
+ }
+ else
+ {
+ SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
+ result = (BadRequest); break;
+ }
+ }
+
+ nxagentXvTrap = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "ProcXvDispatch: Dispatched XVideo operation [%d] for client [%d].\n",
+ stuff->data, client -> index);
+ #endif
+
+ return result;
+}
+
+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;
+ int na;
+ XvAdaptorPtr pa;
+ int nf;
+ XvFormatPtr pf;
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ XvScreenPtr pxvs;
+
+ REQUEST(xvQueryAdaptorsReq);
+ REQUEST_SIZE_MATCH(xvQueryAdaptorsReq);
+
+ if(!(pWin = (WindowPtr)LookupWindow(stuff->window, client) ))
+ {
+ client->errorValue = stuff->window;
+ return (BadWindow);
+ }
+
+ pScreen = pWin->drawable.pScreen;
+ pxvs = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr;
+
+ 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 += (strlen(pa->name) + 3) & ~3;
+ totalSize += pa->nFormats * sz_xvFormat;
+ pa++;
+ }
+
+ rep.length = totalSize >> 2;
+
+ _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 = strlen(pa->name);
+ ainfo.num_formats = pa->nFormats;
+
+ _WriteAdaptorInfo(client, &ainfo);
+
+ WriteToClient(client, ainfo.name_size, pa->name);
+
+ nf = pa->nFormats;
+ pf = pa->pFormats;
+ while (nf--)
+ {
+ format.depth = pf->depth;
+ format.visual = pf->visual;
+ _WriteFormat(client, &format);
+ pf++;
+ }
+
+ pa++;
+
+ }
+
+ return (client->noClientException);
+
+}
+
+static int
+ProcXvQueryEncodings(ClientPtr client)
+{
+ xvEncodingInfo einfo;
+ xvQueryEncodingsReply rep;
+ int totalSize;
+ XvPortPtr pPort;
+ int ne;
+ XvEncodingPtr pe;
+ int status;
+
+ REQUEST(xvQueryEncodingsReq);
+ REQUEST_SIZE_MATCH(xvQueryEncodingsReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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 += (strlen(pe->name) + 3) & ~3;
+ pe++;
+ }
+
+ rep.length = totalSize >> 2;
+
+ _WriteQueryEncodingsReply(client, &rep);
+
+ ne = pPort->pAdaptor->nEncodings;
+ pe = pPort->pAdaptor->pEncodings;
+ while (ne--)
+ {
+ einfo.encoding = pe->id;
+ einfo.name_size = 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, einfo.name_size, pe->name);
+ pe++;
+ }
+
+ return (client->noClientException);
+
+}
+
+static int
+ProcXvPutVideo(ClientPtr client)
+{
+ register DrawablePtr pDraw;
+ XvPortPtr pPort;
+ register GCPtr pGC;
+ int status;
+
+ REQUEST(xvPutVideoReq);
+ REQUEST_SIZE_MATCH(xvPutVideoReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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 = XVCALL(diMatchPort)(pPort, pDraw);
+ if (status != Success)
+ {
+ return status;
+ }
+
+ return XVCALL(diPutVideo)(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)
+{
+ register DrawablePtr pDraw;
+ XvPortPtr pPort;
+ register GCPtr pGC;
+ int status;
+
+ REQUEST(xvPutStillReq);
+ REQUEST_SIZE_MATCH(xvPutStillReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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 = XVCALL(diMatchPort)(pPort, pDraw);
+ if (status != Success)
+ {
+ return status;
+ }
+
+ return XVCALL(diPutStill)(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)
+{
+ register DrawablePtr pDraw;
+ XvPortPtr pPort;
+ register GCPtr pGC;
+ int status;
+
+ REQUEST(xvGetVideoReq);
+ REQUEST_SIZE_MATCH(xvGetVideoReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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 = XVCALL(diMatchPort)(pPort, pDraw);
+ if (status != Success)
+ {
+ return status;
+ }
+
+ return XVCALL(diGetVideo)(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)
+{
+ register DrawablePtr pDraw;
+ XvPortPtr pPort;
+ register GCPtr pGC;
+ int status;
+
+ REQUEST(xvGetStillReq);
+ REQUEST_SIZE_MATCH(xvGetStillReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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 = XVCALL(diMatchPort)(pPort, pDraw);
+ if (status != Success)
+ {
+ return status;
+ }
+
+ return XVCALL(diGetStill)(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)
+{
+ register DrawablePtr pDraw;
+ REQUEST(xvSelectVideoNotifyReq);
+ REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq);
+
+ if(!(pDraw = (DrawablePtr)LOOKUP_DRAWABLE(stuff->drawable, client) ))
+ {
+ client->errorValue = stuff->drawable;
+ return (BadWindow);
+ }
+
+ return XVCALL(diSelectVideoNotify)(client, pDraw, stuff->onoff);
+
+}
+
+static int
+ProcXvSelectPortNotify(ClientPtr client)
+{
+ int status;
+ XvPortPtr pPort;
+ REQUEST(xvSelectPortNotifyReq);
+ REQUEST_SIZE_MATCH(xvSelectPortNotifyReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ return XVCALL(diSelectPortNotify)(client, pPort, stuff->onoff);
+
+}
+
+static int
+ProcXvGrabPort(ClientPtr client)
+{
+ int result, status;
+ XvPortPtr pPort;
+ xvGrabPortReply rep;
+ REQUEST(xvGrabPortReq);
+ REQUEST_SIZE_MATCH(xvGrabPortReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ status = XVCALL(diGrabPort)(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);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ return XVCALL(diUngrabPort)(client, pPort, stuff->time);
+
+}
+
+
+static int
+ProcXvStopVideo(ClientPtr client)
+{
+ int status;
+ register DrawablePtr pDraw;
+ XvPortPtr pPort;
+ REQUEST(xvStopVideoReq);
+ REQUEST_SIZE_MATCH(xvStopVideoReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ if(!(pDraw = LOOKUP_DRAWABLE(stuff->drawable, client) ))
+ {
+ client->errorValue = stuff->drawable;
+ return (BadDrawable);
+ }
+
+ return XVCALL(diStopVideo)(client, pPort, pDraw);
+
+}
+
+static int
+ProcXvSetPortAttribute(ClientPtr client)
+{
+ int status;
+ XvPortPtr pPort;
+ REQUEST(xvSetPortAttributeReq);
+ REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ if (!ValidAtom(stuff->attribute))
+ {
+ client->errorValue = stuff->attribute;
+ return(BadAtom);
+ }
+
+ status = XVCALL(diSetPortAttribute)(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);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ if (!ValidAtom(stuff->attribute))
+ {
+ client->errorValue = stuff->attribute;
+ return(BadAtom);
+ }
+
+ status = XVCALL(diGetPortAttribute)(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);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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 < rep.num_attributes; i++, pAtt++)
+ {
+ rep.text_size += (strlen(pAtt->name) + 1 + 3) & ~3L;
+ }
+
+ rep.length = (rep.num_attributes * sz_xvAttributeInfo) + rep.text_size;
+ rep.length >>= 2;
+
+ _WriteQueryPortAttributesReply(client, &rep);
+
+ for(i = 0, pAtt = pPort->pAdaptor->pAttributes;
+ i < rep.num_attributes; 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 = (size + 3) & ~3L;
+
+ _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, pGC, client);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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 = XVCALL(diMatchPort)(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 = (size + 3) >> 2;
+
+ if((width < stuff->width) || (height < stuff->height))
+ return BadValue;
+
+ if(client->req_len < size)
+ return BadLength;
+
+ return XVCALL(diPutImage)(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 BadShmSegCode;
+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, pGC, client);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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 = XVCALL(diMatchPort)(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;
+
+ if(!(shmdesc = (ShmDescPtr)LookupIDByType(stuff->shmseg, ShmSegType)))
+ {
+ client->errorValue = stuff->shmseg;
+ return BadShmSegCode;
+ }
+
+ 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 = XVCALL(diPutImage)(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.sequenceNumber = client->sequence;
+ ev.minorEvent = xv_ShmPutImage;
+ ev.majorEvent = XvReqCode;
+ ev.shmseg = stuff->shmseg;
+ ev.offset = stuff->offset;
+ WriteEventsToClient(client, 1, (xEvent *) &ev);
+ }
+
+ return status;
+}
+#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;
+ REQUEST(xvQueryImageAttributesReq);
+
+ REQUEST_SIZE_MATCH(xvQueryImageAttributesReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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 = xalloc(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 = 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, rep.length);
+ WriteToClient(client, rep.length << 2, (char*)offsets);
+
+ xfree(offsets);
+
+ return Success;
+}
+
+static int
+ProcXvListImageFormats(ClientPtr client)
+{
+ XvPortPtr pPort;
+ XvImagePtr pImage;
+ int i;
+ xvListImageFormatsReply rep;
+ xvImageFormatInfo info;
+ REQUEST(xvListImageFormatsReq);
+
+ REQUEST_SIZE_MATCH(xvListImageFormatsReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.num_formats = pPort->pAdaptor->nImages;
+ rep.length = rep.num_formats * sz_xvImageFormatInfo >> 2;
+
+ _WriteListImageFormatsReply(client, &rep);
+
+ pImage = pPort->pAdaptor->pImages;
+
+ for(i = 0; i < rep.num_formats; 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;
+}
+
+
+
+/* Swapped Procs */
+
+static int
+SProcXvQueryExtension(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvQueryExtensionReq);
+ swaps(&stuff->length, n);
+ return ProcXvQueryExtension(client);
+}
+
+static int
+SProcXvQueryAdaptors(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvQueryAdaptorsReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ return ProcXvQueryAdaptors(client);
+}
+
+static int
+SProcXvQueryEncodings(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvQueryEncodingsReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->port, n);
+ return ProcXvQueryEncodings(client);
+}
+
+static int
+SProcXvGrabPort(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvGrabPortReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->port, n);
+ swapl(&stuff->time, n);
+ return ProcXvGrabPort(client);
+}
+
+static int
+SProcXvUngrabPort(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvUngrabPortReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->port, n);
+ swapl(&stuff->time, n);
+ return ProcXvUngrabPort(client);
+}
+
+static int
+SProcXvPutVideo(ClientPtr client)
+{
+ register 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 ProcXvPutVideo(client);
+}
+
+static int
+SProcXvPutStill(ClientPtr client)
+{
+ register 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 ProcXvPutStill(client);
+}
+
+static int
+SProcXvGetVideo(ClientPtr client)
+{
+ register 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 ProcXvGetVideo(client);
+}
+
+static int
+SProcXvGetStill(ClientPtr client)
+{
+ register 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 ProcXvGetStill(client);
+}
+
+static int
+SProcXvPutImage(ClientPtr client)
+{
+ register 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 ProcXvPutImage(client);
+}
+
+#ifdef MITSHM
+static int
+SProcXvShmPutImage(ClientPtr client)
+{
+ register 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);
+ 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->offset, n);
+ swaps(&stuff->width, n);
+ swaps(&stuff->height, n);
+ return ProcXvShmPutImage(client);
+}
+#endif
+
+
+static int
+SProcXvSelectVideoNotify(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvSelectVideoNotifyReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->drawable, n);
+ return ProcXvSelectVideoNotify(client);
+}
+
+static int
+SProcXvSelectPortNotify(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvSelectPortNotifyReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->port, n);
+ return ProcXvSelectPortNotify(client);
+}
+
+static int
+SProcXvStopVideo(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvStopVideoReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->port, n);
+ swapl(&stuff->drawable, n);
+ return ProcXvStopVideo(client);
+}
+
+static int
+SProcXvSetPortAttribute(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvSetPortAttributeReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->port, n);
+ swapl(&stuff->attribute, n);
+ return ProcXvSetPortAttribute(client);
+}
+
+static int
+SProcXvGetPortAttribute(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvGetPortAttributeReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->port, n);
+ swapl(&stuff->attribute, n);
+ return ProcXvGetPortAttribute(client);
+}
+
+static int
+SProcXvQueryBestSize(ClientPtr client)
+{
+ register 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 ProcXvQueryBestSize(client);
+}
+
+static int
+SProcXvQueryPortAttributes(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvQueryPortAttributesReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->port, n);
+ return ProcXvQueryPortAttributes(client);
+}
+
+static int
+SProcXvQueryImageAttributes(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvQueryImageAttributesReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->id, n);
+ swaps(&stuff->width, n);
+ swaps(&stuff->width, n);
+ return ProcXvQueryImageAttributes(client);
+}
+
+static int
+SProcXvListImageFormats(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvListImageFormatsReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->port, n);
+ return ProcXvListImageFormats(client);
+}
+
+
+static int
+SWriteQueryExtensionReply(
+ ClientPtr client,
+ xvQueryExtensionReply *rep
+){
+ register 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
+){
+ register 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
+){
+ register 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
+){
+ register 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
+){
+ register 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
+){
+ register char n;
+
+ swapl(&pFormat->visual, n);
+ (void)WriteToClient(client, sz_xvFormat, (char *)pFormat);
+
+ return Success;
+}
+
+static int
+SWriteAttributeInfo(
+ ClientPtr client,
+ xvAttributeInfo *pAtt
+){
+ register 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
+){
+ register 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
+){
+ register 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
+){
+ register 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
+){
+ register 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
+){
+ register 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
+){
+ register 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
+){
+ register char n;
+
+ swaps(&rep->sequenceNumber, n);
+ swapl(&rep->length, n);
+ swapl(&rep->num_formats, n);
+
+ (void)WriteToClient(client, sz_xvListImageFormatsReply, (char *)&rep);
+
+ return Success;
+}
+
+
+#ifdef PANORAMIX
+
+
+
+
+static int
+XineramaXvStopVideo(ClientPtr client)
+{
+ int result = Success, i;
+ PanoramiXRes *draw, *port;
+ REQUEST(xvStopVideoReq);
+ REQUEST_SIZE_MATCH(xvStopVideoReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+ return BadDrawable;
+
+ if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->port, XvXRTPort, SecurityReadAccess)))
+ return _XvBadPort;
+
+ 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 = Success, i;
+
+ REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
+
+ if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->port, XvXRTPort, SecurityReadAccess)))
+ return _XvBadPort;
+
+ 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 = Success, i, x, y;
+
+ REQUEST_SIZE_MATCH(xvShmPutImageReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+ return BadDrawable;
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, SecurityReadAccess)))
+ return BadGC;
+
+ if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->port, XvXRTPort, SecurityReadAccess)))
+ return _XvBadPort;
+
+ 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 -= panoramiXdataPtr[i].x;
+ stuff->drw_y -= panoramiXdataPtr[i].y;
+ }
+ stuff->send_event = (send_event && !i) ? 1 : 0;
+
+ result = ProcXvShmPutImage(client);
+ }
+ }
+ return result;
+}
+#endif
+
+static int
+XineramaXvPutImage(ClientPtr client)
+{
+ REQUEST(xvPutImageReq);
+ PanoramiXRes *draw, *gc, *port;
+ Bool isRoot;
+ int result = Success, i, x, y;
+
+ REQUEST_AT_LEAST_SIZE(xvPutImageReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+ return BadDrawable;
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, SecurityReadAccess)))
+ return BadGC;
+
+ if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->port, XvXRTPort, SecurityReadAccess)))
+ return _XvBadPort;
+
+ 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 -= panoramiXdataPtr[i].x;
+ stuff->drw_y -= panoramiXdataPtr[i].y;
+ }
+
+ result = ProcXvPutImage(client);
+ }
+ }
+ return result;
+}
+
+static int
+XineramaXvPutVideo(ClientPtr client)
+{
+ REQUEST(xvPutImageReq);
+ PanoramiXRes *draw, *gc, *port;
+ Bool isRoot;
+ int result = Success, i, x, y;
+
+ REQUEST_AT_LEAST_SIZE(xvPutVideoReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+ return BadDrawable;
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, SecurityReadAccess)))
+ return BadGC;
+
+ if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->port, XvXRTPort, SecurityReadAccess)))
+ return _XvBadPort;
+
+ 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 -= panoramiXdataPtr[i].x;
+ stuff->drw_y -= panoramiXdataPtr[i].y;
+ }
+
+ result = ProcXvPutVideo(client);
+ }
+ }
+ return result;
+}
+
+static int
+XineramaXvPutStill(ClientPtr client)
+{
+ REQUEST(xvPutImageReq);
+ PanoramiXRes *draw, *gc, *port;
+ Bool isRoot;
+ int result = Success, i, x, y;
+
+ REQUEST_AT_LEAST_SIZE(xvPutImageReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+ return BadDrawable;
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, SecurityReadAccess)))
+ return BadGC;
+
+ if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->port, XvXRTPort, SecurityReadAccess)))
+ return _XvBadPort;
+
+ 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 -= panoramiXdataPtr[i].x;
+ stuff->drw_y -= panoramiXdataPtr[i].y;
+ }
+
+ result = ProcXvPutStill(client);
+ }
+ }
+ return result;
+}
+
+
+void XineramifyXv(void)
+{
+ ScreenPtr pScreen, screen0 = screenInfo.screens[0];
+ XvScreenPtr xvsp0 = (XvScreenPtr)screen0->devPrivates[XvScreenIndex].ptr;
+ XvAdaptorPtr refAdapt, pAdapt;
+ XvAttributePtr pAttr;
+ XvScreenPtr xvsp;
+ Bool isOverlay, hasOverlay;
+ PanoramiXRes *port;
+ XvAdaptorPtr MatchingAdaptors[MAXSCREENS];
+ int i, j, k, l;
+
+ XvXRTPort = CreateNewResourceType(XineramaDeleteResource);
+
+ if(!xvsp0) return;
+
+ for(i = 0; i < xvsp0->nAdaptors; i++) {
+ refAdapt = xvsp0->pAdaptors + i;
+
+ bzero(MatchingAdaptors, sizeof(XvAdaptorPtr) * MAXSCREENS);
+
+ MatchingAdaptors[0] = refAdapt;
+
+ if(!(refAdapt->type & XvInputMask)) continue;
+
+ isOverlay = FALSE;
+ for(j = 0; j < refAdapt->nAttributes; j++) {
+ pAttr = refAdapt->pAttributes + j;
+ if(!strcmp(pAttr->name, "XV_COLORKEY")) {
+ isOverlay = TRUE;
+ break;
+ }
+ }
+
+ for(j = 1; j < PanoramiXNumScreens; j++) {
+ pScreen = screenInfo.screens[j];
+ xvsp = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr;
+
+ /* Do not try to go on if xv is not supported on this screen */
+ if (xvsp==NULL) continue ;
+
+ /* if the adaptor has the same name it's a perfect match */
+ for(k = 0; k < xvsp->nAdaptors; k++) {
+ pAdapt = xvsp->pAdaptors + k;
+ if(!strcmp(refAdapt->name, pAdapt->name)) {
+ MatchingAdaptors[j] = pAdapt;
+ break;
+ }
+ }
+ if(MatchingAdaptors[j]) continue; /* found it */
+
+ /* otherwise we only look for XvImage adaptors */
+ if(!(refAdapt->type & XvImageMask)) continue;
+ if(refAdapt->nImages <= 0) continue;
+
+ /* prefer overlay/overlay non-overlay/non-overlay pairing */
+ for(k = 0; k < xvsp->nAdaptors; k++) {
+ pAdapt = xvsp->pAdaptors + k;
+ if((pAdapt->type & XvImageMask) && (pAdapt->nImages > 0)) {
+ hasOverlay = FALSE;
+ for(l = 0; l < pAdapt->nAttributes; l++) {
+ if(!strcmp(pAdapt->name, "XV_COLORKEY")) {
+ hasOverlay = TRUE;
+ break;
+ }
+ }
+ if(isOverlay && hasOverlay) {
+ MatchingAdaptors[j] = pAdapt;
+ break;
+ }
+ else if(!isOverlay && !hasOverlay) {
+ MatchingAdaptors[j] = pAdapt;
+ break;
+ }
+ }
+ }
+
+ if(MatchingAdaptors[j]) continue; /* found it */
+
+ /* but we'll take any XvImage pairing if we can get it */
+
+ for(k = 0; k < xvsp->nAdaptors; k++) {
+ pAdapt = xvsp->pAdaptors + k;
+ if((pAdapt->type & XvImageMask) && (pAdapt->nImages > 0)) {
+ MatchingAdaptors[j] = pAdapt;
+ break;
+ }
+ }
+ }
+
+ /* now create a resource for each port */
+ for(j = 0; j < refAdapt->nPorts; j++) {
+ if(!(port = xalloc(sizeof(PanoramiXRes))))
+ break;
+ port->info[0].id = MatchingAdaptors[0]->base_id + j;
+ AddResource(port->info[0].id, XvXRTPort, port);
+
+ for(k = 1; 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;
+ }
+ }
+ }
+}
+
+#endif
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.X.original
new file mode 100644
index 000000000..21ab0b6a0
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.X.original
@@ -0,0 +1,2217 @@
+/* $XdotOrg: xc/programs/Xserver/Xext/xvdisp.c,v 1.6 2005/07/03 08:53:36 daniels Exp $ */
+/***********************************************************
+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.
+
+******************************************************************/
+/* $XFree86: xc/programs/Xserver/Xext/xvdisp.c,v 1.27 2003/07/16 01:38:31 dawes Exp $ */
+
+/*
+** File:
+**
+** xvdisp.c --- Xv server extension dispatch module.
+**
+** Author:
+**
+** David Carver (Digital Workstation Engineering/Project Athena)
+**
+** Revisions:
+**
+** 11.06.91 Carver
+** - changed SetPortControl to SetPortAttribute
+** - changed GetPortControl to GetPortAttribute
+** - changed QueryBestSize
+**
+** 15.05.91 Carver
+** - version 2.0 upgrade
+**
+** 24.01.91 Carver
+** - version 1.4 upgrade
+**
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#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
+#define _XSHM_SERVER_
+#include <X11/extensions/shmstr.h>
+#endif
+
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#endif
+
+#include "xvdisp.h"
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+
+unsigned long XvXRTPort;
+
+#ifdef MITSHM
+static int XineramaXvShmPutImage(ClientPtr);
+#endif
+static int XineramaXvPutImage(ClientPtr);
+static int XineramaXvPutVideo(ClientPtr);
+static int XineramaXvPutStill(ClientPtr);
+static int XineramaXvSetPortAttribute(ClientPtr);
+static int XineramaXvStopVideo(ClientPtr);
+#endif
+
+/* INTERNAL */
+
+static int ProcXvQueryExtension(ClientPtr);
+static int ProcXvQueryAdaptors(ClientPtr);
+static int ProcXvQueryEncodings(ClientPtr);
+static int ProcXvPutVideo(ClientPtr);
+static int ProcXvPutStill(ClientPtr);
+static int ProcXvGetVideo(ClientPtr);
+static int ProcXvGetStill(ClientPtr);
+static int ProcXvGrabPort(ClientPtr);
+static int ProcXvUngrabPort(ClientPtr);
+static int ProcXvSelectVideoNotify(ClientPtr);
+static int ProcXvSelectPortNotify(ClientPtr);
+static int ProcXvStopVideo(ClientPtr);
+static int ProcXvSetPortAttribute(ClientPtr);
+static int ProcXvGetPortAttribute(ClientPtr);
+static int ProcXvQueryBestSize(ClientPtr);
+static int ProcXvQueryPortAttributes(ClientPtr);
+static int ProcXvPutImage(ClientPtr);
+#ifdef MITSHM
+static int ProcXvShmPutImage(ClientPtr);
+#endif
+static int ProcXvQueryImageAttributes(ClientPtr);
+static int ProcXvListImageFormats(ClientPtr);
+
+static int SProcXvQueryExtension(ClientPtr);
+static int SProcXvQueryAdaptors(ClientPtr);
+static int SProcXvQueryEncodings(ClientPtr);
+static int SProcXvPutVideo(ClientPtr);
+static int SProcXvPutStill(ClientPtr);
+static int SProcXvGetVideo(ClientPtr);
+static int SProcXvGetStill(ClientPtr);
+static int SProcXvGrabPort(ClientPtr);
+static int SProcXvUngrabPort(ClientPtr);
+static int SProcXvSelectVideoNotify(ClientPtr);
+static int SProcXvSelectPortNotify(ClientPtr);
+static int SProcXvStopVideo(ClientPtr);
+static int SProcXvSetPortAttribute(ClientPtr);
+static int SProcXvGetPortAttribute(ClientPtr);
+static int SProcXvQueryBestSize(ClientPtr);
+static int SProcXvQueryPortAttributes(ClientPtr);
+static int SProcXvPutImage(ClientPtr);
+#ifdef MITSHM
+static int SProcXvShmPutImage(ClientPtr);
+#endif
+static int SProcXvQueryImageAttributes(ClientPtr);
+static int SProcXvListImageFormats(ClientPtr);
+
+static int SWriteQueryAdaptorsReply(ClientPtr, xvQueryAdaptorsReply *);
+static int SWriteQueryExtensionReply(ClientPtr, xvQueryExtensionReply *);
+static int SWriteQueryEncodingsReply(ClientPtr, xvQueryEncodingsReply *);
+static int SWriteAdaptorInfo(ClientPtr, xvAdaptorInfo *);
+static int SWriteEncodingInfo(ClientPtr, xvEncodingInfo *);
+static int SWriteFormat(ClientPtr, xvFormat *);
+static int SWriteAttributeInfo(ClientPtr, xvAttributeInfo *);
+static int SWriteGrabPortReply(ClientPtr, xvGrabPortReply *);
+static int SWriteGetPortAttributeReply(ClientPtr, xvGetPortAttributeReply *);
+static int SWriteQueryBestSizeReply(ClientPtr, xvQueryBestSizeReply *);
+static int SWriteQueryPortAttributesReply(
+ ClientPtr, xvQueryPortAttributesReply *);
+static int SWriteQueryImageAttributesReply(
+ ClientPtr, xvQueryImageAttributesReply*);
+static int SWriteListImageFormatsReply(ClientPtr, xvListImageFormatsReply*);
+static int SWriteImageFormatInfo(ClientPtr, xvImageFormatInfo*);
+
+#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
+
+/*
+** ProcXvDispatch
+**
+**
+**
+*/
+
+int
+ProcXvDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+
+ UpdateCurrentTime();
+
+ switch (stuff->data)
+ {
+ case xv_QueryExtension: return(ProcXvQueryExtension(client));
+ case xv_QueryAdaptors: return(ProcXvQueryAdaptors(client));
+ case xv_QueryEncodings: return(ProcXvQueryEncodings(client));
+ case xv_PutVideo:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ return(XineramaXvPutVideo(client));
+ else
+#endif
+ return(ProcXvPutVideo(client));
+ case xv_PutStill:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ return(XineramaXvPutStill(client));
+ else
+#endif
+ return(ProcXvPutStill(client));
+ case xv_GetVideo: return(ProcXvGetVideo(client));
+ case xv_GetStill: return(ProcXvGetStill(client));
+ case xv_GrabPort: return(ProcXvGrabPort(client));
+ case xv_UngrabPort: return(ProcXvUngrabPort(client));
+ case xv_SelectVideoNotify: return(ProcXvSelectVideoNotify(client));
+ case xv_SelectPortNotify: return(ProcXvSelectPortNotify(client));
+ case xv_StopVideo:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ return(XineramaXvStopVideo(client));
+ else
+#endif
+ return(ProcXvStopVideo(client));
+ case xv_SetPortAttribute:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ return(XineramaXvSetPortAttribute(client));
+ else
+#endif
+ return(ProcXvSetPortAttribute(client));
+ case xv_GetPortAttribute: return(ProcXvGetPortAttribute(client));
+ case xv_QueryBestSize: return(ProcXvQueryBestSize(client));
+ case xv_QueryPortAttributes: return(ProcXvQueryPortAttributes(client));
+ case xv_PutImage:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ return(XineramaXvPutImage(client));
+ else
+#endif
+ return(ProcXvPutImage(client));
+#ifdef MITSHM
+ case xv_ShmPutImage:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ return(XineramaXvShmPutImage(client));
+ else
+#endif
+ return(ProcXvShmPutImage(client));
+#endif
+ case xv_QueryImageAttributes: return(ProcXvQueryImageAttributes(client));
+ case xv_ListImageFormats: return(ProcXvListImageFormats(client));
+ default:
+ if (stuff->data < xvNumRequests)
+ {
+ SendErrorToClient(client, XvReqCode, stuff->data, 0,
+ BadImplementation);
+ return(BadImplementation);
+ }
+ else
+ {
+ SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
+ return(BadRequest);
+ }
+ }
+}
+
+int
+SProcXvDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+
+ UpdateCurrentTime();
+
+ switch (stuff->data)
+ {
+ case xv_QueryExtension: return(SProcXvQueryExtension(client));
+ case xv_QueryAdaptors: return(SProcXvQueryAdaptors(client));
+ case xv_QueryEncodings: return(SProcXvQueryEncodings(client));
+ case xv_PutVideo: return(SProcXvPutVideo(client));
+ case xv_PutStill: return(SProcXvPutStill(client));
+ case xv_GetVideo: return(SProcXvGetVideo(client));
+ case xv_GetStill: return(SProcXvGetStill(client));
+ case xv_GrabPort: return(SProcXvGrabPort(client));
+ case xv_UngrabPort: return(SProcXvUngrabPort(client));
+ case xv_SelectVideoNotify: return(SProcXvSelectVideoNotify(client));
+ case xv_SelectPortNotify: return(SProcXvSelectPortNotify(client));
+ case xv_StopVideo: return(SProcXvStopVideo(client));
+ case xv_SetPortAttribute: return(SProcXvSetPortAttribute(client));
+ case xv_GetPortAttribute: return(SProcXvGetPortAttribute(client));
+ case xv_QueryBestSize: return(SProcXvQueryBestSize(client));
+ case xv_QueryPortAttributes: return(SProcXvQueryPortAttributes(client));
+ case xv_PutImage: return(SProcXvPutImage(client));
+#ifdef MITSHM
+ case xv_ShmPutImage: return(SProcXvShmPutImage(client));
+#endif
+ case xv_QueryImageAttributes: return(SProcXvQueryImageAttributes(client));
+ case xv_ListImageFormats: return(SProcXvListImageFormats(client));
+ default:
+ if (stuff->data < xvNumRequests)
+ {
+ SendErrorToClient(client, XvReqCode, stuff->data, 0,
+ BadImplementation);
+ return(BadImplementation);
+ }
+ else
+ {
+ SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
+ return(BadRequest);
+ }
+ }
+}
+
+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;
+ int na;
+ XvAdaptorPtr pa;
+ int nf;
+ XvFormatPtr pf;
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ XvScreenPtr pxvs;
+
+ REQUEST(xvQueryAdaptorsReq);
+ REQUEST_SIZE_MATCH(xvQueryAdaptorsReq);
+
+ if(!(pWin = (WindowPtr)LookupWindow(stuff->window, client) ))
+ {
+ client->errorValue = stuff->window;
+ return (BadWindow);
+ }
+
+ pScreen = pWin->drawable.pScreen;
+ pxvs = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr;
+
+ 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 += (strlen(pa->name) + 3) & ~3;
+ totalSize += pa->nFormats * sz_xvFormat;
+ pa++;
+ }
+
+ rep.length = totalSize >> 2;
+
+ _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 = strlen(pa->name);
+ ainfo.num_formats = pa->nFormats;
+
+ _WriteAdaptorInfo(client, &ainfo);
+
+ WriteToClient(client, ainfo.name_size, pa->name);
+
+ nf = pa->nFormats;
+ pf = pa->pFormats;
+ while (nf--)
+ {
+ format.depth = pf->depth;
+ format.visual = pf->visual;
+ _WriteFormat(client, &format);
+ pf++;
+ }
+
+ pa++;
+
+ }
+
+ return (client->noClientException);
+
+}
+
+static int
+ProcXvQueryEncodings(ClientPtr client)
+{
+ xvEncodingInfo einfo;
+ xvQueryEncodingsReply rep;
+ int totalSize;
+ XvPortPtr pPort;
+ int ne;
+ XvEncodingPtr pe;
+ int status;
+
+ REQUEST(xvQueryEncodingsReq);
+ REQUEST_SIZE_MATCH(xvQueryEncodingsReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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 += (strlen(pe->name) + 3) & ~3;
+ pe++;
+ }
+
+ rep.length = totalSize >> 2;
+
+ _WriteQueryEncodingsReply(client, &rep);
+
+ ne = pPort->pAdaptor->nEncodings;
+ pe = pPort->pAdaptor->pEncodings;
+ while (ne--)
+ {
+ einfo.encoding = pe->id;
+ einfo.name_size = 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, einfo.name_size, pe->name);
+ pe++;
+ }
+
+ return (client->noClientException);
+
+}
+
+static int
+ProcXvPutVideo(ClientPtr client)
+{
+ register DrawablePtr pDraw;
+ XvPortPtr pPort;
+ register GCPtr pGC;
+ int status;
+
+ REQUEST(xvPutVideoReq);
+ REQUEST_SIZE_MATCH(xvPutVideoReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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 = XVCALL(diMatchPort)(pPort, pDraw);
+ if (status != Success)
+ {
+ return status;
+ }
+
+ return XVCALL(diPutVideo)(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)
+{
+ register DrawablePtr pDraw;
+ XvPortPtr pPort;
+ register GCPtr pGC;
+ int status;
+
+ REQUEST(xvPutStillReq);
+ REQUEST_SIZE_MATCH(xvPutStillReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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 = XVCALL(diMatchPort)(pPort, pDraw);
+ if (status != Success)
+ {
+ return status;
+ }
+
+ return XVCALL(diPutStill)(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)
+{
+ register DrawablePtr pDraw;
+ XvPortPtr pPort;
+ register GCPtr pGC;
+ int status;
+
+ REQUEST(xvGetVideoReq);
+ REQUEST_SIZE_MATCH(xvGetVideoReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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 = XVCALL(diMatchPort)(pPort, pDraw);
+ if (status != Success)
+ {
+ return status;
+ }
+
+ return XVCALL(diGetVideo)(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)
+{
+ register DrawablePtr pDraw;
+ XvPortPtr pPort;
+ register GCPtr pGC;
+ int status;
+
+ REQUEST(xvGetStillReq);
+ REQUEST_SIZE_MATCH(xvGetStillReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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 = XVCALL(diMatchPort)(pPort, pDraw);
+ if (status != Success)
+ {
+ return status;
+ }
+
+ return XVCALL(diGetStill)(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)
+{
+ register DrawablePtr pDraw;
+ REQUEST(xvSelectVideoNotifyReq);
+ REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq);
+
+ if(!(pDraw = (DrawablePtr)LOOKUP_DRAWABLE(stuff->drawable, client) ))
+ {
+ client->errorValue = stuff->drawable;
+ return (BadWindow);
+ }
+
+ return XVCALL(diSelectVideoNotify)(client, pDraw, stuff->onoff);
+
+}
+
+static int
+ProcXvSelectPortNotify(ClientPtr client)
+{
+ int status;
+ XvPortPtr pPort;
+ REQUEST(xvSelectPortNotifyReq);
+ REQUEST_SIZE_MATCH(xvSelectPortNotifyReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ return XVCALL(diSelectPortNotify)(client, pPort, stuff->onoff);
+
+}
+
+static int
+ProcXvGrabPort(ClientPtr client)
+{
+ int result, status;
+ XvPortPtr pPort;
+ xvGrabPortReply rep;
+ REQUEST(xvGrabPortReq);
+ REQUEST_SIZE_MATCH(xvGrabPortReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ status = XVCALL(diGrabPort)(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);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ return XVCALL(diUngrabPort)(client, pPort, stuff->time);
+
+}
+
+
+static int
+ProcXvStopVideo(ClientPtr client)
+{
+ int status;
+ register DrawablePtr pDraw;
+ XvPortPtr pPort;
+ REQUEST(xvStopVideoReq);
+ REQUEST_SIZE_MATCH(xvStopVideoReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ if(!(pDraw = LOOKUP_DRAWABLE(stuff->drawable, client) ))
+ {
+ client->errorValue = stuff->drawable;
+ return (BadDrawable);
+ }
+
+ return XVCALL(diStopVideo)(client, pPort, pDraw);
+
+}
+
+static int
+ProcXvSetPortAttribute(ClientPtr client)
+{
+ int status;
+ XvPortPtr pPort;
+ REQUEST(xvSetPortAttributeReq);
+ REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ if (!ValidAtom(stuff->attribute))
+ {
+ client->errorValue = stuff->attribute;
+ return(BadAtom);
+ }
+
+ status = XVCALL(diSetPortAttribute)(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);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ if (!ValidAtom(stuff->attribute))
+ {
+ client->errorValue = stuff->attribute;
+ return(BadAtom);
+ }
+
+ status = XVCALL(diGetPortAttribute)(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);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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 < rep.num_attributes; i++, pAtt++)
+ {
+ rep.text_size += (strlen(pAtt->name) + 1 + 3) & ~3L;
+ }
+
+ rep.length = (rep.num_attributes * sz_xvAttributeInfo) + rep.text_size;
+ rep.length >>= 2;
+
+ _WriteQueryPortAttributesReply(client, &rep);
+
+ for(i = 0, pAtt = pPort->pAdaptor->pAttributes;
+ i < rep.num_attributes; 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 = (size + 3) & ~3L;
+
+ _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, pGC, client);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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 = XVCALL(diMatchPort)(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 = (size + 3) >> 2;
+
+ if((width < stuff->width) || (height < stuff->height))
+ return BadValue;
+
+ if(client->req_len < size)
+ return BadLength;
+
+ return XVCALL(diPutImage)(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 BadShmSegCode;
+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, pGC, client);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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 = XVCALL(diMatchPort)(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;
+
+ if(!(shmdesc = (ShmDescPtr)LookupIDByType(stuff->shmseg, ShmSegType)))
+ {
+ client->errorValue = stuff->shmseg;
+ return BadShmSegCode;
+ }
+
+ 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 = XVCALL(diPutImage)(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.sequenceNumber = client->sequence;
+ ev.minorEvent = xv_ShmPutImage;
+ ev.majorEvent = XvReqCode;
+ ev.shmseg = stuff->shmseg;
+ ev.offset = stuff->offset;
+ WriteEventsToClient(client, 1, (xEvent *) &ev);
+ }
+
+ return status;
+}
+#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;
+ REQUEST(xvQueryImageAttributesReq);
+
+ REQUEST_SIZE_MATCH(xvQueryImageAttributesReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ 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 = xalloc(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 = 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, rep.length);
+ WriteToClient(client, rep.length << 2, (char*)offsets);
+
+ xfree(offsets);
+
+ return Success;
+}
+
+static int
+ProcXvListImageFormats(ClientPtr client)
+{
+ XvPortPtr pPort;
+ XvImagePtr pImage;
+ int i;
+ xvListImageFormatsReply rep;
+ xvImageFormatInfo info;
+ REQUEST(xvListImageFormatsReq);
+
+ REQUEST_SIZE_MATCH(xvListImageFormatsReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.num_formats = pPort->pAdaptor->nImages;
+ rep.length = rep.num_formats * sz_xvImageFormatInfo >> 2;
+
+ _WriteListImageFormatsReply(client, &rep);
+
+ pImage = pPort->pAdaptor->pImages;
+
+ for(i = 0; i < rep.num_formats; 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;
+}
+
+
+
+/* Swapped Procs */
+
+static int
+SProcXvQueryExtension(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvQueryExtensionReq);
+ swaps(&stuff->length, n);
+ return ProcXvQueryExtension(client);
+}
+
+static int
+SProcXvQueryAdaptors(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvQueryAdaptorsReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ return ProcXvQueryAdaptors(client);
+}
+
+static int
+SProcXvQueryEncodings(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvQueryEncodingsReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->port, n);
+ return ProcXvQueryEncodings(client);
+}
+
+static int
+SProcXvGrabPort(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvGrabPortReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->port, n);
+ swapl(&stuff->time, n);
+ return ProcXvGrabPort(client);
+}
+
+static int
+SProcXvUngrabPort(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvUngrabPortReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->port, n);
+ swapl(&stuff->time, n);
+ return ProcXvUngrabPort(client);
+}
+
+static int
+SProcXvPutVideo(ClientPtr client)
+{
+ register 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 ProcXvPutVideo(client);
+}
+
+static int
+SProcXvPutStill(ClientPtr client)
+{
+ register 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 ProcXvPutStill(client);
+}
+
+static int
+SProcXvGetVideo(ClientPtr client)
+{
+ register 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 ProcXvGetVideo(client);
+}
+
+static int
+SProcXvGetStill(ClientPtr client)
+{
+ register 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 ProcXvGetStill(client);
+}
+
+static int
+SProcXvPutImage(ClientPtr client)
+{
+ register 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 ProcXvPutImage(client);
+}
+
+#ifdef MITSHM
+static int
+SProcXvShmPutImage(ClientPtr client)
+{
+ register 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);
+ 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->offset, n);
+ swaps(&stuff->width, n);
+ swaps(&stuff->height, n);
+ return ProcXvShmPutImage(client);
+}
+#endif
+
+
+static int
+SProcXvSelectVideoNotify(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvSelectVideoNotifyReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->drawable, n);
+ return ProcXvSelectVideoNotify(client);
+}
+
+static int
+SProcXvSelectPortNotify(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvSelectPortNotifyReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->port, n);
+ return ProcXvSelectPortNotify(client);
+}
+
+static int
+SProcXvStopVideo(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvStopVideoReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->port, n);
+ swapl(&stuff->drawable, n);
+ return ProcXvStopVideo(client);
+}
+
+static int
+SProcXvSetPortAttribute(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvSetPortAttributeReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->port, n);
+ swapl(&stuff->attribute, n);
+ return ProcXvSetPortAttribute(client);
+}
+
+static int
+SProcXvGetPortAttribute(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvGetPortAttributeReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->port, n);
+ swapl(&stuff->attribute, n);
+ return ProcXvGetPortAttribute(client);
+}
+
+static int
+SProcXvQueryBestSize(ClientPtr client)
+{
+ register 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 ProcXvQueryBestSize(client);
+}
+
+static int
+SProcXvQueryPortAttributes(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvQueryPortAttributesReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->port, n);
+ return ProcXvQueryPortAttributes(client);
+}
+
+static int
+SProcXvQueryImageAttributes(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvQueryImageAttributesReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->id, n);
+ swaps(&stuff->width, n);
+ swaps(&stuff->width, n);
+ return ProcXvQueryImageAttributes(client);
+}
+
+static int
+SProcXvListImageFormats(ClientPtr client)
+{
+ register char n;
+ REQUEST(xvListImageFormatsReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->port, n);
+ return ProcXvListImageFormats(client);
+}
+
+
+static int
+SWriteQueryExtensionReply(
+ ClientPtr client,
+ xvQueryExtensionReply *rep
+){
+ register 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
+){
+ register 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
+){
+ register 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
+){
+ register 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
+){
+ register 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
+){
+ register char n;
+
+ swapl(&pFormat->visual, n);
+ (void)WriteToClient(client, sz_xvFormat, (char *)pFormat);
+
+ return Success;
+}
+
+static int
+SWriteAttributeInfo(
+ ClientPtr client,
+ xvAttributeInfo *pAtt
+){
+ register 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
+){
+ register 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
+){
+ register 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
+){
+ register 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
+){
+ register 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
+){
+ register 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
+){
+ register 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
+){
+ register char n;
+
+ swaps(&rep->sequenceNumber, n);
+ swapl(&rep->length, n);
+ swapl(&rep->num_formats, n);
+
+ (void)WriteToClient(client, sz_xvListImageFormatsReply, (char *)&rep);
+
+ return Success;
+}
+
+
+#ifdef PANORAMIX
+
+
+
+
+static int
+XineramaXvStopVideo(ClientPtr client)
+{
+ int result = Success, i;
+ PanoramiXRes *draw, *port;
+ REQUEST(xvStopVideoReq);
+ REQUEST_SIZE_MATCH(xvStopVideoReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+ return BadDrawable;
+
+ if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->port, XvXRTPort, SecurityReadAccess)))
+ return _XvBadPort;
+
+ 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 = Success, i;
+
+ REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
+
+ if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->port, XvXRTPort, SecurityReadAccess)))
+ return _XvBadPort;
+
+ 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 = Success, i, x, y;
+
+ REQUEST_SIZE_MATCH(xvShmPutImageReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+ return BadDrawable;
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, SecurityReadAccess)))
+ return BadGC;
+
+ if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->port, XvXRTPort, SecurityReadAccess)))
+ return _XvBadPort;
+
+ 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 -= panoramiXdataPtr[i].x;
+ stuff->drw_y -= panoramiXdataPtr[i].y;
+ }
+ stuff->send_event = (send_event && !i) ? 1 : 0;
+
+ result = ProcXvShmPutImage(client);
+ }
+ }
+ return result;
+}
+#endif
+
+static int
+XineramaXvPutImage(ClientPtr client)
+{
+ REQUEST(xvPutImageReq);
+ PanoramiXRes *draw, *gc, *port;
+ Bool isRoot;
+ int result = Success, i, x, y;
+
+ REQUEST_AT_LEAST_SIZE(xvPutImageReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+ return BadDrawable;
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, SecurityReadAccess)))
+ return BadGC;
+
+ if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->port, XvXRTPort, SecurityReadAccess)))
+ return _XvBadPort;
+
+ 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 -= panoramiXdataPtr[i].x;
+ stuff->drw_y -= panoramiXdataPtr[i].y;
+ }
+
+ result = ProcXvPutImage(client);
+ }
+ }
+ return result;
+}
+
+static int
+XineramaXvPutVideo(ClientPtr client)
+{
+ REQUEST(xvPutImageReq);
+ PanoramiXRes *draw, *gc, *port;
+ Bool isRoot;
+ int result = Success, i, x, y;
+
+ REQUEST_AT_LEAST_SIZE(xvPutVideoReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+ return BadDrawable;
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, SecurityReadAccess)))
+ return BadGC;
+
+ if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->port, XvXRTPort, SecurityReadAccess)))
+ return _XvBadPort;
+
+ 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 -= panoramiXdataPtr[i].x;
+ stuff->drw_y -= panoramiXdataPtr[i].y;
+ }
+
+ result = ProcXvPutVideo(client);
+ }
+ }
+ return result;
+}
+
+static int
+XineramaXvPutStill(ClientPtr client)
+{
+ REQUEST(xvPutImageReq);
+ PanoramiXRes *draw, *gc, *port;
+ Bool isRoot;
+ int result = Success, i, x, y;
+
+ REQUEST_AT_LEAST_SIZE(xvPutImageReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+ return BadDrawable;
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, SecurityReadAccess)))
+ return BadGC;
+
+ if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->port, XvXRTPort, SecurityReadAccess)))
+ return _XvBadPort;
+
+ 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 -= panoramiXdataPtr[i].x;
+ stuff->drw_y -= panoramiXdataPtr[i].y;
+ }
+
+ result = ProcXvPutStill(client);
+ }
+ }
+ return result;
+}
+
+
+void XineramifyXv(void)
+{
+ ScreenPtr pScreen, screen0 = screenInfo.screens[0];
+ XvScreenPtr xvsp0 = (XvScreenPtr)screen0->devPrivates[XvScreenIndex].ptr;
+ XvAdaptorPtr refAdapt, pAdapt;
+ XvAttributePtr pAttr;
+ XvScreenPtr xvsp;
+ Bool isOverlay, hasOverlay;
+ PanoramiXRes *port;
+ XvAdaptorPtr MatchingAdaptors[MAXSCREENS];
+ int i, j, k, l;
+
+ XvXRTPort = CreateNewResourceType(XineramaDeleteResource);
+
+ if(!xvsp0) return;
+
+ for(i = 0; i < xvsp0->nAdaptors; i++) {
+ refAdapt = xvsp0->pAdaptors + i;
+
+ bzero(MatchingAdaptors, sizeof(XvAdaptorPtr) * MAXSCREENS);
+
+ MatchingAdaptors[0] = refAdapt;
+
+ if(!(refAdapt->type & XvInputMask)) continue;
+
+ isOverlay = FALSE;
+ for(j = 0; j < refAdapt->nAttributes; j++) {
+ pAttr = refAdapt->pAttributes + j;
+ if(!strcmp(pAttr->name, "XV_COLORKEY")) {
+ isOverlay = TRUE;
+ break;
+ }
+ }
+
+ for(j = 1; j < PanoramiXNumScreens; j++) {
+ pScreen = screenInfo.screens[j];
+ xvsp = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr;
+
+ /* Do not try to go on if xv is not supported on this screen */
+ if (xvsp==NULL) continue ;
+
+ /* if the adaptor has the same name it's a perfect match */
+ for(k = 0; k < xvsp->nAdaptors; k++) {
+ pAdapt = xvsp->pAdaptors + k;
+ if(!strcmp(refAdapt->name, pAdapt->name)) {
+ MatchingAdaptors[j] = pAdapt;
+ break;
+ }
+ }
+ if(MatchingAdaptors[j]) continue; /* found it */
+
+ /* otherwise we only look for XvImage adaptors */
+ if(!(refAdapt->type & XvImageMask)) continue;
+ if(refAdapt->nImages <= 0) continue;
+
+ /* prefer overlay/overlay non-overlay/non-overlay pairing */
+ for(k = 0; k < xvsp->nAdaptors; k++) {
+ pAdapt = xvsp->pAdaptors + k;
+ if((pAdapt->type & XvImageMask) && (pAdapt->nImages > 0)) {
+ hasOverlay = FALSE;
+ for(l = 0; l < pAdapt->nAttributes; l++) {
+ if(!strcmp(pAdapt->name, "XV_COLORKEY")) {
+ hasOverlay = TRUE;
+ break;
+ }
+ }
+ if(isOverlay && hasOverlay) {
+ MatchingAdaptors[j] = pAdapt;
+ break;
+ }
+ else if(!isOverlay && !hasOverlay) {
+ MatchingAdaptors[j] = pAdapt;
+ break;
+ }
+ }
+ }
+
+ if(MatchingAdaptors[j]) continue; /* found it */
+
+ /* but we'll take any XvImage pairing if we can get it */
+
+ for(k = 0; k < xvsp->nAdaptors; k++) {
+ pAdapt = xvsp->pAdaptors + k;
+ if((pAdapt->type & XvImageMask) && (pAdapt->nImages > 0)) {
+ MatchingAdaptors[j] = pAdapt;
+ break;
+ }
+ }
+ }
+
+ /* now create a resource for each port */
+ for(j = 0; j < refAdapt->nPorts; j++) {
+ if(!(port = xalloc(sizeof(PanoramiXRes))))
+ break;
+ port->info[0].id = MatchingAdaptors[0]->base_id + j;
+ AddResource(port->info[0].id, XvXRTPort, port);
+
+ for(k = 1; 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;
+ }
+ }
+ }
+}
+
+#endif