summaryrefslogtreecommitdiff
path: root/render
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:48:57 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:48:57 +0000
commit9508a382f8a9f241dab097d921b6d290c1c3a776 (patch)
treefa456480bae7040c3f971a70b390f2d091c680b5 /render
parentded6147bfb5d75ff1e67c858040a628b61bc17d1 (diff)
Initial revision
Diffstat (limited to 'render')
-rw-r--r--render/animcur.c400
-rw-r--r--render/filter.c263
-rw-r--r--render/glyph.c416
-rw-r--r--render/glyphstr.h127
-rw-r--r--render/miglyph.c239
-rw-r--r--render/miindex.c353
-rw-r--r--render/mipict.c516
-rw-r--r--render/mipict.h210
-rw-r--r--render/mirect.c181
-rw-r--r--render/mitrap.c196
-rw-r--r--render/mitri.c352
-rw-r--r--render/picture.c1305
-rw-r--r--render/picture.h228
-rw-r--r--render/picturestr.h501
-rw-r--r--render/render.c2584
15 files changed, 7871 insertions, 0 deletions
diff --git a/render/animcur.c b/render/animcur.c
new file mode 100644
index 000000000..7a4e22d59
--- /dev/null
+++ b/render/animcur.c
@@ -0,0 +1,400 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/animcur.c,v 1.5 2002/12/22 15:07:12 tsi 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.
+ */
+
+/*
+ * Animated cursors for X. Not specific to Render in any way, but
+ * stuck there because Render has the other cool cursor extension.
+ * Besides, everyone has Render.
+ *
+ * Implemented as a simple layer over the core cursor code; it
+ * creates composite cursors out of a set of static cursors and
+ * delta times between each image.
+ */
+
+#include "X.h"
+#include "Xmd.h"
+#include "servermd.h"
+#include "scrnintstr.h"
+#include "dixstruct.h"
+#include "cursorstr.h"
+#include "dixfontstr.h"
+#include "opaque.h"
+#include "picturestr.h"
+
+typedef struct _AnimCurElt {
+ CursorPtr pCursor; /* cursor to show */
+ CARD32 delay; /* in ms */
+} AnimCurElt;
+
+typedef struct _AnimCur {
+ int nelt; /* number of elements in the elts array */
+ AnimCurElt *elts; /* actually allocated right after the structure */
+} AnimCurRec, *AnimCurPtr;
+
+typedef struct _AnimScrPriv {
+ CursorPtr pCursor;
+ int elt;
+ CARD32 time;
+
+ CloseScreenProcPtr CloseScreen;
+
+ ScreenBlockHandlerProcPtr BlockHandler;
+
+ CursorLimitsProcPtr CursorLimits;
+ DisplayCursorProcPtr DisplayCursor;
+ SetCursorPositionProcPtr SetCursorPosition;
+ RealizeCursorProcPtr RealizeCursor;
+ UnrealizeCursorProcPtr UnrealizeCursor;
+ RecolorCursorProcPtr RecolorCursor;
+} AnimCurScreenRec, *AnimCurScreenPtr;
+
+typedef struct _AnimCurState {
+ CursorPtr pCursor;
+ ScreenPtr pScreen;
+ int elt;
+ CARD32 time;
+} AnimCurStateRec, *AnimCurStatePtr;
+
+static AnimCurStateRec animCurState;
+
+static unsigned char empty[4];
+
+static CursorBits animCursorBits = {
+ empty, empty, 2, 1, 1, 0, 0, 1
+};
+
+int AnimCurScreenPrivateIndex = -1;
+int AnimCurGeneration;
+
+#define IsAnimCur(c) ((c)->bits == &animCursorBits)
+#define GetAnimCur(c) ((AnimCurPtr) ((c) + 1))
+#define GetAnimCurScreen(s) ((AnimCurScreenPtr) ((s)->devPrivates[AnimCurScreenPrivateIndex].ptr))
+#define GetAnimCurScreenIfSet(s) ((AnimCurScreenPrivateIndex != -1) ? GetAnimCurScreen(s) : NULL)
+#define SetAnimCurScreen(s,p) ((s)->devPrivates[AnimCurScreenPrivateIndex].ptr = (pointer) (p))
+
+#define Wrap(as,s,elt,func) (((as)->elt = (s)->elt), (s)->elt = func)
+#define Unwrap(as,s,elt) ((s)->elt = (as)->elt)
+
+static Bool
+AnimCurDisplayCursor (ScreenPtr pScreen,
+ CursorPtr pCursor);
+
+static Bool
+AnimCurSetCursorPosition (ScreenPtr pScreen,
+ int x,
+ int y,
+ Bool generateEvent);
+
+static Bool
+AnimCurCloseScreen (int index, ScreenPtr pScreen)
+{
+ AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
+ Bool ret;
+
+ Unwrap(as, pScreen, CloseScreen);
+
+ Unwrap(as, pScreen, BlockHandler);
+
+ Unwrap(as, pScreen, CursorLimits);
+ Unwrap(as, pScreen, DisplayCursor);
+ Unwrap(as, pScreen, SetCursorPosition);
+ Unwrap(as, pScreen, RealizeCursor);
+ Unwrap(as, pScreen, UnrealizeCursor);
+ Unwrap(as, pScreen, RecolorCursor);
+ SetAnimCurScreen(pScreen,0);
+ ret = (*pScreen->CloseScreen) (index, pScreen);
+ xfree (as);
+ if (index == 0)
+ AnimCurScreenPrivateIndex = -1;
+ return ret;
+}
+
+static void
+AnimCurCursorLimits (ScreenPtr pScreen,
+ CursorPtr pCursor,
+ BoxPtr pHotBox,
+ BoxPtr pTopLeftBox)
+{
+ AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
+
+ Unwrap (as, pScreen, CursorLimits);
+ if (IsAnimCur(pCursor))
+ {
+ AnimCurPtr ac = GetAnimCur(pCursor);
+
+ (*pScreen->CursorLimits) (pScreen, ac->elts[0].pCursor, pHotBox, pTopLeftBox);
+ }
+ else
+ {
+ (*pScreen->CursorLimits) (pScreen, pCursor, pHotBox, pTopLeftBox);
+ }
+ Wrap (as, pScreen, CursorLimits, AnimCurCursorLimits);
+}
+
+/*
+ * This has to be a screen block handler instead of a generic
+ * block handler so that it is well ordered with respect to the DRI
+ * block handler responsible for releasing the hardware to DRI clients
+ */
+
+static void
+AnimCurScreenBlockHandler (int screenNum,
+ pointer blockData,
+ pointer pTimeout,
+ pointer pReadmask)
+{
+ ScreenPtr pScreen = screenInfo.screens[screenNum];
+ AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
+
+ if (pScreen == animCurState.pScreen)
+ {
+ CARD32 now = GetTimeInMillis ();
+
+ if ((INT32) (now - animCurState.time) >= 0)
+ {
+ AnimCurPtr ac = GetAnimCur(animCurState.pCursor);
+ int elt = (animCurState.elt + 1) % ac->nelt;
+ DisplayCursorProcPtr DisplayCursor;
+
+ /*
+ * Not a simple Unwrap/Wrap as this
+ * isn't called along the DisplayCursor
+ * wrapper chain.
+ */
+ DisplayCursor = pScreen->DisplayCursor;
+ pScreen->DisplayCursor = as->DisplayCursor;
+ (void) (*pScreen->DisplayCursor) (pScreen, ac->elts[elt].pCursor);
+ as->DisplayCursor = pScreen->DisplayCursor;
+ pScreen->DisplayCursor = DisplayCursor;
+
+ animCurState.elt = elt;
+ animCurState.time = now + ac->elts[elt].delay;
+ }
+ AdjustWaitForDelay (pTimeout, animCurState.time - now);
+ }
+ Unwrap (as, pScreen, BlockHandler);
+ (*pScreen->BlockHandler) (screenNum, blockData, pTimeout, pReadmask);
+ Wrap (as, pScreen, BlockHandler, AnimCurScreenBlockHandler);
+}
+
+static Bool
+AnimCurDisplayCursor (ScreenPtr pScreen,
+ CursorPtr pCursor)
+{
+ AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
+ Bool ret;
+
+ Unwrap (as, pScreen, DisplayCursor);
+ if (IsAnimCur(pCursor))
+ {
+ if (pCursor != animCurState.pCursor)
+ {
+ AnimCurPtr ac = GetAnimCur(pCursor);
+
+ ret = (*pScreen->DisplayCursor) (pScreen, ac->elts[0].pCursor);
+ if (ret)
+ {
+ animCurState.elt = 0;
+ animCurState.time = GetTimeInMillis () + ac->elts[0].delay;
+ animCurState.pCursor = pCursor;
+ animCurState.pScreen = pScreen;
+ }
+ }
+ else
+ ret = TRUE;
+ }
+ else
+ {
+ animCurState.pCursor = 0;
+ animCurState.pScreen = 0;
+ ret = (*pScreen->DisplayCursor) (pScreen, pCursor);
+ }
+ Wrap (as, pScreen, DisplayCursor, AnimCurDisplayCursor);
+ return ret;
+}
+
+static Bool
+AnimCurSetCursorPosition (ScreenPtr pScreen,
+ int x,
+ int y,
+ Bool generateEvent)
+{
+ AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
+ Bool ret;
+
+ Unwrap (as, pScreen, SetCursorPosition);
+ if (animCurState.pCursor)
+ animCurState.pScreen = pScreen;
+ ret = (*pScreen->SetCursorPosition) (pScreen, x, y, generateEvent);
+ Wrap (as, pScreen, SetCursorPosition, AnimCurSetCursorPosition);
+ return ret;
+}
+
+static Bool
+AnimCurRealizeCursor (ScreenPtr pScreen,
+ CursorPtr pCursor)
+{
+ AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
+ Bool ret;
+
+ Unwrap (as, pScreen, RealizeCursor);
+ if (IsAnimCur(pCursor))
+ ret = TRUE;
+ else
+ ret = (*pScreen->RealizeCursor) (pScreen, pCursor);
+ Wrap (as, pScreen, RealizeCursor, AnimCurRealizeCursor);
+ return ret;
+}
+
+static Bool
+AnimCurUnrealizeCursor (ScreenPtr pScreen,
+ CursorPtr pCursor)
+{
+ AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
+ Bool ret;
+
+ Unwrap (as, pScreen, UnrealizeCursor);
+ if (IsAnimCur(pCursor))
+ {
+ AnimCurPtr ac = GetAnimCur(pCursor);
+ int i;
+
+ if (pScreen->myNum == 0)
+ for (i = 0; i < ac->nelt; i++)
+ FreeCursor (ac->elts[i].pCursor, 0);
+ ret = TRUE;
+ }
+ else
+ ret = (*pScreen->UnrealizeCursor) (pScreen, pCursor);
+ Wrap (as, pScreen, UnrealizeCursor, AnimCurUnrealizeCursor);
+ return ret;
+}
+
+static void
+AnimCurRecolorCursor (ScreenPtr pScreen,
+ CursorPtr pCursor,
+ Bool displayed)
+{
+ AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
+
+ Unwrap (as, pScreen, RecolorCursor);
+ if (IsAnimCur(pCursor))
+ {
+ AnimCurPtr ac = GetAnimCur(pCursor);
+ int i;
+
+ for (i = 0; i < ac->nelt; i++)
+ (*pScreen->RecolorCursor) (pScreen, ac->elts[i].pCursor,
+ displayed &&
+ animCurState.elt == i);
+ }
+ else
+ (*pScreen->RecolorCursor) (pScreen, pCursor, displayed);
+ Wrap (as, pScreen, RecolorCursor, AnimCurRecolorCursor);
+}
+
+Bool
+AnimCurInit (ScreenPtr pScreen)
+{
+ AnimCurScreenPtr as;
+
+ if (AnimCurGeneration != serverGeneration)
+ {
+ AnimCurScreenPrivateIndex = AllocateScreenPrivateIndex ();
+ if (AnimCurScreenPrivateIndex < 0)
+ return FALSE;
+ AnimCurGeneration = serverGeneration;
+ animCurState.pCursor = 0;
+ animCurState.pScreen = 0;
+ animCurState.elt = 0;
+ animCurState.time = 0;
+ }
+ as = (AnimCurScreenPtr) xalloc (sizeof (AnimCurScreenRec));
+ if (!as)
+ return FALSE;
+ Wrap(as, pScreen, CloseScreen, AnimCurCloseScreen);
+
+ Wrap(as, pScreen, BlockHandler, AnimCurScreenBlockHandler);
+
+ Wrap(as, pScreen, CursorLimits, AnimCurCursorLimits);
+ Wrap(as, pScreen, DisplayCursor, AnimCurDisplayCursor);
+ Wrap(as, pScreen, SetCursorPosition, AnimCurSetCursorPosition);
+ Wrap(as, pScreen, RealizeCursor, AnimCurRealizeCursor);
+ Wrap(as, pScreen, UnrealizeCursor, AnimCurUnrealizeCursor);
+ Wrap(as, pScreen, RecolorCursor, AnimCurRecolorCursor);
+ SetAnimCurScreen(pScreen,as);
+ return TRUE;
+}
+
+int
+AnimCursorCreate (CursorPtr *cursors, CARD32 *deltas, int ncursor, CursorPtr *ppCursor)
+{
+ CursorPtr pCursor;
+ int i;
+ AnimCurPtr ac;
+ AnimCurElt *ae;
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ if (!GetAnimCurScreenIfSet (screenInfo.screens[i]))
+ return BadImplementation;
+
+ for (i = 0; i < ncursor; i++)
+ if (IsAnimCur (cursors[i]))
+ return BadMatch;
+
+ pCursor = (CursorPtr) xalloc (sizeof (CursorRec) +
+ sizeof (AnimCurRec) +
+ ncursor * sizeof (AnimCurElt));
+ if (!pCursor)
+ return BadAlloc;
+ pCursor->bits = &animCursorBits;
+ animCursorBits.refcnt++;
+ pCursor->refcnt = 1;
+
+ pCursor->foreRed = cursors[0]->foreRed;
+ pCursor->foreGreen = cursors[0]->foreGreen;
+ pCursor->foreBlue = cursors[0]->foreBlue;
+
+ pCursor->backRed = cursors[0]->backRed;
+ pCursor->backGreen = cursors[0]->backGreen;
+ pCursor->backBlue = cursors[0]->backBlue;
+
+ /*
+ * Fill in the AnimCurRec
+ */
+ ac = GetAnimCur (pCursor);
+ ac->nelt = ncursor;
+ ac->elts = (AnimCurElt *) (ac + 1);
+ ae = ac->elts;
+
+ for (i = 0; i < ncursor; i++)
+ {
+ cursors[i]->refcnt++;
+ ac->elts[i].pCursor = cursors[i];
+ ac->elts[i].delay = deltas[i];
+ }
+
+ *ppCursor = pCursor;
+ return Success;
+}
diff --git a/render/filter.c b/render/filter.c
new file mode 100644
index 000000000..a2f7563cb
--- /dev/null
+++ b/render/filter.c
@@ -0,0 +1,263 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/filter.c,v 1.1 2002/09/26 02:56:52 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.
+ */
+
+#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"
+
+static char **filterNames;
+static int nfilterNames;
+
+int
+PictureGetFilterId (char *filter, int len, Bool makeit)
+{
+ int i;
+ char *name;
+ char **names;
+
+ if (len < 0)
+ len = strlen (filter);
+ for (i = 0; i < nfilterNames; i++)
+ if (len == strlen (filterNames[i]) &&
+ !strncmp (filterNames[i], filter, len))
+ return i;
+ if (!makeit)
+ return -1;
+ name = xalloc (strlen (filter) + 1);
+ if (!name)
+ return -1;
+ strncpy (name, filter, len);
+ name[len] = '\0';
+ if (filterNames)
+ names = xrealloc (filterNames, (nfilterNames + 1) * sizeof (char *));
+ else
+ names = xalloc (sizeof (char *));
+ if (!names)
+ {
+ xfree (name);
+ return -1;
+ }
+ filterNames = names;
+ i = nfilterNames++;
+ filterNames[i] = name;
+ return i;
+}
+
+static Bool
+PictureSetDefaultIds (void)
+{
+ /* careful here -- this list must match the #define values */
+
+ if (PictureGetFilterId (FilterNearest, -1, TRUE) != PictFilterNearest)
+ return FALSE;
+ if (PictureGetFilterId (FilterBilinear, -1, TRUE) != PictFilterBilinear)
+ return FALSE;
+
+ if (PictureGetFilterId (FilterFast, -1, TRUE) != PictFilterFast)
+ return FALSE;
+ if (PictureGetFilterId (FilterGood, -1, TRUE) != PictFilterGood)
+ return FALSE;
+ if (PictureGetFilterId (FilterBest, -1, TRUE) != PictFilterBest)
+ return FALSE;
+ return TRUE;
+}
+
+char *
+PictureGetFilterName (int id)
+{
+ if (0 <= id && id < nfilterNames)
+ return filterNames[id];
+ else
+ return 0;
+}
+
+static void
+PictureFreeFilterIds (void)
+{
+ int i;
+
+ for (i = 0; i < nfilterNames; i++)
+ xfree (filterNames[i]);
+ xfree (filterNames);
+ nfilterNames = 0;
+ filterNames = 0;
+}
+
+int
+PictureAddFilter (ScreenPtr pScreen, char *filter, xFixed *params, int nparams)
+{
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ int id = PictureGetFilterId (filter, -1, TRUE);
+ int i;
+ PictFilterPtr filters;
+
+ if (id < 0)
+ return -1;
+ /*
+ * It's an error to attempt to reregister a filter
+ */
+ for (i = 0; i < ps->nfilters; i++)
+ if (ps->filters[i].id == id)
+ return -1;
+ if (ps->filters)
+ filters = xrealloc (ps->filters, (ps->nfilters + 1) * sizeof (PictFilterRec));
+ else
+ filters = xalloc (sizeof (PictFilterRec));
+ if (!filters)
+ return -1;
+ ps->filters = filters;
+ i = ps->nfilters++;
+ ps->filters[i].name = PictureGetFilterName (id);
+ ps->filters[i].params = params;
+ ps->filters[i].nparams = nparams;
+ ps->filters[i].id = id;
+ return id;
+}
+
+Bool
+PictureSetFilterAlias (ScreenPtr pScreen, char *filter, char *alias)
+{
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ int filter_id = PictureGetFilterId (filter, -1, FALSE);
+ int alias_id = PictureGetFilterId (alias, -1, TRUE);
+ int i;
+
+ if (filter_id < 0 || alias_id < 0)
+ return FALSE;
+ for (i = 0; i < ps->nfilterAliases; i++)
+ if (ps->filterAliases[i].alias_id == alias_id)
+ break;
+ if (i == ps->nfilterAliases)
+ {
+ PictFilterAliasPtr aliases;
+
+ if (ps->filterAliases)
+ aliases = xrealloc (ps->filterAliases,
+ (ps->nfilterAliases + 1) *
+ sizeof (PictFilterAliasRec));
+ else
+ aliases = xalloc (sizeof (PictFilterAliasRec));
+ if (!aliases)
+ return FALSE;
+ ps->filterAliases = aliases;
+ ps->filterAliases[i].alias = PictureGetFilterName (alias_id);
+ ps->filterAliases[i].alias_id = alias_id;
+ ps->nfilterAliases++;
+ }
+ ps->filterAliases[i].filter_id = filter_id;
+ return TRUE;
+}
+
+PictFilterPtr
+PictureFindFilter (ScreenPtr pScreen, char *name, int len)
+{
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ int id = PictureGetFilterId (name, len, FALSE);
+ int i;
+
+ if (id < 0)
+ return 0;
+ /* Check for an alias, allow them to recurse */
+ for (i = 0; i < ps->nfilterAliases; i++)
+ if (ps->filterAliases[i].alias_id == id)
+ {
+ id = ps->filterAliases[i].filter_id;
+ i = 0;
+ }
+ /* find the filter */
+ for (i = 0; i < ps->nfilters; i++)
+ if (ps->filters[i].id == id)
+ return &ps->filters[i];
+ return 0;
+}
+
+Bool
+PictureSetDefaultFilters (ScreenPtr pScreen)
+{
+ if (!filterNames)
+ if (!PictureSetDefaultIds ())
+ return FALSE;
+ if (PictureAddFilter (pScreen, FilterNearest, 0, 0) < 0)
+ return FALSE;
+ if (PictureAddFilter (pScreen, FilterBilinear, 0, 0) < 0)
+ return FALSE;
+
+ if (!PictureSetFilterAlias (pScreen, FilterNearest, FilterFast))
+ return FALSE;
+ if (!PictureSetFilterAlias (pScreen, FilterBilinear, FilterGood))
+ return FALSE;
+ if (!PictureSetFilterAlias (pScreen, FilterBilinear, FilterBest))
+ return FALSE;
+ return TRUE;
+}
+
+void
+PictureResetFilters (ScreenPtr pScreen)
+{
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+
+ xfree (ps->filters);
+ xfree (ps->filterAliases);
+ PictureFreeFilterIds ();
+}
+
+int
+SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int nparams)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ PictFilterPtr pFilter = PictureFindFilter (pScreen, name, len);
+ xFixed *new_params;
+ int i;
+
+ if (!pFilter)
+ return BadName;
+ if (nparams > pFilter->nparams)
+ return BadMatch;
+ if (pFilter->nparams != pPicture->filter_nparams)
+ {
+ new_params = xalloc (pFilter->nparams * sizeof (xFixed));
+ if (!new_params)
+ return BadAlloc;
+ xfree (pPicture->filter_params);
+ pPicture->filter_params = new_params;
+ pPicture->filter_nparams = pFilter->nparams;
+ }
+ for (i = 0; i < nparams; i++)
+ pPicture->filter_params[i] = params[i];
+ for (; i < pFilter->nparams; i++)
+ pPicture->filter_params[i] = pFilter->params[i];
+ pPicture->filter = pFilter->id;
+ return Success;
+}
diff --git a/render/glyph.c b/render/glyph.c
new file mode 100644
index 000000000..b4f08c223
--- /dev/null
+++ b/render/glyph.c
@@ -0,0 +1,416 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/glyph.c,v 1.6 2001/10/28 03:34:19 tsi 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.
+ */
+
+#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;
+}
+
+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;
+
+ if (!globalGlyphs[fdepth].hashSet)
+ {
+ if (!AllocateGlyphHash (&globalGlyphs[fdepth], &glyphHashSets[0]))
+ return FALSE;
+ }
+ glyphSet = xalloc (sizeof (GlyphSetRec));
+ if (!glyphSet)
+ return FALSE;
+ 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);
+ xfree (glyphSet);
+ }
+ return Success;
+}
diff --git a/render/glyphstr.h b/render/glyphstr.h
new file mode 100644
index 000000000..99f55e3eb
--- /dev/null
+++ b/render/glyphstr.h
@@ -0,0 +1,127 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/glyphstr.h,v 1.4 2001/01/21 21:19:39 tsi 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 "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;
+} GlyphSetRec, *GlyphSetPtr;
+
+typedef struct _GlyphList {
+ INT16 xOff;
+ INT16 yOff;
+ CARD8 len;
+ PictFormatPtr format;
+} GlyphListRec, *GlyphListPtr;
+
+extern GlyphHashRec globalGlyphs[GlyphFormatNum];
+
+GlyphHashSetPtr
+FindGlyphHashSet (CARD32 filled);
+
+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/render/miglyph.c b/render/miglyph.c
new file mode 100644
index 000000000..00b6764d6
--- /dev/null
+++ b/render/miglyph.c
@@ -0,0 +1,239 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/miglyph.c,v 1.6 2000/12/05 03:13:31 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.
+ */
+
+#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/render/miindex.c b/render/miindex.c
new file mode 100644
index 000000000..739348273
--- /dev/null
+++ b/render/miindex.c
@@ -0,0 +1,353 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/miindex.c,v 1.8 2002/11/06 22:45:36 keithp Exp $
+ *
+ * Copyright © 2001 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.
+ */
+
+#ifndef _MIINDEX_H_
+#define _MIINDEX_H_
+
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+#include "colormapst.h"
+
+#define NUM_CUBE_LEVELS 4
+#define NUM_GRAY_LEVELS 13
+
+static Bool
+miBuildRenderColormap (ColormapPtr pColormap, Pixel *pixels, int *nump)
+{
+ int r, g, b;
+ unsigned short red, green, blue;
+ Pixel pixel;
+ Bool used[MI_MAX_INDEXED];
+ int needed;
+ int policy;
+ int cube, gray;
+ int i, n;
+
+ if (pColormap->mid != pColormap->pScreen->defColormap)
+ {
+ policy = PictureCmapPolicyAll;
+ }
+ else
+ {
+ int avail = pColormap->pVisual->ColormapEntries;
+ policy = PictureCmapPolicy;
+ if (policy == PictureCmapPolicyDefault)
+ {
+ if (avail >= 256 && (pColormap->pVisual->class|DynamicClass) == PseudoColor)
+ policy = PictureCmapPolicyColor;
+ else if (avail >= 64)
+ policy = PictureCmapPolicyGray;
+ else
+ policy = PictureCmapPolicyMono;
+ }
+ }
+ /*
+ * Make sure enough cells are free for the chosen policy
+ */
+ for (;;)
+ {
+ switch (policy) {
+ case PictureCmapPolicyAll:
+ needed = 0;
+ break;
+ case PictureCmapPolicyColor:
+ needed = 71;
+ break;
+ case PictureCmapPolicyGray:
+ needed = 11;
+ break;
+ case PictureCmapPolicyMono:
+ default:
+ needed = 0;
+ break;
+ }
+ if (needed <= pColormap->freeRed)
+ break;
+ policy--;
+ }
+
+ /*
+ * Compute size of cube and gray ramps
+ */
+ cube = gray = 0;
+ switch (policy) {
+ case PictureCmapPolicyAll:
+ /*
+ * Allocate as big a cube as possible
+ */
+ if ((pColormap->pVisual->class|DynamicClass) == PseudoColor)
+ {
+ for (cube = 1; cube * cube * cube < pColormap->pVisual->ColormapEntries; cube++)
+ ;
+ cube--;
+ if (cube == 1)
+ cube = 0;
+ }
+ else
+ cube = 0;
+ /*
+ * Figure out how many gray levels to use so that they
+ * line up neatly with the cube
+ */
+ if (cube)
+ {
+ needed = pColormap->pVisual->ColormapEntries - (cube*cube*cube);
+ /* levels to fill in with */
+ gray = needed / (cube - 1);
+ /* total levels */
+ gray = (gray + 1) * (cube - 1) + 1;
+ }
+ else
+ gray = pColormap->pVisual->ColormapEntries;
+ break;
+
+ case PictureCmapPolicyColor:
+ cube = NUM_CUBE_LEVELS;
+ /* fall through ... */
+ case PictureCmapPolicyGray:
+ gray = NUM_GRAY_LEVELS;
+ break;
+ case PictureCmapPolicyMono:
+ default:
+ gray = 2;
+ break;
+ }
+
+ memset (used, '\0', pColormap->pVisual->ColormapEntries * sizeof (Bool));
+ for (r = 0; r < cube; r++)
+ for (g = 0; g < cube; g++)
+ for (b = 0; b < cube; b++)
+ {
+ red = (r * 65535 + (cube-1)/2) / (cube - 1);
+ green = (g * 65535 + (cube-1)/2) / (cube - 1);
+ blue = (b * 65535 + (cube-1)/2) / (cube - 1);
+ if (AllocColor (pColormap, &red, &green,
+ &blue, &pixel, 0) != Success)
+ return FALSE;
+ used[pixel] = TRUE;
+ }
+ for (g = 0; g < gray; g++)
+ {
+ red = green = blue = (g * 65535 + (gray-1)/2) / (gray - 1);
+ if (AllocColor (pColormap, &red, &green, &blue, &pixel, 0) != Success)
+ return FALSE;
+ used[pixel] = TRUE;
+ }
+ n = 0;
+ for (i = 0; i < pColormap->pVisual->ColormapEntries; i++)
+ if (used[i])
+ pixels[n++] = i;
+
+ *nump = n;
+
+ return TRUE;
+}
+
+/* 0 <= red, green, blue < 32 */
+static Pixel
+FindBestColor (miIndexedPtr pIndexed, Pixel *pixels, int num,
+ int red, int green, int blue)
+{
+ Pixel best = pixels[0];
+ int bestDist = 1 << 30;
+ int dist;
+ int dr, dg, db;
+ while (num--)
+ {
+ Pixel pixel = *pixels++;
+ CARD32 v = pIndexed->rgba[pixel];
+
+ dr = ((v >> 19) & 0x1f);
+ dg = ((v >> 11) & 0x1f);
+ db = ((v >> 3) & 0x1f);
+ dr = dr - red;
+ dg = dg - green;
+ db = db - blue;
+ dist = dr * dr + dg * dg + db * db;
+ if (dist < bestDist)
+ {
+ bestDist = dist;
+ best = pixel;
+ }
+ }
+ return best;
+}
+
+/* 0 <= gray < 32768 */
+static Pixel
+FindBestGray (miIndexedPtr pIndexed, Pixel *pixels, int num, int gray)
+{
+ Pixel best = pixels[0];
+ int bestDist = 1 << 30;
+ int dist;
+ int dr;
+ int r;
+
+ while (num--)
+ {
+ Pixel pixel = *pixels++;
+ CARD32 v = pIndexed->rgba[pixel];
+
+ r = v & 0xff;
+ r = r | (r << 8);
+ dr = gray - (r >> 1);
+ dist = dr * dr;
+ if (dist < bestDist)
+ {
+ bestDist = dist;
+ best = pixel;
+ }
+ }
+ return best;
+}
+
+Bool
+miInitIndexed (ScreenPtr pScreen,
+ PictFormatPtr pFormat)
+{
+ ColormapPtr pColormap = pFormat->index.pColormap;
+ VisualPtr pVisual = pColormap->pVisual;
+ miIndexedPtr pIndexed;
+ Pixel pixels[MI_MAX_INDEXED];
+ xrgb rgb[MI_MAX_INDEXED];
+ int num;
+ int i;
+ Pixel p, r, g, b;
+
+ if (pVisual->ColormapEntries > MI_MAX_INDEXED)
+ return FALSE;
+
+ if (pVisual->class & DynamicClass)
+ {
+ if (!miBuildRenderColormap (pColormap, pixels, &num))
+ return FALSE;
+ }
+ else
+ {
+ num = pVisual->ColormapEntries;
+ for (p = 0; p < num; p++)
+ pixels[p] = p;
+ }
+
+ pIndexed = xalloc (sizeof (miIndexedRec));
+ if (!pIndexed)
+ return FALSE;
+
+ pFormat->index.nvalues = num;
+ pFormat->index.pValues = xalloc (num * sizeof (xIndexValue));
+ if (!pFormat->index.pValues)
+ {
+ xfree (pIndexed);
+ return FALSE;
+ }
+
+
+ /*
+ * Build mapping from pixel value to ARGB
+ */
+ QueryColors (pColormap, num, pixels, rgb);
+ for (i = 0; i < num; i++)
+ {
+ p = pixels[i];
+ pFormat->index.pValues[i].pixel = p;
+ pFormat->index.pValues[i].red = rgb[i].red;
+ pFormat->index.pValues[i].green = rgb[i].green;
+ pFormat->index.pValues[i].blue = rgb[i].blue;
+ pFormat->index.pValues[i].alpha = 0xffff;
+ pIndexed->rgba[p] = (0xff000000 |
+ ((rgb[i].red & 0xff00) << 8) |
+ ((rgb[i].green & 0xff00) ) |
+ ((rgb[i].blue & 0xff00) >> 8));
+ }
+
+ /*
+ * Build mapping from RGB to pixel value. This could probably be
+ * done a bit quicker...
+ */
+ switch (pVisual->class | DynamicClass) {
+ case GrayScale:
+ pIndexed->color = FALSE;
+ for (r = 0; r < 32768; r++)
+ pIndexed->ent[r] = FindBestGray (pIndexed, pixels, num, r);
+ break;
+ case PseudoColor:
+ pIndexed->color = TRUE;
+ p = 0;
+ for (r = 0; r < 32; r++)
+ for (g = 0; g < 32; g++)
+ for (b = 0; b < 32; b++)
+ {
+ pIndexed->ent[p] = FindBestColor (pIndexed, pixels, num,
+ r, g, b);
+ p++;
+ }
+ break;
+ }
+ pFormat->index.devPrivate = pIndexed;
+ return TRUE;
+}
+
+void
+miCloseIndexed (ScreenPtr pScreen,
+ PictFormatPtr pFormat)
+{
+ if (pFormat->index.devPrivate)
+ {
+ xfree (pFormat->index.devPrivate);
+ pFormat->index.devPrivate = 0;
+ }
+ if (pFormat->index.pValues)
+ {
+ xfree (pFormat->index.pValues);
+ pFormat->index.pValues = 0;
+ }
+}
+
+void
+miUpdateIndexed (ScreenPtr pScreen,
+ PictFormatPtr pFormat,
+ int ndef,
+ xColorItem *pdef)
+{
+ miIndexedPtr pIndexed = pFormat->index.devPrivate;
+
+ if (pIndexed)
+ {
+ while (ndef--)
+ {
+ pIndexed->rgba[pdef->pixel] = (0xff000000 |
+ ((pdef->red & 0xff00) << 8) |
+ ((pdef->green & 0xff00) ) |
+ ((pdef->blue & 0xff00) >> 8));
+ pdef++;
+ }
+ }
+}
+
+#endif /* _MIINDEX_H_ */
diff --git a/render/mipict.c b/render/mipict.c
new file mode 100644
index 000000000..3971a8f6e
--- /dev/null
+++ b/render/mipict.c
@@ -0,0 +1,516 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/mipict.c,v 1.14 2002/11/06 22:45:36 keithp Exp $
+ *
+ * Copyright © 1999 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.
+ */
+
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+
+#ifndef __GNUC__
+#define __inline
+#endif
+
+int
+miCreatePicture (PicturePtr pPicture)
+{
+ return Success;
+}
+
+void
+miDestroyPicture (PicturePtr pPicture)
+{
+ if (pPicture->freeCompClip)
+ REGION_DESTROY(pPicture->pDrawable->pScreen, pPicture->pCompositeClip);
+}
+
+void
+miDestroyPictureClip (PicturePtr pPicture)
+{
+ switch (pPicture->clientClipType) {
+ case CT_NONE:
+ return;
+ case CT_PIXMAP:
+ (*pPicture->pDrawable->pScreen->DestroyPixmap) ((PixmapPtr) (pPicture->clientClip));
+ break;
+ default:
+ /*
+ * we know we'll never have a list of rectangles, since ChangeClip
+ * immediately turns them into a region
+ */
+ REGION_DESTROY(pPicture->pDrawable->pScreen, pPicture->clientClip);
+ break;
+ }
+ pPicture->clientClip = NULL;
+ pPicture->clientClipType = CT_NONE;
+}
+
+int
+miChangePictureClip (PicturePtr pPicture,
+ int type,
+ pointer value,
+ int n)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ pointer clientClip;
+ int clientClipType;
+
+ switch (type) {
+ case CT_PIXMAP:
+ /* convert the pixmap to a region */
+ clientClip = (pointer) BITMAP_TO_REGION(pScreen, (PixmapPtr) value);
+ if (!clientClip)
+ return BadAlloc;
+ clientClipType = CT_REGION;
+ (*pScreen->DestroyPixmap) ((PixmapPtr) value);
+ break;
+ case CT_REGION:
+ clientClip = value;
+ clientClipType = CT_REGION;
+ break;
+ case CT_NONE:
+ clientClip = 0;
+ clientClipType = CT_NONE;
+ break;
+ default:
+ clientClip = (pointer) RECTS_TO_REGION(pScreen, n,
+ (xRectangle *) value,
+ type);
+ if (!clientClip)
+ return BadAlloc;
+ clientClipType = CT_REGION;
+ xfree(value);
+ break;
+ }
+ (*ps->DestroyPictureClip) (pPicture);
+ pPicture->clientClip = clientClip;
+ pPicture->clientClipType = clientClipType;
+ pPicture->stateChanges |= CPClipMask;
+ return Success;
+}
+
+void
+miChangePicture (PicturePtr pPicture,
+ Mask mask)
+{
+ return;
+}
+
+void
+miValidatePicture (PicturePtr pPicture,
+ Mask mask)
+{
+ DrawablePtr pDrawable = pPicture->pDrawable;
+
+ if ((mask & (CPClipXOrigin|CPClipYOrigin|CPClipMask|CPSubwindowMode)) ||
+ (pDrawable->serialNumber != (pPicture->serialNumber & DRAWABLE_SERIAL_BITS)))
+ {
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ WindowPtr pWin = (WindowPtr) pDrawable;
+ RegionPtr pregWin;
+ Bool freeTmpClip, freeCompClip;
+
+ if (pPicture->subWindowMode == IncludeInferiors)
+ {
+ pregWin = NotClippedByChildren(pWin);
+ freeTmpClip = TRUE;
+ }
+ else
+ {
+ pregWin = &pWin->clipList;
+ freeTmpClip = FALSE;
+ }
+ freeCompClip = pPicture->freeCompClip;
+
+ /*
+ * if there is no client clip, we can get by with just keeping the
+ * pointer we got, and remembering whether or not should destroy
+ * (or maybe re-use) it later. this way, we avoid unnecessary
+ * copying of regions. (this wins especially if many clients clip
+ * by children and have no client clip.)
+ */
+ if (pPicture->clientClipType == CT_NONE)
+ {
+ if (freeCompClip)
+ REGION_DESTROY(pScreen, pPicture->pCompositeClip);
+ pPicture->pCompositeClip = pregWin;
+ pPicture->freeCompClip = freeTmpClip;
+ }
+ else
+ {
+ /*
+ * we need one 'real' region to put into the composite clip. if
+ * pregWin the current composite clip are real, we can get rid of
+ * one. if pregWin is real and the current composite clip isn't,
+ * use pregWin for the composite clip. if the current composite
+ * clip is real and pregWin isn't, use the current composite
+ * clip. if neither is real, create a new region.
+ */
+
+ REGION_TRANSLATE(pScreen, pPicture->clientClip,
+ pDrawable->x + pPicture->clipOrigin.x,
+ pDrawable->y + pPicture->clipOrigin.y);
+
+ if (freeCompClip)
+ {
+ REGION_INTERSECT(pPicture->pScreen, pPicture->pCompositeClip,
+ pregWin, pPicture->clientClip);
+ if (freeTmpClip)
+ REGION_DESTROY(pScreen, pregWin);
+ }
+ else if (freeTmpClip)
+ {
+ REGION_INTERSECT(pScreen, pregWin, pregWin, pPicture->clientClip);
+ pPicture->pCompositeClip = pregWin;
+ }
+ else
+ {
+ pPicture->pCompositeClip = REGION_CREATE(pScreen, NullBox, 0);
+ REGION_INTERSECT(pScreen, pPicture->pCompositeClip,
+ pregWin, pPicture->clientClip);
+ }
+ pPicture->freeCompClip = TRUE;
+ REGION_TRANSLATE(pScreen, pPicture->clientClip,
+ -(pDrawable->x + pPicture->clipOrigin.x),
+ -(pDrawable->y + pPicture->clipOrigin.y));
+ }
+ } /* end of composite clip for a window */
+ else
+ {
+ BoxRec pixbounds;
+
+ /* XXX should we translate by drawable.x/y here ? */
+ /* If you want pixmaps in offscreen memory, yes */
+ pixbounds.x1 = pDrawable->x;
+ pixbounds.y1 = pDrawable->y;
+ pixbounds.x2 = pDrawable->x + pDrawable->width;
+ pixbounds.y2 = pDrawable->y + pDrawable->height;
+
+ if (pPicture->freeCompClip)
+ {
+ REGION_RESET(pScreen, pPicture->pCompositeClip, &pixbounds);
+ }
+ else
+ {
+ pPicture->freeCompClip = TRUE;
+ pPicture->pCompositeClip = REGION_CREATE(pScreen, &pixbounds, 1);
+ }
+
+ if (pPicture->clientClipType == CT_REGION)
+ {
+ if(pDrawable->x || pDrawable->y) {
+ REGION_TRANSLATE(pScreen, pPicture->clientClip,
+ pDrawable->x + pPicture->clipOrigin.x,
+ pDrawable->y + pPicture->clipOrigin.y);
+ REGION_INTERSECT(pScreen, pPicture->pCompositeClip,
+ pPicture->pCompositeClip, pPicture->clientClip);
+ REGION_TRANSLATE(pScreen, pPicture->clientClip,
+ -(pDrawable->x + pPicture->clipOrigin.x),
+ -(pDrawable->y + pPicture->clipOrigin.y));
+ } else {
+ REGION_TRANSLATE(pScreen, pPicture->pCompositeClip,
+ -pPicture->clipOrigin.x, -pPicture->clipOrigin.y);
+ REGION_INTERSECT(pScreen, pPicture->pCompositeClip,
+ pPicture->pCompositeClip, pPicture->clientClip);
+ REGION_TRANSLATE(pScreen, pPicture->pCompositeClip,
+ pPicture->clipOrigin.x, pPicture->clipOrigin.y);
+ }
+ }
+ } /* end of composite clip for pixmap */
+ }
+}
+
+#define BOUND(v) (INT16) ((v) < MINSHORT ? MINSHORT : (v) > MAXSHORT ? MAXSHORT : (v))
+
+static __inline Bool
+miClipPictureReg (RegionPtr pRegion,
+ RegionPtr pClip,
+ int dx,
+ int dy)
+{
+ if (REGION_NUM_RECTS(pRegion) == 1 &&
+ REGION_NUM_RECTS(pClip) == 1)
+ {
+ BoxPtr pRbox = REGION_RECTS(pRegion);
+ BoxPtr pCbox = REGION_RECTS(pClip);
+ int v;
+
+ if (pRbox->x1 < (v = pCbox->x1 + dx))
+ pRbox->x1 = BOUND(v);
+ if (pRbox->x2 > (v = pCbox->x2 + dx))
+ pRbox->x2 = BOUND(v);
+ if (pRbox->y1 < (v = pCbox->y1 + dy))
+ pRbox->y1 = BOUND(v);
+ if (pRbox->y2 > (v = pCbox->y2 + dy))
+ pRbox->y2 = BOUND(v);
+ if (pRbox->x1 >= pRbox->x2 ||
+ pRbox->y1 >= pRbox->y2)
+ {
+ REGION_EMPTY(pScreen, pRegion);
+ }
+ }
+ else
+ {
+ REGION_TRANSLATE(pScreen, pRegion, dx, dy);
+ if (!REGION_INTERSECT (pScreen, pRegion, pRegion, pClip))
+ return FALSE;
+ REGION_TRANSLATE(pScreen, pRegion, -dx, -dy);
+ }
+ return TRUE;
+}
+
+static __inline Bool
+miClipPictureSrc (RegionPtr pRegion,
+ PicturePtr pPicture,
+ int dx,
+ int dy)
+{
+ /* XXX what to do with clipping from transformed pictures? */
+ if (pPicture->transform)
+ return TRUE;
+ if (pPicture->repeat)
+ {
+ if (pPicture->clientClipType != CT_NONE)
+ {
+ REGION_TRANSLATE(pScreen, pRegion,
+ dx - pPicture->clipOrigin.x,
+ dy - pPicture->clipOrigin.y);
+ if (!REGION_INTERSECT (pScreen, pRegion, pRegion,
+ (RegionPtr) pPicture->clientClip))
+ return FALSE;
+ REGION_TRANSLATE(pScreen, pRegion,
+ - (dx - pPicture->clipOrigin.x),
+ - (dy - pPicture->clipOrigin.y));
+ }
+ return TRUE;
+ }
+ else
+ {
+ return miClipPictureReg (pRegion,
+ pPicture->pCompositeClip,
+ dx,
+ dy);
+ }
+}
+
+Bool
+miComputeCompositeRegion (RegionPtr pRegion,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ int v;
+
+ pRegion->extents.x1 = xDst;
+ v = xDst + width;
+ pRegion->extents.x2 = BOUND(v);
+ pRegion->extents.y1 = yDst;
+ v = yDst + height;
+ pRegion->extents.y2 = BOUND(v);
+ pRegion->data = 0;
+ /* Check for empty operation */
+ if (pRegion->extents.x1 >= pRegion->extents.x2 ||
+ pRegion->extents.y1 >= pRegion->extents.y2)
+ {
+ REGION_EMPTY (pDst->pDrawable->pScreen, pRegion);
+ return TRUE;
+ }
+ /* clip against src */
+ if (!miClipPictureSrc (pRegion, pSrc, xDst - xSrc, yDst - ySrc))
+ {
+ REGION_UNINIT (pScreen, pRegion);
+ return FALSE;
+ }
+ if (pSrc->alphaMap)
+ {
+ if (!miClipPictureSrc (pRegion, pSrc->alphaMap,
+ xDst - (xSrc + pSrc->alphaOrigin.x),
+ yDst - (ySrc + pSrc->alphaOrigin.y)))
+ {
+ REGION_UNINIT (pScreen, pRegion);
+ return FALSE;
+ }
+ }
+ /* clip against mask */
+ if (pMask)
+ {
+ if (!miClipPictureSrc (pRegion, pMask, xDst - xMask, yDst - yMask))
+ {
+ REGION_UNINIT (pScreen, pRegion);
+ return FALSE;
+ }
+ if (pMask->alphaMap)
+ {
+ if (!miClipPictureSrc (pRegion, pMask->alphaMap,
+ xDst - (xMask + pMask->alphaOrigin.x),
+ yDst - (yMask + pMask->alphaOrigin.y)))
+ {
+ REGION_UNINIT (pScreen, pRegion);
+ return FALSE;
+ }
+ }
+ }
+ if (!miClipPictureReg (pRegion, pDst->pCompositeClip, 0, 0))
+ {
+ REGION_UNINIT (pScreen, pRegion);
+ return FALSE;
+ }
+ if (pDst->alphaMap)
+ {
+ if (!miClipPictureReg (pRegion, pDst->alphaMap->pCompositeClip,
+ -pDst->alphaOrigin.x,
+ -pDst->alphaOrigin.y))
+ {
+ REGION_UNINIT (pScreen, pRegion);
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+void
+miRenderColorToPixel (PictFormatPtr format,
+ xRenderColor *color,
+ CARD32 *pixel)
+{
+ CARD32 r, g, b, a;
+ miIndexedPtr pIndexed;
+
+ switch (format->type) {
+ case PictTypeDirect:
+ r = color->red >> (16 - Ones (format->direct.redMask));
+ g = color->green >> (16 - Ones (format->direct.greenMask));
+ b = color->blue >> (16 - Ones (format->direct.blueMask));
+ a = color->alpha >> (16 - Ones (format->direct.alphaMask));
+ r = r << format->direct.red;
+ g = g << format->direct.green;
+ b = b << format->direct.blue;
+ a = a << format->direct.alpha;
+ *pixel = r|g|b|a;
+ break;
+ case PictTypeIndexed:
+ pIndexed = (miIndexedPtr) (format->index.devPrivate);
+ if (pIndexed->color)
+ {
+ r = color->red >> 11;
+ g = color->green >> 11;
+ b = color->blue >> 11;
+ *pixel = miIndexToEnt15 (pIndexed, (r << 10) | (g << 5) | b);
+ }
+ else
+ {
+ r = color->red >> 8;
+ g = color->green >> 8;
+ b = color->blue >> 8;
+ *pixel = miIndexToEntY24 (pIndexed, (r << 16) | (g << 8) | b);
+ }
+ break;
+ }
+}
+
+static CARD16
+miFillColor (CARD32 pixel, int bits)
+{
+ while (bits < 16)
+ {
+ pixel |= pixel << bits;
+ bits <<= 1;
+ }
+ return (CARD16) pixel;
+}
+
+void
+miRenderPixelToColor (PictFormatPtr format,
+ CARD32 pixel,
+ xRenderColor *color)
+{
+ CARD32 r, g, b, a;
+ miIndexedPtr pIndexed;
+
+ switch (format->type) {
+ case PictTypeDirect:
+ r = (pixel >> format->direct.red) & format->direct.redMask;
+ g = (pixel >> format->direct.green) & format->direct.greenMask;
+ b = (pixel >> format->direct.blue) & format->direct.blueMask;
+ a = (pixel >> format->direct.alpha) & format->direct.alphaMask;
+ color->red = miFillColor (r, Ones (format->direct.redMask));
+ color->green = miFillColor (r, Ones (format->direct.greenMask));
+ color->blue = miFillColor (r, Ones (format->direct.blueMask));
+ color->alpha = miFillColor (r, Ones (format->direct.alphaMask));
+ break;
+ case PictTypeIndexed:
+ pIndexed = (miIndexedPtr) (format->index.devPrivate);
+ pixel = pIndexed->rgba[pixel & (MI_MAX_INDEXED-1)];
+ r = (pixel >> 16) & 0xff;
+ g = (pixel >> 8) & 0xff;
+ b = (pixel ) & 0xff;
+ color->red = miFillColor (r, 8);
+ color->green = miFillColor (g, 8);
+ color->blue = miFillColor (b, 8);
+ color->alpha = 0xffff;
+ break;
+ }
+}
+
+Bool
+miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
+{
+ PictureScreenPtr ps;
+
+ if (!PictureInit (pScreen, formats, nformats))
+ return FALSE;
+ ps = GetPictureScreen(pScreen);
+ ps->CreatePicture = miCreatePicture;
+ ps->DestroyPicture = miDestroyPicture;
+ ps->ChangePictureClip = miChangePictureClip;
+ ps->DestroyPictureClip = miDestroyPictureClip;
+ ps->ChangePicture = miChangePicture;
+ ps->ValidatePicture = miValidatePicture;
+ ps->InitIndexed = miInitIndexed;
+ ps->CloseIndexed = miCloseIndexed;
+ ps->UpdateIndexed = miUpdateIndexed;
+
+ /* MI rendering routines */
+ ps->Composite = 0; /* requires DDX support */
+ ps->Glyphs = miGlyphs;
+ ps->CompositeRects = miCompositeRects;
+ ps->Trapezoids = miTrapezoids;
+ ps->Triangles = miTriangles;
+ ps->TriStrip = miTriStrip;
+ ps->TriFan = miTriFan;
+
+ return TRUE;
+}
diff --git a/render/mipict.h b/render/mipict.h
new file mode 100644
index 000000000..0154fb5f0
--- /dev/null
+++ b/render/mipict.h
@@ -0,0 +1,210 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/mipict.h,v 1.13 2002/11/06 22:45:36 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 _MIPICT_H_
+#define _MIPICT_H_
+
+#include "picturestr.h"
+
+#define MI_MAX_INDEXED 256 /* XXX depth must be <= 8 */
+
+#if MI_MAX_INDEXED <= 256
+typedef CARD8 miIndexType;
+#endif
+
+typedef struct _miIndexed {
+ Bool color;
+ CARD32 rgba[MI_MAX_INDEXED];
+ miIndexType ent[32768];
+} miIndexedRec, *miIndexedPtr;
+
+#define miCvtR8G8B8to15(s) ((((s) >> 3) & 0x001f) | \
+ (((s) >> 6) & 0x03e0) | \
+ (((s) >> 9) & 0x7c00))
+#define miIndexToEnt15(mif,rgb15) ((mif)->ent[rgb15])
+#define miIndexToEnt24(mif,rgb24) miIndexToEnt15(mif,miCvtR8G8B8to15(rgb24))
+
+#define miIndexToEntY24(mif,rgb24) ((mif)->ent[CvtR8G8B8toY15(rgb24)])
+
+int
+miCreatePicture (PicturePtr pPicture);
+
+void
+miDestroyPicture (PicturePtr pPicture);
+
+void
+miDestroyPictureClip (PicturePtr pPicture);
+
+int
+miChangePictureClip (PicturePtr pPicture,
+ int type,
+ pointer value,
+ int n);
+
+void
+miChangePicture (PicturePtr pPicture,
+ Mask mask);
+
+void
+miValidatePicture (PicturePtr pPicture,
+ Mask mask);
+
+
+Bool
+miClipPicture (RegionPtr pRegion,
+ PicturePtr pPicture,
+ INT16 xReg,
+ INT16 yReg,
+ INT16 xPict,
+ INT16 yPict);
+
+Bool
+miComputeCompositeRegion (RegionPtr pRegion,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+Bool
+miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
+
+void
+miGlyphExtents (int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs,
+ BoxPtr extents);
+
+void
+miGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs);
+
+void
+miRenderColorToPixel (PictFormatPtr pPict,
+ xRenderColor *color,
+ CARD32 *pixel);
+
+void
+miRenderPixelToColor (PictFormatPtr pPict,
+ CARD32 pixel,
+ xRenderColor *color);
+
+void
+miCompositeRects (CARD8 op,
+ PicturePtr pDst,
+ xRenderColor *color,
+ int nRect,
+ xRectangle *rects);
+
+void
+miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box);
+
+void
+miTrapezoids (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntrap,
+ xTrapezoid *traps);
+
+void
+miPointFixedBounds (int npoint, xPointFixed *points, BoxPtr bounds);
+
+void
+miTriangleBounds (int ntri, xTriangle *tris, BoxPtr bounds);
+
+void
+miRasterizeTriangle (PicturePtr pMask,
+ xTriangle *tri,
+ int x_off,
+ int y_off);
+
+void
+miTriangles (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntri,
+ xTriangle *tris);
+
+void
+miTriStrip (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoint,
+ xPointFixed *points);
+
+void
+miTriFan (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoint,
+ xPointFixed *points);
+
+PicturePtr
+miCreateAlphaPicture (ScreenPtr pScreen,
+ PicturePtr pDst,
+ PictFormatPtr pPictFormat,
+ CARD16 width,
+ CARD16 height);
+
+Bool
+miInitIndexed (ScreenPtr pScreen,
+ PictFormatPtr pFormat);
+
+void
+miCloseIndexed (ScreenPtr pScreen,
+ PictFormatPtr pFormat);
+
+void
+miUpdateIndexed (ScreenPtr pScreen,
+ PictFormatPtr pFormat,
+ int ndef,
+ xColorItem *pdef);
+
+#endif /* _MIPICT_H_ */
diff --git a/render/mirect.c b/render/mirect.c
new file mode 100644
index 000000000..33c7a9f14
--- /dev/null
+++ b/render/mirect.c
@@ -0,0 +1,181 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/mirect.c,v 1.4 2001/06/08 19:36:34 keithp Exp $
+ *
+ * Copyright © 2000 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.
+ */
+
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+
+static void
+miColorRects (PicturePtr pDst,
+ PicturePtr pClipPict,
+ xRenderColor *color,
+ int nRect,
+ xRectangle *rects,
+ int xoff,
+ int yoff)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ CARD32 pixel;
+ GCPtr pGC;
+ CARD32 tmpval[4];
+ RegionPtr pClip;
+ unsigned long mask;
+
+ miRenderColorToPixel (pDst->pFormat, color, &pixel);
+
+ pGC = GetScratchGC (pDst->pDrawable->depth, pScreen);
+ if (!pGC)
+ return;
+ tmpval[0] = GXcopy;
+ tmpval[1] = pixel;
+ mask = GCFunction | GCForeground;
+ if (pClipPict->clientClipType == CT_REGION)
+ {
+ tmpval[2] = pDst->clipOrigin.x - xoff;
+ tmpval[3] = pDst->clipOrigin.y - yoff;
+ mask |= CPClipXOrigin|CPClipYOrigin;
+
+ pClip = REGION_CREATE (pScreen, NULL, 1);
+ REGION_COPY (pScreen, pClip,
+ (RegionPtr) pClipPict->clientClip);
+ (*pGC->funcs->ChangeClip) (pGC, CT_REGION, pClip, 0);
+ }
+
+ ChangeGC (pGC, mask, tmpval);
+ ValidateGC (pDst->pDrawable, pGC);
+ if (xoff || yoff)
+ {
+ int i;
+ for (i = 0; i < nRect; i++)
+ {
+ rects[i].x -= xoff;
+ rects[i].y -= yoff;
+ }
+ }
+ (*pGC->ops->PolyFillRect) (pDst->pDrawable, pGC, nRect, rects);
+ if (xoff || yoff)
+ {
+ int i;
+ for (i = 0; i < nRect; i++)
+ {
+ rects[i].x += xoff;
+ rects[i].y += yoff;
+ }
+ }
+ FreeScratchGC (pGC);
+}
+
+void
+miCompositeRects (CARD8 op,
+ PicturePtr pDst,
+ xRenderColor *color,
+ int nRect,
+ xRectangle *rects)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+
+ if (color->alpha == 0xffff)
+ {
+ if (op == PictOpOver)
+ op = PictOpSrc;
+ }
+ if (op == PictOpClear)
+ color->red = color->green = color->blue = color->alpha = 0;
+
+ if (op == PictOpSrc || op == PictOpClear)
+ {
+ miColorRects (pDst, pDst, color, nRect, rects, 0, 0);
+ if (pDst->alphaMap)
+ miColorRects (pDst->alphaMap, pDst,
+ color, nRect, rects,
+ pDst->alphaOrigin.x,
+ pDst->alphaOrigin.y);
+ }
+ else
+ {
+ PictFormatPtr rgbaFormat;
+ PixmapPtr pPixmap;
+ PicturePtr pSrc;
+ xRectangle one;
+ int error;
+ Pixel pixel;
+ GCPtr pGC;
+ CARD32 tmpval[2];
+
+ rgbaFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8);
+ if (!rgbaFormat)
+ goto bail1;
+
+ pPixmap = (*pScreen->CreatePixmap) (pScreen, 1, 1,
+ rgbaFormat->depth);
+ if (!pPixmap)
+ goto bail2;
+
+ miRenderColorToPixel (rgbaFormat, color, &pixel);
+
+ pGC = GetScratchGC (rgbaFormat->depth, pScreen);
+ if (!pGC)
+ goto bail3;
+ tmpval[0] = GXcopy;
+ tmpval[1] = pixel;
+
+ ChangeGC (pGC, GCFunction | GCForeground, tmpval);
+ ValidateGC (&pPixmap->drawable, pGC);
+ one.x = 0;
+ one.y = 0;
+ one.width = 1;
+ one.height = 1;
+ (*pGC->ops->PolyFillRect) (&pPixmap->drawable, pGC, 1, &one);
+
+ tmpval[0] = xTrue;
+ pSrc = CreatePicture (0, &pPixmap->drawable, rgbaFormat,
+ CPRepeat, tmpval, 0, &error);
+
+ if (!pSrc)
+ goto bail4;
+
+ while (nRect--)
+ {
+ CompositePicture (op, pSrc, 0, pDst, 0, 0, 0, 0,
+ rects->x,
+ rects->y,
+ rects->width,
+ rects->height);
+ rects++;
+ }
+
+ FreePicture ((pointer) pSrc, 0);
+bail4:
+ FreeScratchGC (pGC);
+bail3:
+ (*pScreen->DestroyPixmap) (pPixmap);
+bail2:
+bail1:
+ ;
+ }
+}
diff --git a/render/mitrap.c b/render/mitrap.c
new file mode 100644
index 000000000..7f592ccd4
--- /dev/null
+++ b/render/mitrap.c
@@ -0,0 +1,196 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/mitrap.c,v 1.9 2002/11/05 23:39:16 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.
+ */
+
+#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);
+ PicturePtr pPicture = 0;
+ BoxRec bounds;
+ INT16 xDst, yDst;
+ INT16 xRel, yRel;
+
+ xDst = traps[0].left.p1.x >> 16;
+ yDst = traps[0].left.p1.y >> 16;
+
+ if (maskFormat)
+ {
+ 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++)
+ {
+ if (!xTrapezoidValid(traps))
+ continue;
+ if (!maskFormat)
+ {
+ miTrapezoidBounds (1, traps, &bounds);
+ if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
+ continue;
+ pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
+ bounds.x2 - bounds.x1,
+ bounds.y2 - bounds.y1);
+ if (!pPicture)
+ continue;
+ }
+ (*ps->RasterizeTrapezoid) (pPicture, traps,
+ -bounds.x1, -bounds.y1);
+ if (!maskFormat)
+ {
+ 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);
+ }
+ }
+ if (maskFormat)
+ {
+ 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);
+ }
+}
diff --git a/render/mitri.c b/render/mitri.c
new file mode 100644
index 000000000..fc706f117
--- /dev/null
+++ b/render/mitri.c
@@ -0,0 +1,352 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/mitri.c,v 1.6 2002/08/12 04:03:21 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.
+ */
+
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+
+void
+miPointFixedBounds (int npoint, xPointFixed *points, BoxPtr bounds)
+{
+ bounds->x1 = xFixedToInt (points->x);
+ bounds->x2 = xFixedToInt (xFixedCeil (points->x));
+ bounds->y1 = xFixedToInt (points->y);
+ bounds->y2 = xFixedToInt (xFixedCeil (points->y));
+ points++;
+ npoint--;
+ while (npoint-- > 0)
+ {
+ INT16 x1 = xFixedToInt (points->x);
+ INT16 x2 = xFixedToInt (xFixedCeil (points->x));
+ INT16 y1 = xFixedToInt (points->y);
+ INT16 y2 = xFixedToInt (xFixedCeil (points->y));
+
+ if (x1 < bounds->x1)
+ bounds->x1 = x1;
+ else if (x2 > bounds->x2)
+ bounds->x2 = x2;
+ if (y1 < bounds->y1)
+ bounds->y1 = y1;
+ else if (y2 > bounds->y2)
+ bounds->y2 = y2;
+ points++;
+ }
+}
+
+void
+miTriangleBounds (int ntri, xTriangle *tris, BoxPtr bounds)
+{
+ miPointFixedBounds (ntri * 3, (xPointFixed *) tris, bounds);
+}
+
+void
+miRasterizeTriangle (PicturePtr pPicture,
+ xTriangle *tri,
+ int x_off,
+ int y_off)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ xPointFixed *top, *left, *right, *t;
+ xTrapezoid trap[2];
+
+ top = &tri->p1;
+ left = &tri->p2;
+ right = &tri->p3;
+ if (left->y < top->y) {
+ t = left; left = top; top = t;
+ }
+ if (right->y < top->y) {
+ t = right; right = top; top = t;
+ }
+ if (right->x < left->x) {
+ t = right; right = left; left = t;
+ }
+
+ /*
+ * Two cases:
+ *
+ * + +
+ * / \ / \
+ * / \ / \
+ * / + + \
+ * / -- -- \
+ * / -- -- \
+ * / --- --- \
+ * +-- --+
+ */
+
+ trap[0].top = top->y;
+
+ trap[0].left.p1.x = top->x;
+ trap[0].left.p1.y = trap[0].top;
+ trap[0].left.p2.x = left->x;
+ trap[0].left.p2.y = left->y;
+
+ trap[0].right.p1 = trap[0].left.p1;
+ trap[0].right.p2.x = right->x;
+ trap[0].right.p2.y = right->y;
+
+ if (right->y < left->y)
+ {
+ trap[0].bottom = trap[0].right.p2.y;
+
+ trap[1].top = trap[0].bottom;
+ trap[1].bottom = trap[0].left.p2.y;
+
+ trap[1].left = trap[0].left;
+ trap[1].right.p1 = trap[0].right.p2;
+ trap[1].right.p2 = trap[0].left.p2;
+ }
+ else
+ {
+ trap[0].bottom = trap[0].left.p2.y;
+
+ trap[1].top = trap[0].bottom;
+ trap[1].bottom = trap[0].right.p2.y;
+
+ trap[1].right = trap[0].right;
+ trap[1].left.p1 = trap[0].left.p2;
+ trap[1].left.p2 = trap[0].right.p2;
+ }
+ if (trap[0].top != trap[0].bottom)
+ (*ps->RasterizeTrapezoid) (pPicture, &trap[0], x_off, y_off);
+ if (trap[1].top != trap[1].bottom)
+ (*ps->RasterizeTrapezoid) (pPicture, &trap[1], x_off, y_off);
+}
+
+void
+miTriangles (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntri,
+ xTriangle *tris)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ BoxRec bounds;
+ PicturePtr pPicture = 0;
+ INT16 xDst, yDst;
+ INT16 xRel, yRel;
+
+ xDst = tris[0].p1.x >> 16;
+ yDst = tris[0].p1.y >> 16;
+
+ if (maskFormat)
+ {
+ miTriangleBounds (ntri, tris, &bounds);
+ if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1)
+ return;
+ pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
+ bounds.x2 - bounds.x1,
+ bounds.y2 - bounds.y1);
+ if (!pPicture)
+ return;
+ }
+ for (; ntri; ntri--, tris++)
+ {
+ if (!maskFormat)
+ {
+ miTriangleBounds (1, tris, &bounds);
+ if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1)
+ continue;
+ pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
+ bounds.x2 - bounds.x1,
+ bounds.y2 - bounds.y1);
+ if (!pPicture)
+ break;
+ }
+ miRasterizeTriangle (pPicture, tris, -bounds.x1, -bounds.y1);
+ if (!maskFormat)
+ {
+ 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);
+ }
+ /* XXX adjust xSrc and ySrc */
+ }
+ if (maskFormat)
+ {
+ 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);
+ }
+}
+
+void
+miTriStrip (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoint,
+ xPointFixed *points)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ xTriangle tri;
+ BoxRec bounds;
+ PicturePtr pPicture = 0;
+ INT16 xDst, yDst;
+ INT16 xRel, yRel;
+
+ xDst = points[0].x >> 16;
+ yDst = points[0].y >> 16;
+
+ if (npoint < 3)
+ return;
+ if (maskFormat)
+ {
+ miPointFixedBounds (npoint, points, &bounds);
+ if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1)
+ return;
+ pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
+ bounds.x2 - bounds.x1,
+ bounds.y2 - bounds.y1);
+ if (!pPicture)
+ return;
+ }
+ for (; npoint >= 3; npoint--, points++)
+ {
+ tri.p1 = points[0];
+ tri.p2 = points[1];
+ tri.p3 = points[2];
+ if (!maskFormat)
+ {
+ miTriangleBounds (1, &tri, &bounds);
+ if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1)
+ continue;
+ pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
+ bounds.x2 - bounds.x1,
+ bounds.y2 - bounds.y1);
+ if (!pPicture)
+ continue;
+ }
+ miRasterizeTriangle (pPicture, &tri, -bounds.x1, -bounds.y1);
+ if (!maskFormat)
+ {
+ 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);
+ }
+ }
+ if (maskFormat)
+ {
+ 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);
+ }
+}
+
+void
+miTriFan (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoint,
+ xPointFixed *points)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ xTriangle tri;
+ BoxRec bounds;
+ PicturePtr pPicture = 0;
+ xPointFixed *first;
+ INT16 xDst, yDst;
+ INT16 xRel, yRel;
+
+ xDst = points[0].x >> 16;
+ yDst = points[0].y >> 16;
+
+ if (npoint < 3)
+ return;
+ if (maskFormat)
+ {
+ miPointFixedBounds (npoint, points, &bounds);
+ if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1)
+ return;
+ pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
+ bounds.x2 - bounds.x1,
+ bounds.y2 - bounds.y1);
+ if (!pPicture)
+ return;
+ }
+ first = points++;
+ npoint--;
+ for (; npoint >= 2; npoint--, points++)
+ {
+ tri.p1 = *first;
+ tri.p2 = points[0];
+ tri.p3 = points[1];
+ if (!maskFormat)
+ {
+ miTriangleBounds (1, &tri, &bounds);
+ if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1)
+ continue;
+ pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
+ bounds.x2 - bounds.x1,
+ bounds.y2 - bounds.y1);
+ if (!pPicture)
+ continue;
+ }
+ miRasterizeTriangle (pPicture, &tri, -bounds.x1, -bounds.y1);
+ if (!maskFormat)
+ {
+ 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);
+ }
+ }
+ if (maskFormat)
+ {
+ 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);
+ }
+}
diff --git a/render/picture.c b/render/picture.c
new file mode 100644
index 000000000..b2ef69bdf
--- /dev/null
+++ b/render/picture.c
@@ -0,0 +1,1305 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/picture.c,v 1.30 2003/01/26 16:40:43 eich 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.
+ */
+
+#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;
+
+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);
+ 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.pVisual = &pScreen->visuals[PICT_FORMAT_VIS(format)];
+ break;
+ }
+ }
+ *nformatp = nformats;
+ return pFormats;
+}
+
+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.pVisual->vid == pScreen->rootVisual)
+ format->index.pColormap = (ColormapPtr) LookupIDByType(pScreen->defColormap,
+ RT_COLORMAP);
+ else
+ {
+ if (CreateColormap (FakeClientID (0), pScreen,
+ format->index.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:
+ type = PictTypeDirect;
+ break;
+ case DirectColor:
+ default:
+ return 0;
+ }
+ while (nformat--)
+ {
+ if (format->depth == depth && format->type == type)
+ {
+ if (type == PictTypeIndexed)
+ {
+ if (format->index.pVisual == pVisual)
+ 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)
+ {
+ if ((formats[n].index.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->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;
+}
+
+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;
+}
+
+#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->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ 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 <= xTrue)
+ pPicture->repeat = 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 (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;
+ }
+ }
+ (*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
+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;
+ }
+ }
+ return Success;
+}
+
+static void
+ValidateOnePicture (PicturePtr pPicture)
+{
+ if (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)
+ {
+ 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->transform)
+ xfree (pPicture->transform);
+ 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);
+}
+
+typedef xFixed_32_32 xFixed_48_16;
+
+#define MAX_FIXED_48_16 ((xFixed_48_16) 0x7fffffff)
+#define MIN_FIXED_48_16 (-((xFixed_48_16) 1 << 31))
+
+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/render/picture.h b/render/picture.h
new file mode 100644
index 000000000..2c2b1b3b4
--- /dev/null
+++ b/render/picture.h
@@ -0,0 +1,228 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/picture.h,v 1.18 2002/11/06 22:45:36 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 _PICTURE_H_
+#define _PICTURE_H_
+
+typedef struct _DirectFormat *DirectFormatPtr;
+typedef struct _PictFormat *PictFormatPtr;
+typedef struct _Picture *PicturePtr;
+
+/*
+ * While the protocol is generous in format support, the
+ * sample implementation allows only packed RGB and GBR
+ * representations for data to simplify software rendering,
+ */
+#define PICT_FORMAT(bpp,type,a,r,g,b) (((bpp) << 24) | \
+ ((type) << 16) | \
+ ((a) << 12) | \
+ ((r) << 8) | \
+ ((g) << 4) | \
+ ((b)))
+
+/*
+ * gray/color formats use a visual index instead of argb
+ */
+#define PICT_VISFORMAT(bpp,type,vi) (((bpp) << 24) | \
+ ((type) << 16) | \
+ ((vi)))
+
+#define PICT_FORMAT_BPP(f) (((f) >> 24) )
+#define PICT_FORMAT_TYPE(f) (((f) >> 16) & 0xff)
+#define PICT_FORMAT_A(f) (((f) >> 12) & 0x0f)
+#define PICT_FORMAT_R(f) (((f) >> 8) & 0x0f)
+#define PICT_FORMAT_G(f) (((f) >> 4) & 0x0f)
+#define PICT_FORMAT_B(f) (((f) ) & 0x0f)
+#define PICT_FORMAT_RGB(f) (((f) ) & 0xfff)
+#define PICT_FORMAT_VIS(f) (((f) ) & 0xffff)
+
+#define PICT_TYPE_OTHER 0
+#define PICT_TYPE_A 1
+#define PICT_TYPE_ARGB 2
+#define PICT_TYPE_ABGR 3
+#define PICT_TYPE_COLOR 4
+#define PICT_TYPE_GRAY 5
+
+#define PICT_FORMAT_COLOR(f) (PICT_FORMAT_TYPE(f) & 2)
+
+/* 32bpp formats */
+#define PICT_a8r8g8b8 PICT_FORMAT(32,PICT_TYPE_ARGB,8,8,8,8)
+#define PICT_x8r8g8b8 PICT_FORMAT(32,PICT_TYPE_ARGB,0,8,8,8)
+#define PICT_a8b8g8r8 PICT_FORMAT(32,PICT_TYPE_ABGR,8,8,8,8)
+#define PICT_x8b8g8r8 PICT_FORMAT(32,PICT_TYPE_ABGR,0,8,8,8)
+
+/* 24bpp formats */
+#define PICT_r8g8b8 PICT_FORMAT(24,PICT_TYPE_ARGB,0,8,8,8)
+#define PICT_b8g8r8 PICT_FORMAT(24,PICT_TYPE_ABGR,0,8,8,8)
+
+/* 16bpp formats */
+#define PICT_r5g6b5 PICT_FORMAT(16,PICT_TYPE_ARGB,0,5,6,5)
+#define PICT_b5g6r5 PICT_FORMAT(16,PICT_TYPE_ABGR,0,5,6,5)
+
+#define PICT_a1r5g5b5 PICT_FORMAT(16,PICT_TYPE_ARGB,1,5,5,5)
+#define PICT_x1r5g5b5 PICT_FORMAT(16,PICT_TYPE_ARGB,0,5,5,5)
+#define PICT_a1b5g5r5 PICT_FORMAT(16,PICT_TYPE_ABGR,1,5,5,5)
+#define PICT_x1b5g5r5 PICT_FORMAT(16,PICT_TYPE_ABGR,0,5,5,5)
+#define PICT_a4r4g4b4 PICT_FORMAT(16,PICT_TYPE_ARGB,4,4,4,4)
+#define PICT_x4r4g4b4 PICT_FORMAT(16,PICT_TYPE_ARGB,4,4,4,4)
+#define PICT_a4b4g4r4 PICT_FORMAT(16,PICT_TYPE_ARGB,4,4,4,4)
+#define PICT_x4b4g4r4 PICT_FORMAT(16,PICT_TYPE_ARGB,4,4,4,4)
+
+/* 8bpp formats */
+#define PICT_a8 PICT_FORMAT(8,PICT_TYPE_A,8,0,0,0)
+#define PICT_r3g3b2 PICT_FORMAT(8,PICT_TYPE_ARGB,0,3,3,2)
+#define PICT_b2g3r3 PICT_FORMAT(8,PICT_TYPE_ABGR,0,3,3,2)
+#define PICT_a2r2g2b2 PICT_FORMAT(8,PICT_TYPE_ARGB,2,2,2,2)
+#define PICT_a2b2g2r2 PICT_FORMAT(8,PICT_TYPE_ABGR,2,2,2,2)
+
+#define PICT_c8 PICT_FORMAT(8,PICT_TYPE_COLOR,0,0,0,0)
+#define PICT_g8 PICT_FORMAT(8,PICT_TYPE_GRAY,0,0,0,0)
+
+/* 4bpp formats */
+#define PICT_a4 PICT_FORMAT(4,PICT_TYPE_A,4,0,0,0)
+#define PICT_r1g2b1 PICT_FORMAT(4,PICT_TYPE_ARGB,0,1,2,1)
+#define PICT_b1g2r1 PICT_FORMAT(4,PICT_TYPE_ABGR,0,1,2,1)
+#define PICT_a1r1g1b1 PICT_FORMAT(4,PICT_TYPE_ARGB,1,1,1,1)
+#define PICT_a1b1g1r1 PICT_FORMAT(4,PICT_TYPE_ABGR,1,1,1,1)
+
+#define PICT_c4 PICT_FORMAT(4,PICT_TYPE_COLOR,0,0,0,0)
+#define PICT_g4 PICT_FORMAT(4,PICT_TYPE_GRAY,0,0,0,0)
+
+/* 1bpp formats */
+#define PICT_a1 PICT_FORMAT(1,PICT_TYPE_A,1,0,0,0)
+
+#define PICT_g1 PICT_FORMAT(1,PICT_TYPE_GRAY,0,0,0,0)
+
+/*
+ * For dynamic indexed visuals (GrayScale and PseudoColor), these control the
+ * selection of colors allocated for drawing to Pictures. The default
+ * policy depends on the size of the colormap:
+ *
+ * Size Default Policy
+ * ----------------------------
+ * < 64 PolicyMono
+ * < 256 PolicyGray
+ * 256 PolicyColor (only on PseudoColor)
+ *
+ * The actual allocation code lives in miindex.c, and so is
+ * austensibly server dependent, but that code does:
+ *
+ * PolicyMono Allocate no additional colors, use black and white
+ * PolicyGray Allocate 13 gray levels (11 cells used)
+ * PolicyColor Allocate a 4x4x4 cube and 13 gray levels (71 cells used)
+ * PolicyAll Allocate as big a cube as possible, fill with gray (all)
+ *
+ * Here's a picture to help understand how many colors are
+ * actually allocated (this is just the gray ramp):
+ *
+ * gray level
+ * all 0000 1555 2aaa 4000 5555 6aaa 8000 9555 aaaa bfff d555 eaaa ffff
+ * b/w 0000 ffff
+ * 4x4x4 5555 aaaa
+ * extra 1555 2aaa 4000 6aaa 8000 9555 bfff d555 eaaa
+ *
+ * The default colormap supplies two gray levels (black/white), the
+ * 4x4x4 cube allocates another two and nine more are allocated to fill
+ * in the 13 levels. When the 4x4x4 cube is not allocated, a total of
+ * 11 cells are allocated.
+ */
+
+#define PictureCmapPolicyInvalid -1
+#define PictureCmapPolicyDefault 0
+#define PictureCmapPolicyMono 1
+#define PictureCmapPolicyGray 2
+#define PictureCmapPolicyColor 3
+#define PictureCmapPolicyAll 4
+
+extern int PictureCmapPolicy;
+
+int PictureParseCmapPolicy (const char *name);
+
+/* Fixed point updates from Carl Worth, USC, Information Sciences Institute */
+
+#ifdef WIN32
+typedef __int64 xFixed_32_32;
+#else
+# if defined(__alpha__) || defined(__alpha) || \
+ defined(ia64) || defined(__ia64__) || \
+ defined(__sparc64__) || \
+ defined(__s390x__) || \
+ defined(x86_64) || defined (__x86_64__)
+typedef long xFixed_32_32;
+# else
+# if defined(__GNUC__) && \
+ ((__GNUC__ > 2) || \
+ ((__GNUC__ == 2) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ > 7)))
+__extension__
+# endif
+typedef long long int xFixed_32_32;
+# endif
+#endif
+
+typedef CARD32 xFixed_1_31;
+typedef CARD32 xFixed_1_16;
+typedef INT32 xFixed_16_16;
+
+/*
+ * An unadorned "xFixed" is the same as xFixed_16_16,
+ * (since it's quite common in the code)
+ */
+typedef xFixed_16_16 xFixed;
+#define XFIXED_BITS 16
+
+#define xFixedToInt(f) (int) ((f) >> XFIXED_BITS)
+#define IntToxFixed(i) ((xFixed) (i) << XFIXED_BITS)
+#define xFixedE ((xFixed) 1)
+#define xFixed1 (IntToxFixed(1))
+#define xFixed1MinusE (xFixed1 - xFixedE)
+#define xFixedFrac(f) ((f) & xFixed1MinusE)
+#define xFixedFloor(f) ((f) & ~xFixed1MinusE)
+#define xFixedCeil(f) xFixedFloor((f) + xFixed1MinusE)
+
+#define xFixedFraction(f) ((f) & xFixed1MinusE)
+#define xFixedMod2(f) ((f) & (xFixed1 | xFixed1MinusE))
+
+/* whether 't' is a well defined not obviously empty trapezoid */
+#define xTrapezoidValid(t) ((t)->left.p1.y != (t)->left.p2.y && \
+ (t)->right.p1.y != (t)->right.p2.y && \
+ (int) ((t)->bottom - (t)->top) > 0)
+
+/*
+ * Standard NTSC luminance conversions:
+ *
+ * y = r * 0.299 + g * 0.587 + b * 0.114
+ *
+ * Approximate this for a bit more speed:
+ *
+ * y = (r * 153 + g * 301 + b * 58) / 512
+ *
+ * This gives 17 bits of luminance; to get 15 bits, lop the low two
+ */
+
+#define CvtR8G8B8toY15(s) (((((s) >> 16) & 0xff) * 153 + \
+ (((s) >> 8) & 0xff) * 301 + \
+ (((s) ) & 0xff) * 58) >> 2)
+
+#endif /* _PICTURE_H_ */
diff --git a/render/picturestr.h b/render/picturestr.h
new file mode 100644
index 000000000..cb5ea0ac9
--- /dev/null
+++ b/render/picturestr.h
@@ -0,0 +1,501 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/picturestr.h,v 1.22 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.
+ */
+
+#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 {
+ VisualPtr pVisual;
+ 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;
+
+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 unused : 23;
+
+ 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;
+} PictureRec;
+
+typedef struct {
+ char *name;
+ xFixed *params;
+ int nparams;
+ int id;
+} PictFilterRec, *PictFilterPtr;
+
+#define PictFilterNearest 0
+#define PictFilterBilinear 1
+
+#define PictFilterFast 2
+#define PictFilterGood 3
+#define PictFilterBest 4
+
+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 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;
+} 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); \
+ } \
+} \
+
+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, xFixed *params, int nparams);
+
+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
+SetPictureTransform (PicturePtr pPicture,
+ PictTransform *transform);
+
+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);
+
+void RenderExtensionInit (void);
+
+Bool
+AnimCurInit (ScreenPtr pScreen);
+
+int
+AnimCursorCreate (CursorPtr *cursors, CARD32 *deltas, int ncursor, CursorPtr *ppCursor);
+
+#ifdef PANORAMIX
+void PanoramiXRenderInit (void);
+void PanoramiXRenderReset (void);
+#endif
+
+#endif /* _PICTURESTR_H_ */
diff --git a/render/render.c b/render/render.c
new file mode 100644
index 000000000..a4f90ea77
--- /dev/null
+++ b/render/render.c
@@ -0,0 +1,2584 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/render.c,v 1.26 2003/02/14 18:15:21 dawes 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
+#include "X.h"
+#include "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 "render.h"
+#include "renderproto.h"
+#include "picturestr.h"
+#include "glyphstr.h"
+#include "Xfuncproto.h"
+#include "cursorstr.h"
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#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 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 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,
+};
+
+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,
+};
+
+static void
+RenderResetProc (ExtensionEntry *extEntry);
+
+static CARD8 RenderReqCode;
+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;
+ RenderReqCode = (CARD8) extEntry->base;
+ RenderErrBase = extEntry->errorBase;
+}
+
+static void
+RenderResetProc (ExtensionEntry *extEntry)
+{
+}
+
+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);
+ 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 (pSrc, stuff->src, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_ALPHA (pMask, stuff->mask, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen ||
+ (pMask && 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 (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 (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 (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 (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 <= NLOCALGLYPH)
+ glyphsBase = glyphsLocal;
+ else
+ {
+ glyphsBase = (GlyphNewPtr) ALLOCATE_LOCAL (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);
+
+ if (glyphsBase != glyphsLocal)
+ DEALLOCATE_LOCAL (glyphsBase);
+ return client->noClientException;
+bail:
+ while (glyphs != glyphsBase)
+ {
+ --glyphs;
+ xfree (glyphs->glyph);
+ }
+ if (glyphsBase != glyphsLocal)
+ DEALLOCATE_LOCAL (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 (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)
+ {
+ gs = *(GlyphSet *) buffer;
+ 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);
+
+ 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);
+ 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
+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
+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
+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;
+}
+
+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_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;
+}
+
+void
+PanoramiXRenderReset (void)
+{
+ int i;
+ for (i = 0; i < RenderNumberRequests; i++)
+ ProcRenderVector[i] = PanoramiXSaveRenderVector[i];
+}
+
+#endif /* PANORAMIX */