summaryrefslogtreecommitdiff
path: root/xc/programs/Xserver/PEX5/ddpex/mi
diff options
context:
space:
mode:
Diffstat (limited to 'xc/programs/Xserver/PEX5/ddpex/mi')
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/Imakefile16
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/include/ddpex2.h210
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/include/miClip.h247
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/include/miFont.h132
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/include/miInfo.h349
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/include/miLUT.h432
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/include/miLight.h272
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/include/miLineDash.h72
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/include/miMarkers.h154
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/include/miNS.h136
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/include/miNurbs.h271
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/include/miPick.h133
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/include/miRender.h335
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/include/miStrMacro.h198
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/include/miStruct.h147
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/include/miText.h65
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/include/miWks.h190
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/include/mipex.h390
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/include/mixform.h55
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level0/README48
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level1/Imakefile81
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level1/mi52stubs.c177
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level1/miDDCtoGC.c589
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level1/miLevel1.c127
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level1/miListUtil.c343
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level1/miLvl1Tab.c80
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level1/miPck1Prim.c403
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level1/miRndFArea.c526
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level1/miRndMarkr.c276
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level1/miRndPLine.c183
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level1/miRndTStrip.c740
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level1/miRndText.c122
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level2/Imakefile117
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level2/ddContext.c1091
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level2/miBldXform.c709
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level2/miCellArray.c266
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level2/miClip.c246
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level2/miConvert.c954
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level2/miCopy.c1097
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level2/miDestroy.c141
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level2/miFillArea.c1528
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level2/miInquire.c1389
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level2/miLight.c605
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level2/miLvl2Tab.c1143
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level2/miMarkers.c146
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level2/miNCurve.c743
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level2/miNSTrim.c1943
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level2/miNSurf.c2466
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level2/miNurbs.c378
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level2/miOCs.c1614
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level2/miPickPrim.c1242
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level2/miPolyLine.c530
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level2/miQuadMesh.c265
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level2/miReplace.c309
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level2/miSOFAS.c216
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level2/miSearch.c295
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level2/miTestOCs.c269
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level2/miText.c2168
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level2/miTrans.c1024
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level2/miTriStrip.c2219
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level2/pexOCParse.c2249
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level3/Imakefile63
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level3/miRender.c1966
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level3/miRndrPick.c502
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level4/Imakefile82
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level4/css_ex_str.c309
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level4/css_plain.c222
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level4/css_tbls.c607
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level4/miDynamics.c222
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level4/miPick.c727
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level4/miSC.c212
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level4/miStruct.c2487
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level4/miTraverse.c596
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/level4/miWks.c2415
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/shared/Imakefile99
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/shared/miClrApLUT.c217
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/shared/miColrLUT.c295
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/shared/miDCueLUT.c232
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/shared/miEdgeLUT.c263
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/shared/miFont.c888
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/shared/miFontLUT.c228
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/shared/miIntLUT.c435
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/shared/miLUT.c835
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/shared/miLUTProcs.ci658
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/shared/miLightLUT.c249
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/shared/miLineLUT.c280
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/shared/miMarkLUT.c258
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/shared/miMisc.c870
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/shared/miNS.c446
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/shared/miPattLUT.c433
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/shared/miTextLUT.c257
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/shared/miUtils.c624
-rw-r--r--xc/programs/Xserver/PEX5/ddpex/mi/shared/miViewLUT.c258
93 files changed, 53096 insertions, 0 deletions
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/Imakefile b/xc/programs/Xserver/PEX5/ddpex/mi/Imakefile
new file mode 100644
index 000000000..8af6bc664
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/Imakefile
@@ -0,0 +1,16 @@
+XCOMM $XConsortium: Imakefile /main/1 1996/12/02 10:18:54 lehors $
+XCOMM This is only used on NT where we do not know how to jump over this dir
+
+#ifdef Win32Architecture
+
+#define IHaveSubdirs
+#define PassCDebugFlags CDEBUGFLAGS="$(CDEBUGFLAGS)"
+
+ SUBDIRS = level1 level2 level3 level4 shared
+
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
+MakeLintLibSubdirs($(SUBDIRS))
+LintSubdirs($(SUBDIRS))
+
+#endif
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/include/ddpex2.h b/xc/programs/Xserver/PEX5/ddpex/mi/include/ddpex2.h
new file mode 100644
index 000000000..aab4f486e
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/include/ddpex2.h
@@ -0,0 +1,210 @@
+/* $TOG: ddpex2.h /main/3 1998/02/10 12:38:12 kaleb $ */
+
+/***********************************************************
+
+Copyright 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Copyright 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution of
+the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS 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 DDPEX2_H
+#define DDPEX2_H 1
+
+#include "miRender.h"
+
+/*
+No! this is just the same as miGenericStr
+typedef struct {
+ ddUSHORT ocNumber;
+ ddUSHORT pexOCLength;
+} ddGenericOCStr, *ddGenericOCPtr;
+*/
+
+typedef listofColour miColourStruct;
+
+typedef miListHeader miMarkerStruct;
+
+typedef struct {
+ ddCoord3D *pOrigin; /* origin of the string */
+ ddCoord3D *pDirections; /* 2 orientation vectors */
+ ddUSHORT numEncodings; /* # of mono encodings */
+ pexMonoEncoding *pText; /* text strings */
+} miTextStruct;
+
+typedef struct {
+ ddCoord2D *pOrigin; /* origin of the string */
+ ddUSHORT numEncodings; /* # of mono encodings */
+ pexMonoEncoding *pText; /* text strings */
+} miText2DStruct;
+
+typedef struct {
+ ddCoord3D *pOrigin; /* origin of the string */
+ ddCoord3D *pOffset; /* offset */
+ ddUSHORT numEncodings; /* # of mono encodings */
+ pexMonoEncoding *pText; /* text string */
+} miAnnoTextStruct;
+
+typedef struct {
+ ddCoord2D *pOrigin; /* origin of the string */
+ ddCoord2D *pOffset; /* offset */
+ ddUSHORT numEncodings; /* # of mono encodings */
+ pexMonoEncoding *pText; /* text string */
+} miAnnoText2DStruct;
+
+typedef miListHeader miPolylineStruct;
+
+typedef struct {
+ ddUSHORT order; /* curve order */
+ ddFLOAT uMin;
+ ddFLOAT uMax;
+ ddUSHORT numKnots;
+ ddFLOAT *pKnots;
+ ddListBounds bounds;
+ miListHeader points;
+} miNurbStruct;
+
+typedef struct {
+ ddUSHORT shape;
+ ddUCHAR ignoreEdges;
+ ddUCHAR contourHint;
+ listofddFacet *pFacets;
+ ddListBounds bounds;
+ miListHeader points;
+} miFillAreaStruct;
+
+typedef struct {
+ ddUSHORT numLists;
+ ddUSHORT maxData;
+ ddUSHORT *pConnects;
+} miConnList;
+
+typedef struct {
+ ddUSHORT numLists;
+ ddUSHORT maxData;
+ miConnList *pConnLists;
+} miConnListList;
+
+typedef struct {
+ ddUSHORT numListLists;
+ ddUSHORT maxData;
+ miConnListList *data;
+} miConnHeader;
+
+typedef struct {
+ ddUSHORT shape;
+ ddUSHORT edgeAttribs;
+ ddUCHAR contourHint;
+ ddUCHAR contourCountsFlag;
+ ddUSHORT numFAS;
+ ddUSHORT numEdges;
+ ddUCHAR *edgeData;
+ listofddFacet pFacets;
+ ddListBounds bounds;
+ miListHeader points;
+ miConnHeader connects;
+} miSOFASStruct;
+
+typedef struct {
+ listofddFacet *pFacets;
+ ddListBounds bounds;
+ miListHeader points;
+} miTriangleStripStruct;
+
+typedef struct {
+ ddUSHORT mPts;
+ ddUSHORT nPts;
+ ddUSHORT shape;
+ listofddFacet *pFacets;
+ ddListBounds bounds;
+ miListHeader points;
+} miQuadMeshStruct;
+
+typedef struct {
+ ddUSHORT uOrder;
+ ddUSHORT vOrder;
+ ddUSHORT mPts;
+ ddUSHORT nPts;
+ ddULONG numUknots;
+ ddFLOAT *pUknots;
+ ddULONG numVknots;
+ ddFLOAT *pVknots;
+ miListHeader points;
+ ddULONG numTrimCurveLists;
+ listofTrimCurve *trimCurves;
+} miNurbSurfaceStruct;
+
+
+typedef struct {
+ ddEnumTypeIndex type;
+ union {
+ char *pNone;
+ char *pImpDep;
+ ddPSC_IsoparametricCurves *pIsoCurves;
+ ddPSC_LevelCurves *pMcLevelCurves;
+ ddPSC_LevelCurves *pWcLevelCurves;
+ } data;
+} miPSurfaceCharsStruct;
+
+typedef struct {
+ listofObj *enableList;
+ listofObj *disableList;
+} miLightStateStruct;
+
+typedef struct {
+ ddUSHORT operator;
+ listofObj *halfspaces;
+} miMCVolume_Struct;
+
+typedef struct {
+ ddULONG dx;
+ ddULONG dy;
+ ddListBounds bounds;
+ miListHeader point;
+ listofColour colours;
+} miCellArrayStruct;
+
+
+typedef struct {
+ ddULONG GDPid;
+ ddULONG numBytes;
+ miListHeader points;
+ ddPointer pData;
+} miGdpStruct;
+
+
+#endif
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/include/miClip.h b/xc/programs/Xserver/PEX5/ddpex/mi/include/miClip.h
new file mode 100644
index 000000000..faca364f8
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/include/miClip.h
@@ -0,0 +1,247 @@
+/* $TOG: miClip.h /main/4 1998/02/10 12:38:18 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS 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 MI_CLIP_H
+#define MI_CLIP_H
+#include "miLight.h"
+/*
+ * CLIP_POINT4D - set oc to the clip code for the specified point.
+ *
+ */
+
+#define CLIP_POINT4D(in_pt, oc, clip_mode) \
+ if ((clip_mode) == MI_MCLIP) { \
+ float t; \
+ int count; \
+ int num_halfspaces = pddc->Static.misc.ms_MCV->numObj; \
+ ddHalfSpace *MC_HSpace = \
+ (ddHalfSpace *)(pddc->Static.misc.ms_MCV->pList); \
+ \
+ for (count = 0, (oc) = 0; count < num_halfspaces; count++) { \
+ DOT_PRODUCT(&(MC_HSpace->vector), (in_pt), t); \
+ if ((t) < MC_HSpace->dist ) \
+ (oc) |= MI_CLIP_LEFT; /* any one will do */ \
+ MC_HSpace++; \
+ } \
+ } else { \
+ if (((ddCoord4D *)(in_pt))->x < -((ddCoord4D *)(in_pt))->w) \
+ (oc) = MI_CLIP_LEFT; \
+ else if (((ddCoord4D *)(in_pt))->x > ((ddCoord4D *)(in_pt))->w) \
+ (oc) = MI_CLIP_RIGHT; \
+ else (oc) = 0; \
+ if (((ddCoord4D *)(in_pt))->y < -((ddCoord4D *)(in_pt))->w) \
+ (oc) |= MI_CLIP_BOTTOM; \
+ else if (((ddCoord4D *)(in_pt))->y > ((ddCoord4D *)(in_pt))->w) \
+ (oc) |= MI_CLIP_TOP; \
+ if (((ddCoord4D *)(in_pt))->z < -((ddCoord4D *)(in_pt))->w) \
+ (oc) |= MI_CLIP_FRONT; \
+ else if (((ddCoord4D *)(in_pt))->z > ((ddCoord4D *)(in_pt))->w) \
+ (oc) |= MI_CLIP_BACK; \
+ }
+
+#endif
+/*********************************************************************/
+
+/* COMPUTE_CLIP_PARAMS - compute whether or not a point is clipped, and
+ * how far it is to the current clipping boundary
+ */
+
+#define COMPUTE_CLIP_PARAMS(pt,t,Shift,mode,c_clip,HSpace,clip_code ) \
+ \
+ /* pt -4D point in question \
+ * t -floating point scale factor \
+ * Shift -Portion of clip code to work on \
+ * mode -Model or view clipping \
+ * c_clip -current clip plane for view clipping \
+ * HSpace -pointer to half space for model clip \
+ * clip_code -composire clipping code output \
+ */ \
+ \
+ if((mode) == MI_MCLIP) { \
+ \
+ DOT_PRODUCT(&(HSpace)->vector, (pt).ptr, t); \
+ if((t)< ((HSpace)->dist)) clip_code |= (1<<(Shift)); \
+ \
+ } else { \
+ switch (c_clip) \
+ { \
+ case MI_CLIP_LEFT: \
+ if ((pt).p4Dpt->x < -(pt).p4Dpt->w) \
+ clip_code |= (1 << (Shift)); \
+ (t) = (pt).p4Dpt->w + (pt).p4Dpt->x; \
+ break; \
+ case MI_CLIP_RIGHT: \
+ if ((pt).p4Dpt->x > (pt).p4Dpt->w) \
+ clip_code |= (1 << (Shift)); \
+ (t) = (pt).p4Dpt->w - (pt).p4Dpt->x; \
+ break; \
+ case MI_CLIP_BOTTOM: \
+ if ((pt).p4Dpt->y < -(pt).p4Dpt->w) \
+ clip_code |= (1 << (Shift)); \
+ (t) = (pt).p4Dpt->w + (pt).p4Dpt->y; \
+ break; \
+ case MI_CLIP_TOP: \
+ if ((pt).p4Dpt->y > (pt).p4Dpt->w) \
+ clip_code |= (1 << (Shift)); \
+ (t) = (pt).p4Dpt->w - (pt).p4Dpt->y; \
+ break; \
+ case MI_CLIP_FRONT: \
+ if ((pt).p4Dpt->z < -(pt).p4Dpt->w) \
+ clip_code |= (1 << (Shift)); \
+ (t) = (pt).p4Dpt->w + (pt).p4Dpt->z; \
+ break; \
+ case MI_CLIP_BACK: \
+ if ((pt).p4Dpt->z > (pt).p4Dpt->w) \
+ clip_code |= (1 << (Shift)); \
+ (t) = (pt).p4Dpt->w - (pt).p4Dpt->z; \
+ break; \
+ } \
+ }
+
+
+ /* remember that ALL vertex types are of the form:
+ *
+ * |---------------------------|---------|----------|---------|
+ * coords color normal edge
+ * (opt) (opt) (opt)
+ */
+
+/* Assumes that point A is "out" and point B is "in" */
+#define CLIP_AND_COPY(pt_type, in_ptA, t_A, in_ptB, t_B, out_pt) \
+ { \
+ float t; \
+ if (clip_mode == MI_MCLIP) \
+ t = ((MC_HSpace->dist - t_A) / (t_B - t_A)); \
+ else t = (t_A) / ((t_A) - (t_B)); \
+ \
+ *(out_pt).p4Dpt = *(in_ptA).p4Dpt; \
+ \
+ (out_pt).p4Dpt->x += t * ((in_ptB).p4Dpt->x - (in_ptA).p4Dpt->x); \
+ (out_pt).p4Dpt->y += t * ((in_ptB).p4Dpt->y - (in_ptA).p4Dpt->y); \
+ (out_pt).p4Dpt->z += t * ((in_ptB).p4Dpt->z - (in_ptA).p4Dpt->z); \
+ (out_pt).p4Dpt->w += t * ((in_ptB).p4Dpt->w - (in_ptA).p4Dpt->w); \
+ \
+ (in_ptA).p4Dpt++; \
+ (in_ptB).p4Dpt++; \
+ (out_pt).p4Dpt++; \
+ \
+ if (DD_IsVertColour(pt_type)) \
+ { \
+ *(out_pt).pRgbFloatClr = *(in_ptA).pRgbFloatClr; \
+ \
+ (out_pt).pRgbFloatClr->red += \
+ t * ((in_ptB).pRgbFloatClr->red - \
+ (in_ptA).pRgbFloatClr->red); \
+ (out_pt).pRgbFloatClr->green += \
+ t * ((in_ptB).pRgbFloatClr->green - \
+ (in_ptA).pRgbFloatClr->green); \
+ (out_pt).pRgbFloatClr->blue += \
+ t * ((in_ptB).pRgbFloatClr->blue - \
+ (in_ptA).pRgbFloatClr->blue); \
+ (in_ptA).pRgbFloatClr++; \
+ (in_ptB).pRgbFloatClr++; \
+ (out_pt).pRgbFloatClr++; \
+ } \
+ if (DD_IsVertNormal(pt_type)) \
+ { \
+ *(out_pt).pNormal = *(in_ptA).pNormal; \
+ \
+ (out_pt).pNormal->x += \
+ t * ((in_ptB).pNormal->x - \
+ (in_ptA).pNormal->x); \
+ (out_pt).pNormal->y += \
+ t * ((in_ptB).pNormal->y - \
+ (in_ptA).pNormal->y); \
+ (out_pt).pNormal->z += \
+ t * ((in_ptB).pNormal->z - \
+ (in_ptA).pNormal->z); \
+ (in_ptA).pNormal++; \
+ (in_ptB).pNormal++; \
+ (out_pt).pNormal++; \
+ } \
+ \
+ if (DD_IsVertEdge(pt_type)) { \
+ *(out_pt).pEdge = *(in_ptA).pEdge; \
+ (in_ptA).pEdge++; \
+ (in_ptB).pEdge++; \
+ (out_pt).pEdge++; \
+ } \
+ (in_ptA).ptr -= point_size; \
+ (in_ptB).ptr -= point_size; \
+ (out_pt).ptr -= point_size; \
+ }
+
+
+/* Macros to manipulate the forward and backward edge flags of the triangle
+ * strip and quad mesh primitives
+ */
+#define FWD_EDGE_FLAG (1<<0)
+#define BKWD_EDGE_FLAG (1<<1)
+
+#define SET_FWD_EDGE(v_ptr, edge_offset) *(v_ptr + edge_offset) |= FWD_EDGE_FLAG
+#define CLEAR_FWD_EDGE(v_ptr, edge_offset) *(v_ptr + edge_offset) &= ~FWD_EDGE_FLAG
+#define SET_BKWD_EDGE(v_ptr, edge_offset) *(v_ptr + edge_offset) |= BKWD_EDGE_FLAG
+#define CLEAR_BKWD_EDGE(v_ptr, edge_offset) *(v_ptr + edge_offset) \
+ &= ~BKWD_EDGE_FLAG
+
+#define IS_ODD(num) (num & 1) /* macro to determine the correct "sense" of
+ * triangle strip facet in order to correctly
+ * calculate facet normals.
+ */
+
+#define MI_MCLIP 0
+#define MI_VCLIP 1
+
+
+/* JSH - assuming copy may overlap */
+#define COPY_POINT(in_pt, out_pt, point_size) \
+ memmove( (out_pt).ptr, (in_pt).ptr, (point_size) )
+
+/* JSH - assuming copy may overlap */
+#define COPY_FACET(in_fct, out_fct, facet_size) \
+ memmove( (out_fct), (in_fct), (facet_size) )
+
+
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/include/miFont.h b/xc/programs/Xserver/PEX5/ddpex/mi/include/miFont.h
new file mode 100644
index 000000000..5abed9142
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/include/miFont.h
@@ -0,0 +1,132 @@
+/* $TOG: miFont.h /main/5 1998/02/10 12:38:22 kaleb $ */
+
+/***********************************************************
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution of
+the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/include/miFont.h,v 1.2 1999/01/31 12:21:27 dawes Exp $ */
+/*
+ * font internal format
+ */
+#ifndef MI_FONT_H
+#define MI_FONT_H
+
+#include "ddpex.h"
+#include "ddpex3.h"
+#include "miRender.h"
+#include "PEXprotost.h"
+
+#define START_PROPS 0x100
+#define START_DISPATCH(_num_props) (START_PROPS + 160 * _num_props)
+#define START_PATH(_num_ch_, _num_props) (START_DISPATCH(_num_props) + sizeof(Dispatch) * _num_ch_)
+#define NUM_DISPATCH 128
+
+#ifndef PADDING
+#define PADDING(n) ( (n)%4 ? (4 - (n)%4) : 0)
+#endif /* PADDING */
+
+/* definitions in the local font coordinate system */
+#define FONT_COORD_HEIGHT 100.0
+#define FONT_COORD_BASE 0.0
+#define FONT_COORD_CAP 100.0
+#define FONT_COORD_HALF 50.0
+
+typedef enum {
+ PATH_2D=0,
+ PATH_3D=1,
+ PATH_4D=2
+} Font_path_type;
+
+typedef struct {
+ Font_path_type type;
+ ddFLOAT center;
+ ddFLOAT right;
+ ddULONG n_vertices;
+ miListHeader strokes;
+} Ch_stroke_data;
+
+typedef enum {
+ FONT_POLYLINES=0,
+ FONT_SPLINES=1,
+ FONT_POLYGONS=2
+} Font_type;
+
+typedef struct {
+ Font_type font_type;
+ char name[80];
+ unsigned long num_ch;
+ float top, bottom, max_width;
+ Ch_stroke_data **ch_data; /* list of *Ch_stroke_data, one per char */
+ pexFontInfo font_info;
+ pexFontProp *properties; /* list of associated properties */
+ int lutRefCount;/* number of LUTs referencing this font */
+ int freeFlag; /* should this be freed when no more refs */
+} miFontHeader;
+
+typedef struct {
+ ddFLOAT top, bottom, width;
+} Meta_font;
+
+typedef struct {
+ char propname[80];
+ char propvalue[80];
+}Property;
+
+typedef struct
+{
+ int magic; /* magic number */
+ char name[80]; /* name of this font */
+ float top, /* extreme values */
+ bottom,
+ max_width;
+ int num_ch; /* no. of fonts in the set */
+ int num_props; /* no. of font properties */
+ Property *properties; /* array of properties */
+} Font_file_header;
+
+typedef struct
+{
+ float center, /* center of the character */
+ right; /* right edge */
+ long offset; /* offset in the file of the character
+ * description */
+} Dispatch;
+
+#endif /* MI_FONT_H */
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/include/miInfo.h b/xc/programs/Xserver/PEX5/ddpex/mi/include/miInfo.h
new file mode 100644
index 000000000..3005e82dc
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/include/miInfo.h
@@ -0,0 +1,349 @@
+/* $TOG: miInfo.h /main/5 1998/02/10 12:38:27 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+
+/* this file contains the definitions for the enum type and imp dep constant
+ * values
+ * Theoretically, these values can depend on the capabilities of the
+ * different workstation types, which basically depends on the drawable
+ * of the workstation. Currently, the SI support is the same for all
+ * drawables. If your implementation requires different support for each
+ * drawables, then define a similar set of values as these for
+ * each type. They are then loaded in a table which is accessed
+ * according to the drawable type (see ddpex/shared/miMisc.c).
+ */
+
+#ifndef MI_INFO_H
+#define MI_INFO_H
+
+#include "miNS.h"
+/* imp dep constants */
+
+/* These values are in two arrays that can be accessed by
+ * the PEXID constant value. Two arrays are used since some values are CARD32 and
+ * some are FLOAT. SI_NUM_..._IMPS define how many values there are of each type
+ */
+
+/* card32s */
+#define SI_NUM_INT_IMPS 22
+
+#define SI_DITHERING_SUPPORTED MI_FALSE
+#define SI_MAX_EDGE_WIDTH ~((unsigned long)0)
+#define SI_MAX_LINE_WIDTH ~((unsigned long)0)
+#define SI_MAX_MARKER_SIZE ~((unsigned long)0)
+#define SI_MAX_MODEL_CLIP_PLANES 64
+#define SI_MAX_NAME_SET_NAMES MINS_NAMESET_SIZE
+#define SI_MAX_NON_AMBIENT_LIGHTS 64
+#define SI_MAX_NURB_ORDER 10
+#define SI_MAX_TRIM_CURVE_ORDER 6
+#define SI_MIN_EDGE_WIDTH 1
+#define SI_MIN_LINE_WIDTH 1
+#define SI_MIN_MARKER_SIZE 1
+#define SI_NOM_EDGE_WIDTH 1 /* nominal edge width */
+#define SI_NOM_LINE_WIDTH 1 /* nominal line width */
+#define SI_NOM_MARKER_SIZE 1 /* nominal marker size */
+#define SI_SUPP_EDGE_WIDTHS ~((unsigned long)0) /* number of supported edge widths */
+#define SI_SUPP_LINE_WIDTHS ~((unsigned long)0) /* number of supported line widths */
+#define SI_SUPP_MARKER_SIZES ~((unsigned long)0) /* number of supported marker sizes */
+#define SI_BEST_COLOUR_APPROX_VALUES PEXColourApproxAnyValues
+#define SI_TRANSPARENCY_SUPPORTED MI_FALSE
+#define SI_DOUBLE_BUFFERING_SUPPORTED MI_TRUE
+#define SI_MAX_HITS_EVENT_SUPPORTED MI_TRUE
+
+/* floats */
+#define SI_NUM_FLOAT_IMPS 12
+
+/* ALL CIE primary chromaticity coefficients are taken from
+ * Rodgers' Procedural Elements for Computer Graphics
+ * for Color CRT monitor aligned to d6500 white
+ */
+#define SI_CHROM_RED_U 0.628
+#define SI_CHROM_RED_V 0.346
+#define SI_LUM_RED 1.0
+#define SI_CHROM_GREEN_U 0.268
+#define SI_CHROM_GREEN_V 0.588
+#define SI_LUM_GREEN 1.0
+#define SI_CHROM_BLUE_U 0.150
+#define SI_CHROM_BLUE_V 0.070
+#define SI_LUM_BLUE 1.0
+#define SI_CHROM_WHITE_U 0.313
+#define SI_CHROM_WHITE_V 0.329
+#define SI_LUM_WHITE 1.0
+
+
+/* enumerated type info */
+
+/* the SI_..._NUM value is the number of supported types */
+
+/* If you are changing these values.....
+ * OK, I blew it here. You gotta change the NUM info here
+ * AND you gotta go into ../shared/miMisc.c and change the
+ * stuff that's in the info tables. Maybe there's a way
+ * to do this so you can just go to one place and change it
+ * Also, this info isn't coded to match what's really happening
+ * in the rendering, so's if you change what happens during
+ * rendering, you gotta come here and change dese tables too.
+ * It isn't all done automagically and it probably should, but
+ * it's too late now. These values are used when setting the
+ * real_entry of LUTS.
+ */
+
+/* marker type */
+#define SI_MARKER_NUM 5
+#define SI_MARKER_1 "Dot"
+#define SI_MARKER_2 "Cross"
+#define SI_MARKER_3 "Asterisk"
+#define SI_MARKER_4 "Circle"
+#define SI_MARKER_5 "X"
+
+/* annotation text style */
+#define SI_ATEXT_NUM 2
+#define SI_ATEXT_1 "NotConnected"
+#define SI_ATEXT_2 "Connected"
+
+/* interior style */
+#define SI_INT_NUM 3
+#define SI_INT_1 "Hollow"
+#define SI_INT_2 "Solid"
+#define SI_INT_5 "Empty"
+/* others */
+#define SI_INT_3 "Pattern"
+#define SI_INT_4 "Hatch"
+
+/* hatch style */
+#define SI_HATCH_NUM 0
+
+/* line type */
+#define SI_LINE_NUM 4
+#define SI_LINE_1 "Solid"
+#define SI_LINE_2 "Dashed"
+#define SI_LINE_3 "Dotted"
+#define SI_LINE_4 "DashDot"
+
+/* surface edge type */
+#define SI_EDGE_NUM 4
+#define SI_EDGE_1 "Solid"
+#define SI_EDGE_2 "Dashed"
+#define SI_EDGE_3 "Dotted"
+#define SI_EDGE_4 "DashDot"
+
+/* pick device type */
+#define SI_PICK_DEVICE_NUM 2
+#define SI_PICK_DEVICE_1 "DC_HitBox"
+#define SI_PICK_DEVICE_2 "NPC_HitVolume"
+
+/* pick one methods */
+#define SI_PICK_ONE_NUM 1
+#define SI_PICK_ONE_LAST "Last"
+/* others */
+#define SI_PICK_ONE_CLOSEST_Z "ClosestZ"
+#define SI_PICK_ONE_VISIBLE_ANY "VisibleAny"
+#define SI_PICK_ONE_VISIBLE_CLOSEST "VisibleClosest"
+
+/* pick all methods */
+#define SI_PICK_ALL_NUM 1
+#define SI_PICK_ALL_ALL "All"
+/* others */
+#define SI_PICK_ALL_VISIBLE "Visible"
+
+/* polyline interpolation method */
+#define SI_LINE_INTERP_NUM 1
+#define SI_LINE_INTERP_1 "None"
+/* others */
+#define SI_LINE_INTERP_2 "Color"
+
+/* curve approximation method */
+#define SI_CURVE_APPROX_NUM 6
+#define SI_CURVE_APPROX_1 "ConstantBetweenKnots" /* (Imp. Dep.) */
+#define SI_CURVE_APPROX_2 "ConstantBetweenKnots"
+#define SI_CURVE_APPROX_3 "WCS_ChordalSize"
+#define SI_CURVE_APPROX_4 "NPC_ChordalSize"
+#define SI_CURVE_APPROX_6 "WCS_ChordalDev"
+#define SI_CURVE_APPROX_7 "NPC_ChordalDev"
+/* others */
+#define SI_CURVE_APPROX_5 "DC_ChordalSize"
+#define SI_CURVE_APPROX_8 "DC_ChordalDev"
+#define SI_CURVE_APPROX_9 "WCS_Relative"
+#define SI_CURVE_APPROX_10 "NPC_Relative"
+#define SI_CURVE_APPROX_11 "DC_Relative"
+
+/* reflection method */
+#define SI_REFLECT_NUM 4
+#define SI_REFLECT_1 "NoShading"
+#define SI_REFLECT_2 "Ambient"
+#define SI_REFLECT_3 "Diffuse"
+#define SI_REFLECT_4 "Specular"
+/* others */
+
+/* surface interpolation method */
+#define SI_SURF_INTERP_NUM 1
+#define SI_SURF_INTERP_1 "None"
+/* others */
+#define SI_SURF_INTERP_2 "Color"
+#define SI_SURF_INTERP_3 "DotProduct"
+#define SI_SURF_INTERP_4 "Normal"
+
+/* surface approximation method */
+#define SI_SURF_APPROX_NUM 6
+#define SI_SURF_APPROX_1 "ConstantBetweenKnots" /* (Imp. Dep.) */
+#define SI_SURF_APPROX_2 "ConstantBetweenKnots"
+#define SI_SURF_APPROX_3 "WCS_ChordalSize"
+#define SI_SURF_APPROX_4 "NPC_ChordalSize"
+#define SI_SURF_APPROX_6 "WCS_PlanarDev"
+#define SI_SURF_APPROX_7 "NPC_PlanarDev"
+/* others */
+#define SI_SURF_APPROX_5 "DC_ChordalSize"
+#define SI_SURF_APPROX_8 "DC_PlanarDev"
+#define SI_SURF_APPROX_9 "WCS_Relative"
+#define SI_SURF_APPROX_10 "NPC_Relative"
+#define SI_SURF_APPROX_11 "DC_Relative"
+
+/* trim curve approximation method */
+#define SI_TRIM_CURVE_NUM 2
+#define SI_TRIM_CURVE_1 "ConstantBetweenKnots" /* (Imp. Dep.) */
+#define SI_TRIM_CURVE_2 "ConstantBetweenKnots"
+
+/* model clip operator */
+#define SI_MODEL_CLIP_NUM 2
+#define SI_MODEL_CLIP_1 "Replace"
+#define SI_MODEL_CLIP_2 "Intersection"
+
+/* light type */
+#define SI_LIGHT_NUM 4
+#define SI_LIGHT_1 "Ambient"
+#define SI_LIGHT_2 "WCS_Vector"
+#define SI_LIGHT_3 "WCS_Point"
+#define SI_LIGHT_4 "WCS_Spot"
+
+/* colour type */
+#define SI_COLOUR_NUM 2
+#define SI_COLOUR_0 "Indexed"
+#define SI_COLOUR_1 "RGBFloat"
+/* others */
+#define SI_COLOUR_2 "CIEFloat"
+#define SI_COLOUR_3 "HSVFloat"
+#define SI_COLOUR_4 "HLSFloat"
+#define SI_COLOUR_5 "RGBInt8"
+#define SI_COLOUR_6 "RGBInt16"
+
+/* float format */
+#define SI_FLOAT_NUM 2
+#define SI_FLOAT_1 "IEEE_754_32"
+#define SI_FLOAT_2 "DEC_F_Floating"
+/* others */
+#define SI_FLOAT_3 "IEEE_754_64"
+#define SI_FLOAT_4 "DEC_D_Floating"
+
+/* hlhsr mode */
+#define SI_HLHSR_NUM 1
+#define SI_HLHSR_1 "Off"
+/* others */
+#define SI_HLHSR_2 "ZBuffer"
+#define SI_HLHSR_3 "Painters"
+#define SI_HLHSR_4 "Scanline"
+#define SI_HLHSR_5 "HiddenLineOnly"
+#define SI_HLHSR_6 "ZBufferId"
+
+/* prompt echo type */
+#define SI_PET_NUM 1
+#define SI_PET_1 "EchoPrimitive"
+/* others */
+#define SI_PET_2 "EchoStructure"
+#define SI_PET_3 "EchoNetwork"
+
+/* display update mode */
+#define SI_UPDATE_NUM 5
+#define SI_UPDATE_1 "VisualizeEach"
+#define SI_UPDATE_2 "VisualizeEasy"
+#define SI_UPDATE_3 "VisualizeNone"
+#define SI_UPDATE_4 "SimulateSome"
+#define SI_UPDATE_5 "VisualizeWhenever"
+
+/* colour approximation type */
+#define SI_CLR_APPROX_TYPE_NUM 2
+#define SI_CLR_APPROX_TYPE_1 "ColorSpace"
+#define SI_CLR_APPROX_TYPE_2 "ColorRange"
+
+/* colour approximation model */
+#define SI_CLR_APPROX_MODEL_NUM 1
+#define SI_CLR_APPROX_MODEL_1 "RGB"
+/* others */
+#define SI_CLR_APPROX_MODEL_2 "CIE"
+#define SI_CLR_APPROX_MODEL_3 "HSV"
+#define SI_CLR_APPROX_MODEL_4 "HLS"
+#define SI_CLR_APPROX_MODEL_5 "YIQ"
+
+/* gdp */
+#define SI_GDP_NUM 0
+
+/* gdp3 */
+#define SI_GDP3_NUM 0
+
+/* gse */
+#define SI_GSE_NUM 0
+
+/* escape */
+#define SI_ESCAPE_NUM 1
+#define SI_ESCAPE_1 "SetEchoColor"
+
+/* rendering colour model */
+#define SI_REND_COLOUR_NUM 1
+#define SI_REND_COLOUR_1 "RGB"
+/* others */
+#define SI_REND_COLOUR_0 "(Imp. Dep.)"
+#define SI_REND_COLOUR_2 "CIE"
+#define SI_REND_COLOUR_3 "HSV"
+#define SI_REND_COLOUR_4 "HLS"
+
+/* parametric surface characteristics */
+#define SI_P_SURF_CHAR_NUM 3
+#define SI_P_SURF_CHAR_1 "None"
+#define SI_P_SURF_CHAR_2 "None"
+#define SI_P_SURF_CHAR_3 "IsoparametricCurves"
+/* others */
+#define SI_P_SURF_CHAR_4 "MC_LevelCurves"
+#define SI_P_SURF_CHAR_5 "WC_Levelcurves"
+
+#endif /* MI_INFO_H */
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/include/miLUT.h b/xc/programs/Xserver/PEX5/ddpex/mi/include/miLUT.h
new file mode 100644
index 000000000..14b8b86b2
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/include/miLUT.h
@@ -0,0 +1,432 @@
+/* $TOG: miLUT.h /main/5 1998/02/10 12:38:32 kaleb $ */
+
+/***********************************************************
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution of
+the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS 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 MILUT_H
+#define MILUT_H
+
+#include "mipex.h"
+
+/****** devPriv data structures ******/
+/* pex-si uses data which looks like pex protocol format */
+
+typedef struct {
+ ddEnumTypeIndex lineType;
+ ddEnumTypeIndex polylineInterp;
+ ddCurveApprox curveApprox;
+ ddFLOAT lineWidth; /* this is really a scale */
+ ddColourSpecifier lineColour;
+} ddLineBundleEntry;
+
+typedef struct {
+ ddEnumTypeIndex markerType;
+ ddSHORT unused;
+ ddFLOAT markerScale; /* this really is a scale */
+ ddColourSpecifier markerColour;
+} ddMarkerBundleEntry;
+
+typedef struct {
+ ddUSHORT textFontIndex;
+ ddUSHORT textPrecision;
+ ddFLOAT charExpansion;
+ ddFLOAT charSpacing;
+ ddColourSpecifier textColour;
+} ddTextBundleEntry;
+
+typedef struct {
+ ddEnumTypeIndex interiorStyle;
+ ddSHORT interiorStyleIndex;
+ ddEnumTypeIndex reflectionModel;
+ ddEnumTypeIndex surfaceInterp;
+ ddEnumTypeIndex bfInteriorStyle;
+ ddSHORT bfInteriorStyleIndex;
+ ddEnumTypeIndex bfReflectionModel;
+ ddEnumTypeIndex bfSurfaceInterp;
+ ddSurfaceApprox surfaceApprox;
+ ddColourSpecifier surfaceColour;
+ ddReflectionAttr reflectionAttr;
+ ddColourSpecifier bfSurfaceColour;
+ ddReflectionAttr bfReflectionAttr;
+} ddInteriorBundleEntry;
+
+typedef struct {
+ ddSwitch edges;
+ ddUCHAR unused;
+ ddEnumTypeIndex edgeType;
+ ddFLOAT edgeWidth; /* this is really a scale */
+ ddColourSpecifier edgeColour;
+} ddEdgeBundleEntry;
+
+typedef struct {
+ ddSHORT colourType;
+ ddUSHORT numx;
+ ddUSHORT numy;
+ ddUSHORT unused;
+ /* LISTof Colour(numx, numy) 2D array of colours */
+ union {
+ ddIndexedColour *indexed;
+ ddRgb8Colour *rgb8;
+ ddRgb16Colour *rgb16;
+ ddRgbFloatColour *rgbFloat;
+ ddHsvColour *hsvFloat;
+ ddHlsColour *hlsFloat;
+ ddCieColour *cieFloat;
+ } colours;
+} ddPatternEntry;
+
+/* a ddColourEntry is just ddColourSpecifier */
+
+#define MILUT_MAX_CS_PER_ENTRY 16
+/* Much easier to code if this is a fixed size entry, thus we'll have it
+ * max out at MAX_CS_PER_ENTRY charsets per entry, MAX_CS_PER_ENTRY character
+ * sets per font group seems plenty reasonable. */
+
+typedef struct {
+ ddULONG numFonts;
+ diFontHandle fonts[MILUT_MAX_CS_PER_ENTRY]; /* list of fonts */
+} ddTextFontEntry;
+
+/* a ddViewEntry is defined in ddpex.h */
+
+typedef struct {
+ ddEnumTypeIndex lightType;
+ ddSHORT unused;
+ ddVector3D direction;
+ ddCoord3D point;
+ ddFLOAT concentration;
+ ddFLOAT spreadAngle;
+ ddFLOAT attenuation1;
+ ddFLOAT attenuation2;
+ ddColourSpecifier lightColour;
+} ddLightEntry;
+
+typedef struct {
+ ddUCHAR mode;
+ ddUCHAR unused;
+ ddUSHORT unused2;
+ ddFLOAT frontPlane;
+ ddFLOAT backPlane;
+ ddFLOAT frontScaling;
+ ddFLOAT backScaling;
+ ddColourSpecifier depthCueColour;
+} ddDepthCueEntry;
+
+typedef struct {
+ ddEnumTypeIndex approxType;
+ ddEnumTypeIndex approxModel;
+ ddUSHORT max1;
+ ddUSHORT max2;
+ ddUSHORT max3;
+ ddUCHAR dither;
+ ddUCHAR unused;
+ ddULONG mult1;
+ ddULONG mult2;
+ ddULONG mult3;
+ ddFLOAT weight1;
+ ddFLOAT weight2;
+ ddFLOAT weight3;
+ ddULONG basePixel;
+} ddColourApproxEntry;
+
+/* table entry definitions */
+/* some definitions contain a set and realized entry. this happens when
+ * realized data can differ from set data.
+ */
+
+/* status values */
+#define MILUT_UNDEFINED 0
+#define MILUT_PREDEFINED 1
+#define MILUT_DEFINED 2
+
+/* the device independent information for all table entries */
+typedef struct {
+ ddUSHORT status;
+ ddTableIndex index;
+} miTableEntry;
+
+typedef struct _miLineBundleEntry {
+ miTableEntry entry_info;
+/* device dependent data */
+ ddLineBundleEntry entry; /* set entry */
+ ddLineBundleEntry real_entry; /* realized entry */
+} miLineBundleEntry;
+
+typedef struct _miMarkerBundleEntry {
+ miTableEntry entry_info;
+/* device dependent data */
+ ddMarkerBundleEntry entry; /* set entry */
+ ddMarkerBundleEntry real_entry; /* realized entry */
+} miMarkerBundleEntry;
+
+typedef struct _miTextBundleEntry {
+ miTableEntry entry_info;
+/* device dependent data */
+ ddTextBundleEntry entry; /* set entry */
+ ddTextBundleEntry real_entry; /* realized entry */
+} miTextBundleEntry;
+
+typedef struct _miInteriorBundleEntry {
+ miTableEntry entry_info;
+/* device dependent data */
+ ddInteriorBundleEntry entry; /* set entry */
+ ddInteriorBundleEntry real_entry; /* realized entry */
+} miInteriorBundleEntry;
+
+typedef struct _miEdgeBundleEntry {
+ miTableEntry entry_info;
+/* device dependent data */
+ ddEdgeBundleEntry entry; /* set entry */
+ ddEdgeBundleEntry real_entry; /* realized entry */
+} miEdgeBundleEntry;
+
+typedef struct _miPatternEntry {
+ miTableEntry entry_info;
+/* device dependent data */
+ ddPatternEntry entry; /* set entry = realized entry */
+} miPatternEntry;
+
+/* each entry in the font table is a list of PEX or X fonts. */
+typedef struct _miTextFontEntry {
+ miTableEntry entry_info;
+/* device dependent data */
+ ddTextFontEntry entry; /* set entry = realized entry */
+} miTextFontEntry;
+
+typedef struct _miColourEntry {
+ miTableEntry entry_info;
+/* device dependent data */
+ ddColourSpecifier entry; /* set entry = realized entry */
+} miColourEntry;
+
+typedef struct _miViewEntry {
+ miTableEntry entry_info;
+/* device dependent data */
+ ddViewEntry entry; /* set entry = realized entry */
+ ddFLOAT vom[4][4]; /* concated mats */
+ ddFLOAT vom_inv[4][4]; /* inverse of vom */
+ ddBOOL inv_flag; /* is vom_inv current */
+} miViewEntry;
+
+typedef struct _miLightEntry {
+ miTableEntry entry_info;
+/* device dependent data */
+ ddLightEntry entry; /* set entry = realized entry */
+ double cosSpreadAngle; /* cosine */
+} miLightEntry;
+
+typedef struct _miDepthCueEntry {
+ miTableEntry entry_info;
+/* device dependent data */
+ ddDepthCueEntry entry; /* set entry = realized entry */
+} miDepthCueEntry;
+
+typedef struct _miColourApproxEntry {
+ miTableEntry entry_info;
+/* device dependent data */
+ ddColourApproxEntry entry; /* set entry = realized entry */
+} miColourApproxEntry;
+
+typedef ddpex43rtn (*miOpsTableType)();
+
+typedef struct _miLUTHeader {
+ /* the resource id is in the dipex resource structure */
+ /* the lut type is also in the dipex resource structure */
+ ddDrawableInfo drawExample;
+ ddSHORT drawType;
+ /* there are macros defined in this file to get at these: */
+ ddUSHORT startIndex;
+ ddUSHORT defaultIndex;
+ ddUSHORT numDefined;
+ ddTableInfo tableInfo;
+ /**/
+ listofObj *wksRefList;
+ listofObj *rendRefList;
+ ddBOOL freeFlag;
+/* the lut entries are just an array of entries. this works OK
+ * for small tables. if you want a large table, you'll probably
+ * want to change this scheme to use a hash table into the array
+ * or maybe n-ary trees to improve performance of searching for
+ * entries (see macros below). PEX-SI does linear search
+ */
+ union {
+ miLineBundleEntry *line;
+ miMarkerBundleEntry *marker;
+ miTextBundleEntry *text;
+ miInteriorBundleEntry *interior;
+ miEdgeBundleEntry *edge;
+ miPatternEntry *pattern;
+ miTextFontEntry *font;
+ miColourEntry *colour;
+ miViewEntry *view;
+ miLightEntry *light;
+ miDepthCueEntry *depthCue;
+ miColourApproxEntry *colourApprox;
+ } plut;
+/* Table of operation procs for luts. One for each lut request & some
+ * internal ones.
+ * Individual procedures can be loaded depending on the lut type.
+ * These procs are defined in the files mi<type>LUT.c.
+ * diPEX always calls 'general' procedures (defined in miLUT.c)
+ * directly. Those procedures then call the individual procs through
+ * this table as needed. Not all requests need to be handled
+ * differently for each table type. For those requests, the
+ * general procedure does all of the work and there is no individual
+ * procedure. The general procedure is loaded into the table for
+ * that op.
+ */
+#define MILUT_MIN_REQUEST PEX_CreateLookupTable
+#define MILUT_MAX_REQUEST PEX_DeleteTableEntries
+#define MILUT_IMPDEP_REQUESTS 6
+#define MILUT_NUM_REQUESTS (MILUT_MAX_REQUEST - MILUT_MIN_REQUEST + 1 + MILUT_IMPDEP_REQUESTS)
+/* map pex request opcode to index into op table */
+#define MILUT_REQUEST_OP(req) ((req) - MILUT_MIN_REQUEST)
+/* imp dep opcodes to use to map into op table */
+#define milut_InquireEntryAddress (MILUT_MAX_REQUEST + 1)
+#define milut_entry_check (milut_InquireEntryAddress + 1)
+#define milut_copy_pex_to_mi (milut_entry_check + 1)
+#define milut_copy_mi_to_pex (milut_copy_pex_to_mi + 1)
+#define milut_realize_entry (milut_copy_mi_to_pex + 1)
+#define milut_mod_call_back (milut_realize_entry + 1)
+
+ miOpsTableType ops[MILUT_NUM_REQUESTS];
+} miLUTHeader;
+
+#define MILUT_HEADER(handle) \
+ ((miLUTHeader *)(handle)->deviceData)
+
+#define MILUT_DEFINE_HEADER(handle, phead) \
+ miLUTHeader *(phead) = MILUT_HEADER(handle)
+
+#define MILUT_DESTROY_HEADER( phead ) \
+ puDeleteList( (phead)->wksRefList ); \
+ puDeleteList( (phead)->rendRefList ); \
+ xfree((phead)->plut.line); \
+ xfree((phead))
+
+#define MILUT_CHECK_DESTROY( handle, phead ) \
+ if ( (phead)->freeFlag && \
+ !(phead)->wksRefList->numObj && \
+ !(phead)->rendRefList->numObj ) \
+ { \
+ MILUT_DESTROY_HEADER( phead ); \
+ xfree(handle); \
+ }
+
+#define MILUT_MAX_INDEX 65535
+
+#define MILUT_TYPE(handle) (handle->lutType)
+
+#define MILUT_START_INDEX( pheader ) \
+ (pheader)->startIndex
+
+/* max number of definable entries */
+#define MILUT_DEF_ENTS( pheader ) \
+ (pheader)->tableInfo.definableEntries
+
+#define MILUT_ALLOC_ENTS( pheader ) \
+ (MILUT_DEF_ENTS(pheader))
+
+/* number of predefined entries */
+#define MILUT_PRENUM( pheader ) \
+ (pheader)->tableInfo.numPredefined
+
+/* index of first predefined entry */
+#define MILUT_PREMIN( pheader ) \
+ (pheader)->tableInfo.predefinedMin
+
+/* index of last predefined entry: premax = premin + prenum - 1 */
+#define MILUT_PREMAX( pheader ) \
+ (pheader)->tableInfo.predefinedMax
+
+/* number of defined entries (includes predefined ones) */
+#define MILUT_NUM_ENTS( pheader ) \
+ (pheader)->numDefined
+
+/* index of default entry */
+#define MILUT_DEFAULT_INDEX( pheader ) \
+ (pheader)->defaultIndex
+
+#define MILUT_COPY_COLOUR(Colour, Buf, Type) \
+ mibcopy((Colour), (Buf), colour_type_sizes[(int) (Type)])
+
+/* set status of entries
+ * i must be declared when using this
+ * and pentry must be pointing to the first entry to set status
+ * if the flag is TRUE, the entry's index is also set
+ * The flag is used to 'set up' the table to be used with a full table
+ * of contiguous indices (as apposed to a sparse table where entries
+ * can have any index value) most efficiently. Sparse entries will
+ * work, but continguous entries are used more often (I know - sparse
+ * entries haven't worked for almost 2 years and no-one has complained)
+ */
+#define MILUT_SET_STATUS( pentry, num_ents, stat, flag ) \
+ for ( i=0; i<(num_ents); i++, (pentry)++ ) { \
+ (pentry)->entry_info.status = (stat); \
+ if (flag) (pentry)->entry_info.index = i; }
+
+/* return pointer to entry with index 'index'. if that entry
+ * is not defined, return NULL
+ * pentry must be initially pointing to entry where search is to
+ * begin
+ * plast must be pointing to the last definable entry in the lut
+ * This does a linear search. Change this to a more efficient
+ * method for large tables
+ */
+#define MILUT_GET_ENTRY(ind, pentry, plast) \
+ while ( ((pentry) < (plast)) && ((ind) != (pentry)->entry_info.index) ) \
+ (pentry)++; \
+ if ((pentry) == (plast)) pentry = NULL; \
+ else if ((ind) != (pentry)->entry_info.index) pentry = NULL
+
+#define MILUT_INIT_COLOUR(Colour) \
+ (Colour).colourType = PEXIndexedColour; \
+ (Colour).colour.indexed.index = 1
+
+/* modification types passed to call back procedure */
+#define MILUT_COPY_MOD 0
+#define MILUT_SET_MOD 1
+#define MILUT_DEL_MOD 2
+
+#endif /* MILUT_H */
+
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/include/miLight.h b/xc/programs/Xserver/PEX5/ddpex/mi/include/miLight.h
new file mode 100644
index 000000000..65edb6b19
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/include/miLight.h
@@ -0,0 +1,272 @@
+/* $TOG: miLight.h /main/5 1998/02/10 12:38:37 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/include/miLight.h,v 1.4 1998/10/04 09:34:07 dawes Exp $ */
+
+#ifndef MI_LIGHT_H
+#define MI_LIGHT_H
+
+/* Macros for lighting calculations */
+
+/****
+ *
+ * Name: NEAR_ZERO
+ * Synopsis: determine if a floating point ia approximately 0.
+ *
+ ****/
+#define ZERO_TOLERANCE 1.0e-30
+#define NEAR_ZERO(a) \
+ ( ((a) < 0) ? ((a) > -ZERO_TOLERANCE) : ((a) < ZERO_TOLERANCE) )
+
+/****
+ *
+ * Name: DOT_PRODUCT
+ * Synopsis: Compute the Dot (or inner) product of two vectors
+ *
+ ****/
+#define DOT_PRODUCT(v1, v2, v1_dot_v2) \
+{ \
+ ddFLOAT *t1, *t2; \
+ t1 = (ddFLOAT *) (v1); \
+ t2 = (ddFLOAT *) (v2); \
+ (v1_dot_v2) = (*(t1++) * *(t2++)); \
+ (v1_dot_v2) += (*(t1++) * *(t2++)); \
+ (v1_dot_v2) += (*(t1 ) * *(t2 )); \
+}
+
+
+/****
+ *
+ * Name: CROSS_PRODUCT
+ * Synopsis: Give three points p0, p1, p2, compute the cross product
+ * of the two vectors (p1p0)x(p1p2). This corresponds to
+ * computing the geomtric normal of a facet whose coordinates
+ * are specified in counter-clockwise order.
+ *
+ ****/
+#define CROSS_PRODUCT(p0, p1, p2, v) \
+{ \
+ register ddFLOAT *t; \
+ t = (ddFLOAT *) (v); \
+ *(t++) = (((p2->y-p1->y)*(p0->z-p1->z))-((p0->y-p1->y)*(p2->z-p1->z))); \
+ *(t++) = -(((p2->x-p1->x)*(p0->z-p1->z))-((p0->x-p1->x)*(p2->z-p1->z))); \
+ *(t ) = (((p2->x-p1->x)*(p0->y-p1->y))-((p0->x-p1->x)*(p2->y-p1->y))); \
+}
+
+
+/****
+ *
+ * Name: COPY_VECTOR
+ * Synopsis: Copy a 3-component vector.
+ *
+ ****/
+#define COPY_VECTOR(dest, src) \
+{ \
+ register ddFLOAT *d, *s; \
+ d = (ddFLOAT *) (dest); \
+ s = (ddFLOAT *) (src); \
+ *(d++) = *(s++); \
+ *(d++) = *(s++); \
+ *(d ) = *(s ); \
+}
+
+
+/****
+ *
+ * Name: NEGATE_VECTOR
+ * Synopsis: Reverse direction of a 3-component vector.
+ *
+ ****/
+#define NEGATE_VECTOR(dest, src) \
+{ \
+ register ddFLOAT *d, *s; \
+ d = (ddFLOAT *) (dest); \
+ s = (ddFLOAT *) (src); \
+ *(d++) = -(*(s++)); \
+ *(d++) = -(*(s++)); \
+ *(d ) = -(*(s )); \
+}
+
+
+/****
+ *
+ * Name: NORMALIZE_VECTOR
+ * Synopsis: Normalize a 3-component vector.
+ * Description: Replace arbitrary vector with unit vector (same direction)
+ * and also return the original length.
+ *
+ ****/
+#define NORMALIZE_VECTOR(vector, length) \
+{ \
+ ddFLOAT *v; \
+ v = (ddFLOAT *) (vector); \
+ DOT_PRODUCT(v, v, (length)); \
+ (length) = sqrt ((length)); \
+ if (length != 0.0) { \
+ *(v++) /= (length); \
+ *(v++) /= (length); \
+ *(v ) /= (length); \
+ } \
+}
+
+
+/****
+ *
+ * Name: CALCULATE_REFLECTION_VECTOR
+ * Synopsis: Calculates the reflection vector as determined by
+ * the laws of geometrical optics.
+ *
+ ****/
+#define CALCULATE_REFLECTION_VECTOR(refl, n_dot_l, normal, light) \
+{ \
+ ddFLOAT *r, *n, *l; \
+ ddFLOAT temp; \
+ r = (ddFLOAT *) (refl); \
+ temp = 2.0 * (n_dot_l); \
+ n = (ddFLOAT *) (normal); \
+ l = (ddFLOAT *) (light); \
+ *(r++) = temp * (*(n++)) - *(l++); \
+ *(r++) = temp * (*(n++)) - *(l++); \
+ *(r ) = temp * (*(n )) - *(l ); \
+}
+
+
+/****
+ *
+ * Name: CALCULATE_DIRECTION_VECTOR
+ * Synopsis: Calculates the direction vector (without normalization)
+ * from one position to another.
+ *
+ ****/
+#define CALCULATE_DIRECTION_VECTOR(to, from, dir) \
+{ \
+ register ddFLOAT *d, *t, *f; \
+ d = (ddFLOAT *) (dir); \
+ t = (ddFLOAT *) (to); \
+ f = (ddFLOAT *) (from); \
+ *(d++) = *(t++) - *(f++); \
+ *(d++) = *(t++) - *(f++); \
+ *(d ) = *(t ) - *(f ); \
+}
+
+/****
+ *
+ * Name: APPLY_DEPTH_CUING
+ * Synopsis: Applies depth cueing calculation to a colour
+ * value according to the suggested equations of
+ * the PHIGS spec, "Annex E - Informative"
+ *
+ ****/
+#define APPLY_DEPTH_CUEING(dcue_entry, pt_depth, in_color, out_color) \
+{ \
+ float tmp1, tmp2; \
+ \
+ if ((pt_depth) > (dcue_entry).frontPlane) { \
+ tmp1 = (1.0 - ((dcue_entry).frontScaling)); \
+ (out_color)->red = \
+ ((dcue_entry).frontScaling * (in_color)->red) + \
+ ((tmp1) * (dcue_entry).depthCueColour.colour.rgbFloat.red); \
+ \
+ (out_color)->green = \
+ ((dcue_entry).frontScaling * (in_color)->green) + \
+ ((tmp1) * (dcue_entry).depthCueColour.colour.rgbFloat.green);\
+ \
+ (out_color)->blue = \
+ ((dcue_entry).frontScaling * (in_color)->blue) + \
+ ((tmp1) * (dcue_entry).depthCueColour.colour.rgbFloat.blue); \
+ \
+ } else if ((pt_depth) < (dcue_entry).backPlane) { \
+ tmp1 = (1.0 - ((dcue_entry).backScaling)); \
+ (out_color)->red = \
+ ((dcue_entry).backScaling * (in_color)->red) + \
+ ((tmp1) * (dcue_entry).depthCueColour.colour.rgbFloat.red); \
+ \
+ (out_color)->green = \
+ ((dcue_entry).backScaling * (in_color)->green) + \
+ ((tmp1) * (dcue_entry).depthCueColour.colour.rgbFloat.green);\
+ \
+ (out_color)->blue = \
+ ((dcue_entry).backScaling * (in_color)->blue) + \
+ ((tmp1) * (dcue_entry).depthCueColour.colour.rgbFloat.blue); \
+ \
+ } else { /* between front and back planes */ \
+ \
+ tmp1 = ((dcue_entry).backScaling + \
+ (((pt_depth) - (dcue_entry).backPlane) * \
+ (((dcue_entry).frontScaling-(dcue_entry).backScaling) / \
+ ((dcue_entry).frontPlane-(dcue_entry).backPlane)) ) ); \
+ \
+ tmp2 = (1.0 - tmp1); \
+ \
+ (out_color)->red = (((tmp1) * (in_color)->red) + \
+ (tmp2 * (dcue_entry).depthCueColour.colour.rgbFloat.red)); \
+ \
+ (out_color)->green = (((tmp1) * (in_color)->green) + \
+ (tmp2 * (dcue_entry).depthCueColour.colour.rgbFloat.green)); \
+ \
+ (out_color)->blue = (((tmp1) * (in_color)->blue) + \
+ (tmp2 * (dcue_entry).depthCueColour.colour.rgbFloat.blue)); \
+ } \
+}
+
+/*
+ *
+ * Name: AVERAGE
+ * Synopsis: Give three points p0, p1, p2, compute the average
+ * position in world coordinates
+ *
+ ****/
+#define AVERAGE(p0, p1, p2, avg) \
+{ \
+ register ddFLOAT *t; \
+ t = (ddFLOAT *) (avg); \
+ *(t++) = ((p0->x) + (p1->x) + (p2->x)) / 3.0; \
+ *(t++) = ((p0->y) + (p1->y) + (p2->y)) / 3.0; \
+ *(t ) = ((p0->z) + (p1->z) + (p2->z)) / 3.0; \
+}
+
+
+
+#endif
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/include/miLineDash.h b/xc/programs/Xserver/PEX5/ddpex/mi/include/miLineDash.h
new file mode 100644
index 000000000..601226301
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/include/miLineDash.h
@@ -0,0 +1,72 @@
+/* $TOG: miLineDash.h /main/3 1998/02/10 12:38:43 kaleb $ */
+
+/*****************************************************************
+
+Copyright 1989,1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Copyright 1989,1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Sun Microsystems,
+and The Open Group, not be used in advertising or publicity
+pertaining to distribution of the software without specific, written
+prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS 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 MI_LINEDASH_H
+#define MI_LINEDASH_H
+
+/*
+ * Define the pre-defined PEX line dash types for ddx
+ *
+ * PEX defines four line dash styles:
+ *
+ * PEXLineTypeSolid
+ * clearly no pattern needed here!
+ * PEXLineTypeDashed
+ * defined for this implementation as 7 pixels on, 7 off.....
+ * PEXLineTypeDotted
+ * defined for this implementation as 1 pixels on, 5 off.....
+ * PEXLineTypeDashDot
+ * defined for this implementation as
+ * 9 pixels on, 3 off, 1 on, 3 off....
+ */
+#define MAX_LINE_DASH_LENGTH_SIZE 4*sizeof(unsigned char)
+static int mi_line_dashed_length = 2;
+static unsigned char mi_line_dashed[] = {7,7};
+static int mi_line_dotted_length = 2;
+static unsigned char mi_line_dotted[] = {1,5};
+static int mi_line_dashdot_length = 4;
+static unsigned char mi_line_dashdot[] = {7,3,1,3};
+
+#endif /* MI_LINEDASH_H */
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/include/miMarkers.h b/xc/programs/Xserver/PEX5/ddpex/mi/include/miMarkers.h
new file mode 100644
index 000000000..9536c79f3
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/include/miMarkers.h
@@ -0,0 +1,154 @@
+/* $TOG: miMarkers.h /main/3 1998/02/10 12:38:47 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS 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 MI_MARKERS_H
+#define MI_MARKERS_H
+
+/*
+ * Marker geometry definitions
+ *
+ * There are five predefined marker types:
+ * PEXMarkerDot: draw a single pixel
+ * PEXMarkerCross: draws a "+" sign
+ * PEXMarkerAsterisk: draws an "*"
+ * PEXMarkerCircle: draws a circle.
+ * PEXMarkerX: draw an "X"
+ *
+ * The geometry for a pixel is simple and requires no pre-definition.
+ * the geometry for a circle must be computed on the fly.
+ *
+ * The geomtries for the remaining three marker types are pre-defined
+ * in the following data structures.
+ *
+ */
+
+/*
+ * PEXMarkerCross
+ *
+ * the cross is defined as two polylines: (-1.0, 0.0) <-> (1.0, 0.0)
+ * (0.0, -1.0) <-> (0.0, 1.0)
+ */
+static ddCoord2D cross_data_1[2]={ -1.0, 0.0,
+ 1.0, 0.0 };
+static ddCoord2D cross_data_2[2]={ 0.0, -1.0,
+ 0.0, 1.0 };
+static MarkerlistofddPoint cross_list[2]={
+ 2, /* numPoints */
+ 2*sizeof(ddCoord2D), /* maxData */
+ cross_data_1, /* data pointer */
+ 2, /* numPoints */
+ 2*sizeof(ddCoord2D), /* maxData */
+ cross_data_2 }; /* data pointer */
+static miListHeader cross_header={ DD_2D_POINT, /* type */
+ 0, /* flags */
+ 2, /* numLists */
+ 2, /* maxLists */
+ (listofddPoint *)cross_list }; /* listofddPoint */
+
+/*
+ * PEXMarkerAsterisk
+ *
+ * the Asterisk is defined as four polylines:
+ * (-1.0, 0.0) <-> (1.0, 0.0)
+ * (0.0, -1.0) <-> (0.0, 1.0)
+ * (-0.707, -0.707) <-> (0.707, 0.707)
+ * (0.707, -0.707) <-> (-0.707, 0.707)
+ *
+ * Note that 0.707 is ~ sqrt(2.0)/2.0, or the endpoints of either of the
+ * vertical or horizontal segments rotated by 45 degrees.
+ */
+static ddCoord2D asterisk_data_1[2]={ -1.0, 0.0,
+ 1.0, 0.0 };
+static ddCoord2D asterisk_data_2[2]={ 0.0, -1.0,
+ 0.0, 1.0 };
+static ddCoord2D asterisk_data_3[2]={ -0.7071, -0.7071,
+ 0.7071, 0.7071 };
+static ddCoord2D asterisk_data_4[2]={ 0.7071, -0.7071,
+ -0.7071, 0.7071 };
+static MarkerlistofddPoint asterisk_list[4]={
+ 2, /*numPoints*/
+ 2*sizeof(ddCoord2D), /* maxData */
+ asterisk_data_1, /* data */
+ 2, /*numPoints*/
+ 2*sizeof(ddCoord2D), /* maxData */
+ asterisk_data_2, /* data */
+ 2, /*numPoints*/
+ 2*sizeof(ddCoord2D), /* maxData */
+ asterisk_data_3, /* data */
+ 2, /*numPoints*/
+ 2*sizeof(ddCoord2D), /* maxData */
+ asterisk_data_4 }; /* data */
+static miListHeader asterisk_header={ DD_2D_POINT, /* type */
+ 0, /* flags */
+ 4, /* numLists */
+ 4, /* maxLists */
+ (listofddPoint *)asterisk_list }; /* data */
+
+/*
+ * PEXMarkerX
+ *
+ * the X is defined as two polylines: (-1.0, -1.0) <-> (1.0, 1.0)
+ * (1.0, -1.0) <-> (-1.0, 1.0)
+ */
+static ddCoord2D X_data_1[2]={ -1.0, -1.0,
+ 1.0, 1.0 };
+static ddCoord2D X_data_2[2]={ 1.0, -1.0,
+ -1.0, 1.0 };
+static MarkerlistofddPoint X_list[2]={
+ 2, /* numPoints */
+ 16, /* maxData */
+ X_data_1, /* data pointer */
+ 2, /* numPoints */
+ 2*sizeof(ddCoord2D), /* maxData */
+ X_data_2 }; /* data pointer */
+static miListHeader X_header={ DD_2D_POINT, /* type */
+ 0, /* flags */
+ 2, /* numLists */
+ 2, /* maxLists */
+ (listofddPoint *)X_list }; /* listofddPoint */
+
+
+#endif
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/include/miNS.h b/xc/programs/Xserver/PEX5/ddpex/mi/include/miNS.h
new file mode 100644
index 000000000..c67b2eb3e
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/include/miNS.h
@@ -0,0 +1,136 @@
+/* $TOG: miNS.h /main/3 1998/02/10 12:38:52 kaleb $ */
+
+/***********************************************************
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution of
+the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS 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 "ddpex.h"
+
+#ifndef MINS_H
+#define MINS_H
+
+typedef ddULONG ddNamePiece;
+typedef ddNamePiece *ddNamePtr;
+
+#define MINS_MIN_NAME 0
+#define MINS_MAX_NAME 255
+#define MINS_NAMESET_SIZE (MINS_MAX_NAME - MINS_MIN_NAME +1)
+
+#define MINS_VALID_NAME(name) \
+ ( ((name) >= MINS_MIN_NAME) && ((name) <= MINS_MAX_NAME) )
+
+#define MINS_COUNT_BITS(type_or_var) (sizeof(type_or_var) * 8)
+
+/* Name N is present if bit MINS_NAMESET_BIT(N) is set in
+ * nameset word[ MINS_NAMESET_WORD(N) ]
+ */
+#define MINS_NAMESET_WORD_COUNT \
+ (MINS_NAMESET_SIZE / MINS_COUNT_BITS(ddNamePiece))
+
+#define MINS_NAMESET_WORD_NUM(one_name) \
+ ((one_name) / MINS_COUNT_BITS(ddNamePiece))
+
+#define MINS_NAMESET_BIT(one_name) \
+ (1 << ((one_name) % MINS_COUNT_BITS(ddNamePiece)))
+
+#define MINS_EMPTY_NAMESET(nameset) \
+ { register ddNamePtr n = nameset; \
+ register ddNamePtr end = &nameset[MINS_NAMESET_WORD_COUNT]; \
+ do { *n = 0; n++; } while (n < end); }
+
+#define MINS_FILL_NAMESET(nameset) \
+ { register ddNamePtr n = nameset; \
+ register ddNamePtr end = &nameset[MINS_NAMESET_WORD_COUNT]; \
+ do { *n = ~0; n++; } while (n < end); }
+
+#define MINS_COPY_NAMESET(source, dest) \
+ { register ddNamePtr s = (source), d = (dest); \
+ register ddNamePtr end = &(d)[MINS_NAMESET_WORD_COUNT]; \
+ do { *d = *s; d++; s++; } while (d < end); }
+
+#define MINS_OR_NAMESETS(source, dest) \
+ { register ddNamePtr s = (source), d = (dest); \
+ register ddNamePtr end = &(d)[MINS_NAMESET_WORD_COUNT]; \
+ do { *d |= *s; d++; s++; } while (d < end); }
+
+#define MINS_IS_NAME_IN_SET(one_name, nameset) \
+ ((nameset)[MINS_NAMESET_WORD_NUM(one_name)] & \
+ MINS_NAMESET_BIT(one_name))
+
+#define MINS_ADD_TO_NAMESET(one_name, nameset) \
+ (nameset)[MINS_NAMESET_WORD_NUM(one_name)] |= \
+ MINS_NAMESET_BIT(one_name)
+
+#define MINS_REMOVE_FROM_NAMESET(one_name, nameset) \
+ (nameset)[MINS_NAMESET_WORD_NUM(one_name)] &= \
+ ~MINS_NAMESET_BIT(one_name)
+
+#define MINS_NOT_NAMESET(nameset) \
+ { register ddNamePtr n = nameset; \
+ register ddNamePtr end = &nameset[MINS_NAMESET_WORD_COUNT];\
+ do { *n = ~(*n); n++; } \
+ while (n < end); }
+
+#define MINS_IS_NAMESET_EMPTY(nameset, isempty) \
+ { register ddNamePtr n = nameset; \
+ register ddNamePtr end = &nameset[MINS_NAMESET_WORD_COUNT];\
+ (isempty) = ~0; \
+ do { (isempty) = (isempty) && !(*n); n++; } \
+ while (n < end); }
+
+#define MINS_MATCH_NAMESETS(names1, names2, match) \
+ { register ddNamePtr n1 = names1, n2=names2; \
+ register ddNamePtr end = &names1[MINS_NAMESET_WORD_COUNT]; \
+ (match) = 0; \
+ do { (match) = (match) || ((*n1) & (*n2)); n1++; n2++; } \
+ while (n1 < end); }
+
+typedef struct _miNSHeader {
+ /* the resource id is in the dipex resource structure */
+ listofObj *wksRefList;
+ listofObj *rendRefList;
+ ddULONG refCount; /* pick & search context*/
+ ddULONG nameCount;
+ ddNamePiece names[ MINS_NAMESET_WORD_COUNT ];
+ ddBOOL freeFlag;
+} miNSHeader;
+
+#endif /* MINS_H */
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/include/miNurbs.h b/xc/programs/Xserver/PEX5/ddpex/mi/include/miNurbs.h
new file mode 100644
index 000000000..924141c1c
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/include/miNurbs.h
@@ -0,0 +1,271 @@
+/* $TOG: miNurbs.h /main/4 1998/02/10 12:38:57 kaleb $ */
+
+/*****************************************************************
+
+Copyright 1989,1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Copyright 1989,1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Sun Microsystems,
+and The Open Group, not be used in advertising or publicity
+pertaining to distribution of the software without specific, written
+prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS 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 MI_NURB_H
+#define MI_NURB_H 1
+
+#ifdef NDEBUG
+extern unsigned nurb_debug_flags;
+#define NURB_DEBUG_FLAG(_b) (nurb_debug_flags & (_b))
+#endif /* NDEBUG */
+
+/* Nurb Debug Flags:
+ * 0x01 (1) Surface edge paths
+ * 0x02 (2) Surface iso curve paths
+ * 0x04 (4) Trimming data, tessellated and ordered
+ * 0x08 (8) Surface facet paths for untrimmed surfaces
+ * 0x10 (16) Trimmed surface polygons
+ * 0x20 (32) Surface facet paths
+ * 0x40 (64) Surface polygons before trimming
+ * 0x80 (128) Surface hollow-edge paths
+ * 0x100 (256) Surface grids
+ * 0x200 (512) Initial data
+ */
+
+#define MAXORD 10
+#define MAXTCORD 6
+
+#define XX 0
+#define YY 1
+#define ZZ 2
+#define WW 3
+
+#define MAX(a,b) ( ((a) > (b)) ? (a) : (b) )
+
+extern double mi_nu_ptofd[MAXORD][MAXORD];
+
+#define NURB_TRIM_DATA_INIT( _t ) \
+ { \
+ (_t).nloops = 0; \
+ (_t).loops = (Nurb_trim_loop_rep *)NULL; \
+ (_t).cur_vertex = 1; \
+ (_t).vertices = (Nurb_param_point *)NULL; \
+ (_t).ep_index = 0; \
+ (_t).ep_list_size = 0; \
+ (_t).ep_list = (Nurb_edge_point *)NULL; \
+ }
+
+#define NURB_SURF_STATE_INIT( _s ) \
+ { \
+ (_s)->reps.facets = 0; \
+ (_s)->reps.edges = 0; \
+ (_s)->reps.isocrvs = 0; \
+ (_s)->reps.markers = 0; \
+ (_s)->reps.hollow = 0; \
+ (_s)->reps.grids = 0; \
+ (_s)->reps.normals = 0; \
+ (_s)->reps.trim_data = 0; \
+ (_s)->grids.number = 0; \
+ (_s)->grids.flags.normals = 0; \
+ (_s)->grids.grids = (Nurb_grid *)NULL; \
+ (_s)->ruknots = (ddFLOAT *)NULL; \
+ (_s)->rvknots = (ddFLOAT *)NULL; \
+ (_s)->facets = (miListHeader *)NULL; \
+ (_s)->sofas = (miSOFASStruct *)NULL; \
+ (_s)->edges = (miListHeader *)NULL; \
+ (_s)->isocrvs = (miListHeader *)NULL; \
+ (_s)->markers = (miListHeader *)NULL; \
+ (_s)->hollow = (miListHeader *)NULL; \
+ NURB_TRIM_DATA_INIT((_s)->trim_data); \
+ }
+
+#define NURB_INIT_RANGE_LIST( _r ) \
+ (_r)->size = 0; \
+ (_r)->number = 0; \
+ (_r)->limits = (Nurb_limit *)NULL;
+
+#define EXTENTS_OVERLAP( _ea, _eb ) \
+ (!((_eb).umin > (_ea).umax || (_eb).umax < (_ea).umin || \
+ (_eb).vmin > (_ea).vmax || (_eb).vmax < (_ea).vmin))
+
+#define GET_TRIM_CURVE_TOLERANCE( _crv, _tolerance ) \
+ switch ( (_crv)->curveApprox.approxMethod ) { \
+ case PEXApproxImpDep: \
+ case PEXApproxConstantBetweenKnots: \
+ (_tolerance) = (_crv)->curveApprox.tolerance; \
+ break; \
+ default: \
+ (_tolerance) = 1.0; \
+ }
+
+#define ADD_POINT_TO_LIST( _l, _r, _op, _pt ) \
+if ((_l)) { \
+ listofddPoint *pddlist; \
+ if ( (_op) == PT_MOVE ) { \
+ (_l)->numLists++; \
+ MI_ALLOCLISTHEADER( (_l), \
+ MI_ROUND_LISTHEADERCOUNT( (_l)->numLists ) ); \
+ } \
+ pddlist = &((_l)->ddList[(_l)->numLists-1]); \
+ pddlist->numPoints++; \
+ if ( (_r) ) { \
+ MI_ALLOCLISTOFDDPOINT( pddlist, \
+ MI_ROUND_LISTHEADERCOUNT(pddlist->numPoints),\
+ sizeof(ddCoord4D) ); \
+ pddlist->pts.p4Dpt[pddlist->numPoints - 1] = *((ddCoord4D *)(_pt)); \
+ } else { \
+ MI_ALLOCLISTOFDDPOINT( pddlist, \
+ MI_ROUND_LISTHEADERCOUNT(pddlist->numPoints),\
+ sizeof(ddCoord3D) ); \
+ pddlist->pts.p3Dpt[pddlist->numPoints - 1] = *((ddCoord3D *)(_pt)); \
+ } \
+}
+
+typedef enum {
+ PT_NOP,
+ PT_MOVE,
+ PT_LINE,
+ PT_MARKER
+} Nurb_path_op;
+
+typedef enum {
+ NURB_SAME_CONTOUR = 0,
+ NURB_NEW_CONTOUR = 1,
+ NURB_NEW_FACET = 2
+} Nurb_facet_op;
+
+typedef struct {
+ unsigned facets: 1;
+ unsigned isocrvs: 1;
+ unsigned edges: 1;
+ unsigned markers: 1; /* first order in u and v, use markers */
+ unsigned hollow: 1;
+ unsigned grids: 1;
+ unsigned normals: 1;
+ unsigned trim_data: 1;
+} Nurb_rep_flags;
+
+typedef struct {
+ double lmin;
+ double lmax;
+} Nurb_limit;
+
+typedef struct {
+ int size;
+ int number;
+ Nurb_limit *limits;
+} Nurb_limitlst;
+
+typedef struct {
+ double u;
+ double v;
+} Nurb_param_point;
+
+typedef struct {
+ double umin, umax;
+ double vmin, vmax;
+} Nurb_param_limit;
+
+typedef struct Nurb_trim_segment {
+ int first, last; /* indices in vertex list */
+ int start, end; /* effective limit of seg */
+ int current;
+ unsigned dir;
+ ddULONG vis;
+ Nurb_param_limit extent; /* of segment */
+ struct Nurb_trim_segment *next;
+} Nurb_trim_segment;
+
+typedef struct {
+ Nurb_param_limit extent; /* of loop */
+ Nurb_trim_segment *segs; /* linked list of segments, NULL terminated */
+} Nurb_trim_loop_rep;
+
+typedef struct {
+ int flags;
+ int count; /* of rectangles this point is part of */
+ double u, v;
+ ddCoord4D pt;
+ ddVector3D normal;
+ int next, prev, branch;
+} Nurb_edge_point;
+
+typedef struct {
+ Nurb_param_point *vertices; /* of tessellated curves */
+ int cur_vertex; /* index of current vertex */
+ int nloops;
+ Nurb_trim_loop_rep *loops; /* array of representations */
+ Nurb_edge_point *ep_list; /* polygon edge points */
+ int ep_index; /* index of current one */
+ int ep_list_size; /* # allocated entries */
+} Nurb_trim_data;
+
+typedef struct {
+ Nurb_edge_point *pts;
+ int nu, nv;
+ Nurb_param_limit extent;
+} Nurb_grid;
+
+typedef struct {
+ int number;
+ struct {
+ unsigned normals;
+ } flags;
+ Nurb_grid *grids;
+} Nurb_gridlst;
+
+typedef struct {
+ int gitype;
+ int isocount[2];
+ int approx_type;
+ ddFLOAT approx_value[2];
+ Nurb_param_limit range;
+ Nurb_param_limit param_limits;
+ Nurb_rep_flags reps;
+ ddFLOAT *ruknots;
+ ddFLOAT *rvknots;
+ Nurb_gridlst grids;
+ Nurb_trim_data trim_data;
+ Nurb_param_point corners[5];
+ Nurb_trim_segment edge_segs[4];
+ miListHeader *facets;
+ miSOFASStruct *sofas;
+ miListHeader *edges;
+ miListHeader *isocrvs;
+ miListHeader *markers;
+ miListHeader *hollow;
+} Nurb_surf_state;
+
+#endif /* MI_NURB_H */
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/include/miPick.h b/xc/programs/Xserver/PEX5/ddpex/mi/include/miPick.h
new file mode 100644
index 000000000..90e669e0e
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/include/miPick.h
@@ -0,0 +1,133 @@
+/* $TOG: miPick.h /main/3 1998/02/10 12:39:02 kaleb $ */
+
+/***********************************************************
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution of
+the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS 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 "mipex.h"
+#include "ddpex4.h"
+
+#ifndef MIPICK_H
+#define MIPICK_H
+
+ /* there is one data rec and one input record for each pick device */
+ /* supported pick devices are defined in miInfo.h */
+#define MIWKS_NUM_PICK_DEVICES SI_PICK_DEVICE_NUM
+
+typedef struct {
+ ddEnumTypeIndex type; /* dc_hitbox or npc_hitvolume */
+ ddUSHORT status; /* PEXOk or PEXNoPick */
+ listofObj *path; /* start path */
+ ddUSHORT pathOrder;
+ diNSHandle inclusion;
+ diNSHandle exclusion;
+ union {
+ char dc_data_rec; /* none */
+ char npc_data_rec; /* none */
+ } data_rec; /* place holder */
+ ddEnumTypeIndex pet;
+ ddViewport echoVolume;
+ ddUSHORT echoSwitch;
+ ddPointer devPriv;
+} miPickDevice;
+
+typedef struct {
+ /* the resource id is in the dipex resource structure */
+ diWKSHandle pWks;
+ ddEnumTypeIndex type; /* dc_hitbox or npc_hitvolume */
+ ddUSHORT status; /* PEXOk or PEXNoPick */
+ listofObj *path; /* list of pick element refs */
+ ddUSHORT pathOrder;
+ diNSHandle incl_handle;
+ diNSHandle excl_handle;
+ union {
+ char dc_data_rec;
+ char npc_data_rec;
+ } data_rec;
+ union {
+ ddPC_DC_HitBox dc_hit_box;
+ ddPC_NPC_HitVolume npc_hit_volume;
+ } input_rec;
+ ddPointer devPriv;
+} miPickMeasureStr;
+
+
+/* macros for pick devices and pick measures */
+
+/* set this to return the index into array of pick devices based
+ * on the device type specified
+ * device types:
+ * PEXPickDeviceDC_HitBox 1
+ * PEXPickDeviceNPC_HitVolume 2
+ */
+#define MIWKS_PICK_DEV_INDEX(devindex, devtype) \
+ (devindex) = (devtype) - 1
+
+/* for both pick device and pick measure */
+#define MIWKS_SIZE_DATA_REC_1 \
+ sizeof(char)
+
+#define MIWKS_SIZE_DATA_REC_2 \
+ sizeof(char)
+
+/* for pick measure */
+#define MIWKS_PM_DATA_REC_1(pPick) \
+ (pPick)->data_rec.dc_data_rec
+
+#define MIWKS_PM_DATA_REC_2(pPick) \
+ (pPick)->data_rec.npc_data_rec
+
+#define MIWKS_PM_INPUT_STR_1 ddPC_DC_HitBox
+#define MIWKS_PM_INPUT_REC_1(pPick) \
+ (pPick)->input_rec.dc_hit_box
+
+#define MIWKS_PM_INPUT_STR_2 ddPC_NPC_HitVolume
+#define MIWKS_PM_INPUT_REC_2(pPick) \
+ (pPick)->input_rec.npc_hit_volume
+
+/* for pick device */
+#define MIWKS_PD_DATA_REC_1(pPick) \
+ (pPick)->data_rec.dc_data_rec
+
+#define MIWKS_PD_DATA_REC_2(pPick) \
+ (pPick)->data_rec.npc_data_rec
+
+#endif /* MIPICK_H */
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/include/miRender.h b/xc/programs/Xserver/PEX5/ddpex/mi/include/miRender.h
new file mode 100644
index 000000000..d611fc343
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/include/miRender.h
@@ -0,0 +1,335 @@
+
+/* $TOG: miRender.h /main/5 1998/02/10 12:39:06 kaleb $ */
+
+/***********************************************************
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution of
+the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS 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 MI_RENDER_H
+#define MI_RENDER_H
+
+#include "ddpex.h"
+#include "ddpex3.h"
+#include "ddpex4.h"
+#include "gc.h"
+#include "miNS.h"
+#include "PEXprotost.h"
+#include "miLUT.h"
+
+/*
+ * Create a data list header. THis list header is simply
+ * used as a pointer to the start of the scratch data areas
+ * maintained for transformation and clipping.
+ */
+typedef struct _miListHeader {
+ ddPointType type; /* type of vertices in lists */
+ ddUSHORT flags; /* various random path flags */
+ ddULONG numLists; /* number of list headers */
+ ddULONG maxLists; /* allocated number of list headers */
+ listofddPoint *ddList; /* data area pointer */
+} miListHeader;
+
+/*
+ * The DD context is divided into two parts: values that remain
+ * static across structure and values that can vary within structures.
+ * Only the dynamic values (those in miDynamicDDContext) must be stored
+ * across structure references - such as in BeginStructure
+ */
+typedef struct _miDynamicDDContext {
+ ddPCAttr *pPCAttr; /* Pipeline context for renderer */
+ ddNamePiece currentNames[MINS_NAMESET_WORD_COUNT];
+ struct _miDynamicDDContext *next; /* Next pointer for stacking */
+ ddFLOAT mc_to_wc_xform[4][4];
+ ddFLOAT wc_to_npc_xform[4][4];
+ ddFLOAT mc_to_npc_xform[4][4];
+ ddFLOAT wc_to_cc_xform[4][4];
+ ddFLOAT cc_to_dc_xform[4][4];
+ ddFLOAT mc_to_cc_xform[4][4];
+ ddFLOAT mc_to_dc_xform[4][4];
+ ddFLOAT npc_to_cc_xform[4][4];
+ ddUSHORT clipFlags;
+ ddUSHORT filter_flags;
+ ddUSHORT do_prims;
+} miDynamicDDContext;
+
+/* definitions for filter_flags */
+#define MI_DDC_HIGHLIGHT_FLAG 1<<0
+#define MI_DDC_INVISIBLE_FLAG 1<<1
+#define MI_DDC_DETECTABLE_FLAG 1<<2
+
+#define MI_DDC_DO_PRIMS(pRend) \
+ ((miDDContext *)(pRend)->pDDContext)->Dynamic->do_prims
+
+#define MI_DDC_SET_DO_PRIMS(pRend, pddc) \
+ (pddc)->Dynamic->do_prims = \
+ !((pddc)->Dynamic->filter_flags & MI_DDC_INVISIBLE_FLAG) \
+ && ( !(pRend)->render_mode || \
+ ((pRend)->render_mode && \
+ ((pddc)->Dynamic->filter_flags & MI_DDC_DETECTABLE_FLAG)) )
+
+#define MI_DDC_IS_HIGHLIGHT(pddc) \
+ ((pddc)->Dynamic->filter_flags & MI_DDC_HIGHLIGHT_FLAG)
+
+#define MI_DDC_SET_HIGHLIGHT(pddc) \
+ (pddc)->Dynamic->filter_flags |= MI_DDC_HIGHLIGHT_FLAG
+
+#define MI_DDC_CLEAR_HIGHLIGHT(pddc) \
+ (pddc)->Dynamic->filter_flags &= ~MI_DDC_HIGHLIGHT_FLAG
+
+#define MI_DDC_IS_INVISIBLE(pddc) \
+ ((pddc)->Dynamic->filter_flags & MI_DDC_INVISIBLE_FLAG)
+
+#define MI_DDC_SET_INVISIBLE(pddc) \
+ (pddc)->Dynamic->filter_flags |= MI_DDC_INVISIBLE_FLAG
+
+#define MI_DDC_CLEAR_INVISIBLE(pddc) \
+ (pddc)->Dynamic->filter_flags &= ~MI_DDC_INVISIBLE_FLAG
+
+#define MI_DDC_IS_DETECTABLE(pddc) \
+ ((pddc)->Dynamic->filter_flags & MI_DDC_DETECTABLE_FLAG)
+
+#define MI_DDC_SET_DETECTABLE(pddc) \
+ (pddc)->Dynamic->filter_flags |= MI_DDC_DETECTABLE_FLAG
+
+#define MI_DDC_CLEAR_DETECTABLE(pddc) \
+ (pddc)->Dynamic->filter_flags &= ~MI_DDC_DETECTABLE_FLAG
+
+/*
+ * The static portion of the DD context is itself divided into several parts:
+ * immediate rendering attributes from the pipeline context, a jump
+ * table for the level 1 rendering routines, and other assorted intermediate
+ * values that are used during rendering.
+ * Note that immediate rendering attributes means that bundled attributes
+ * have been extracted from the appropriate LUTs. Code that uses the
+ * DDC rendering attributes, therefore, do not need to check the ASF's.
+ */
+
+/*
+ *Level 1 rendering Procedure Vector used in DDC
+ * The index of a procedure is arbitrarily specified
+ * the following defines.
+ */
+#define POLYLINE_RENDER_TABLE_INDEX 0
+#define FILLAREA_RENDER_TABLE_INDEX 1
+#define TEXT_RENDER_TABLE_INDEX 2
+#define MARKER_RENDER_TABLE_INDEX 3
+#define TRISTRIP_RENDER_TABLE_INDEX 4
+#define RENDER_TABLE_LENGTH 5
+
+typedef ddpex2rtn (*RendTableType)();
+
+/*
+ * This structure is a copy of the attributes in the PipeLine context
+ * with the exception that all references to bundles and bundled
+ * attributes have been removed. Furthermore, this list contains
+ * references to no attributes that are no bundled: they are
+ * just as easily accessed from the dynamic copy of the PC.
+ */
+typedef struct _miDDContextRendAttrs {
+ ddEnumTypeIndex markerType;
+ ddFLOAT markerScale;
+ ddColourSpecifier markerColour;
+ ddUSHORT textFont;
+ ddUSHORT textPrecision;
+ ddFLOAT charExpansion;
+ ddFLOAT charSpacing;
+ ddColourSpecifier textColour;
+ ddFLOAT charHeight;
+ ddVector2D charUp;
+ ddUSHORT textPath;
+ ddTextAlignmentData textAlignment;
+ ddFLOAT atextHeight;
+ ddVector2D atextUp;
+ ddUSHORT atextPath;
+ ddTextAlignmentData atextAlignment;
+ ddEnumTypeIndex atextStyle;
+ ddEnumTypeIndex lineType;
+ ddFLOAT lineWidth;
+ ddColourSpecifier lineColour;
+ ddCurveApprox curveApprox;
+ ddEnumTypeIndex lineInterp;
+ ddEnumTypeIndex intStyle;
+ ddColourSpecifier surfaceColour;
+ ddReflectionAttr reflAttr;
+ ddEnumTypeIndex reflModel;
+ ddEnumTypeIndex surfInterp;
+ ddEnumTypeIndex bfIntStyle;
+ ddColourSpecifier bfSurfColour;
+ ddReflectionAttr bfReflAttr;
+ ddEnumTypeIndex bfReflModel;
+ ddEnumTypeIndex bfSurfInterp;
+ ddSurfaceApprox surfApprox;
+ ddCoord2D patternSize;
+ ddCoord3D patternRefPt;
+ ddVector3D patternRefV1;
+ ddVector3D patternRefV2;
+ ddUSHORT edges;
+ ddEnumTypeIndex edgeType;
+ ddFLOAT edgeWidth;
+ ddColourSpecifier edgeColour;
+ ddUSHORT modelClip;
+ ddULONG pickId;
+ ddULONG hlhsrType;
+ ddColourSpecifier backgroundColour;
+ ddUSHORT clearI;
+ ddUSHORT clearZ;
+ ddUSHORT echoMode;
+ ddColourSpecifier echoColour;
+} miDDContextRendAttrs;
+
+#define MI_MAXTEMPDATALISTS 4 /* Note, must be 2^n for macros to work */
+#define MI_MAXTEMPFACETLISTS 4 /* Note, must be 2^n for macros to work */
+
+/*
+ * the following defines are bit mask flags for the flags field
+ * in the miDDContextMisc struct.
+ *
+ * Note that all these flag are true when the corresponding entry
+ * is INVALID. ie the flag is set if the entry must be updated!
+ */
+
+#define POLYLINEGCFLAG (1<<0) /* change flag for polyline GC */
+#define FILLAREAGCFLAG (1<<1) /* change flag for fill area GC */
+#define EDGEGCFLAG (1<<2) /* change flag for F.A. edge GC */
+#define MARKERGCFLAG (1<<3) /* change flag for marker GC */
+#define TEXTGCFLAG (1<<4) /* change flag for text GC */
+#define NOLINEDASHFLAG (1<<5) /* No Line Dash storage allocated in line GC */
+#define CC_DCUEVERSION (1<<6) /* invalid cc version of depth cue entry */
+#define MCVOLUMEFLAG (1<<7) /* invalid model clip planes entry */
+
+#define INVTRMCTOWCXFRMFLAG (1<<8) /* invalid flag - inverse mc2wc xform */
+#define INVTRWCTOCCXFRMFLAG (1<<9) /* invalid flag - inverse wc2cc xform */
+#define INVTRMCTOCCXFRMFLAG (1<<10) /* invalid flag - inverse mc2cc xform */
+#define INVTRCCTODCXFRMFLAG (1<<11) /* invalid flag - inverse cc2dc xform */
+#define INVVIEWXFRMFLAG (1<<12) /* invalid flag - inverse view xform */
+
+typedef struct _miDDContextMisc {
+ ddULONG listIndex; /* index into following array */
+ miListHeader list4D[MI_MAXTEMPDATALISTS]; /* temp data areas */
+ miListHeader list2D; /* temp area for 2D data */
+ ddULONG facetIndex; /* index into following array */
+ listofddFacet facets[MI_MAXTEMPFACETLISTS]; /* temp facet areas */
+ ddFLOAT viewport_xform[4][4]; /* from npc to viewport */
+ ddULONG flags; /* valid flags for following fields */
+ GCPtr pPolylineGC; /* ddx GC for rendering polylines */
+ GCPtr pFillAreaGC; /* ddx GC for rendering fill areas */
+ GCPtr pEdgeGC; /* ddx GC for rendering F. A. edges */
+ GCPtr pPolyMarkerGC; /* ddx GC for rendering poly markers*/
+ GCPtr pTextGC; /* ddx GC for rendering Text */
+ ddFLOAT inv_tr_mc_to_wc_xform[4][4]; /* inverse transpose */
+ ddFLOAT inv_tr_wc_to_cc_xform[4][4]; /* for normal xforms */
+ ddFLOAT inv_tr_mc_to_cc_xform[4][4];
+ ddFLOAT inv_tr_cc_to_dc_xform[4][4];
+ ddFLOAT inv_vpt_xform[4][4]; /* from viewport to NPC */
+ ddFLOAT inv_view_xform[4][4]; /* from npc to WC */
+ listofObj *ms_MCV; /* modelling space version of the */
+ /* model clipping volume. */
+ ddCoord4D eye_pt; /* eye point in WC */
+ ddColourSpecifier highlight_colour;
+ ddDepthCueEntry cc_dcue_entry; /* cc version of current
+ * depth cue bundle entry */
+} miDDContextMisc;
+
+typedef struct {
+ ddEnumTypeIndex type; /* DC_HitBox or NPC_HitVolume */
+ ddUSHORT status; /* PEXOk or PEXNoPick */
+ ddNamePiece inclusion[MINS_NAMESET_WORD_COUNT];
+ ddNamePiece exclusion[MINS_NAMESET_WORD_COUNT];
+ union {
+ char dc_data_rec; /* none */
+ char npc_data_rec; /* none */
+ } data_rec; /* place holder */
+ union {
+ ddPC_DC_HitBox dc_hit_box;
+ ddPC_NPC_HitVolume npc_hit_volume;
+ } input_rec;
+ ddPointer devPriv;
+} ddPickDeviceStr;
+
+typedef struct _ddSearchDevPriv {
+ ddUSHORT status; /* PEXFound or PEXNotFound */
+ ddCoord3D position;
+ ddFLOAT distance;
+ ddBOOL modelClipFlag;
+ ddNamePiece norm_inclusion[MINS_NAMESET_WORD_COUNT];
+ ddNamePiece norm_exclusion[MINS_NAMESET_WORD_COUNT];
+ ddNamePiece invert_inclusion[MINS_NAMESET_WORD_COUNT];
+ ddNamePiece invert_exclusion[MINS_NAMESET_WORD_COUNT];
+ ddPointer devPriv;
+} ddSearchDeviceStr;
+
+typedef struct _miStaticDDContext {
+ miDDContextRendAttrs *attrs; /* Immediate rendering attributes */
+ miDDContextMisc misc; /* misc. rendering temp vals */
+ RendTableType RenderProcs[RENDER_TABLE_LENGTH]; /* lvl1 jmp table */
+ ddPickDeviceStr pick;
+ ddSearchDeviceStr search;
+} miStaticDDContext;
+
+/*
+ * Finally! the ddContext itself....
+ */
+typedef struct _miDDContext {
+ miStaticDDContext Static;
+ miDynamicDDContext *Dynamic;
+} miDDContext;
+
+/*
+ * the following macro return a pointer to the next free
+ * work data area from the list4D array in the static portion
+ * of the ddContext.
+ */
+#define MI_NEXTTEMPDATALIST(pddc) \
+&((pddc)->Static.misc.list4D[(++(pddc)->Static.misc.listIndex)&(MI_MAXTEMPDATALISTS-1)])
+
+/*
+ * the following macro return a pointer to the next free
+ * work facet area from the facets array in the static portion
+ * of the ddContext.
+ */
+#define MI_NEXTTEMPFACETLIST(pddc) \
+&((pddc)->Static.misc.facets[(++(pddc)->Static.misc.facetIndex)&(MI_MAXTEMPFACETLISTS-1)])
+
+#define NULL4x4 (float (*)[4])0
+extern ddFLOAT ident4x4[4][4];
+
+#endif /* MI_RENDER_H */
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/include/miStrMacro.h b/xc/programs/Xserver/PEX5/ddpex/mi/include/miStrMacro.h
new file mode 100644
index 000000000..0ce8cbf88
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/include/miStrMacro.h
@@ -0,0 +1,198 @@
+/* $TOG: miStrMacro.h /main/6 1998/02/10 12:39:11 kaleb $ */
+
+/***********************************************************
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution of
+the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS 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.
+
+******************************************************************/
+
+/* some macros to use */
+
+#include "miStruct.h"
+#include "mipex.h"
+
+#ifndef MISTRMACRO_H
+#define MISTRMACRO_H
+
+/* structure information */
+#define MISTR_NUM_EL(PS) (PS)->numElements
+
+#define MISTR_EDIT_MODE(PS) (PS)->editMode
+
+#define MISTR_LENGTH(PS) (PS)->totalSize
+
+#define MISTR_NUM_CHILDREN(PS) (PS)->children->numObj
+
+#define MISTR_NUM_PARENTS(PS) (PS)->parents->numObj
+
+#define MISTR_CURR_EL_OFFSET(PS) (PS)->currElementOffset
+
+#define MISTR_CURR_EL_PTR(PS) (PS)->pCurrElement
+
+#define MISTR_ZERO_EL(PS) (PS)->pZeroElement
+
+#define MISTR_LAST_EL(PS) (PS)->pLastElement
+
+#define MISTR_NEXT_EL(PE) (PE)->next
+
+#define MISTR_PREV_EL(PE) (PE)->prev
+
+#define MISTR_EL_DATA(PE) ((PE)->element)
+
+#define MISTR_EL_TYPE(PE) (PE)->element.elementType
+
+#define MISTR_EL_LENGTH(PE) (PE)->element.pexOClength
+
+/* todo: make this more efficient by searching backwards if it's closer */
+/*
+ if (offset < current && offset < curr - off)
+ then start at 0 and go forward
+ else if (offset < current && offset > curr - off)
+ then start at curr and go backward
+ else if (offset > current && offset - curr < off - last)
+ then start at curr and go forward
+ else if (offset > current && offset - curr > off - last)
+ then start at last and go backward
+*/
+
+#define MISTR_FIND_EL(PSTRUCT, OFFSET, PE) \
+ if ((OFFSET) <= 0) \
+ (PE) = MISTR_ZERO_EL(PSTRUCT); \
+ else if ((OFFSET) >= MISTR_NUM_EL(PSTRUCT)) \
+ (PE) = MISTR_PREV_EL(MISTR_LAST_EL(PSTRUCT)); \
+ else if ((OFFSET) == MISTR_CURR_EL_OFFSET(PSTRUCT)) \
+ (PE) = MISTR_CURR_EL_PTR(PSTRUCT); \
+ else { \
+ register int _i, _start; \
+ if ((OFFSET) < MISTR_CURR_EL_OFFSET(PSTRUCT)) { \
+ (PE) = MISTR_ZERO_EL(PSTRUCT); \
+ _start = 0; \
+ } else { \
+ _start = MISTR_CURR_EL_OFFSET(PSTRUCT); \
+ (PE) = MISTR_CURR_EL_PTR(PSTRUCT); \
+ } \
+ for (_i=_start; _i<(OFFSET); _i++, (PE) = MISTR_NEXT_EL(PE)); \
+ }
+
+/* given pointer to element, find out what its OFFSET is in the struct */
+/* the element better be in the struct! */
+/* for now, don't know whether the element is near the beginning or end of
+ * the structure. todo: add hint to improve efficiency such as
+ * whether to start from the beginning or end or maybe some element
+ * and its known OFFSET from whic to start at (and go forwards)
+ */
+#define MISTR_FIND_OFFSET(PSTRUCT, PEL, OFFSET) \
+ if (PEL == MISTR_PREV_EL(MISTR_LAST_EL(PSTRUCT))) \
+ (OFFSET) = MISTR_NUM_EL(PSTRUCT); \
+ else { \
+ register int i; \
+ register miGenericElementPtr ptemp; \
+ for (i = 0, ptemp = MISTR_ZERO_EL(PSTRUCT); \
+ ((i < MISTR_NUM_EL(PSTRUCT)) && (ptemp != (PEL))); \
+ i++, ptemp = MISTR_NEXT_EL(ptemp)); \
+ (OFFSET) = i; \
+ }
+
+/* Must check Proprietary and in Range to avoid Null function ptrs */
+#define MISTR_DEL_ONE_EL(PSTRUCT, PPREV, PEL) { \
+ MISTR_NEXT_EL(PPREV) = MISTR_NEXT_EL(PEL); \
+ MISTR_PREV_EL(MISTR_NEXT_EL(PEL)) = (PPREV); \
+ if (MI_HIGHBIT_ON(MISTR_EL_TYPE(PEL))) \
+ (*DestroyCSSElementTable[MI_OC_PROP])((PSTRUCT), (PEL)); \
+ else \
+ if (MI_IS_PEX_OC(MISTR_EL_TYPE(PEL))) \
+ (*DestroyCSSElementTable[MISTR_EL_TYPE(PEL)])((PSTRUCT), (PEL));\
+ }
+
+#define MISTR_INSERT_ONE_EL(PPREV, PEL) \
+ MISTR_NEXT_EL(PEL) = MISTR_NEXT_EL(PPREV); \
+ MISTR_PREV_EL(MISTR_NEXT_EL(PEL)) = PEL; \
+ MISTR_NEXT_EL(PPREV) = (PEL); \
+ MISTR_PREV_EL(PEL) = (PPREV)
+
+/* PSTRUCT is structure handle; DDSTRUCT is dd structure header */
+/* first can't be 0, last can't be more than number in structure */
+/* inclusive delete, does not update structure header info */
+/* Must check Proprietary and in Range to avoid Null function ptrs */
+#define MISTR_DEL_ELS(PSTRUCT, DDSTRUCT, FIRST, LAST) \
+ if ((int)((LAST) - (FIRST)) >= 0) { \
+ register int num; \
+ register miGenericElementPtr pe, pe1, pe2; \
+ MISTR_FIND_EL((DDSTRUCT), (FIRST), pe1); \
+ pe = MISTR_PREV_EL(pe1); \
+ for (num = (FIRST); num <= (LAST); num++) { \
+ pe2 = MISTR_NEXT_EL(pe1); \
+ if (MI_HIGHBIT_ON(MISTR_EL_TYPE(pe1))) \
+ (*DestroyCSSElementTable[MI_OC_PROP]) \
+ ((PSTRUCT), pe1); \
+ else \
+ if (MI_IS_PEX_OC(MISTR_EL_TYPE(pe1))) \
+ (*DestroyCSSElementTable[MISTR_EL_TYPE(pe1)]) \
+ ((PSTRUCT), pe1); \
+ pe1 = pe2; \
+ } \
+ MISTR_NEXT_EL(pe) = pe1; \
+ MISTR_PREV_EL(pe1) = pe; \
+ }
+
+/* macros for accessing specific data in some elements
+ * these MUST be changed to reflect the storage format of the elements
+ */
+
+/* this macro returns the structure id in an execute structure element.
+ * for the SI, this element has the structure handle in the id field
+ * can't use these on left side of statement because of casting */
+#define MISTR_GET_EXSTR_STR(PEL) \
+ ((pexExecuteStructure *)((PEL)+1))->id
+
+#define MISTR_GET_EXSTR_ID(PEL) \
+ ((ddStructResource *)((pexExecuteStructure *)((PEL)+1))->id)->id
+
+/* use this to change structure in ChangeStructureRefs */
+#define MISTR_PUT_EXSTR_STR(PEL, PSTRUCT) \
+ { pexExecuteStructure *pexstr; \
+ pexstr = (pexExecuteStructure *)((PEL)+1);\
+ pexstr->id = (pexStructure)(PSTRUCT); \
+ }
+
+#define MISTR_GET_LABEL(PEL) ((pexLabel *)((PEL)+1))->label
+
+#define MISTR_GET_PICK_ID(PEL) ((pexPickId *)((PEL)+1))->pickId
+
+#endif /* MISTRMACRO_H */
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/include/miStruct.h b/xc/programs/Xserver/PEX5/ddpex/mi/include/miStruct.h
new file mode 100644
index 000000000..edf4c13fc
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/include/miStruct.h
@@ -0,0 +1,147 @@
+/* $TOG: miStruct.h /main/6 1998/02/10 12:39:15 kaleb $ */
+
+
+/***********************************************************
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution of
+the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/include/miStruct.h,v 1.3 1998/10/04 09:34:07 dawes Exp $ */
+
+#ifndef MISTRUCT_H
+#define MISTRUCT_H
+
+#include "X.h"
+#include "PEXproto.h"
+#include "ddpex.h"
+
+typedef ddpex4rtn (*cssTableType)();
+
+typedef struct {
+ ddUSHORT elementType;
+ ddUSHORT pexOClength;
+ /* concatenate imp. dep. data definitions here */
+ /* sample server definitions are listed later in this file */
+
+ /* do the following to pad to 64 bit alignment for alpha */
+#if defined(__alpha) || defined(__alpha__)
+ ddUSHORT unused0;
+ ddUSHORT unused1;
+#endif
+} miGenericStr;
+
+typedef struct _miCSSElement {
+ struct _miCSSElement *prev, *next;
+ diStructHandle pStruct;
+ miGenericStr element; /* replace this with imp.
+ * dep. data structure */
+} miGenericElementStr, *miGenericElementPtr;
+
+typedef struct _miCSSElementHead {
+ struct _miCSSElementHead *next, *prev;
+} miElementHeadStr;
+
+#define EL_HEAD_SIZE sizeof(miElementHeadStr)
+
+typedef struct _miStructHeader {
+ /* the resource id is in the dipex resource structure */
+ ddUSHORT editMode;
+ ddULONG numElements;
+ ddULONG totalSize; /* of elements when in PEX format */
+ miGenericElementPtr pZeroElement; /* dummy */
+ miGenericElementPtr pLastElement; /* dummy */
+ miGenericElementPtr pCurrElement;
+ ddLONG currElementOffset;
+ listofObj *parents;
+ listofObj *children;
+ listofObj *wksPostedTo; /* directly posted to */
+ listofObj *wksAppearOn; /* indirectly, thru inherit.*/
+ ddULONG refCount; /* for search context & pick measure */
+ ddBOOL freeFlag; /* keep structure until no sc or
+ * pick measure uses it */
+} miStructStr, *miStructPtr;
+
+/* sample server element definitions */
+
+/* all fixed sized elements use the PEX protocol format and are not
+ * defined explicitely
+ */
+
+/*
+ * See ddpex2.h for data definitions for the others
+ */
+
+/* traverser state info. passed to level 4 traverser which is used by
+ * level 4 structure traversal and by level 3 mixed mode traversal.
+ * When following initial path before pick/search, don't want to
+ * follow all execute structure elements, only follow ones in search
+ * path. Also, when following initial path, don't want to call
+ * primitive OCS because actual pick/search isn't done until
+ * start path has been traversed. Use this enum value to determine
+ * when to follow exec.str element and when to bypass primitives
+ */
+typedef enum {
+ ES_YES = 0, /* do 'normal' traversal */
+ ES_POP = 1, /* pick or search is done, pop out of traverser */
+ ES_FOLLOW_PICK = 2, /* follow initial pick path before picking */
+ ES_FOLLOW_SEARCH = 3 /* follow initial search path before search */
+} miExecStrState;
+
+/* added to allow SI to do pick last */
+typedef struct _miPPLevel {
+ ddPickPath pp;
+ struct _miPPLevel *up;
+} miPPLevel;
+
+
+/*
+ * level 3 traversal doesn't do picking or search, so it ALWAYS sets
+ * exec_str_flag to YES and the element pointers to NULL
+ */
+typedef struct {
+ miExecStrState exec_str_flag;
+ ddULONG pickId;
+ ddULONG ROCoffset;
+ ddPickPath *p_curr_pick_el;
+ ddElementRef *p_curr_sc_el;
+ ddSHORT max_depth; /* max depth reached in pick or search */
+ miPPLevel *p_pick_path;
+} miTraverserState;
+
+#endif /* MISTRUCT_H */
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/include/miText.h b/xc/programs/Xserver/PEX5/ddpex/mi/include/miText.h
new file mode 100644
index 000000000..53c73875a
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/include/miText.h
@@ -0,0 +1,65 @@
+/* $TOG: miText.h /main/3 1998/02/10 12:39:20 kaleb $ */
+
+/***********************************************************
+
+Copyright 1989,1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Copyright 1989,1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Sun Microsystems,
+and The Open Group, not be used in advertising or publicity
+pertaining to distribution of the software without specific, written
+prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS 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 MI_TEXT_H
+#define MI_TEXT_H
+
+#include "miRender.h"
+
+#define HEIGHT 100.0
+
+typedef struct {
+ ddVector2D trans; /* Translation per character */
+ miListHeader *path; /* Strokes for char */
+ }miCharPath;
+
+typedef struct {
+ /* Following can be cached */
+ miCharPath *paths; /* Char data */
+ ddFLOAT xform[4][4]; /* CC_to_MC_Xform */
+ /* More cache data may follow, e.g. text attrs. */
+ }miTextElement;
+
+#endif /*MI_TEXT_H*/
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/include/miWks.h b/xc/programs/Xserver/PEX5/ddpex/mi/include/miWks.h
new file mode 100644
index 000000000..b1b97f3c6
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/include/miWks.h
@@ -0,0 +1,190 @@
+/* $TOG: miWks.h /main/5 1998/02/10 12:39:24 kaleb $ */
+
+/***********************************************************
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution of
+the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS 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 "mipex.h"
+#include "ddpex4.h"
+#include "miNS.h"
+#include "miLUT.h"
+#include "miInfo.h"
+#include "miPick.h"
+
+#ifndef MIWKS_H
+#define MIWKS_H
+
+typedef struct _ddOrdStruct {
+ diStructHandle pstruct;
+ ddFLOAT priority;
+ struct _ddOrdStruct *next;
+} ddOrdStruct;
+
+typedef struct {
+ ddULONG numStructs;
+ ddOrdStruct *postruct; /* the first element in the list is a dummy */
+} listofOrdStruct;
+
+/**********************************************************************
+ View numbers sparsely fill the range 0 - 65534
+ Since there is no way to predetermine which views will be defined,
+ all views must be in the original priority list. The original
+ list contains all views possible prioritized in numerical
+ order, 0 is highest priority and 65534 is lowest.
+ Each entry in the priority list contains a range of
+ views. All views in that range are prioritized numerically.
+ When a view is defined, it is put in an entry by itself with
+ first_view = last_view and defined = T. Only defined views can
+ have their priority changed, so putting them in their own entry
+ makes this easier. If a view is deleted, its entry in the priority
+ list has defined=F and stays in the list. If the view is set again,
+ defined is set to T again and it stays in the list whereever it is.
+
+ The higher and lower fields contain the index of the entry containing
+ the higher and lower priority views, resp. When view priorities
+ are set, these values are changed. The highest priority view has
+ higher = -1. The lowest priority view has lower = -1. Invalid
+ entries are kept in a free list.
+ NOTE: higher and lower contain index values into the view priority
+ tables. These values do not correspond to view numbers.
+
+ The max number of defined views is possible. With defined views
+ using one entry and all other views defined in ranges which at
+ most will use one entry between and around every defined view,
+ the max number of entries will be MAX_DEFINED_VIEWS *2 +1.
+ Then, add 2 dummies entries as the head and tail of the list.
+**********************************************************************/
+
+#define MIWKS_MAX_VIEWS 6 /* same as in miViewLUT.c */
+#define MIWKS_MAX_ORD_VIEWS ( MIWKS_MAX_VIEWS * 2 + 3)
+
+typedef struct _ddOrdView {
+ short defined;
+ ddUSHORT first_view; /* view number */
+ ddUSHORT last_view; /* view number */
+ struct _ddOrdView *higher; /* next higher view */
+ struct _ddOrdView *lower; /* next lower view */
+} ddOrdView;
+
+typedef struct {
+ ddULONG defined_views; /* number of defined views */
+ ddOrdView *highest; /* highest pri view */
+ ddOrdView *lowest; /* lowest pri view */
+ ddOrdView *free; /* first unused entry */
+ ddOrdView entries[MIWKS_MAX_ORD_VIEWS];
+} listofOrdView;
+
+#define MIWKS_NEW_OV_ENTRY( plist, index ) \
+ (index) = plist->free; \
+ if ((index) != NULL) { \
+ plist->free = index->lower; \
+ plist->free->higher = NULL; }
+
+typedef struct _miWks {
+ /* the resource id is in the dipex resource structure */
+ ddEnumTypeIndex displayUpdate;
+ ddBYTE visualState;
+ ddBYTE displaySurface;
+ ddBYTE viewUpdate;
+ /* list of defined views and their priorities */
+ /* highest priority is first on the list */
+ listofOrdView views;
+ diLUTHandle reqViewTable;
+ /* deltaviewMask tells which entries in view table are pending */
+ /* VIEW MASKS ONLY GOOD FOR VIEW TABLES WHOSE MAX SIZE IS 32 */
+ ddULONG deltaviewMask;
+ /* current view table is in renderer */
+ ddBYTE wksUpdate;
+ /* wksMask tells if wks window or viewport is pending */
+ ddBYTE wksMask;
+ ddNpcSubvolume reqNpcSubvolume;
+ /* current NPCsubvolume is in renderer */
+ ddViewport reqviewport;
+ /* current Viewport is in renderer */
+ ddBYTE hlhsrUpdate;
+ ddEnumTypeIndex reqhlhsrMode;
+ /* current HLHSR mode is in renderer */
+ ddRendererPtr pRend;
+ /* stuff in renderer: *
+ * render id (same as wks id ) *
+ * pointer to pc (NULL) *
+ * example drawable info *
+ * rendering drawable *
+ * current path *
+ * renderer state *
+ * marker bundle lut handle *
+ * text bundle lut handle *
+ * line bundle lut handle *
+ * interior bundle lut handle *
+ * edge bundle lut handle *
+ * (current) view table handle *
+ * color table lut handle *
+ * depth cue table lut handle *
+ * light table lut handle *
+ * approx tables lut handles *
+ * pattern table lut handle *
+ * font table lut handle *
+ * highlight incl name set *
+ * highlight excl name set *
+ * invis incl name set *
+ * invis excl name set *
+ * current hlhsr mode *
+ * current npc subvolume *
+ * current viewport */
+ ddBYTE bufferUpdate;
+ ddUSHORT curBufferMode;
+ ddUSHORT reqBufferMode;
+ listofOrdStruct postedStructs;
+ ddBYTE dynamics[MAX_DYNAMIC];
+ /* pick measures use workstation, so keep a free flage & reference count */
+ ddBOOL freeFlag;
+ ddLONG refCount;
+ miPickDevice devices[MIWKS_NUM_PICK_DEVICES];
+ /* pwksList is extra object used by deal with dynamics */
+ listofObj *pwksList;
+ DrawablePtr doubleDrawables[2];
+ int curDoubleBuffer;
+ int hasDoubleBuffer;
+ int usingDoubleBuffer;
+ DrawablePtr pCurDrawable;
+} miWksStr, *miWksPtr;
+
+#endif /* MIWKS_H */
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/include/mipex.h b/xc/programs/Xserver/PEX5/ddpex/mi/include/mipex.h
new file mode 100644
index 000000000..8af5996af
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/include/mipex.h
@@ -0,0 +1,390 @@
+/* $TOG: mipex.h /main/6 1998/02/10 12:39:29 kaleb $ */
+
+/***********************************************************
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Sun Microsystems,
+and The Open Group, not be used in advertising or publicity
+pertaining to distribution of the software without specific, written
+prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/include/mipex.h,v 3.1 1998/10/04 09:34:08 dawes Exp $ */
+
+#ifndef MI_H
+#define MI_H
+
+#include "ddpex.h"
+#include "X.h"
+#include "scrnintstr.h"
+
+#define MI_TRUE 1
+#define MI_FALSE 0
+
+#define MI_MAXUSHORT 65535 /* max value for unsigned short int: 2**16 */
+#define MI_PI 3.14159265358979323846 /* from values.h */
+
+#define MI_FIRSTTABLETYPE 1 /* a useful constant that's not in PEX.h */
+
+#define MI_BACKGROUND 0
+#define MI_FOREGROUND 1
+
+/* high bit mask for proprietary OCs */
+#define MI_OC_HIGHBIT 0x8000
+
+/* a redefinable location for use in branching on proprietary OCs */
+#define MI_OC_PROP 0
+
+/* see if propietary bit is set in OC Type */
+#define MI_HIGHBIT_ON(octype) ((octype) & MI_OC_HIGHBIT)
+
+/* see if OC Type (or element) is in range of PEX OCs */
+#define MI_IS_PEX_OC(octype) (((octype) > PEXOCAll) && ((octype) <= PEXMaxOC))
+
+/** redefine ASSURE even if it's already defined **/
+#ifdef ASSURE
+#undef ASSURE
+#endif
+
+
+typedef void (*destroyTableType)();
+
+
+#ifdef DDTEST
+#define ASSURE(test) \
+ if (!(test)) { \
+ ErrorF( "test \n"); \
+ ErrorF( "Failed: Line %d, File %s\n\n", __LINE__, __FILE__); \
+ }
+#else
+#define ASSURE(test)
+#endif /* DDTEST */
+
+/* the WHICDRAW macro looks at the given drawable and determines which
+ * of the suported drawable types it matches
+ * WHICHDRAW should compare the data in the given drawable with the
+ * drawable types defined here to define a impe dep drawable type id
+ * For now, only one drawable type is supported and it
+ * handles all drawables.
+ */
+#define MI_MAXDRAWABLES 1
+/* type depth rootDepth rootVisual */
+#define MI_DRAWABLE0 0/*ANY ANY ANY ANY */
+
+#define MI_SETDRAWEXAMPLE( pdraw, peg ) \
+ (peg)->type = (pdraw)->type; \
+ (peg)->class = (pdraw)->class; \
+ (peg)->depth = (pdraw)->depth; \
+ (peg)->bitsPerPixel = (pdraw)->bitsPerPixel; \
+ (peg)->rootDepth = (pdraw)->pScreen->rootDepth; \
+ (peg)->rootVisual = (pdraw)->pScreen->rootVisual
+
+#define MI_WHICHDRAW( pdraw, type ) \
+ type = MI_DRAWABLE0
+
+/* dd internal error codes */
+#define MI_SUCCESS 0
+#define MI_ALLOCERR 1
+#define MI_EXISTERR 2
+
+#define MI_DEFAULT_COLOUR_FORMAT PEXRgbFloatColour
+
+/* only do indexed & rgb floats now */
+#define MI_BADCOLOURTYPE( format ) \
+ ( (format!=PEXIndexedColour) && \
+ (format!=PEXRgbFloatColour) ) /* && \
+ (format!=PEXCieFloatColour) && \
+ (format!=PEXHsvFloatColour) && \
+ (format!=PEXHlsFloatColour) && \
+ (format!=PEXRgbInt8Colour) && \
+ (format!=PEXRgbInt16Colour) )
+ */
+
+/* JSH - assuming copy may overlap */
+#define mibcopy(pfrom, pto, size) \
+ memmove( (char *)(pto), (char *)(pfrom), (int)(size))
+
+extern int PexErrorBase;
+#define PEXERR( pexerrnum ) (pexerrnum) + PexErrorBase
+
+#ifndef ABS
+#define ABS(x) ((x) < 0 ? -(x) : (x))
+#endif
+
+#define MI_ZERO_TOLERANCE 1.0e-30
+#define MI_NEAR_ZERO( s ) (ABS(s) < MI_ZERO_TOLERANCE)
+#define MI_ZERO_MAG( s ) ((s) < MI_ZERO_TOLERANCE)
+
+#define MI_MAT_IDENTITY( mat, dim ) \
+ { register int i,j; \
+ for (i=0; i<dim; i++) \
+ for (j=0; j<dim; j++) \
+ (mat)[i][j] = ( (i==j) ? 1.0 : 0.0 ); \
+ }
+
+
+typedef struct {
+ ddEnumTypeIndex index;
+ char *name;
+} miEnumType;
+
+typedef enum {
+ VIEW_REP_DYNAMIC=0,
+ MARKER_BUNDLE_DYNAMIC=1,
+ TEXT_BUNDLE_DYNAMIC=2,
+ LINE_BUNDLE_DYNAMIC=3,
+ INTERIOR_BUNDLE_DYNAMIC=4,
+ EDGE_BUNDLE_DYNAMIC=5,
+ COLOUR_TABLE_DYNAMIC=6,
+ PATTERN_TABLE_DYNAMIC=7,
+ WKS_TRANSFORM_DYNAMIC=8,
+ HIGH_FILTER_DYNAMIC=9,
+ INVIS_FILTER_DYNAMIC=10,
+ HLHSR_MODE_DYNAMIC=11,
+ STR_MODIFY_DYNAMIC=12,
+ POST_STR_DYNAMIC=13,
+ UNPOST_STR_DYNAMIC=14,
+ DELETE_STR_DYNAMIC=15,
+ REF_MODIFY_DYNAMIC=16,
+ BUFFER_MODIFY_DYNAMIC=17,
+ LIGHT_TABLE_DYNAMIC=18,
+ DEPTH_CUE_DYNAMIC=19,
+ COLOUR_APPROX_TABLE_DYNAMIC=20,
+ MAX_DYNAMIC = 21
+} ddDynamic;
+
+#ifdef DDTEST
+#define PRINTOC( ptr ) { \
+ ddUSHORT elType, length; \
+ \
+ elType = ((pexElementInfo *)ptr)->elementType; \
+ length = ((pexElementInfo *)ptr)->length; \
+ \
+ ErrorF("Element Type: %3d - %s Length: %d\n", \
+ elType, ocNames[elType], length ); \
+ }
+#else /* DDTEST */
+#define PRINTOC( ptr )
+#endif
+
+/* dd clip routine status returns */
+#define MI_CLIP_LEFT (1<<0)
+#define MI_CLIP_TOP (1<<2)
+#define MI_CLIP_RIGHT (1<<1)
+#define MI_CLIP_BOTTOM (1<<3)
+#define MI_CLIP_FRONT (1<<4)
+#define MI_CLIP_BACK (1<<5)
+
+#define MI_CLIP_TRIVIAL_ACCEPT 0
+#define MI_CLIP_POINT_1 1
+#define MI_CLIP_POINT_2 2
+#define MI_CLIP_TRIVIAL_REJECT 4
+
+/*
+ * Memory management macros for use with data lists in static ddcontext
+ */
+
+/*
+ * MI_ROUND_LISTHEADERCOUNT is used by the clip routines to round up the
+ * header block count by 16 - in other words to allocated headerblocks
+ * in increment of 16 and thus reduce calls to xrealloc.
+ * Note that this doesn't work for beans w/ negative numbers (although
+ * allocating a negative number of header blocks doesn't work well either!).
+ */
+#define MI_ROUND_LISTHEADERCOUNT(val) (((val) + 15) & ~15)
+
+/*
+ * MI_ALLOCLISTHEADER insures that there are numlists headers in the
+ * header array. It also returns either a pointer to the base of the
+ * new header array, or 0 in the event of an xrealloc error.
+ */
+#define MI_ALLOCLISTHEADER(list, numlists) \
+ if ((list)->maxLists < (numlists)) { \
+ int i; \
+ listofddPoint *listptr; \
+ if ((list)->maxLists) \
+ (list)->ddList = \
+ (listofddPoint *)xrealloc((list)->ddList, \
+ (numlists)*sizeof(listofddPoint)); \
+ else \
+ (list)->ddList = \
+ (listofddPoint *)xalloc((numlists)*sizeof(listofddPoint)); \
+ listptr = &(list)->ddList[(list)->maxLists]; \
+ for (i = (list)->maxLists; i < (numlists); i++) { \
+ listptr->numPoints = listptr->maxData = 0; \
+ (listptr++)->pts.p2Dpt = 0; \
+ } \
+ (list)->maxLists=(numlists); \
+ }
+
+/*
+ * MI_FREELISTHEADER xfree's all allocated data associated with
+ * a ListHeader data structure.
+ */
+#define MI_FREELISTHEADER(list) \
+ if ((list)->maxLists) \
+ { \
+ ddULONG maxlists = (list)->maxLists; \
+ listofddPoint *listptr = (list)->ddList; \
+ int mi_freelistheader_counter; \
+ for (mi_freelistheader_counter = 0; \
+ mi_freelistheader_counter < maxlists; \
+ mi_freelistheader_counter++) { \
+ if (listptr->maxData) xfree(listptr->pts.p2Dpt); \
+ listptr++; \
+ } \
+ xfree((list)->ddList); \
+ (list)->maxLists = 0; \
+ }
+
+/*
+ * MI_ALLOCLISTOFDDPOINT insures that there are numpoints in the
+ * vertex array of type type. It also returns either a pointer
+ * to the base of the new data array, or 0 in the event of
+ * an xrealloc error.
+ */
+#define MI_ALLOCLISTOFDDPOINT(buff, numpoints, bytes_per_vert) \
+ if ((buff)->maxData) { \
+ if ((buff)->maxData < (numpoints)*bytes_per_vert) { \
+ (buff)->maxData = (numpoints) * bytes_per_vert; \
+ (buff)->pts.p2Dpt=(ddCoord2D *)xrealloc((buff)->pts.p2Dpt, \
+ (buff)->maxData); \
+ } \
+ } else { \
+ (buff)->maxData = (numpoints) * bytes_per_vert; \
+ (buff)->pts.p2Dpt=(ddCoord2D *)xalloc((buff)->maxData); \
+ }
+
+/*
+ * MI_FREELISTOFDDPOINT frees the data area associated with
+ * the specified list header.
+ * It also sets the list pointer to 0, and the max data count to 0.
+ */
+#define MI_FREELISTOFDDPOINT(buff, numpoints, bytes_per_vert) \
+ if (buff) \
+ { \
+ xfree((buff)->pts.p2Dpt); \
+ (buff)->pts.p2Dpt = 0; \
+ (buff)->maxData = 0; \
+ }
+
+
+/*
+ * Memory management macros for use with facet lists in static ddcontext
+ */
+
+/*
+ * MI_ALLOCLISTOFDDFACET insures that there are numfacets in the
+ * facet array of type type. It also returns either a pointer
+ * to the base of the new data array, or 0 in the event of
+ * an xrealloc error.
+ */
+#define MI_ALLOCLISTOFDDFACET(buff, numfacets, bytes_per_facet) \
+ if ((buff)->maxData) { \
+ if ((buff)->maxData < (numfacets)*bytes_per_facet) { \
+ (buff)->maxData = (numfacets) * bytes_per_facet; \
+ (buff)->facets.pFacetRgbFloatN = \
+ (ddRgbFloatNormal *)xrealloc((buff)->facets.pFacetRgbFloatN, \
+ (buff)->maxData); \
+ } \
+ } else { \
+ (buff)->maxData = (numfacets) * bytes_per_facet; \
+ (buff)->facets.pFacetRgbFloatN = \
+ (ddRgbFloatNormal *)xalloc((buff)->maxData); \
+ }
+
+/*
+ * MI_FREELISTOFDDFACET frees the data area associated with
+ * the specified facet list.
+ * It also sets the list pointer to 0, and the max data count to 0.
+ */
+#define MI_FREELISTOFDDFACET(buff) \
+ if (buff) \
+ { \
+ xfree((buff)->pts.p2Dpt); \
+ (buff)->facets.pFacetRgbFloatN = 0; \
+ (buff)->maxData = 0; \
+ }
+
+
+/* bit handling macros for renderer dynamics change flags */
+
+#define MI_SET_ALL_CHANGES(prend) \
+ prend->tablesChanges = ~0; \
+ prend->namesetsChanges = ~0; \
+ prend->attrsChanges = ~0
+
+#define MI_ZERO_ALL_CHANGES(prend) \
+ prend->tablesChanges = 0; \
+ prend->namesetsChanges = 0; \
+ prend->attrsChanges = 0
+
+
+/* Inverse transform validation routines */
+
+#define VALIDATEINVTRMCTOWCXFRM(pddc) \
+ if (pddc->Static.misc.flags & INVTRMCTOWCXFRMFLAG) { \
+ miMatCopy(pddc->Dynamic->mc_to_wc_xform, \
+ pddc->Static.misc.inv_tr_mc_to_wc_xform); \
+ miMatInverseTranspose(pddc->Static.misc.inv_tr_mc_to_wc_xform);\
+ pddc->Static.misc.flags &= ~INVTRMCTOWCXFRMFLAG; \
+ }
+
+#define VALIDATEINVTRWCTOCCXFRM(pddc) \
+ if (pddc->Static.misc.flags & INVTRWCTOCCXFRMFLAG) { \
+ miMatCopy(pddc->Dynamic->wc_to_cc_xform, \
+ pddc->Static.misc.inv_tr_wc_to_cc_xform); \
+ miMatInverseTranspose(pddc->Static.misc.inv_tr_wc_to_cc_xform);\
+ pddc->Static.misc.flags &= ~INVTRWCTOCCXFRMFLAG; \
+ }
+
+#define VALIDATEINVTRMCTOCCXFRM(pddc) \
+ if (pddc->Static.misc.flags & INVTRMCTOCCXFRMFLAG) { \
+ miMatCopy(pddc->Dynamic->mc_to_cc_xform, \
+ pddc->Static.misc.inv_tr_mc_to_cc_xform); \
+ miMatInverseTranspose(pddc->Static.misc.inv_tr_mc_to_cc_xform);\
+ pddc->Static.misc.flags &= ~INVTRMCTOCCXFRMFLAG; \
+ }
+
+#define VALIDATEINVTRCCTODCXFRM(pddc) \
+ if (pddc->Static.misc.flags & INVTRCCTODCXFRMFLAG) { \
+ miMatCopy(pddc->Dynamic->cc_to_dc_xform, \
+ pddc->Static.misc.inv_tr_cc_to_dc_xform); \
+ miMatInverseTranspose(pddc->Static.misc.inv_tr_cc_to_dc_xform);\
+ pddc->Static.misc.flags &= ~INVTRCCTODCXFRMFLAG; \
+ }
+
+#endif /* MI_H */
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/include/mixform.h b/xc/programs/Xserver/PEX5/ddpex/mi/include/mixform.h
new file mode 100644
index 000000000..490f6657f
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/include/mixform.h
@@ -0,0 +1,55 @@
+/* $TOG: mixform.h /main/3 1998/02/10 12:39:35 kaleb $ */
+
+/***********************************************************
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution of
+the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS 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.
+
+
+******************************************************************/
+/*
+** Definition of some global transformation matrices for fastdd3
+*/
+
+#include "ddpex.h"
+
+ddFLOAT mc_to_dc_xform[4][4];
+ddFLOAT mc_to_npc_xform[4][4];
+ddFLOAT mc_to_wc_xform[4][4];
+ddFLOAT wc_to_npc_xform[4][4];
+ddFLOAT npc_to_dc_xform[4][4];
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level0/README b/xc/programs/Xserver/PEX5/ddpex/mi/level0/README
new file mode 100644
index 000000000..4f88f8689
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level0/README
@@ -0,0 +1,48 @@
+
+/* $TOG: README /main/3 1998/02/10 13:59:41 kaleb $ */
+
+/***********************************************************
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution of
+the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+This directory contains the lowest level support for PEX. The sample
+implementation uses the core X device-dependent code (ddx) for this level.
+Please go to directory Xsrc/server/ddx to find this code.
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level1/Imakefile b/xc/programs/Xserver/PEX5/ddpex/mi/level1/Imakefile
new file mode 100644
index 000000000..7aa86e3f1
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level1/Imakefile
@@ -0,0 +1,81 @@
+XCOMM
+XCOMM $XConsortium: Imakefile /main/10 1996/09/28 16:54:08 rws $
+XCOMM $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level1/Imakefile,v 3.10 1999/04/17 09:08:15 dawes Exp $
+XCOMM
+XCOMM
+XCOMM Copyright 1989, 1990, 1991 by Sun Microsystems, Inc. and the X Consortium
+XCOMM
+XCOMM All Rights Reserved
+XCOMM
+XCOMM Permission to use, copy, modify, and distribute this software and its
+XCOMM documentation for any purpose and without fee is hereby granted,
+XCOMM provided that the above copyright notice appear in all copies and that
+XCOMM both that copyright notice and this permission notice appear in
+XCOMM supporting documentation, and that the names of Sun Microsystems
+XCOMM and the X Consortium not be used in advertising or publicity
+XCOMM pertaining to distribution of the software without specific, written
+XCOMM prior permission.
+XCOMM
+XCOMM SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+XCOMM INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+XCOMM EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+XCOMM CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+XCOMM USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+XCOMM OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+XCOMM PERFORMANCE OF THIS SOFTWARE.
+
+#define IHaveModules
+#include <Server.tmpl>
+
+#ifndef PexDdpexCDebugFlags
+#define PexDdpexCDebugFlags ServerCDebugFlags
+#endif
+
+XCOMM -D defines for ddpex:
+XCOMM DDTEST turns on some fprintf(stderr...)s for debugging
+
+ DEFINES = PexDdpexDefines
+CDEBUGFLAGS = PexDdpexCDebugFlags
+
+ PEXSERVINC = ../../../include
+DDPEXINCLUDE = ../include
+
+INCLUDES = -I. \
+ -I$(DDPEXINCLUDE) \
+ -I$(XINCLUDESRC) \
+ -I$(PEXSERVINC) \
+ -I$(SERVERSRC)/include
+
+SRCS = miDDCtoGC.c \
+ miListUtil.c \
+ miLvl1Tab.c \
+ miRndFArea.c \
+ miRndPLine.c \
+ miRndMarkr.c \
+ miRndText.c \
+ miRndTStrip.c \
+ miPck1Prim.c \
+ mi52stubs.c
+
+OBJS = miDDCtoGC.o \
+ miListUtil.o \
+ miLvl1Tab.o \
+ miRndFArea.o \
+ miRndPLine.o \
+ miRndMarkr.o \
+ miRndText.o \
+ miRndTStrip.o \
+ miPck1Prim.o \
+ mi52stubs.o
+
+ModuleObjectRule()
+
+SubdirLibraryRule($(OBJS))
+
+NormalLibraryTarget(ddpex1,$(OBJS))
+
+LintLibraryTarget(dp1, $(SRCS))
+NormalLintTarget($(SRCS))
+
+DependTarget()
+
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level1/mi52stubs.c b/xc/programs/Xserver/PEX5/ddpex/mi/level1/mi52stubs.c
new file mode 100644
index 000000000..d381d4823
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level1/mi52stubs.c
@@ -0,0 +1,177 @@
+/* $TOG: mi52stubs.c /main/2 1998/02/10 12:40:32 kaleb $ */
+
+/***********************************************************
+
+Copyright 1994, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+******************************************************************/
+
+#include "X.h"
+#include "PEX.h"
+#include "pexError.h"
+#include "pex_site.h"
+#include "pexLookup.h"
+#include "ddpex4.h"
+
+ErrorCode
+PutZBuffer(prend, x, y, width, height, normalizedValues, numValues, Zbuffer)
+ ddRendererStr prend;
+ int x, y;
+ unsigned int width, height;
+ pexSwitch normalizedValues;
+ unsigned int numValues;
+ ddPointer *Zbuffer;
+{
+ return Success;
+}
+
+
+ErrorCode
+SetStructurePermission(pstr, permission)
+ diStructHandle pstr;
+ unsigned int permission;
+{
+ return Success;
+}
+
+
+ErrorCode
+CopyPixmapToAlpha(prend, pDrawable)
+ ddRendererStr prend;
+ DrawablePtr pDrawable;
+{
+ return Success;
+}
+
+
+ErrorCode
+InitMultipass(prend)
+ ddRendererStr prend;
+{
+ return Success;
+}
+
+
+ErrorCode
+GetZBuffer(prend, x, y, width, height, normalizedValues, numValues,
+ undefinedValues, pPEXBuffer)
+ ddRendererStr prend;
+ int x, y;
+ unsigned int width, height;
+ pexSwitch normalizedValues;
+ ddULONG *numValues;
+ pexSwitch *undefinedValues;
+ ddBuffer *pPEXBuffer;
+{
+ return Success;
+}
+
+
+ErrorCode
+ClearRenderer(prend, clearControl)
+ ddRendererStr prend;
+ pexBitmask clearControl;
+{
+ return Success;
+}
+
+
+ErrorCode
+NextPassWoutReply(prend, multipass_control)
+ ddRendererStr prend;
+ unsigned int multipass_control;
+{
+ return Success;
+}
+
+
+ErrorCode
+CopyZBufferToPixmap(prend, pDrawable)
+ ddRendererStr prend;
+ DrawablePtr pDrawable;
+{
+ return Success;
+}
+
+
+ErrorCode
+CopyPipelineStateToPC(prend, ppc, itemMask)
+ ddRendererStr prend;
+ ddPCStr *ppc;
+ unsigned int itemMask;
+{
+ return Success;
+}
+
+
+ErrorCode
+CopyAlphaToPixmap(prend, pDrawable)
+ ddRendererStr prend;
+ DrawablePtr pDrawable;
+{
+ return Success;
+}
+
+
+ErrorCode
+NextPass(prend, multipass_control, count)
+ ddRendererStr prend;
+ unsigned int multipass_control;
+ ddLONG *count;
+{
+ return Success;
+}
+
+
+ErrorCode
+FlushRenderer(prend, flushFlag)
+ ddRendererStr prend;
+ pexSwitch flushFlag;
+{
+ return Success;
+}
+
+
+ErrorCode
+CopyPixmapToZBuffer(prend, pDrawable)
+ ddRendererStr prend;
+ DrawablePtr pDrawable;
+{
+ return Success;
+}
+
+
+ErrorCode
+SetElementPointerAtPickID(pstr, pickId, offset)
+ diStructHandle pstr;
+ int pickId;
+ int offset;
+{
+ return Success;
+}
+
+
+ErrorCode
+CopyPCToPipelineState(prend, ppc, itemMask)
+ ddRendererStr *prend;
+ ddPCStr *ppc;
+ pexBitmask itemMask;
+{
+ return Success;
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level1/miDDCtoGC.c b/xc/programs/Xserver/PEX5/ddpex/mi/level1/miDDCtoGC.c
new file mode 100644
index 000000000..68f8a34b2
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level1/miDDCtoGC.c
@@ -0,0 +1,589 @@
+/* $TOG: miDDCtoGC.c /main/7 1998/02/10 12:39:39 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level1/miDDCtoGC.c,v 3.6 1998/10/04 09:34:09 dawes Exp $ */
+
+#include "miLUT.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "PEXErr.h"
+#include "miRender.h"
+#include "gcstruct.h"
+#include "miLineDash.h"
+#include "pexos.h"
+
+
+/*++
+ |
+ | Function Name: miDDC_to_GC_polyline
+ |
+ | Function Description:
+ | Initializes the attributes in a GC in order to correctly
+ | render a polyline. Currently, therefore, the following
+ | attributes are set:
+ |
+ | line width
+ | dashing
+ |
+ | Note(s):
+ | This routine currently performs no optimization of this
+ | process. For example, no effort is made to globally check
+ | whether this process is even necessary.
+ | Note that this routine assumes that the proper defaults
+ | are set for the GC attributes not used by PEX (attributes
+ | such as line join style or end cap style).
+ |
+ --*/
+
+ddpex3rtn
+miDDC_to_GC_polyline(pRend, pddc, pgc)
+/* in */
+ddRendererPtr pRend; /* renderer handle */
+miDDContext *pddc; /* dd Context handle */
+GCPtr pgc; /* X GC handle */
+{
+ ddLONG gcmask = 0;
+ ddUSHORT status;
+ ddColourSpecifier linecolour;
+ miColourEntry *plinecolour;
+ ddULONG colourindex;
+ ddSHORT linewidth;
+
+
+ /*
+ * Set line colour.
+ * The colour must be processed according
+ * to the contents of the current colour approximation table
+ * entry to compute the proper direct colour.
+ */
+
+ /*
+ * Calculate final color index.
+ */
+ if (pddc->Static.attrs->echoMode == PEXEcho)
+ linecolour = pddc->Static.attrs->echoColour;
+ else
+ linecolour = pddc->Static.attrs->lineColour;
+
+ miColourtoIndex(pRend, pddc->Dynamic->pPCAttr->colourApproxIndex,
+ &linecolour, &colourindex);
+
+ /* Only set GC value if necessary */
+ if (colourindex != pgc->fgPixel) {
+ gcmask |= GCForeground;
+ pgc->fgPixel = colourindex;
+ }
+
+ /*
+ * Set line width. PEX line width is defined as
+ * the product of the line width scale factor (lineWidth in
+ * the PC) and the workstation nominal line width (1 for X).
+ * therefore the linewidth is simply equal to the line width
+ * scale factor. Note that this code sets lineWidth of 1
+ * to ddx linewidth 0. Although this is technically wrong,
+ * it sure does speed things up!
+ */
+ if (pddc->Static.attrs->lineWidth <= 1.0) linewidth = 0;
+ else linewidth = (ddSHORT)pddc->Static.attrs->lineWidth;
+
+ /* Only set GC value if necessary */
+ if (linewidth != pgc->lineWidth) {
+ gcmask |= GCLineWidth;
+ pgc->lineWidth = linewidth;
+ }
+
+ /*
+ * Set the line dash. PEX defines three line dash
+ * types: solid (no dashing), dashed (equally spaced dashes)
+ * dotted (equally spaced dots) and dash dot (alternating
+ * dots and dashes). Note that the default dashing is
+ * defined in miLineDash.h.
+ */
+ /* Only set dashes if necessary */
+ switch (pddc->Static.attrs->lineType) {
+
+ case PEXLineTypeSolid:
+ if (pgc->lineStyle != LineSolid) {
+ gcmask |= GCLineStyle;
+ pgc->lineStyle = LineSolid;
+ }
+ break;
+
+ case PEXLineTypeDashed:
+ if (pgc->lineStyle != LineOnOffDash) {
+ gcmask |= (GCLineStyle | GCDashList);
+ pgc->lineStyle = LineOnOffDash;
+ pgc->numInDashList = mi_line_dashed_length;
+ if (pddc->Static.misc.flags & NOLINEDASHFLAG) {
+ pgc->dash = (unsigned char *)xalloc(MAX_LINE_DASH_LENGTH_SIZE);
+ pddc->Static.misc.flags &= ~NOLINEDASHFLAG;
+ }
+ memcpy( (char *)(pgc->dash), (char *)mi_line_dashed,
+ sizeof(mi_line_dashed));
+
+ } else if (pgc->dash != mi_line_dashed) {
+ gcmask |= GCDashList;
+ pgc->numInDashList = mi_line_dashed_length;
+ if (pddc->Static.misc.flags & NOLINEDASHFLAG) {
+ pgc->dash = (unsigned char *)xalloc(MAX_LINE_DASH_LENGTH_SIZE);
+ pddc->Static.misc.flags &= ~NOLINEDASHFLAG;
+ }
+ memcpy( (char *)(pgc->dash), (char *)mi_line_dashed,
+ sizeof(mi_line_dashed));
+ }
+ break;
+
+ case PEXLineTypeDotted:
+ if (pgc->lineStyle != LineOnOffDash) {
+ gcmask |= (GCLineStyle | GCDashList);
+ pgc->lineStyle = LineOnOffDash;
+ pgc->numInDashList = mi_line_dotted_length;
+ if (pddc->Static.misc.flags & NOLINEDASHFLAG) {
+ pgc->dash = (unsigned char *)xalloc(MAX_LINE_DASH_LENGTH_SIZE);
+ pddc->Static.misc.flags &= ~NOLINEDASHFLAG;
+ }
+ memcpy( (char *)(pgc->dash), (char *)mi_line_dotted,
+ sizeof(mi_line_dotted));
+
+ } else if (pgc->dash != mi_line_dotted) {
+ gcmask |= GCDashList;
+ pgc->numInDashList = mi_line_dotted_length;
+ if (pddc->Static.misc.flags & NOLINEDASHFLAG) {
+ pgc->dash = (unsigned char *)xalloc(MAX_LINE_DASH_LENGTH_SIZE);
+ pddc->Static.misc.flags &= ~NOLINEDASHFLAG;
+ }
+ memcpy( (char *)(pgc->dash), (char *)mi_line_dotted,
+ sizeof(mi_line_dotted));
+ }
+ break;
+
+ case PEXLineTypeDashDot:
+ if (pgc->lineStyle != LineOnOffDash) {
+ gcmask |= (GCLineStyle | GCDashList);
+ pgc->lineStyle = LineOnOffDash;
+ pgc->numInDashList = mi_line_dashdot_length;
+ if (pddc->Static.misc.flags & NOLINEDASHFLAG) {
+ pgc->dash = (unsigned char *)xalloc(MAX_LINE_DASH_LENGTH_SIZE);
+ pddc->Static.misc.flags &= ~NOLINEDASHFLAG;
+ }
+ memcpy( (char *)(pgc->dash), (char *)mi_line_dashdot,
+ sizeof(mi_line_dashdot));
+
+ } else if (pgc->dash != mi_line_dashdot) {
+ gcmask |= GCDashList;
+ pgc->numInDashList = mi_line_dashdot_length;
+ if (pddc->Static.misc.flags & NOLINEDASHFLAG) {
+ pgc->dash = (unsigned char *)xalloc(MAX_LINE_DASH_LENGTH_SIZE);
+ pddc->Static.misc.flags &= ~NOLINEDASHFLAG;
+ }
+ memcpy( (char *)(pgc->dash), (char *)mi_line_dashdot,
+ sizeof(mi_line_dashdot));
+ }
+ break;
+ }
+
+ /* Register changes with ddx */
+ if (gcmask) {
+ pgc->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ pgc->stateChanges |= gcmask;
+ (*pgc->funcs->ChangeGC)(pgc, gcmask);
+ }
+
+ /* Clear polyline GC change flag */
+ pddc->Static.misc.flags &= ~POLYLINEGCFLAG;
+
+ return (Success);
+}
+
+/*++
+ |
+ | Function Name: miDDC_to_GC_edges
+ |
+ | Function Description:
+ | Initializes the attributes in a GC in order to correctly
+ | render the edges of a fill area. Currently, therefore,
+ | the following attributes are set:
+ |
+ | line width
+ | dashing
+ |
+ | Note(s):
+ | Note, that no colour initialization is performed - this attribute
+ | changes too often within the rendering pipeline.
+ | Lastly, note that this routine assumes that the proper defaults
+ | are set for the GC attributes not used by PEX (attributes
+ | such as stipple mask, etc...)
+ |
+ --*/
+
+ddpex3rtn
+miDDC_to_GC_edges(pRend, pddc, pgc)
+/* in */
+ddRendererPtr pRend; /* renderer handle */
+miDDContext *pddc; /* dd Context handle */
+GCPtr pgc; /* X GC handle */
+{
+ ddLONG gcmask = 0;
+ ddUSHORT status;
+ ddColourSpecifier edgecolour;
+ miColourEntry *pedgecolour;
+ ddULONG colourindex;
+ ddSHORT edgewidth;
+
+
+ /*
+ * Set edge colour.
+ * The colour must be processed according
+ * to the contents of the current colour approximation table
+ * entry to compute the proper direct colour.
+ */
+
+ /*
+ * Calculate final color index.
+ */
+ if (pddc->Static.attrs->echoMode == PEXEcho)
+ edgecolour = pddc->Static.attrs->echoColour;
+ else
+ edgecolour = pddc->Static.attrs->edgeColour;
+
+ miColourtoIndex(pRend, pddc->Dynamic->pPCAttr->colourApproxIndex,
+ &edgecolour, &colourindex);
+
+
+ /* Only set GC value if necessary */
+ if (colourindex != pgc->fgPixel) {
+ gcmask |= GCForeground;
+ pgc->fgPixel = colourindex;
+ }
+
+ /*
+ * Set edge width. PEX edge width is defined as
+ * the product of the edge width scale factor (lineWidth in
+ * the PC) and the workstation nominal line width (1 for X).
+ * therefore the edge is simply equal to the edge width
+ * scale factor. Note that this code sets edgeWidth of 1
+ * to ddx linewidth 0. Although this is technically wrong,
+ * it sure does speed things up!
+ */
+ if (pddc->Static.attrs->edgeWidth <= 1.0) edgewidth = 0;
+ else edgewidth = (ddSHORT)pddc->Static.attrs->edgeWidth;
+
+ /* Only set GC value if necessary */
+ if (edgewidth != pgc->lineWidth) {
+ gcmask |= GCLineWidth;
+ pgc->lineWidth = edgewidth;
+ }
+
+ /*
+ * Next, set the edge dash. PEX defines three line dash
+ * types: solid (no dashing), dashed (equally spaced dashes)
+ * dotted (equally spaced dots) and dash dot (alternating
+ * dots and dashes). Note that the default dashing is
+ * defined in miLineDash.h.
+ */
+ switch (pddc->Static.attrs->edgeType) {
+
+ case PEXLineTypeSolid:
+ if (pgc->lineStyle != LineSolid) {
+ gcmask |= GCLineStyle;
+ pgc->lineStyle = LineSolid;
+ }
+ break;
+
+ case PEXLineTypeDashed:
+ if (pgc->lineStyle != LineOnOffDash) {
+ gcmask |= (GCLineStyle | GCDashList);
+ pgc->lineStyle = LineOnOffDash;
+ pgc->numInDashList = mi_line_dashed_length;
+ if (pddc->Static.misc.flags & NOLINEDASHFLAG) {
+ pgc->dash = (unsigned char *)xalloc(MAX_LINE_DASH_LENGTH_SIZE);
+ pddc->Static.misc.flags &= ~NOLINEDASHFLAG;
+ }
+ memcpy( (char *)(pgc->dash), (char *)mi_line_dashed,
+ sizeof(mi_line_dashed));
+
+ } else if (pgc->dash != mi_line_dashed) {
+ gcmask |= GCDashList;
+ pgc->numInDashList = mi_line_dashed_length;
+ if (pddc->Static.misc.flags & NOLINEDASHFLAG) {
+ pgc->dash = (unsigned char *)xalloc(MAX_LINE_DASH_LENGTH_SIZE);
+ pddc->Static.misc.flags &= ~NOLINEDASHFLAG;
+ }
+ memcpy( (char *)(pgc->dash), (char *)mi_line_dashed,
+ sizeof(mi_line_dashed));
+ }
+ break;
+
+ case PEXLineTypeDotted:
+ if (pgc->lineStyle != LineOnOffDash) {
+ gcmask |= (GCLineStyle | GCDashList);
+ pgc->lineStyle = LineOnOffDash;
+ pgc->numInDashList = mi_line_dotted_length;
+ if (pddc->Static.misc.flags & NOLINEDASHFLAG) {
+ pgc->dash = (unsigned char *)xalloc(MAX_LINE_DASH_LENGTH_SIZE);
+ pddc->Static.misc.flags &= ~NOLINEDASHFLAG;
+ }
+ memcpy( (char *)(pgc->dash), (char *)mi_line_dotted,
+ sizeof(mi_line_dotted));
+
+ } else if (pgc->dash != mi_line_dotted) {
+ gcmask |= GCDashList;
+ pgc->numInDashList = mi_line_dotted_length;
+ if (pddc->Static.misc.flags & NOLINEDASHFLAG) {
+ pgc->dash = (unsigned char *)xalloc(MAX_LINE_DASH_LENGTH_SIZE);
+ pddc->Static.misc.flags &= ~NOLINEDASHFLAG;
+ }
+ memcpy( (char *)(pgc->dash), (char *)mi_line_dotted,
+ sizeof(mi_line_dotted));
+ }
+ break;
+
+ case PEXLineTypeDashDot:
+ if (pgc->lineStyle != LineOnOffDash) {
+ gcmask |= (GCLineStyle | GCDashList);
+ pgc->lineStyle = LineOnOffDash;
+ pgc->numInDashList = mi_line_dashdot_length;
+ if (pddc->Static.misc.flags & NOLINEDASHFLAG) {
+ pgc->dash = (unsigned char *)xalloc(MAX_LINE_DASH_LENGTH_SIZE);
+ pddc->Static.misc.flags &= ~NOLINEDASHFLAG;
+ }
+ memcpy( (char *)(pgc->dash), (char *)mi_line_dashdot,
+ sizeof(mi_line_dashdot));
+
+ } else if (pgc->dash != mi_line_dashdot) {
+ gcmask |= GCDashList;
+ pgc->numInDashList = mi_line_dashdot_length;
+ if (pddc->Static.misc.flags & NOLINEDASHFLAG) {
+ pgc->dash = (unsigned char *)xalloc(MAX_LINE_DASH_LENGTH_SIZE);
+ pddc->Static.misc.flags &= ~NOLINEDASHFLAG;
+ }
+ memcpy( (char *)(pgc->dash), (char *)mi_line_dashdot,
+ sizeof(mi_line_dashdot));
+ }
+ break;
+ }
+
+ /* Register changes with ddx */
+ if (gcmask) {
+ pgc->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ pgc->stateChanges |= gcmask;
+ (*pgc->funcs->ChangeGC)(pgc, gcmask);
+ }
+
+ /* Clear polyline GC change flag */
+ pddc->Static.misc.flags &= ~EDGEGCFLAG;
+
+ return (Success);
+}
+
+/*++
+ |
+ | Function Name: miDDC_to_GC_fill_area
+ |
+ | Function Description:
+ | Initializes the attributes in a GC in order to correctly
+ | render a fill area. Currently, therefore,
+ | the following attributes are set:
+ |
+ | interior colour
+ |
+ | Note(s):
+ | Note that this routine assumes that the proper defaults
+ | are set for the GC attributes not used by PEX (attributes
+ | such as stipple mask, etc...)
+ |
+ --*/
+
+ddpex3rtn
+miDDC_to_GC_fill_area(pRend, pddc, pgc)
+/* in */
+ddRendererPtr pRend; /* renderer handle */
+miDDContext *pddc; /* dd Context handle */
+GCPtr pgc; /* X GC handle */
+{
+ ddLONG gcmask = 0;
+
+
+}
+
+/*++
+ |
+ | Function Name: miDDC_to_GC_marker
+ |
+ | Function Description:
+ | Initializes the attributes in a GC in order to correctly
+ | render a marker. Currently, therefore,
+ | the following attributes are set:
+ |
+ | colour
+ |
+ | Note(s):
+ | Note that this routine assumes that the proper defaults
+ | are set for the GC attributes not used by PEX (attributes
+ | such as stipple mask, etc...)
+ |
+ --*/
+
+ddpex3rtn
+miDDC_to_GC_marker(pRend, pddc, pgc)
+/* in */
+ddRendererPtr pRend; /* renderer handle */
+miDDContext *pddc; /* dd Context handle */
+GCPtr pgc; /* X GC handle */
+{
+ ddLONG gcmask = 0;
+ ddUSHORT status;
+ ddColourSpecifier markercolour;
+ miColourEntry *pmarkercolour;
+ ddULONG colourindex;
+
+
+ /*
+ * Set the marker colour.
+ * The colour must be processed according
+ * to the contents of the current colour approximation table
+ * entry to compute the proper direct colour.
+ */
+
+ /*
+ * Calculate final color index.
+ */
+ if (pddc->Static.attrs->echoMode == PEXEcho)
+ markercolour = pddc->Static.attrs->echoColour;
+ else
+ markercolour = pddc->Static.attrs->markerColour;
+
+ miColourtoIndex(pRend, pddc->Dynamic->pPCAttr->colourApproxIndex,
+ &markercolour, &colourindex);
+
+
+ /* Only set GC value if necessary */
+ if (colourindex != pgc->fgPixel) {
+ gcmask |= GCForeground;
+ pgc->fgPixel = colourindex;
+ }
+
+ /* Register changes with ddx */
+ if (gcmask) {
+ pgc->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ pgc->stateChanges |= gcmask;
+ (*pgc->funcs->ChangeGC)(pgc, gcmask);
+ }
+
+ /* Clear polyline GC change flag */
+ pddc->Static.misc.flags &= ~MARKERGCFLAG;
+
+ return (Success);
+}
+
+/*++
+ |
+ | Function Name: miDDC_to_GC_text
+ |
+ | Function Description:
+ | Initializes the attributes in a GC in order to correctly
+ | render a text. Currently, therefore,
+ | the following attributes are set:
+ |
+ | colour
+ |
+ | Note(s):
+ | Note that this routine assumes that the proper defaults
+ | are set for the GC attributes not used by PEX (attributes
+ | such as stipple mask, etc...)
+ |
+ --*/
+
+ddpex3rtn
+miDDC_to_GC_text(pRend, pddc, pgc)
+/* in */
+ddRendererPtr pRend; /* renderer handle */
+miDDContext *pddc; /* dd Context handle */
+GCPtr pgc; /* X GC handle */
+{
+ ddLONG gcmask = 0;
+ ddUSHORT status;
+ ddColourSpecifier textcolour;
+ miColourEntry *ptextcolour;
+ ddULONG colourindex;
+
+ /*
+ * Set text colour.
+ * The colour must be processed according
+ * to the contents of the current colour approximation table
+ * entry to compute the proper direct colour.
+ */
+
+ /*
+ * Calculate final color index.
+ */
+ if (pddc->Static.attrs->echoMode == PEXEcho)
+ textcolour = pddc->Static.attrs->echoColour;
+ else
+ textcolour = pddc->Static.attrs->textColour;
+
+ miColourtoIndex(pRend, pddc->Dynamic->pPCAttr->colourApproxIndex,
+ &textcolour, &colourindex);
+
+
+ /* Only set GC value if necessary */
+ if (colourindex != pgc->fgPixel) {
+ gcmask |= GCForeground;
+ pgc->fgPixel = colourindex;
+ }
+
+ /* Register changes with ddx */
+ if (gcmask) {
+ pgc->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ pgc->stateChanges |= gcmask;
+ (*pgc->funcs->ChangeGC)(pgc, gcmask);
+ }
+
+ /* Clear polyline GC change flag */
+ pddc->Static.misc.flags &= ~TEXTGCFLAG;
+
+ return (Success);
+}
+
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level1/miLevel1.c b/xc/programs/Xserver/PEX5/ddpex/mi/level1/miLevel1.c
new file mode 100644
index 000000000..3abdd5b42
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level1/miLevel1.c
@@ -0,0 +1,127 @@
+/* $TOG: miLevel1.c /main/3 1998/02/10 12:39:44 kaleb $ */
+/*
+
+Copyright 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS 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 "ddpex.h"
+
+ddpex1rtn
+PexTriangle(pRend, pPt1, pPt2, pPt3, pColour1, pColour2, pColour3)
+/* in */
+ ddRendererPtr pRend;
+ ddDeviceCoord *pPt1;
+ ddDeviceCoord *pPt2;
+ ddDeviceCoord *pPt3;
+ ddColourSpecifier *pColour1;
+ ddColourSpecifier *pColour2;
+ ddColourSpecifier *pColour3;
+/* out */
+{
+ return(Success);
+}
+
+ddpex1rtn
+PexTrapezoid(pRend, pPt1, pPt2, pPt3, pPt4, pColour1, pColour2, pColour3, pColour4)
+/* in */
+ ddRendererPtr pRend;
+ ddDeviceCoord *pPt1;
+ ddDeviceCoord *pPt2;
+ ddDeviceCoord *pPt3;
+ ddDeviceCoord *pPt4;
+ ddColourSpecifier *pColour1;
+ ddColourSpecifier *pColour2;
+ ddColourSpecifier *pColour3;
+ ddColourSpecifier *pColour4;
+/* out */
+{
+ return(Success);
+}
+
+ddpex1rtn
+PexInterpSpan1(pRend, pPt1, pPt2, startColour, numSteps)
+/* in */
+ ddRendererPtr pRend;
+ ddDeviceCoord *pPt1;
+ ddDeviceCoord *pPt2;
+ ddTableIndex startColour;
+ ddUSHORT numSteps;
+/* out */
+{
+ return(Success);
+}
+
+ddpex1rtn
+PexInterpSpan2(pRend, pPt1, pPt2, startColour, endColour)
+/* in */
+ ddRendererPtr pRend;
+ ddDeviceCoord *pPt1;
+ ddDeviceCoord *pPt2;
+ ddTableIndex startColour;
+ ddTableIndex endColour;
+/* out */
+{
+ return(Success);
+}
+
+typedef struct {
+ ddULONG width;
+ ddULONG height;
+ ddULONG depth;
+ ddULONG numBytes;
+ ddPointer pBytes;
+} ddGlyphStr;
+
+ddpex1rtn
+PexGlyph(pRend, pUpperLeft, pForeground, pBackground, pGlyph)
+/* in */
+ ddRendererPtr pRend;
+ ddDeviceCoord *pUpperLeft;
+ ddColourSpecifier *pForeground;
+ ddColourSpecifier *pBackground;
+ ddGlyphStr *pGlyph;
+/* out */
+{
+ return(Success);
+}
+
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level1/miListUtil.c b/xc/programs/Xserver/PEX5/ddpex/mi/level1/miListUtil.c
new file mode 100644
index 000000000..952e5a7d2
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level1/miListUtil.c
@@ -0,0 +1,343 @@
+/* $TOG: miListUtil.c /main/4 1998/02/10 12:39:50 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level1/miListUtil.c,v 3.5 1998/10/04 09:34:10 dawes Exp $ */
+
+#include "miRender.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "PEXErr.h"
+#include "gcstruct.h"
+#include "pexos.h"
+
+
+/*++
+ |
+ | Function Name: miCopyPath
+ |
+ | Function Description:
+ | Copies the data in a path to a second path.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+miCopyPath(pddc, vinput, voutput, flags)
+ miDDContext *pddc; /* dd context handle */
+ miListHeader *vinput;
+ miListHeader **voutput;
+ int flags;
+{
+ miListHeader *output;
+ int j;
+ listofddPoint *pddilist;
+ listofddPoint *pddolist;
+ int point_size;
+
+ /* Use the pre-defined 4D list for output */
+ *voutput = output = MI_NEXTTEMPDATALIST(pddc);
+
+ /* Insure sufficient room for each header */
+ MI_ALLOCLISTHEADER(output, vinput->numLists)
+ if (!output->ddList) return(BadAlloc);
+
+ output->type = vinput->type;
+ output->numLists = vinput->numLists;
+ output->flags = vinput->flags;
+
+ pddilist = vinput->ddList;
+ pddolist = output->ddList;
+
+ DD_VertPointSize(vinput->type, point_size);
+
+ /* Now, transform each list */
+ for(j=0; j < vinput->numLists; j++) {
+
+ if ((pddolist->numPoints = pddilist->numPoints) <= 0) continue;
+
+ /*
+ * Insure sufficient room for each vertex
+ * Add one to leave room for possible polygon close.
+ */
+ MI_ALLOCLISTOFDDPOINT(pddolist,(pddilist->numPoints+1),point_size);
+ if (!pddolist->pts.p4Dpt) return(BadAlloc);
+
+ memcpy( (char *)pddolist->pts.p4Dpt,
+ (char *)pddilist->pts.p4Dpt,
+ ((int)(pddilist->numPoints))*point_size);
+
+ pddilist++;
+ pddolist++;
+ }
+
+ return(Success);
+}
+
+#define VERTEX_FLAG (1 << 0)
+#define COLOR_FLAG (1 << 1)
+#define NORMAL_FLAG (1 << 2)
+#define EDGE_FLAG (1 << 3)
+/*++
+ |
+ | Function Name: miFilterPath
+ |
+ | Function Description:
+ | Copies the supplied input path to the output path,
+ | but only copying the indicated fields.
+ |
+ | Note(s):
+ |
+ | fields: (1 << 0) - point data
+ | (1 << 1) - color data
+ | (1 << 2) - normal data
+ | (1 << 3) - edge data
+ |
+ | any combination of the above flags are valid.
+ | if the indicated field doesn not exist, it is ignored.
+ |
+ --*/
+
+ddpex3rtn
+miFilterPath(pddc, vinput, voutput, fields)
+ miDDContext *pddc; /* dd context handle */
+ miListHeader *vinput;
+ miListHeader **voutput;
+ int fields;
+{
+ char *in_pt, *out_pt;
+ listofddPoint *pddilist;
+ listofddPoint *pddolist;
+ miListHeader *output;
+ int in_point_size, out_point_size;
+ int color_offset, normal_offset, edge_offset;
+ int vertex_size, color_size;
+ int i, j;
+
+ /* Use the pre-defined 4D list for output */
+ *voutput = output = MI_NEXTTEMPDATALIST(pddc);
+
+ /* Insure sufficient room for each header */
+ MI_ALLOCLISTHEADER(output, vinput->numLists)
+ if (!output->ddList) return(BadAlloc);
+
+ output->type = vinput->type;
+ output->numLists = vinput->numLists;
+ output->flags = vinput->flags;
+
+ pddilist = vinput->ddList;
+ pddolist = output->ddList;
+
+ if (fields & VERTEX_FLAG) {
+ if (DD_IsVertFloat(vinput->type)) {
+ if (DD_IsVert2D(vinput->type)) vertex_size = sizeof(ddCoord2D);
+ else if (DD_IsVert3D(vinput->type)) vertex_size = sizeof(ddCoord3D);
+ else vertex_size = sizeof(ddCoord4D);
+ } else {
+ if (DD_IsVert2D(vinput->type)) vertex_size = sizeof(ddCoord2DS);
+ else vertex_size = sizeof(ddCoord3DS);
+ }
+ } else DD_UnSetVertCoord(output->type);
+
+ if (fields & COLOR_FLAG) {
+ DD_VertOffsetColor(vinput->type, color_offset);
+ if (color_offset < 0) fields &= ~COLOR_FLAG;
+ else {
+ if (DD_IsVertIndexed(vinput->type))
+ color_size = sizeof(ddIndexedColour);
+ else if (DD_IsVertRGB8(vinput->type))
+ color_size = sizeof(ddRgb8Colour);
+ else if (DD_IsVertRGB16(vinput->type))
+ color_size = sizeof(ddRgb16Colour);
+ else color_size = sizeof(ddRgbFloatColour);
+ }
+ } else DD_UnSetColour(output->type);
+
+ if (fields & NORMAL_FLAG) {
+ DD_VertOffsetNormal(vinput->type, normal_offset);
+ if (normal_offset < 0) fields &= ~NORMAL_FLAG;
+ } else DD_UnSetVertNormal(output->type);
+
+ if (fields & EDGE_FLAG) {
+ DD_VertOffsetEdge(vinput->type, edge_offset);
+ if (edge_offset < 0) fields &= ~EDGE_FLAG;
+ } else DD_UnSetVertEdge(output->type);
+
+ DD_VertPointSize(vinput->type, in_point_size);
+ DD_VertPointSize(output->type, out_point_size);
+
+ /* Now, transform each list */
+ for(j=0; j < vinput->numLists; j++) {
+
+ if ((pddolist->numPoints = pddilist->numPoints) <= 0) continue;
+
+ /*
+ * Insure sufficient room for each vertex
+ * Add one to leave room for possible polygon close.
+ */
+ MI_ALLOCLISTOFDDPOINT(pddolist,(pddilist->numPoints+1),out_point_size);
+ if (!pddolist->pts.p4Dpt) return(BadAlloc);
+ out_pt = (char *)pddolist->pts.p4Dpt;
+ in_pt = (char *)pddilist->pts.p4Dpt;
+
+ for (i = 0; i < pddilist->numPoints; i++) {
+ if (fields & VERTEX_FLAG) memcpy( out_pt, in_pt, vertex_size);
+ if (fields & COLOR_FLAG) memcpy( (out_pt+ color_offset),
+ (in_pt + color_offset),
+ color_size);
+ if (fields & NORMAL_FLAG) memcpy( (out_pt+ color_offset),
+ (in_pt + normal_offset),
+ sizeof(ddVector3D));
+ if (fields & EDGE_FLAG) memcpy( (out_pt+ color_offset),
+ (in_pt + edge_offset),
+ sizeof(ddULONG));
+ in_pt += in_point_size;
+ out_pt += out_point_size;
+ }
+
+ pddilist++;
+ pddolist++;
+ }
+
+ return(Success);
+}
+
+/*++
+ |
+ | Function Name: miComputeListBounds
+ |
+ | Function Description:
+ | Computes the extents of the supplied list.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+miComputeListBounds(pddc, vinput, bounds)
+/* in */
+ miDDContext *pddc;
+ miListHeader *vinput;
+ ddListBounds *bounds;
+{
+/* uses */
+ char *in_pt;
+ listofddPoint *pddilist;
+ int vert_count;
+ int point_size;
+ int j;
+ char first = 1;
+
+ if (DD_IsVert2D(vinput->type)) {
+ bounds->zmin = bounds->zmax = 0.0;
+ bounds->wmin = bounds->wmax = 1.0;
+ } else if (DD_IsVert3D(vinput->type)) {
+ bounds->wmin = bounds->wmax = 1.0;
+ }
+
+ pddilist = vinput->ddList;
+ DD_VertPointSize(vinput->type, point_size);
+
+ /* Now, clip each list */
+
+ for (j = 0; j < vinput->numLists; j++) {
+
+ /* Skip list if no points */
+ if ((vert_count = pddilist->numPoints) <= 0) {
+ pddilist++;
+ continue;
+ }
+
+ in_pt = pddilist->pts.ptr;
+
+ if (first) {
+ bounds->xmin = bounds->xmax = ((ddCoord4D *)in_pt)->x;
+ bounds->ymin = bounds->ymax = ((ddCoord4D *)in_pt)->y;
+ if (DD_IsVert3D(vinput->type))
+ bounds->zmin = bounds->zmax = ((ddCoord4D *)in_pt)->z;
+ else if (DD_IsVert4D(vinput->type))
+ bounds->wmin = bounds->wmax = ((ddCoord4D *)in_pt)->w;
+ first = 0;
+ }
+
+ /* For each vertex, clip a polyline segment */
+ while (vert_count--) {
+
+ if (((ddCoord4D *)in_pt)->x < bounds->xmin)
+ bounds->xmin = ((ddCoord4D *)in_pt)->x;
+ if (((ddCoord4D *)in_pt)->x > bounds->xmax)
+ bounds->xmax = ((ddCoord4D *)in_pt)->x;
+ if (((ddCoord4D *)in_pt)->y < bounds->ymin)
+ bounds->ymin = ((ddCoord4D *)in_pt)->y;
+ if (((ddCoord4D *)in_pt)->y > bounds->ymax)
+ bounds->ymax = ((ddCoord4D *)in_pt)->y;
+
+ if (DD_IsVert3D(vinput->type)) {
+ if (((ddCoord4D *)in_pt)->z < bounds->zmin)
+ bounds->zmin = ((ddCoord4D *)in_pt)->z;
+ if (((ddCoord4D *)in_pt)->z > bounds->zmax)
+ bounds->zmax = ((ddCoord4D *)in_pt)->z;
+
+ } else if (DD_IsVert4D(vinput->type)) {
+ if (((ddCoord4D *)in_pt)->z < bounds->zmin)
+ bounds->zmin = ((ddCoord4D *)in_pt)->z;
+ if (((ddCoord4D *)in_pt)->z > bounds->zmax)
+ bounds->zmax = ((ddCoord4D *)in_pt)->z;
+ if (((ddCoord4D *)in_pt)->w < bounds->wmin)
+ bounds->wmin = ((ddCoord4D *)in_pt)->w;
+ if (((ddCoord4D *)in_pt)->w > bounds->wmax)
+ bounds->wmax = ((ddCoord4D *)in_pt)->w;
+ }
+
+ in_pt += point_size;
+ }
+
+ /* skip to next list */
+ pddilist++;
+
+ }
+
+ return (Success);
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level1/miLvl1Tab.c b/xc/programs/Xserver/PEX5/ddpex/mi/level1/miLvl1Tab.c
new file mode 100644
index 000000000..8743f3195
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level1/miLvl1Tab.c
@@ -0,0 +1,80 @@
+/* $TOG: miLvl1Tab.c /main/3 1998/02/10 12:39:55 kaleb $ */
+
+/***********************************************************
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Sun Microsystems,
+and The Open Group, not be used in advertising or publicity
+pertaining to distribution of the software without specific, written
+prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS 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.
+
+******************************************************************/
+
+/* Level I Rendering routine tables */
+
+#include "mipex.h"
+#include "miRender.h"
+
+/* Rendering procedures for ExecuteOCTable */
+extern ddpex2rtn miRenderPolyLine(),
+ miRenderFillArea(),
+ miRenderText(),
+ miRenderMarker(),
+ miRenderTriStrip();
+
+RendTableType RenderPrimitiveTable[] = {
+ miRenderPolyLine, /* 0 Polylines */
+ miRenderFillArea, /* 1 Fill Areas */
+ miRenderText, /* 2 Text */
+ miRenderMarker, /* 3 Markers */
+ miRenderTriStrip, /* 4 Triangle Strips */
+};
+
+/* Picking procedures for ExecuteOCTable */
+extern ddpex2rtn miPick1PolyLine(),
+ miPick1FillArea(),
+ miPick1Text(),
+ miPick1Marker(),
+ miPick1TriStrip();
+
+RendTableType PickPrimitiveTable[] = {
+ miPick1PolyLine, /* 0 Polylines */
+ miPick1FillArea, /* 1 Fill Areas */
+ miPick1Text, /* 2 Text */
+ miPick1Marker, /* 3 Markers */
+ miPick1TriStrip, /* 4 Triangle Strips */
+};
+
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level1/miPck1Prim.c b/xc/programs/Xserver/PEX5/ddpex/mi/level1/miPck1Prim.c
new file mode 100644
index 000000000..311ad9297
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level1/miPck1Prim.c
@@ -0,0 +1,403 @@
+/* $TOG: miPck1Prim.c /main/4 1998/02/10 12:40:00 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution of
+the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS 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 "miRender.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "PEXErr.h"
+#include "miStruct.h"
+#include "miFont.h"
+#include "miWks.h"
+#include "miText.h"
+#include "miClip.h"
+
+
+/*++
+ |
+ | Function Name: miPick1PolyLine
+ |
+ | Function Description:
+ | Handles the level 1picking of Polyline 3D, Polyline 2D,
+ | Polyline 3D with data OCs.
+ |
+ | Note(s):
+ |
+ ++*/
+
+ddpex2rtn
+miPick1PolyLine(pRend, pddc, input_list)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miDDContext *pddc;
+ miListHeader *input_list;
+{
+/* calls */
+
+ /* Check if anything is remaining. If so, the pick volume */
+ /* intersects the polyline(s). If not, everything has been */
+ /* clipped out. Accordingly, update the global Pick_Flag. */
+
+ if (input_list->numLists > 0) {
+ pddc->Static.pick.status = PEXOk;
+ }
+ return (Success);
+}
+
+
+/*++
+ |
+ | Function Name: miPick1Text
+ |
+ | Function Description:
+ | Handles the level 1 picking of Text OCs.
+ |
+ | Note(s):
+ |
+ ++*/
+
+ddpex2rtn
+miPick1Text(pRend, pddc, input_list)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miDDContext *pddc;
+ miListHeader *input_list;
+/* out */
+{
+/* calls */
+
+ /* Check if anything is remaining. If so, the pick volume */
+ /* intersects the polyline(s). If not, everything has been */
+ /* clipped out. Accordingly, update the global Pick_Flag. */
+
+ if (input_list->numLists > 0) {
+ pddc->Static.pick.status = PEXOk;
+ }
+ return (Success);
+}
+
+
+/*++
+ |
+ | Function Name: miPick1Marker
+ |
+ | Function Description:
+ | Handles the level 1 picking of Marker OCs.
+ |
+ | Note(s):
+ |
+ ++*/
+
+ddpex2rtn
+miPick1Marker(pRend, pddc, input_list)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miDDContext *pddc;
+ miListHeader *input_list;
+/* out */
+{
+/* calls */
+
+ /* Check if anything is remaining. If so, the pick volume */
+ /* intersects the polymarker(s). If not, everything has been*/
+ /* clipped out. Accordingly, update the global Pick_Flag. */
+
+ if (input_list->numLists > 0) {
+ pddc->Static.pick.status = PEXOk;
+ }
+ return (Success);
+}
+
+
+/*
+ * Function Name: CheckFillAreaPick
+ *
+ * Purpose: Check if the input set of points represents a polygon that
+ * is INSIDE or OUTSIDE of the pick aperture.
+ *
+ * Return: Success if the points represent a polygon that is inside.
+ * Otherwise, return a negative number indicating NO_PICK.
+ *
+ */
+static
+ddpex2rtn
+CheckFAreaPick1 (in_list)
+/* in */
+ miListHeader *in_list;
+/* out */
+{
+/* calls */
+
+/* Local variables */
+
+ listofddPoint *poly_list;
+ ddPointUnion pt_list;
+ int pt_size;
+ ddCoord2D v1, v2;
+ ddSHORT x_same, y_same;
+ int i, j;
+ int vcount, hcount;
+
+ /*----------------------Picking Algorithm-------------------------*/
+ /* */
+ /* The first step is to look for trivial acceptance. I.E., the re-*/
+ /* maining polygon is partially enclosed by the pick aperture and */
+ /* at least one point lies completely within the aperture. */
+ /* If not, we have a possible degenerate case wherein, the edges */
+ /* of the remaining polygon is coinciding with the faces of the */
+ /* pick aperture. This also means that all the edges are either */
+ /* horizontal or vertical. There can be no 3D diagonal edges. */
+ /* */
+ /* The algorithm implemented here uses the odd-even rule. The idea*/
+ /* is to treat the input points, a pair at a time as an edge of */
+ /* the polygon remaining. The edge is tested to see if it is hor- */
+ /* -izontal, or vertical or diagonal. Note that we use the 3D def-*/
+ /* inition of horizontal, vertical, and diagonal here. A horizon- */
+ /* edge is an edge parallel to X or Z axis, a vertical edge is one*/
+ /* being parallel to only Y axis, and a diagonal edge is one which*/
+ /* is NOT parallel to any of the three axes of the 3D aperture. */
+ /* */
+ /* Thus, clearly, any diagonal edge present means that the polygon*/
+ /* is intersecting the pick aperture and hence a PICK condition is*/
+ /* detected. However, if there are no diagonal edges, then we have*/
+ /* a degenerate situation with the vertical or horizontal edges at*/
+ /* or on the boundaries of the pick aperture. */
+ /* Using the odd-even rule it is clear that if there are an odd */
+ /* number of vertical edges either to the left or in front of the */
+ /* center of the pick aperture, or to the right or in back of the */
+ /* center of the pick aperture, then the pick is sorrounded by the*/
+ /* polygon and hence is picked. On the other hand, if the number */
+ /* of vertical edges is even, then we have the pick aperture OUT-*/
+ /* SIDE of the polygon, and thus is not picked. The horizontal */
+ /* edges testing come into picture when there are no vertical ones*/
+ /* present. The test once again is to check whether the count of */
+ /* horizontal edges either to the left or front, or right or back */
+ /* of the center of the aperture, is even or odd. If odd, detect */
+ /* a PICK, else, detect a NO_PICK. */
+ /* */
+ /*----------------------------------------------------------------*/
+
+ /* Test for trivial pick case. i.e., at least one point is fully */
+ /* contained within the converted pick aperture in CC. */
+
+ poly_list = in_list->ddList; /* Initialize poly list pointer */
+
+ DD_VertPointSize (in_list->type, pt_size); /* Get point size */
+
+ for (i=0; i<in_list->numLists; i++, poly_list++) {
+
+ /* Get the pointer to the next points list */
+
+ pt_list.ptr = poly_list->pts.ptr;
+
+ for (j=0; j<in_list->ddList->numPoints; j++) {
+
+ /* Update pt_list to point to next point */
+
+ pt_list.ptr += pt_size;
+
+ /* Test for containment within the pick aperture */
+
+ if ((pt_list.p2DSpt->x > -1) &&
+ (pt_list.p2DSpt->x < 1) &&
+ (pt_list.p2DSpt->y > -1) &&
+ (pt_list.p2DSpt->y < 1))
+
+ /* This point is fully within the pick aperture. */
+ /* No need to test further. Just detect PICK. */
+
+ return (Success);
+ }
+ }
+
+ /* We have a degenerate polygon. Test further to determine if the */
+ /* pick aperture is fully or partially enclosed by the polygon. */
+
+ /* Initialize the vertical and horizontal edge counters */
+
+ vcount = hcount = 0;
+
+ /* Set up a loop for testing edges and counting vertical edges */
+ /* and horizontal edges. */
+
+ poly_list = in_list->ddList; /* Initialize poly list pointer */
+
+ for (i=0; i<in_list->numLists; i++, poly_list++) { /* Do for all Polys */
+
+ /* Get the pointer to the next points list */
+
+ pt_list.ptr = poly_list->pts.ptr;
+
+ for (j=0; j<in_list->ddList->numPoints-1; j++) { /* Do for all edges */
+
+ /* Get the first vertex of current edge */
+
+ v1.x = pt_list.p2DSpt->x;
+ v1.y = pt_list.p2DSpt->y;
+
+ /* Update pt_list to point to next point */
+
+ pt_list.ptr += pt_size;
+
+ /* Get the next vertex of current edge */
+
+ v2.x = pt_list.p2DSpt->x;
+ v2.y = pt_list.p2DSpt->y;
+
+ /* Test the edge type and update the vcount and the hcount */
+
+ if (MI_NEAR_ZERO(v1.x-v2.x))
+ x_same = 1;
+ else
+ x_same = 0;
+
+ if (MI_NEAR_ZERO(v1.y-v2.y))
+ y_same = 1;
+ else
+ y_same = 0;
+
+ if ((x_same)&&(v1.x > 0))
+ /* Edge is parallel to Y axis AND is to the right */
+ /* of the center of pick aperture; Increment vcount*/
+
+ vcount++;
+
+ if ((y_same)&&(v1.y > 0))
+ /* Edge is parallel to X axis AND is to the top of */
+ /* the center of pick aperture; Increment the hcount*/
+
+ hcount++;
+
+ } /* Loop for all edges of current polygon */
+
+ /* Test if vcount = odd; if so, detect PICK */
+
+ if (vcount%2) {
+ return (Success);
+ }
+ else {
+
+ /* Else, if vcount == 0, test if hcount = odd; */
+ /* if so, detect PICK. */
+
+ if ((vcount == 0)&&(hcount%2)) return (Success);
+ }
+
+ continue; /* Try the next polygon for containment test */
+
+ } /* Loop for all polygons */
+
+ return (-1); /* Return negative to indicate NO_PICK */
+}
+
+
+/*++
+ |
+ | Function Name: miPick1FillArea
+ |
+ | Function Description:
+ | Handles the level 1 picking of FillArea OCs.
+ |
+ | Note(s):
+ |
+ ++*/
+
+ddpex2rtn
+miPick1FillArea(pRend, pddc, input_list, input_facet, shape, noedges)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miDDContext *pddc;
+ miListHeader *input_list;
+ listofddFacet *input_facet;
+ ddBitmaskShort shape;
+ ddUCHAR noedges;
+/* out */
+{
+/* calls */
+
+ /* Check for successful polygon pick */
+
+ if (CheckFAreaPick1 (input_list) == Success) {
+ pddc->Static.pick.status = PEXOk;
+ }
+ return (Success);
+}
+
+
+/*++
+ |
+ | Function Name: miPick1TriStrip
+ |
+ | Function Description:
+ | Handles the level 1 picking of Triangle Strip OCs.
+ |
+ | Note(s):
+ |
+ ++*/
+
+ddpex2rtn
+miPick1TriStrip(pRend, pddc, input_list, input_facet)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miDDContext *pddc;
+ miListHeader *input_list;
+ listofddFacet *input_facet;
+/* out */
+{
+/* calls */
+
+ /* Check for successful triangle strip pick. */
+ /* Note that clipper for triangle strips will*/
+ /* NOT generate dengenerate cases and hence */
+ /* any remaining vertices will constitute a */
+ /* Pick situation. */
+
+ if ((input_list->numLists) > 0) {
+ pddc->Static.pick.status = PEXOk;
+ }
+ return (Success);
+}
+
+
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level1/miRndFArea.c b/xc/programs/Xserver/PEX5/ddpex/mi/level1/miRndFArea.c
new file mode 100644
index 000000000..bbd9be537
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level1/miRndFArea.c
@@ -0,0 +1,526 @@
+/* $TOG: miRndFArea.c /main/6 1998/02/10 12:40:05 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS 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.
+
+*/
+
+#define NEED_EVENTS
+#include "miRender.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "PEXErr.h"
+#include "extnsionst.h"
+#include "gcstruct.h"
+#include "ddpex2.h"
+
+
+/*++
+ |
+ | Function Name: miRenderFillArea
+ |
+ | Function Description:
+ | Renders fill areas to the screen
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+miRenderFillArea(pRend, pddc, input_list, input_facet, shape, noedges)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miDDContext *pddc; /* dd context handle */
+ miListHeader *input_list; /* fill area data */
+ listofddFacet *input_facet; /* per facet data */
+ ddBitmaskShort shape; /* shape hint */
+ ddUCHAR noedges; /*ignore edges flag*/
+/* out */
+{
+
+/* calls */
+ ddpex3rtn miDDC_to_GC_fill_area();
+ ddpex3rtn miCopyPath();
+ ddpex3rtn miFilterPath();
+ ddpex3rtn miRemoveInvisibleEdges();
+
+
+/* Local variable definitions */
+ ddPointUnion in_pt;
+ ddFacetUnion out_fct;
+ listofddPoint *pddlist;
+ listofddFacet *fct_list;
+ miListHeader *copy_list;
+ miListHeader *temp_list;
+ GCPtr pGC;
+ int point_size, facet_size;
+ int num_points;
+ ddULONG colourindex;
+ ddColourSpecifier intcolour;
+ miColourEntry *pintcolour;
+ int j, k;
+ ddpex3rtn err = Success;
+ ddUSHORT status = 0;
+
+
+ /*
+ * ddx trashes the input data by adding window offsets.
+ * Thus, if the data is going to be re-used for rendering
+ * of edges, it must be saved :-(.
+ */
+ if ((pddc->Static.attrs->edges != PEXOff) &&
+ (!noedges) &&
+ (pddc->Static.attrs->intStyle != PEXInteriorStyleEmpty))
+ miCopyPath(pddc, input_list, &copy_list, 0);
+ else copy_list = input_list;
+
+ /*
+ * Update the fill area GC to reflect the current
+ * fill area attributes
+ */
+ pGC = pddc->Static.misc.pFillAreaGC;
+ if (pddc->Static.misc.flags & FILLAREAGCFLAG)
+ miDDC_to_GC_fill_area(pRend, pddc, pGC);
+
+ /*
+ * Render that path.
+ */
+ switch (pddc->Static.attrs->intStyle) {
+
+ case PEXInteriorStyleHollow:
+ {
+ /*
+ * The final fill area color is determined by a hierarchy
+ * of sources. The first source is the by vertex colors.
+ * If the data has vertex colors, then the final color
+ * is an average of the vertex colors. If there are no
+ * vertex colors, then the fill area is set to the facet
+ * color for the current facet. IF there are no facet colors,
+ * then the color is determined by the surface color attribute.
+ */
+
+ if ( (DD_IsVertColour(input_list->type)) &&
+ (!MI_DDC_IS_HIGHLIGHT(pddc)) ) {
+ /*
+ * If vertex colors, simply create a facet list.
+ */
+ DDFacetSIZE(DD_FACET_RGBFLOAT, facet_size);
+ fct_list = MI_NEXTTEMPFACETLIST(pddc);
+ fct_list->type = DD_FACET_RGBFLOAT;
+ MI_ALLOCLISTOFDDFACET(fct_list, 1, facet_size);
+ if (!fct_list->facets.pNoFacet) return(BadAlloc);
+ out_fct = fct_list->facets;
+ DD_VertPointSize(input_list->type, point_size);
+ point_size -= sizeof(ddCoord2DS);
+
+ out_fct.pFacetRgbFloat->red = 0.0;
+ out_fct.pFacetRgbFloat->green = 0.0;
+ out_fct.pFacetRgbFloat->blue = 0.0;
+ num_points = 0;
+
+ for (j = 0, pddlist = input_list->ddList;
+ j < input_list->numLists; j++, pddlist++) {
+
+ in_pt = pddlist->pts;
+
+ /* Compute average facet color. Note that we exclude */
+ /* the last point from the average, since it is the */
+ /* same as the first point */
+ for (k = 1; k < pddlist->numPoints; k++) {
+ in_pt.p2DSpt++; /* skip coord data */
+ out_fct.pFacetRgbFloat->red
+ += in_pt.pRgbFloatClr->red;
+ out_fct.pFacetRgbFloat->green
+ += in_pt.pRgbFloatClr->green;
+ out_fct.pFacetRgbFloat->blue
+ += in_pt.pRgbFloatClr->blue;
+ in_pt.ptr += point_size; /* skip color and normal */
+ num_points++;
+ }
+ }
+
+ /* complete average */
+ if (num_points > 0) {
+ out_fct.pFacetRgbFloat->red /= num_points;
+ out_fct.pFacetRgbFloat->green /= num_points;
+ out_fct.pFacetRgbFloat->blue /= num_points;
+ }
+ /* clamp on saturation */
+ if (out_fct.pFacetRgbFloat->red > 1.0)
+ out_fct.pFacetRgbFloat->red = 1.0;
+ if (out_fct.pFacetRgbFloat->green > 1.0)
+ out_fct.pFacetRgbFloat->green = 1.0;
+ if (out_fct.pFacetRgbFloat->blue > 1.0)
+ out_fct.pFacetRgbFloat->blue = 1.0;
+
+ /* new facet colors override input ones */
+ fct_list->numFacets = 1;
+ input_facet = fct_list;
+ }
+
+ /* Remove all data from vertex data but vertex coordinates */
+ if ((DD_IsVertNormal(input_list->type)) ||
+ (DD_IsVertEdge(input_list->type)) ||
+ (DD_IsVertColour(input_list->type)) ) {
+ if (err = miFilterPath(pddc, input_list, &temp_list, 1))
+ return(err);
+ input_list = temp_list;
+ }
+
+ if ( (input_facet) &&
+ (input_facet->numFacets > 0) &&
+ (DD_IsFacetColour(input_facet->type)) &&
+ (!MI_DDC_IS_HIGHLIGHT(pddc)) ) {
+
+ /* Compute index value for ddx */
+ if (pddc->Static.attrs->echoMode == PEXEcho)
+ intcolour = pddc->Static.attrs->echoColour;
+ else {
+ intcolour.colourType = PEXRgbFloatColour;
+ intcolour.colour.rgbFloat = *input_facet->facets.pFacetRgbFloat;
+ }
+ miColourtoIndex(pRend, pddc->Dynamic->pPCAttr->colourApproxIndex,
+ &intcolour, &colourindex);
+
+ /* Only set GC value if necessary */
+ if (colourindex != pGC->fgPixel) {
+ pGC->fgPixel = colourindex;
+ /* Register changes with ddx */
+ pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ pGC->stateChanges |= GCForeground;
+ (*pGC->funcs->ChangeGC)(pGC, GCForeground);
+ /* Insure that the GC is reset to proper color next time */
+ pddc->Static.misc.flags |= FILLAREAGCFLAG;
+ }
+
+ /* validate GC prior to start of rendering */
+ if (pGC->serialNumber != pRend->pDrawable->serialNumber)
+ ValidateGC(pRend->pDrawable, pGC);
+
+ /* Render each bound as a polyline */
+ for (j = 0, pddlist = input_list->ddList;
+ j < input_list->numLists; j++, pddlist++) {
+
+ if (pddlist->numPoints > 0) {
+
+ /* Call ddx to render the polygon */
+ (*GetGCValue(pGC, ops->Polylines))
+ (pRend->pDrawable,
+ pGC,
+ CoordModeOrigin,
+ pddlist->numPoints,
+ pddlist->pts.p2DSpt);
+ }
+ }
+ }
+
+ else {
+
+ /*
+ * If no vertex or facet colors, use surface attributes.
+ * Surface attributes are set to highlight colour
+ * if highlighting
+ */
+ if (pddc->Static.attrs->echoMode == PEXEcho)
+ intcolour = pddc->Static.attrs->echoColour;
+ else
+ intcolour = pddc->Static.attrs->surfaceColour;
+
+ miColourtoIndex( pRend,
+ pddc->Dynamic->pPCAttr->colourApproxIndex,
+ &intcolour, &colourindex);
+
+ /* Only set GC value if necessary */
+ if (colourindex != pGC->fgPixel) {
+ pGC->fgPixel = colourindex;
+ /* Register changes with ddx */
+ pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ pGC->stateChanges |= GCForeground;
+ (*pGC->funcs->ChangeGC)(pGC, GCForeground);
+ }
+
+ /* validate GC prior to start of rendering */
+ if (pGC->serialNumber != pRend->pDrawable->serialNumber)
+ ValidateGC(pRend->pDrawable, pGC);
+
+ /* Render each bound as a polyline */
+ for (j = 0, pddlist = input_list->ddList;
+ j < input_list->numLists; j++, pddlist++)
+ if (pddlist->numPoints > 0)
+ /* Call ddx to render the polygon */
+ (*GetGCValue(pGC, ops->Polylines))
+ (pRend->pDrawable,
+ pGC,
+ CoordModeOrigin,
+ pddlist->numPoints,
+ pddlist->pts.p2DSpt);
+ }
+ break;
+ }
+
+ /* Note that patterns and hatching are currently not implemented */
+ case PEXInteriorStylePattern:
+ case PEXInteriorStyleHatch:
+ case PEXInteriorStyleSolid:
+ {
+ /*
+ * The final fill area color is determined by a hierarchy
+ * of sources. The first source is the by vertex colors.
+ * If the data has vertex colors, then the final color
+ * is an average of the vertex colors. If there are no
+ * vertex colors, then the fill area is set to the facet
+ * color for the current facet. IF there are no facet colors,
+ * then the color is determined by the surface color attribute.
+ */
+
+ if ( (DD_IsVertColour(input_list->type)) &&
+ (!MI_DDC_IS_HIGHLIGHT(pddc)) ) {
+ /*
+ * If vertex colors, simply create a facet list.
+ */
+ DDFacetSIZE(DD_FACET_RGBFLOAT, facet_size);
+ fct_list = MI_NEXTTEMPFACETLIST(pddc);
+ fct_list->type = DD_FACET_RGBFLOAT;
+ MI_ALLOCLISTOFDDFACET(fct_list, 1, facet_size);
+ if (!fct_list->facets.pNoFacet) return(BadAlloc);
+ out_fct = fct_list->facets;
+ DD_VertPointSize(input_list->type, point_size);
+ point_size -= sizeof(ddCoord2DS);
+
+ out_fct.pFacetRgbFloat->red = 0.0;
+ out_fct.pFacetRgbFloat->green = 0.0;
+ out_fct.pFacetRgbFloat->blue = 0.0;
+ num_points = 0;
+
+ for (j = 0, pddlist = input_list->ddList;
+ j < input_list->numLists; j++, pddlist++) {
+
+ in_pt = pddlist->pts;
+
+ /* Compute average facet color. Note that we exclude */
+ /* the last point from the average, since it is the */
+ /* same as the first point */
+ for (k = 1; k < pddlist->numPoints; k++) {
+ in_pt.p2DSpt++; /* skip coord data */
+ out_fct.pFacetRgbFloat->red
+ += in_pt.pRgbFloatClr->red;
+ out_fct.pFacetRgbFloat->green
+ += in_pt.pRgbFloatClr->green;
+ out_fct.pFacetRgbFloat->blue
+ += in_pt.pRgbFloatClr->blue;
+ in_pt.ptr += point_size; /* skip color and normal */
+ num_points++;
+ }
+ }
+
+ /* complete average */
+ if (num_points > 0) {
+ out_fct.pFacetRgbFloat->red /= num_points;
+ out_fct.pFacetRgbFloat->green /= num_points;
+ out_fct.pFacetRgbFloat->blue /= num_points;
+ }
+ /* clamp on saturation */
+ if (out_fct.pFacetRgbFloat->red > 1.0)
+ out_fct.pFacetRgbFloat->red = 1.0;
+ if (out_fct.pFacetRgbFloat->green > 1.0)
+ out_fct.pFacetRgbFloat->green = 1.0;
+ if (out_fct.pFacetRgbFloat->blue > 1.0)
+ out_fct.pFacetRgbFloat->blue = 1.0;
+
+ /* new facet colors override input ones */
+ fct_list->numFacets = 1;
+ input_facet = fct_list;
+ }
+
+ /* Remove all data from vertex data but vertex coordinates */
+ if ((DD_IsVertNormal(input_list->type)) ||
+ (DD_IsVertEdge(input_list->type)) ||
+ (DD_IsVertColour(input_list->type)) ) {
+ if (err = miFilterPath(pddc, input_list, &temp_list, 1))
+ return(err);
+ input_list = temp_list;
+ }
+
+ if ( (input_facet) &&
+ (input_facet->numFacets > 0) &&
+ (DD_IsFacetColour(input_facet->type)) &&
+ (!MI_DDC_IS_HIGHLIGHT(pddc)) ) {
+
+ /* Compute index value for ddx */
+ if (pddc->Static.attrs->echoMode == PEXEcho)
+ intcolour = pddc->Static.attrs->echoColour;
+ else {
+ intcolour.colourType = PEXRgbFloatColour;
+ intcolour.colour.rgbFloat = *input_facet->facets.pFacetRgbFloat;
+ }
+ miColourtoIndex(pRend, pddc->Dynamic->pPCAttr->colourApproxIndex,
+ &intcolour, &colourindex);
+
+ /* Only set GC value if necessary */
+ if (colourindex != pGC->fgPixel) {
+ pGC->fgPixel = colourindex;
+ /* Register changes with ddx */
+ pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ pGC->stateChanges |= GCForeground;
+ (*pGC->funcs->ChangeGC)(pGC, GCForeground);
+ /* Insure that the GC is reset to proper color next time */
+ pddc->Static.misc.flags |= FILLAREAGCFLAG;
+ }
+
+ /* validate GC prior to start of rendering */
+ if (pGC->serialNumber != pRend->pDrawable->serialNumber)
+ ValidateGC(pRend->pDrawable, pGC);
+
+ /* Render the polygon. */
+ for (j = 0, pddlist = input_list->ddList;
+ j < input_list->numLists; j++, pddlist++) {
+
+ if (pddlist->numPoints > 0) {
+
+ /* Call ddx to render the polygon */
+ (*GetGCValue(pGC, ops->FillPolygon))
+ (pRend->pDrawable,
+ pGC,
+ shape != PEXUnknownShape ? shape : PEXComplex,
+ CoordModeOrigin,
+ pddlist->numPoints,
+ pddlist->pts.p2DSpt);
+ }
+ }
+ }
+
+ else {
+
+ /*
+ * If no vertex or facet colors, use surface attributes.
+ * Surface attributes are set to highlight colour
+ * if highlighting
+ */
+ if (pddc->Static.attrs->echoMode == PEXEcho)
+ intcolour = pddc->Static.attrs->echoColour;
+ else
+ intcolour = pddc->Static.attrs->surfaceColour;
+
+ miColourtoIndex( pRend,
+ pddc->Dynamic->pPCAttr->colourApproxIndex,
+ &intcolour, &colourindex);
+
+ /* Only set GC value if necessary */
+ if (colourindex != pGC->fgPixel) {
+ pGC->fgPixel = colourindex;
+ /* Register changes with ddx */
+ pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ pGC->stateChanges |= GCForeground;
+ (*pGC->funcs->ChangeGC)(pGC, GCForeground);
+ }
+
+ /* validate GC prior to start of rendering */
+ if (pGC->serialNumber !=
+ pRend->pDrawable->serialNumber)
+ ValidateGC(pRend->pDrawable, pGC);
+
+ /* Render each bound as a polyline */
+ for (j = 0, pddlist = input_list->ddList;
+ j < input_list->numLists; j++, pddlist++)
+ if (pddlist->numPoints > 0)
+ /* Call ddx to render the polygon */
+ (*GetGCValue(pGC, ops->FillPolygon))
+ (pRend->pDrawable,
+ pGC,
+ shape != PEXUnknownShape ? shape : PEXComplex,
+ CoordModeOrigin,
+ pddlist->numPoints,
+ pddlist->pts.p2DSpt);
+ }
+ break;
+ }
+
+ case PEXInteriorStyleEmpty:
+ break;
+ }
+
+ /*
+ * Now check to see if fill area edges are to be drawn
+ */
+ if ((pddc->Static.attrs->edges != PEXOff) && (!noedges)) {
+
+ /* If edge flags, remove invisible edges */
+ if (DD_IsVertEdge(copy_list->type))
+ miRemoveInvisibleEdges(pddc, copy_list, &input_list);
+ else input_list = copy_list;
+
+ /* Remove all data from vertex data but vertex coordinates */
+ if ((DD_IsVertNormal(input_list->type)) ||
+ (DD_IsVertEdge(input_list->type)) ||
+ (DD_IsVertColour(input_list->type)) ) {
+ if (err = miFilterPath(pddc, input_list, &copy_list, 1))
+ return(err);
+ input_list = copy_list;
+ }
+
+ /*
+ * Update the fill area GC to reflect the current
+ * fill area attributes
+ */
+ if (pddc->Static.misc.flags & EDGEGCFLAG)
+ miDDC_to_GC_edges(pRend, pddc, pddc->Static.misc.pEdgeGC);
+
+ /* validate GC prior to start of rendering */
+ if (pddc->Static.misc.pEdgeGC->serialNumber !=
+ pRend->pDrawable->serialNumber)
+ ValidateGC(pRend->pDrawable, pddc->Static.misc.pEdgeGC);
+
+ /* Render each bound as a polyline */
+ for (j = 0, pddlist = input_list->ddList;
+ j < input_list->numLists; j++, pddlist++)
+ if (pddlist->numPoints > 0)
+ /* Call ddx to render the polygon */
+ (*GetGCValue(pddc->Static.misc.pEdgeGC, ops->Polylines))
+ (pRend->pDrawable,
+ pddc->Static.misc.pEdgeGC,
+ CoordModeOrigin,
+ pddlist->numPoints,
+ pddlist->pts.p2DSpt);
+ }
+
+ return(Success);
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level1/miRndMarkr.c b/xc/programs/Xserver/PEX5/ddpex/mi/level1/miRndMarkr.c
new file mode 100644
index 000000000..013bdd38d
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level1/miRndMarkr.c
@@ -0,0 +1,276 @@
+/* $TOG: miRndMarkr.c /main/7 1998/02/10 12:40:10 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level1/miRndMarkr.c,v 3.6 1998/10/04 09:34:12 dawes Exp $ */
+
+#define NEED_EVENTS
+#include "miRender.h"
+#include "Xprotostr.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "PEXErr.h"
+#include "extnsionst.h"
+#include "gcstruct.h"
+#include "ddpex2.h"
+#include "miMarkers.h"
+#include "pexos.h"
+
+#define FULL_CIRCLE 360*64
+
+
+/*++
+ |
+ | Function Name: miRenderMarker
+ |
+ | Function Description:
+ | Renders Polylines to the screen.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+miRenderMarker(pRend, pddc, input_list)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miDDContext *pddc; /* dd context handle */
+ miListHeader *input_list; /* fill area data */
+{
+/* calls */
+ ddpex3rtn miTransform();
+ ddpex3rtn miClipPointList();
+
+/* Local variable definitions */
+ miListHeader *temp_list;
+ miListHeader save_list;
+ int i, j, k;
+ miListHeader *input_marker_list, *xformed_marker;
+ listofddPoint *pddlist1, *pddlist2;
+ float marker_trans[4][4];
+ ddCoord2DS *in_pt;
+ ddpex3rtn status;
+
+
+ /* Remove all data but vertex coordinates */
+ if ((DD_IsVertNormal(input_list->type)) ||
+ (DD_IsVertEdge(input_list->type)) ||
+ (DD_IsVertColour(input_list->type)) ) {
+ status = miFilterPath(pddc, input_list, &temp_list, 0);
+ if (status) return(status);
+ input_list = temp_list;
+ }
+
+ /*
+ * Update the marker GC to reflect the current
+ * marker attributes
+ */
+ if (pddc->Static.misc.flags & MARKERGCFLAG)
+ miDDC_to_GC_marker(pRend, pddc, pddc->Static.misc.pPolyMarkerGC);
+
+ /*
+ * Now render the appropriate marker
+ */
+ switch (pddc->Static.attrs->markerType) {
+
+ case PEXMarkerDot:
+ /* validate GC prior to start of rendering */
+ if (pddc->Static.misc.pPolyMarkerGC->serialNumber !=
+ pRend->pDrawable->serialNumber)
+ ValidateGC(pRend->pDrawable, pddc->Static.misc.pPolyMarkerGC);
+
+ /*
+ * Render a pixel at each marker position
+ */
+ for (j = 0, pddlist1 = input_list->ddList;
+ j < input_list->numLists; j++, pddlist1++)
+ if (pddlist1->numPoints > 0)
+ /* Call ddx to render the polylines */
+ (*GetGCValue(pddc->Static.misc.pPolyMarkerGC, ops->PolyPoint))
+ (pRend->pDrawable,
+ pddc->Static.misc.pPolyMarkerGC,
+ CoordModeOrigin,
+ pddlist1->numPoints,
+ pddlist1->pts.p2DSpt);
+ break;
+
+ case PEXMarkerCross:
+ /* new path contains the default marker description to render */
+ input_marker_list = &cross_header;
+ goto render_marker;
+
+ case PEXMarkerAsterisk:
+ /* new path contains the default marker description to render */
+ input_marker_list = &asterisk_header;
+ goto render_marker;
+
+ case PEXMarkerCircle:
+ {
+ xArc *parcs=0, /* ddx polyarc input structure */
+ *pcurarcs;
+
+ /*
+ * Draw a circle for each position in the PolyMarker list.
+ */
+ for (i = 0, pddlist1 = input_list->ddList;
+ i < input_list->numLists; i++, pddlist1++) {
+ /*
+ * Ensure enough arc structures
+ */
+ if (parcs)
+ pcurarcs = parcs =
+ (xArc *)xrealloc(parcs,sizeof(xArc)*pddlist1->numPoints);
+ else pcurarcs = parcs =
+ (xArc *)xalloc(sizeof(xArc)*pddlist1->numPoints);
+
+ in_pt = pddlist1->pts.p2DSpt;
+
+ /* Create an arc structure for every PolyMarker point */
+ for (j = 0; j < pddlist1->numPoints; j++) {
+ pcurarcs->x = in_pt->x
+ - (ddUSHORT)pddc->Static.attrs->markerScale;
+ pcurarcs->y = (in_pt++)->y
+ - (ddUSHORT)pddc->Static.attrs->markerScale;
+ pcurarcs->width = (ddUSHORT)(pddc->Static.attrs->markerScale*2);
+ pcurarcs->height = pcurarcs->width;
+ pcurarcs->angle1 = 0;
+ (pcurarcs++)->angle2 = FULL_CIRCLE;
+ }
+
+ /* validate GC prior to start of rendering */
+ if (pddc->Static.misc.pPolyMarkerGC->serialNumber !=
+ pRend->pDrawable->serialNumber)
+ ValidateGC(pRend->pDrawable, pddc->Static.misc.pPolyMarkerGC);
+
+ /* Call ddx to render a circle */
+ (*GetGCValue(pddc->Static.misc.pPolyMarkerGC, ops->PolyArc))
+ (pRend->pDrawable,
+ pddc->Static.misc.pPolyMarkerGC,
+ pddlist1->numPoints,
+ parcs);
+ }
+
+ /* free temporary resources */
+ if (parcs) xfree(parcs);
+
+ }
+ break;
+
+ case PEXMarkerX:
+ /* new path contains the default marker description to render */
+ input_marker_list = &X_header;
+
+render_marker:
+ /*
+ * marker_trans contains the transformation to transform
+ * the unit marker default specification to the final
+ * screen size/position. The scale factor used in x and y
+ * is the PC makerScale, while the translation is provided
+ * by the (now DC) marker position specified in the input
+ * vertex list.
+ */
+ memcpy( (char *) marker_trans,
+ (char *) ident4x4, 16 * sizeof(ddFLOAT));
+ marker_trans[0][0] = pddc->Static.attrs->markerScale;
+ marker_trans[1][1] = pddc->Static.attrs->markerScale;
+
+ /*
+ * the transform routine automatically" selects the
+ * output data area. In order to not overwrite the
+ * polymarker data, the list header is copied to
+ * a temporary area. Note that the maxLists field
+ * associated with the old list is zeroed so that
+ * new data will be alloc'ed on the next transform.
+ */
+ save_list = *input_list;
+ input_list->maxLists = 0;
+
+ /*
+ * Draw a marker for each position in the PolyMarker list.
+ */
+ for (i = 0, pddlist1 = save_list.ddList;
+ i < save_list.numLists; i++, pddlist1++) {
+
+ in_pt = pddlist1->pts.p2DSpt;
+
+ /* for every PolyMarker point */
+ for (j = 0; j < pddlist1->numPoints; j++) {
+
+ /* Transform marker description into screen coords */
+ marker_trans[0][3] = (float)in_pt->x;
+ marker_trans[1][3] = (float)(in_pt++)->y;
+ if (status = miTransform(pddc,
+ input_marker_list, &xformed_marker,
+ marker_trans,
+ NULL4x4,
+ DD_2DS_POINT))
+ return (status);
+
+ /* validate GC prior to start of rendering */
+ if (pddc->Static.misc.pPolyMarkerGC->serialNumber !=
+ pRend->pDrawable->serialNumber)
+ ValidateGC(pRend->pDrawable, pddc->Static.misc.pPolyMarkerGC);
+
+ /* We should have DC paths here; Render them */
+ for (k = 0, pddlist2 = xformed_marker->ddList;
+ k < xformed_marker->numLists; k++, pddlist2++)
+ if (pddlist2->numPoints > 0)
+ /* Call ddx to render the polylines */
+ (*GetGCValue(pddc->Static.misc.pPolyMarkerGC,ops->Polylines))
+ (pRend->pDrawable,
+ pddc->Static.misc.pPolyMarkerGC,
+ CoordModeOrigin,
+ pddlist2->numPoints,
+ pddlist2->pts.p2DSpt);
+ }
+ }
+ MI_FREELISTHEADER(&save_list);
+ break;
+
+ default:
+ break;
+ }
+
+ return (Success);
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level1/miRndPLine.c b/xc/programs/Xserver/PEX5/ddpex/mi/level1/miRndPLine.c
new file mode 100644
index 000000000..2bdcce576
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level1/miRndPLine.c
@@ -0,0 +1,183 @@
+/* $TOG: miRndPLine.c /main/3 1998/02/10 12:40:15 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS 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.
+
+*/
+
+#define NEED_EVENTS
+#include "mipex.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "PEXErr.h"
+#include "miRender.h"
+#include "extnsionst.h"
+#include "gcstruct.h"
+#include "ddpex2.h"
+
+
+/*++
+ |
+ | Function Name: miRenderPolyLine
+ |
+ | Function Description:
+ | Renders Polylines to the screen.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+miRenderPolyLine(pRend, pddc, input_list)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miDDContext *pddc; /* dd context handle */
+ miListHeader *input_list; /* fill area data */
+{
+/* calls */
+ ddpex3rtn miFilterPath();
+ ddpex3rtn miClipPolyLines();
+
+/* Local variable definitions */
+ listofddPoint *pddlist;
+ ddPointUnion pt;
+ ddCoord2DS line[2];
+ GCPtr pGC;
+ ddULONG colourindex;
+ ddColourSpecifier intcolour;
+ int j;
+ int count;
+
+ /*
+ * Update the fill area GC to reflect the current
+ * polyline attributes
+ */
+ if (pddc->Static.misc.flags & POLYLINEGCFLAG)
+ miDDC_to_GC_polyline(pRend, pddc, pddc->Static.misc.pPolylineGC);
+
+ /* Polyline with Data ? */
+ if (!DD_IsVertColour(input_list->type))
+ {
+
+ /* validate GC prior to start of rendering */
+ if (pddc->Static.misc.pPolylineGC->serialNumber !=
+ pRend->pDrawable->serialNumber)
+ ValidateGC(pRend->pDrawable, pddc->Static.misc.pPolylineGC);
+
+ /* We should have DC paths here; Render them */
+ for (j = 0, pddlist = input_list->ddList;
+ j < input_list->numLists; j++, pddlist++) {
+ if (pddlist->numPoints > 0) {
+
+ /* Call ddx to render the polylines */
+ (*GetGCValue(pddc->Static.misc.pPolylineGC, ops->Polylines))
+ (pRend->pDrawable,
+ pddc->Static.misc.pPolylineGC,
+ CoordModeOrigin,
+ pddlist->numPoints,
+ pddlist->pts.p2DSpt);
+ }
+ }
+ }
+ else
+ {
+ pGC = pddc->Static.misc.pPolylineGC;
+
+ intcolour.colourType = PEXRgbFloatColour;
+
+ /* Render each bound as a polyline */
+ for (j = 0, pddlist = input_list->ddList;
+ j < input_list->numLists; j++, pddlist++) {
+
+ if ((count = pddlist->numPoints) <= 1) continue;
+
+ pt = pddlist->pts;
+
+ /* Each polyline segment has a (potentially) different color */
+ while (--count) {
+
+ /* Compute index value for ddx */
+ line[0] = *(pt.p2DSpt++);
+ /* Use first vertex color for line color if no interpolation
+ * Use line color attribute if highlighting.
+ */
+ if (!MI_DDC_IS_HIGHLIGHT(pddc))
+ intcolour.colour.rgbFloat = *(pt.pRgbFloatClr++);
+ else {
+ intcolour.colour.rgbFloat =
+ pddc->Static.attrs->lineColour.colour.rgbFloat;
+ pt.pRgbFloatClr++;
+ }
+ /* Note, can't have any other per-vertex data other than color */
+ line[1] = *pt.p2DSpt;
+
+ miColourtoIndex( pRend, pddc->Dynamic->pPCAttr->colourApproxIndex,
+ &intcolour, &colourindex);
+
+ /* Only set GC value if necessary */
+ if (colourindex != pGC->fgPixel) {
+ pGC->fgPixel = colourindex;
+ /* Register changes with ddx */
+ pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ pGC->stateChanges |= GCForeground;
+ (*pGC->funcs->ChangeGC)(pGC, GCForeground);
+ /* Insure that the GC is reset to proper color next time */
+ pddc->Static.misc.flags |= POLYLINEGCFLAG;
+ }
+
+ /* validate GC prior to start of rendering */
+ if (pGC->serialNumber != pRend->pDrawable->serialNumber)
+ ValidateGC(pRend->pDrawable, pGC);
+
+ /* Call ddx to render the polyline */
+ (*GetGCValue(pGC, ops->Polylines))
+ (pRend->pDrawable,
+ pGC,
+ CoordModeOrigin,
+ 2,
+ line);
+ }
+ }
+ }
+
+ return (Success);
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level1/miRndTStrip.c b/xc/programs/Xserver/PEX5/ddpex/mi/level1/miRndTStrip.c
new file mode 100644
index 000000000..67425a7f1
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level1/miRndTStrip.c
@@ -0,0 +1,740 @@
+/* $TOG: miRndTStrip.c /main/4 1998/02/10 12:40:21 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS 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.
+
+*/
+
+#define NEED_EVENTS
+#include "miRender.h"
+#include "miClip.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "PEXErr.h"
+#include "extnsionst.h"
+#include "gcstruct.h"
+#include "ddpex2.h"
+
+
+/*++
+ |
+ | Function Name: miRenderTriStrip
+ |
+ | Function Description:
+ | Renders a triangle strip to a drawable
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+miRenderTriStrip(pRend, pddc, input_list, input_facet)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miDDContext *pddc; /* dd context handle */
+ miListHeader *input_list; /* triangle strip vertex data */
+ listofddFacet *input_facet; /* per facet data */
+{
+
+
+/* calls */
+ ddpex3rtn miDDC_to_GC_fill_area();
+ ddpex3rtn miCopyPath();
+ ddpex3rtn miFilterPath();
+ ddpex3rtn miCloseFillArea();
+ ddpex3rtn miRemoveInvisibleEdges();
+
+
+/* Local variable definitions */
+ ddPointUnion in_pt, tmp_pt;
+ ddFacetUnion out_fct;
+ listofddPoint *pddlist;
+ listofddFacet *fct_list;
+ miListHeader *edge_copy;
+ miListHeader *temp_list;
+ GCPtr pGC;
+ int point_size, facet_size, num_facets,
+ color_offset, edge_offset;
+ ddULONG colourindex;
+ ddColourSpecifier intcolour;
+ miColourEntry *pintcolour;
+ ddCoord2DS output_array[4];
+ int i, j, k;
+ ddpex3rtn err = Success;
+ ddUSHORT status = 0;
+
+ /* remember that ALL vertex types are of the form:
+ *
+ * |---------------------------|---------|----------|---------|
+ * coords color normal edge
+ * (opt) (opt) (opt)
+ */
+
+
+
+ if (input_list->numLists == 0) return(1);
+
+ else {
+ /*
+ * ddx trashes the input data by adding window offsets.
+ * Thus, if the data is going to be re-used for rendering
+ * of edges, it must be saved :-(.
+ */
+
+ if (pddc->Static.attrs->edges != PEXOff)
+ miCopyPath(pddc, input_list, &edge_copy, 0);
+
+ /*
+ * Update the fill area GC to reflect the current
+ * fill area attributes
+ */
+ pGC = pddc->Static.misc.pFillAreaGC;
+ if (pddc->Static.misc.flags & FILLAREAGCFLAG)
+ miDDC_to_GC_fill_area(pRend, pddc, pddc->Static.misc.pFillAreaGC);
+
+ /*
+ * Render appropriately. One can assume that facets have been
+ * pre-computed if we need facet data.
+ */
+
+ switch (pddc->Static.attrs->intStyle) {
+
+ case PEXInteriorStyleHollow:
+
+ /* At this point, for a fully implemented level1, there would
+ * be another "switch" statement here that would select between
+ * interpolation methods. This switch would exist also exist
+ * for the "solid" fill styles as well. We have, for now,
+ * only implemented InterpNone (flat shading)
+ */
+
+ {
+ /*
+ * The final fill area color is determined by a hierarchy
+ * of sources. The first source is the vertex colors.
+ * If the data has vertex colors, then the final color
+ * is an average of the vertex colors. If there are no
+ * vertex colors, then the facet is set to the
+ * color for the current facet. IF there are no facet colors,
+ * then the color is determined by the surface color attribute.
+ * If highlighting is on, then the color is determined by
+ * the surface color attribute which has been set to the
+ * highlight color
+ */
+
+ if ( (DD_IsVertColour(input_list->type)) &&
+ (!MI_DDC_IS_HIGHLIGHT(pddc)) ) {
+ /*
+ * If vertex colors, simply create a facet list.
+ */
+ DDFacetSIZE(DD_FACET_RGBFLOAT, facet_size);
+ fct_list = MI_NEXTTEMPFACETLIST(pddc);
+ fct_list->type = DD_FACET_RGBFLOAT;
+
+
+ MI_ALLOCLISTOFDDFACET(fct_list, input_facet->numFacets, facet_size);
+ if (!fct_list->facets.pNoFacet) return(BadAlloc);
+ out_fct = fct_list->facets;
+ DD_VertPointSize(input_list->type, point_size);
+ DD_VertOffsetColor(input_list->type, color_offset);
+
+ for(i = 0, pddlist = input_list->ddList;
+ i < input_list->numLists; i++) {
+ in_pt = pddlist->pts;
+ in_pt.ptr += color_offset; /* skip coord data */
+
+ /* Compute average facet color */
+ for (k = 2; k < (pddlist->numPoints); k++) {
+ out_fct.pFacetRgbFloat->red = 0.0;
+ out_fct.pFacetRgbFloat->green = 0.0;
+ out_fct.pFacetRgbFloat->blue = 0.0;
+
+ tmp_pt.ptr = in_pt.ptr + point_size;
+
+ out_fct.pFacetRgbFloat->red
+ += in_pt.pRgbFloatClr->red;
+ out_fct.pFacetRgbFloat->green
+ += in_pt.pRgbFloatClr->green;
+ out_fct.pFacetRgbFloat->blue
+ += in_pt.pRgbFloatClr->blue;
+
+ out_fct.pFacetRgbFloat->red
+ += tmp_pt.pRgbFloatClr->red;
+ out_fct.pFacetRgbFloat->green
+ += tmp_pt.pRgbFloatClr->green;
+ out_fct.pFacetRgbFloat->blue
+ += tmp_pt.pRgbFloatClr->blue;
+ tmp_pt.ptr += point_size;
+ out_fct.pFacetRgbFloat->red
+ += tmp_pt.pRgbFloatClr->red;
+ out_fct.pFacetRgbFloat->green
+ += tmp_pt.pRgbFloatClr->green;
+ out_fct.pFacetRgbFloat->blue
+ += tmp_pt.pRgbFloatClr->blue;
+
+ if (pddlist->numPoints > 2) {
+ out_fct.pFacetRgbFloat->red /= 3;
+ out_fct.pFacetRgbFloat->green /= 3;
+ out_fct.pFacetRgbFloat->blue /= 3;
+ }
+ /* clamp on saturation */
+ if (out_fct.pFacetRgbFloat->red > 1.0)
+ out_fct.pFacetRgbFloat->red = 1.0;
+ if (out_fct.pFacetRgbFloat->green > 1.0)
+ out_fct.pFacetRgbFloat->green = 1.0;
+ if (out_fct.pFacetRgbFloat->blue > 1.0)
+ out_fct.pFacetRgbFloat->blue = 1.0;
+
+
+ in_pt.ptr += point_size; /* skip to next point */
+ out_fct.pFacetRgbFloat++;
+ fct_list->numFacets++;
+ }
+ ++pddlist;
+ }
+ /* new facet colors override input ones */
+ input_facet = fct_list;
+ }
+
+ /* Remove all data from vertex data but vertex coordinates */
+ if ((DD_IsVertNormal(input_list->type)) ||
+ (DD_IsVertEdge(input_list->type)) ||
+ (DD_IsVertColour(input_list->type)) ) {
+ if (err = miFilterPath(pddc, input_list, &temp_list, 1))
+ return(err);
+ input_list = temp_list;
+ }
+
+ if ( (input_facet) &&
+ (input_facet->numFacets > 0) &&
+ (DD_IsFacetColour(input_facet->type)) &&
+ (!MI_DDC_IS_HIGHLIGHT(pddc)) ) {
+
+ pGC = pddc->Static.misc.pFillAreaGC;
+ out_fct = input_facet->facets;
+ DDFacetSIZE(input_facet->type, facet_size);
+ if (pddc->Static.attrs->echoMode == PEXEcho)
+ intcolour = pddc->Static.attrs->echoColour;
+ else {
+ intcolour.colourType = PEXRgbFloatColour;
+ intcolour.colour.rgbFloat = *out_fct.pFacetRgbFloat;
+ }
+ miColourtoIndex( pRend, pddc->Dynamic->pPCAttr->colourApproxIndex,
+ &intcolour, &colourindex);
+
+ }
+
+ else {
+
+ /*
+ * If no vertex or facet colors, use surface attributes.
+ * If highlighting is on, then the color is determined by
+ * the surface color attribute which has been set to the
+ * highlight color
+ */
+ if (pddc->Static.attrs->echoMode == PEXEcho)
+ intcolour = pddc->Static.attrs->echoColour;
+ else {
+ intcolour = pddc->Static.attrs->surfaceColour;
+ }
+
+ miColourtoIndex( pRend,
+ pddc->Dynamic->pPCAttr->colourApproxIndex,
+ &intcolour, &colourindex);
+ }
+
+ /* Only set GC value if necessary */
+ if (colourindex != pGC->fgPixel) {
+ pGC->fgPixel = colourindex;
+ /* Register changes with ddx */
+ pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ pGC->stateChanges |= GCForeground;
+ (*pGC->funcs->ChangeGC)(pGC, GCForeground);
+ /* Insure that the GC is reset to proper color next time */
+ pddc->Static.misc.flags |= FILLAREAGCFLAG;
+ }
+
+ /* validate GC prior to start of rendering */
+ if (pGC->serialNumber !=
+ pRend->pDrawable->serialNumber)
+ ValidateGC(pRend->pDrawable, pGC);
+
+ /* Render each bound as a polyline.
+ * Note - Additional functionality should be able
+ * to distinguesh between "real" and degenerate facets
+ * (produced by clipping) by some internal mechanism,
+ * possibly more bits in the edge flags, and NOT
+ * draw the boundaries for degenerate facets here.
+ */
+
+ DD_VertPointSize(input_list->type, point_size);
+
+ for(i = 0, pddlist = input_list->ddList;
+ i < input_list->numLists; i++) {
+
+ for (j = 2, in_pt.ptr = pddlist->pts.ptr;
+ j < pddlist->numPoints; j++) {
+
+ output_array[0] = *in_pt.p2DSpt;
+
+ tmp_pt.ptr = in_pt.ptr + point_size;
+
+ output_array[1] = *tmp_pt.p2DSpt;
+
+ tmp_pt.ptr += point_size;
+
+ output_array[2] = *tmp_pt.p2DSpt;
+
+ output_array[3] = *in_pt.p2DSpt;
+
+ /* Call ddx to fill polygon */
+ (*GetGCValue
+ (pddc->Static.misc.pFillAreaGC, ops->Polylines))
+ (pRend->pDrawable,
+ pddc->Static.misc.pFillAreaGC,
+ CoordModeOrigin,
+ 4,
+ output_array);
+
+ in_pt.ptr += point_size;
+
+ if ( (input_facet) &&
+ (input_facet->numFacets > 0) &&
+ (DD_IsFacetColour(input_facet->type)) ) {
+ out_fct.pNoFacet += facet_size;
+
+ if (pddc->Static.attrs->echoMode == PEXEcho)
+ intcolour = pddc->Static.attrs->echoColour;
+ else {
+ intcolour.colourType = PEXRgbFloatColour;
+ intcolour.colour.rgbFloat = *out_fct.pFacetRgbFloat;
+ }
+ miColourtoIndex( pRend,
+ pddc->Dynamic->pPCAttr->colourApproxIndex,
+ &intcolour, &colourindex);
+ /* Only set GC value if necessary */
+ if (colourindex != pGC->fgPixel) {
+ pGC->fgPixel = colourindex;
+ /* Register changes with ddx */
+ pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ pGC->stateChanges |= GCForeground;
+ (*pGC->funcs->ChangeGC)(pGC, GCForeground);
+ /* Insure that the GC is reset to proper color next time */
+ pddc->Static.misc.flags |= FILLAREAGCFLAG;
+ }
+
+ /* validate GC prior to start of rendering */
+ if (pGC->serialNumber != pRend->pDrawable->serialNumber)
+ ValidateGC(pRend->pDrawable, pGC);
+
+ }
+ }
+ ++pddlist;
+ }
+
+ }
+ break;
+
+ case PEXInteriorStylePattern:
+ case PEXInteriorStyleHatch:
+ case PEXInteriorStyleSolid:
+ {
+ /*
+ * The final facet color is determined by a hierarchy
+ * of sources. The first source is the by vertex colors.
+ * If the data has vertex colors, then the final color
+ * is an average of the vertex colors. If there are no
+ * vertex colors, then the fill area is set to the facet
+ * color for the current facet. IF there are no facet colors,
+ * then the color is determined by the surface color attribute.
+ * If highlighting is on, then the color is determined by
+ * the surface color attribute which has been set to the
+ * highlight color
+ */
+
+ if ( (DD_IsVertColour(input_list->type)) &&
+ (!MI_DDC_IS_HIGHLIGHT(pddc)) ) {
+ /*
+ * If vertex colors, simply create a facet list.
+ */
+ DDFacetSIZE(DD_FACET_RGBFLOAT, facet_size);
+ fct_list = MI_NEXTTEMPFACETLIST(pddc);
+ fct_list->type = DD_FACET_RGBFLOAT;
+
+ /* Determine number of facets */
+ for (i = 0, num_facets = 0, pddlist = input_list->ddList;
+ i < input_list->numLists; i++) {
+ if (pddlist->numPoints > 2)
+ num_facets += (pddlist->numPoints - 2);
+ pddlist++;
+ }
+
+ MI_ALLOCLISTOFDDFACET(fct_list, num_facets, facet_size);
+ if (!fct_list->facets.pNoFacet) return(BadAlloc);
+ out_fct = fct_list->facets;
+
+ DD_VertPointSize(input_list->type, point_size);
+ DD_VertOffsetColor(input_list->type, color_offset);
+
+ for(i = 0, pddlist = input_list->ddList;
+ i < input_list->numLists; i++) {
+ in_pt = pddlist->pts;
+ in_pt.ptr += color_offset; /* skip coord data */
+
+ /* Compute average facet color */
+ for (k = 2; k < (pddlist->numPoints); k++) {
+ out_fct.pFacetRgbFloat->red = 0.0;
+ out_fct.pFacetRgbFloat->green = 0.0;
+ out_fct.pFacetRgbFloat->blue = 0.0;
+
+ tmp_pt.ptr = in_pt.ptr + point_size;
+
+ out_fct.pFacetRgbFloat->red
+ += in_pt.pRgbFloatClr->red;
+ out_fct.pFacetRgbFloat->green
+ += in_pt.pRgbFloatClr->green;
+ out_fct.pFacetRgbFloat->blue
+ += in_pt.pRgbFloatClr->blue;
+
+ out_fct.pFacetRgbFloat->red
+ += tmp_pt.pRgbFloatClr->red;
+ out_fct.pFacetRgbFloat->green
+ += tmp_pt.pRgbFloatClr->green;
+ out_fct.pFacetRgbFloat->blue
+ += tmp_pt.pRgbFloatClr->blue;
+ tmp_pt.ptr += point_size;
+ out_fct.pFacetRgbFloat->red
+ += tmp_pt.pRgbFloatClr->red;
+ out_fct.pFacetRgbFloat->green
+ += tmp_pt.pRgbFloatClr->green;
+ out_fct.pFacetRgbFloat->blue
+ += tmp_pt.pRgbFloatClr->blue;
+
+ if (pddlist->numPoints > 2) {
+ out_fct.pFacetRgbFloat->red /= 3.0;
+ out_fct.pFacetRgbFloat->green /= 3.0;
+ out_fct.pFacetRgbFloat->blue /= 3.0;
+ }
+ /* clamp on saturation */
+ if (out_fct.pFacetRgbFloat->red > 1.0)
+ out_fct.pFacetRgbFloat->red = 1.0;
+ if (out_fct.pFacetRgbFloat->green > 1.0)
+ out_fct.pFacetRgbFloat->green = 1.0;
+ if (out_fct.pFacetRgbFloat->blue > 1.0)
+ out_fct.pFacetRgbFloat->blue = 1.0;
+
+
+ in_pt.ptr += point_size; /* skip to next point */
+ out_fct.pFacetRgbFloat++;
+ fct_list->numFacets++;
+ }
+ ++pddlist;
+ }
+ /* new facet colors override input ones */
+ input_facet = fct_list;
+
+ }
+
+ /* Remove all data from vertex data but vertex coordinates */
+ if ((DD_IsVertNormal(input_list->type)) ||
+ (DD_IsVertEdge(input_list->type)) ||
+ (DD_IsVertColour(input_list->type)) ) {
+ if (err = miFilterPath(pddc, input_list, &temp_list, 1))
+ return(err);
+ input_list = temp_list;
+ }
+
+ if ( (input_facet) &&
+ (input_facet->numFacets > 0) &&
+ (DD_IsFacetColour(input_facet->type)) &&
+ (!MI_DDC_IS_HIGHLIGHT(pddc)) ) {
+
+ pGC = pddc->Static.misc.pFillAreaGC;
+ out_fct = input_facet->facets;
+ DDFacetSIZE(input_facet->type, facet_size);
+
+
+ /* Render each bound as a polygon */
+
+ DD_VertPointSize(input_list->type, point_size);
+
+ for(i = 0, pddlist = input_list->ddList;
+ i < input_list->numLists; i++) {
+
+ for (j = 2, in_pt.ptr = pddlist->pts.ptr;
+ j < pddlist->numPoints; j++) {
+
+ output_array[0] = *in_pt.p2DSpt;
+
+ tmp_pt.ptr = in_pt.ptr + point_size;
+
+ output_array[1] = *tmp_pt.p2DSpt;
+
+ tmp_pt.ptr += point_size;
+
+ output_array[2] = *tmp_pt.p2DSpt;
+
+ output_array[3] = *in_pt.p2DSpt;
+
+
+ /* Compute index value for ddx */
+ if (pddc->Static.attrs->echoMode == PEXEcho)
+ intcolour = pddc->Static.attrs->echoColour;
+ else {
+ intcolour.colourType = PEXRgbFloatColour;
+ intcolour.colour.rgbFloat = *out_fct.pFacetRgbFloat;
+ }
+ miColourtoIndex(pRend, pddc->Dynamic->pPCAttr->colourApproxIndex,
+ &intcolour, &colourindex);
+
+ /* Only set GC value if necessary */
+ if (colourindex != pGC->fgPixel) {
+ pGC->fgPixel = colourindex;
+ /* Register changes with ddx */
+ pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ pGC->stateChanges |= GCForeground;
+ (*pGC->funcs->ChangeGC)(pGC, GCForeground);
+ /* Insure that the GC is reset to proper color next time */
+ pddc->Static.misc.flags |= FILLAREAGCFLAG;
+ }
+
+ /* validate GC prior to start of rendering */
+ if (pGC->serialNumber != pRend->pDrawable->serialNumber)
+ ValidateGC(pRend->pDrawable, pGC);
+
+ /* Call ddx to fill polygon */
+ (*GetGCValue(pGC, ops->FillPolygon))
+ (pRend->pDrawable,
+ pGC,
+ Convex,
+ CoordModeOrigin,
+ 4,
+ output_array);
+
+
+
+ in_pt.ptr += point_size;
+ out_fct.pNoFacet += facet_size;
+ }
+ pddlist++;
+ }
+ }
+
+ else {
+
+ /*
+ * If no vertex or facet colors, use surface attributes.
+ * If highlighting is on, then the color is determined by
+ * the surface color attribute which has been set to the
+ * highlight color
+ */
+ if (pddc->Static.attrs->echoMode == PEXEcho)
+ intcolour = pddc->Static.attrs->echoColour;
+ else {
+ intcolour = pddc->Static.attrs->surfaceColour;
+ }
+
+ miColourtoIndex( pRend,
+ pddc->Dynamic->pPCAttr->colourApproxIndex,
+ &intcolour, &colourindex);
+
+ /* Only set GC value if necessary */
+ if (colourindex != pGC->fgPixel) {
+ pGC->fgPixel = colourindex;
+ /* Register changes with ddx */
+ pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ pGC->stateChanges |= GCForeground;
+ (*pGC->funcs->ChangeGC)(pGC, GCForeground);
+ /* Insure that the GC is reset to proper color next time */
+ pddc->Static.misc.flags |= FILLAREAGCFLAG;
+ }
+
+ /* validate GC prior to start of rendering */
+ if (pGC->serialNumber !=
+ pRend->pDrawable->serialNumber)
+ ValidateGC(pRend->pDrawable, pGC);
+
+ /* Render each bound as a polyline */
+ DD_VertPointSize(input_list->type, point_size);
+
+ for(i = 0, pddlist = input_list->ddList;
+ i < input_list->numLists; i++) {
+
+ for (j = 2, in_pt.ptr = pddlist->pts.ptr;
+ j < pddlist->numPoints; j++) {
+
+ output_array[0] = *in_pt.p2DSpt;
+
+ tmp_pt.ptr = in_pt.ptr + point_size;
+
+ output_array[1] = *tmp_pt.p2DSpt;
+
+ tmp_pt.ptr += point_size;
+
+ output_array[2] = *tmp_pt.p2DSpt;
+
+ output_array[3] = *in_pt.p2DSpt;
+
+ /* Call ddx to fill polygon */
+ (*GetGCValue(pGC, ops->FillPolygon))
+ (pRend->pDrawable,
+ pGC,
+ Convex,
+ CoordModeOrigin,
+ 4,
+ output_array);
+
+ in_pt.ptr += point_size;
+ }
+ pddlist++;
+ }
+
+
+ break;
+ }
+ }
+
+ case PEXInteriorStyleEmpty:
+ break;
+
+ } /*End of area rendering */
+
+ /*
+ * Now check to see if fill area edges are to be drawn
+ */
+ if (pddc->Static.attrs->edges != PEXOff) {
+
+ input_list = edge_copy;
+
+ DD_VertPointSize(input_list->type, point_size);
+ DD_VertOffsetEdge(input_list->type, edge_offset);
+
+ /*
+ * Update the fill area GC to reflect the current
+ * fill area attributes
+ */
+ if (pddc->Static.misc.flags & EDGEGCFLAG)
+ miDDC_to_GC_edges(pRend, pddc, pddc->Static.misc.pEdgeGC);
+
+ /* validate GC prior to start of rendering */
+ if (pddc->Static.misc.pEdgeGC->serialNumber !=
+ pRend->pDrawable->serialNumber)
+ ValidateGC(pRend->pDrawable, pddc->Static.misc.pEdgeGC);
+
+
+ for (i = 0, pddlist = input_list->ddList;
+ i < input_list->numLists; i++) {
+
+
+ /* Render each bound as a polyline */
+
+ /*
+ * Within an edge flag, there are two bits determining edge
+ * visibility. Bit zero determines whether an edge is drawn
+ * between the current vertex N and vertex N-2, while bit one
+ * determines if an edge is drawn between edge N and N+1.
+ * If N-2 < 0 or N+1 > numfacets the edge is not drawn.
+ *
+ * 2_________ _4
+ * /\ /|\
+ * / \ / \
+ * / \ / \
+ * / \ / \
+ * 1<--------+3+---------5
+ *
+ * So, for the third element in the edge list,
+ * bit 0 indicates presence of an edge from 3 -> 4
+ * (forward edge)
+ * bit 1 indicates presence of an edge from 3 -> 1
+ * (backward edge)
+ *
+ */
+
+
+ for (j = 0, in_pt.ptr = pddlist->pts.ptr;
+ j < pddlist->numPoints; j++) {
+
+ if((j+1) < pddlist->numPoints){
+ if(FWD_EDGE_FLAG & *(in_pt.ptr + edge_offset)) {
+
+ output_array[0] = *in_pt.p2DSpt;
+
+ tmp_pt.ptr = in_pt.ptr + point_size;
+
+ output_array[1] = *tmp_pt.p2DSpt;
+
+ (*GetGCValue(pddc->Static.misc.pEdgeGC, ops->Polylines))
+ (pRend->pDrawable,
+ pddc->Static.misc.pEdgeGC,
+ CoordModeOrigin,
+ 2,
+ output_array);
+ }
+ }
+ if (j > 1){
+ if(BKWD_EDGE_FLAG & *(in_pt.ptr + edge_offset)) {
+
+ output_array[0] = *in_pt.p2DSpt;
+
+ tmp_pt.ptr = in_pt.ptr - (2 * point_size);
+
+ output_array[1] = *tmp_pt.p2DSpt;
+
+ (*GetGCValue(pddc->Static.misc.pEdgeGC, ops->Polylines))
+ (pRend->pDrawable,
+ pddc->Static.misc.pEdgeGC,
+ CoordModeOrigin,
+ 2,
+ output_array);
+
+ }
+ }
+ in_pt.ptr += point_size;
+ }
+ ++pddlist;
+ }
+ }
+
+ return (Success);
+ }
+}
+
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level1/miRndText.c b/xc/programs/Xserver/PEX5/ddpex/mi/level1/miRndText.c
new file mode 100644
index 000000000..0ed05fcee
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level1/miRndText.c
@@ -0,0 +1,122 @@
+/* $TOG: miRndText.c /main/3 1998/02/10 12:40:27 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level1/miRndText.c,v 3.5 1998/10/04 09:34:13 dawes Exp $ */
+
+#define NEED_EVENTS
+#include "miRender.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "PEXErr.h"
+#include "extnsionst.h"
+#include "gcstruct.h"
+#include "ddpex2.h"
+
+
+/*++
+ |
+ | Function Name: miRenderText
+ |
+ | Function Description:
+ | Renders Text to the screen.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+miRenderText(pRend, pddc, input_list)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miDDContext *pddc; /* dd context handle */
+ miListHeader *input_list; /* fill area data */
+{
+/* calls */
+ ddpex3rtn miFilterPath();
+
+/* Local variable definitions */
+ miListHeader *temp_list;
+ listofddPoint *sp;
+ int j;
+ ddpex3rtn err = Success;
+
+ /* Remove all data but vertex coordinates */
+ if ((DD_IsVertNormal(input_list->type)) ||
+ (DD_IsVertEdge(input_list->type)) ||
+ (DD_IsVertColour(input_list->type)) ) {
+ err = miFilterPath(pddc, input_list, &temp_list, 1);
+ if (err) return (err);
+ input_list = temp_list;
+ }
+
+ /*
+ * Update the text GC to reflect the current
+ * text attributes
+ */
+ if (pddc->Static.misc.flags & TEXTGCFLAG)
+ miDDC_to_GC_text(pRend, pddc, pddc->Static.misc.pTextGC);
+
+ /* Validate GC prior to start of rendering */
+
+ if (pddc->Static.misc.pTextGC->serialNumber !=
+ pRend->pDrawable->serialNumber)
+ ValidateGC(pRend->pDrawable, pddc->Static.misc.pTextGC);
+
+ /* We should have DC paths here; Render them */
+
+ for (j = 0, sp = input_list->ddList;
+ j < input_list->numLists; j++, sp++) {
+ if (sp->numPoints > 0) {
+
+ /* Call ddx to render the polylines */
+ (*GetGCValue(pddc->Static.misc.pTextGC, ops->Polylines))
+ (pRend->pDrawable,
+ pddc->Static.misc.pTextGC,
+ CoordModeOrigin,
+ sp->numPoints,
+ sp->pts.p2DSpt);
+ }
+ }
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level2/Imakefile b/xc/programs/Xserver/PEX5/ddpex/mi/level2/Imakefile
new file mode 100644
index 000000000..b9ed7c86c
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level2/Imakefile
@@ -0,0 +1,117 @@
+XCOMM
+XCOMM $XConsortium: Imakefile /main/8 1996/09/28 16:54:14 rws $
+XCOMM $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level2/Imakefile,v 3.9 1999/04/17 09:08:16 dawes Exp $
+XCOMM
+XCOMM
+XCOMM Copyright 1989, 1990, 1991 by Sun Microsystems, Inc. and the X Consortium
+XCOMM
+XCOMM All Rights Reserved
+XCOMM
+XCOMM Permission to use, copy, modify, and distribute this software and its
+XCOMM documentation for any purpose and without fee is hereby granted,
+XCOMM provided that the above copyright notice appear in all copies and that
+XCOMM both that copyright notice and this permission notice appear in
+XCOMM supporting documentation, and that the names of Sun Microsystems
+XCOMM and the X Consortium not be used in advertising or publicity
+XCOMM pertaining to distribution of the software without specific, written
+XCOMM prior permission.
+XCOMM
+XCOMM SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+XCOMM INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+XCOMM EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+XCOMM CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+XCOMM USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+XCOMM OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+XCOMM PERFORMANCE OF THIS SOFTWARE.
+
+#define IHaveModules
+#include <Server.tmpl>
+
+#ifndef PexDdpexCDebugFlags
+#define PexDdpexCDebugFlags ServerCDebugFlags
+#endif
+
+XCOMM -D defines for ddpex:
+XCOMM DDTEST turns on some fprintf(stderr...)s for debugging
+
+ DEFINES = PexDdpexDefines
+CDEBUGFLAGS = PexDdpexCDebugFlags
+
+ PEXSERVINC = ../../../include
+DDPEXINCLUDE = ../include
+
+INCLUDES = -I. \
+ -I$(DDPEXINCLUDE) \
+ -I$(XINCLUDESRC) \
+ -I$(PEXSERVINC) \
+ -I$(SERVERSRC)/include
+
+SRCS = ddContext.c \
+ miBldXform.c \
+ miClip.c \
+ miCellArray.c \
+ miConvert.c \
+ miDestroy.c \
+ miFillArea.c \
+ miLight.c \
+ miLvl2Tab.c \
+ miMarkers.c \
+ miNCurve.c \
+ miNSurf.c \
+ miNSTrim.c \
+ miNurbs.c \
+ miOCs.c \
+ miPolyLine.c \
+ miQuadMesh.c \
+ miSOFAS.c \
+ miTestOCs.c \
+ miText.c \
+ miTrans.c \
+ miTriStrip.c \
+ miCopy.c \
+ miInquire.c \
+ miReplace.c \
+ miPickPrim.c \
+ miSearch.c \
+ pexOCParse.c
+
+OBJS = ddContext.o \
+ miBldXform.o \
+ miClip.o \
+ miConvert.o \
+ miCellArray.o \
+ miDestroy.o \
+ miFillArea.o \
+ miLight.o \
+ miLvl2Tab.o \
+ miMarkers.o \
+ miNCurve.o \
+ miNSurf.o \
+ miNSTrim.o \
+ miNurbs.o \
+ miOCs.o \
+ miPolyLine.o \
+ miQuadMesh.o \
+ miSOFAS.o \
+ miTestOCs.o \
+ miText.o \
+ miTrans.o \
+ miTriStrip.o \
+ miCopy.o \
+ miInquire.o \
+ miReplace.o \
+ miPickPrim.o \
+ miSearch.o \
+ pexOCParse.o
+
+ModuleObjectRule()
+
+SubdirLibraryRule($(OBJS))
+
+NormalLibraryTarget(ddpex2,$(OBJS))
+
+LintLibraryTarget(dp2, $(SRCS))
+NormalLintTarget($(SRCS))
+
+DependTarget()
+
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level2/ddContext.c b/xc/programs/Xserver/PEX5/ddpex/mi/level2/ddContext.c
new file mode 100644
index 000000000..1322cce00
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level2/ddContext.c
@@ -0,0 +1,1091 @@
+/* $TOG: ddContext.c /main/11 1998/02/10 12:40:37 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity
+pertaining to distribution of the software without specific, written
+prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level2/ddContext.c,v 3.5 1998/10/04 09:34:15 dawes Exp $ */
+
+#include "miWks.h"
+#include "miStruct.h"
+#include "miRender.h"
+#include "PEXErr.h"
+#include "pexUtils.h"
+#include "pixmap.h"
+#include "windowstr.h"
+#include "regionstr.h"
+#include "miscstruct.h"
+#include "pexos.h"
+
+
+static void deleteDynamicDDContext();
+
+/* External variables used */
+
+extern void miMatMult();
+extern RendTableType RenderPrimitiveTable[];
+extern RendTableType PickPrimitiveTable[];
+
+/* pcflag is initialized in ddpexInit() */
+extern ddBOOL pcflag;
+extern ddPCAttr defaultPCAttr;
+#define MI_GET_DEFAULT_PC(pPC) \
+ if (!pcflag) { \
+ DefaultPC(pPC); \
+ pcflag = MI_TRUE; }
+
+/*++
+ |
+ | Function Name: CreateDDContext
+ |
+ | Function Description:
+ | Creates and initializes a DDContext structure and
+ | intializes the Renderer pointer.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+CreateDDContext(pRend)
+ ddRendererPtr pRend; /* renderer handle */
+{
+
+ extern GCPtr CreateScratchGC();
+ miDDContext *pddc;
+ ddPCAttr *ppca;
+ listofObj *pMC, *pLS;
+ int i;
+
+ pRend->pDDContext = NULL;
+
+ /*
+ * Create the dd attribute context: this requires creating both the
+ * static and Dynamic portions of the DDContext.
+ */
+ pddc = (miDDContext *) xalloc(sizeof(miDDContext));
+ if (!pddc)
+ return (BadAlloc);
+ pddc->Dynamic = (miDynamicDDContext *) xalloc(sizeof(miDynamicDDContext));
+ if (!pddc->Dynamic) {
+ xfree((char *) pddc);
+ return (BadAlloc);
+ }
+ /* allocate storage for local copy of PC */
+ pddc->Dynamic->pPCAttr = (ddPCAttr *) xalloc(sizeof(ddPCAttr));
+ if (!pddc->Dynamic->pPCAttr) {
+ xfree((char *) pddc->Dynamic);
+ xfree((char *) pddc);
+ return (BadAlloc);
+ }
+
+ /* initialize pointers so that panic-caused freeing is clean */
+ pddc->Static.misc.ms_MCV = NULL;
+ pddc->Static.attrs = NULL;
+ pddc->Dynamic->next = NULL;
+ pddc->Dynamic->pPCAttr->modelClipVolume = NULL;
+ pddc->Dynamic->pPCAttr->lightState = NULL;
+ pddc->Static.misc.pPolylineGC = NULL;
+ pddc->Static.misc.pFillAreaGC = NULL;
+ pddc->Static.misc.pEdgeGC = NULL;
+ pddc->Static.misc.pPolyMarkerGC = NULL;
+ pddc->Static.misc.pTextGC = NULL;
+
+
+ /* don't forget Model Clip and lightState in PC */
+ pddc->Dynamic->pPCAttr->modelClipVolume = puCreateList(DD_HALF_SPACE);
+ if (!pddc->Dynamic->pPCAttr->modelClipVolume) {
+ DeleteDDContext(pddc);
+ return (BadAlloc);
+ }
+
+ pddc->Dynamic->pPCAttr->lightState = puCreateList(DD_INDEX);
+ if (!pddc->Dynamic->pPCAttr->lightState) {
+ DeleteDDContext(pddc);
+ return (BadAlloc);
+ }
+
+ /* don't forget transformed versions of MCVolume in PC */
+ pddc->Static.misc.ms_MCV = puCreateList(DD_HALF_SPACE);
+ if (!pddc->Static.misc.ms_MCV) {
+ DeleteDDContext(pddc);
+ return (BadAlloc);
+ }
+
+ /*
+ * Initialize the newly created ddcontext.
+ */
+ ppca = pddc->Dynamic->pPCAttr;
+ pMC = ppca->modelClipVolume;
+ pLS = ppca->lightState;
+ if (pRend->pPC != NULL) {
+ *ppca = *pRend->pPC->pPCAttr;
+
+ /*
+ * don't forget the model clip half planes and list of light sources,
+ * which are only pointed to
+ */
+ if (puCopyList(pRend->pPC->pPCAttr->modelClipVolume, pMC)) {
+ DeleteDDContext(pddc);
+ return (BadAlloc);
+ }
+ if (puCopyList(pRend->pPC->pPCAttr->lightState, pLS)) {
+ DeleteDDContext(pddc);
+ return (BadAlloc);
+ }
+ } else { /* use default PC values */
+ MI_GET_DEFAULT_PC(&defaultPCAttr);
+ *ppca = defaultPCAttr;
+
+ /*
+ * don't forget the model clip half planes and list of light sources,
+ * which are only pointed to
+ */
+ if (puCopyList(defaultPCAttr.modelClipVolume, pMC)) {
+ DeleteDDContext(pddc);
+ return (BadAlloc);
+ }
+ if (puCopyList(defaultPCAttr.lightState, pLS)) {
+ DeleteDDContext(pddc);
+ return (BadAlloc);
+ }
+ }
+ ppca->modelClipVolume = pMC;
+ ppca->lightState = pLS;
+
+ /* copy the current name set from the ns resource to the renderer */
+ MINS_EMPTY_NAMESET(pddc->Dynamic->currentNames);
+ if (ppca->pCurrentNS) {
+ miNSHeader *pns = (miNSHeader *) ppca->pCurrentNS->deviceData;
+
+ MINS_COPY_NAMESET(pns->names, pddc->Dynamic->currentNames);
+ }
+ pddc->Dynamic->filter_flags = 0;
+ pddc->Dynamic->do_prims = 1;
+
+ /*
+ * Initialize level 1 rendering procedure jump table
+ */
+ memcpy( (char *) pddc->Static.RenderProcs,
+ (char *) RenderPrimitiveTable,
+ sizeof(RendTableType) * RENDER_TABLE_LENGTH);
+
+ /*
+ * Allocate storage and initialize the DD context rendering attributes.
+ */
+ if (!(pddc->Static.attrs =
+ (miDDContextRendAttrs *) xalloc(sizeof(miDDContextRendAttrs)))) {
+ DeleteDDContext(pddc);
+ return (BadAlloc);
+ }
+
+ /*
+ * Intialize the scratch data pointer areas Setting the maxlists or
+ * maxData fields to 0 insures that headers are allocated the first time
+ * the lists are used.
+ */
+ pddc->Static.misc.listIndex = 0;
+ for (i = 0; i < MI_MAXTEMPDATALISTS; i++)
+ pddc->Static.misc.list4D[i].maxLists = 0;
+ pddc->Static.misc.list2D.maxLists = 0;
+
+ for (i = 0; i < MI_MAXTEMPFACETLISTS; i++)
+ pddc->Static.misc.facets[i].maxData = 0;
+
+ /*
+ * get a GC use the default values for now a scratch gc should be OK,
+ * it's the same as a regular gc except it doesn't create the tile or
+ * stipple I don't think we need to express interest in any change to the
+ * GC, since the ddpex code which uses the gc is the only one who should
+ * be changing it. But, we may need to express interest in window events
+ * or something if we can.
+ *
+ * a GC is created for each primitive type. THis should reduce the number of
+ * calls to change GC as otherwise this call would be required for each
+ * primitive. Note, that the down-side of this approach is that many
+ * hardware platforms only support a single graphics context, and thus
+ * will have to be re-loaded at every validate GC anyways.... There is no
+ * drawable if doing a search (ISS), so don't create the GCs. They aren't
+ * needed.
+ */
+
+ if (pRend->pDrawable) {
+ pddc->Static.misc.flags |= (POLYLINEGCFLAG | FILLAREAGCFLAG |
+ EDGEGCFLAG | MARKERGCFLAG | TEXTGCFLAG |
+ NOLINEDASHFLAG);
+
+ if (!(pddc->Static.misc.pPolylineGC =
+ CreateScratchGC(pRend->pDrawable->pScreen, pRend->pDrawable->depth))) {
+ DeleteDDContext(pddc);
+ return (BadAlloc);
+ }
+ if (!(pddc->Static.misc.pFillAreaGC =
+ CreateScratchGC(pRend->pDrawable->pScreen, pRend->pDrawable->depth))) {
+ DeleteDDContext(pddc);
+ return (BadAlloc);
+ }
+ if (!(pddc->Static.misc.pEdgeGC =
+ CreateScratchGC(pRend->pDrawable->pScreen, pRend->pDrawable->depth))) {
+ DeleteDDContext(pddc);
+ return (BadAlloc);
+ }
+ if (!(pddc->Static.misc.pPolyMarkerGC =
+ CreateScratchGC(pRend->pDrawable->pScreen, pRend->pDrawable->depth))) {
+ DeleteDDContext(pddc);
+ return (BadAlloc);
+ }
+ if (!(pddc->Static.misc.pTextGC =
+ CreateScratchGC(pRend->pDrawable->pScreen, pRend->pDrawable->depth))) {
+ DeleteDDContext(pddc);
+ return (BadAlloc);
+ }
+ }
+ /* init pick and search structs */
+ pddc->Static.pick.type = 0;
+ pddc->Static.pick.status = PEXNoPick;
+
+ MINS_EMPTY_NAMESET(pddc->Static.pick.inclusion);
+ MINS_EMPTY_NAMESET(pddc->Static.pick.exclusion);
+
+ pddc->Static.search.status = PEXNotFound;
+
+ MINS_EMPTY_NAMESET(pddc->Static.search.norm_inclusion);
+ MINS_EMPTY_NAMESET(pddc->Static.search.norm_exclusion);
+ MINS_EMPTY_NAMESET(pddc->Static.search.invert_inclusion);
+ MINS_EMPTY_NAMESET(pddc->Static.search.invert_exclusion);
+
+ /* Indicate all xforms in static are invalid */
+ pddc->Static.misc.flags |= ( INVTRCCTODCXFRMFLAG | INVTRWCTOCCXFRMFLAG
+ | INVTRMCTOCCXFRMFLAG | INVTRMCTOWCXFRMFLAG | INVVIEWXFRMFLAG );
+
+ /* Mark as invalid any transform dependant fields in ddContext
+ */
+ pddc->Static.misc.flags |= (MCVOLUMEFLAG | CC_DCUEVERSION);
+
+ /* If successfull, initialize Renderer pointer and return */
+ pRend->pDDContext = (ddPointer) pddc;
+ return (Success);
+}
+
+/*++
+ |
+ | Function Name: DeleteDDContext
+ |
+ | Function Description:
+ | Deletes all of the storage used by the ddPEX attribute context.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+DeleteDDContext(pDDContext)
+/* in */
+ miDDContext *pDDContext; /* ddPEX attribute structure */
+/* out */
+{
+ miDynamicDDContext *pdddc, *pdddc2;
+ int i;
+
+#ifdef DDTEST
+ ErrorF(" DeleteDDContext\n");
+#endif
+
+ if (!pDDContext) return(Success); /* just in case */
+
+ /* Free the ddcontext attribute store */
+ if (pDDContext->Static.attrs) {
+ xfree((char *) (pDDContext->Static.attrs));
+ pDDContext->Static.attrs = 0;
+ }
+
+ /*
+ * free the scratch rendering data buffers.
+ */
+ for (i = 0; i < MI_MAXTEMPDATALISTS; i++) {
+ MI_FREELISTHEADER(&(pDDContext->Static.misc.list4D[i]));
+ }
+ MI_FREELISTHEADER(&pDDContext->Static.misc.list2D);
+
+ for (i = 0; i < MI_MAXTEMPFACETLISTS; i++)
+ if (pDDContext->Static.misc.facets[i].maxData) {
+ xfree((char *)(pDDContext->Static.misc.facets[i].facets.pNoFacet));
+ pDDContext->Static.misc.facets[i].facets.pNoFacet = 0;
+ }
+
+ if (pDDContext->Static.misc.ms_MCV) {
+ puDeleteList(pDDContext->Static.misc.ms_MCV);
+ pDDContext->Static.misc.ms_MCV = 0;
+ }
+
+ /*
+ * Free the graphics contexts.
+ */
+ if (pDDContext->Static.misc.pPolylineGC)
+ FreeScratchGC(pDDContext->Static.misc.pPolylineGC);
+
+ if (pDDContext->Static.misc.pFillAreaGC)
+ FreeScratchGC(pDDContext->Static.misc.pFillAreaGC);
+
+ if (pDDContext->Static.misc.pEdgeGC)
+ FreeScratchGC(pDDContext->Static.misc.pEdgeGC);
+
+ if (pDDContext->Static.misc.pPolyMarkerGC)
+ FreeScratchGC(pDDContext->Static.misc.pPolyMarkerGC);
+
+ if (pDDContext->Static.misc.pTextGC)
+ FreeScratchGC(pDDContext->Static.misc.pTextGC);
+
+ /* free the Dynamic part(s) */
+ pdddc = pDDContext->Dynamic;
+ while (pdddc) {
+ pdddc2 = pdddc->next;
+ deleteDynamicDDContext(pdddc);
+ pdddc = pdddc2;
+ }
+
+ /* zero pointers to force illumination of any server bugs */
+ pDDContext->Static.misc.ms_MCV = NULL;
+ pDDContext->Static.attrs = NULL;
+ pDDContext->Static.misc.pPolylineGC = NULL;
+ pDDContext->Static.misc.pFillAreaGC = NULL;
+ pDDContext->Static.misc.pEdgeGC = NULL;
+ pDDContext->Static.misc.pPolyMarkerGC = NULL;
+ pDDContext->Static.misc.pTextGC = NULL;
+
+ pDDContext->Dynamic = NULL;
+
+ /* Lastly, free the ddcontext pointer itself.... */
+ xfree((char *) (pDDContext));
+
+ return (Success);
+} /* DeleteDDContext */
+
+/*++
+ |
+ | Function Name: deleteDynamicDDContext
+ |
+ | Function Description:
+ | Deletes all of the storage used by the DynamicDDContext
+ | attribute context.
+ |
+ | Note(s):
+ |
+ --*/
+
+static
+void
+deleteDynamicDDContext(pdddc)
+/* in */
+ miDynamicDDContext *pdddc;
+{
+ /* delete the dynamic part of the DDContext */
+
+ if (!pdddc) return;
+
+ /* delete the pc attributes */
+ if (pdddc->pPCAttr) {
+ /* model clip volume */
+ if (pdddc->pPCAttr->modelClipVolume) {
+ puDeleteList(pdddc->pPCAttr->modelClipVolume);
+ pdddc->pPCAttr->modelClipVolume = NULL;
+ }
+ /* list of light source indices */
+ if (pdddc->pPCAttr->lightState) {
+ puDeleteList(pdddc->pPCAttr->lightState);
+ pdddc->pPCAttr->lightState = NULL;
+ }
+ /* pc attr */
+ xfree((char *) pdddc->pPCAttr);
+ pdddc->pPCAttr = NULL;
+ }
+ xfree((char *) pdddc);
+} /* deleteDynamicDDContext */
+
+/*++
+ |
+ | Function Name: PushddContext
+ |
+ | Function Description:
+ | Pushes an instance of the ddContext on the stack, and creates
+ | a new "current" copy.
+ |
+ | The ddContext is divided into two parts: static and dynamic.
+ | The static attributes of the ddContext are either invarient
+ | across CSS hierarchy levels, or must be recomputed when moving
+ | up a level in the hierarchy. Dybnamic attributes, on the other
+ | hand, are stored in the stack when decending down the CSS, and
+ | thus can be restored by a simple "pop" operation when climbing
+ | back up through the CSS hierarchy.
+ |
+ | This routine, therefore, saves the current dynamic ddContext
+ | attributes on the stack, and initializes a new dynamic ddContext.
+ |
+ | Note(s):
+ | Since some of the dynamic ddContext elements contain and/or
+ | are pointers to objects, the info cannot be copied directly,
+ | but new objects must be made to be pointed to and their contents copied.
+ | So, the sequence that this procedure goes through is this:
+ | create a new dd context data structure
+ | copy old context to the new context, but remember
+ | that pointers to objects will be replaced.
+ | create a new PCAttr structure and copy old to new
+ | update the current path and transform matrices
+ | push the new context onto the stack
+ |
+ --*/
+
+ddpex3rtn
+PushddContext(pRend)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+/* out */
+{
+ miDDContext *pDDContext = (miDDContext *) (pRend->pDDContext);
+ miDynamicDDContext *oldDContext = pDDContext->Dynamic;
+ miDynamicDDContext *newDContext;
+
+#ifdef DDTEST
+ ErrorF(" BeginStructure %d\n", sId);
+#endif
+
+ /* First, create a new dynamic dd context */
+ if (!(newDContext = (miDynamicDDContext *) xalloc(sizeof(miDynamicDDContext)))) {
+ return (BadAlloc);
+ }
+
+ /*
+ * copy the contents of the old Dynamic ddContext to the new one this
+ * also copies the current name set
+ */
+ *newDContext = *oldDContext;
+
+ /* now, create a new PC for the new dd context */
+ if (!(newDContext->pPCAttr = (ddPCAttr *) xalloc(sizeof(ddPCAttr)))) {
+ xfree((char *) newDContext);
+ return (BadAlloc);
+ }
+ /* Copy static portion of PC attrs */
+ *newDContext->pPCAttr = *oldDContext->pPCAttr;
+
+ /* now create new stuff for pointers in new PCAttr to point to */
+ /* model clip volume */
+ newDContext->pPCAttr->modelClipVolume = puCreateList(DD_HALF_SPACE);
+ if (!newDContext->pPCAttr->modelClipVolume) {
+ deleteDynamicDDContext(newDContext);
+ return (BadAlloc);
+ }
+ if (puCopyList(oldDContext->pPCAttr->modelClipVolume,
+ newDContext->pPCAttr->modelClipVolume)) {
+ deleteDynamicDDContext(newDContext);
+ return (BadAlloc);
+ }
+ /* light source indices */
+ newDContext->pPCAttr->lightState = puCreateList(DD_INDEX);
+ if (!newDContext->pPCAttr->lightState) {
+ deleteDynamicDDContext(newDContext);
+ return (BadAlloc);
+ }
+ if (puCopyList(oldDContext->pPCAttr->lightState,
+ newDContext->pPCAttr->lightState)) {
+ deleteDynamicDDContext(newDContext);
+ return (BadAlloc);
+ }
+ /** Concatenate the local and global transforms into the new
+ ** global transform, then identity out the local one **/
+ miMatMult(newDContext->pPCAttr->globalMat,
+ oldDContext->pPCAttr->localMat,
+ oldDContext->pPCAttr->globalMat);
+
+ memcpy( (char *) newDContext->pPCAttr->localMat,
+ (char *) ident4x4, 16 * sizeof(ddFLOAT));
+
+ /** Push the new context onto the renderer DDContext **/
+ /* newContext points to the old context */
+ newDContext->next = pDDContext->Dynamic;
+ /* renderer points to the new context */
+ pDDContext->Dynamic = newDContext;
+
+ return (Success);
+} /* PushddContext */
+
+/*++
+ |
+ | Function Name: PopddContext
+ |
+ | Function Description:
+ | Pops an instance of a dynamic ddContext structure off the stack.
+ | (See description above.)
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+PopddContext(pRend)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+/* out */
+{
+ miDDContext *pddc = (miDDContext *) pRend->pDDContext;
+ miDynamicDDContext *oldDDDContext;
+
+#ifdef DDTEST
+ ErrorF(" EndStructure\n");
+#endif
+
+ /** Pop off top of attr context stack **/
+ oldDDDContext = pddc->Dynamic;
+ pddc->Dynamic = oldDDDContext->next;
+
+ /** Free up storage used by oldContext **/
+ deleteDynamicDDContext(oldDDDContext);
+
+ /* Mark as invalid appropriate inverse transforms in dd context */
+ pddc->Static.misc.flags |= (INVTRMCTOWCXFRMFLAG | INVTRWCTOCCXFRMFLAG |
+ INVTRMCTOCCXFRMFLAG | INVTRCCTODCXFRMFLAG |
+ INVVIEWXFRMFLAG);
+
+ /* Mark as invalid any transform dependant fields in ddContext */
+ pddc->Static.misc.flags |= (MCVOLUMEFLAG | CC_DCUEVERSION);
+
+ return (Success);
+
+} /* PopddContext */
+
+/*++
+ |
+ | Function Name: ValidateDDContextAttrs
+ |
+ | Function Description:
+ | Updates the rendering attributes to match the
+ | attributes associated with the current PC.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+ValidateDDContextAttrs(pRend, pddc, tables, namesets, attrs)
+ ddRendererPtr pRend; /* renderer handle */
+ miDDContext *pddc; /* ddPEX attribute structure */
+ ddBitmask tables, namesets, attrs;
+{
+ ddpex3rtn miConvertColor();
+ miLineBundleEntry *linebundle = 0;
+ miTextBundleEntry *textbundle = 0;
+ miMarkerBundleEntry *markerbundle = 0;
+ miInteriorBundleEntry *intbundle = 0;
+ miEdgeBundleEntry *edgebundle = 0;
+ miViewEntry *view = 0;
+ ddUSHORT status = 0;
+ char colors;
+
+ colors = (tables & PEXDynColourTable) || (tables & PEXDynColourTableContents);
+
+ /*
+ * Marker Attributes
+ */
+ if ((tables & PEXDynMarkerBundle) ||
+ (tables & PEXDynMarkerBundleContents) ||
+ colors) {
+ if (~(pddc->Dynamic->pPCAttr->asfs
+ & (PEXMarkerTypeAsf | PEXMarkerScaleAsf | PEXMarkerColourAsf))) {
+
+ if ((InquireLUTEntryAddress(PEXMarkerBundleLUT,
+ pRend->lut[PEXMarkerBundleLUT],
+ pddc->Dynamic->pPCAttr->markerIndex,
+ &status, (ddPointer *) (&markerbundle)))
+ == PEXLookupTableError)
+ return (PEXLookupTableError);
+ }
+ /* always try to set the color */
+ if (!MI_DDC_IS_HIGHLIGHT(pddc)) {
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXMarkerColourAsf) == PEXBundled) {
+ miConvertColor(pRend,
+ &markerbundle->real_entry.markerColour,
+ pddc->Dynamic->pPCAttr->rdrColourModel,
+ &pddc->Static.attrs->markerColour);
+ } else {
+ miConvertColor(pRend,
+ &pddc->Dynamic->pPCAttr->markerColour,
+ pddc->Dynamic->pPCAttr->rdrColourModel,
+ &pddc->Static.attrs->markerColour);
+ }
+ }
+ /* only set these if it's the bundle that changed */
+ if ((tables & PEXDynMarkerBundle) ||
+ (tables & PEXDynMarkerBundleContents)) {
+
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXMarkerTypeAsf) == PEXBundled)
+ pddc->Static.attrs->markerType = markerbundle->real_entry.markerType;
+ else
+ pddc->Static.attrs->markerType = pddc->Dynamic->pPCAttr->markerType;
+
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXMarkerScaleAsf) == PEXBundled)
+ pddc->Static.attrs->markerScale =
+ markerbundle->real_entry.markerScale;
+ else
+ pddc->Static.attrs->markerScale =
+ pddc->Dynamic->pPCAttr->markerScale;
+
+ }
+ pddc->Static.misc.flags |= MARKERGCFLAG;
+ }
+
+ /*
+ * Text Attributes
+ */
+ if ((tables & PEXDynTextBundle) ||
+ (tables & PEXDynTextBundleContents) ||
+ colors) {
+ if (~(pddc->Dynamic->pPCAttr->asfs
+ & (PEXTextFontIndexAsf | PEXTextPrecAsf | PEXCharExpansionAsf |
+ PEXCharSpacingAsf | PEXTextColourAsf))) {
+
+ if ((InquireLUTEntryAddress(PEXTextBundleLUT,
+ pRend->lut[PEXTextBundleLUT],
+ pddc->Dynamic->pPCAttr->textIndex,
+ &status, (ddPointer *) (&textbundle)))
+ == PEXLookupTableError)
+ return (PEXLookupTableError);
+ }
+ /* First, bundled attributes */
+ /* always try to set the color */
+ if (!MI_DDC_IS_HIGHLIGHT(pddc)) {
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXTextColourAsf) == PEXBundled) {
+ miConvertColor(pRend,
+ &textbundle->real_entry.textColour,
+ pddc->Dynamic->pPCAttr->rdrColourModel,
+ &pddc->Static.attrs->textColour);
+ } else {
+ miConvertColor(pRend,
+ &pddc->Dynamic->pPCAttr->textColour,
+ pddc->Dynamic->pPCAttr->rdrColourModel,
+ &pddc->Static.attrs->textColour);
+ }
+ }
+ /* only set these if it's the bundle that changed */
+ if ((tables & PEXDynTextBundle) ||
+ (tables & PEXDynTextBundleContents)) {
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXTextFontIndexAsf) == PEXBundled)
+ pddc->Static.attrs->textFont = textbundle->real_entry.textFontIndex;
+ else
+ pddc->Static.attrs->textFont = pddc->Dynamic->pPCAttr->textFont;
+
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXTextPrecAsf) == PEXBundled)
+ pddc->Static.attrs->textPrecision =
+ textbundle->real_entry.textPrecision;
+ else
+ pddc->Static.attrs->textPrecision =
+ pddc->Dynamic->pPCAttr->textPrecision;
+
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXCharExpansionAsf) == PEXBundled)
+ pddc->Static.attrs->charExpansion =
+ textbundle->real_entry.charExpansion;
+ else
+ pddc->Static.attrs->charExpansion =
+ pddc->Dynamic->pPCAttr->charExpansion;
+
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXCharSpacingAsf) == PEXBundled)
+ pddc->Static.attrs->charSpacing = textbundle->real_entry.charSpacing;
+ else
+ pddc->Static.attrs->charSpacing = pddc->Dynamic->pPCAttr->charSpacing;
+ }
+ }
+
+ /*
+ * Next, unbundled attributes always do these, but there may be some way
+ * to put some smarts in about this
+ */
+ pddc->Static.attrs->charHeight = pddc->Dynamic->pPCAttr->charHeight;
+ pddc->Static.attrs->charUp = pddc->Dynamic->pPCAttr->charUp;
+ pddc->Static.attrs->textPath = pddc->Dynamic->pPCAttr->textPath;
+ pddc->Static.attrs->textAlignment = pddc->Dynamic->pPCAttr->textAlignment;
+ pddc->Static.attrs->atextHeight = pddc->Dynamic->pPCAttr->atextHeight;
+ pddc->Static.attrs->atextUp = pddc->Dynamic->pPCAttr->atextUp;
+ pddc->Static.attrs->atextPath = pddc->Dynamic->pPCAttr->atextPath;
+ pddc->Static.attrs->atextAlignment = pddc->Dynamic->pPCAttr->atextAlignment;
+ pddc->Static.attrs->atextStyle = pddc->Dynamic->pPCAttr->atextStyle;
+
+ pddc->Static.misc.flags |= TEXTGCFLAG;
+
+ /*
+ * Line Attributes
+ */
+ if ((tables & PEXDynLineBundle) ||
+ (tables & PEXDynLineBundleContents) ||
+ colors) {
+ if (~(pddc->Dynamic->pPCAttr->asfs
+ & (PEXLineTypeAsf | PEXLineWidthAsf | PEXLineColourAsf |
+ PEXCurveApproxAsf | PEXPolylineInterpAsf))) {
+ if ((InquireLUTEntryAddress(PEXLineBundleLUT,
+ pRend->lut[PEXLineBundleLUT],
+ pddc->Dynamic->pPCAttr->lineIndex,
+ &status, (ddPointer *) (&linebundle)))
+ == PEXLookupTableError)
+ return (PEXLookupTableError);
+ }
+ /* Update DDC rendering attributes if bundled */
+ /* always try to set the color */
+ if (!MI_DDC_IS_HIGHLIGHT(pddc)) {
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXLineColourAsf) == PEXBundled) {
+ miConvertColor(pRend,
+ &linebundle->real_entry.lineColour,
+ pddc->Dynamic->pPCAttr->rdrColourModel,
+ &pddc->Static.attrs->lineColour);
+ } else {
+ miConvertColor(pRend,
+ &pddc->Dynamic->pPCAttr->lineColour,
+ pddc->Dynamic->pPCAttr->rdrColourModel,
+ &pddc->Static.attrs->lineColour);
+ }
+ }
+ /* only set these if it's the bundle that changed */
+ if ((tables & PEXDynLineBundle) ||
+ (tables & PEXDynLineBundleContents)) {
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXLineTypeAsf) == PEXBundled)
+ pddc->Static.attrs->lineType = linebundle->real_entry.lineType;
+ else
+ pddc->Static.attrs->lineType = pddc->Dynamic->pPCAttr->lineType;
+
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXLineWidthAsf) == PEXBundled)
+ pddc->Static.attrs->lineWidth = linebundle->real_entry.lineWidth;
+ else
+ pddc->Static.attrs->lineWidth = pddc->Dynamic->pPCAttr->lineWidth;
+
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXCurveApproxAsf) == PEXBundled)
+ pddc->Static.attrs->curveApprox = linebundle->real_entry.curveApprox;
+ else
+ pddc->Static.attrs->curveApprox = pddc->Dynamic->pPCAttr->curveApprox;
+
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXPolylineInterpAsf) == PEXBundled)
+ pddc->Static.attrs->lineInterp = linebundle->real_entry.polylineInterp;
+ else
+ pddc->Static.attrs->lineInterp = pddc->Dynamic->pPCAttr->lineInterp;
+ }
+ pddc->Static.misc.flags |= POLYLINEGCFLAG;
+ }
+
+ /*
+ * Surface Attributes
+ */
+
+ if ((tables & PEXDynInteriorBundle) ||
+ (tables & PEXDynInteriorBundleContents) ||
+ colors) {
+ if (~(pddc->Dynamic->pPCAttr->asfs
+ & (PEXInteriorStyleAsf | PEXInteriorStyleIndexAsf |
+ PEXSurfaceColourAsf | PEXSurfaceInterpAsf |
+ PEXReflectionModelAsf | PEXReflectionAttrAsf |
+ PEXBfInteriorStyleAsf | PEXBfInteriorStyleIndexAsf |
+ PEXBfSurfaceColourAsf | PEXBfSurfaceInterpAsf |
+ PEXBfReflectionModelAsf | PEXBfReflectionAttrAsf |
+ PEXSurfaceApproxAsf))) {
+ if ((InquireLUTEntryAddress(PEXInteriorBundleLUT,
+ pRend->lut[PEXInteriorBundleLUT],
+ pddc->Dynamic->pPCAttr->intIndex,
+ &status, (ddPointer *) (&intbundle)))
+ == PEXLookupTableError)
+ return (PEXLookupTableError);
+ }
+ /* Update DDC rendering attributes if bundled */
+ /* always try to set the color */
+ if (!MI_DDC_IS_HIGHLIGHT(pddc)) {
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXSurfaceColourAsf) == PEXBundled) {
+ miConvertColor(pRend,
+ &intbundle->real_entry.surfaceColour,
+ pddc->Dynamic->pPCAttr->rdrColourModel,
+ &pddc->Static.attrs->surfaceColour);
+ } else {
+ miConvertColor(pRend,
+ &pddc->Dynamic->pPCAttr->surfaceColour,
+ pddc->Dynamic->pPCAttr->rdrColourModel,
+ &pddc->Static.attrs->surfaceColour);
+ }
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXBfSurfaceColourAsf) == PEXBundled) {
+ miConvertColor(pRend,
+ &intbundle->real_entry.bfSurfaceColour,
+ pddc->Dynamic->pPCAttr->rdrColourModel,
+ &pddc->Static.attrs->bfSurfColour);
+ } else {
+ miConvertColor(pRend,
+ &pddc->Dynamic->pPCAttr->bfSurfColour,
+ pddc->Dynamic->pPCAttr->rdrColourModel,
+ &pddc->Static.attrs->bfSurfColour);
+ }
+
+ }
+ /* only set these if it's the bundle that changed */
+ if ((tables & PEXDynInteriorBundle) ||
+ (tables & PEXDynInteriorBundleContents)) {
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXSurfaceInterpAsf)
+ == PEXBundled)
+ pddc->Static.attrs->surfInterp =
+ intbundle->real_entry.surfaceInterp;
+ else
+ pddc->Static.attrs->surfInterp =
+ pddc->Dynamic->pPCAttr->surfInterp;
+
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXReflectionModelAsf)
+ == PEXBundled)
+ pddc->Static.attrs->reflModel =
+ intbundle->real_entry.reflectionModel;
+ else
+ pddc->Static.attrs->reflModel =
+ pddc->Dynamic->pPCAttr->reflModel;
+
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXReflectionAttrAsf)
+ == PEXBundled){
+ pddc->Static.attrs->reflAttr =
+ intbundle->real_entry.reflectionAttr;
+ miConvertColor(pRend,
+ &intbundle->real_entry.reflectionAttr.specularColour,
+ pddc->Dynamic->pPCAttr->rdrColourModel,
+ &pddc->Static.attrs->reflAttr.specularColour);
+ } else {
+ pddc->Static.attrs->reflAttr = pddc->Dynamic->pPCAttr->reflAttr;
+ miConvertColor(pRend,
+ &pddc->Dynamic->pPCAttr->reflAttr.specularColour,
+ pddc->Dynamic->pPCAttr->rdrColourModel,
+ &pddc->Static.attrs->reflAttr.specularColour);
+ }
+
+
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXInteriorStyleAsf)
+ == PEXBundled)
+ pddc->Static.attrs->intStyle =
+ intbundle->real_entry.interiorStyle;
+ else
+ pddc->Static.attrs->intStyle = pddc->Dynamic->pPCAttr->intStyle;
+
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXBfSurfaceInterpAsf)
+ == PEXBundled)
+ pddc->Static.attrs->bfSurfInterp =
+ intbundle->real_entry.bfSurfaceInterp;
+ else
+ pddc->Static.attrs->bfSurfInterp =
+ pddc->Dynamic->pPCAttr->bfSurfInterp;
+
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXBfReflectionModelAsf)
+ == PEXBundled)
+ pddc->Static.attrs->bfReflModel =
+ intbundle->real_entry.bfReflectionModel;
+ else
+ pddc->Static.attrs->bfReflModel =
+ pddc->Dynamic->pPCAttr->bfReflModel;
+
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXBfReflectionAttrAsf)
+ == PEXBundled){
+ pddc->Static.attrs->bfReflAttr =
+ intbundle->real_entry.bfReflectionAttr;
+ miConvertColor(pRend,
+ &intbundle->real_entry.bfReflectionAttr.specularColour,
+ pddc->Dynamic->pPCAttr->rdrColourModel,
+ &pddc->Static.attrs->bfReflAttr.specularColour);
+ } else {
+ pddc->Static.attrs->bfReflAttr =
+ pddc->Dynamic->pPCAttr->bfReflAttr;
+ miConvertColor(pRend,
+ &pddc->Dynamic->pPCAttr->bfReflAttr.specularColour,
+ pddc->Dynamic->pPCAttr->rdrColourModel,
+ &pddc->Static.attrs->bfReflAttr.specularColour);
+ }
+
+
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXBfInteriorStyleAsf)
+ == PEXBundled)
+ pddc->Static.attrs->bfIntStyle =
+ intbundle->real_entry.bfInteriorStyle;
+ else
+ pddc->Static.attrs->bfIntStyle =
+ pddc->Dynamic->pPCAttr->bfIntStyle;
+
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXSurfaceApproxAsf)
+ == PEXBundled)
+ pddc->Static.attrs->surfApprox =
+ intbundle->real_entry.surfaceApprox;
+ else
+ pddc->Static.attrs->surfApprox =
+ pddc->Dynamic->pPCAttr->surfApprox;
+ }
+ pddc->Static.misc.flags |= FILLAREAGCFLAG;
+ }
+
+ /*
+ * Surface edge Attributes
+ */
+ if ((tables & PEXDynEdgeBundle) ||
+ (tables & PEXDynEdgeBundleContents) ||
+ colors) {
+ if (~(pddc->Dynamic->pPCAttr->asfs
+ & (PEXSurfaceEdgeTypeAsf | PEXSurfaceEdgeWidthAsf |
+ PEXSurfaceEdgeColourAsf | PEXSurfaceEdgesAsf))) {
+ if ((InquireLUTEntryAddress(PEXEdgeBundleLUT,
+ pRend->lut[PEXEdgeBundleLUT],
+ pddc->Dynamic->pPCAttr->edgeIndex,
+ &status, (ddPointer *) (&edgebundle)))
+ == PEXLookupTableError)
+ return (PEXLookupTableError);
+ }
+ /* always try to set the color */
+ if (!MI_DDC_IS_HIGHLIGHT(pddc)) {
+
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXSurfaceEdgeColourAsf) == PEXBundled) {
+ miConvertColor(pRend,
+ &edgebundle->real_entry.edgeColour,
+ pddc->Dynamic->pPCAttr->rdrColourModel,
+ &pddc->Static.attrs->edgeColour);
+ } else {
+ miConvertColor(pRend,
+ &pddc->Dynamic->pPCAttr->edgeColour,
+ pddc->Dynamic->pPCAttr->rdrColourModel,
+ &pddc->Static.attrs->edgeColour);
+ }
+ }
+ /* only set these if it's the bundle that changed */
+ if ((tables & PEXDynEdgeBundle) ||
+ (tables & PEXDynEdgeBundleContents)) {
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXSurfaceEdgesAsf) == PEXBundled)
+ pddc->Static.attrs->edges = edgebundle->real_entry.edges;
+ else
+ pddc->Static.attrs->edges = pddc->Dynamic->pPCAttr->edges;
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXSurfaceEdgeTypeAsf) == PEXBundled)
+ pddc->Static.attrs->edgeType = edgebundle->real_entry.edgeType;
+ else
+ pddc->Static.attrs->edgeType = pddc->Dynamic->pPCAttr->edgeType;
+
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXSurfaceEdgeWidthAsf) == PEXBundled)
+ pddc->Static.attrs->edgeWidth = edgebundle->real_entry.edgeWidth;
+ else
+ pddc->Static.attrs->edgeWidth = pddc->Dynamic->pPCAttr->edgeWidth;
+ }
+ pddc->Static.misc.flags |= EDGEGCFLAG;
+ }
+
+ /*
+ * View table
+ */
+ if ((attrs & PEXDynNpcSubvolume) || (attrs & PEXDynViewport)) {
+ extern ddpex3rtn miBldViewport_xform();
+
+ miBldViewport_xform(pRend, pRend->pDrawable,
+ pddc->Static.misc.viewport_xform, pddc );
+ }
+ if ((tables & PEXDynViewTable) || (tables & PEXDynViewTableContents)) {
+ extern ddpex3rtn miBldCC_xform();
+
+ miBldCC_xform(pRend, pddc);
+ }
+
+ /* the echo colour change always take places */
+ pddc->Static.attrs->echoColour = pRend->echoColour;
+
+ /* If the echo mode changes, we have to change all these GCs */
+ if( attrs & PEXDynEchoMode )
+ {
+ pddc->Static.attrs->echoMode = pRend->echoMode;
+ pddc->Static.misc.flags |= POLYLINEGCFLAG;
+ pddc->Static.misc.flags |= MARKERGCFLAG;
+ pddc->Static.misc.flags |= FILLAREAGCFLAG;
+ pddc->Static.misc.flags |= EDGEGCFLAG;
+ pddc->Static.misc.flags |= TEXTGCFLAG;
+ }
+
+ /*
+ * Set the Clip List in each GC if there are any
+ * all GCs are defined at the same time so check if any one exists
+ */
+ if ((attrs & PEXDynClipList) && pddc->Static.misc.pPolylineGC)
+ {
+
+ extern int SetClipRects();
+ extern void ValidateGC();
+ xRectangle *xrects, *p;
+ ddDeviceRect *ddrects;
+ ddLONG numrects;
+ XID gcval;
+ int i;
+
+ numrects = pRend->clipList->numObj;
+ if (numrects) {
+ ddrects = (ddDeviceRect *) pRend->clipList->pList;
+ xrects = (xRectangle*) xalloc(numrects * sizeof(xRectangle));
+ if (!xrects) return BadAlloc;
+ /* Need to convert to XRectangle format */
+ for (i = 0, p = xrects; i < numrects; i++, p++, ddrects++) {
+ p->x = ddrects->xmin;
+ p->y = pRend->pDrawable->height - ddrects->ymax;
+ p->width = ddrects->xmax - ddrects->xmin + 1;
+ p->height = ddrects->ymax - ddrects->ymin + 1;
+ }
+
+ SetClipRects(pddc->Static.misc.pPolylineGC, 0, 0,
+ (int)numrects, xrects, Unsorted);
+ SetClipRects(pddc->Static.misc.pFillAreaGC, 0, 0,
+ (int)numrects, xrects, Unsorted);
+ SetClipRects(pddc->Static.misc.pEdgeGC, 0, 0,
+ (int)numrects, xrects, Unsorted);
+ SetClipRects(pddc->Static.misc.pPolyMarkerGC, 0, 0,
+ (int)numrects, xrects, Unsorted);
+ SetClipRects(pddc->Static.misc.pTextGC, 0, 0,
+ (int)numrects, xrects, Unsorted);
+ xfree((char*)xrects);
+ }
+ else {
+ gcval = None;
+ ChangeGC(pddc->Static.misc.pPolylineGC, GCClipMask, &gcval);
+ ChangeGC(pddc->Static.misc.pFillAreaGC, GCClipMask, &gcval);
+ ChangeGC(pddc->Static.misc.pEdgeGC, GCClipMask, &gcval);
+ ChangeGC(pddc->Static.misc.pPolyMarkerGC, GCClipMask, &gcval);
+ ChangeGC(pddc->Static.misc.pTextGC, GCClipMask, &gcval);
+ }
+ ValidateGC(pRend->pDrawable, pddc->Static.misc.pPolylineGC);
+ ValidateGC(pRend->pDrawable, pddc->Static.misc.pFillAreaGC);
+ ValidateGC(pRend->pDrawable, pddc->Static.misc.pEdgeGC);
+ ValidateGC(pRend->pDrawable, pddc->Static.misc.pPolyMarkerGC);
+ ValidateGC(pRend->pDrawable, pddc->Static.misc.pTextGC);
+ }
+
+ return (Success);
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level2/miBldXform.c b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miBldXform.c
new file mode 100644
index 000000000..9bca71000
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miBldXform.c
@@ -0,0 +1,709 @@
+/* $TOG: miBldXform.c /main/8 1998/02/10 12:40:42 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name Sun Microsystems not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level2/miBldXform.c,v 3.5 1998/10/04 09:34:16 dawes Exp $ */
+
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "miLUT.h"
+#include "PEXErr.h"
+#include "pixmap.h"
+#include "windowstr.h"
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "regionstr.h"
+#include "miscstruct.h"
+#include "miRender.h"
+#include "pexos.h"
+
+/* External variables and functions */
+extern void miMatMult();
+extern void miMatCopy();
+extern ddpex3rtn InquireLUTEntryAddress();
+extern void SetViewportClip();
+
+
+/*++
+ |
+ | Function Name: miBldViewport_xform
+ |
+ | Function Description:
+ | Computes the viewport_xform with special handling for the ddc.
+ | This is used for setting up for drawing, picking, searching,
+ | and MapDCtoWC/MapWCtoDC
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+miBldViewport_xform(pRend, pDrawable, xform, pddc )
+ ddRendererPtr pRend; /* renderer handle */
+ DrawablePtr pDrawable; /* pointer to X drawable */
+ ddFLOAT xform[4][4]; /* returned transform */
+ miDDContext *pddc; /* dd context handle */
+{
+
+ ddFLOAT Sx, Sy, Sz;
+ ddFLOAT Sxy;
+ ddFLOAT Tx, Ty, Tz;
+
+ /*
+ * Determine the npc -> dc viewport transform. Let's represent
+ * this transform as follows :
+ *
+ * Sx 0 0 0
+ * 0 Sy 0 0
+ * 0 0 Sz 0
+ * Tx Ty Tz 1
+ *
+ * There are two components to this transformation.
+ *
+ * NOTE THAT THE TRANSLATION COMPONENTS DETERMINED IN THE BeginRenderi
+ng
+ * CODE ARE DIFFERENT FOR THE PICKING CASE. WE USE THE PHIGS DC SPACE
+ * TO REPRESENT THE PICK APERTURE AS OPPOSED TO THE X'S SCREEN SPACE.
+ *
+ *
+ * The elements Sx, Sy, Tx, and Ty are computed in two stages as
+ * follows :
+ *
+ * First, the npc subvolume in the renderer determines
+ * the subvolume that is projected onto the viewport.
+ * This tranformation is implemented by "magnifying" this
+ * subvolume to the range (0, 0, 0)-(1,1,1)
+ *
+ * NPC space "magnified" space
+ *
+ * +-----+(c,d) +--------+(1,1)
+ * | | | |
+ * | | <====> | |
+ * | | | |
+ * (a,b)+-----+ (0,0)+--------+
+ *
+ * 1/(c-a) 0 0
+ * 0 1/(d-b) 0
+ * -a/(c-a) -b/(d-b) 0
+ *
+ */
+ /*
+ * Initialize the scaling components Sx, Sy, and Sz.
+ *
+ */
+
+ Sx = 1/(pRend->npcSubvolume.maxval.x - pRend->npcSubvolume.minval.x);
+ Sy = 1/(pRend->npcSubvolume.maxval.y - pRend->npcSubvolume.minval.y);
+ Sz = 1/(pRend->npcSubvolume.maxval.z - pRend->npcSubvolume.minval.z);
+
+ /*
+ * Secondly, if the useDrawable flag in the viewport is set, then
+ * get the min and max of the drawable from the pDrawable passed
+ * and store it in the viewport as the default values. Otherwise,
+ * the values are as available in the viewport slot of renderer
+ * context already set up. Note that the same aspect ratio limitation
+ * used above also applies to the viewport transform.
+ */
+ memcpy( (char *) xform, (char *) ident4x4, 16 * sizeof(ddFLOAT));
+
+ if (pRend->viewport.useDrawable) { /* Use the drawable width and height */
+ /* FOR RENDERING:
+ * Note that The origin is always 0,0 since ddx points
+ * are specified relative to the window origin
+ * Lastly, note that the screen origin is at the upper left
+ * corner of the window, the viewing space origin is at the
+ * lower left corner. To "flip" the coordinates to match
+ * the screen space, apply the following transform:
+ *
+ * 1 0 0 0
+ * 0 -1 0 0
+ * 0 0 1 0
+ * 0 window_y_max 0 0
+ *
+ *
+ * ie y' = (window_y_max - y)
+ *
+ */
+ /* FOR PICKING:
+ * Note that The origin is always 0,0 since DC points
+ * are specified relative to the window origin. The
+ * required transform is :
+ *
+ * Sx 0 0 0
+ * 0 Sy 0 0
+ * 0 0 1 0
+ * 0 0 0 0
+ *
+ */
+ /*
+ * Modify the scaling components Sx and Sy to include the second
+ * transform as follows :
+ */
+
+ Sx *= (ddFLOAT)pDrawable->width;
+ Sy *= (ddFLOAT)pDrawable->height;
+
+ /*
+ * Initialize the translation components Tx, Ty and Tz
+ * Note the difference for picking and searching from
+ * drawing. drawing flips the y value. the others don't
+ */
+
+ Tx = 0.0;
+ if ((pRend->render_mode == MI_REND_PICKING) || (!pddc))
+ Ty = 0.0;
+ else if ((pRend->render_mode == MI_REND_DRAWING) && (pddc))
+ Ty = pDrawable->height;
+ Tz = 0.0;
+
+ } else {
+
+ xRectangle viewport;
+
+ /* FOR RENDERING:
+ * Limit the rendering for each of the GC's to the viewport
+ * Note that The origin is always 0,0 since ddx points
+ * are specified relative to the window origin
+ * Lastly, note that the screen origin is at the upper left
+ * corner of the window, the viewing space origin is at the
+ * lower left corner. Furthermore, primitives must also be
+ * translated from this lower left origin to the viewport origin.
+ * To "flip" the coordinates to match the screen space, apply
+ * the following transform:
+ *
+ * 1 0 0 0
+ * 0 -1 0 0
+ * 0 0 1 0
+ * viewport_origin_x (window_y_max - viewport_origin_y) 0 0
+ *
+ *
+ * ie y' = (window_y_max - viewport_origin_y - y)
+ *
+ * Lastly, note that the origin of the clipping rectangle for
+ * ddx is relative to the upper left corner of the rectangle,
+ * thus this corner must still be further offset by the viewport
+ * height.
+ *
+ */
+ /* FOR PICKING:
+ * Limit the picking for each of the primitives to the viewport
+ * Note that The origin is always 0,0 since DC points
+ * are specified relative to the window origin. The required
+ * transform is :
+ *
+ * Sx 0 0 0
+ * 0 Sy 0 0
+ * 0 0 1 0
+ * Tx Ty 0 0
+ *
+ */
+ /* FOR SEARCHING: (this is called when initializing the renderer)
+ * there is no drawable, so work around that. None of what this
+ * procedure does is needed for searching, so there may be a better
+ * way to deal with this.
+ */
+ viewport.width = pRend->viewport.maxval.x - pRend->viewport.minval.x;
+ viewport.height = pRend->viewport.maxval.y - pRend->viewport.minval.y;
+
+ viewport.x = pRend->viewport.minval.x;
+ if (pDrawable)
+ viewport.y = pDrawable->height -
+ pRend->viewport.minval.y -
+ viewport.height;
+ else
+ viewport.y = 0;
+
+ /*
+ * Modify the scaling components Sx and Sy to include the second
+ * transform as follows :
+ */
+
+ Sx *= (ddFLOAT)viewport.width;
+ Sy *= (ddFLOAT)viewport.height;
+
+ /*
+ * Initialize the translation components Tx, Ty and Tz.
+ */
+
+ Tx = (ddFLOAT)pRend->viewport.minval.x;
+
+ if ((pRend->render_mode == MI_REND_PICKING) || (!pddc))
+ Ty = (ddFLOAT)pRend->viewport.minval.y;
+ else if ((pRend->render_mode == MI_REND_DRAWING) && (pddc))
+ if (pDrawable)
+ Ty = (ddFLOAT)(pDrawable->height - pRend->viewport.minval.y);
+ else Ty = 0.0;
+ Tz = 0.0;
+
+ if ((pRend->render_mode == MI_REND_DRAWING) && pDrawable && pddc) {
+ /* Set the GC clip mask to clip to the viewport */
+
+ ddLONG numrects = pRend->clipList->numObj;
+
+ if (numrects > 0) {
+ xRectangle *xrects, *p;
+ ddDeviceRect *ddrects;
+ RegionPtr clipRegion;
+ RegionRec tempRegion;
+ GCPtr pGC;
+ BoxRec box;
+ int i;
+
+ ddrects = (ddDeviceRect *) pRend->clipList->pList;
+ xrects = (xRectangle*) xalloc (numrects * sizeof(xRectangle));
+ if (!xrects) return BadAlloc;
+ /* Need to convert to XRectangle format */
+ for (i = 0, p = xrects; i < numrects; i++, p++, ddrects++) {
+ p->x = ddrects->xmin;
+ p->y = pRend->pDrawable->height - ddrects->ymax;
+ p->width = ddrects->xmax - ddrects->xmin + 1;
+ p->height = ddrects->ymax - ddrects->ymin + 1;
+ }
+
+ /*
+ * Compute the intersection of the viewport and the GC's
+ * clip region. Note that there is a GC for each of the
+ * primitive types, and we only have to compute the
+ * intersected region for one of them. This computed region
+ * will be good for all of the GC's.
+ */
+
+ pGC = pddc->Static.misc.pPolylineGC;
+
+ clipRegion = RECTS_TO_REGION(pGC->pScreen, numrects,
+ xrects, Unsorted);
+
+ xfree((char *) xrects);
+
+ box.x1 = viewport.x;
+ box.y1 = viewport.y;
+ box.x2 = viewport.x + viewport.width;
+ box.y2 = viewport.y + viewport.height;
+
+ REGION_INIT(pGC->pScreen, &tempRegion, &box, 1);
+ REGION_INTERSECT(pGC->pScreen, clipRegion, clipRegion, &tempRegion);
+ REGION_UNINIT(pGC->pScreen, &tempRegion);
+
+
+ /*
+ * Now set the GC clip regions.
+ */
+
+ SetViewportClip (pddc->Static.misc.pPolylineGC, clipRegion);
+ SetViewportClip (pddc->Static.misc.pFillAreaGC, clipRegion);
+ SetViewportClip (pddc->Static.misc.pEdgeGC, clipRegion);
+ SetViewportClip (pddc->Static.misc.pPolyMarkerGC, clipRegion);
+ SetViewportClip (pddc->Static.misc.pTextGC, clipRegion);
+
+ REGION_DESTROY(pGC->pScreen, clipRegion);
+ }
+ else {
+ SetClipRects(pddc->Static.misc.pPolylineGC,
+ 0, 0, 1, &viewport,YXBanded);
+ SetClipRects(pddc->Static.misc.pFillAreaGC,
+ 0, 0, 1, &viewport,YXBanded);
+ SetClipRects(pddc->Static.misc.pEdgeGC,
+ 0, 0, 1, &viewport,YXBanded);
+ SetClipRects(pddc->Static.misc.pPolyMarkerGC,
+ 0, 0, 1, &viewport,YXBanded);
+ SetClipRects(pddc->Static.misc.pTextGC,
+ 0, 0, 1, &viewport,YXBanded);
+ }
+ }
+ }
+
+ /*
+ * Note that Phigs requires that aspect ratio be maintained.
+ * Therefore, choose the minimum X or y ratio to represent the
+ * x and y view port scaling factor. Note that Z is exempt
+ * from this aspect ratio restriction.
+ */
+ Sxy = (Sx < Sy) ? Sx : Sy;
+
+ /*
+ * Finally, set the viewport transform components using Sxy, Sz,
+ * and the initial Tx, Ty, Tz modified suitably.
+ */
+
+ xform[0][0]= Sxy;
+ /* Negate the value to "flip" the screen (see above), IF WE ARE */
+ /* RENDERING. On the other hand, since we are PICKING, we need */
+ /* the PHIGS DC, i.e., the lower left is the origin and NO FLIP */
+ /* of y is required. */
+ /* In case pddc is NULL, this routine is being called from Map- */
+ /* DcWc and the situation is similar to PICKING. i.e., No y flip*/
+ /* is required. */
+ if ((pRend->render_mode == MI_REND_PICKING) || (!pddc))
+ xform[1][1]= Sxy;
+ else if ((pRend->render_mode == MI_REND_DRAWING) && (pddc))
+ xform[1][1]= -Sxy;
+ xform[2][2]= Sz;
+
+ xform[0][3] = Tx - (pRend->npcSubvolume.minval.x * Sxy);
+
+ /* Note, the "+" compensates for negating the [1][1] term above */
+ if ((pRend->render_mode == MI_REND_PICKING) || (!pddc))
+ xform[1][3]= Ty - (pRend->npcSubvolume.minval.y * Sxy);
+ else if ((pRend->render_mode == MI_REND_DRAWING) && (pddc))
+ xform[1][3]= Ty + (pRend->npcSubvolume.minval.y * Sxy);
+
+ xform[2][3]= Tz - (pRend->npcSubvolume.minval.z * Sz);
+
+ /* Mark as invalid appropriate inverse transforms in dd context */
+ if (pddc)
+ pddc->Static.misc.flags |= ( INVTRCCTODCXFRMFLAG );
+
+}
+
+/*++
+ |
+ | Function Name: miBldCC_xform
+ |
+ | Function Description:
+ | Computes the transformation to go from NPC to the PEX-SI's
+ | clipping space.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+miBldCC_xform(pRend, pddc)
+ ddRendererPtr pRend; /* renderer handle */
+ miDDContext *pddc; /* dd context handle */
+
+{
+
+ ddNpcSubvolume *cliplimits;
+ miViewEntry *viewbundle;
+ ddFLOAT cc_to_npc[4][4];
+ ddUSHORT status;
+
+ /*
+ * Check if a view LUT is available and accordingly, get the view
+ * matrices either from the view LUT or from the defaults.
+ */
+
+ if (!(pRend->lut[PEXViewLUT])) { /* Use defaults */
+
+ memcpy( (char *) pddc->Dynamic->npc_to_cc_xform,
+ (char *) ident4x4,
+ 16 * sizeof(ddFLOAT));
+ pddc->Dynamic->npc_to_cc_xform[0][0] = 2.0;
+ pddc->Dynamic->npc_to_cc_xform[1][1] = 2.0;
+ pddc->Dynamic->npc_to_cc_xform[2][2] = 2.0;
+ pddc->Dynamic->npc_to_cc_xform[0][3] = -1.0;
+ pddc->Dynamic->npc_to_cc_xform[1][3] = -1.0;
+ pddc->Dynamic->npc_to_cc_xform[2][3] = -1.0;
+
+ memcpy( (char *) pddc->Dynamic->wc_to_npc_xform,
+ (char *) ident4x4,
+ 16*(sizeof(ddFLOAT)));
+
+ memcpy( (char *) cc_to_npc,
+ (char *) ident4x4,
+ 16 * sizeof(ddFLOAT));
+ cc_to_npc[0][0] = 0.5;
+ cc_to_npc[1][1] = 0.5;
+ cc_to_npc[2][2] = 0.5;
+ cc_to_npc[0][3] = 0.5;
+ cc_to_npc[1][3] = 0.5;
+ cc_to_npc[2][3] = 0.5;
+
+/* THIS SHOULD GO AWAY EVENTUALLY... */
+pddc->Dynamic->clipFlags = 0;
+
+ } else {
+
+ /* Get the view table entry at current view index first */
+
+ if ((InquireLUTEntryAddress (PEXViewLUT, pRend->lut[PEXViewLUT],
+ pddc->Dynamic->pPCAttr->viewIndex,
+ &status, (ddPointer *)(&viewbundle)))
+ == PEXLookupTableError)
+ return (PEXLookupTableError);
+
+ miMatCopy(viewbundle->vom, pddc->Dynamic->wc_to_npc_xform);
+
+/* THIS SHOULD GO AWAY EVENTUALLY... */
+pddc->Dynamic->clipFlags = viewbundle->entry.clipFlags;
+
+ if (viewbundle->entry.clipFlags)
+ {
+ /* Use the clip limits as set up in the current view */
+
+ cliplimits = &viewbundle->entry.clipLimits;
+ /*
+ * Compute the npc_to_cc & cc_to_npc
+ * transformations.
+ * The Pex view clipper can only clip against a cube with
+ * corners (-1,-1,-1) (1,1,1).
+ * It is therefore necessary to append an additional
+ * transformation to the wc_to_cc_xform transform such
+ * that the view clip volume is transformed to this cube,
+ * rather than leave the space untouched and clip against actual
+ * clip planes specified in the view lut.
+ * Note that this transformation must be undone by the
+ * subsequent cc_to_dc_xform, so the inverse of this
+ * matrix is pre-pended to this transform.
+ *
+ * two matrices then (note these extend trivially into 3D):
+ *
+ * NPC subvolume SI clipping space
+ *
+ * +-----+(c,d) +--------+(1,1)
+ * | | | |
+ * | | <====> | |
+ * | | | |
+ * (a,b)+-----+ (-1,-1)+--------+
+ *
+ * npc_to_clip: 2/(c-a) 0 0
+ * 0 2/(d-b) 0
+ * (c+a)/(a-c) (d+b)/b-d) 0
+ *
+ * clip_to_npc: (c-a)/2 0 0
+ * 0 (d-b)/2 0
+ * (c+a)/2 (d+b)/2 0
+ *
+ * Last, note that the cliplimits from the view table entry are only
+ * used if enabled by the clip flags.
+ */
+ memcpy( (char *) pddc->Dynamic->npc_to_cc_xform,
+ (char *) ident4x4, 16 * sizeof(ddFLOAT));
+
+ memcpy( (char *) cc_to_npc,
+ (char *) ident4x4, 16 * sizeof(ddFLOAT));
+
+ /* set up X & Y clip limits */
+
+ if (viewbundle->entry.clipFlags & PEXClipXY) {
+ pddc->Dynamic->npc_to_cc_xform[0][0] =
+ 2.0/(cliplimits->maxval.x - cliplimits->minval.x);
+ pddc->Dynamic->npc_to_cc_xform[1][1] =
+ 2.0/(cliplimits->maxval.y - cliplimits->minval.y);
+ pddc->Dynamic->npc_to_cc_xform[0][3] =
+ (cliplimits->maxval.x + cliplimits->minval.x) /
+ (cliplimits->minval.x - cliplimits->maxval.x);
+ pddc->Dynamic->npc_to_cc_xform[1][3] =
+ (cliplimits->maxval.y + cliplimits->minval.y) /
+ (cliplimits->minval.y - cliplimits->maxval.y);
+
+ cc_to_npc[0][0] =
+ (cliplimits->maxval.x - cliplimits->minval.x)/2.0;
+ cc_to_npc[1][1] =
+ (cliplimits->maxval.y - cliplimits->minval.y)/2.0;
+ cc_to_npc[0][3] =
+ (cliplimits->maxval.x + cliplimits->minval.x)/2.0;
+ cc_to_npc[1][3] =
+ (cliplimits->maxval.y + cliplimits->minval.y)/2.0;
+ } else {
+
+ /* Use default NPC clip limits (0.0 <-> 1.0) */
+
+ pddc->Dynamic->npc_to_cc_xform[0][0] = 2.0/(1.0 - 0.0);
+ pddc->Dynamic->npc_to_cc_xform[1][1] = 2.0/(1.0 - 0.0);
+ pddc->Dynamic->npc_to_cc_xform[0][3] = (1.0 + 0.0)/(0.0 - 1.0);
+ pddc->Dynamic->npc_to_cc_xform[1][3] = (1.0 + 0.0)/(0.0 - 1.0);
+
+ cc_to_npc[0][0] = (1.0 - 0.0)/2.0;
+ cc_to_npc[1][1] = (1.0 - 0.0)/2.0;
+ cc_to_npc[0][3] = (1.0 + 0.0)/2.0;
+ cc_to_npc[1][3] = (1.0 + 0.0)/2.0;
+ }
+
+ /* Now, front & back clip limits */
+
+ if ( (viewbundle->entry.clipFlags & PEXClipFront) &&
+ (viewbundle->entry.clipFlags & PEXClipBack) ) {
+
+ /* Both front and back clipping on */
+
+ pddc->Dynamic->npc_to_cc_xform[2][2] =
+ 2.0/(cliplimits->maxval.z - cliplimits->minval.z);
+ pddc->Dynamic->npc_to_cc_xform[2][3] =
+ (cliplimits->maxval.z + cliplimits->minval.z) /
+ (cliplimits->minval.z - cliplimits->maxval.z);
+
+ cc_to_npc[2][2] =
+ (cliplimits->maxval.z - cliplimits->minval.z)/2.0;
+ cc_to_npc[2][3] =
+ (cliplimits->maxval.z + cliplimits->minval.z)/2.0;
+
+ } else if (viewbundle->entry.clipFlags & PEXClipFront) {
+
+ /* Only front clipping ON; Use default NPC Back value */
+
+ pddc->Dynamic->npc_to_cc_xform[2][2] =
+ 2.0/(1.0 - cliplimits->minval.z);
+ pddc->Dynamic->npc_to_cc_xform[2][3] =
+ (1.0 + cliplimits->minval.z) /
+ (cliplimits->minval.z - 1.0);
+
+ cc_to_npc[2][2] =
+ (1.0 - cliplimits->minval.z)/2.0;
+ cc_to_npc[2][3] =
+ (1.0 + cliplimits->minval.z)/2.0;
+
+ } else if (viewbundle->entry.clipFlags & PEXClipBack) {
+
+ /* Only back clipping ON; Use default NPC Front value */
+
+ pddc->Dynamic->npc_to_cc_xform[2][2] = 2.0/(cliplimits->maxval.z);
+ pddc->Dynamic->npc_to_cc_xform[2][3] = -1.0;
+
+ cc_to_npc[2][2] = (cliplimits->maxval.z)/2.0;
+ cc_to_npc[2][3] = (cliplimits->maxval.z)/2.0;
+
+ } else {
+
+ /* Both front and back clipping OFF; Use default NPC space */
+
+ pddc->Dynamic->npc_to_cc_xform[2][2] = 2.0/(1.0 - 0.0);
+ pddc->Dynamic->npc_to_cc_xform[2][3] = (1.0 + 0.0) / (0.0 - 1.0);
+
+ cc_to_npc[2][2] = (1.0 - 0.0)/2.0;
+ cc_to_npc[2][3] = (1.0 + 0.0)/2.0;
+ }
+
+ }
+ else /* All clipping OFF; Use the entire NPC space, i.e., (0,0,0) */
+ /* to (1,1,1) */
+ {
+
+ memcpy( (char *) pddc->Dynamic->npc_to_cc_xform,
+ (char *) ident4x4, 16 * sizeof(ddFLOAT));
+ pddc->Dynamic->npc_to_cc_xform[0][0] = 2.0;
+ pddc->Dynamic->npc_to_cc_xform[1][1] = 2.0;
+ pddc->Dynamic->npc_to_cc_xform[2][2] = 2.0;
+ pddc->Dynamic->npc_to_cc_xform[0][3] = -1.0;
+ pddc->Dynamic->npc_to_cc_xform[1][3] = -1.0;
+ pddc->Dynamic->npc_to_cc_xform[2][3] = -1.0;
+
+ memcpy( (char *) cc_to_npc,
+ (char *) ident4x4, 16 * sizeof(ddFLOAT));
+ cc_to_npc[0][0] = 0.5;
+ cc_to_npc[1][1] = 0.5;
+ cc_to_npc[2][2] = 0.5;
+ cc_to_npc[0][3] = 0.5;
+ cc_to_npc[1][3] = 0.5;
+ cc_to_npc[2][3] = 0.5;
+
+ }
+ }
+
+ /*
+ * Compute the various composites stored in the
+ * dd context.
+ */
+ /*
+ * Compute the composite cc -> dc, i.e., Clip to Device.
+ */
+ miMatMult ( pddc->Dynamic->cc_to_dc_xform,
+ cc_to_npc,
+ pddc->Static.misc.viewport_xform);
+
+ /*
+ * Compute the composite wc -> cc, i.e., World to Clip.
+ */
+ miMatMult ( pddc->Dynamic->wc_to_cc_xform,
+ pddc->Dynamic->wc_to_npc_xform,
+ pddc->Dynamic->npc_to_cc_xform);
+ /*
+ * Compute the composite mc -> wc, i.e. Modelling to World
+ */
+ miMatMult( pddc->Dynamic->mc_to_wc_xform,
+ pddc->Dynamic->pPCAttr->localMat,
+ pddc->Dynamic->pPCAttr->globalMat);
+
+ /*
+ * Compute the composite mc -> npc, i.em Modelling to NPC
+ */
+ miMatMult ( pddc->Dynamic->mc_to_npc_xform,
+ pddc->Dynamic->mc_to_wc_xform,
+ pddc->Dynamic->wc_to_npc_xform);
+
+ /*
+ * Compute the composite [VCM], i.e, Modelling to Clip.
+ */
+ miMatMult ( pddc->Dynamic->mc_to_cc_xform,
+ pddc->Dynamic->mc_to_wc_xform,
+ pddc->Dynamic->wc_to_cc_xform);
+ /*
+ * Compute the composite mc -> dc transform, i.e., Modelling to Device.
+ */
+ miMatMult ( pddc->Dynamic->mc_to_dc_xform,
+ pddc->Dynamic->mc_to_cc_xform,
+ pddc->Dynamic->cc_to_dc_xform);
+
+ /* Mark as invalid appropriate inverse transforms in dd context */
+ pddc->Static.misc.flags |= (INVTRWCTOCCXFRMFLAG | INVTRMCTOCCXFRMFLAG |
+ INVVIEWXFRMFLAG | CC_DCUEVERSION);
+
+}
+
+
+void SetViewportClip(pGC, clipRegion)
+ GCPtr pGC;
+ RegionPtr clipRegion;
+{
+ /*
+ * When we call the GC's ChangeClip function, it destroys
+ * the region we pass to it. Since this function is called
+ * for each of the GC's, we copy clipRegion into tempRegion
+ * and use tempRegion when calling ChangeClip.
+ */
+
+ RegionPtr tempRegion = REGION_CREATE(pGC->pScreen, NullBox, 0);
+
+ REGION_COPY(pGC->pScreen, tempRegion, clipRegion);
+
+ pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ pGC->clipOrg.x = 0;
+ pGC->clipOrg.y = 0;
+ pGC->stateChanges |= GCClipXOrigin|GCClipYOrigin;
+ (*pGC->funcs->ChangeClip)(pGC, CT_REGION, tempRegion, 0);
+ if (pGC->funcs->ChangeGC)
+ (*pGC->funcs->ChangeGC) (pGC, GCClipXOrigin|GCClipYOrigin|GCClipMask);
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level2/miCellArray.c b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miCellArray.c
new file mode 100644
index 000000000..b0f51733d
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miCellArray.c
@@ -0,0 +1,266 @@
+/* $TOG: miCellArray.c /main/7 1998/02/10 12:40:49 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level2/miCellArray.c,v 3.6 1998/10/04 09:34:17 dawes Exp $ */
+
+#include "mipex.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "ddpex3.h"
+#include "PEXErr.h"
+#include "miStruct.h"
+#include "PEXprotost.h"
+#include "miRender.h"
+#include "ddpex2.h"
+#include "pexos.h"
+
+
+/*++
+ |
+ | Function Name: miCellArray
+ |
+ | Function Description:
+ |
+ | Draws the outline of the cell array parallelogram using
+ | the current polyline attributes.
+ |
+ | Note(s): A whole lot-o work needs to be done in order to
+ | support full color indexing (which is really an
+ | attempt at texture mapping)
+ |
+ | The Parse routine (in pexOCParse) should be enhanced to detect
+ | whether |dR|, |dQ|, dx or dy are of zero length
+ |
+ |
+ |
+ --*/
+
+
+ddpex3rtn
+miCellArray(pRend, pExecuteOC)
+/* in */
+ ddRendererPtr pRend;
+ miGenericStr *pExecuteOC;
+
+ {
+
+/***************************************************************************/
+
+ /* calls */
+ extern ocTableType InitExecuteOCTable[];
+
+ /* Local variable definitions */
+ miGenericStr *pGStr;
+ miCellArrayStruct *ddCell = (miCellArrayStruct *)(pExecuteOC+1);
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ miListHeader *input = &ddCell->point;
+ miPolylineStruct *output;
+ listofddPoint *pddolist;
+ int point_size, nGridLines, i;
+ ddPointUnion in_pt, out_pt, Ppt, Qpt, Rpt, Spt;
+ ddpex3rtn status;
+ ddCoord3D dRpt, dQpt, x_step, y_step,
+ basept, endpt;
+ ddCoord2D tempQ, tempR;
+
+
+
+/*
+ * A Cell Array is defined by three points, P, Q, and R-> This
+ * defines a parallelogram, closed by an implied S
+ *
+ * P-----(dR)---->R
+ * \ \
+ * \ \
+ * (dQ) \
+ * \ \
+ * \ \
+ * Q--------------S (implied)
+ *
+ * S = P + dR + dQ
+ */
+
+ if (!(pGStr = (miGenericStr *) (xalloc(sizeof(miGenericStr) +
+ sizeof(miPolylineStruct)))))
+ return(BadAlloc);
+
+ pGStr->elementType = PEXOCPolylineSet;
+
+ output = (miPolylineStruct *) (pGStr + 1);
+
+ /* We need to initialize the maxLists to zero since the MI_ALLOCLISTHEADER
+ macro does reallocs only when necessary, based on this field. The
+ intent is to use the temp lists of the renderer over & over, but
+ in this case we are not getting a header from MI_NEXTTEMPDATALIST */
+
+ output->maxLists = 0;
+
+ nGridLines = (ddCell->dx) + (ddCell->dy) + 2;
+ MI_ALLOCLISTHEADER(output,MI_ROUND_LISTHEADERCOUNT(nGridLines));
+
+ point_size = sizeof(ddCoord3DL);
+ for(i = 0, pddolist = output->ddList; i < nGridLines; i++){
+ MI_ALLOCLISTOFDDPOINT(pddolist, 2, point_size);
+ pddolist++;
+ }
+
+ /* Initialize output listHeader */
+ output->type = DD_3D_POINT;
+ output->flags = input->flags;
+ output->numLists = nGridLines;
+
+ /* Get input points */
+ if (DD_IsVert3D(input->type))
+ {
+ Ppt.ptr = ddCell->point.ddList->pts.ptr;
+ Rpt.ptr = Ppt.ptr + sizeof(ddCoord3D);
+ Qpt.ptr = Rpt.ptr + sizeof(ddCoord3D);
+ }
+ else
+ {
+ Ppt.ptr = ddCell->point.ddList->pts.ptr;
+ Spt.ptr = Ppt.ptr + sizeof(ddCoord2D);
+
+ tempR.x = Spt.p2Dpt->x;
+ tempR.y = Ppt.p2Dpt->y;
+ tempQ.x = Ppt.p2Dpt->x;
+ tempQ.y = Spt.p2Dpt->y;
+
+ Rpt.p2Dpt = &tempR;
+ Qpt.p2Dpt = &tempQ;
+ }
+
+ /* Calculate DQ and DR */
+ dQpt.x = Qpt.p2Dpt->x - Ppt.p2Dpt->x;
+ dQpt.y = Qpt.p2Dpt->y - Ppt.p2Dpt->y;
+ dRpt.x = Rpt.p2Dpt->x - Ppt.p2Dpt->x;
+ dRpt.y = Rpt.p2Dpt->y - Ppt.p2Dpt->y;
+
+ /* Calculate step sizes for grid lines */
+ x_step.x = (dRpt.x / ddCell->dx);
+ x_step.y = (dRpt.y / ddCell->dx);
+ y_step.x = (dQpt.x / ddCell->dy);
+ y_step.y = (dQpt.y / ddCell->dy);
+
+ /* Add Z component if necessary */
+ if DD_IsVert3D(input->type) {
+ dQpt.z = Rpt.p3Dpt->z - Ppt.p3Dpt->z;
+ dRpt.z = Qpt.p3Dpt->z - Ppt.p3Dpt->z;
+ x_step.z = (dRpt.z / ddCell->dx);
+ y_step.z = (dRpt.z / ddCell->dy);
+ } else {
+ x_step.z = 0.0;
+ y_step.z = 0.0;
+ }
+
+ basept.x = Ppt.p2Dpt->x;
+ basept.y = Ppt.p2Dpt->y;
+ if DD_IsVert3D(input->type) basept.z = Ppt.p3Dpt->z;
+ else basept.z = 0.0;
+
+ pddolist = output->ddList;
+ /* "x" lines */
+ for(i = 0, out_pt.ptr = pddolist->pts.ptr;
+ i <= ddCell->dy; i++){
+
+ out_pt.ptr = pddolist->pts.ptr;
+ endpt.x = basept.x + dRpt.x;
+ endpt.y = basept.y + dRpt.y;
+ endpt.z = basept.z + dRpt.z;
+
+ memcpy( out_pt.ptr, (char *)&basept, point_size);
+ out_pt.ptr += point_size;
+ memcpy( out_pt.ptr, (char *)&endpt, point_size);
+ out_pt.ptr += point_size;
+
+ basept.x += y_step.x;
+ basept.y += y_step.y;
+ basept.z += y_step.z;
+
+ pddolist->numPoints = 2;
+ pddolist++;
+ }
+
+ basept.x = Ppt.p2Dpt->x;
+ basept.y = Ppt.p2Dpt->y;
+ if DD_IsVert3D(input->type) basept.z = Ppt.p3Dpt->z;
+ else basept.z = 0.0;
+
+ /* "y" lines */
+ for(i = 0; i <= ddCell->dx; i++){
+
+ out_pt.ptr = pddolist->pts.ptr;
+ endpt.x = basept.x + dQpt.x;
+ endpt.y = basept.y + dQpt.y;
+ endpt.z = basept.z + dQpt.z;
+
+ memcpy( out_pt.ptr, (char *)&basept, point_size);
+ out_pt.ptr += point_size;
+ memcpy( out_pt.ptr, (char *)&endpt, point_size);
+ out_pt.ptr += point_size;
+
+ basept.x += x_step.x;
+ basept.y += x_step.y;
+ basept.z += x_step.z;
+
+ pddolist->numPoints = 2;
+ pddolist++;
+ }
+ output->numLists = nGridLines;
+
+ /* Call Polyline routine with output array */
+ status = InitExecuteOCTable[(int)(pGStr->elementType)](pRend, pGStr);
+
+ /* clean up memory allocation */
+
+ for(i = 0, pddolist = output->ddList; i < nGridLines; i++){
+ xfree((char *)pddolist->pts.ptr);
+ pddolist++;
+ }
+ xfree((char *)output->ddList);
+ xfree((char *)pGStr);
+
+ return(status);
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level2/miClip.c b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miClip.c
new file mode 100644
index 000000000..8866cc04f
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miClip.c
@@ -0,0 +1,246 @@
+/* $TOG: miClip.c /main/5 1998/02/10 12:40:54 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level2/miClip.c,v 3.5 1998/10/04 09:34:17 dawes Exp $ */
+
+#include "mipex.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "PEXErr.h"
+#include "miRender.h"
+#include "miClip.h"
+#include "gcstruct.h"
+#include "pexos.h"
+
+
+/*++
+ |
+ | Function Name: miClipPointList
+ |
+ | Function Description:
+ | Clips each point is a listofddPoint. Clipping here means
+ | that the point is either copied or not copied to the
+ | output list.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+miClipPointList(pddc, vinput, voutput, clip_mode)
+/* in */
+ miDDContext *pddc;
+ miListHeader *vinput;
+ miListHeader **voutput;
+ ddUSHORT clip_mode;
+{
+
+/* uses */
+ char *in_pt;
+ char *out_pt;
+ miListHeader *output;
+ listofddPoint *pddilist;
+ listofddPoint *pddolist;
+ int num_lists;
+ int vert_count;
+ int num_points;
+ int point_size, clip_code;
+ int j,k, num_passes;
+ float t;
+ ddUSHORT oc, clipflags;
+ ddHalfSpace *MC_HSpace;
+
+ /* Vertex data must be homogeneous for clipper */
+ if (!(DD_IsVert4D(vinput->type))) return(1);
+
+ /* Reformat clipflags to internal format */
+ if (pddc->Dynamic->clipFlags & PEXClipXY)
+ clipflags=(MI_CLIP_LEFT | MI_CLIP_RIGHT | MI_CLIP_TOP | MI_CLIP_BOTTOM);
+ else clipflags = 0;
+ if (pddc->Dynamic->clipFlags & PEXClipFront) clipflags |= MI_CLIP_FRONT;
+ if (pddc->Dynamic->clipFlags & PEXClipBack) clipflags |= MI_CLIP_BACK;
+
+ /* Use the pre-defined clip list for output */
+ *voutput = output = MI_NEXTTEMPDATALIST(pddc);
+
+ /* Allocate an initial number of headers */
+ MI_ALLOCLISTHEADER(output, MI_ROUND_LISTHEADERCOUNT(vinput->numLists))
+ if (!output->ddList) return(BadAlloc);
+
+ output->type = vinput->type;
+ output->flags = vinput->flags;
+
+ pddilist = vinput->ddList;
+ pddolist = output->ddList;
+ DD_VertPointSize(vinput->type, point_size);
+
+ num_lists = 0;
+
+ /* Now, clip each list */
+ for (j = 0; j < vinput->numLists; j++) {
+
+ /* Skip list if no points */
+ if ((vert_count = pddilist->numPoints) <= 0) {
+ pddilist++;
+ continue;
+ }
+
+ /* Insure sufficient room for each vertex */
+ MI_ALLOCLISTOFDDPOINT(pddolist, vert_count, point_size);
+ if (!(out_pt = pddolist->pts.ptr)) return(BadAlloc);
+
+ in_pt = pddilist->pts.ptr;
+
+ num_points = 0;
+
+
+ /* For each vertex, clip a polyline segment */
+ while (vert_count--) {
+
+ /* this is really only used for annotation text, so going */
+ /* through all the half-spaces for each point is not */
+ /* a big deal */
+
+ CLIP_POINT4D(in_pt, oc, clip_mode);
+
+ if (!(oc)) {
+ /* Copy the next point into the clip array */
+ memcpy( out_pt, in_pt, point_size);
+ num_points++;
+ out_pt += point_size;
+ }
+
+ /* skip to next point */
+ in_pt += point_size;
+ }
+
+ /* skip to next list */
+ pddilist++;
+
+ /* Don't increment list count unless points were added to last list */
+ if (num_points > 0) {
+ pddolist->numPoints = num_points;
+ num_lists++;
+ pddolist++;
+ }
+ }
+
+
+ output->numLists = num_lists;
+
+ return (Success);
+
+}
+
+
+
+/*++
+ |
+ | ComputeMCVolume(pRend, pddc)
+ |
+ | Compute a modelling coordinate version of the model clipping
+ | volume;
+ |
+ --*/
+ddpex3rtn
+ComputeMCVolume(pRend, pddc)
+ ddRendererPtr pRend; /* renderer handle */
+ miDDContext *pddc;
+{
+ extern void miMatCopy();
+ extern void miMatMatInverse();
+
+ ddHalfSpace *wcHS, /* world coord half spaces */
+ mcHS; /* model coord half spaces */
+
+ int i, count;
+ float pxform[4][4]; /* point transform */
+ float vxform[4][4]; /* vector transform */
+ float length;
+
+
+ /* check to see if already computed */
+ if (pddc->Static.misc.flags & MCVOLUMEFLAG) {
+
+ /* Verify inverse transform */
+ VALIDATEINVTRMCTOWCXFRM(pddc);
+
+ /* Don't want transpose of inverse for point xform! */
+ miMatCopy(pddc->Static.misc.inv_tr_mc_to_wc_xform,
+ pxform);
+ miMatTranspose(pxform);
+
+ /* Want transpose of forward point xform for inverse vector xform */
+ miMatCopy(pddc->Dynamic->mc_to_wc_xform, vxform);
+ miMatTranspose(vxform);
+
+ count = pddc->Dynamic->pPCAttr->modelClipVolume->numObj;
+ wcHS = (ddHalfSpace *)(pddc->Dynamic->pPCAttr->modelClipVolume->pList);
+
+ pddc->Static.misc.ms_MCV->numObj = 0;
+
+ for(i = 0; i < count; i++) {
+
+ miTransformPoint(&wcHS->point, pxform,
+ &mcHS.point);
+
+ miTransformVector(&wcHS->vector, vxform, &mcHS.vector);
+
+ NORMALIZE_VECTOR(&mcHS.vector, length);
+
+ DOT_PRODUCT(&mcHS.vector, &mcHS.point, mcHS.dist);
+
+ puAddToList(&mcHS, 1, pddc->Static.misc.ms_MCV);
+
+ ++wcHS;
+
+ }
+
+ /* Clear ddc status flag */
+ pddc->Static.misc.flags &= ~MCVOLUMEFLAG;
+ }
+ return (Success);
+}
+
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level2/miConvert.c b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miConvert.c
new file mode 100644
index 000000000..65c093643
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miConvert.c
@@ -0,0 +1,954 @@
+/* $TOG: miConvert.c /main/8 1998/02/10 12:40:59 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level2/miConvert.c,v 1.7 1998/10/04 09:34:17 dawes Exp $ */
+
+#include "miLUT.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "PEXErr.h"
+#include "miRender.h"
+#include "pexos.h"
+
+
+typedef void (*ColorConversionTableType)();
+static void PEXIndexedColour_to_PEXRdrColourModelRGB();
+static void PEXRgb8Colour_to_PEXRdrColourModelRGB();
+static void PEXRgb16Colour_to_PEXRdrColourModelRGB();
+static void NoChange();
+
+/*
+ * Color conversion jump table for miConvertVertexColors,
+ * miConvertFacetColors and miConvertColor.
+ *
+ * Note that only conversions supported are
+ *
+ * indexed ->rgbFloat
+ * Rgb8 ->rgbFloat
+ * Rgb16 ->rgbFloat
+ *
+ */
+
+static
+ColorConversionTableType
+ColourConversionRoutine[(PEXRdrColourModelHLS+1)*(PEXMaxColour+1)] = {
+/* Convert to Implementation dependant Color Model */
+ PEXIndexedColour_to_PEXRdrColourModelRGB, /* Indexed -> ImpDep */
+ NoChange, /* RgbFloat -> ImpDep */
+ NULL, /* Cie -> ImpDep */
+ NULL, /* Hsv -> ImpDep */
+ NULL, /* Hls -> ImpDep */
+ PEXRgb8Colour_to_PEXRdrColourModelRGB, /* Rgb8 -> ImpDep */
+ PEXRgb16Colour_to_PEXRdrColourModelRGB, /* Rgb16 -> ImpDep */
+/* Convert to Rgb Float */
+ PEXIndexedColour_to_PEXRdrColourModelRGB, /* Indexed -> RgbFloat */
+ NoChange, /* RgbFloat -> RgbFloat */
+ NULL, /* Cie -> RgbFloat */
+ NULL, /* Hsv -> RgbFloat */
+ NULL, /* Hls -> RgbFloat */
+ PEXRgb8Colour_to_PEXRdrColourModelRGB, /* Rgb8 -> RgbFloat */
+ PEXRgb16Colour_to_PEXRdrColourModelRGB, /* Rgb16 -> RgbFloat */
+/* Convert to Cie Float */
+ NULL, /* Indexed -> CieFloat */
+ NULL, /* RgbFloat -> CieFloat */
+ NULL, /* Cie -> CieFloat */
+ NULL, /* Hsv -> CieFloat */
+ NULL, /* Hls -> CieFloat */
+ NULL, /* Rgb8 -> CieFloat */
+ NULL, /* Rgb16 -> CieFloat */
+/* Convert to Hsv Float */
+ NULL, /* Indexed -> HsvFloat */
+ NULL, /* RgbFloat -> HsvFloat */
+ NULL, /* Cie -> HsvFloat */
+ NULL, /* Hsv -> HsvFloat */
+ NULL, /* Hls -> HsvFloat */
+ NULL, /* Rgb8 -> HsvFloat */
+ NULL, /* Rgb16 -> HsvFloat */
+/* Convert to Hls Float */
+ NULL, /* Indexed -> HlsFloat */
+ NULL, /* RgbFloat -> HlsFloat */
+ NULL, /* Cie -> HlsFloat */
+ NULL, /* Hsv -> HlsFloat */
+ NULL, /* Hls -> HlsFloat */
+ NULL, /* Rgb8 -> HlsFloat */
+ NULL, /* Rgb16 -> HlsFloat */
+};
+
+/*++
+ |
+ | Function Name: PEXIndexedColour_to_PEXRdrColourModelRGB
+ |
+ | Function Description:
+ | Convert vertex colors to the specified rendering color model
+ |
+ | Note(s):
+ |
+ --*/
+
+static
+void
+PEXIndexedColour_to_PEXRdrColourModelRGB(pRend, in_col, out_col)
+ddRendererPtr pRend; /* renderer handle */
+ddIndexedColour **in_col;
+ddRgbFloatColour **out_col;
+{
+ miColourEntry *pintcolour;
+ ddUSHORT status;
+
+ InquireLUTEntryAddress (PEXColourLUT, pRend->lut[PEXColourLUT],
+ ((*in_col)++)->index,
+ &status,
+ (ddPointer *)&pintcolour);
+
+ /* Insure that LUT entry is in correct color model */
+ if (pintcolour->entry.colourType != PEXRgbFloatColour)
+ ColourConversionRoutine[pintcolour->entry.colourType*PEXRdrColourModelRGB]
+ (pRend, &pintcolour->entry.colour.rgbFloat, out_col);
+ else *((*out_col)++) = pintcolour->entry.colour.rgbFloat;
+
+}
+
+/*++
+ |
+ | Function Name: PEXRgb8Colour_to_PEXRdrColourModelRGB
+ |
+ | Function Description:
+ | Convert vertex colors to the specified rendering color model
+ |
+ | Note(s):
+ |
+ --*/
+
+static
+void
+PEXRgb8Colour_to_PEXRdrColourModelRGB(pRend, in_col, out_col)
+ddRendererPtr pRend; /* renderer handle */
+ddRgb8Colour **in_col;
+ddRgbFloatColour **out_col;
+{
+ (*out_col)->red = (*in_col)->red;
+ (*out_col)->green = (*in_col)->green;
+ ((*out_col)++)->blue = ((*in_col)++)->blue;
+}
+
+/*++
+ |
+ | Function Name: PEXRgb16Colour_to_PEXRdrColourModelRGB
+ |
+ | Function Description:
+ | Convert vertex colors to the specified rendering color model
+ |
+ | Note(s):
+ |
+ --*/
+
+static
+void
+PEXRgb16Colour_to_PEXRdrColourModelRGB(pRend, in_col, out_col)
+ddRendererPtr pRend; /* renderer handle */
+ddRgb16Colour **in_col;
+ddRgbFloatColour **out_col;
+{
+ (*out_col)->red = (*in_col)->red;
+ (*out_col)->green = (*in_col)->green;
+ ((*out_col)++)->blue = ((*in_col)++)->blue;
+}
+
+/*++
+ |
+ | Function Name: NoChange
+ |
+ | Function Description:
+ | Dummy label to indicate no color change needed.
+ |
+ | Note(s):
+ |
+ --*/
+
+static
+void
+NoChange(pRend, in_col, out_col)
+ddRendererPtr pRend; /* renderer handle */
+ddRgb16Colour **in_col;
+ddRgbFloatColour **out_col;
+{
+}
+
+/*++
+ |
+ | Function Name: miConvertColor
+ |
+ | Function Description:
+ | Converts a ddColourSpecifier to the specified rendering color model.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+miConvertColor(pRend, cinput, rdrColourModel, coutput)
+/* in */
+ddRendererPtr pRend; /* renderer handle */
+ddColourSpecifier *cinput; /* input color */
+ddSHORT rdrColourModel; /* output color model */
+/* out */
+ddColourSpecifier *coutput; /* output color */
+{
+/* uses */
+ ColorConversionTableType convert;
+ ddSHORT input_color;
+ char *icolptr;
+ char *ocolptr;
+
+ /* find proper conversion routine */
+ convert = ColourConversionRoutine[cinput->colourType*rdrColourModel];
+
+ /* convert is 1 if input and output color model are the same */
+ if (convert == NoChange) {
+ /* no conversion necessary */
+ *coutput = *cinput;
+ return Success;
+ }
+
+ /* convert is NULL if output color model not supported */
+ if (convert == NULL) {
+ return 1;
+ }
+
+ /* set output color type */
+ switch(rdrColourModel) {
+ case PEXRdrColourModelImpDep:
+ coutput->colourType = PEXRgbFloatColour;
+ break;
+ case PEXRdrColourModelRGB:
+ coutput->colourType = PEXRgbFloatColour;
+ break;
+ case PEXRdrColourModelHSV:
+ coutput->colourType = PEXHsvFloatColour;
+ break;
+ case PEXRdrColourModelHLS:
+ coutput->colourType = PEXHlsFloatColour;
+ break;
+ case PEXRdrColourModelCIE:
+ coutput->colourType = PEXCieFloatColour;
+ break;
+ }
+
+ /* convert color data */
+ icolptr = (char *)&(cinput->colour.indexed);
+ ocolptr = (char *)&(coutput->colour.indexed);
+ (*convert)(pRend, &icolptr, &ocolptr);
+
+ return (Success);
+}
+
+/*++
+ |
+ | Function Name: miConvertVertexColors
+ |
+ | Function Description:
+ | Convert vertex colors to the specified rendering color model
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+miConvertVertexColors(pRend, vinput, rdrColourModel, voutput)
+/* in */
+ddRendererPtr pRend; /* renderer handle */
+miListHeader *vinput; /* input vertex list */
+ddSHORT rdrColourModel; /* output color model */
+/* out */
+miListHeader **voutput; /* output vertex list */
+{
+/* uses */
+ ddPointUnion in_pt, out_pt;
+ miListHeader *output;
+ listofddPoint *pddilist;
+ listofddPoint *pddolist;
+ miDDContext *pddc = (miDDContext *)pRend->pDDContext;
+ int list_count = 0;
+ int vert_count;
+ int point_size, out_point_size;
+ int coord_size;
+ ddPointType type;
+ int i, j;
+ ColorConversionTableType convert;
+ ddSHORT input_color;
+
+ /* if no vertex colors, done! */
+ if (!DD_IsVertColour(vinput->type)) {
+ *voutput = vinput;
+ return Success;
+ }
+
+ /* extract vertex color type */
+ if (DD_IsVertIndexed(vinput->type)) input_color = PEXIndexedColour;
+ else if (DD_IsVertRGBFLOAT(vinput->type)) input_color = PEXRgbFloatColour;
+ else if (DD_IsVertRGB8(vinput->type)) input_color = PEXRgb8Colour;
+ else if (DD_IsVertRGB16(vinput->type)) input_color = PEXRgb16Colour;
+ else if (DD_IsVertHSV(vinput->type)) input_color = PEXHsvFloatColour;
+ else if (DD_IsVertHLS(vinput->type)) input_color = PEXHlsFloatColour;
+ else if (DD_IsVertCIE(vinput->type)) input_color = PEXCieFloatColour;
+
+ /* find proper conversion routine */
+ convert = ColourConversionRoutine[input_color*rdrColourModel];
+
+ /* convert is 1 if input and output color model are the same */
+ if (convert == NoChange) {
+ /* no conversion necessary */
+ *voutput = vinput;
+ return Success;
+ }
+
+ /* convert is NULL if output color model not supported */
+ if (convert == NULL) {
+ return 1;
+ }
+
+ /* Initialize output list */
+ output = MI_NEXTTEMPDATALIST(pddc);
+ MI_ALLOCLISTHEADER(output, MI_ROUND_LISTHEADERCOUNT(vinput->numLists))
+ if (!output->ddList) return(BadAlloc);
+
+ type = vinput->type;
+ DD_VertPointSize( (type & (DDPT_SHORT | DDPT_4D)), coord_size );
+
+ /* set output color type */
+ switch(rdrColourModel) {
+ case PEXRdrColourModelImpDep:
+ case PEXRdrColourModelRGB:
+ DD_SetVertRGBFLOAT(type);
+ break;
+ case PEXRdrColourModelHSV:
+ DD_SetVertHSV(type);
+ break;
+ case PEXRdrColourModelHLS:
+ DD_SetVertHLS(type);
+ break;
+ case PEXRdrColourModelCIE:
+ DD_SetVertCIE(type);
+ break;
+ }
+ output->type = type;
+ DD_VertPointSize( type, out_point_size );
+
+ pddilist = vinput->ddList;
+ pddolist = output->ddList;
+
+ /*
+ * Traverse each list.
+ */
+ for (i = 0; i < vinput->numLists; i++) {
+
+ if ((vert_count = pddolist->numPoints = pddilist->numPoints) <= 1) {
+ pddilist++;
+ continue;
+ }
+
+ /* Insure sufficient room for each vertex */
+ MI_ALLOCLISTOFDDPOINT(pddolist, vert_count+1, out_point_size);
+ if (!pddolist->pts.p2DSpt) return(BadAlloc);
+
+ /*
+ * Copy each point and initialize the edges.
+ * Note that the edge flag is always the last
+ * ddULONG of a vertex. Thus incrementing the
+ * destination pointer by the size of the input
+ * point "automatically" places the pointer
+ * at the start of the edge flag field.
+ */
+ in_pt = pddilist->pts;
+ out_pt = pddolist->pts;
+
+ for (j = 0; j < vert_count; j++) {
+
+ /* Copy the coordinate data to the output list */
+ memcpy( out_pt.ptr, in_pt.ptr, coord_size);
+ in_pt.ptr += coord_size;
+ out_pt.ptr += coord_size;
+
+ /* convert the color */
+ (*convert)(pRend, &(in_pt.ptr), &(out_pt.ptr));
+
+ /* Copy the normal data to the output list */
+ if (DD_IsVertNormal(vinput->type))
+ *(out_pt.pNormal++) = *(in_pt.pNormal++);
+
+ /* Copy the edge flag data to the output list */
+ if (DD_IsVertEdge(vinput->type))
+ *(out_pt.pEdge++) = *(in_pt.pEdge++);
+ }
+
+ /* Now, skip to next input list */
+ pddilist++;
+ pddolist++;
+ list_count++;
+ }
+
+ output->numLists = list_count;
+ *voutput = output;
+ return (Success);
+}
+
+/*++
+ |
+ | Function Name: miConvertFacetColors
+ |
+ | Function Description:
+ | Convert vertex colors to the specified rendering color model
+ |
+ | Note(s):
+ | Currently, this will ONLY convert from indexed -> RGBFLOAT
+ |
+ --*/
+
+ddpex3rtn
+miConvertFacetColors(pRend, finput, rdrColourModel, foutput)
+/* in */
+ddRendererPtr pRend; /* renderer handle */
+listofddFacet *finput; /* input facet list */
+ddSHORT rdrColourModel; /* output color model */
+/* out */
+listofddFacet **foutput; /* output facet list */
+{
+ listofddFacet *fct_list;
+ ddFacetUnion in_fct;
+ ddFacetUnion out_fct;
+ miDDContext *pddc = (miDDContext *)pRend->pDDContext;
+ int j;
+ int facet_size;
+ ColorConversionTableType convert;
+ ddSHORT input_color;
+
+ /* if no vertex colors, done! */
+ if ((!DD_IsFacetColour(finput->type)) || (finput->type == DD_FACET_NONE)) {
+ *foutput = finput;
+ return Success;
+ }
+
+ /* extract facet color type */
+ switch(finput->type) {
+ case DD_FACET_INDEX:
+ case DD_FACET_INDEX_NORM:
+ input_color = PEXIndexedColour;
+ break;
+ case DD_FACET_RGB8:
+ case DD_FACET_RGB8_NORM:
+ input_color = PEXRgb8Colour;
+ break;
+ case DD_FACET_RGB16:
+ case DD_FACET_RGB16_NORM:
+ input_color = PEXRgb16Colour;
+ break;
+ case DD_FACET_RGBFLOAT:
+ case DD_FACET_RGBFLOAT_NORM:
+ input_color = PEXRgbFloatColour;
+ break;
+ case DD_FACET_HSV:
+ case DD_FACET_HSV_NORM:
+ input_color = PEXHsvFloatColour;
+ break;
+ case DD_FACET_HLS:
+ case DD_FACET_HLS_NORM:
+ input_color = PEXHlsFloatColour;
+ break;
+ case DD_FACET_CIE:
+ case DD_FACET_CIE_NORM:
+ input_color = PEXCieFloatColour;
+ break;
+ }
+
+ /* find proper conversion routine */
+ convert = ColourConversionRoutine[input_color*rdrColourModel];
+
+ /* convert is 1 if input and output color model are the same */
+ if (convert == NoChange) {
+ /* no conversion necessary */
+ *foutput = finput;
+ return Success;
+ }
+
+ /* convert is NULL if output color model not supported */
+ if (convert == NULL) {
+ return 1;
+ }
+
+ /* Get next free facet list header */
+ fct_list = MI_NEXTTEMPFACETLIST(pddc);
+
+ /* set output color type */
+ switch(rdrColourModel) {
+ case PEXRdrColourModelImpDep:
+ case PEXRdrColourModelRGB:
+ if (DD_IsFacetNormal(finput->type))
+ fct_list->type = DD_FACET_RGBFLOAT_NORM;
+ else fct_list->type = DD_FACET_RGBFLOAT;
+ break;
+ case PEXRdrColourModelHSV:
+ if (DD_IsFacetNormal(finput->type))
+ fct_list->type = DD_FACET_HSV_NORM;
+ else fct_list->type = DD_FACET_HSV;
+ break;
+ case PEXRdrColourModelHLS:
+ if (DD_IsFacetNormal(finput->type))
+ fct_list->type = DD_FACET_HLS_NORM;
+ else fct_list->type = DD_FACET_HLS;
+ break;
+ case PEXRdrColourModelCIE:
+ if (DD_IsFacetNormal(finput->type))
+ fct_list->type = DD_FACET_CIE_NORM;
+ else fct_list->type = DD_FACET_CIE;
+ break;
+ }
+
+ /*
+ * Allocate storage for the facet list
+ */
+ DDFacetSIZE(fct_list->type, facet_size);
+ MI_ALLOCLISTOFDDFACET(fct_list, finput->numFacets, facet_size);
+ if (!(out_fct.pNoFacet = fct_list->facets.pNoFacet)) return(BadAlloc);
+
+ in_fct = finput->facets;
+
+ /* Remember, facet data is of the form:
+ *
+ * |--------------|--------------------------|
+ * color (opt) normal (opt)
+ */
+
+ for (j = 0; j < finput->numFacets; j++) {
+
+ /* convert the color */
+ (*convert)(pRend, &(in_fct.pNoFacet), &(out_fct.pNoFacet));
+
+ /* Copy the input normal */
+ if (DD_IsFacetNormal(finput->type))
+ *(out_fct.pFacetN++) = *(in_fct.pFacetN++);
+
+ }
+
+ fct_list->numFacets = finput->numFacets;
+ *foutput = fct_list;
+
+ return(Success);
+
+}
+
+/*++
+ |
+ | Function Name: miColourtoIndex
+ |
+ | Function Description:
+ | Convert a direct color to an index using the
+ | color approximation table.
+ |
+ | Note(s):
+ | Dithering is ignored as there is no screen data with which to dither.
+ |
+ --*/
+
+ddpex3rtn
+miColourtoIndex(pRend, colourApproxIndex, directcolour, colourindex)
+/* in */
+ddRendererPtr pRend; /* renderer handle */
+ddTableIndex colourApproxIndex; /* colour approx table index */
+ddColourSpecifier *directcolour; /* Direct colour input */
+/* out */
+ddULONG *colourindex; /* output colour index */
+{
+ miColourApproxEntry *pLUT;
+ ddColourApproxEntry *pentry;
+ ddUSHORT status;
+
+ /* Fetch current color approximation table entry */
+ if ((InquireLUTEntryAddress (PEXColourApproxLUT,
+ pRend->lut[PEXColourApproxLUT],
+ colourApproxIndex,
+ &status, (ddPointer *)&pLUT))
+ == PEXLookupTableError)
+ return (PEXLookupTableError);
+
+ pentry = &pLUT->entry;
+
+ /******************************************
+ * Need color mode conversion code here!!!
+ * for now, do nothing....
+ *****************************************/
+ if (directcolour->colourType != pentry->approxModel) {}
+
+ /* now perform direct -> index conversion. */
+ if (pentry->approxType == PEXColourSpace) {
+ switch (pentry->approxModel) {
+
+ case PEXRgbFloatColour:
+ case PEXCieFloatColour:
+ case PEXHsvFloatColour:
+ case PEXHlsFloatColour:
+ {
+ *colourindex =
+ ((ddULONG)(directcolour->colour.rgbFloat.red*pentry->max1))
+ * pentry->mult1;
+
+ *colourindex +=
+ ((ddULONG)(directcolour->colour.rgbFloat.green*pentry->max2))
+ * pentry->mult2;
+
+ *colourindex +=
+ ((ddULONG)(directcolour->colour.rgbFloat.blue*pentry->max3))
+ * pentry->mult3;
+
+ *colourindex += pentry->basePixel;
+ break;
+ }
+
+ case PEXRgb8Colour:
+ *colourindex =
+ ((ddULONG)(directcolour->colour.rgb8.red*pentry->max1))
+ * pentry->mult1;
+
+ *colourindex +=
+ ((ddULONG)(directcolour->colour.rgb8.green*pentry->max2))
+ * pentry->mult2;
+
+ *colourindex +=
+ ((ddULONG)(directcolour->colour.rgb8.blue*pentry->max3))
+ * pentry->mult3;
+
+ *colourindex += pentry->basePixel;
+ break;
+
+ case PEXRgb16Colour:
+ *colourindex =
+ ((ddULONG)(directcolour->colour.rgb16.red*pentry->max1))
+ * pentry->mult1;
+
+ *colourindex +=
+ ((ddULONG)(directcolour->colour.rgb16.green*pentry->max2))
+ * pentry->mult2;
+
+ *colourindex +=
+ ((ddULONG)(directcolour->colour.rgb16.blue*pentry->max3))
+ * pentry->mult3;
+
+ *colourindex += pentry->basePixel;
+ break;
+ }
+ } else /* if (pentry->approxType == PEXColourRange) */ {
+ ddFLOAT floatindex;
+ ddFLOAT nw1, nw2, nw3;
+
+ /* use floatindex as temp var */
+ floatindex = pentry->weight1 + pentry->weight2 + pentry->weight3;
+ nw1 = pentry->weight1 / floatindex;
+ nw2 = pentry->weight2 / floatindex;
+ nw3 = pentry->weight3 / floatindex;
+
+ switch (pentry->approxModel) {
+
+ case PEXRgbFloatColour:
+ case PEXCieFloatColour:
+ case PEXHsvFloatColour:
+ case PEXHlsFloatColour:
+ {
+ floatindex = directcolour->colour.rgbFloat.red * nw1;
+ floatindex += directcolour->colour.rgbFloat.green * nw2;
+ floatindex += directcolour->colour.rgbFloat.blue * nw3;
+
+ floatindex *= pentry->max1;
+ *colourindex = (ddULONG)(floatindex * pentry->mult1) +
+ (ddULONG)(floatindex * pentry->mult2) +
+ (ddULONG)(floatindex * pentry->mult3) +
+ pentry->basePixel;
+ break;
+ }
+
+ case PEXRgb8Colour:
+ floatindex = directcolour->colour.rgb8.red * nw1;
+ floatindex += directcolour->colour.rgb8.green * nw2;
+ floatindex += directcolour->colour.rgb8.blue * nw3;
+
+ floatindex *= pentry->max1;
+ *colourindex = (ddULONG)(floatindex * pentry->mult1) +
+ (ddULONG)(floatindex * pentry->mult2) +
+ (ddULONG)(floatindex * pentry->mult3) +
+ pentry->basePixel;
+ break;
+
+ case PEXRgb16Colour:
+ floatindex = directcolour->colour.rgb16.red * nw1;
+ floatindex += directcolour->colour.rgb16.green * nw2;
+ floatindex += directcolour->colour.rgb16.blue * nw3;
+
+ floatindex *= pentry->max1;
+ *colourindex = (ddULONG)(floatindex * pentry->mult1) +
+ (ddULONG)(floatindex * pentry->mult2) +
+ (ddULONG)(floatindex * pentry->mult3) +
+ pentry->basePixel;
+ break;
+ }
+ }
+
+ return (Success);
+}
+
+/*++
+ |
+ | Function Name: miAddEdgeFlag
+ |
+ | Function Description:
+ | Add edge visibility flags to a list of vertices.
+ | Performs not operation if there already are edge
+ | flags in the data. Note all edges are set to "visible".
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+miAddEdgeFlag(pddc, vinput, voutput)
+/* in */
+ miDDContext *pddc;
+ miListHeader *vinput;
+ miListHeader **voutput;
+{
+/* uses */
+ char *in_pt, *out_pt;
+ ddULONG *edge_ptr;
+ miListHeader *output;
+ listofddPoint *pddilist;
+ listofddPoint *pddolist;
+ int list_count = 0;
+ int vert_count;
+ int point_size, out_point_size;
+ int i, j;
+
+ /* If already have vertices, then simply return */
+ if (DD_IsVertEdge(vinput->type)) {
+ *voutput = vinput;
+ return(Success);
+ }
+
+ /* Initialize output list */
+ output = MI_NEXTTEMPDATALIST(pddc);
+ MI_ALLOCLISTHEADER(output, MI_ROUND_LISTHEADERCOUNT(vinput->numLists))
+ if (!output->ddList) return(BadAlloc);
+
+ DD_VertPointSize(vinput->type, point_size);
+ output->type = vinput->type;
+ DD_SetVertEdge(output->type);
+ DD_VertPointSize(output->type, out_point_size);
+
+ pddilist = vinput->ddList;
+ pddolist = output->ddList;
+
+ /*
+ * Traverse each list.
+ */
+ for (i = 0; i < vinput->numLists; i++) {
+
+ if ((vert_count = pddolist->numPoints = pddilist->numPoints) <= 1) {
+ pddilist++;
+ continue;
+ }
+
+ /* Insure sufficient room for each vertex */
+ MI_ALLOCLISTOFDDPOINT(pddolist, vert_count+1, out_point_size);
+ if (!pddolist->pts.p2DSpt) return(BadAlloc);
+
+ /*
+ * Copy each point and initialize the edges.
+ * Note that the edge flag is always the last
+ * ddULONG of a vertex. Thus incrementing the
+ * destination pointer by the size of the input
+ * point "automatically" places the pointer
+ * at the start of the edge flag field.
+ */
+ in_pt = pddilist->pts.ptr;
+ out_pt = pddolist->pts.ptr;
+
+ for (j = 0; j < vert_count; j++) {
+ memcpy( out_pt, in_pt, point_size);
+ in_pt += point_size;
+ out_pt += point_size;
+ edge_ptr = (ddULONG *)out_pt;
+ *(edge_ptr++) = ~0;
+ out_pt = (char *)edge_ptr;
+ }
+
+ /* Now, skip to next input list */
+ pddilist++;
+ pddolist++;
+ list_count++;
+ }
+
+ output->numLists = list_count;
+ *voutput = output;
+ return (Success);
+}
+
+
+/*++
+ |
+ | Function Name: miRemoveInvisibleEdges
+ |
+ | Function Description:
+ | Checks the edge flags of each edge in the input
+ | vertex list and removes the "invisible" ones.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+miRemoveInvisibleEdges(pddc, vinput, voutput)
+/* in */
+ miDDContext *pddc;
+ miListHeader *vinput;
+ miListHeader **voutput;
+{
+/* uses */
+ char *in_pt, *out_pt;
+ ddULONG *edge_ptr;
+ miListHeader *output;
+ listofddPoint *pddilist;
+ listofddPoint *pddolist;
+ int list_count = 0;
+ int vert_count, counter;
+ int point_size;
+ int edge_offset;
+ int i, j;
+
+ /* If already have vertices, then simply return */
+ if (!(DD_IsVertEdge(vinput->type))) {
+ *voutput = vinput;
+ return(Success);
+ }
+
+ /* Initialize output list */
+ output = MI_NEXTTEMPDATALIST(pddc);
+ MI_ALLOCLISTHEADER(output, MI_ROUND_LISTHEADERCOUNT(vinput->numLists))
+ if (!output->ddList) return(BadAlloc);
+
+ output->type = vinput->type;
+ output->numLists = vinput->numLists;
+ output->flags = vinput->flags;
+
+ DD_VertPointSize(vinput->type, point_size);
+ DD_VertOffsetEdge(vinput->type, edge_offset);
+
+ pddilist = vinput->ddList;
+ pddolist = output->ddList;
+
+ /*
+ * Traverse each list.
+ */
+ for (i = 0; i < vinput->numLists; i++) {
+
+ if ((vert_count = pddilist->numPoints) <= 1) {
+ pddilist++;
+ continue;
+ }
+
+ /* Insure sufficient room for each vertex */
+ MI_ALLOCLISTOFDDPOINT(pddolist, vert_count, point_size);
+ if (!pddolist->pts.p2DSpt) return(BadAlloc);
+
+ /*
+ * Copy each point and initialize the edges.
+ * Note that the edge flag is always the last
+ * ddULONG of a vertex. Thus incrementing the
+ * destination pointer by the size of the input
+ * point "automatically" places the pointer
+ * at the start of the edge flag field.
+ */
+ in_pt = pddilist->pts.ptr;
+ out_pt = pddolist->pts.ptr;
+
+ for (j = 0, counter = 0; j < vert_count; j++) {
+ edge_ptr = (ddULONG *)(in_pt + edge_offset);
+ if (*edge_ptr) {
+ memcpy( out_pt, in_pt, point_size);
+ out_pt += point_size;
+ counter++;
+ } else if (counter) {
+ /* if edge is invisible, start new list */
+
+ /* First, end last edge of previous edge */
+ memcpy( out_pt, in_pt, point_size);
+ pddolist->numPoints = counter + 1;
+ counter = 0;
+
+ /* Insure enough room for new list header */
+ list_count++;
+ MI_ALLOCLISTHEADER(output,
+ MI_ROUND_LISTHEADERCOUNT(list_count));
+ if (!output->ddList) return(BadAlloc);
+ pddolist = &output->ddList[list_count];
+
+ /* Next, insure enough room for vertices in new list */
+ MI_ALLOCLISTOFDDPOINT(pddolist, vert_count - j, point_size);
+ if (!(out_pt = pddolist->pts.ptr)) return(BadAlloc);
+ }
+
+ in_pt += point_size;
+ }
+
+ /* Now, skip to next input list */
+ pddilist++;
+ if (counter > 1) {
+ pddolist->numPoints = counter;
+ list_count++;
+ MI_ALLOCLISTHEADER(output, MI_ROUND_LISTHEADERCOUNT(list_count));
+ if (!output->ddList) return(BadAlloc);
+ pddolist = &output->ddList[list_count];
+ }
+ }
+
+ output->numLists = list_count;
+ *voutput = output;
+ return (Success);
+}
+
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level2/miCopy.c b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miCopy.c
new file mode 100644
index 000000000..477010e66
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miCopy.c
@@ -0,0 +1,1097 @@
+/* $TOG: miCopy.c /main/10 1998/02/10 12:41:05 kaleb $ */
+
+/***********************************************************
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution of
+the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level2/miCopy.c,v 3.6 1998/10/04 09:34:18 dawes Exp $ */
+
+
+#include "ddpex.h"
+#include "ddpex3.h"
+#include "PEX.h"
+#include "PEXproto.h"
+#include "pexExtract.h"
+#include "ddpex2.h"
+#include "miStruct.h"
+#include "pexUtils.h"
+#include "pexos.h"
+
+
+/*
+ bcopy data, fix up pointers
+ */
+/*
+ Please note that any routines added to this file may also cause
+ a corresponding modification to the level function tables (miTables.c)
+ */
+
+/*
+ Coders must ensure that storage is allocated in the same chunks as for the
+ corresponding parse function, otherwise unfortunate things may
+ happen during freeing of storage.
+ */
+
+#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
+#define CAT(a,b) a##b
+#else
+#define CAT(a,b) a/**/b
+#endif
+
+#define OC_COPY_FUNC_HEADER(suffix) \
+ ddpex2rtn CAT(copy,suffix)(pSrc, ppDst) \
+ miGenericElementStr *pSrc; \
+ miGenericElementStr **ppDst;
+
+#define DST_STORE_AND_COPY(DD_ST, TYPE, SIZE) \
+ *ppDst = (miGenericElementPtr) \
+ xalloc((unsigned long)((SIZE) + sizeof(miGenericElementStr))); \
+ if (!(*ppDst)) return (BadAlloc); \
+ memmove( (char *)(*ppDst), (char *)pSrc, \
+ (int)((SIZE) + sizeof(miGenericElementStr))); \
+ DD_ST = (TYPE *)((*ppDst)+1);
+
+#define COPY_DECL(NAME,TYPE) \
+ TYPE * CAT(dst,NAME) = 0, * CAT(src,NAME) = (TYPE *)(pSrc + 1);
+
+#define COPY_MORE(DST, TYPE, NUMBER, SRC) \
+ if ((NUMBER) > 0) { \
+ DST = (TYPE *)xalloc((unsigned long)((NUMBER) * sizeof(TYPE))); \
+ if (!(DST)) err = BadAlloc; \
+ else memmove((char *)(DST),(char *)(SRC),(int)((NUMBER)*sizeof(TYPE))); } \
+ else DST = 0;
+
+/*
+ Returns number of bytes used to store the data
+ Differs from similar routine in pexOCParse.c because that one counts
+ from the protocol format; this one counts dd native format instead
+ */
+static int
+CountddFacetOptData(pFacet)
+listofddFacet *pFacet;
+{
+ switch(pFacet->type){
+ case DD_FACET_INDEX_NORM:
+ return (sizeof(ddIndexNormal) * pFacet->numFacets);
+
+ case DD_FACET_RGBFLOAT_NORM:
+ return (sizeof(ddRgbFloatNormal) * pFacet->numFacets);
+
+ case DD_FACET_CIE_NORM:
+ return (sizeof(ddCieNormal) * pFacet->numFacets);
+
+ case DD_FACET_HSV_NORM:
+ return (sizeof(ddHsvNormal) * pFacet->numFacets);
+
+ case DD_FACET_HLS_NORM:
+ return (sizeof(ddHlsNormal) * pFacet->numFacets);
+
+ case DD_FACET_RGB8_NORM:
+ return (sizeof(ddRgb8Normal) * pFacet->numFacets);
+
+ case DD_FACET_RGB16_NORM:
+ return (sizeof(ddRgb16Normal) * pFacet->numFacets);
+
+ case DD_FACET_NORM:
+ return (sizeof(ddVector3D) * pFacet->numFacets);
+
+ case DD_FACET_INDEX:
+ return (sizeof(ddIndexedColour) * pFacet->numFacets);
+
+ case DD_FACET_RGBFLOAT:
+ return (sizeof(ddRgbFloatColour) * pFacet->numFacets);
+
+ case DD_FACET_CIE:
+ return (sizeof(ddCieColour) * pFacet->numFacets);
+
+ case DD_FACET_HSV:
+ return (sizeof(ddHsvColour) * pFacet->numFacets);
+
+ case DD_FACET_HLS:
+ return (sizeof(ddHlsColour) * pFacet->numFacets);
+
+ case DD_FACET_RGB8:
+ return (sizeof(ddRgb8Colour) * pFacet->numFacets);
+
+ case DD_FACET_NONE:
+ default:
+ return (0);
+ }
+}
+
+static int
+CountddVertexData(pPoint, point_type)
+listofddPoint *pPoint;
+ddPointType point_type;
+{
+ switch (point_type) {
+ case DD_INDEX_NORM_EDGE_POINT:
+ return (sizeof(ddIndexNormEdgePoint) * pPoint->numPoints);
+
+ case DD_RGBFLOAT_NORM_EDGE_POINT:
+ return (sizeof(ddRgbFloatNormEdgePoint) * pPoint->numPoints);
+
+ case DD_CIE_NORM_EDGE_POINT:
+ return (sizeof(ddCieNormEdgePoint) * pPoint->numPoints);
+
+ case DD_HSV_NORM_EDGE_POINT:
+ return (sizeof(ddHsvNormEdgePoint) * pPoint->numPoints);
+
+ case DD_HLS_NORM_EDGE_POINT:
+ return (sizeof(ddHlsNormEdgePoint) * pPoint->numPoints);
+
+ case DD_RGB8_NORM_EDGE_POINT:
+ return (sizeof(ddRgb8NormEdgePoint) * pPoint->numPoints);
+
+ case DD_RGB16_NORM_EDGE_POINT:
+ return (sizeof(ddRgb16NormEdgePoint) * pPoint->numPoints);
+
+ case DD_NORM_EDGE_POINT:
+ return (sizeof(ddNormEdgePoint) * pPoint->numPoints);
+
+ case DD_INDEX_NORM_POINT:
+ return (sizeof(ddIndexNormalPoint) * pPoint->numPoints);
+
+ case DD_RGBFLOAT_NORM_POINT:
+ return (sizeof(ddRgbFloatNormalPoint) * pPoint->numPoints);
+
+ case DD_CIE_NORM_POINT:
+ return (sizeof(ddCieNormalPoint) * pPoint->numPoints);
+
+ case DD_HSV_NORM_POINT:
+ return (sizeof(ddHsvNormalPoint) * pPoint->numPoints);
+
+ case DD_HLS_NORM_POINT:
+ return (sizeof(ddHlsNormalPoint) * pPoint->numPoints);
+
+ case DD_RGB8_NORM_POINT:
+ return (sizeof(ddRgb8NormalPoint) * pPoint->numPoints);
+
+ case DD_RGB16_NORM_POINT:
+ return (sizeof(ddRgb16NormalPoint) * pPoint->numPoints);
+
+ case DD_NORM_POINT:
+ return (sizeof(ddNormalPoint) * pPoint->numPoints);
+
+ case DD_INDEX_EDGE_POINT:
+ return (sizeof(ddIndexEdgePoint) * pPoint->numPoints);
+
+ case DD_RGBFLOAT_EDGE_POINT:
+ return (sizeof(ddRgbFloatEdgePoint) * pPoint->numPoints);
+
+ case DD_CIE_EDGE_POINT:
+ return (sizeof(ddCieEdgePoint) * pPoint->numPoints);
+
+ case DD_HSV_EDGE_POINT:
+ return (sizeof(ddHsvEdgePoint) * pPoint->numPoints);
+
+ case DD_HLS_EDGE_POINT:
+ return (sizeof(ddHlsEdgePoint) * pPoint->numPoints);
+
+ case DD_RGB8_EDGE_POINT:
+ return (sizeof(ddRgb8EdgePoint) * pPoint->numPoints);
+
+ case DD_RGB16_EDGE_POINT:
+ return (sizeof(ddRgb16EdgePoint) * pPoint->numPoints);
+
+ case DD_INDEX_POINT:
+ return (sizeof(ddIndexPoint) * pPoint->numPoints);
+
+ case DD_RGBFLOAT_POINT:
+ return (sizeof(ddRgbFloatPoint) * pPoint->numPoints);
+
+ case DD_CIE_POINT:
+ return (sizeof(ddCiePoint) * pPoint->numPoints);
+
+ case DD_HSV_POINT:
+ return (sizeof(ddHsvPoint) * pPoint->numPoints);
+
+ case DD_HLS_POINT:
+ return (sizeof(ddHlsPoint) * pPoint->numPoints);
+
+ case DD_RGB8_POINT:
+ return (sizeof(ddRgb8Point) * pPoint->numPoints);
+
+ case DD_RGB16_POINT:
+ return (sizeof(ddRgb16Point) * pPoint->numPoints);
+
+ case DD_EDGE_POINT:
+ return (sizeof(ddEdgePoint) * pPoint->numPoints);
+
+ case DD_3D_POINT:
+ return (sizeof(ddCoord3D) * pPoint->numPoints);
+
+ default:
+ return(0);
+ }
+}
+
+
+OC_COPY_FUNC_HEADER(ColourOC)
+{
+ COPY_DECL(Colour,miColourStruct);
+
+ switch (srcColour->colourType) {
+ case PEXIndexedColour: {
+ DST_STORE_AND_COPY( dstColour, miColourStruct,
+ (sizeof(miColourStruct)
+ + sizeof(ddIndexedColour)));
+ dstColour->colour.pIndex = (ddIndexedColour *)(dstColour+1);
+ break; }
+
+ case PEXRgbFloatColour : {
+ DST_STORE_AND_COPY( dstColour, miColourStruct,
+ (sizeof(miColourStruct)
+ + sizeof(ddRgbFloatColour)));
+ dstColour->colour.pRgbFloat = (ddRgbFloatColour *)(dstColour+1);
+ break; }
+
+ case PEXCieFloatColour : {
+ DST_STORE_AND_COPY( dstColour, miColourStruct,
+ (sizeof(miColourStruct)
+ + sizeof(ddCieColour)));
+ dstColour->colour.pCie = (ddCieColour *)(dstColour+1);
+ break; }
+
+ case PEXHsvFloatColour : {
+ DST_STORE_AND_COPY( dstColour, miColourStruct,
+ (sizeof(miColourStruct)
+ + sizeof(ddHsvColour)));
+ dstColour->colour.pHsv = (ddHsvColour *)(dstColour+1);
+ break; }
+
+ case PEXHlsFloatColour : {
+ DST_STORE_AND_COPY( dstColour, miColourStruct,
+ (sizeof(miColourStruct)
+ + sizeof(ddHlsColour)));
+ dstColour->colour.pHls = (ddHlsColour *)(dstColour+1);
+ break; }
+
+ case PEXRgb8Colour : {
+ DST_STORE_AND_COPY( dstColour, miColourStruct,
+ (sizeof(miColourStruct)
+ + sizeof(ddRgb8Colour)));
+ dstColour->colour.pRgb8 = (ddRgb8Colour *)(dstColour+1);
+ break; }
+
+ case PEXRgb16Colour : {
+ DST_STORE_AND_COPY( dstColour, miColourStruct,
+ (sizeof(miColourStruct)
+ + sizeof(ddRgb16Colour)));
+ dstColour->colour.pRgb16 = (ddRgb16Colour *)(dstColour+1);
+ break; }
+
+ }
+
+ return(Success);
+}
+
+OC_COPY_FUNC_HEADER(ColourIndexOC)
+{
+ COPY_DECL(Colour,miColourStruct);
+
+ DST_STORE_AND_COPY( dstColour, miColourStruct, (sizeof(miColourStruct)
+ + sizeof(ddIndexedColour)));
+ dstColour->colour.pIndex = (ddIndexedColour *)(dstColour+1);
+
+ return(Success);
+}
+
+OC_COPY_FUNC_HEADER(LightState)
+{
+ COPY_DECL(LightState,miLightStateStruct);
+
+ DST_STORE_AND_COPY( dstLightState, miLightStateStruct,
+ sizeof(miLightStateStruct)
+ + 2 * sizeof(listofObj)
+ + sizeof(CARD16) *
+ (srcLightState->enableList->maxObj
+ + srcLightState->disableList->maxObj));
+
+ dstLightState->enableList = (listofObj *)(dstLightState + 1);
+ dstLightState->enableList->pList = (ddPointer)(dstLightState->enableList +1);
+ dstLightState->disableList =
+ (listofObj *)((dstLightState->enableList->pList +
+ sizeof(CARD16) * dstLightState->enableList->maxObj));
+ dstLightState->disableList->pList =
+ (ddPointer)(dstLightState->disableList + 1);
+ return(Success);
+}
+
+/* can use the same for both 3D and 2D */
+OC_COPY_FUNC_HEADER(MCVolume)
+{
+ int listSize = 0;
+ COPY_DECL(MCVolume, miMCVolume_Struct);
+ listSize = puCountList( DD_HALF_SPACE, srcMCVolume->halfspaces->numObj);
+ DST_STORE_AND_COPY(dstMCVolume, miMCVolume_Struct,
+ sizeof(miMCVolume_Struct) + listSize);
+ dstMCVolume->halfspaces = (listofObj *)(dstMCVolume+1);
+ return(Success);
+}
+
+OC_COPY_FUNC_HEADER(Marker)
+{
+ listofddPoint *dstPoint;
+ COPY_DECL(Marker, miMarkerStruct);
+
+ DST_STORE_AND_COPY( dstMarker, miListHeader,
+ sizeof(miListHeader) + sizeof(listofddPoint)
+ + srcMarker->ddList->numPoints * sizeof(pexCoord3D));
+ dstPoint = (listofddPoint *)(dstMarker+1);
+ dstMarker->ddList = dstPoint;
+ dstPoint->pts.p3Dpt = (ddCoord3D *)(dstPoint + 1);
+
+ return(Success);
+}
+
+
+OC_COPY_FUNC_HEADER(Marker2D)
+{
+ listofddPoint *dstPoint;
+ COPY_DECL(Marker, miMarkerStruct);
+
+ DST_STORE_AND_COPY( dstMarker, miListHeader,
+ sizeof(miListHeader) + sizeof(listofddPoint)
+ + srcMarker->ddList->numPoints * sizeof(pexCoord2D));
+ dstPoint = (listofddPoint *)(dstMarker+1);
+ dstMarker->ddList = dstPoint;
+ dstPoint->pts.p2Dpt = (ddCoord2D *)(dstPoint + 1);
+
+ return(Success);
+}
+
+
+OC_COPY_FUNC_HEADER(Text)
+{
+ COPY_DECL(Text, miTextStruct);
+
+ DST_STORE_AND_COPY( dstText, miTextStruct, sizeof(miTextStruct)
+ + 3 * sizeof(ddCoord3D)
+ + pSrc->element.pexOClength * sizeof(CARD32)
+ - sizeof(pexText));
+ /* this also allocates any trailing pads, but so
+ much the better */
+ dstText->pOrigin = (ddCoord3D *)(dstText + 1);
+ dstText->pDirections = (dstText->pOrigin) + 1;
+ dstText->pText = (pexMonoEncoding *)((dstText->pDirections) + 2);
+
+ return(Success);
+}
+
+
+OC_COPY_FUNC_HEADER(Text2D)
+{
+ COPY_DECL(Text, miText2DStruct);
+
+ DST_STORE_AND_COPY( dstText, miText2DStruct, sizeof(miText2DStruct)
+ + sizeof(ddCoord2D)
+ + pSrc->element.pexOClength * sizeof(CARD32)
+ - sizeof(pexText2D));
+ /* this also allocates any trailing pads, but so
+ much the better */
+ dstText->pOrigin = (ddCoord2D *)(dstText + 1);
+ dstText->pText = (pexMonoEncoding *)((dstText->pOrigin) + 1);
+
+ return(Success);
+
+}
+
+
+OC_COPY_FUNC_HEADER(AnnotationText)
+{
+ COPY_DECL(Text, miAnnoTextStruct);
+
+ DST_STORE_AND_COPY( dstText, miAnnoTextStruct, sizeof(miAnnoTextStruct)
+ + 2 * sizeof(ddCoord3D)
+ + pSrc->element.pexOClength * sizeof(CARD32)
+ - sizeof(pexAnnotationText));
+ /* this also allocates any trailing pads, but so
+ much the better */
+ dstText->pOrigin = (ddCoord3D *)(dstText + 1);
+ dstText->pOffset = (dstText->pOrigin) + 1;
+ dstText->pText = (pexMonoEncoding *)((dstText->pOffset) + 1);
+
+ return(Success);
+
+}
+
+
+OC_COPY_FUNC_HEADER(AnnotationText2D)
+{
+ COPY_DECL(Text, miAnnoText2DStruct);
+
+ DST_STORE_AND_COPY( dstText, miAnnoText2DStruct, sizeof(miAnnoText2DStruct)
+ + 2 * sizeof(ddCoord2D)
+ + pSrc->element.pexOClength * sizeof(CARD32)
+ - sizeof(pexAnnotationText2D));
+ /* this also allocates any trailing pads, but so
+ much the better */
+ dstText->pOrigin = (ddCoord2D *)(dstText + 1);
+ dstText->pOffset = (dstText->pOrigin) + 1;
+ dstText->pText = (pexMonoEncoding *)((dstText->pOffset) + 1);
+
+ return(Success);
+
+}
+
+
+OC_COPY_FUNC_HEADER(Polyline2D)
+{
+ listofddPoint *dstPoint;
+ COPY_DECL(Poly, miPolylineStruct);
+
+ DST_STORE_AND_COPY( dstPoly, miListHeader,
+ sizeof(miListHeader) + sizeof(listofddPoint)
+ + srcPoly->ddList->numPoints * sizeof(ddCoord2D));
+ dstPoint = (listofddPoint *)(dstPoly+1);
+ dstPoly->ddList = dstPoint;
+ dstPoint->pts.p2Dpt = (ddCoord2D *)(dstPoint + 1);
+
+ return(Success);
+
+}
+
+
+
+OC_COPY_FUNC_HEADER(Polyline)
+{
+ listofddPoint *dstPoint;
+ COPY_DECL(Poly, miPolylineStruct);
+
+ DST_STORE_AND_COPY( dstPoly, miListHeader,
+ sizeof(miListHeader) + sizeof(listofddPoint)
+ + srcPoly->ddList->numPoints * sizeof(ddCoord3D));
+ dstPoint = (listofddPoint *)(dstPoly+1);
+ dstPoly->ddList = dstPoint;
+ dstPoint->pts.p3Dpt = (ddCoord3D *)(dstPoint + 1);
+
+ return(Success);
+
+}
+
+
+OC_COPY_FUNC_HEADER(PolylineSet)
+{
+ listofddPoint *pPoint;
+ ddUSHORT i;
+ int vertexSize = 0;
+ ddPointer ddPtr = 0;
+ ddpex2rtn err = Success;
+ COPY_DECL(Poly, miPolylineStruct);
+
+ for (i=0, pPoint = srcPoly->ddList; i<srcPoly->numLists; i++, pPoint++)
+ vertexSize += CountddVertexData(pPoint, srcPoly->type);
+ DST_STORE_AND_COPY( dstPoly, miListHeader,
+ (sizeof(miListHeader) + vertexSize
+ + srcPoly->numLists * sizeof(listofddPoint)));
+
+ dstPoly->ddList = (listofddPoint *)(dstPoly+1);
+ for (i=0, pPoint = dstPoly->ddList, vertexSize = 0,
+ ddPtr = (ddPointer)(dstPoly->ddList + dstPoly->numLists);
+ i<dstPoly->numLists;
+ i++, pPoint++) {
+ vertexSize = CountddVertexData(pPoint, dstPoly->type);
+ pPoint->pts.ptr = (char *)ddPtr;
+ ddPtr += vertexSize;
+ /* could have subtracted pointers, but this is more maintainable */
+ }
+
+ return(Success);
+
+}
+
+
+OC_COPY_FUNC_HEADER(NurbCurve)
+{
+ ddUSHORT pointSize = 0;
+ COPY_DECL(Nurb, miNurbStruct);
+
+ pointSize = (srcNurb->points.type == DDPT_4D)
+ ? sizeof(ddCoord4D) : sizeof(ddCoord3D);
+ DST_STORE_AND_COPY( dstNurb, miNurbStruct,
+ sizeof(miNurbStruct) + sizeof(listofddPoint)
+ + srcNurb->numKnots * sizeof(PEXFLOAT)
+ + srcNurb->points.ddList->numPoints * pointSize);
+ dstNurb->pKnots = (ddFLOAT *)(dstNurb+1);
+ dstNurb->points.ddList =
+ (listofddPoint *)(dstNurb->pKnots + srcNurb->numKnots);
+ if (srcNurb->points.type == DDPT_4D) {
+ dstNurb->points.ddList->pts.p4Dpt =
+ (ddCoord4D *)((dstNurb->points.ddList)+1);
+ } else {
+ dstNurb->points.ddList->pts.p3Dpt =
+ (ddCoord3D *)((dstNurb->points.ddList)+1);
+ }
+
+ return(Success);
+}
+
+
+OC_COPY_FUNC_HEADER(FillArea2D)
+{
+ COPY_DECL(Fill, miFillAreaStruct);
+
+ DST_STORE_AND_COPY( dstFill, miFillAreaStruct, (sizeof(miFillAreaStruct) +
+ sizeof(listofddFacet) + sizeof(listofddPoint)
+ + srcFill->points.ddList->numPoints *sizeof(ddCoord2D)));
+ dstFill->pFacets = (listofddFacet *)(dstFill+1);
+ dstFill->points.ddList = (listofddPoint *)((dstFill->pFacets)+1);
+ dstFill->points.ddList->pts.p2Dpt = (ddCoord2D *)((dstFill->points.ddList) + 1);
+
+ return(Success);
+}
+
+
+
+
+OC_COPY_FUNC_HEADER(FillArea)
+{
+ COPY_DECL(Fill, miFillAreaStruct);
+
+ DST_STORE_AND_COPY( dstFill, miFillAreaStruct, (sizeof(miFillAreaStruct) +
+ sizeof(listofddFacet) + sizeof(listofddPoint)
+ + srcFill->points.ddList->numPoints *sizeof(ddCoord3D)));
+ dstFill->pFacets = (listofddFacet *)(dstFill+1);
+ dstFill->points.ddList = (listofddPoint *)((dstFill->pFacets)+1);
+ dstFill->points.ddList->pts.p3Dpt = (ddCoord3D *)((dstFill->points.ddList) + 1);
+
+ return(Success);
+}
+
+
+OC_COPY_FUNC_HEADER(ExtFillArea)
+{
+ ddpex2rtn err = Success;
+ int facetSize = 0, vertexSize = 0;
+ ddPointer facetPtr = 0, vertexPtr = 0;
+ COPY_DECL(Fill, miFillAreaStruct);
+
+ facetSize = CountddFacetOptData(srcFill->pFacets);
+ vertexSize = CountddVertexData(srcFill->points.ddList, srcFill->points.type);
+ DST_STORE_AND_COPY( dstFill, miFillAreaStruct,
+ (sizeof(miFillAreaStruct) + facetSize + vertexSize
+ + sizeof(listofddFacet) + sizeof(listofddPoint)));
+ dstFill->pFacets = (listofddFacet *)(dstFill+1);
+ dstFill->points.ddList = (listofddPoint *)((dstFill->pFacets)+1);
+
+ facetPtr = (ddPointer)(dstFill->points.ddList + 1);
+ if (facetSize == 0)
+ dstFill->pFacets->facets.pNoFacet = 0;
+ else
+ dstFill->pFacets->facets.pNoFacet = facetPtr;
+
+ vertexPtr = facetPtr + facetSize;
+ if (vertexSize == 0)
+ dstFill->points.ddList->pts.ptr = 0;
+ else
+ dstFill->points.ddList->pts.ptr = (char *)vertexPtr;
+
+ return(Success);
+}
+
+
+OC_COPY_FUNC_HEADER(FillAreaSet2D)
+{
+ listofddPoint *ddPoint;
+ ddpex2rtn err = Success;
+ int listSize = 0;
+ ddUSHORT i;
+ ddPointer ddPtr = 0;
+ COPY_DECL(Fill, miFillAreaStruct);
+
+ for ( i=0, ddPoint = srcFill->points.ddList;
+ i < srcFill->points.numLists;
+ i++, ddPoint++ )
+ listSize += ddPoint->numPoints * sizeof(ddCoord2D);
+
+ DST_STORE_AND_COPY( dstFill, miFillAreaStruct,
+ (sizeof(miFillAreaStruct) + sizeof(listofddFacet)
+ + listSize
+ + (srcFill->points.numLists * sizeof(listofddPoint))));
+ dstFill->pFacets = (listofddFacet *)(dstFill+1);
+ dstFill->points.ddList = (listofddPoint *)((dstFill->pFacets)+1);
+
+ for ( i=0, ddPoint = dstFill->points.ddList,
+ ddPtr = (ddPointer)(ddPoint + dstFill->points.numLists);
+ i<dstFill->points.numLists;
+ i++, ddPoint++ ) {
+
+ ddPoint->pts.p2Dpt = (ddCoord2D *)ddPtr;
+ ddPtr += ddPoint->numPoints * sizeof(ddCoord2D);
+ }
+
+ return(Success);
+}
+
+
+OC_COPY_FUNC_HEADER(FillAreaSet)
+{
+ listofddPoint *ddPoint;
+ ddpex2rtn err = Success;
+ int listSize = 0;
+ ddUSHORT i;
+ ddPointer ddPtr = 0;
+ COPY_DECL(Fill, miFillAreaStruct);
+
+ for ( i=0, ddPoint = srcFill->points.ddList;
+ i < srcFill->points.numLists;
+ i++, ddPoint++ )
+ listSize += ddPoint->numPoints * sizeof(ddCoord3D);
+
+ DST_STORE_AND_COPY( dstFill, miFillAreaStruct,
+ (sizeof(miFillAreaStruct) + sizeof(listofddFacet)
+ + listSize
+ + (srcFill->points.numLists * sizeof(listofddPoint))));
+ dstFill->pFacets = (listofddFacet *)(dstFill+1);
+ dstFill->points.ddList = (listofddPoint *)((dstFill->pFacets)+1);
+
+ for ( i=0, ddPoint = dstFill->points.ddList,
+ ddPtr = (ddPointer)(ddPoint + dstFill->points.numLists);
+ i<dstFill->points.numLists;
+ i++, ddPoint++ ) {
+
+ ddPoint->pts.p3Dpt = (ddCoord3D *)ddPtr;
+ ddPtr += ddPoint->numPoints * sizeof(ddCoord3D);
+ }
+
+ return(Success);
+}
+
+
+OC_COPY_FUNC_HEADER(ExtFillAreaSet)
+{
+ listofddPoint *dstPoint, *srcPoint;
+ ddUSHORT i;
+ int facetSize = 0, vertexSize = 0;
+ ddPointer facetPtr = 0, vertexPtr = 0;
+ ddpex2rtn err = Success;
+ COPY_DECL(Fill, miFillAreaStruct);
+
+ facetSize = CountddFacetOptData(srcFill->pFacets);
+ for (i=0, srcPoint=srcFill->points.ddList;
+ i<srcFill->points.numLists;
+ i++, srcPoint++) {
+ vertexSize += CountddVertexData(srcPoint, srcFill->points.type); }
+
+ DST_STORE_AND_COPY( dstFill, miFillAreaStruct,
+ (sizeof(miFillAreaStruct) + sizeof(listofddFacet)
+ + facetSize + vertexSize
+ + (srcFill->points.numLists * sizeof(listofddPoint))));
+ dstFill->pFacets = (listofddFacet *)(dstFill+1);
+ dstFill->points.ddList = (listofddPoint *)((dstFill->pFacets)+1);
+
+ facetPtr = (ddPointer)(dstFill->points.ddList + dstFill->points.numLists);
+ if (facetSize == 0)
+ dstFill->pFacets->facets.pNoFacet = 0;
+ else
+ dstFill->pFacets->facets.pNoFacet = facetPtr;
+
+ vertexPtr = facetPtr + facetSize;
+
+ for (i=0, dstPoint=dstFill->points.ddList, vertexSize = 0;
+ i<dstFill->points.numLists;
+ i++, dstPoint++, srcPoint++) {
+
+ vertexSize = CountddVertexData(dstPoint, dstFill->points.type);
+ dstPoint->pts.ptr = (char *)vertexPtr;
+ vertexPtr += vertexSize;
+ }
+
+ return(Success);
+}
+
+
+OC_COPY_FUNC_HEADER(SOFAS)
+{
+ ddUSHORT i,j, k;
+ miConnListList *dstCLL, *srcCLL;
+ miConnList *dstCList, *srcCList;
+ ddpex2rtn err = Success;
+ int vertexSize = 0, facetSize = 0, edgeSize = 0;
+ ddPointer ptr;
+ extern void destroySOFAS();
+ COPY_DECL(Fill, miSOFASStruct);
+
+ facetSize = CountddFacetOptData( &srcFill->pFacets);
+ vertexSize = CountddVertexData( srcFill->points.ddList,
+ srcFill->points.type);
+ if (srcFill->edgeData) {
+ edgeSize = srcFill->numEdges * sizeof(ddUCHAR);
+ edgeSize += ((4 - (edgeSize & 3)) & 3);
+ }
+
+ DST_STORE_AND_COPY( dstFill, miSOFASStruct,
+ sizeof(miSOFASStruct) + sizeof(listofddPoint)
+ + srcFill->numEdges * sizeof(ddUCHAR)
+ + facetSize + vertexSize + edgeSize +
+ srcFill->connects.numListLists * sizeof(miConnListList));
+
+ dstFill->points.ddList = (listofddPoint *)(dstFill + 1);
+ ptr = (ddPointer)(dstFill->points.ddList + 1);
+ if (facetSize == 0) dstFill->pFacets.facets.pNoFacet = 0;
+ else dstFill->pFacets.facets.pNoFacet = ptr;
+ ptr += facetSize;
+ if (vertexSize == 0) dstFill->points.ddList->pts.ptr = 0;
+ else dstFill->points.ddList->pts.ptr = (char *)ptr;
+ ptr += vertexSize;
+ if (edgeSize == 0) dstFill->edgeData = 0;
+ else dstFill->edgeData = ptr;
+ ptr += edgeSize;
+ dstFill->connects.data = (miConnListList *)ptr;
+ for ( i=0, dstCLL = dstFill->connects.data, srcCLL = srcFill->connects.data;
+ i<srcFill->numFAS;
+ i++, dstCLL++, srcCLL++) {
+ COPY_MORE( dstCLL->pConnLists, miConnList,
+ srcCLL->numLists * sizeof(miConnList),
+ srcCLL->pConnLists);
+ if (err != Success) {
+ destroySOFAS(dstFill);
+ return(BadAlloc);
+ }
+ for ( j=0,dstCList = dstCLL->pConnLists, srcCList = srcCLL->pConnLists;
+ j<dstCLL->numLists;
+ j++, dstCList++, srcCList++) {
+ COPY_MORE( dstCList->pConnects, ddUSHORT,
+ srcCList->numLists * sizeof(ddUSHORT),
+ srcCList->pConnects);
+ if (err != Success) {
+ destroySOFAS(dstFill);
+ return(BadAlloc);
+ }
+ }
+ }
+
+ return(Success);
+}
+
+
+
+OC_COPY_FUNC_HEADER(TriangleStrip)
+{
+ ddpex2rtn err = Success;
+ int vertexSize = 0, facetSize = 0;
+ COPY_DECL(Triangle, miTriangleStripStruct);
+
+ facetSize = CountddFacetOptData(srcTriangle->pFacets);
+ vertexSize = CountddVertexData( srcTriangle->points.ddList,
+ srcTriangle->points.type);
+ DST_STORE_AND_COPY( dstTriangle, miTriangleStripStruct,
+ (sizeof(miTriangleStripStruct) + sizeof(listofddFacet)
+ + vertexSize + facetSize + sizeof(listofddPoint)));
+ dstTriangle->pFacets = (listofddFacet *)(dstTriangle+1);
+ dstTriangle->points.ddList = (listofddPoint *)((dstTriangle->pFacets)+1);
+ dstTriangle->pFacets->facets.pNoFacet
+ = (ddPointer)(dstTriangle->points.ddList + 1);
+ dstTriangle->points.ddList->pts.ptr
+ = (char *)(dstTriangle->pFacets->facets.pNoFacet + facetSize);
+
+ return(Success);
+}
+
+
+OC_COPY_FUNC_HEADER(QuadrilateralMesh)
+{
+ ddpex2rtn err = Success;
+ int vertexSize = 0, facetSize = 0;
+ COPY_DECL(Quad, miQuadMeshStruct);
+
+ facetSize = CountddFacetOptData(srcQuad->pFacets);
+ vertexSize = CountddVertexData(srcQuad->points.ddList, srcQuad->points.type);
+ DST_STORE_AND_COPY( dstQuad, miQuadMeshStruct, (sizeof(miQuadMeshStruct)
+ + vertexSize + facetSize
+ + sizeof(listofddFacet) + sizeof(listofddPoint)));
+ dstQuad->pFacets = (listofddFacet *)(dstQuad+1);
+ dstQuad->points.ddList = (listofddPoint *)((dstQuad->pFacets)+1);
+ dstQuad->pFacets->facets.pNoFacet
+ = (ddPointer)(dstQuad->points.ddList + 1);
+ dstQuad->points.ddList->pts.ptr
+ = (char *)(dstQuad->pFacets->facets.pNoFacet + facetSize);
+
+ return(Success);
+}
+
+
+OC_COPY_FUNC_HEADER(NurbSurface)
+{
+ ddULONG i, j, k;
+ listofTrimCurve *dstTrim, *srcTrim;
+ ddTrimCurve *dstTC, *srcTC;
+ ddpex2rtn err = Success;
+ extern void destroyNurbSurface();
+ COPY_DECL(Nurb, miNurbSurfaceStruct);
+
+ DST_STORE_AND_COPY(dstNurb, miNurbSurfaceStruct, (sizeof(miNurbSurfaceStruct)
+ + (srcNurb->numUknots * srcNurb->numVknots) * (sizeof(ddFLOAT))
+ + (sizeof(listofddPoint))
+ + (srcNurb->mPts * srcNurb->nPts * sizeof(ddCoord4D)
+ + (sizeof(listofTrimCurve))
+ + srcNurb->numTrimCurveLists * sizeof(ddTrimCurve))));
+ dstNurb->pUknots = (ddFLOAT *)(dstNurb+1);
+ dstNurb->pVknots = (ddFLOAT *)((dstNurb->pUknots) + srcNurb->numUknots);
+ dstNurb->points.ddList =
+ (listofddPoint *)((dstNurb->pVknots) + srcNurb->numVknots);
+ dstNurb->points.ddList->pts.ptr = (char *)(dstNurb->points.ddList + 1);
+ dstNurb->trimCurves =
+ (listofTrimCurve *)((dstNurb->points.ddList->pts.ptr)
+ + (srcNurb->mPts * srcNurb->nPts * sizeof(ddCoord4D)));
+
+ for (i=0, dstTrim = dstNurb->trimCurves, srcTrim = srcNurb->trimCurves;
+ i<dstNurb->numTrimCurveLists;
+ i++, dstTrim++, srcTrim++) {
+
+ dstTrim->pTC = (ddTrimCurve *)xalloc(srcTrim->count*sizeof(ddTrimCurve));
+ COPY_MORE(dstTrim->pTC, ddTrimCurve, srcTrim->count, srcTrim->pTC);
+ if (err) {
+ destroyNurbSurface(dstNurb);
+ return(BadAlloc);
+ }
+
+ for ( k=0, dstTC = dstTrim->pTC, srcTC = srcTrim->pTC;
+ k < dstTrim->count;
+ k++, dstTC++, srcTC++) {
+ COPY_MORE(dstTC->pKnots, ddFLOAT, dstTC->numKnots, srcTC->pKnots );
+ if (err) {
+ dstTC->points.pts.ptr = 0;
+ destroyNurbSurface(dstNurb);
+ return(BadAlloc);
+ }
+ if (srcTC->pttype == DD_3D_POINT) {
+ /* Note that this only works because these points are
+ * never transformed */
+ COPY_MORE( dstTC->points.pts.p3Dpt, ddCoord3D,
+ dstTC->points.numPoints, srcTC->points.pts.p3Dpt );
+ } else {
+ COPY_MORE( dstTC->points.pts.p2Dpt, ddCoord2D,
+ dstTC->points.numPoints, srcTC->points.pts.p2Dpt );
+ }
+ if (err) {
+ destroyNurbSurface(dstNurb);
+ return(BadAlloc);
+ }
+ }
+ }
+ return(Success);
+
+}
+
+OC_COPY_FUNC_HEADER(CellArray2D)
+{
+ COPY_DECL(Cell, miCellArrayStruct);
+
+ DST_STORE_AND_COPY( dstCell, miCellArrayStruct,
+ sizeof(miCellArrayStruct) + sizeof(listofddPoint)
+ + 2 * sizeof(ddCoord2D)
+ + srcCell->dx * srcCell->dy * sizeof(ddIndexedColour));
+ dstCell->point.ddList = (listofddPoint *)(dstCell+1);
+ dstCell->point.ddList->pts.p2Dpt =
+ (ddCoord2D *)((dstCell->point.ddList) + 1);
+ dstCell->colours.colour.pIndex =
+ (ddIndexedColour *)((dstCell->point.ddList->pts.p2Dpt) + 2);
+
+ return(Success);
+}
+
+
+OC_COPY_FUNC_HEADER(CellArray)
+{
+ COPY_DECL(Cell, miCellArrayStruct);
+
+ DST_STORE_AND_COPY( dstCell, miCellArrayStruct,
+ sizeof(miCellArrayStruct) + sizeof(listofddPoint)
+ + 3 * sizeof(ddCoord3D)
+ + srcCell->dx * srcCell->dy * sizeof(ddIndexedColour));
+ dstCell->point.ddList = (listofddPoint *)(dstCell+1);
+ dstCell->point.ddList->pts.p3Dpt =
+ (ddCoord3D *)((dstCell->point.ddList) + 1);
+ dstCell->colours.colour.pIndex =
+ (ddIndexedColour *)((dstCell->point.ddList->pts.p3Dpt) + 3);
+
+ return(Success);
+
+}
+
+OC_COPY_FUNC_HEADER(ExtCellArray)
+{
+ unsigned long size;
+ COPY_DECL(Cell, miCellArrayStruct);
+
+ size = (((srcCell->colours.colourType==PEXIndexedColour)
+ || (srcCell->colours.colourType==PEXRgb8Colour)) ? 4 :
+ ((srcCell->colours.colourType==PEXRgb16Colour) ? 8 : 12 ));
+ DST_STORE_AND_COPY( dstCell, miCellArrayStruct,
+ sizeof(miCellArrayStruct) + sizeof(listofddPoint)
+ + 3 * sizeof(ddCoord3D)
+ + srcCell->dx * srcCell->dy * size);
+ dstCell->point.ddList = (listofddPoint *)(dstCell+1);
+
+ dstCell->point.ddList->pts.p3Dpt =
+ (ddCoord3D *)((dstCell->point.ddList) + 1);
+
+ switch (srcCell->colours.colourType) {
+ case PEXIndexedColour: {
+ dstCell->colours.colour.pIndex =
+ (ddIndexedColour *)((dstCell->point.ddList->pts.p3Dpt)+3);
+ break; }
+ case PEXRgbFloatColour : {
+ dstCell->colours.colour.pRgbFloat =
+ (ddRgbFloatColour *)((dstCell->point.ddList->pts.p3Dpt)+3);
+ break; }
+ case PEXCieFloatColour : {
+ dstCell->colours.colour.pCie =
+ (ddCieColour *)((dstCell->point.ddList->pts.p3Dpt)+3);
+ break; }
+ case PEXHsvFloatColour : {
+ dstCell->colours.colour.pHsv =
+ (ddHsvColour *)((dstCell->point.ddList->pts.p3Dpt)+3);
+ break; }
+ case PEXHlsFloatColour : {
+ dstCell->colours.colour.pHls =
+ (ddHlsColour *)((dstCell->point.ddList->pts.p3Dpt)+3);
+ break; }
+ case PEXRgb8Colour : {
+ dstCell->colours.colour.pRgb8 =
+ (ddRgb8Colour *)((dstCell->point.ddList->pts.p3Dpt)+3);
+ break; }
+ case PEXRgb16Colour : {
+ dstCell->colours.colour.pRgb16 =
+ (ddRgb16Colour *)((dstCell->point.ddList->pts.p3Dpt)+3);
+ break; }
+ }
+
+ return(Success);
+
+}
+
+
+OC_COPY_FUNC_HEADER(PSurfaceChars)
+{
+ COPY_DECL(PSC, miPSurfaceCharsStruct);
+
+ switch (srcPSC->type) {
+ case PEXPSCNone:
+ case PEXPSCImpDep:
+ DST_STORE_AND_COPY( dstPSC, miPSurfaceCharsStruct,
+ sizeof(miPSurfaceCharsStruct));
+ break;
+
+ case PEXPSCIsoCurves: {
+ DST_STORE_AND_COPY( dstPSC, miPSurfaceCharsStruct,
+ sizeof(miPSurfaceCharsStruct)
+ + sizeof(ddPSC_IsoparametricCurves));
+ dstPSC->data.pIsoCurves = (ddPSC_IsoparametricCurves *)(dstPSC + 1);
+ break;
+ }
+
+ case PEXPSCMcLevelCurves: {
+ DST_STORE_AND_COPY( dstPSC, miPSurfaceCharsStruct,
+ sizeof(miPSurfaceCharsStruct)
+ + sizeof(ddPSC_LevelCurves));
+ dstPSC->data.pMcLevelCurves = (ddPSC_LevelCurves *)(dstPSC + 1);
+ break;
+ }
+
+ case PEXPSCWcLevelCurves: {
+ DST_STORE_AND_COPY( dstPSC, miPSurfaceCharsStruct,
+ sizeof(miPSurfaceCharsStruct)
+ + sizeof(ddPSC_LevelCurves));
+ dstPSC->data.pWcLevelCurves = (ddPSC_LevelCurves *)(dstPSC + 1);
+ break;
+ }
+ }
+
+ return(Success);
+}
+
+
+
+
+OC_COPY_FUNC_HEADER(Gdp2D)
+{
+ COPY_DECL(Gdp, miGdpStruct);
+
+ DST_STORE_AND_COPY( dstGdp, miGdpStruct, (sizeof(miGdpStruct)
+ + sizeof(listofddPoint) + srcGdp->numBytes
+ + srcGdp->points.ddList->numPoints * sizeof(ddCoord2D)));
+ dstGdp->points.ddList = (listofddPoint *)(dstGdp+1);
+ dstGdp->points.ddList->pts.p2Dpt = (ddCoord2D *)((dstGdp->points.ddList) +1);
+ dstGdp->pData = ((ddUCHAR *)(dstGdp->points.ddList))
+ + srcGdp->points.ddList->numPoints * sizeof(ddCoord2D);
+
+ return(Success);
+}
+
+
+OC_COPY_FUNC_HEADER(Gdp)
+{
+ COPY_DECL(Gdp, miGdpStruct);
+
+ DST_STORE_AND_COPY( dstGdp, miGdpStruct, (sizeof(miGdpStruct)
+ + sizeof(listofddPoint) + srcGdp->numBytes
+ + srcGdp->points.ddList->numPoints * sizeof(ddCoord3D)));
+ dstGdp->points.ddList = (listofddPoint *)(dstGdp+1);
+ dstGdp->points.ddList->pts.p3Dpt = (ddCoord3D *)((dstGdp->points.ddList) +1);
+ dstGdp->pData = ((ddUCHAR *)(dstGdp->points.ddList))
+ + srcGdp->points.ddList->numPoints * sizeof(ddCoord3D);
+
+ return(Success);
+}
+
+
+OC_COPY_FUNC_HEADER(SetAttribute)
+{
+ COPY_DECL(Attrib, pexElementInfo);
+
+ DST_STORE_AND_COPY( dstAttrib, pexElementInfo,
+ srcAttrib->length * sizeof(CARD32));
+
+ return(Success);
+}
+
+
+OC_COPY_FUNC_HEADER(PropOC)
+{
+ COPY_DECL(PropOC, pexElementInfo);
+
+ DST_STORE_AND_COPY( dstPropOC, pexElementInfo,
+ srcPropOC->length * sizeof(CARD32));
+
+ return(Success);
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level2/miDestroy.c b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miDestroy.c
new file mode 100644
index 000000000..184886794
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miDestroy.c
@@ -0,0 +1,141 @@
+/* $TOG: miDestroy.c /main/5 1998/02/10 12:41:10 kaleb $ */
+
+/***********************************************************
+
+Copyright 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Copyright 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution of
+the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS 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 "X.h"
+#include "ddpex.h"
+#include "ddpex3.h"
+#include "PEX.h"
+#include "PEXproto.h"
+#include "pexExtract.h"
+#include "ddpex2.h"
+#include "miStruct.h"
+#include "pexUtils.h"
+
+
+/** This file contains the definition for the OC Destroy Functions,
+ ** each of which takes one parameter: a pointer to the element to be
+ ** destroyed (in server native internal format).
+ ****Note that these functions may be replaced by PEX server porters.
+ **/
+
+#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
+#define CAT(a,b) a##b
+#else
+#define CAT(a,b) a/**/b
+#endif /* __STDC__ */
+
+#define OC_DESTROY_FUNC_HEADER(suffix) \
+ void CAT(destroy,suffix)(pExecuteOC) \
+ miGenericElementPtr pExecuteOC; /* internal format */
+
+
+/* nothing to delete */
+OC_DESTROY_FUNC_HEADER(NoOp)
+{
+ return;
+}
+
+/* Most OC's are allocated in one hunk */
+OC_DESTROY_FUNC_HEADER(OC_PEX)
+{
+ xfree(pExecuteOC); /* was allocated in one hunk */
+ return;
+}
+
+/* others are more chewy */
+OC_DESTROY_FUNC_HEADER(NurbSurface)
+{
+ miNurbSurfaceStruct *ddNurb = (miNurbSurfaceStruct *)(pExecuteOC + 1);
+ listofTrimCurve *ddTrim;
+ ddTrimCurve *ddTC;
+ ddULONG i, j;
+
+ if (!pExecuteOC) return;
+
+ for ( i=0, ddTrim = ddNurb->trimCurves;
+ i < ddNurb->numTrimCurveLists;
+ i++, ddTrim++ ) {
+ if (ddTrim->pTC) {
+ for ( j=0, ddTC = ddTrim->pTC;
+ j < ddTrim->count;
+ j++, ddTC++ ) {
+ if (ddTC->pKnots) xfree(ddTC->pKnots);
+ if (ddTC->points.pts.ptr) xfree(ddTC->points.pts.ptr);
+ else break;
+ }
+ xfree(ddTrim->pTC);
+ } else break;
+ }
+
+ xfree(pExecuteOC);
+
+ return;
+}
+
+/* and sofas have a LOT of stuffing */
+OC_DESTROY_FUNC_HEADER(SOFAS)
+{
+ ddUSHORT i,j;
+ miSOFASStruct *ddFill = (miSOFASStruct *)(pExecuteOC + 1);
+ miConnListList *pCLL;
+ miConnList *pCList;
+
+ if (!pExecuteOC) return;
+
+ for ( i=0, pCLL = ddFill->connects.data;
+ i<ddFill->connects.numListLists;
+ i++, pCLL++) {
+ if (pCLL->pConnLists) {
+ for ( j=0, pCList=(miConnList *)(pCLL->pConnLists);
+ j<pCLL->numLists;
+ j++, pCList++) {
+ if (pCList->pConnects) xfree(pCList->pConnects);
+ else break;
+ }
+ } else break;
+ xfree(pCLL->pConnLists);
+ }
+ xfree(pExecuteOC);
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level2/miFillArea.c b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miFillArea.c
new file mode 100644
index 000000000..1d39115f6
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miFillArea.c
@@ -0,0 +1,1528 @@
+/* $TOG: miFillArea.c /main/11 1998/02/10 12:41:15 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level2/miFillArea.c,v 3.5 1998/10/04 09:34:19 dawes Exp $ */
+
+#include "miLUT.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "ddpex3.h"
+#include "PEXErr.h"
+#include "miStruct.h"
+#include "PEXprotost.h"
+#include "miRender.h"
+#include "gcstruct.h"
+#include "ddpex2.h"
+#include "miLight.h"
+#include "miClip.h"
+#include "pexos.h"
+
+
+static ddpex3rtn Complete_FillArea_Facetlist();
+static ddpex3rtn Calculate_FillArea_Facet_Normal();
+static ddpex3rtn Calculate_FillArea_Vertex_Color_and_Normal();
+
+/*++
+ |
+ | Function Name: miFillArea
+ |
+ | Function Description:
+ | Handles the Fill area 3D, Fill area 2D, Fill area 3D with data,
+ | Fill are set 2D, Fill are set 3D, Fill are set 3D with data ocs.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+miFillArea(pRend, pExecuteOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pExecuteOC;
+/* out */
+{
+/* calls */
+ ddpex3rtn miTransform();
+ ddpex3rtn miConvertVertexColors();
+ ddpex3rtn miConvertFacetColors();
+ ddpex3rtn miLightFillArea();
+ ddpex3rtn miClipFillArea();
+ ddpex3rtn miCullFillArea();
+ ddpex3rtn miRenderFillArea();
+
+/* Local variable definitions */
+ miFillAreaStruct *ddFill = (miFillAreaStruct *)(pExecuteOC+1);
+ miListHeader *input_list = &ddFill->points; /* Input points */
+ ddBitmaskShort shape = ddFill->shape; /* shape hint */
+ ddUCHAR noEdges = ddFill->ignoreEdges; /* edge flag*/
+ listofddFacet *input_facet = ddFill->pFacets; /* facets */
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+
+ miListHeader *color_list,
+ *mc_list,
+ *mc_clist,
+ *wc_list,
+ *light_list,
+ *cc_list,
+ *clip_list,
+ *dcue_list,
+ *cull_list,
+ *dc_list;
+
+ listofddFacet *color_facet,
+ *mc_facet,
+ *wc_facet,
+ *light_facet,
+ *cc_facet,
+ *clip_facet,
+ *cull_facet,
+ *dc_facet;
+
+ listofddPoint *sp;
+ int i, j;
+ ddUSHORT clip_mode;
+ ddpex3rtn status;
+ ddPointType out_type;
+
+ /*
+ * Convert per-vertex and per-facet colors to rendering color model.
+ * Note that this implementation only supports rgb float.
+ */
+
+ if (DD_IsVertColour(input_list->type)) {
+ if (status = miConvertVertexColors(pRend,
+ input_list, PEXRdrColourModelRGB,
+ &color_list))
+ return (status);
+ } else {
+ color_list = input_list;
+ }
+
+ if ((input_facet) && (DD_IsFacetColour(input_facet->type))) {
+ if (status = miConvertFacetColors(pRend,
+ input_facet, PEXRdrColourModelRGB,
+ &color_facet))
+ return (status);
+ } else {
+ color_facet = input_facet;
+ }
+
+ /* Check for Model clipping */
+
+ if (pddc->Dynamic->pPCAttr->modelClip == PEXClip) {
+ /* Compute modelling coord version of clipping volume */
+ ComputeMCVolume(pRend, pddc);
+ clip_mode = MI_MCLIP;
+
+ /* Tranform points to 4D for clipping */
+ out_type = color_list->type;
+ if (status = miTransform(pddc,
+ color_list, &mc_clist,
+ ident4x4,
+ ident4x4,
+ DD_SetVert4D(out_type)))
+ return (status);
+
+
+ if (status = miClipFillArea(pddc, mc_clist, color_facet,
+ &mc_list, &mc_facet, clip_mode))
+ return (status);
+
+ /* if nothing left after modeling clip, return early */
+ if (mc_list->numLists <= 0) return(Success);
+
+ } else {
+ mc_list = color_list;
+ mc_facet = color_facet;
+ }
+
+ clip_mode = MI_VCLIP;
+
+ /*
+ * First, check lighting requirements
+ */
+ if (pddc->Static.attrs->reflModel != PEXReflectionNoShading) {
+
+ /* Transform to WC prior to applying lighting */
+ out_type = mc_list->type;
+ if (DD_IsVertNormal(out_type)) VALIDATEINVTRMCTOWCXFRM(pddc);
+ if (status = miTransform(pddc, mc_list, &wc_list,
+ pddc->Dynamic->mc_to_wc_xform,
+ pddc->Static.misc.inv_tr_mc_to_wc_xform,
+ DD_SetVert4D(out_type)))
+ return (status);
+
+ /* Transform facet normals if necessary */
+ if ((mc_facet) &&
+ (mc_facet->numFacets > 0) &&
+ (DD_IsFacetNormal(mc_facet->type))) {
+ VALIDATEINVTRMCTOWCXFRM(pddc);
+ if (status = miFacetTransform(pddc,
+ mc_facet, &wc_facet,
+ pddc->Static.misc.inv_tr_mc_to_wc_xform))
+ return (status);
+ } else wc_facet = mc_facet;
+
+ /* Apply lighting */
+ if (status = miLightFillArea(pRend, pddc,
+ wc_list, wc_facet,
+ &light_list, &light_facet))
+ return (status);
+
+
+ /* Transform to CC for clipping */
+ if (DD_IsVertNormal(light_list->type)) VALIDATEINVTRWCTOCCXFRM(pddc);
+ if (status = miTransform(pddc, light_list, &cc_list,
+ pddc->Dynamic->wc_to_cc_xform,
+ pddc->Static.misc.inv_tr_wc_to_cc_xform,
+ light_list->type))
+ return (status);
+
+ /* Transform facet normals if necessary */
+ if ( (light_facet) &&
+ (light_facet->numFacets > 0) &&
+ (DD_IsFacetNormal(light_facet->type)) ) {
+ VALIDATEINVTRWCTOCCXFRM(pddc);
+ if (status = miFacetTransform(pddc,
+ light_facet, &cc_facet,
+ pddc->Static.misc.inv_tr_wc_to_cc_xform))
+ return (status);
+ } else cc_facet = light_facet;
+
+ }
+ else {
+
+ out_type = mc_list->type;
+ if (DD_IsVertNormal(out_type)) VALIDATEINVTRMCTOCCXFRM(pddc);
+ if (status = miTransform(pddc, mc_list, &cc_list,
+ pddc->Dynamic->mc_to_cc_xform,
+ pddc->Static.misc.inv_tr_mc_to_cc_xform,
+ DD_SetVert4D(out_type)))
+ return (status);
+
+
+ if ((mc_facet) &&
+ (mc_facet->numFacets > 0) &&
+ (DD_IsFacetNormal(mc_facet->type))) {
+ VALIDATEINVTRMCTOCCXFRM(pddc);
+ if (status = miFacetTransform(pddc,
+ mc_facet, &cc_facet,
+ pddc->Static.misc.inv_tr_mc_to_cc_xform))
+ return (status);
+ } else cc_facet = mc_facet;
+ }
+
+ /* View clip primitive */
+ if (status = miClipFillArea(pddc, cc_list, cc_facet,
+ &clip_list, &clip_facet, clip_mode))
+ return (status);
+
+ /* if nothing left after view clip, return early */
+ if (clip_list->numLists <= 0) return(Success);
+
+ /* Now cull according to current culling mode */
+ if (pddc->Dynamic->pPCAttr->cullMode) {
+ if (status = miCullFillArea(pddc, clip_list, clip_facet,
+ &cull_list, &cull_facet))
+ return (status);
+
+ /* if nothing left after culling, return early */
+ if (cull_list->numLists <= 0) return(Success);
+ clip_list = cull_list;
+ clip_facet = cull_facet;
+ } else {
+ cull_list = clip_list;
+ cull_facet = clip_facet;
+ }
+
+ /* DEPTH CUEING */
+ if (pddc->Dynamic->pPCAttr->depthCueIndex) {
+ miDepthCueFillArea(pRend, cull_list, cull_facet, &dcue_list);
+ cull_list = dcue_list;
+ }
+
+ /* Lastly, transform to DC coordinates */
+ out_type = cull_list->type;
+ DD_SetVert2D(out_type);
+ DD_SetVertShort(out_type);
+ if (DD_IsVertNormal(out_type)) VALIDATEINVTRCCTODCXFRM(pddc);
+ if (status = miTransform(pddc, cull_list, &dc_list,
+ pddc->Dynamic->cc_to_dc_xform,
+ pddc->Static.misc.inv_tr_cc_to_dc_xform,
+ out_type) )
+ return (status);
+
+ /* Transform facet normals if necessary */
+ if ( (clip_facet) &&
+ (clip_facet->numFacets > 0) &&
+ (DD_IsFacetNormal(clip_facet->type)) ) {
+ VALIDATEINVTRCCTODCXFRM(pddc);
+ if (status = miFacetTransform(pddc,
+ clip_facet, &dc_facet,
+ pddc->Static.misc.inv_tr_cc_to_dc_xform))
+ return (status);
+ } else dc_facet = clip_facet;
+
+
+ return (pddc->Static.RenderProcs[FILLAREA_RENDER_TABLE_INDEX](pRend,
+ pddc,
+ dc_list,
+ dc_facet,
+ shape,
+ noEdges));
+}
+
+/*++
+ |
+ | Function Name: miClipFillArea
+ |
+ | Function Description:
+ | Handles the fill area 3D, fill area 2D,
+ | and fill area set 3D with data ocs.
+ |
+ | Note(s):
+ |
+ | This routine uses a Sutherland-Hodgman approach for
+ | polygon clipping. (See, for example, Rodger's "Procedural
+ | Elements for Computer Graphics", pp 169-179)).
+ | Each list is clipped successively against each (enabled)
+ | clipping boundary.
+ |
+ --*/
+ddpex3rtn
+miClipFillArea(pddc, input_vert, input_fct, output_vert, output_fct, clip_mode)
+/* in */
+ miDDContext *pddc;
+ miListHeader *input_vert; /* input vertex data */
+ listofddFacet *input_fct; /* input facet data */
+ miListHeader **output_vert; /* output vertex data */
+ listofddFacet **output_fct; /* output facet data */
+ ddUSHORT clip_mode; /* view or model clipping */
+{
+/* calls */
+ ddpex3rtn miCloseFillArea();
+
+/* uses */
+ ddPointUnion in_ptP, in_ptQ;
+ ddPointUnion out_pt;
+ float t_ptP, t_ptQ;
+ char *in_fct, *out_fct;
+ int point_size;
+ int facet_size;
+ int num_points;
+ int extra_point;
+ int vert_count;
+ miListHeader *input, *output, *list1, *list2;
+ listofddPoint *pddilist;
+ listofddPoint *pddolist;
+ listofddFacet *finput, *foutput, *fct_list1, *fct_list2;
+ int num_lists;
+ int i, j, k, num_planes;
+ ddUSHORT clipflags;
+ ddUSHORT current_clip;
+ int edge_offset, clip_code, pts_inlist;
+ ddULONG *edge_ptr;
+ ddHalfSpace *MC_HSpace;
+ ddpex3rtn status;
+ char do_edges,
+ outside; /* flag to indicate current */
+ /* point of interest is outside */
+
+
+
+ /* Vertex data must be homogeneous for view clipping */
+ if ((clip_mode == MI_VCLIP) && !(DD_IsVert4D(input_vert->type)))
+ return(1);
+
+ /* Insure that the polygon bounds form closed contours */
+ if (status = miCloseFillArea(input_vert)) return(status);
+
+ /* PHIGS specifies a single facet for a set of fill areas */
+ *output_fct = input_fct;
+
+ /*
+ * Use the pre-defined clip lists for output
+ * Note that two buffers are used in "ping-pong" fashion:
+ * first the first buffer is used for output, then the second.
+ */
+ list1 = MI_NEXTTEMPDATALIST(pddc);
+ MI_ALLOCLISTHEADER(list1, MI_ROUND_LISTHEADERCOUNT(input_vert->numLists));
+ if (!list1->ddList) return(BadAlloc);
+
+ list2 = MI_NEXTTEMPDATALIST(pddc);
+ MI_ALLOCLISTHEADER(list2, MI_ROUND_LISTHEADERCOUNT(input_vert->numLists));
+ if (!list2->ddList) return(BadAlloc);
+
+ /*
+ * Must have edge flags in vertex if edges are to be drawn -
+ * otherwise, cannot determine wich edges are "original" and
+ * which edges where added by the clipper.
+ */
+
+ if (pddc->Static.attrs->edges != PEXOff) {
+ do_edges = PEXOn;
+ if (!(DD_IsVertEdge(input_vert->type))) {
+ if (status = miAddEdgeFlag(pddc, input_vert, &list1))
+ return(status);
+ input = list1;
+ } else input = input_vert;
+ } else {
+ do_edges = PEXOff;
+ /* Allocate an initial number of headers */
+ input = input_vert;
+ }
+ /* Note that adding edges will change the input type */
+ list1->type = input->type;
+ list2->type = input->type;
+ list1->flags = input->flags;
+ list2->flags = input->flags;
+ output = list2;
+
+
+ /* Get point size so that this works for all point types */
+ DD_VertPointSize(input->type, point_size);
+ DD_VertOffsetEdge(input->type, edge_offset);
+
+ /*
+ * Each list is now clipped in turn against each (enabled) boundary.
+ */
+
+
+ if (clip_mode == MI_MCLIP) {
+ num_planes = pddc->Static.misc.ms_MCV->numObj;
+ MC_HSpace = (ddHalfSpace *)(pddc->Static.misc.ms_MCV->pList);
+ }
+ else num_planes = 6; /* view clipping to a cube */
+
+ for (i = 0; i < num_planes; i++) {
+ current_clip = 1 << i; /* current_clip is new clip bound */
+
+ num_lists = 0; /* Restart list counter each pass */
+
+ for (j = 0, pddilist = input->ddList, pddolist = output->ddList,
+ output->numLists = 0;
+ j < input->numLists; j++) {
+
+
+ /* Don't process if no points */
+ if ((vert_count = pddilist->numPoints) <= 0) {
+ pddilist++;
+ continue;
+ }
+
+ /*
+ * Insure sufficient room for each vertex.
+ * Note that twice the vertex count is an upper-bound for
+ * a clipped polygon (although there is probably a "tighter fit").
+ */
+ MI_ALLOCLISTOFDDPOINT(pddolist, 2*vert_count, point_size);
+ if (!(out_pt.ptr = (char *)pddolist->pts.ptr)) return(BadAlloc);
+ pts_inlist = 0;
+ clip_code = 0;
+ /* Aquire two points */
+ /* and generate clip code */
+ in_ptP.ptr = pddilist->pts.ptr;
+ COMPUTE_CLIP_PARAMS(in_ptP,t_ptP,0,clip_mode,
+ current_clip,MC_HSpace,clip_code);
+
+ if(!(clip_code)) {
+ COPY_POINT(in_ptP, out_pt, point_size);
+ ++pts_inlist;
+ out_pt.ptr += point_size;
+ }
+
+ in_ptQ.ptr = in_ptP.ptr + point_size;
+
+ for (k = 1; k < pddilist->numPoints; k++){
+
+ COMPUTE_CLIP_PARAMS(in_ptQ, t_ptQ, 1, clip_mode,
+ current_clip,MC_HSpace,clip_code);
+
+ switch(clip_code) {
+ case 0: /* both P and Q are in bounds */
+ COPY_POINT(in_ptQ, out_pt, point_size);
+ out_pt.ptr += point_size;
+ ++pts_inlist;
+ outside = PEXOff;
+ break;
+ case 1: /* P is out, Q is in */
+ CLIP_AND_COPY(input->type, in_ptP, t_ptP,
+ in_ptQ, t_ptQ, out_pt);
+ out_pt.ptr += point_size;
+ COPY_POINT(in_ptQ, out_pt, point_size);
+ out_pt.ptr += point_size;
+ pts_inlist += 2;
+ outside = PEXOff;
+ break;
+ case 2: /* P is in, Q is out */
+ CLIP_AND_COPY(input->type, in_ptQ, t_ptQ,
+ in_ptP, t_ptP, out_pt);
+ if (do_edges == PEXOn) {
+ edge_ptr = (ddULONG *)(out_pt.ptr + edge_offset);
+ *edge_ptr = 0;
+ }
+ out_pt.ptr += point_size;
+ ++pts_inlist;
+ outside = PEXOn;
+ break;
+ case 3: /* both are out */
+ outside = PEXOn;
+ break;
+ }
+
+ in_ptP.ptr = in_ptQ.ptr;
+ t_ptP = t_ptQ;
+ in_ptQ.ptr += point_size;
+ clip_code >>= 1;
+ }
+
+ if (pts_inlist > 1) {
+ if (outside == PEXOn) {
+ /* special case where last segment clipped out. Need to
+ close the fill area */
+ COPY_POINT(pddolist->pts, out_pt, point_size);
+ pts_inlist++;
+ }
+ pddolist->numPoints = pts_inlist;
+ pddolist++;
+ num_lists++;
+
+ }
+
+ /* Now, skip to next input list */
+ pddilist++;
+ }
+
+ /* Complete initialization of output list header */
+ output->numLists = num_lists;
+
+ /* Use result of previous clip for input to next clip */
+ input = output;
+ if (output == list2)
+ output = list1;
+ else output = list2;
+
+ if (clip_mode == MI_MCLIP) MC_HSpace++;
+ } /* end of processing for all planes */
+
+ /* Current input list is last processed (clipped) list */
+ *output_vert = input;
+ return (Success);
+
+}
+
+/*++
+ |
+ | miLightFillArea(pRend, pddc, input_vert, input_fct, output_vert, output_fct)
+ |
+ | Perform lighting calculations for the vertex or facet
+ | data provided according to the current attributes.
+ |
+ --*/
+ddpex3rtn
+miLightFillArea(pRend, pddc, input_vert, input_fct, output_vert, output_fct)
+ ddRendererPtr pRend; /* renderer handle */
+ miDDContext *pddc; /* dd Context pointer */
+ miListHeader *input_vert; /* input vertex data */
+ listofddFacet *input_fct; /* input facet data */
+ miListHeader **output_vert; /* output vertex data */
+ listofddFacet **output_fct; /* output facet data */
+{
+/* calls */
+ ddpex3rtn miApply_Lighting();
+ ddpex3rtn miFilterPath();
+
+/* uses */
+ listofddFacet *fct_list;
+ miListHeader *out_vert;
+ ddRgbFloatNormal *in_fct;
+ ddRgbFloatColour *out_fct;
+ listofddPoint *pddilist;
+ listofddPoint *pddolist;
+ ddRgbFloatNormalPoint4D *in_pt;
+ ddRgbFloatPoint4D *out_pt;
+ int i, j;
+ ddpex3rtn status;
+
+ /*
+ * First, Insure that the vertex and/or facet data
+ * is sufficient for the current Surface Interpolation method.
+ * Note that this implementation does not support
+ * PEXSurfaceInterpDotProduct and PEXSurfaceInterpNormal and
+ * that these surface interpolation types are approximated by
+ * PEXSurfaceInterpColour. The cases dealt with here, therefore,
+ * are constant surface color (thus a single color is computed
+ * per facet) and interpolated surface color (thus a color
+ * per verted is required).
+ */
+ switch(pddc->Static.attrs->surfInterp) {
+
+ case PEXSurfaceInterpNone:
+
+ /*
+ * Insure that input facet data is in proper format
+ * for flat shading.
+ */
+ if ((!input_fct) ||
+ (input_fct->numFacets == 0) ||
+ (!( (DD_IsFacetColour(input_fct->type)) &&
+ (DD_IsFacetNormal(input_fct->type))))) {
+ Complete_FillArea_Facetlist(pddc, input_vert, input_fct,
+ output_fct);
+ input_fct = *output_fct;
+ }
+
+ /*
+ * Should have facets with normals and surface colors now.
+ * Since we are flat shading, there is no further use
+ * for per-vertex color or normal data (however, leave
+ * any edge information). Remove it to prevent confusion
+ * further down the pipeline.
+ */
+ if ( (DD_IsVertNormal(input_vert->type)) ||
+ (DD_IsVertNormal(input_vert->type)) ) {
+ if (status = miFilterPath(pddc, input_vert, output_vert,
+ ((1 << 3) | 1) ))
+ return(status);
+ } else {
+ *output_vert = input_vert;
+ }
+
+ /*
+ * allocate storage for the facet list
+ * Note that the output facet list only contains colors.
+ */
+ *output_fct = fct_list = MI_NEXTTEMPFACETLIST(pddc);
+ fct_list->numFacets = input_fct->numFacets;
+ fct_list->type = DD_FACET_RGBFLOAT;
+ MI_ALLOCLISTOFDDFACET(fct_list, input_fct->numFacets,
+ sizeof(ddRgbFloatColour));
+ if (!(out_fct = fct_list->facets.pFacetRgbFloat)) return(BadAlloc);
+ in_fct = input_fct->facets.pFacetRgbFloatN;
+ pddilist = input_vert->ddList;
+
+ /*
+ * Compute lighted facet color for each facet.
+ * Facet color is simply the sum of the lighting contributions
+ * from each light source.
+ */
+ for (i= 0; i < input_fct->numFacets; i++) {
+ if (status = miApply_Lighting(pRend, pddc,
+ pddilist->pts.p4Dpt,
+ &(in_fct->colour),
+ &(in_fct->normal),
+ out_fct ))
+ return(status);
+
+ in_fct++;
+ out_fct++;
+ pddilist++;
+ }
+ break;
+
+ case PEXSurfaceInterpColour:
+ case PEXSurfaceInterpDotProduct:
+ case PEXSurfaceInterpNormal:
+
+ if ( (!DD_IsVertColour(input_vert->type)) ||
+ (!DD_IsVertNormal(input_vert->type)) ) {
+ Calculate_FillArea_Vertex_Color_and_Normal(pddc, input_vert,
+ input_fct,
+ output_vert);
+ input_vert = *output_vert;
+ }
+
+ /* No further need for per facet data */
+ *output_fct = 0;
+
+ /* Perform shading on a per-vertex basis */
+ if (pddc->Static.attrs->reflModel != PEXReflectionNoShading) {
+
+ /* Use one of the pre-defined 4D list for output */
+ *output_vert = out_vert = MI_NEXTTEMPDATALIST(pddc);
+
+ /* Insure sufficient room for each header */
+ MI_ALLOCLISTHEADER(out_vert, input_vert->numLists)
+ if (!out_vert->ddList) return(BadAlloc);
+
+ out_vert->type = DD_RGBFLOAT_POINT4D;
+ out_vert->numLists = input_vert->numLists;
+ out_vert->flags = input_vert->flags;
+
+ pddilist = input_vert->ddList;
+ pddolist = out_vert->ddList;
+
+ for (i = 0; i < input_vert->numLists; i++) {
+
+ pddolist->numPoints = pddilist->numPoints;
+
+ MI_ALLOCLISTOFDDPOINT(pddolist,(pddilist->numPoints+1),
+ sizeof(ddRgbFloatPoint4D));
+ if (!(out_pt = pddolist->pts.pRgbFloatpt4D)) return(BadAlloc);
+ in_pt = pddilist->pts.pRgbFloatNpt4D;
+
+ for (j = 0; j < pddilist->numPoints; j++)
+ {
+ out_pt->pt = in_pt->pt;
+ if (status = miApply_Lighting(pRend, pddc,
+ &(in_pt->pt),
+ &(in_pt->colour),
+ &(in_pt->normal),
+ &(out_pt->colour)))
+ return(status);
+
+ in_pt++;
+ out_pt++;
+ }
+ pddilist++;
+ pddolist++;
+ }
+
+ }
+
+ break;
+
+ default:
+ *output_vert = input_vert;
+ *output_fct = input_fct;
+
+ }
+
+ return(Success);
+}
+
+/*++
+ |
+ | miCullFillArea(pddc, input_vert, input_fct, output_vert, output_fct)
+ |
+ | Perform lighting calculations for the vertex or facet
+ | data provided according to the current attributes.
+ |
+ --*/
+ddpex3rtn
+miCullFillArea(pddc, input_vert, input_fct, output_vert, output_fct)
+ miDDContext *pddc; /* dd Context pointer */
+ miListHeader *input_vert; /* input vertex data */
+ listofddFacet *input_fct; /* input facet data */
+ miListHeader **output_vert; /* output vertex data */
+ listofddFacet **output_fct; /* output facet data */
+{
+/* uses */
+ miListHeader *out_vert;
+ listofddPoint *pddilist;
+ listofddPoint *pddolist;
+ listofddFacet *fct_list;
+ ddFacetUnion in_fct;
+ ddFacetUnion out_fct;
+ listofddPoint temp;
+ int i, j;
+ char accept;
+ char return_facet_list;
+ int numLists=0;
+ int point_size, facet_size;
+
+ /*
+ * Create facet normals if necessary. These are used to determine
+ * if the facet is to be culled. Note: only return a facet list
+ * if a valid facet list is input.
+ */
+ if ( (!input_fct) || (input_fct->numFacets <= 0) ) {
+ Calculate_FillArea_Facet_Normal(pddc, input_vert,
+ (listofddFacet *)0, &input_fct);
+ return_facet_list = 0;
+ *output_fct = 0;
+
+ } else {
+ if (!(DD_IsFacetNormal(input_fct->type))) {
+ Calculate_FillArea_Facet_Normal(pddc, input_vert,
+ input_fct, output_fct);
+ input_fct = *output_fct;
+ }
+ return_facet_list = 1;
+ }
+
+ /*
+ * allocate storage for the output vertex and facet list
+ */
+ *output_vert = out_vert = MI_NEXTTEMPDATALIST(pddc);
+ out_vert->type = input_vert->type;
+ out_vert->flags = input_vert->flags;
+ MI_ALLOCLISTHEADER(out_vert, input_vert->numLists)
+ if (!out_vert->ddList) return(BadAlloc);
+ pddilist = input_vert->ddList;
+ pddolist = out_vert->ddList;
+ DD_VertPointSize(input_vert->type, point_size);
+
+ fct_list = MI_NEXTTEMPFACETLIST(pddc);
+ fct_list->type = input_fct->type;
+ DDFacetSIZE(input_fct->type, facet_size);
+ MI_ALLOCLISTOFDDFACET(fct_list, input_fct->numFacets, facet_size);
+ out_fct = fct_list->facets;
+ if (!out_fct.pNoFacet) return(BadAlloc);
+ in_fct = input_fct->facets;
+
+
+ /*
+ * This test is performed in NPC space. As a result,
+ * the sign of the z component of the facet normal
+ * indicates the direction in which the facet is pointing.
+ * Therefore if the cullmode is PEXBackFaces and the
+ * z component is negative, reject the facet. Similarily,
+ * if the z component of the normal is positive, and
+ * the cullmode is PEXFrontFaces, also reject the face.
+ * Lastly, note that it is not necessary to copy the vertex
+ * data - it is sufficient to copy the listofddPoint header.
+ * To avoid alloc problems, however, the headers
+ * are interchanged. (As opposed to over-writing the destination
+ * header)
+ */
+ for (i= 0; i < input_fct->numFacets; i++) {
+
+ accept = 0;
+
+ if (pddc->Dynamic->pPCAttr->cullMode == PEXBackFaces) {
+ if (DD_IsFacetColour(input_fct->type)) {
+ if (in_fct.pFacetRgbFloatN->normal.z >= 0) accept = 1;
+ } else if (in_fct.pFacetN->z >= 0) accept = 1;
+ } else /* pddc->Dynamic->pPCAttr->cullMode == PEXFrontFaces */ {
+ if (DD_IsFacetColour(input_fct->type)) {
+ if (in_fct.pFacetRgbFloatN->normal.z < 0) accept = 1;
+ } else if (in_fct.pFacetN->z < 0) accept = 1;
+ }
+
+
+ if (accept) {
+ /* First, swap the listofddPoint headers */
+ temp = *pddilist;
+ *pddilist = *pddolist;
+ *(pddolist++) = temp;
+
+ /* Now, copy the facet info */
+ if (DD_IsFacetColour(input_fct->type))
+ *(out_fct.pFacetRgbFloatN++) = *in_fct.pFacetRgbFloatN;
+ else *(out_fct.pFacetN++) = *in_fct.pFacetN;
+
+ numLists++;
+ }
+
+ pddilist++;
+ if (DD_IsFacetColour(input_fct->type)) in_fct.pFacetRgbFloatN++;
+ else in_fct.pFacetN++;
+ }
+
+ out_vert->numLists = numLists;
+ fct_list->numFacets = numLists;
+
+ /*
+ * Only return facet list if one was passed in. Reduces the
+ * information that must be processed by the rest of the pipeline.
+ */
+ if (return_facet_list) *output_fct = fct_list;
+
+ return(Success);
+}
+
+/*++
+ |
+ | Function Name: miCloseFillArea
+ |
+ | Function Description:
+ | Close each bound in a list of vertex lists. "Closing"
+ | a bound means insuring that the last point in the
+ | bound is the same as the first point. This routine is
+ | used, for example, to close each bound in a polygon
+ | prior to "hollow" style rendering.
+ |
+ | Note(s):
+ | Note this routine does its work in place - the input
+ | list of vertices is (potentially) modified.
+ |
+ --*/
+
+ddpex3rtn
+miCloseFillArea(vinput)
+/* in */
+ miListHeader *vinput;
+{
+/* uses */
+ char *first_pt, *last_pt;
+ listofddPoint *pddlist;
+ int vert_count;
+ int point_size;
+ int i, j;
+ int close;
+
+ pddlist = vinput->ddList;
+ DD_VertPointSize(vinput->type, point_size);
+
+ /*
+ * Close each list.
+ */
+ for (i = 0; i < vinput->numLists; i++) {
+
+ if ((vert_count = pddlist->numPoints) <= 1) {
+ pddlist++;
+ continue;
+ }
+
+ close = 1;
+
+ /*
+ * Insure that the list forms a closed bound.
+ * Note that comparison is point type dependant.
+ */
+ first_pt = (char *)pddlist->pts.p4Dpt;
+ last_pt = ((char *)pddlist->pts.p4Dpt) + (vert_count-1)*point_size;
+
+ if (DD_IsVertFloat(vinput->type)) {
+
+ if ((DD_IsVert2D(vinput->type)) &&
+ (((ddCoord4D *)first_pt)->x == ((ddCoord4D *)last_pt)->x) &&
+ (((ddCoord4D *)first_pt)->y == ((ddCoord4D *)last_pt)->y))
+ close = 0;
+
+ else
+ if ((DD_IsVert3D(vinput->type)) &&
+ (((ddCoord4D *)first_pt)->x == ((ddCoord4D *)last_pt)->x) &&
+ (((ddCoord4D *)first_pt)->y == ((ddCoord4D *)last_pt)->y) &&
+ (((ddCoord4D *)first_pt)->z == ((ddCoord4D *)last_pt)->z))
+ close = 0;
+
+ else
+ if ((((ddCoord4D *)first_pt)->x == ((ddCoord4D *)last_pt)->x) &&
+ (((ddCoord4D *)first_pt)->y == ((ddCoord4D *)last_pt)->y) &&
+ (((ddCoord4D *)first_pt)->z == ((ddCoord4D *)last_pt)->z) &&
+ (((ddCoord4D *)first_pt)->w == ((ddCoord4D *)last_pt)->w))
+ close = 0;
+
+ } else {
+
+ if ((DD_IsVert2D(vinput->type)) &&
+ (((ddCoord3DS *)first_pt)->x == ((ddCoord3DS *)last_pt)->x) &&
+ (((ddCoord3DS *)first_pt)->y == ((ddCoord3DS *)last_pt)->y))
+ close = 0;
+
+ else
+ if ((((ddCoord3DS *)first_pt)->x == ((ddCoord3DS *)last_pt)->x) &&
+ (((ddCoord3DS *)first_pt)->y == ((ddCoord3DS *)last_pt)->y) &&
+ (((ddCoord3DS *)first_pt)->z == ((ddCoord3DS *)last_pt)->z))
+ close = 0;
+
+ }
+
+
+ /*
+ * if close is set then need to close the bound.
+ * Copy the first point to one poast the last point
+ * in the bound.
+ */
+ if (close) {
+
+ /* Insure sufficient room for each vertex */
+ MI_ALLOCLISTOFDDPOINT(pddlist, vert_count+1, point_size);
+ if (!pddlist->pts.p2DSpt) return(BadAlloc);
+
+ /* Insure realloc didn't move array */
+ first_pt = (char *)pddlist->pts.p4Dpt;
+ last_pt = ((char *)pddlist->pts.p4Dpt)
+ + (vert_count * point_size);
+
+ /* copy first point to end of list */
+ /* JSH - assuming copy may overlap */
+ memmove( last_pt, first_pt, point_size);
+
+ /* Increment point count */
+ pddlist->numPoints += 1;
+ }
+
+ /* Now, ski to next input list */
+ pddlist++;
+ }
+ return (Success);
+}
+
+/*++
+ |
+ | Complete_FillArea_Facetlist(pddc, input_vert, input_fct, output_fct)
+ |
+ | Create an output facet list with facet color and normal using
+ | proper precedence rules.
+ |
+ --*/
+static
+ddpex3rtn
+Complete_FillArea_Facetlist(pddc, input_vert, input_fct, output_fct)
+ miDDContext *pddc;
+ miListHeader *input_vert; /* input vertex data */
+ listofddFacet *input_fct; /* input facet data */
+ listofddFacet **output_fct; /* output facet data */
+{
+
+ listofddFacet *fct_list;
+ ddRgbFloatNormal *out_fct;
+ listofddPoint *pddlist;
+ char *in_pt;
+ ddFacetUnion in_fct;
+ int point_size, color_offset, normal_offset;
+ int numPoints;
+ ddCoord3D *vert1, *vert2, *vert3;
+ int i,j;
+ int point_count;
+ float length;
+ char have_colors, have_normals, done;
+
+ have_colors = have_normals = 0;
+
+ /* What data must be added to output facet list ? */
+ if ((input_fct) && (input_fct->type != DD_FACET_NONE)) {
+ in_fct.pNoFacet = input_fct->facets.pNoFacet;
+ if DD_IsFacetNormal(input_fct->type) have_normals = ~0;
+ if DD_IsFacetColour(input_fct->type) have_colors = ~0;
+ }
+
+ if ((have_colors) && (have_normals)) { /* Why are we here? */
+ *output_fct = input_fct;
+ return(Success);
+ }
+
+ /*
+ * Allocate storage for the facet list
+ */
+ fct_list = MI_NEXTTEMPFACETLIST(pddc);
+ MI_ALLOCLISTOFDDFACET(fct_list, 1, sizeof(ddRgbFloatNormal));
+ if (!fct_list->facets.pFacetRgbFloatN) return(BadAlloc);
+ out_fct = (ddRgbFloatNormal *)fct_list->facets.pFacetRgbFloatN;
+
+ DD_VertPointSize(input_vert->type, point_size);
+
+ /*
+ * Compute "intrinsic" color of facet.
+ * There is a "hierarchy" of sources for a facet's intrinsic
+ * color:
+ * vertex_color present? facet_color = vertex_color
+ * else facet_color present? facet_color = facet_color
+ * else facet_color = PC_surface_color
+ * Obviously there is no pre-defined facet color in this routine,
+ * so either use vertex color or surface color from PC.
+ */
+
+ if (DD_IsVertColour(input_vert->type)) {
+ /* Compute average facet color */
+ point_count = 0;
+ pddlist = input_vert->ddList;
+ out_fct->colour.red=out_fct->colour.green=out_fct->colour.blue=0.0;
+ for (i = 0; i < input_vert->numLists; i++, pddlist++) {
+ in_pt = pddlist->pts.ptr;
+ for (j = 0; j < input_vert->numLists;
+ j++, in_pt += point_size, point_count++) {
+ out_fct->colour.red += ((ddRgbFloatPoint4D *)in_pt)->colour.red;
+ out_fct->colour.green += ((ddRgbFloatPoint4D *)in_pt)->colour.green;
+ out_fct->colour.blue += ((ddRgbFloatPoint4D *)in_pt)->colour.blue;
+ }
+ }
+ out_fct->colour.red /= point_count;
+ out_fct->colour.green /= point_count;
+ out_fct->colour.blue /= point_count;
+
+ } else if (have_colors) {
+ out_fct->colour = *in_fct.pFacetRgbFloat;
+
+ } else {
+ /* use front face colors. This needs to get generalized
+ to deal with back-facing attributes*/
+ out_fct->colour = pddc->Static.attrs->surfaceColour.colour.rgbFloat;
+ }
+
+ if (!(have_normals)) {
+
+ done = PEXOff;
+ pddlist = input_vert->ddList;
+
+ for (j = 0; ((j < input_vert->numLists) && !(done)); j++) {
+
+ /* Don't process if insufficient number of points */
+ if ((numPoints = pddlist->numPoints) > 2) {
+
+ in_pt = pddlist->pts.ptr;
+
+ /*
+ * Compute surface normal.
+ * The Surface normal is the cross product of the first
+ * three non-colinear points.
+ */
+
+ vert1 = ((ddCoord3D *)in_pt);
+ in_pt += point_size;
+ vert2 = ((ddCoord3D *)in_pt);
+ in_pt += point_size;
+ vert3 = ((ddCoord3D *)in_pt);
+ in_pt += point_size;
+
+ numPoints -= 3;
+
+ CROSS_PRODUCT(vert1, vert2, vert3, &(out_fct->normal));
+ NORMALIZE_VECTOR(&(out_fct->normal), length);
+
+ while (NEAR_ZERO(length) && (numPoints > 0)) {
+ vert1 = vert2;
+ vert2 = vert3;
+ vert3 = ((ddCoord3D *)in_pt);
+ in_pt += point_size;
+ CROSS_PRODUCT(vert1, vert2, vert3, &(out_fct->normal));
+ NORMALIZE_VECTOR(&(out_fct->normal), length);
+ numPoints--;
+ }
+ if (!(NEAR_ZERO(length))) done = PEXOn; /* :-) */
+
+ }
+ pddlist++;
+ }
+
+ } else {
+ /* use input facet normals */
+ out_fct->normal = *in_fct.pFacetN;
+ }
+
+ fct_list->type = DD_FACET_RGBFLOAT_NORM;
+ fct_list->numFacets = 1;
+
+ *output_fct = fct_list;
+
+ return(Success);
+}
+
+/*++
+ |
+ | Calculate_FillArea_Facet_Normal
+ |
+ | Add facet normals to a facet list.
+ |
+ --*/
+static ddpex3rtn
+Calculate_FillArea_Facet_Normal(pddc, input_vert, input_fct, output_fct)
+ miDDContext *pddc;
+ miListHeader *input_vert; /* input vertex data */
+ listofddFacet *input_fct; /* input facet data */
+ listofddFacet **output_fct; /* output facet data */
+{
+
+ listofddFacet *fct_list;
+ ddRgbFloatColour *in_fct;
+ ddFacetUnion out_fct;
+ listofddPoint *pddlist;
+ char *in_pt;
+ ddVector3D normal;
+ int point_size;
+ int numPoints;
+ ddCoord3D *vert1, *vert2, *vert3;
+ int numfacets;
+ int i, j;
+ float length;
+ char done;
+
+ /* Some quick error checking */
+ if ((input_fct) && (DD_IsFacetNormal(input_fct->type))) return(Success);
+
+ /*
+ * Allocate storage for the output facet list
+ */
+ fct_list = MI_NEXTTEMPFACETLIST(pddc);
+ if ((input_fct) && DD_IsFacetColour(input_fct->type)) {
+ in_fct = input_fct->facets.pFacetRgbFloat;
+ fct_list->type = DD_FACET_RGBFLOAT_NORM;
+ numfacets = 1;
+ MI_ALLOCLISTOFDDFACET(fct_list, 1, sizeof(ddRgbFloatNormal));
+ } else {
+ in_fct = 0;
+ fct_list->type = DD_FACET_NORM;
+ numfacets = 1;
+ MI_ALLOCLISTOFDDFACET(fct_list, 1, sizeof(ddVector3D));
+ }
+
+ fct_list->numFacets = numfacets;
+
+ if (!fct_list->facets.pNoFacet) return(BadAlloc);
+ out_fct = fct_list->facets;
+
+ DD_VertPointSize(input_vert->type, point_size);
+
+ pddlist = input_vert->ddList;
+
+
+ /* Copy the input facet color */
+ if (in_fct) {
+ *out_fct.pFacetRgbFloat = *in_fct;
+ in_fct++;
+ }
+
+ done = PEXOff;
+
+ for(i = 0; ((i < input_vert->numLists) && (!(done))); i++) {
+
+
+ if ((numPoints = pddlist->numPoints) > 2) {
+
+ in_pt = pddlist->pts.ptr;
+
+ /*
+ * Compute surface normal.
+ * The Surface normal is the cross product of the first
+ * three non-colinear points.
+ */
+ numPoints -= 3;
+ vert1 = ((ddCoord3D *)in_pt);
+ in_pt += point_size;
+ vert2 = ((ddCoord3D *)in_pt);
+ in_pt += point_size;
+ vert3 = ((ddCoord3D *)in_pt);
+ in_pt += point_size;
+ CROSS_PRODUCT(vert1, vert2, vert3, &normal);
+ NORMALIZE_VECTOR(&normal, length);
+
+ while (NEAR_ZERO(length) && (--numPoints >= 0)) {
+ vert1 = vert2;
+ vert2 = vert3;
+ vert3 = ((ddCoord3D *)in_pt);
+ in_pt += point_size;
+ CROSS_PRODUCT(vert1, vert2, vert3, &normal);
+ NORMALIZE_VECTOR(&normal, length);
+ }
+
+ /* Initialize to some arbitrary value if degenerate */
+ if (!NEAR_ZERO(length)) {
+ done = PEXOn;
+
+ if (in_fct) (out_fct.pFacetRgbFloatN++)->normal = normal;
+ else *(out_fct.pFacetN++) = normal;
+ }
+ }
+
+ pddlist++;
+ }
+
+ *output_fct = fct_list;
+
+ return(Success);
+}
+
+/*++
+ |
+ | Calculate_FillArea_Vertex_Color_and_Normal
+ |
+ | Add vertex normals and colors to a vertex list.
+ |
+ --*/
+static ddpex3rtn
+Calculate_FillArea_Vertex_Color_and_Normal(pddc, input_vert, input_fct,
+ output_vert)
+ miDDContext *pddc;
+ miListHeader *input_vert; /* input vertex data */
+ listofddFacet *input_fct; /* input facet data */
+ miListHeader **output_vert; /* output vertex data */
+{
+ miListHeader *out_vert;
+ listofddFacet *fct_list;
+ ddRgbFloatNormal *out_fct;
+ listofddPoint *pddilist;
+ listofddPoint *pddolist;
+ ddRgbFloatNormalPoint4D *out_pt;
+ ddPointUnion in_pt;
+ ddFacetUnion in_fct;
+ int point_size, facet_size;
+ int numFacets=0;
+ int numPoints;
+ int i,j;
+ char done;
+
+ /* Some quick error checking */
+ if ((DD_IsVertNormal(input_vert->type)) &&
+ (DD_IsVertColour(input_vert->type)))
+ return(Success);
+
+ /* Use one of the pre-defined 4D list for output */
+ *output_vert = out_vert = MI_NEXTTEMPDATALIST(pddc);
+
+ /* Insure sufficient room for each header */
+ MI_ALLOCLISTHEADER(out_vert, input_vert->numLists)
+ if (!out_vert->ddList) return(BadAlloc);
+
+ out_vert->type = DD_RGBFLOAT_NORM_POINT4D;
+ out_vert->numLists = input_vert->numLists;
+ out_vert->flags = input_vert->flags;
+
+ pddilist = input_vert->ddList;
+ pddolist = out_vert->ddList;
+
+ DD_VertPointSize(input_vert->type, point_size);
+
+ /* Compute facet normals if no per-vertex normals with data */
+ if (!(DD_IsVertNormal(input_vert->type))) {
+
+ if (!(input_fct)) {
+ if (i = Calculate_FillArea_Facet_Normal(pddc, input_vert,
+ input_fct, &fct_list))
+ return(i);
+ input_fct = fct_list;
+
+ }
+
+ else if (!(DD_IsFacetNormal(input_fct->type))) {
+ if (i = Calculate_FillArea_Facet_Normal(pddc, input_vert,
+ input_fct, &fct_list))
+ return(i);
+ input_fct = fct_list;
+ }
+ }
+
+ if ((input_fct) && (input_fct->numFacets > 0))
+ in_fct = input_fct->facets;
+ else in_fct.pNoFacet = 0;
+
+ DDFacetSIZE(input_fct->type, facet_size);
+
+ done = PEXOff;
+
+ for (i = 0; i < input_vert->numLists; i++) {
+
+ pddolist->numPoints = pddilist->numPoints;
+
+ MI_ALLOCLISTOFDDPOINT(pddolist,(pddilist->numPoints+1),
+ sizeof(ddRgbFloatNormalPoint4D));
+ if (!(out_pt = pddolist->pts.pRgbFloatNpt4D)) return(BadAlloc);
+ in_pt = pddilist->pts;
+
+ for (j = 0; j < pddilist->numPoints; j++)
+ {
+ /* First copy over coordinate data */
+ out_pt->pt = *in_pt.p4Dpt;
+
+ /*
+ * Next color
+ * Colour is derived first from the vertex, second from the
+ * facet, and third from the current PC attributes.
+ */
+ if (DD_IsVertColour(input_vert->type))
+ out_pt->colour = in_pt.pRgbFloatpt4D->colour;
+ else if ((in_fct.pNoFacet) && (DD_IsFacetColour(input_fct->type)))
+ out_pt->colour = *in_fct.pFacetRgbFloat;
+ else
+ out_pt->colour = pddc->Static.attrs->surfaceColour.colour.rgbFloat;
+
+ /*
+ * Next normals
+ * Colour is derived first from the vertex, second from the
+ * facet (note that we insured above that there were facet normals).
+ */
+ if (DD_IsVertNormal(input_vert->type))
+ out_pt->normal = in_pt.pNpt4D->normal;
+ else if (DD_IsFacetColour(input_fct->type))
+ out_pt->normal = in_fct.pFacetRgbFloatN->normal;
+ else out_pt->normal = *in_fct.pFacetN;
+
+ out_pt++;
+ in_pt.ptr += point_size;
+ }
+
+ pddilist++;
+ pddolist++;
+ }
+
+ return(Success);
+}
+
+
+
+/*++
+ |
+ | DepthCueFillArea(pRend, input_vert, input_fct, output_vert)
+ |
+ | Applies depth cueing to the vertex colors in a FillArea data list
+ |
+ --*/
+ddpex3rtn
+miDepthCueFillArea(pRend, input_vert, input_fct, output_vert)
+ ddRendererPtr pRend; /* renderer handle */
+ miListHeader *input_vert; /* input vertex data */
+ listofddFacet *input_fct; /* input facet data */
+ miListHeader **output_vert; /* output vertex data */
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ miListHeader *out_vert;
+ listofddFacet *fct_list;
+ ddRgbFloatNormal *out_fct;
+ listofddPoint *pddilist;
+ listofddPoint *pddolist;
+ ddPointUnion in_pt, out_pt;
+ ddRgbFloatColour *in_color;
+ ddFacetUnion in_fct;
+ int point_size, facet_size;
+ int numFacets=0;
+ int numPoints;
+ int i,j,outpoint_size;
+ miColourEntry *pintcolour;
+ ddFLOAT pt_depth;
+ ddULONG colourindex;
+ ddColourSpecifier intcolour;
+ ddUSHORT status;
+ ddDepthCueEntry *dcue_entry;
+
+ /* look for empty list header */
+ if (input_vert->numLists == 0) return(Success);
+
+ /* validate CC version of Depth Cue information */
+ if (pddc->Static.misc.flags & CC_DCUEVERSION)
+ Compute_CC_Dcue(pRend, pddc);
+
+ /* check to make sure depth cuing is enabled */
+ if (pddc->Static.misc.cc_dcue_entry.mode == PEXOff) {
+ *output_vert = input_vert;
+ return(Success);
+ }
+
+ /* Else, depth cue! Use one of the pre-defined 4D list for output */
+ *output_vert = out_vert = MI_NEXTTEMPDATALIST(pddc);
+
+ /* Insure sufficient room for each header */
+ MI_ALLOCLISTHEADER(out_vert, input_vert->numLists)
+ if (!out_vert->ddList) return(BadAlloc);
+
+ out_vert->type = input_vert->type;
+ DD_SetVertRGBFLOAT(out_vert->type);
+ out_vert->numLists = input_vert->numLists;
+ out_vert->flags = input_vert->flags;
+
+ pddilist = input_vert->ddList;
+ pddolist = out_vert->ddList;
+ DD_VertPointSize(input_vert->type, point_size);
+
+ if ((input_fct) && (input_fct->numFacets > 0)){
+ in_fct = input_fct->facets;
+ DDFacetSIZE(input_fct->type, facet_size);
+ }
+ else in_fct.pNoFacet = 0;
+
+ /* Get current surface color if appropriate */
+ if (!(DD_IsVertColour(input_vert->type)) &&
+ (pddc->Static.attrs->surfaceColour.colourType
+ == PEXIndexedColour)) {
+ if ((InquireLUTEntryAddress (PEXColourLUT, pRend->lut[PEXColourLUT],
+ pddc->Static.attrs->surfaceColour.colour.indexed.index,
+ &status, (ddPointer *)&pintcolour)) == PEXLookupTableError)
+ return (PEXLookupTableError);
+ }
+
+ DD_VertPointSize(out_vert->type, outpoint_size);
+
+ for (i = 0; i < input_vert->numLists; i++) {
+
+ pddolist->numPoints = pddilist->numPoints;
+
+ MI_ALLOCLISTOFDDPOINT(pddolist,(pddilist->numPoints+1),
+ outpoint_size);
+ if (!(out_pt.ptr = pddolist->pts.ptr)) return(BadAlloc);
+ in_pt = pddilist->pts;
+
+ for (j = 0; j < pddilist->numPoints; j++) {
+ /* First copy over coordinate data */
+ pt_depth = in_pt.p4Dpt->z;
+ *out_pt.p4Dpt = *in_pt.p4Dpt;
+ in_pt.p4Dpt++;
+ out_pt.p4Dpt++;
+
+ /*
+ * Next color
+ * Colour is derived first from the vertex, second from the
+ * facet, and third from the current PC attributes.
+ */
+
+ if (DD_IsVertColour(input_vert->type)){
+ in_color = in_pt.pRgbFloatClr;
+ in_pt.pRgbFloatClr++;
+ }
+ else {
+ if ((in_fct.pNoFacet) && (DD_IsFacetColour(input_fct->type)))
+ in_color = in_fct.pFacetRgbFloat;
+ else {
+ if (pddc->Static.attrs->surfaceColour.colourType
+ == PEXIndexedColour)
+ in_color = &pintcolour->entry.colour.rgbFloat;
+ else in_color =
+ &(pddc->Static.attrs->surfaceColour.colour.rgbFloat);
+ }
+ }
+
+ APPLY_DEPTH_CUEING(pddc->Static.misc.cc_dcue_entry,
+ pt_depth, in_color, out_pt.pRgbFloatClr)
+
+ out_pt.pRgbFloatClr++;
+
+ /*
+ * Next normals
+ * Colour is derived first from the vertex, second from the
+ * facet (note that we insured above that there were facet normals).
+ */
+
+ if DD_IsVertNormal(input_vert->type) {
+ *out_pt.pNormal = *in_pt.pNormal;
+ in_pt.pNormal++;
+ out_pt.pNormal++;
+ }
+
+ /* Next pass along edge info if there is any */
+ if (DD_IsVertEdge(out_vert->type)) {
+ *out_pt.pEdge = *in_pt.pEdge;
+ in_pt.pEdge++;
+ out_pt.pEdge++;
+ }
+
+
+ }
+
+ pddilist++;
+ pddolist++;
+ }
+
+ return(Success);
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level2/miInquire.c b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miInquire.c
new file mode 100644
index 000000000..54ef871a7
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miInquire.c
@@ -0,0 +1,1389 @@
+/* $TOG: miInquire.c /main/11 1998/02/10 12:41:21 kaleb $ */
+
+/***********************************************************
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution of
+the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level2/miInquire.c,v 3.6 1998/10/04 09:34:20 dawes Exp $ */
+
+
+#include "ddpex.h"
+#include "ddpex3.h"
+#include "PEX.h"
+#include "PEXproto.h"
+#include "pexExtract.h"
+#include "ddpex2.h"
+#include "miStruct.h"
+#include "pexUtils.h"
+#include "pexos.h"
+
+
+/*
+ opposites of parse, although since we know in advance (from storing)
+ the size of the original OC, we only need to one memory allocation
+ per OC, and since all output is written to the pex buffer, only
+ checking for sufficient size and reallocing is necessary
+ */
+
+/*
+ Please note that any routines added to this file may also cause
+ a corresponding modification to the level function tables (miTables.c)
+ */
+
+#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
+#define CAT(a,b) a##b
+#else
+#define CAT(a,b) a/**/b
+#endif
+
+#define OC_INQ_FUNC_HEADER(suffix) \
+ ddpex2rtn CAT(inquire,suffix)(pExecuteOC, pBuf, ppPEXOC) \
+ miGenericElementStr *pExecuteOC; /* internal format */ \
+ ddBuffer *pBuf; \
+ pexElementInfo **ppPEXOC; /* PEX format */
+
+#define COPY_PTR(PTR) ddPointer PTR;
+
+#define LEN_WO_HEADER(OCtype) (pPEXOC->length * sizeof(CARD32) - sizeof(OCtype))
+
+#define GET_INQ_STORAGE(PEX_ST, PEX_TYPE, DD_ST, DD_TYPE) \
+ if (PU_BUF_TOO_SMALL( pBuf, (pExecuteOC->element.pexOClength)<<2)) { \
+ if ((puBuffRealloc(pBuf, (pExecuteOC->element.pexOClength)<<2)) != Success) {\
+ return (BadAlloc); } } \
+ *ppPEXOC = (pexElementInfo *)(pBuf->pBuf); \
+ (*ppPEXOC)->elementType = pExecuteOC->element.elementType; \
+ (*ppPEXOC)->length = pExecuteOC->element.pexOClength; \
+ (PEX_ST) = (PEX_TYPE *)(*ppPEXOC); \
+ DD_ST = (DD_TYPE *)(pExecuteOC + 1);
+
+#define GET_MORE_STORAGE(DD_ST, TYPE, SIZE) \
+ (DD_ST) = (TYPE *)xalloc((unsigned long)(SIZE)); \
+ if (!(DD_ST)) return (BadAlloc);
+
+
+
+
+
+static void
+InqFacetOptData(pFacetList, ptr, rcolourType, rfacetMask, rptr)
+listofddFacet *pFacetList;
+ddPointer ptr;
+INT16 *rcolourType; /* out */
+CARD16 *rfacetMask; /* out */
+ddPointer *rptr; /* out */
+{
+ switch (pFacetList->type) {
+
+ case DD_FACET_INDEX_NORM: {
+ *rfacetMask = PEXGAColour | PEXGANormal;
+ *rcolourType = PEXIndexedColour;
+ PACK_LISTOF_STRUCT( pFacetList->numFacets, ddIndexNormal,
+ pFacetList->facets.pFacetIndexN, ptr);
+ break; }
+
+ case DD_FACET_RGBFLOAT_NORM: {
+ *rfacetMask = PEXGAColour | PEXGANormal;
+ *rcolourType = PEXRgbFloatColour ;
+ PACK_LISTOF_STRUCT( pFacetList->numFacets, ddRgbFloatNormal,
+ pFacetList->facets.pFacetRgbFloatN, ptr);
+ break; }
+
+ case DD_FACET_CIE_NORM: {
+ *rfacetMask = PEXGAColour | PEXGANormal;
+ *rcolourType = PEXCieFloatColour ;
+ PACK_LISTOF_STRUCT( pFacetList->numFacets, ddCieNormal,
+ pFacetList->facets.pFacetCieN, ptr);
+ break; }
+
+ case DD_FACET_HSV_NORM: {
+ *rfacetMask = PEXGAColour | PEXGANormal;
+ *rcolourType = PEXHsvFloatColour ;
+ PACK_LISTOF_STRUCT( pFacetList->numFacets, ddHsvNormal,
+ pFacetList->facets.pFacetHsvN, ptr);
+ break; }
+
+ case DD_FACET_HLS_NORM: {
+ *rfacetMask = PEXGAColour | PEXGANormal;
+ *rcolourType = PEXHlsFloatColour ;
+ PACK_LISTOF_STRUCT( pFacetList->numFacets, ddHlsNormal,
+ pFacetList->facets.pFacetHlsN, ptr);
+ break; }
+
+ case DD_FACET_RGB8_NORM: {
+ *rfacetMask = PEXGAColour | PEXGANormal;
+ *rcolourType = PEXRgb8Colour ;
+ PACK_LISTOF_STRUCT( pFacetList->numFacets, ddRgb8Normal,
+ pFacetList->facets.pFacetRgb8N, ptr);
+ break; }
+
+ case DD_FACET_RGB16_NORM: {
+ *rfacetMask = PEXGAColour | PEXGANormal;
+ *rcolourType = PEXRgb16Colour ;
+ PACK_LISTOF_STRUCT( pFacetList->numFacets, ddRgb16Normal,
+ pFacetList->facets.pFacetRgb16N, ptr);
+ break; }
+
+
+ case DD_FACET_NORM: {
+ *rfacetMask = PEXGANormal;
+ /* return an out of range value instead of 0 */
+ *rcolourType = 666;
+ PACK_LISTOF_STRUCT( pFacetList->numFacets, ddVector3D,
+ pFacetList->facets.pFacetN, ptr);
+ break; }
+
+ case DD_FACET_INDEX: {
+ *rfacetMask = PEXGAColour;
+ *rcolourType = PEXIndexedColour;
+ PACK_LISTOF_STRUCT( pFacetList->numFacets, ddIndexedColour,
+ pFacetList->facets.pFacetIndex, ptr);
+
+ break; }
+
+ case DD_FACET_RGBFLOAT: {
+ *rfacetMask = PEXGAColour;
+ *rcolourType = PEXRgbFloatColour ;
+ PACK_LISTOF_STRUCT( pFacetList->numFacets, ddRgbFloatColour,
+ pFacetList->facets.pFacetRgbFloat, ptr);
+ break; }
+
+ case DD_FACET_CIE: {
+ *rfacetMask = PEXGAColour;
+ *rcolourType = PEXCieFloatColour ;
+ PACK_LISTOF_STRUCT( pFacetList->numFacets, ddCieColour,
+ pFacetList->facets.pFacetCie, ptr);
+ break; }
+
+ case DD_FACET_HSV: {
+ *rfacetMask = PEXGAColour;
+ *rcolourType = PEXHsvFloatColour ;
+ PACK_LISTOF_STRUCT( pFacetList->numFacets, ddHsvColour,
+ pFacetList->facets.pFacetHsv, ptr);
+ break; }
+
+ case DD_FACET_HLS: {
+ *rfacetMask = PEXGAColour;
+ *rcolourType = PEXHlsFloatColour ;
+ PACK_LISTOF_STRUCT( pFacetList->numFacets, ddHlsColour,
+ pFacetList->facets.pFacetHls, ptr);
+ break; }
+
+ case DD_FACET_RGB8: {
+ *rfacetMask = PEXGAColour;
+ *rcolourType = PEXRgb8Colour ;
+ PACK_LISTOF_STRUCT( pFacetList->numFacets, ddRgb8Colour,
+ pFacetList->facets.pFacetRgb8, ptr);
+ break; }
+
+ case DD_FACET_RGB16: {
+ *rfacetMask = PEXGAColour;
+ *rcolourType = PEXRgb16Colour ;
+ PACK_LISTOF_STRUCT( pFacetList->numFacets, ddRgb16Colour,
+ pFacetList->facets.pFacetRgb16, ptr);
+ break; }
+
+ case DD_FACET_NONE: {
+ /* neither Colour nor Normal specified */
+ *rfacetMask = 0;
+ /* return an out of range value instead of 0 */
+ *rcolourType = 666;
+ break; }
+ }
+
+ *rptr = ptr;
+}
+
+
+static void
+InqVertexData(pVertexList, point_type, ptr, rcolourType, rvertexMask, rptr)
+listofddPoint *pVertexList;
+ddPointType point_type;
+ddPointer ptr;
+INT16 *rcolourType; /* out */
+CARD16 *rvertexMask; /* out */
+ddPointer *rptr; /* out */
+{
+ switch (point_type) {
+ case DD_INDEX_NORM_EDGE_POINT: {
+ *rcolourType = PEXIndexedColour;
+ *rvertexMask = PEXGAColour | PEXGANormal | PEXGAEdges;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddIndexNormEdgePoint,
+ pVertexList->pts.pIndexNEpt, ptr);
+ break; }
+
+ case DD_RGBFLOAT_NORM_EDGE_POINT: {
+ *rcolourType = PEXRgbFloatColour;
+ *rvertexMask = PEXGAColour | PEXGANormal | PEXGAEdges;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddRgbFloatNormEdgePoint,
+ pVertexList->pts.pRgbFloatNEpt, ptr);
+ break; }
+
+ case DD_CIE_NORM_EDGE_POINT: {
+ *rcolourType = PEXCieFloatColour;
+ *rvertexMask = PEXGAColour | PEXGANormal | PEXGAEdges;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddCieNormEdgePoint,
+ pVertexList->pts.pCieNEpt, ptr);
+ break; }
+
+ case DD_HSV_NORM_EDGE_POINT: {
+ *rcolourType = PEXHsvFloatColour;
+ *rvertexMask = PEXGAColour | PEXGANormal | PEXGAEdges;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddHsvNormEdgePoint,
+ pVertexList->pts.pHsvNEpt, ptr);
+ break; }
+
+ case DD_HLS_NORM_EDGE_POINT: {
+ *rcolourType = PEXHlsFloatColour;
+ *rvertexMask = PEXGAColour | PEXGANormal | PEXGAEdges;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddHlsNormEdgePoint,
+ pVertexList->pts.pHlsNEpt, ptr);
+ break; }
+
+ case DD_RGB8_NORM_EDGE_POINT: {
+ *rcolourType = PEXRgb8Colour ;
+ *rvertexMask = PEXGAColour | PEXGANormal | PEXGAEdges;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddRgb8NormEdgePoint,
+ pVertexList->pts.pRgb8NEpt, ptr);
+ break; }
+
+ case DD_RGB16_NORM_EDGE_POINT: {
+ *rcolourType = PEXRgb16Colour;
+ *rvertexMask = PEXGAColour | PEXGANormal | PEXGAEdges;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddRgb16NormEdgePoint,
+ pVertexList->pts.pRgb16NEpt, ptr);
+ break; }
+
+ case DD_NORM_EDGE_POINT: {
+ /* take this out to prevent overwrite of valid facet colortype
+ *rcolourType = 0;
+ */
+ *rvertexMask = PEXGANormal | PEXGAEdges;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddNormEdgePoint,
+ pVertexList->pts.pNEpt, ptr);
+ break; }
+
+ case DD_INDEX_NORM_POINT: {
+ *rcolourType = PEXIndexedColour;
+ *rvertexMask = PEXGAColour | PEXGANormal;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddIndexNormalPoint,
+ pVertexList->pts.pIndexNpt, ptr);
+ break; }
+
+ case DD_RGBFLOAT_NORM_POINT: {
+ *rcolourType = PEXRgbFloatColour;
+ *rvertexMask = PEXGAColour | PEXGANormal;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddRgbFloatNormalPoint,
+ pVertexList->pts.pRgbFloatNpt, ptr);
+ break; }
+
+ case DD_CIE_NORM_POINT: {
+ *rcolourType = PEXCieFloatColour;
+ *rvertexMask = PEXGAColour | PEXGANormal;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddCieNormalPoint,
+ pVertexList->pts.pCieNpt, ptr);
+ break; }
+
+ case DD_HSV_NORM_POINT: {
+ *rcolourType = PEXHsvFloatColour;
+ *rvertexMask = PEXGAColour | PEXGANormal;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddHsvNormalPoint,
+ pVertexList->pts.pHsvNpt, ptr);
+ break; }
+
+ case DD_HLS_NORM_POINT: {
+ *rcolourType = PEXHlsFloatColour;
+ *rvertexMask = PEXGAColour | PEXGANormal;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddHlsNormalPoint,
+ pVertexList->pts.pHlsNpt, ptr);
+ break; }
+
+ case DD_RGB8_NORM_POINT: {
+ *rcolourType = PEXRgb8Colour ;
+ *rvertexMask = PEXGAColour | PEXGANormal;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddRgb8NormalPoint,
+ pVertexList->pts.pRgb8Npt, ptr);
+ break; }
+
+ case DD_RGB16_NORM_POINT: {
+ *rcolourType = PEXRgb16Colour;
+ *rvertexMask = PEXGAColour | PEXGANormal;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddRgb16NormalPoint,
+ pVertexList->pts.pRgb16Npt, ptr);
+ break; }
+
+ case DD_NORM_POINT: {
+ /* take this out to prevent overwrite of valid facet colortype
+ *rcolourType = 0;
+ */
+ *rvertexMask = PEXGANormal;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddNormalPoint,
+ pVertexList->pts.pNpt, ptr);
+ break; }
+
+ case DD_INDEX_EDGE_POINT: {
+ *rcolourType = PEXIndexedColour;
+ *rvertexMask = PEXGAColour | PEXGAEdges;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddIndexEdgePoint,
+ pVertexList->pts.pIndexEpt, ptr);
+ break; }
+
+ case DD_RGBFLOAT_EDGE_POINT: {
+ *rcolourType = PEXRgbFloatColour;
+ *rvertexMask = PEXGAColour | PEXGAEdges;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddRgbFloatEdgePoint,
+ pVertexList->pts.pRgbFloatEpt, ptr);
+ break; }
+
+ case DD_CIE_EDGE_POINT: {
+ *rcolourType = PEXCieFloatColour;
+ *rvertexMask = PEXGAColour | PEXGAEdges;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddCieEdgePoint,
+ pVertexList->pts.pCieEpt, ptr);
+ break; }
+
+ case DD_HSV_EDGE_POINT: {
+ *rcolourType = PEXHsvFloatColour;
+ *rvertexMask = PEXGAColour | PEXGAEdges;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddHsvEdgePoint,
+ pVertexList->pts.pHsvEpt, ptr);
+ break; }
+
+ case DD_HLS_EDGE_POINT: {
+ *rcolourType = PEXHlsFloatColour;
+ *rvertexMask = PEXGAColour | PEXGAEdges;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddHlsEdgePoint,
+ pVertexList->pts.pHlsEpt, ptr);
+ break; }
+
+ case DD_RGB8_EDGE_POINT: {
+ *rcolourType = PEXRgb8Colour ;
+ *rvertexMask = PEXGAColour | PEXGAEdges;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddRgb8EdgePoint,
+ pVertexList->pts.pRgb8Ept, ptr);
+ break; }
+
+ case DD_RGB16_EDGE_POINT: {
+ *rcolourType = PEXRgb16Colour;
+ *rvertexMask = PEXGAColour | PEXGAEdges;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddRgb16EdgePoint,
+ pVertexList->pts.pRgb16Ept, ptr);
+ break; }
+
+ case DD_EDGE_POINT: {
+ /* neither Colour nor Normal specified */
+ /* take this out to prevent overwrite of valid facet colortype
+ *rcolourType = 0;
+ */
+ *rvertexMask = 0;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddEdgePoint,
+ pVertexList->pts.pEpt, ptr);
+ break; }
+ case DD_INDEX_POINT: {
+ *rcolourType = PEXIndexedColour;
+ *rvertexMask = PEXGAColour;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddIndexPoint,
+ pVertexList->pts.pIndexpt, ptr);
+ break; }
+
+ case DD_RGBFLOAT_POINT: {
+ *rcolourType = PEXRgbFloatColour;
+ *rvertexMask = PEXGAColour;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddRgbFloatPoint,
+ pVertexList->pts.pRgbFloatpt, ptr);
+ break; }
+
+ case DD_CIE_POINT: {
+ *rcolourType = PEXCieFloatColour;
+ *rvertexMask = PEXGAColour;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddCiePoint,
+ pVertexList->pts.pCiept, ptr);
+ break; }
+
+ case DD_HSV_POINT: {
+ *rcolourType = PEXHsvFloatColour;
+ *rvertexMask = PEXGAColour;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddHsvPoint,
+ pVertexList->pts.pHsvpt, ptr);
+ break; }
+
+ case DD_HLS_POINT: {
+ *rcolourType = PEXHlsFloatColour;
+ *rvertexMask = PEXGAColour;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddHlsPoint,
+ pVertexList->pts.pHlspt, ptr);
+ break; }
+
+ case DD_RGB8_POINT: {
+ *rcolourType = PEXRgb8Colour ;
+ *rvertexMask = PEXGAColour;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddRgb8Point,
+ pVertexList->pts.pRgb8pt, ptr);
+ break; }
+
+ case DD_RGB16_POINT: {
+ *rcolourType = PEXRgb16Colour;
+ *rvertexMask = PEXGAColour;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddRgb16Point,
+ pVertexList->pts.pRgb16pt, ptr);
+ break; }
+
+ case DD_3D_POINT: {
+ /* neither Colour nor Normal specified */
+ /* take this out to prevent overwrite of valid facet colortype
+ *rcolourType = 0;
+ */
+ *rvertexMask = 0;
+ PACK_LISTOF_STRUCT( pVertexList->numPoints, ddCoord3D,
+ pVertexList->pts.p3Dpt, ptr);
+ break; }
+ }
+
+ *rptr = ptr;
+ if (DD_IsVertEdge(point_type)) *rvertexMask |= PEXGAEdges;
+}
+
+
+OC_INQ_FUNC_HEADER(ColourOC)
+{
+ pexMarkerColour *pColour;
+ miColourStruct *ddColour;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE( pColour, pexMarkerColour, ddColour, miColourStruct);
+ ptr = (ddPointer)&(pColour->colourSpec);
+ PACK_CARD16(ddColour->colourType, ptr);
+ SKIP_PADDING(ptr,2);
+
+ switch (ddColour->colourType) {
+ case PEXIndexedColour: {
+ PACK_STRUCT(pexIndexedColour, ddColour->colour.pIndex, ptr);
+ break; }
+ case PEXRgbFloatColour : {
+ PACK_STRUCT(pexRgbFloatColour, ddColour->colour.pRgbFloat, ptr);
+ break; }
+ case PEXCieFloatColour : {
+ PACK_STRUCT(pexCieColour, ddColour->colour.pCie, ptr);
+ break; }
+ case PEXHsvFloatColour : {
+ PACK_STRUCT(pexHsvColour, ddColour->colour.pHsv, ptr);
+ break; }
+ case PEXHlsFloatColour : {
+ PACK_STRUCT(pexHlsColour, ddColour->colour.pHls, ptr);
+ break; }
+ case PEXRgb8Colour : {
+ PACK_STRUCT(pexRgb8Colour, ddColour->colour.pRgb8, ptr);
+ break; }
+ case PEXRgb16Colour : {
+ PACK_STRUCT(pexRgb16Colour, ddColour->colour.pRgb16, ptr);
+ break; }
+ }
+
+ return(Success);
+}
+
+OC_INQ_FUNC_HEADER(ColourIndexOC)
+{
+ miColourStruct *ddColour;
+ pexMarkerColourIndex *pColour;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE(pColour, pexMarkerColourIndex, ddColour, miColourStruct);
+ ptr = (ddPointer)&(pColour->index);
+ PACK_CARD16(ddColour->colour.pIndex->index,ptr);
+
+ return(Success);
+}
+
+OC_INQ_FUNC_HEADER(LightState)
+{
+ miLightStateStruct *ddLightState;
+ pexLightState *pLightState;
+ ddUSHORT i, *pi;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE(pLightState, pexLightState, ddLightState,
+ miLightStateStruct);
+ ptr = (ddPointer)(((pexElementInfo *)pLightState)+1);
+ PACK_CARD16(ddLightState->enableList->numObj, ptr);
+ PACK_CARD16(ddLightState->disableList->numObj, ptr);
+
+ for ( i=0, pi=(ddUSHORT *)(ddLightState->enableList->pList);
+ i<ddLightState->enableList->numObj;
+ i++, pi++ ) {
+ PACK_CARD16(*pi, ptr);
+ }
+
+ SKIP_PADDING(ptr, ((ddLightState->enableList->numObj) %2)*sizeof(CARD16));
+
+ for ( i=0, pi=(ddUSHORT *)(ddLightState->disableList->pList);
+ i<ddLightState->disableList->numObj;
+ i++, pi++ ) {
+ PACK_CARD16(*pi, ptr);
+ }
+
+ return(Success);
+}
+
+OC_INQ_FUNC_HEADER(MCVolume)
+{
+
+ miMCVolume_Struct *ddMCVolume;
+ pexModelClipVolume *pMCVolume;
+
+ ddHalfSpace *ddHS;
+ pexHalfSpace *pHS;
+ ddUSHORT i;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE( pMCVolume, pexModelClipVolume,
+ ddMCVolume, miMCVolume_Struct);
+ ptr = (ddPointer)(((pexElementInfo *)pMCVolume)+1);
+ PACK_CARD16(ddMCVolume->operator, ptr);
+ PACK_CARD16(ddMCVolume->halfspaces->numObj, ptr);
+
+ for ( i=0, ddHS=(ddHalfSpace *)(ddMCVolume->halfspaces->pList);
+ i < ddMCVolume->halfspaces->numObj; i++) {
+
+ PACK_COORD3D(&ddHS->orig_point, ptr);
+ PACK_VECTOR3D(&ddHS->orig_vector, ptr);
+ ddHS++;
+ }
+
+ return(Success);
+}
+
+
+OC_INQ_FUNC_HEADER(MCVolume2D)
+{
+
+ miMCVolume_Struct *ddMCVolume2D;
+ pexModelClipVolume2D *pMCVolume2D;
+
+ ddHalfSpace *ddHS;
+ pexHalfSpace2D *pHS;
+ int i;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE(pMCVolume2D, pexModelClipVolume2D,
+ ddMCVolume2D, miMCVolume_Struct)
+ ptr = (ddPointer)(((pexElementInfo *)pMCVolume2D)+1);
+ PACK_CARD16(ddMCVolume2D->operator, ptr);
+ PACK_CARD16(ddMCVolume2D->halfspaces->numObj, ptr);
+
+ for (i=0, ddHS=(ddHalfSpace *)(ddMCVolume2D->halfspaces->pList),
+ pHS = (pexHalfSpace2D *)(ptr);
+ i < ddMCVolume2D->halfspaces->numObj; i++) {
+
+ PACK_COORD2D(&(ddHS->orig_point), ptr);
+ PACK_VECTOR2D(&(ddHS->orig_vector), ptr);
+ ddHS++;
+ }
+
+ return(Success);
+}
+
+
+OC_INQ_FUNC_HEADER(Marker)
+{
+ miMarkerStruct *ddMarker;
+ pexMarker *pMarker;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE( pMarker, pexMarker, ddMarker, miListHeader);
+ ptr = (ddPointer)(pMarker + 1);
+ PACK_LISTOF_COORD3D( ddMarker->ddList->numPoints,
+ ddMarker->ddList->pts.p3Dpt, ptr);
+
+ return(Success);
+}
+
+
+OC_INQ_FUNC_HEADER(Marker2D)
+{
+ miMarkerStruct *ddMarker;
+ pexMarker2D *pMarker;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE( pMarker, pexMarker2D, ddMarker, miListHeader);
+ ptr = (ddPointer)(pMarker + 1);
+ PACK_LISTOF_COORD2D( ddMarker->ddList->numPoints,
+ ddMarker->ddList->pts.p2Dpt, ptr);
+
+ return(Success);
+}
+
+
+OC_INQ_FUNC_HEADER(Text)
+{
+ miTextStruct *ddText;
+ pexText *pText;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE( pText, pexText, ddText, miTextStruct);
+ ptr = (ddPointer)(((pexElementInfo *)pText)+1);
+ PACK_COORD3D( ddText->pOrigin, ptr);
+ PACK_COORD3D( ddText->pDirections, ptr);
+ PACK_COORD3D( (ddText->pDirections) + 1, ptr);
+ PACK_CARD16(ddText->numEncodings, ptr);
+ SKIP_PADDING(ptr, 2);
+ memcpy( (char *)ptr, (char *)(ddText->pText),
+ (int)( sizeof(CARD32) * pText->head.length
+ - sizeof(pexText)));
+
+ return(Success);
+}
+
+
+OC_INQ_FUNC_HEADER(Text2D)
+{
+ miText2DStruct *ddText;
+ pexText2D *pText;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE( pText, pexText2D, ddText, miText2DStruct);
+ ptr = (ddPointer)(((pexElementInfo *)pText)+1);
+ PACK_COORD2D( ddText->pOrigin, ptr);
+ PACK_CARD16(ddText->numEncodings, ptr);
+ SKIP_PADDING(ptr, 2);
+ memcpy( (char *)ptr, (char *)(ddText->pText),
+ (int)( sizeof(CARD32) * pText->head.length
+ - sizeof(pexText2D)));
+
+ return(Success);
+}
+
+
+OC_INQ_FUNC_HEADER(AnnotationText)
+{
+ miAnnoTextStruct *ddText;
+ pexAnnotationText *pText;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE(pText, pexAnnotationText, ddText, miAnnoTextStruct);
+ ptr = (ddPointer)(((pexElementInfo *)pText)+1);
+ PACK_COORD3D( ddText->pOrigin, ptr);
+ PACK_COORD3D( ddText->pOffset, ptr);
+ PACK_CARD16(ddText->numEncodings, ptr);
+ SKIP_PADDING(ptr, 2);
+ memcpy( (char *)ptr, (char *)(ddText->pText),
+ (int)( sizeof(CARD32) * pText->head.length
+ - sizeof(pexAnnotationText)));
+
+ return(Success);
+}
+
+
+OC_INQ_FUNC_HEADER(AnnotationText2D)
+{
+ miAnnoText2DStruct *ddText;
+ pexAnnotationText2D *pText;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE(pText, pexAnnotationText2D, ddText, miAnnoText2DStruct);
+ ptr = (ddPointer)(((pexElementInfo *)pText)+1);
+ PACK_COORD2D( ddText->pOrigin, ptr);
+ PACK_COORD2D( ddText->pOffset, ptr);
+ PACK_CARD16(ddText->numEncodings, ptr);
+ SKIP_PADDING(ptr, 2);
+ memcpy( (char *)ptr, (char *)(ddText->pText),
+ (int)( sizeof(CARD32) * pText->head.length
+ - sizeof(pexAnnotationText2D)));
+
+ return(Success);
+}
+
+
+OC_INQ_FUNC_HEADER(Polyline2D)
+{
+ miPolylineStruct *ddPoly;
+ pexPolyline2D *pPoly;
+ listofddPoint *ddPoint;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE( pPoly, pexPolyline2D, ddPoly, miListHeader);
+ ptr = (ddPointer)(pPoly + 1);
+ ddPoint = (listofddPoint *)(ddPoly+1);
+ PACK_LISTOF_COORD2D(ddPoint->numPoints,ddPoint->pts.p2Dpt,ptr);
+
+ return(Success);
+}
+
+
+
+OC_INQ_FUNC_HEADER(Polyline)
+{
+ miPolylineStruct *ddPoly;
+ pexPolyline *pPoly;
+ listofddPoint *ddPoint;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE( pPoly, pexPolyline, ddPoly, miListHeader);
+ ptr = (ddPointer)(pPoly + 1);
+ ddPoint = (listofddPoint *)(ddPoly+1);
+ PACK_LISTOF_COORD3D(ddPoint->numPoints,ddPoint->pts.p3Dpt,ptr);
+
+ return(Success);
+}
+
+
+OC_INQ_FUNC_HEADER(PolylineSet)
+{
+ miPolylineStruct *ddPoly;
+ pexPolylineSet *pPoly;
+ listofddPoint *ddPoint;
+ ddUSHORT i;
+ ddPointer rptr = 0;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE( pPoly, pexPolylineSet, ddPoly, miListHeader);
+ ptr = (ddPointer)(pPoly + 1);
+
+ for (i=0, ddPoint = (listofddPoint *)(ddPoly+1);
+ i<ddPoly->numLists;
+ i++, ddPoint++) {
+
+ PACK_CARD32(ddPoint->numPoints, ptr);
+ InqVertexData( ddPoint, ddPoly->type, ptr, &(pPoly->colourType),
+ &(pPoly->vertexAttribs), &rptr);
+ ptr = rptr;
+ }
+
+ pPoly->numLists = ddPoly->numLists;
+ return(Success);
+}
+
+
+OC_INQ_FUNC_HEADER(NurbCurve)
+{
+ miNurbStruct *ddNurb;
+ pexNurbCurve *pNurb;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE( pNurb, pexNurbCurve, ddNurb, miNurbStruct);
+ ptr = (ddPointer)(((pexElementInfo *)pNurb)+1);
+ PACK_CARD16(ddNurb->order, ptr);
+ SKIP_PADDING(ptr, 2); /* type place holder (see below) */
+ PACK_FLOAT(ddNurb->uMin, ptr);
+ PACK_FLOAT(ddNurb->uMax, ptr);
+ PACK_CARD32(ddNurb->numKnots, ptr);
+ PACK_CARD32(ddNurb->points.ddList->numPoints, ptr);
+
+ PACK_LISTOF_STRUCT( ddNurb->numKnots, PEXFLOAT, ddNurb->pKnots, ptr);
+
+ if (ddNurb->points.type == DDPT_4D) {
+ pNurb->coordType = PEXRational;
+ PACK_LISTOF_STRUCT( ddNurb->points.ddList->numPoints, ddCoord4D,
+ ddNurb->points.ddList->pts.p4Dpt, ptr);
+ } else {
+ pNurb->coordType = PEXNonRational;
+ PACK_LISTOF_STRUCT( ddNurb->points.ddList->numPoints, ddCoord3D,
+ ddNurb->points.ddList->pts.p3Dpt, ptr);
+ }
+
+ return(Success);
+}
+
+
+OC_INQ_FUNC_HEADER(FillArea2D)
+{
+ miFillAreaStruct *ddFill;
+ pexFillArea2D *pFill;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE( pFill, pexFillArea2D, ddFill, miFillAreaStruct);
+ ptr = (ddPointer)(((pexElementInfo *)pFill)+1);
+ PACK_CARD16(ddFill->shape, ptr);
+ PACK_CARD8(ddFill->ignoreEdges, ptr);
+ SKIP_PADDING(ptr, 1);
+
+ PACK_LISTOF_COORD2D( ddFill->points.ddList->numPoints,
+ ddFill->points.ddList->pts.p2Dpt,ptr);
+
+ return(Success);
+}
+
+
+
+
+OC_INQ_FUNC_HEADER(FillArea)
+{
+ miFillAreaStruct *ddFill;
+ pexFillArea *pFill;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE( pFill, pexFillArea, ddFill, miFillAreaStruct);
+ ptr = (ddPointer)(((pexElementInfo *)pFill)+1);
+ PACK_CARD16(ddFill->shape, ptr);
+ PACK_CARD8(ddFill->ignoreEdges, ptr);
+ SKIP_PADDING(ptr, 1);
+
+ PACK_LISTOF_COORD3D( ddFill->points.ddList->numPoints,
+ ddFill->points.ddList->pts.p3Dpt, ptr);
+
+ return(Success);
+}
+
+
+OC_INQ_FUNC_HEADER(ExtFillArea)
+{
+ miFillAreaStruct *ddFill;
+ pexExtFillArea *pFill;
+ ddPointer rptr = 0;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE( pFill, pexExtFillArea, ddFill, miFillAreaStruct);
+ ptr = (ddPointer)(((pexElementInfo *)pFill)+1);
+ PACK_CARD16(ddFill->shape, ptr);
+ PACK_CARD8(ddFill->ignoreEdges, ptr);
+
+ ptr = (ddPointer)(pFill+1);
+ PACK_CARD32(ddFill->points.ddList->numPoints, ptr);
+ InqFacetOptData( ddFill->pFacets, ptr, &(pFill->colourType),
+ &(pFill->facetAttribs), &rptr);
+ ptr = rptr;
+
+ InqVertexData( ddFill->points.ddList, ddFill->points.type, ptr,
+ &(pFill->colourType), &(pFill->vertexAttribs), &rptr);
+ ptr = rptr;
+
+ return(Success);
+}
+
+
+OC_INQ_FUNC_HEADER(FillAreaSet2D)
+{
+ miFillAreaStruct *ddFill;
+ pexFillAreaSet2D *pFill;
+ ddULONG i;
+ listofddPoint *ddPoint;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE( pFill, pexFillAreaSet2D, ddFill, miFillAreaStruct);
+ ptr = (ddPointer)(((pexElementInfo *)pFill)+1);
+ PACK_CARD16(ddFill->shape, ptr);
+ PACK_CARD8(ddFill->ignoreEdges, ptr);
+ PACK_CARD8(ddFill->contourHint, ptr);
+
+ PACK_CARD32(ddFill->points.numLists, ptr);
+
+ for (i=0, ddPoint = ddFill->points.ddList;
+ i<ddFill->points.numLists;
+ i++, ddPoint++) {
+
+ PACK_CARD32(ddPoint->numPoints, ptr);
+ PACK_LISTOF_STRUCT( ddPoint->numPoints, ddCoord2D,
+ ddPoint->pts.p2Dpt, ptr);
+ }
+
+ return(Success);
+}
+
+
+OC_INQ_FUNC_HEADER(FillAreaSet)
+{
+ miFillAreaStruct *ddFill;
+ pexFillAreaSet *pFill;
+ ddULONG i;
+ listofddPoint *ddPoint;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE( pFill, pexFillAreaSet, ddFill, miFillAreaStruct);
+ ptr = (ddPointer)(((pexElementInfo *)pFill)+1);
+ PACK_CARD16(ddFill->shape, ptr);
+ PACK_CARD8(ddFill->ignoreEdges, ptr);
+ PACK_CARD8(ddFill->contourHint, ptr);
+
+ PACK_CARD32(ddFill->points.numLists, ptr);
+
+ for (i=0, ddPoint = ddFill->points.ddList;
+ i<ddFill->points.numLists;
+ i++, ddPoint++) {
+
+ PACK_CARD32( ddPoint->numPoints, ptr);
+ PACK_LISTOF_STRUCT( ddPoint->numPoints, ddCoord3D,
+ ddPoint->pts.p3Dpt, ptr);
+ }
+
+ return(Success);
+}
+
+
+OC_INQ_FUNC_HEADER(ExtFillAreaSet)
+{
+ miFillAreaStruct *ddFill;
+ pexExtFillAreaSet *pFill;
+ ddULONG i;
+ listofddPoint *ddPoint;
+ ddPointer rptr = 0;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE(pFill, pexExtFillAreaSet, ddFill, miFillAreaStruct);
+ ptr = (ddPointer)(((pexElementInfo *)pFill)+1);
+ PACK_CARD16(ddFill->shape, ptr);
+ PACK_CARD8(ddFill->ignoreEdges, ptr);
+ PACK_CARD8(ddFill->contourHint, ptr);
+ pFill->numLists = ddFill->points.numLists;
+ ptr = (ddPointer)(pFill+1);
+
+ InqFacetOptData( ddFill->pFacets, ptr, &(pFill->colourType),
+ &(pFill->facetAttribs), &rptr);
+ ptr = rptr;
+
+ for (i=0, ddPoint = ddFill->points.ddList;
+ i<ddFill->points.numLists;
+ i++, ddPoint++) {
+
+ PACK_CARD32( ddPoint->numPoints, ptr);
+ InqVertexData( ddPoint, ddFill->points.type, ptr, &(pFill->colourType),
+ &(pFill->vertexAttribs), &rptr);
+ ptr = rptr;
+ }
+
+ return(Success);
+}
+
+
+OC_INQ_FUNC_HEADER(SOFAS)
+{
+ miSOFASStruct *ddFill;
+ pexSOFAS *pFill;
+ CARD16 i,j;
+ miConnListList *pCLL;
+ miConnList *pCList;
+ ddPointer rptr = 0;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE( pFill, pexSOFAS, ddFill, miSOFASStruct);
+ pFill->shape = ddFill->shape;
+ pFill->edgeAttributes = ddFill->edgeAttribs;
+ pFill->contourHint = ddFill->contourHint;
+ pFill->contourCountsFlag = ddFill->contourCountsFlag;
+ pFill->numFAS = ddFill->numFAS;
+ pFill->numVertices = ddFill->points.ddList->numPoints;
+ pFill->numEdges = ddFill->numEdges;
+ pFill->numContours = ddFill->connects.numListLists;
+
+ ptr = (ddPointer)(pFill+1);
+ InqFacetOptData( &(ddFill->pFacets), ptr, &(pFill->colourType),
+ &(pFill->FAS_Attributes), &rptr);
+ ptr = rptr;
+
+ InqVertexData( ddFill->points.ddList, ddFill->points.type, ptr,
+ &(pFill->colourType), &(pFill->vertexAttributes), &rptr);
+ ptr = rptr;
+
+ if (pFill->edgeAttributes) {
+ PACK_LISTOF_STRUCT(ddFill->numEdges, ddUCHAR, ddFill->edgeData, ptr);
+ SKIP_PADDING(ptr,((((int)((pFill->numEdges + 3)/4))*4)));
+ }
+
+ for (i=0, pCLL = ddFill->connects.data; i<pFill->numContours; i++, pCLL++) {
+ PACK_CARD16(pCLL->numLists,ptr);
+ for (j=0, pCList=pCLL->pConnLists; j<pCLL->numLists; j++, pCList++) {
+ PACK_CARD16(pCList->numLists,ptr);
+ PACK_LISTOF_STRUCT( pCList->numLists, ddUSHORT,
+ pCList->pConnects, ptr);
+ }
+ }
+
+ return(Success);
+}
+
+
+
+OC_INQ_FUNC_HEADER(TriangleStrip)
+{
+ miTriangleStripStruct *ddTriangle;
+ pexTriangleStrip *pTriangle;
+ ddPointer rptr = 0;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE( pTriangle, pexTriangleStrip, ddTriangle,
+ miTriangleStripStruct);
+ pTriangle->numVertices = ddTriangle->points.ddList->numPoints;
+ ptr = (ddPointer)(pTriangle +1);
+
+ InqFacetOptData( ddTriangle->pFacets, ptr, &(pTriangle->colourType),
+ &(pTriangle->facetAttribs), &rptr);
+ ptr = rptr;
+
+ InqVertexData( ddTriangle->points.ddList, ddTriangle->points.type, ptr,
+ &(pTriangle->colourType), &(pTriangle->vertexAttribs),
+ &rptr);
+ ptr = rptr;
+
+ return(Success);
+}
+
+
+OC_INQ_FUNC_HEADER(QuadrilateralMesh)
+{
+ miQuadMeshStruct *ddQuad;
+ pexQuadrilateralMesh *pQuad;
+ ddPointer rptr = 0;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE(pQuad, pexQuadrilateralMesh, ddQuad, miQuadMeshStruct);
+ pQuad->mPts = ddQuad->mPts;
+ pQuad->nPts = ddQuad->nPts;
+ pQuad->shape = ddQuad->shape;
+ ptr = (ddPointer)(pQuad+1);
+
+ InqFacetOptData( ddQuad->pFacets, ptr, &(pQuad->colourType),
+ &(pQuad->facetAttribs), &rptr);
+ ptr = rptr;
+
+ InqVertexData( ddQuad->points.ddList, ddQuad->points.type, ptr,
+ &(pQuad->colourType), &(pQuad->vertexAttribs), &rptr);
+ ptr = rptr;
+
+ return(Success);
+}
+
+
+OC_INQ_FUNC_HEADER(NurbSurface)
+{
+ miNurbSurfaceStruct *ddNurb;
+ pexNurbSurface *pNurb;
+ ddULONG i, j;
+ listofTrimCurve *ddTrim;
+ ddTrimCurve *ddTC;
+ ddUSHORT type;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE( pNurb, pexNurbSurface, ddNurb, miNurbSurfaceStruct);
+ ptr = (ddPointer)(((pexElementInfo *)pNurb)+1);
+
+ SKIP_PADDING(ptr, 2); /* type place holder (see below) */
+ PACK_CARD16(ddNurb->uOrder, ptr);
+ PACK_CARD16(ddNurb->vOrder, ptr);
+ SKIP_PADDING(ptr, 2);
+ PACK_CARD32(ddNurb->numUknots, ptr);
+ PACK_CARD32(ddNurb->numVknots, ptr);
+ PACK_CARD16(ddNurb->mPts, ptr);
+ PACK_CARD16(ddNurb->nPts, ptr);
+ PACK_CARD32(ddNurb->numTrimCurveLists, ptr);
+
+ PACK_LISTOF_STRUCT(ddNurb->numUknots, PEXFLOAT, ddNurb->pUknots, ptr);
+ PACK_LISTOF_STRUCT(ddNurb->numVknots, PEXFLOAT, ddNurb->pVknots, ptr);
+
+ i = ddNurb->mPts * ddNurb->nPts;
+ if (ddNurb->points.type == DD_HOMOGENOUS_POINT) {
+ pNurb->type = PEXRational;
+ PACK_LISTOF_STRUCT(i, ddCoord4D, ddNurb->points.ddList->pts.p4Dpt, ptr);
+ } else {
+ pNurb->type = PEXNonRational;
+ PACK_LISTOF_STRUCT(i, ddCoord3D, ddNurb->points.ddList->pts.p3Dpt, ptr);
+ }
+
+ for (i=0, ddTrim = ddNurb->trimCurves;
+ i<ddNurb->numTrimCurveLists;
+ i++, ddTrim++) {
+
+ PACK_CARD32(ddTrim->count, ptr);
+ for (j=0, ddTC=ddTrim->pTC; j<ddTrim->count; j++, ddTC++) {
+ PACK_CARD8(ddTC->visibility, ptr);
+ SKIP_PADDING(ptr, 1);
+ PACK_CARD16(ddTC->order, ptr);
+ type = (ddTC->pttype = DD_3D_POINT) ? PEXRational : PEXNonRational;
+ PACK_CARD16(type, ptr);
+ PACK_INT16(ddTC->curveApprox.approxMethod, ptr);
+ PACK_FLOAT(ddTC->curveApprox.tolerance, ptr);
+ PACK_FLOAT(ddTC->uMin, ptr);
+ PACK_FLOAT(ddTC->uMax, ptr);
+ PACK_CARD32(ddTC->numKnots, ptr);
+ PACK_CARD32(ddTC->points.numPoints, ptr);
+ PACK_LISTOF_STRUCT(ddTC->numKnots,PEXFLOAT,ddTC->pKnots, ptr);
+ if (ddTC->pttype == DD_3D_POINT) {
+ PACK_LISTOF_STRUCT( ddTC->points.numPoints, ddCoord4D,
+ ddTC->points.pts.p4Dpt, ptr);
+ } else {
+ PACK_LISTOF_STRUCT( ddTC->points.numPoints, ddCoord3D,
+ ddTC->points.pts.p3Dpt, ptr);
+ }
+
+ }
+ }
+
+ return(Success);
+
+}
+
+
+OC_INQ_FUNC_HEADER(CellArray2D)
+{
+ miCellArrayStruct *ddCell;
+ pexCellArray2D *pCell;
+ int i=2;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE( pCell, pexCellArray2D, ddCell, miCellArrayStruct);
+ ptr = (ddPointer)&(pCell->point1);
+
+ PACK_LISTOF_COORD2D(i, ddCell->point.ddList->pts.p2Dpt, ptr);
+
+ PACK_CARD32(ddCell->dx, ptr);
+ PACK_CARD32(ddCell->dy, ptr);
+ i = ddCell->dx * ddCell->dy;
+ PACK_LISTOF_STRUCT(i, ddIndexedColour, ddCell->colours.colour.pIndex, ptr);
+
+ return(Success);
+}
+
+
+OC_INQ_FUNC_HEADER(CellArray)
+{
+ miCellArrayStruct *ddCell;
+ pexCellArray *pCell;
+ int i=3;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE( pCell, pexCellArray, ddCell, miCellArrayStruct);
+ ptr = (ddPointer)&(pCell->point1);
+
+ PACK_LISTOF_COORD3D(i, ddCell->point.ddList->pts.p3Dpt, ptr);
+
+ PACK_CARD32(ddCell->dx, ptr);
+ PACK_CARD32(ddCell->dy, ptr);
+ i = ddCell->dx * ddCell->dy;
+ PACK_LISTOF_STRUCT(i, ddIndexedColour, ddCell->colours.colour.pIndex, ptr);
+
+ return(Success);
+}
+
+
+OC_INQ_FUNC_HEADER(ExtCellArray)
+{
+ miCellArrayStruct *ddCell;
+ pexExtCellArray *pCell;
+ int i=3;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE( pCell, pexExtCellArray, ddCell, miCellArrayStruct);
+ ptr = (ddPointer)&(pCell->colourType);
+
+ PACK_CARD16(ddCell->colours.colourType, ptr);
+ SKIP_PADDING(ptr, 2);
+
+ PACK_LISTOF_COORD3D(i, ddCell->point.ddList->pts.p3Dpt, ptr);
+ PACK_CARD32(ddCell->dx, ptr);
+ PACK_CARD32(ddCell->dy, ptr);
+ i = ddCell->dx * ddCell->dy;
+
+ switch (pCell->colourType) {
+ case PEXIndexedColour: {
+ PACK_LISTOF_STRUCT( i, ddIndexedColour,
+ ddCell->colours.colour.pIndex, ptr);
+ break; }
+ case PEXRgbFloatColour : {
+ PACK_LISTOF_STRUCT( i, ddRgbFloatColour,
+ ddCell->colours.colour.pRgbFloat, ptr);
+ break; }
+ case PEXCieFloatColour : {
+ PACK_LISTOF_STRUCT( i, ddCieColour,
+ ddCell->colours.colour.pCie, ptr);
+ break; }
+ case PEXHsvFloatColour : {
+ PACK_LISTOF_STRUCT( i, ddHsvColour,
+ ddCell->colours.colour.pHsv, ptr);
+ break; }
+ case PEXHlsFloatColour : {
+ PACK_LISTOF_STRUCT( i, ddHlsColour,
+ ddCell->colours.colour.pHls, ptr);
+ break; }
+ case PEXRgb8Colour : {
+ PACK_LISTOF_STRUCT( i, ddRgb8Colour,
+ ddCell->colours.colour.pRgb8, ptr);
+ break; }
+ case PEXRgb16Colour : {
+ PACK_LISTOF_STRUCT( i, ddRgb16Colour,
+ ddCell->colours.colour.pRgb16, ptr);
+ break; }
+ }
+
+ return(Success);
+
+}
+
+
+OC_INQ_FUNC_HEADER(PSurfaceChars)
+{
+ miPSurfaceCharsStruct *ddPSC = (miPSurfaceCharsStruct *)(pExecuteOC+1);
+ pexParaSurfCharacteristics *pPSC;
+ COPY_PTR(ptr);
+
+ switch (ddPSC->type) {
+ case PEXPSCNone:
+ case PEXPSCImpDep:
+ GET_INQ_STORAGE( pPSC, pexParaSurfCharacteristics, ddPSC,
+ miPSurfaceCharsStruct);
+ ptr = (ddPointer)(pPSC+1);
+ break;
+
+ case PEXPSCIsoCurves: {
+ GET_INQ_STORAGE( pPSC, pexParaSurfCharacteristics, ddPSC,
+ miPSurfaceCharsStruct);
+ pPSC->characteristics = ddPSC->type;
+ pPSC->length = 4 * sizeof(CARD16);
+ ptr = (ddPointer)(pPSC+1);
+ PACK_CARD16(ddPSC->data.pIsoCurves->placementType, ptr);
+ SKIP_PADDING(ptr,2);
+ PACK_CARD16(ddPSC->data.pIsoCurves->numUcurves, ptr);
+ PACK_CARD16(ddPSC->data.pIsoCurves->numVcurves, ptr);
+ break;
+ }
+
+ case PEXPSCMcLevelCurves: {
+ GET_INQ_STORAGE( pPSC, pexParaSurfCharacteristics, ddPSC,
+ miPSurfaceCharsStruct);
+ pPSC->characteristics = ddPSC->type;
+ pPSC->length = sizeof(pexCoord3D) + sizeof(pexVector3D) +
+ (2 *sizeof(CARD16)) + (sizeof(PEXFLOAT)*
+ ddPSC->data.pMcLevelCurves->numberIntersections);
+ ptr = (ddPointer)(pPSC+1);
+ PACK_STRUCT(pexCoord3D, &(ddPSC->data.pMcLevelCurves->origin),ptr);
+ PACK_STRUCT(pexVector3D, &(ddPSC->data.pMcLevelCurves->direction),ptr);
+ PACK_CARD16(ddPSC->data.pMcLevelCurves->numberIntersections, ptr);
+ SKIP_PADDING(ptr,2);
+ PACK_LISTOF_STRUCT(ddPSC->data.pMcLevelCurves->numberIntersections,
+ PEXFLOAT, ddPSC->data.pMcLevelCurves->pPoints,
+ ptr);
+ break;
+ }
+
+ case PEXPSCWcLevelCurves: {
+ GET_INQ_STORAGE( pPSC, pexParaSurfCharacteristics, ddPSC,
+ miPSurfaceCharsStruct);
+ pPSC->characteristics = ddPSC->type;
+ pPSC->length = sizeof(pexCoord3D) + sizeof(pexVector3D) +
+ (2 *sizeof(CARD16)) + (sizeof(PEXFLOAT)*
+ ddPSC->data.pWcLevelCurves->numberIntersections);
+ ptr = (ddPointer)(pPSC+1);
+ PACK_STRUCT(pexCoord3D, &(ddPSC->data.pWcLevelCurves->origin),ptr);
+ PACK_STRUCT(pexVector3D, &(ddPSC->data.pWcLevelCurves->direction),ptr);
+ PACK_CARD16(ddPSC->data.pWcLevelCurves->numberIntersections, ptr);
+ SKIP_PADDING(ptr,2);
+ PACK_LISTOF_STRUCT(ddPSC->data.pWcLevelCurves->numberIntersections,
+ PEXFLOAT, ddPSC->data.pWcLevelCurves->pPoints,
+ ptr);
+ break;
+ }
+ }
+
+ pPSC->characteristics = ddPSC->type;
+ pPSC->length=(CARD16)((*ppPEXOC)->length-sizeof(pexParaSurfCharacteristics));
+ return(Success);
+}
+
+
+
+
+OC_INQ_FUNC_HEADER(Gdp2D)
+{
+ miGdpStruct *ddGdp;
+ pexGdp2D *pGdp;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE( pGdp, pexGdp2D, ddGdp, miGdpStruct);
+ pGdp->gdpId = ddGdp->GDPid;
+ pGdp->numPoints = ddGdp->points.ddList->numPoints;
+ pGdp->numBytes = ddGdp->numBytes;
+ ptr = (ddPointer)(pGdp + 1);
+ PACK_LISTOF_COORD2D( ddGdp->points.ddList->numPoints,
+ ddGdp->points.ddList->pts.p2Dpt, ptr);
+ PACK_LISTOF_STRUCT( ddGdp->numBytes, ddUCHAR, ddGdp->pData, ptr);
+
+ return(Success);
+}
+
+
+OC_INQ_FUNC_HEADER(Gdp)
+{
+ miGdpStruct *ddGdp;
+ pexGdp *pGdp;
+ COPY_PTR(ptr);
+
+ GET_INQ_STORAGE( pGdp, pexGdp, ddGdp, miGdpStruct);
+ pGdp->gdpId = ddGdp->GDPid;
+ pGdp->numPoints = ddGdp->points.ddList->numPoints;
+ pGdp->numBytes = ddGdp->numBytes;
+ ptr = (ddPointer)(pGdp + 1);
+ PACK_LISTOF_COORD3D( ddGdp->points.ddList->numPoints,
+ ddGdp->points.ddList->pts.p3Dpt, ptr);
+ PACK_LISTOF_STRUCT( ddGdp->numBytes, ddUCHAR, ddGdp->pData, ptr);
+
+ return(Success);
+
+}
+
+
+
+OC_INQ_FUNC_HEADER(SetAttribute)
+{
+ /** The function vector should be set up to have this
+ ** SetAttribute function as the entry for all of the OC entries other
+ ** than those listed above or those NULL'd out
+ **/
+
+ ddElementInfo *dstAttrib, *srcAttrib;
+
+ GET_INQ_STORAGE( dstAttrib, ddElementInfo, srcAttrib, ddElementInfo);
+
+ memcpy( (char *)dstAttrib, (char *)srcAttrib,
+ (int)(srcAttrib->length * sizeof(CARD32)));
+
+ return(Success);
+}
+
+OC_INQ_FUNC_HEADER(PropOC)
+{
+ /** The function Handles Proprietary Vendor OCs
+ **/
+
+ ddElementInfo *dstPropOC, *srcPropOC;
+
+ GET_INQ_STORAGE( dstPropOC, ddElementInfo, srcPropOC, ddElementInfo);
+
+ memcpy( (char *)dstPropOC, (char *)srcPropOC,
+ (int)(srcPropOC->length * sizeof(CARD32)));
+
+ return(Success);
+}
+
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level2/miLight.c b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miLight.c
new file mode 100644
index 000000000..a3065b0b2
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miLight.c
@@ -0,0 +1,605 @@
+/* $TOG: miLight.c /main/5 1998/02/10 12:41:26 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level2/miLight.c,v 1.7 1998/10/04 09:34:20 dawes Exp $ */
+
+#include "miLUT.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "PEXErr.h"
+#include "miRender.h"
+#include "miLight.h"
+#include "pexos.h"
+
+
+extern ddpex3rtn InquireLUTEntryAddress();
+ddpex3rtn ComputeWCEyePosition();
+
+/*++
+ |
+ | Apply_Lighting(pRend, pddc, input_vert, output_fct)
+ |
+ | Create a facet list for the fill area defined by the
+ | specified vertex list.
+ |
+ | NOTE: This routine does not use back-facing lighting parameters.
+ | Furthermore, it assumes that the input lights are
+ | specified in rgb.
+ |
+ --*/
+ddpex3rtn
+miApply_Lighting(pRend, pddc, point, mat_color, normal, out_color)
+ ddRendererPtr pRend; /* renderer handle */
+ miDDContext *pddc;
+ ddCoord4D *point;
+ ddRgbFloatColour *mat_color;
+ ddVector3D *normal;
+ ddRgbFloatColour *out_color;
+{
+/* calls */
+#ifndef XFree86LOADER
+ double pow();
+#endif
+
+/* uses */
+ listofObj *light_sources = pddc->Dynamic->pPCAttr->lightState;
+ ddUSHORT *index = (ddUSHORT *)light_sources->pList;
+ miLightEntry *pLUT;
+ ddLightEntry *lightentry;
+ ddUSHORT status;
+ ddFLOAT n_dot_l, v_dot_r, d_dot_l;
+ ddFLOAT distance;
+ ddFLOAT atten;
+ ddVector3D view_vec, refl_vec, light_vec;
+ int j;
+
+
+ /* some quick bounds checking */
+ if (light_sources->numObj <= 0) {
+ *out_color = *mat_color;
+ return(Success);
+ }
+
+ out_color->red = out_color->green = out_color->blue = 0.0;
+
+ for (j = 0; j < light_sources->numObj; j++) {
+ /* Fetch light source data from LUT */
+ if ((InquireLUTEntryAddress (PEXLightLUT,
+ pRend->lut[PEXLightLUT], *index,
+ &status, (ddPointer *)(&pLUT)))
+ == PEXLookupTableError)
+ return (PEXLookupTableError);
+
+ lightentry = &pLUT->entry;
+
+ /*
+ * Insure that light color is same model as the current
+ * rendering model.
+ */
+ if (lightentry->lightColour.colourType) {}
+
+ /* The shading equations are different for each light type */
+ switch(lightentry->lightType) {
+
+ case PEXLightAmbient:
+ /*
+ * An ambient light simply adds a constant background
+ * color term to all the facets in a scene.
+ */
+ out_color->red +=
+ pddc->Static.attrs->reflAttr.ambient *
+ (lightentry->lightColour.colour.rgbFloat.red *
+ mat_color->red);
+ out_color->green +=
+ pddc->Static.attrs->reflAttr.ambient *
+ (lightentry->lightColour.colour.rgbFloat.green*
+ mat_color->green);
+ out_color->blue +=
+ pddc->Static.attrs->reflAttr.ambient *
+ (lightentry->lightColour.colour.rgbFloat.blue *
+ mat_color->blue);
+ break;
+
+ case PEXLightWcsVector:
+ /*
+ * A directional light source is located at an
+ * infinite distance from the object along
+ * the specified direction.
+ */
+ n_dot_l = 0.0;
+
+ /* compute reflect view vector */
+ DOT_PRODUCT(&lightentry->direction, normal, n_dot_l);
+ /* negate because light vector should point towards light */
+ n_dot_l = -n_dot_l;
+ if (n_dot_l <= 0.0) break;
+
+ switch(pddc->Static.attrs->reflModel) {
+ /*
+ * Note that the total light source contribution
+ * is the sum of the specular, diffuse and ambient
+ * contributions.
+ */
+ case PEXReflectionSpecular:
+
+ CALCULATE_REFLECTION_VECTOR(&refl_vec, -n_dot_l,
+ normal,
+ &lightentry->direction);
+ refl_vec.x *= -1.0;
+ refl_vec.y *= -1.0;
+ refl_vec.z *= -1.0;
+ NORMALIZE_VECTOR (&refl_vec, v_dot_r);
+
+ /*
+ * Insure eye point is correct for view vector
+ * calculation. As eye_point is computed from
+ * the inverse view matrix, this matrix must
+ * be valid for eye point to be correct.
+ */
+ if (pddc->Static.misc.flags & INVVIEWXFRMFLAG)
+ ComputeWCEyePosition(pRend, pddc);
+
+ if (NEAR_ZERO(pddc->Static.misc.eye_pt.w)) {
+ /*
+ * if the homogeneous component of the eye
+ * position is near zero after the inverse
+ * transform from NPC space, it indicates that
+ * the view transform is an orthographic, as oppposed
+ * to perspective transformation and that the eye
+ * point thus represents a vector rather than a point
+ */
+ view_vec.x = pddc->Static.misc.eye_pt.x;
+ view_vec.y = pddc->Static.misc.eye_pt.y;
+ view_vec.z = pddc->Static.misc.eye_pt.z;
+ } else {
+ /*
+ * Compute the view vector.
+ */
+ CALCULATE_DIRECTION_VECTOR(&pddc->Static.misc.eye_pt,
+ point,
+ &view_vec);
+ NORMALIZE_VECTOR (&view_vec, v_dot_r);
+ }
+
+ DOT_PRODUCT(&refl_vec, &view_vec, v_dot_r);
+ if (v_dot_r > 0.0)
+ {
+ v_dot_r = pow(v_dot_r,
+ pddc->Static.attrs->reflAttr.specularConc);
+ out_color->red +=
+ v_dot_r *
+ pddc->Static.attrs->reflAttr.specular *
+ (lightentry->lightColour.colour.rgbFloat.red *
+ pddc->Static.attrs->reflAttr.specularColour.colour.rgbFloat.red);
+ out_color->green +=
+ v_dot_r *
+ pddc->Static.attrs->reflAttr.specular *
+ (lightentry->lightColour.colour.rgbFloat.green *
+ pddc->Static.attrs->reflAttr.specularColour.colour.rgbFloat.green);
+ out_color->blue +=
+ v_dot_r *
+ pddc->Static.attrs->reflAttr.specular *
+ (lightentry->lightColour.colour.rgbFloat.blue *
+ pddc->Static.attrs->reflAttr.specularColour.colour.rgbFloat.blue);
+ }
+
+ case PEXReflectionDiffuse:
+
+ out_color->red += n_dot_l *
+ pddc->Static.attrs->reflAttr.diffuse *
+ (lightentry->lightColour.colour.rgbFloat.red *
+ mat_color->red);
+ out_color->green += n_dot_l *
+ pddc->Static.attrs->reflAttr.diffuse *
+ (lightentry->lightColour.colour.rgbFloat.green *
+ mat_color->green);
+ out_color->blue += n_dot_l *
+ pddc->Static.attrs->reflAttr.diffuse *
+ (lightentry->lightColour.colour.rgbFloat.blue *
+ mat_color->blue);
+
+ case PEXReflectionAmbient:
+ /* No ambient contribution except from ambient lights */
+
+ break;
+ }
+ break;
+
+ case PEXLightWcsPoint:
+ /*
+ * A point light source is a radiating point source
+ * located at the specified position.
+ */
+ n_dot_l = 0.0;
+ /*
+ * Note that the total light source contribution
+ * is the sum if the specular, diffuse and ambient
+ * contributions.
+ */
+
+ CALCULATE_DIRECTION_VECTOR(&lightentry->point,
+ point,
+ &light_vec);
+ NORMALIZE_VECTOR (&light_vec, distance);
+
+ /* compute reflect view vector */
+ DOT_PRODUCT(&light_vec, normal, n_dot_l);
+ if (n_dot_l <= 0.0) break;
+
+ /* Compute light attenuation */
+ atten = 1.0/(lightentry->attenuation1 +
+ (lightentry->attenuation2 * distance));
+
+ switch(pddc->Static.attrs->reflModel) {
+
+ case PEXReflectionSpecular:
+
+ CALCULATE_REFLECTION_VECTOR(&refl_vec, n_dot_l,
+ normal,
+ &light_vec);
+ NORMALIZE_VECTOR (&refl_vec, v_dot_r);
+
+ /*
+ * Insure eye point is correct for view vector
+ * calculation. As eye_point is computed from
+ * the inverse view matrix, this matrix must
+ * be valid for eye point to be correct.
+ */
+ if (pddc->Static.misc.flags & INVVIEWXFRMFLAG)
+ ComputeWCEyePosition(pRend, pddc);
+
+ if (NEAR_ZERO(pddc->Static.misc.eye_pt.w)) {
+ /*
+ * if the homogeneous component of the eye
+ * position is near zero after the inverse
+ * transform from NPC space, it indicates that
+ * the view transform is an orthographic, as oppposed
+ * to perspective transformation and that the eye
+ * point thus represents a vector rather than a point
+ */
+ view_vec.x = pddc->Static.misc.eye_pt.x;
+ view_vec.y = pddc->Static.misc.eye_pt.y;
+ view_vec.z = pddc->Static.misc.eye_pt.z;
+ } else {
+ /*
+ * Compute the view vector.
+ */
+ CALCULATE_DIRECTION_VECTOR(&pddc->Static.misc.eye_pt,
+ point,
+ &view_vec);
+ NORMALIZE_VECTOR (&view_vec, v_dot_r);
+ }
+
+ DOT_PRODUCT(&refl_vec, &view_vec, v_dot_r);
+ if (v_dot_r > 0.0)
+ {
+ v_dot_r = pow(v_dot_r,
+ pddc->Static.attrs->reflAttr.specularConc);
+ out_color->red +=
+ atten * v_dot_r *
+ pddc->Static.attrs->reflAttr.specular *
+ (lightentry->lightColour.colour.rgbFloat.red *
+ pddc->Static.attrs->reflAttr.specularColour.colour.rgbFloat.red);
+ out_color->green +=
+ atten * v_dot_r *
+ pddc->Static.attrs->reflAttr.specular *
+ (lightentry->lightColour.colour.rgbFloat.green *
+ pddc->Static.attrs->reflAttr.specularColour.colour.rgbFloat.green);
+ out_color->blue +=
+ atten * v_dot_r *
+ pddc->Static.attrs->reflAttr.specular *
+ (lightentry->lightColour.colour.rgbFloat.blue *
+ pddc->Static.attrs->reflAttr.specularColour.colour.rgbFloat.blue);
+ }
+
+ case PEXReflectionDiffuse:
+
+ out_color->red += atten * n_dot_l *
+ pddc->Static.attrs->reflAttr.diffuse *
+ (lightentry->lightColour.colour.rgbFloat.red *
+ mat_color->red);
+ out_color->green += atten * n_dot_l *
+ pddc->Static.attrs->reflAttr.diffuse *
+ (lightentry->lightColour.colour.rgbFloat.green *
+ mat_color->green);
+ out_color->blue += atten * n_dot_l *
+ pddc->Static.attrs->reflAttr.diffuse *
+ (lightentry->lightColour.colour.rgbFloat.blue *
+ mat_color->blue);
+
+ case PEXReflectionAmbient:
+ /* No ambient contribution except from ambient lights */
+ break;
+ }
+ break;
+
+ case PEXLightWcsSpot:
+ /*
+ * A spot light source is a radiating point source
+ * output whose output is limited by a cone of specified
+ * direction and angle.
+ */
+ n_dot_l = 0.0;
+ /*
+ * Note that the total light source contribution
+ * is the sum if the specular, diffuse and ambient
+ * contributions.
+ */
+
+ CALCULATE_DIRECTION_VECTOR(&lightentry->point,
+ point,
+ &light_vec);
+ NORMALIZE_VECTOR (&light_vec, distance);
+
+ /* Check that object is within spot angle. */
+ DOT_PRODUCT(&lightentry->direction, &light_vec, d_dot_l);
+ /* Negate because light vec should point other way for this test */
+ d_dot_l = -d_dot_l;
+ if (d_dot_l <= pLUT->cosSpreadAngle) break;
+ d_dot_l = pow(d_dot_l, lightentry->concentration);
+
+ /* compute reflect view vector */
+ DOT_PRODUCT(&light_vec, normal, n_dot_l);
+ if (n_dot_l <= 0.0) break;
+
+ /* Compute light attenuation */
+ atten = 1.0/(lightentry->attenuation1 +
+ (lightentry->attenuation2 * distance));
+
+ switch(pddc->Static.attrs->reflModel) {
+
+ case PEXReflectionSpecular:
+
+ CALCULATE_REFLECTION_VECTOR(&refl_vec, n_dot_l,
+ normal,
+ &light_vec);
+ NORMALIZE_VECTOR (&refl_vec, v_dot_r);
+
+ /*
+ * Insure eye point is correct for view vector
+ * calculation. As eye_point is computed from
+ * the inverse view matrix, this matrix must
+ * be valid for eye point to be correct.
+ */
+ if (pddc->Static.misc.flags & INVVIEWXFRMFLAG)
+ ComputeWCEyePosition(pRend, pddc);
+
+ if (NEAR_ZERO(pddc->Static.misc.eye_pt.w)) {
+ /*
+ * if the homogeneous component of the eye
+ * position is near zero after the inverse
+ * transform from NPC space, it indicates that
+ * the view transform is an orthographic, as oppposed
+ * to perspective transformation and that the eye
+ * point thus represents a vector rather than a point
+ */
+ view_vec.x = pddc->Static.misc.eye_pt.x;
+ view_vec.y = pddc->Static.misc.eye_pt.y;
+ view_vec.z = pddc->Static.misc.eye_pt.z;
+ } else {
+ /*
+ * Compute the view vector.
+ */
+ CALCULATE_DIRECTION_VECTOR(&pddc->Static.misc.eye_pt,
+ point,
+ &view_vec);
+ NORMALIZE_VECTOR (&view_vec, v_dot_r);
+ }
+
+ DOT_PRODUCT(&refl_vec, &view_vec, v_dot_r);
+ if (v_dot_r > 0.0)
+ {
+ v_dot_r = pow(v_dot_r,
+ pddc->Static.attrs->reflAttr.specularConc);
+ out_color->red +=
+ atten * v_dot_r * d_dot_l *
+ pddc->Static.attrs->reflAttr.specular *
+ (lightentry->lightColour.colour.rgbFloat.red *
+ pddc->Static.attrs->reflAttr.specularColour.colour.rgbFloat.red);
+ out_color->green +=
+ atten * v_dot_r * d_dot_l *
+ pddc->Static.attrs->reflAttr.specular *
+ (lightentry->lightColour.colour.rgbFloat.green *
+ pddc->Static.attrs->reflAttr.specularColour.colour.rgbFloat.green);
+ out_color->blue +=
+ atten * v_dot_r * d_dot_l *
+ pddc->Static.attrs->reflAttr.specular *
+ (lightentry->lightColour.colour.rgbFloat.blue *
+ pddc->Static.attrs->reflAttr.specularColour.colour.rgbFloat.blue);
+ }
+
+ case PEXReflectionDiffuse:
+
+ out_color->red += atten * n_dot_l * d_dot_l *
+ pddc->Static.attrs->reflAttr.diffuse *
+ (lightentry->lightColour.colour.rgbFloat.red *
+ mat_color->red);
+ out_color->green += atten * n_dot_l * d_dot_l *
+ pddc->Static.attrs->reflAttr.diffuse *
+ (lightentry->lightColour.colour.rgbFloat.green *
+ mat_color->green);
+ out_color->blue += atten * n_dot_l * d_dot_l *
+ pddc->Static.attrs->reflAttr.diffuse *
+ (lightentry->lightColour.colour.rgbFloat.blue *
+ mat_color->blue);
+
+ case PEXReflectionAmbient:
+ /* No ambient contribution except from ambient lights */
+ break;
+ }
+ }
+ index++; /* skip to next light source index in list */
+
+ }
+
+ return(Success);
+}
+
+/*++
+ |
+ | ComputeWCEyePosition(pRend, pddc)
+ |
+ | Compute a WC eye position from the inverse view transform.
+ |
+ --*/
+ddpex3rtn ComputeWCEyePosition(pRend, pddc)
+ ddRendererPtr pRend; /* renderer handle */
+ miDDContext *pddc;
+{
+ extern void miMatCopy();
+
+ /* First, update inverse view matrix */
+ miViewEntry *pLUT;
+ ddUSHORT status;
+ ddCoord4D NPCEye;
+ ddFLOAT mag;
+
+ /* Get the view table entry at current view index first */
+ if ((InquireLUTEntryAddress (PEXViewLUT, pRend->lut[PEXViewLUT],
+ pddc->Dynamic->pPCAttr->viewIndex,
+ &status, (ddPointer *)&pLUT))
+ == PEXLookupTableError)
+ return (PEXLookupTableError);
+
+
+ /* Compute the composite [VOM] next */
+/*
+ ddViewEntry *viewbundle;
+ viewbundle = &pLUT->entry;
+ miMatMult (pddc->Static.misc.inv_view_xform,
+ viewbundle->orientation,
+ viewbundle->mapping );
+*/
+
+ if (!pLUT->inv_flag)
+ {
+ /* compute the inverse */
+ miMatCopy(pLUT->vom, pddc->Static.misc.inv_view_xform);
+ miMatInverse(pddc->Static.misc.inv_view_xform);
+ miMatCopy(pddc->Static.misc.inv_view_xform, pLUT->vom_inv);
+ pLUT->inv_flag = MI_TRUE;
+ }
+ else
+ miMatCopy(pLUT->vom_inv, pddc->Static.misc.inv_view_xform);
+
+ /* Clear ddc status flag */
+ pddc->Static.misc.flags &= ~INVVIEWXFRMFLAG;
+
+ /*
+ * Multiply NPC eye point by inverse view matrix
+ * NPC eye point is defined as (0.0, 0.0, 1.0, 0.0) in NPC space
+ */
+ NPCEye.x = 0.0;
+ NPCEye.y = 0.0;
+ NPCEye.z = 1.0;
+ NPCEye.w = 0.0;
+ miTransformPoint(&NPCEye, pddc->Static.misc.inv_view_xform,
+ &pddc->Static.misc.eye_pt);
+
+ /* normalize the result if a eye pint is a vector in WC */
+ if (NEAR_ZERO(pddc->Static.misc.eye_pt.w)) {
+ NORMALIZE_VECTOR (&(pddc->Static.misc.eye_pt), mag);
+ }
+}
+
+
+/*++
+ |
+ | Compute_CC_Dcue(pRend, pddc)
+ |
+ | Compute a CC version of the current depth cue bundle entry
+ |
+ --*/
+ddpex3rtn Compute_CC_Dcue(pRend, pddc)
+ ddRendererPtr pRend; /* renderer handle */
+ miDDContext *pddc;
+{
+ ddpex3rtn miConvertColor();
+
+ ddUSHORT status;
+ miDepthCueEntry *dcue_entry;
+ ddFLOAT *matrix, cc_frontplane, cc_backplane;
+
+ /* Check valid flag */
+ if (!(pddc->Static.misc.flags & CC_DCUEVERSION)) return(Success);
+
+ /* Get current depth cueing information */
+ if ((InquireLUTEntryAddress (PEXDepthCueLUT, pRend->lut[PEXDepthCueLUT],
+ pddc->Dynamic->pPCAttr->depthCueIndex,
+ &status, (ddPointer *)&dcue_entry)) == PEXLookupTableError)
+ return (PEXLookupTableError);
+
+ /* Compute cc versions of front and back planes
+ We assume that the transformation matrix from npc to cc is
+ diagonal, and only tranform the "z" portion */
+
+ matrix = (ddFLOAT *)(pddc->Dynamic->npc_to_cc_xform);
+
+ /* skip to Z translate and scale terms */
+ matrix += 10;
+
+ cc_frontplane = (*matrix * dcue_entry->entry.frontPlane) + *(matrix + 1);
+ cc_backplane = (*matrix * dcue_entry->entry.backPlane) + *(matrix + 1);
+
+ /* copy over relevant info */
+ pddc->Static.misc.cc_dcue_entry.mode = dcue_entry->entry.mode;
+ pddc->Static.misc.cc_dcue_entry.frontScaling =
+ dcue_entry->entry.frontScaling;
+ pddc->Static.misc.cc_dcue_entry.backScaling =
+ dcue_entry->entry.backScaling;
+
+ pddc->Static.misc.cc_dcue_entry.frontPlane = cc_frontplane;
+ pddc->Static.misc.cc_dcue_entry.backPlane = cc_backplane;
+
+ /* Convert depth cue color to proper rendering model during copy */
+ miConvertColor(pRend,
+ &dcue_entry->entry.depthCueColour,
+ pddc->Dynamic->pPCAttr->rdrColourModel,
+ &pddc->Static.misc.cc_dcue_entry.depthCueColour);
+
+ /* validate flag */
+ pddc->Static.misc.flags &= ~CC_DCUEVERSION;
+
+}
+
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level2/miLvl2Tab.c b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miLvl2Tab.c
new file mode 100644
index 000000000..7cb056ca7
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miLvl2Tab.c
@@ -0,0 +1,1143 @@
+/* $TOG: miLvl2Tab.c /main/6 1998/02/10 12:41:32 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS 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.
+
+*/
+
+/* Level II output command handling tables */
+
+#include "mipex.h"
+
+
+/* procedures for PickExecuteOCTable and SearchExecuteOCTable */
+
+extern ddpex2rtn miTestPickGdp3d(),
+ miTestPickGdp2d(),
+ miPickAnnoText3D(),
+ miPickAnnoText2D(),
+ miPickPrimitives(),
+ miTestSearchGdp3d(),
+ miTestSearchGdp2d(),
+ miSearchPrimitives();
+
+/* procedures for ExecuteOCTable */
+
+extern ddpex2rtn miMarkerType(),
+ miMarkerScale(),
+ miMarkerColourOC(),
+ miMarkerBundleIndex(),
+ miTextFontIndex(),
+ miTextPrecision(),
+ miCharExpansion(),
+ miCharSpacing(),
+ miTextColourOC(),
+ miCharHeight(),
+ miCharUpVector(),
+ miTextPath(),
+ miTextAlignment(),
+ miAtextHeight(),
+ miAtextUpVector(),
+ miAtextPath(),
+ miAtextAlignment(),
+ miAtextStyle(),
+ miTextBundleIndex(),
+ miLineType(),
+ miLineWidth(),
+ miLineColourOC(),
+ miCurveApproximation(),
+ miTestSetAttribute(),
+ miLineBundleIndex(),
+ miInteriorStyle(),
+ miTestSetAttribute(),
+ miSurfaceColourOC(),
+ miSurfaceReflAttr(),
+ miSurfaceReflModel(),
+ miSurfaceInterp(),
+ miSurfaceApproximation(),
+ miTestSetAttribute(),
+ miTestColourOC(),
+ miCullingMode(),
+ miInteriorBundleIndex(),
+ miSurfaceEdgeFlag(),
+ miSurfaceEdgeType(),
+ miSurfaceEdgeWidth(),
+ miEdgeColourOC(),
+ miEdgeBundleIndex(),
+ miSetAsfValues(),
+ miLocalTransform(),
+ miLocalTransform2D(),
+ miGlobalTransform(),
+ miGlobalTransform2D(),
+ miModelClip(),
+ miSetMCVolume(),
+ miSetMCVolume(),
+ miRestoreMCV(),
+ miViewIndex(),
+ miLightStateOC(),
+ miPickId(),
+ miColourApproxIndex(),
+ miRenderingColourModel(),
+ miParaSurfCharacteristics(),
+ miAddToNameSet(),
+ miExecuteStructure(),
+ miNoop(),
+ miPolyMarker(),
+ miText3D(),
+ miText2D(),
+ miAnnoText3D(),
+ miAnnoText2D(),
+ miPolyLines(),
+ miNurbsCurve(),
+ miFillArea(),
+ miTriangleStrip(),
+ miQuadMesh(),
+ miSOFAS(),
+ miNurbsSurface(),
+ miCellArray(),
+ miTestExtCellArray(),
+ miTestGDP(),
+ miDepthCueIndex() ;
+
+
+/* for now, use the old parse routines from dipex. These use the
+ * ocs in PEX format and convert them to the original level III
+ * calls and these call the execute procedure directly
+ */
+
+extern ddpex2rtn
+ parseColourOC(),
+ parseLightState(),
+ parseColourIndexOC(),
+ parseApplicationData(),
+ parseGse(),
+ parseMarker(),
+ parseMarker2D(),
+ parseText(),
+ parseText2D(),
+ parseAnnotationText(),
+ parseAnnotationText2D(),
+ parsePolyline(),
+ parsePolyline2D(),
+ parsePolylineSet(),
+ parseNurbCurve(),
+ parseFillArea(),
+ parseFillArea2D(),
+ parseExtFillArea(),
+ parseFillAreaSet(),
+ parseFillAreaSet2D(),
+ parseExtFillAreaSet(),
+ parseTriangleStrip(),
+ parseQuadrilateralMesh(),
+ parseNurbSurface(),
+ parseCellArray(),
+ parseCellArray2D(),
+ parseExtCellArray(),
+ parseGdp(),
+ parseGdp2D(),
+ parseSetAttribute(),
+ parsePropOC(),
+ parseSOFAS(),
+ parsePSurfaceChars(),
+ parseSetMCVolume(),
+ parseSetMCVolume2D();
+
+ocTableType ParseOCTable[] = {
+ parsePropOC, /* 0 dummy entry */
+ parseSetAttribute, /* 1 marker type */
+ parseSetAttribute, /* 2 marker scale */
+ parseColourIndexOC, /* 3 marker colour index */
+ parseColourOC, /* 4 marker colour */
+ parseSetAttribute, /* 5 marker bundle index */
+ parseSetAttribute, /* 6 text font index */
+ parseSetAttribute, /* 7 text precision */
+ parseSetAttribute, /* 8 character expansion */
+ parseSetAttribute, /* 9 character spacing */
+ parseColourIndexOC, /* 10 text colour index */
+ parseColourOC, /* 11 text colour */
+ parseSetAttribute, /* 12 character height */
+ parseSetAttribute, /* 13 character up vector */
+ parseSetAttribute, /* 14 text path */
+ parseSetAttribute, /* 15 text alignment */
+ parseSetAttribute, /* 16 annotation text height */
+ parseSetAttribute, /* 17 annotation text up vector */
+ parseSetAttribute, /* 18 annotation text path */
+ parseSetAttribute, /* 19 annotation text alignment */
+ parseSetAttribute, /* 20 annotation text style */
+ parseSetAttribute, /* 21 text bundle index */
+ parseSetAttribute, /* 22 line type */
+ parseSetAttribute, /* 23 line width */
+ parseColourIndexOC, /* 24 line colour index */
+ parseColourOC, /* 25 line colour */
+ parseSetAttribute, /* 26 curve approximation method */
+ parseSetAttribute, /* 27 polyline interpolation method */
+ parseSetAttribute, /* 28 line bundle index */
+ parseSetAttribute, /* 29 surface interior style */
+ parseSetAttribute, /* 30 surface interior style index */
+ parseColourIndexOC, /* 31 surface colour index */
+ parseColourOC, /* 32 surface colour */
+ parseSetAttribute, /* 33 surface reflection attributes */
+ parseSetAttribute, /* 34 surface reflection model */
+ parseSetAttribute, /* 35 surface interpolation method */
+ parseSetAttribute, /* 36 backface surface interior style */
+ parseSetAttribute, /* 37 backface surface interior style index */
+ parseColourIndexOC, /* 38 backface surface colour index */
+ parseColourOC, /* 39 backface surface colour */
+ parseSetAttribute, /* 40 backface surface reflection
+ * attributes */
+ parseSetAttribute, /* 41 backface surface reflection model */
+ parseSetAttribute, /* 42 backface surface interpolation method */
+ parseSetAttribute, /* 43 surface approximation */
+ parseSetAttribute, /* 44 facet culling mode */
+ parseSetAttribute, /* 45 facet distinguish flag */
+ parseSetAttribute, /* 46 pattern size */
+ parseSetAttribute, /* 47 pattern reference point */
+ parseSetAttribute, /* 48 pattern reference point and vectors */
+ parseSetAttribute, /* 49 interior bundle index */
+ parseSetAttribute, /* 50 surface edge flag */
+ parseSetAttribute, /* 51 surface edge type */
+ parseSetAttribute, /* 52 surface edge width */
+ parseColourIndexOC, /* 53 surface edge colour index */
+ parseColourOC, /* 54 surface edge colour */
+ parseSetAttribute, /* 55 edge bundle index */
+ parseSetAttribute, /* 56 set individual asf */
+ parseSetAttribute, /* 57 local transform 3d */
+ parseSetAttribute, /* 58 local transform 2d */
+ parseSetAttribute, /* 59 global transform 3d */
+ parseSetAttribute, /* 60 global transform 2d */
+ parseSetAttribute, /* 61 model clip */
+ parseSetMCVolume, /* 62 set model clip volume 3d */
+ parseSetMCVolume2D, /* 63 set model clip volume 2d */
+ parseSetAttribute, /* 64 restore model clip volume */
+ parseSetAttribute, /* 65 view index */
+ parseLightState, /* 66 light source state */
+ parseSetAttribute, /* 67 depth cue index */
+ parseSetAttribute, /* 68 pick id */
+ parseSetAttribute, /* 69 hlhsr identifier */
+ parseSetAttribute, /* 70 colour approx index */
+ parseSetAttribute, /* 71 rendering colour model */
+ parsePSurfaceChars, /* 72 parametric surface attributes */
+ parseSetAttribute, /* 73 add names to name set */
+ parseSetAttribute, /* 74 remove names from name set */
+ parseSetAttribute, /* 75 execute structure */
+ parseSetAttribute, /* 76 label */
+ parseSetAttribute, /* 77 application data */
+ parseSetAttribute, /* 78 gse */
+ parseMarker, /* 79 marker 3d */
+ parseMarker2D, /* 80 marker 2d */
+ parseText, /* 81 text3d */
+ parseText2D, /* 82 text2d */
+ parseAnnotationText, /* 83 annotation text3d */
+ parseAnnotationText2D, /* 84 annotation text2d */
+ parsePolyline, /* 85 polyline3d */
+ parsePolyline2D, /* 86 polyline2d */
+ parsePolylineSet, /* 87 polyline set 3d with data */
+ parseNurbCurve, /* 88 non-uniform b spline curve */
+ parseFillArea, /* 89 fill area 3d */
+ parseFillArea2D, /* 90 fill area 2d */
+ parseExtFillArea, /* 91 fill area 3d with data */
+ parseFillAreaSet, /* 92 fill area set 3d */
+ parseFillAreaSet2D, /* 93 fill area set 2d */
+ parseExtFillAreaSet, /* 94 fill area set 3d with data */
+ parseTriangleStrip, /* 95 triangle strip */
+ parseQuadrilateralMesh, /* 96 quadrilateral mesh */
+ parseSOFAS, /* 97 set of fill area sets */
+ parseNurbSurface, /* 98 non-uniform b spline surface */
+ parseCellArray, /* 99 cell array 3d */
+ parseCellArray2D, /* 100 cell array 2d */
+ parseExtCellArray, /* 101 extended cell array 3d */
+ parseGdp, /* 102 gdp 3d */
+ parseGdp2D, /* 103 gdp 2d */
+ parseSetAttribute /* 104 Noop */
+};
+
+extern void destroyOC_PEX(),
+ destroyNoOp(),
+ destroySOFAS(),
+ destroyNurbSurface();
+
+destroyTableType DestroyOCTable[] = {
+ destroyOC_PEX, /* 0 entry for proprietary OCs */
+ destroyOC_PEX, /* 1 marker type */
+ destroyOC_PEX, /* 2 marker scale */
+ destroyOC_PEX, /* 3 marker colour index */
+ destroyOC_PEX, /* 4 marker colour */
+ destroyOC_PEX, /* 5 marker bundle index */
+ destroyOC_PEX, /* 6 text font index */
+ destroyOC_PEX, /* 7 text precision */
+ destroyOC_PEX, /* 8 character expansion */
+ destroyOC_PEX, /* 9 character spacing */
+ destroyOC_PEX, /* 10 text colour index */
+ destroyOC_PEX, /* 11 text colour */
+ destroyOC_PEX, /* 12 character height */
+ destroyOC_PEX, /* 13 character up vector */
+ destroyOC_PEX, /* 14 text path */
+ destroyOC_PEX, /* 15 text alignment */
+ destroyOC_PEX, /* 16 annotation text height */
+ destroyOC_PEX, /* 17 annotation text up vector */
+ destroyOC_PEX, /* 18 annotation text path */
+ destroyOC_PEX, /* 19 annotation text alignment */
+ destroyOC_PEX, /* 20 annotation text style */
+ destroyOC_PEX, /* 21 text bundle index */
+ destroyOC_PEX, /* 22 line type */
+ destroyOC_PEX, /* 23 line width */
+ destroyOC_PEX, /* 24 line colour index */
+ destroyOC_PEX, /* 25 line colour */
+ destroyOC_PEX, /* 26 curve approximation method */
+ destroyOC_PEX, /* 27 polyline interpolation method */
+ destroyOC_PEX, /* 28 line bundle index */
+ destroyOC_PEX, /* 29 surface interior style */
+ destroyOC_PEX, /* 30 surface interior style index */
+ destroyOC_PEX, /* 31 surface colour index */
+ destroyOC_PEX, /* 32 surface colour */
+ destroyOC_PEX, /* 33 surface reflection attributes */
+ destroyOC_PEX, /* 34 surface reflection model */
+ destroyOC_PEX, /* 35 surface interpolation method */
+ destroyOC_PEX, /* 36 backface surface interior style */
+ destroyOC_PEX, /* 37 backface surface interior style index */
+ destroyOC_PEX, /* 38 backface surface colour index */
+ destroyOC_PEX, /* 39 backface surface colour */
+ destroyOC_PEX, /* 40 backface surface reflection */
+ destroyOC_PEX, /* 41 backface surface reflection model */
+ destroyOC_PEX, /* 42 backface surface interpolation method */
+ destroyOC_PEX, /* 43 surface approximation */
+ destroyOC_PEX, /* 44 facet culling mode */
+ destroyOC_PEX, /* 45 facet distinguish flag */
+ destroyOC_PEX, /* 46 pattern size */
+ destroyOC_PEX, /* 47 pattern reference point */
+ destroyOC_PEX, /* 48 pattern reference point and vectors */
+ destroyOC_PEX, /* 49 interior bundle index */
+ destroyOC_PEX, /* 50 surface edge flag */
+ destroyOC_PEX, /* 51 surface edge type */
+ destroyOC_PEX, /* 52 surface edge width */
+ destroyOC_PEX, /* 53 surface edge colour index */
+ destroyOC_PEX, /* 54 surface edge colour */
+ destroyOC_PEX, /* 55 edge bundle index */
+ destroyOC_PEX, /* 56 set individual asf */
+ destroyOC_PEX, /* 57 local transform 3d */
+ destroyOC_PEX, /* 58 local transform 2d */
+ destroyOC_PEX, /* 59 global transform 3d */
+ destroyOC_PEX, /* 60 global transform 2d */
+ destroyOC_PEX, /* 61 model clip */
+ destroyOC_PEX, /* 62 destroy model clip volume 3d */
+ destroyOC_PEX, /* 63 destroy model clip volume 2d */
+ destroyOC_PEX, /* 64 restore model clip volume */
+ destroyOC_PEX, /* 65 view index */
+ destroyOC_PEX, /* 66 light source state */
+ destroyOC_PEX, /* 67 depth cue index */
+ destroyOC_PEX, /* 68 pick id */
+ destroyOC_PEX, /* 69 hlhsr identifier */
+ destroyOC_PEX, /* 70 colour approx index */
+ destroyOC_PEX, /* 71 rendering colour model */
+ destroyOC_PEX, /* 72 parametric surface characteristics */
+ destroyOC_PEX, /* 73 add names to name set */
+ destroyOC_PEX, /* 74 remove names from name set */
+ destroyOC_PEX, /* 75 execute structure */
+ destroyOC_PEX, /* 76 label */
+ destroyOC_PEX, /* 77 application data */
+ destroyOC_PEX, /* 78 gse */
+ destroyOC_PEX, /* 79 marker 3d */
+ destroyOC_PEX, /* 80 marker 2d */
+ destroyOC_PEX, /* 81 text3d */
+ destroyOC_PEX, /* 82 text2d */
+ destroyOC_PEX, /* 83 annotation text3d */
+ destroyOC_PEX, /* 84 annotation text2d */
+ destroyOC_PEX, /* 85 polyline3d */
+ destroyOC_PEX, /* 86 polyline2d */
+ destroyOC_PEX, /* 87 polyline set 3d with data */
+ destroyOC_PEX, /* 88 non-uniform b spline curve */
+ destroyOC_PEX, /* 89 fill area 3d */
+ destroyOC_PEX, /* 90 fill area 2d */
+ destroyOC_PEX, /* 91 fill area 3d with data */
+ destroyOC_PEX, /* 92 fill area set 3d */
+ destroyOC_PEX, /* 93 fill area set 2d */
+ destroyOC_PEX, /* 94 fill area set 3d with data */
+ destroyOC_PEX, /* 95 triangle strip */
+ destroyOC_PEX, /* 96 quadrilateral mesh */
+ destroySOFAS, /* 97 set of fill area sets */
+ destroyNurbSurface, /* 98 non-uniform b spline surface */
+ destroyOC_PEX, /* 99 cell array 3d */
+ destroyOC_PEX, /* 100 cell array 2d */
+ destroyOC_PEX, /* 101 extended cell array 3d */
+ destroyOC_PEX, /* 102 gdp 3d */
+ destroyOC_PEX, /* 103 gdp 2d */
+ destroyOC_PEX /* 104 Noop */
+};
+
+/* initial setup for output command table in renderers */
+
+ocTableType InitExecuteOCTable[] = {
+ miNoop, /* 0 dummy entry */
+ miMarkerType, /* 1 marker type */
+ miMarkerScale, /* 2 marker scale */
+ miMarkerColourOC, /* 3 marker colour index */
+ miMarkerColourOC, /* 4 marker colour */
+ miMarkerBundleIndex, /* 5 marker bundle index */
+ miTextFontIndex, /* 6 text font index */
+ miTextPrecision, /* 7 text precision */
+ miCharExpansion, /* 8 character expansion */
+ miCharSpacing, /* 9 character spacing */
+ miTextColourOC, /* 10 text colour index */
+ miTextColourOC, /* 11 text colour */
+ miCharHeight, /* 12 character height */
+ miCharUpVector, /* 13 character up vector */
+ miTextPath, /* 14 text path */
+ miTextAlignment, /* 15 text alignment */
+ miAtextHeight, /* 16 annotation text height */
+ miAtextUpVector, /* 17 annotation text up vector */
+ miAtextPath, /* 18 annotation text path */
+ miAtextAlignment, /* 19 annotation text alignment */
+ miAtextStyle, /* 20 annotation text style */
+ miTextBundleIndex, /* 21 text bundle index */
+ miLineType, /* 22 line type */
+ miLineWidth, /* 23 line width */
+ miLineColourOC, /* 24 line colour index */
+ miLineColourOC, /* 25 line colour */
+ miCurveApproximation, /* 26 curve approximation method */
+ miTestSetAttribute, /* 27 polyline interpolation method */
+ miLineBundleIndex, /* 28 line bundle index */
+ miInteriorStyle, /* 29 surface interior style */
+ miTestSetAttribute, /* 30 surface interior style index */
+ miSurfaceColourOC, /* 31 surface colour index */
+ miSurfaceColourOC, /* 32 surface colour */
+ miSurfaceReflAttr, /* 33 surface reflection attributes */
+ miSurfaceReflModel, /* 34 surface reflection model */
+ miSurfaceInterp, /* 35 surface interpolation method */
+ miTestSetAttribute, /* 36 backface surface interior style */
+ miTestSetAttribute, /* 37 backface surface interior style index */
+ miTestColourOC, /* 38 backface surface colour index */
+ miTestColourOC, /* 39 backface surface colour */
+ miTestSetAttribute, /* 40 backface surface reflection attributes */
+ miTestSetAttribute, /* 41 backface surface reflection model */
+ miTestSetAttribute, /* 42 backface surface interpolation method */
+ miSurfaceApproximation, /* 43 surface approximation */
+ miCullingMode, /* 44 facet culling mode */
+ miTestSetAttribute, /* 45 facet distinguish flag */
+ miTestSetAttribute, /* 46 pattern size */
+ miTestSetAttribute, /* 47 pattern reference point */
+ miTestSetAttribute, /* 48 pattern reference point and vectors */
+ miInteriorBundleIndex, /* 49 interior bundle index */
+ miSurfaceEdgeFlag, /* 50 surface edge flag */
+ miSurfaceEdgeType, /* 51 surface edge type */
+ miSurfaceEdgeWidth, /* 52 surface edge width */
+ miEdgeColourOC, /* 53 surface edge colour index */
+ miEdgeColourOC, /* 54 surface edge colour */
+ miEdgeBundleIndex, /* 55 edge bundle index */
+ miSetAsfValues, /* 56 set individual asf */
+ miLocalTransform, /* 57 local transform 3d */
+ miLocalTransform2D, /* 58 local transform 2d */
+ miGlobalTransform, /* 59 global transform 3d */
+ miGlobalTransform2D, /* 60 global transform 2d */
+ miModelClip, /* 61 model clip */
+ miSetMCVolume, /* 62 set model clip volume 3d */
+ miSetMCVolume, /* 63 set model clip volume 2d */
+ miRestoreMCV, /* 64 restore model clip volume */
+ miViewIndex, /* 65 view index */
+ miLightStateOC, /* 66 light source state */
+ miDepthCueIndex, /* 67 depth cue index */
+ miPickId, /* 68 pick id */
+ miTestSetAttribute, /* 69 hlhsr identifier */
+ miColourApproxIndex, /* 70 colour approx index */
+ miRenderingColourModel, /* 71 rendering colour model */
+ miParaSurfCharacteristics, /* 72 parametric surface characteristics */
+ miAddToNameSet, /* 73 add names to name set */
+ miAddToNameSet, /* 74 remove names from name set */
+ miExecuteStructure, /* 75 execute structure */
+ miNoop, /* 76 label */
+ miNoop, /* 77 application data */
+ miNoop, /* 78 gse */
+ miPolyMarker, /* 79 marker 3d */
+ miPolyMarker, /* 80 marker 2d */
+ miText3D, /* 81 text3d */
+ miText2D, /* 82 text2d */
+ miAnnoText3D, /* 83 annotation text3d */
+ miAnnoText2D, /* 84 annotation text2d */
+ miPolyLines, /* 85 polyline3d */
+ miPolyLines, /* 86 polyline2d */
+ miPolyLines, /* 87 polyline set 3d with data */
+ miNurbsCurve, /* 88 non-uniform b spline curve */
+ miFillArea, /* 89 fill area 3d */
+ miFillArea, /* 90 fill area 2d */
+ miFillArea, /* 91 fill area 3d with data */
+ miFillArea, /* 92 fill area set 3d */
+ miFillArea, /* 93 fill area set 2d */
+ miFillArea, /* 94 fill area set 3d with data */
+ miTriangleStrip, /* 95 triangle strip */
+ miQuadMesh, /* 96 quadrilateral mesh */
+ miSOFAS, /* 97 set of fill area sets */
+ miNurbsSurface, /* 98 non-uniform b spline surface */
+ miCellArray, /* 99 cell array 3d */
+ miCellArray, /* 100 cell array 2d */
+ miCellArray, /* 101 extended cell array 3d */
+ miTestGDP, /* 102 gdp 3d */
+ miTestGDP, /* 103 gdp 2d */
+ miNoop /* 104 Noop */
+};
+
+/* initial setup for output command table for picking */
+
+ocTableType PickExecuteOCTable[] = {
+ miNoop, /* 0 dummy entry */
+ miMarkerType, /* 1 marker type */
+ miMarkerScale, /* 2 marker scale */
+ miMarkerColourOC, /* 3 marker colour index */
+ miMarkerColourOC, /* 4 marker colour */
+ miMarkerBundleIndex, /* 5 marker bundle index */
+ miTextFontIndex, /* 6 text font index */
+ miTextPrecision, /* 7 text precision */
+ miCharExpansion, /* 8 character expansion */
+ miCharSpacing, /* 9 character spacing */
+ miTextColourOC, /* 10 text colour index */
+ miTextColourOC, /* 11 text colour */
+ miCharHeight, /* 12 character height */
+ miCharUpVector, /* 13 character up vector */
+ miTextPath, /* 14 text path */
+ miTextAlignment, /* 15 text alignment */
+ miAtextHeight, /* 16 annotation text height */
+ miAtextUpVector, /* 17 annotation text up vector */
+ miAtextPath, /* 18 annotation text path */
+ miAtextAlignment, /* 19 annotation text alignment */
+ miAtextStyle, /* 20 annotation text style */
+ miTextBundleIndex, /* 21 text bundle index */
+ miLineType, /* 22 line type */
+ miLineWidth, /* 23 line width */
+ miLineColourOC, /* 24 line colour index */
+ miLineColourOC, /* 25 line colour */
+ miCurveApproximation, /* 26 curve approximation method */
+ miTestSetAttribute, /* 27 polyline interpolation method */
+ miLineBundleIndex, /* 28 line bundle index */
+ miInteriorStyle, /* 29 surface interior style */
+ miTestSetAttribute, /* 30 surface interior style index */
+ miSurfaceColourOC, /* 31 surface colour index */
+ miSurfaceColourOC, /* 32 surface colour */
+ miSurfaceReflAttr, /* 33 surface reflection attributes */
+ miSurfaceReflModel, /* 34 surface reflection model */
+ miSurfaceInterp, /* 35 surface interpolation method */
+ miTestSetAttribute, /* 36 backface surface interior style */
+ miTestSetAttribute, /* 37 backface surface interior style index */
+ miTestColourOC, /* 38 backface surface colour index */
+ miTestColourOC, /* 39 backface surface colour */
+ miTestSetAttribute, /* 40 backface surface reflection attributes */
+ miTestSetAttribute, /* 41 backface surface reflection model */
+ miTestSetAttribute, /* 42 backface surface interpolation method */
+ miSurfaceApproximation, /* 43 surface approximation */
+ miCullingMode, /* 44 facet culling mode */
+ miTestSetAttribute, /* 45 facet distinguish flag */
+ miTestSetAttribute, /* 46 pattern size */
+ miTestSetAttribute, /* 47 pattern reference point */
+ miTestSetAttribute, /* 48 pattern reference point and vectors */
+ miInteriorBundleIndex, /* 49 interior bundle index */
+ miSurfaceEdgeFlag, /* 50 surface edge flag */
+ miSurfaceEdgeType, /* 51 surface edge type */
+ miSurfaceEdgeWidth, /* 52 surface edge width */
+ miEdgeColourOC, /* 53 surface edge colour index */
+ miEdgeColourOC, /* 54 surface edge colour */
+ miEdgeBundleIndex, /* 55 edge bundle index */
+ miSetAsfValues, /* 56 set individual asf */
+ miLocalTransform, /* 57 local transform 3d */
+ miLocalTransform2D, /* 58 local transform 2d */
+ miGlobalTransform, /* 59 global transform 3d */
+ miGlobalTransform2D, /* 60 global transform 2d */
+ miModelClip, /* 61 model clip */
+ miSetMCVolume, /* 62 set model clip volume 3d */
+ miSetMCVolume, /* 63 set model clip volume 2d */
+ miRestoreMCV, /* 64 restore model clip volume */
+ miViewIndex, /* 65 view index */
+ miLightStateOC, /* 66 light source state */
+ miDepthCueIndex, /* 67 depth cue index */
+ miPickId, /* 68 pick id */
+ miTestSetAttribute, /* 69 hlhsr identifier */
+ miColourApproxIndex, /* 70 colour approx index */
+ miRenderingColourModel, /* 71 rendering colour model */
+ miParaSurfCharacteristics, /* 72 parametric surface characteristics */
+ miAddToNameSet, /* 73 add names to name set */
+ miAddToNameSet, /* 74 remove names from name set */
+ miExecuteStructure, /* 75 execute structure */
+ miNoop, /* 76 label */
+ miNoop, /* 77 application data */
+ miNoop, /* 78 gse */
+ miPickPrimitives, /* 79 marker 3d */
+ miPickPrimitives, /* 80 marker 2d */
+ miPickPrimitives, /* 81 text3d */
+ miPickPrimitives, /* 82 text2d */
+ miPickAnnoText3D, /* 83 annotation text3d */
+ miPickAnnoText2D, /* 84 annotation text2d */
+ miPickPrimitives, /* 85 polyline3d */
+ miPickPrimitives, /* 86 polyline2d */
+ miPickPrimitives, /* 87 polyline set 3d with data */
+ miPickPrimitives, /* 88 non-uniform b spline curve */
+ miPickPrimitives, /* 89 fill area 3d */
+ miPickPrimitives, /* 90 fill area 2d */
+ miPickPrimitives, /* 91 fill area 3d with data */
+ miPickPrimitives, /* 92 fill area set 3d */
+ miPickPrimitives, /* 93 fill area set 2d */
+ miPickPrimitives, /* 94 fill area set 3d with data */
+ miPickPrimitives, /* 95 triangle strip */
+ miPickPrimitives, /* 96 quadrilateral mesh */
+ miPickPrimitives, /* 97 set of fill area sets */
+ miPickPrimitives, /* 98 non-uniform b spline surface */
+ miPickPrimitives, /* 99 cell array 3d */
+ miPickPrimitives, /* 100 cell array 2d */
+ miPickPrimitives, /* 101 extended cell array 3d */
+ miTestPickGdp3d, /* 102 gdp 3d */
+ miTestPickGdp2d, /* 103 gdp 2d */
+ miNoop /* 104 Noop */
+};
+
+
+/* initial setup for output command table for searching */
+
+ocTableType SearchExecuteOCTable[] = {
+ miNoop, /* 0 dummy entry */
+ miMarkerType, /* 1 marker type */
+ miMarkerScale, /* 2 marker scale */
+ miMarkerColourOC, /* 3 marker colour index */
+ miMarkerColourOC, /* 4 marker colour */
+ miMarkerBundleIndex, /* 5 marker bundle index */
+ miTextFontIndex, /* 6 text font index */
+ miTextPrecision, /* 7 text precision */
+ miCharExpansion, /* 8 character expansion */
+ miCharSpacing, /* 9 character spacing */
+ miTextColourOC, /* 10 text colour index */
+ miTextColourOC, /* 11 text colour */
+ miCharHeight, /* 12 character height */
+ miCharUpVector, /* 13 character up vector */
+ miTextPath, /* 14 text path */
+ miTextAlignment, /* 15 text alignment */
+ miAtextHeight, /* 16 annotation text height */
+ miAtextUpVector, /* 17 annotation text up vector */
+ miAtextPath, /* 18 annotation text path */
+ miAtextAlignment, /* 19 annotation text alignment */
+ miAtextStyle, /* 20 annotation text style */
+ miTextBundleIndex, /* 21 text bundle index */
+ miLineType, /* 22 line type */
+ miLineWidth, /* 23 line width */
+ miLineColourOC, /* 24 line colour index */
+ miLineColourOC, /* 25 line colour */
+ miCurveApproximation, /* 26 curve approximation method */
+ miTestSetAttribute, /* 27 polyline interpolation method */
+ miLineBundleIndex, /* 28 line bundle index */
+ miInteriorStyle, /* 29 surface interior style */
+ miTestSetAttribute, /* 30 surface interior style index */
+ miSurfaceColourOC, /* 31 surface colour index */
+ miSurfaceColourOC, /* 32 surface colour */
+ miSurfaceReflAttr, /* 33 surface reflection attributes */
+ miSurfaceReflModel, /* 34 surface reflection model */
+ miSurfaceInterp, /* 35 surface interpolation method */
+ miTestSetAttribute, /* 36 backface surface interior style */
+ miTestSetAttribute, /* 37 backface surface interior style index */
+ miTestColourOC, /* 38 backface surface colour index */
+ miTestColourOC, /* 39 backface surface colour */
+ miTestSetAttribute, /* 40 backface surface reflection attributes */
+ miTestSetAttribute, /* 41 backface surface reflection model */
+ miTestSetAttribute, /* 42 backface surface interpolation method */
+ miSurfaceApproximation, /* 43 surface approximation */
+ miCullingMode, /* 44 facet culling mode */
+ miTestSetAttribute, /* 45 facet distinguish flag */
+ miTestSetAttribute, /* 46 pattern size */
+ miTestSetAttribute, /* 47 pattern reference point */
+ miTestSetAttribute, /* 48 pattern reference point and vectors */
+ miInteriorBundleIndex, /* 49 interior bundle index */
+ miSurfaceEdgeFlag, /* 50 surface edge flag */
+ miSurfaceEdgeType, /* 51 surface edge type */
+ miSurfaceEdgeWidth, /* 52 surface edge width */
+ miEdgeColourOC, /* 53 surface edge colour index */
+ miEdgeColourOC, /* 54 surface edge colour */
+ miEdgeBundleIndex, /* 55 edge bundle index */
+ miSetAsfValues, /* 56 set individual asf */
+ miLocalTransform, /* 57 local transform 3d */
+ miLocalTransform2D, /* 58 local transform 2d */
+ miGlobalTransform, /* 59 global transform 3d */
+ miGlobalTransform2D, /* 60 global transform 2d */
+ miModelClip, /* 61 model clip */
+ miSetMCVolume, /* 62 set model clip volume 3d */
+ miSetMCVolume, /* 63 set model clip volume 2d */
+ miRestoreMCV, /* 64 restore model clip volume */
+ miViewIndex, /* 65 view index */
+ miLightStateOC, /* 66 light source state */
+ miDepthCueIndex, /* 67 depth cue index */
+ miPickId, /* 68 pick id */
+ miTestSetAttribute, /* 69 hlhsr identifier */
+ miColourApproxIndex, /* 70 colour approx index */
+ miRenderingColourModel, /* 71 rendering colour model */
+ miParaSurfCharacteristics, /* 72 parametric surface characteristics */
+ miAddToNameSet, /* 73 add names to name set */
+ miAddToNameSet, /* 74 remove names from name set */
+ miExecuteStructure, /* 75 execute structure */
+ miNoop, /* 76 label */
+ miNoop, /* 77 application data */
+ miNoop, /* 78 gse */
+ miSearchPrimitives, /* 79 marker 3d */
+ miSearchPrimitives, /* 80 marker 2d */
+ miSearchPrimitives, /* 81 text3d */
+ miSearchPrimitives, /* 82 text2d */
+ miSearchPrimitives, /* 83 annotation text3d */
+ miSearchPrimitives, /* 84 annotation text2d */
+ miSearchPrimitives, /* 85 polyline3d */
+ miSearchPrimitives, /* 86 polyline2d */
+ miSearchPrimitives, /* 87 polyline set 3d with data */
+ miSearchPrimitives, /* 88 non-uniform b spline curve */
+ miSearchPrimitives, /* 89 fill area 3d */
+ miSearchPrimitives, /* 90 fill area 2d */
+ miSearchPrimitives, /* 91 fill area 3d with data */
+ miSearchPrimitives, /* 92 fill area set 3d */
+ miSearchPrimitives, /* 93 fill area set 2d */
+ miSearchPrimitives, /* 94 fill area set 3d with data */
+ miSearchPrimitives, /* 95 triangle strip */
+ miSearchPrimitives, /* 96 quadrilateral mesh */
+ miSearchPrimitives, /* 97 set of fill area sets */
+ miSearchPrimitives, /* 98 non-uniform b spline surface */
+ miSearchPrimitives, /* 99 cell array 3d */
+ miSearchPrimitives, /* 100 cell array 2d */
+ miSearchPrimitives, /* 101 extended cell array 3d */
+ miTestSearchGdp3d, /* 102 gdp 3d */
+ miTestSearchGdp2d, /* 103 gdp 2d */
+ miNoop /* 104 Noop */
+};
+
+
+extern ddpex2rtn
+ copyAnnotationText(),
+ copyAnnotationText2D(),
+ copyCellArray(),
+ copyCellArray2D(),
+ copyColourIndexOC(),
+ copyColourOC(),
+ copyExtCellArray(),
+ copyExtFillArea(),
+ copyExtFillAreaSet(),
+ copyFillArea(),
+ copyFillArea2D(),
+ copyFillAreaSet(),
+ copyFillAreaSet2D(),
+ copyGdp(),
+ copyGdp2D(),
+ copyLightState(),
+ copyMarker(),
+ copyMarker2D(),
+ copyNurbCurve(),
+ copyNurbSurface(),
+ copyPolyline(),
+ copyPolyline2D(),
+ copyPolylineSet(),
+ copyPSurfaceChars(),
+ copyMCVolume(),
+ copyQuadrilateralMesh(),
+ copySetAttribute(),
+ copyPropOC(),
+ copySOFAS(),
+ copyText(),
+ copyText2D(),
+ copyTriangleStrip();
+
+
+
+ocTableType CopyOCTable[] = {
+ copyPropOC, /* 0 dummy entry */
+ copySetAttribute, /* 1 marker type */
+ copySetAttribute, /* 2 marker scale */
+ copyColourIndexOC, /* 3 marker colour index */
+ copyColourOC, /* 4 marker colour */
+ copySetAttribute, /* 5 marker bundle index */
+ copySetAttribute, /* 6 text font index */
+ copySetAttribute, /* 7 text precision */
+ copySetAttribute, /* 8 character expansion */
+ copySetAttribute, /* 9 character spacing */
+ copyColourIndexOC, /* 10 text colour index */
+ copyColourOC, /* 11 text colour */
+ copySetAttribute, /* 12 character height */
+ copySetAttribute, /* 13 character up vector */
+ copySetAttribute, /* 14 text path */
+ copySetAttribute, /* 15 text alignment */
+ copySetAttribute, /* 16 annotation text height */
+ copySetAttribute, /* 17 annotation text up vector */
+ copySetAttribute, /* 18 annotation text path */
+ copySetAttribute, /* 19 annotation text alignment */
+ copySetAttribute, /* 20 annotation text style */
+ copySetAttribute, /* 21 text bundle index */
+ copySetAttribute, /* 22 line type */
+ copySetAttribute, /* 23 line width */
+ copyColourIndexOC, /* 24 line colour index */
+ copyColourOC, /* 25 line colour */
+ copySetAttribute, /* 26 curve approximation method */
+ copySetAttribute, /* 27 polyline interpolation method */
+ copySetAttribute, /* 28 line bundle index */
+ copySetAttribute, /* 29 surface interior style */
+ copySetAttribute, /* 30 surface interior style index */
+ copyColourIndexOC, /* 31 surface colour index */
+ copyColourOC, /* 32 surface colour */
+ copySetAttribute, /* 33 surface reflection attributes */
+ copySetAttribute, /* 34 surface reflection model */
+ copySetAttribute, /* 35 surface interpolation method */
+ copySetAttribute, /* 36 backface surface interior style */
+ copySetAttribute, /* 37 backface surface interior style index */
+ copyColourIndexOC, /* 38 backface surface colour index */
+ copyColourOC, /* 39 backface surface colour */
+ copySetAttribute, /* 40 backface surface reflection
+ * attributes */
+ copySetAttribute, /* 41 backface surface reflection model */
+ copySetAttribute, /* 42 backface surface interpolation method */
+ copySetAttribute, /* 43 surface approximation */
+ copySetAttribute, /* 44 facet culling mode */
+ copySetAttribute, /* 45 facet distinguish flag */
+ copySetAttribute, /* 46 pattern size */
+ copySetAttribute, /* 47 pattern reference point */
+ copySetAttribute, /* 48 pattern reference point and vectors */
+ copySetAttribute, /* 49 interior bundle index */
+ copySetAttribute, /* 50 surface edge flag */
+ copySetAttribute, /* 51 surface edge type */
+ copySetAttribute, /* 52 surface edge width */
+ copyColourIndexOC, /* 53 surface edge colour index */
+ copyColourOC, /* 54 surface edge colour */
+ copySetAttribute, /* 55 edge bundle index */
+ copySetAttribute, /* 56 set individual asf */
+ copySetAttribute, /* 57 local transform 3d */
+ copySetAttribute, /* 58 local transform 2d */
+ copySetAttribute, /* 59 global transform 3d */
+ copySetAttribute, /* 60 global transform 2d */
+ copySetAttribute, /* 61 model clip */
+ copyMCVolume, /* 62 copy model clip volume 3d */
+ copyMCVolume, /* 63 copy model clip volume 2d */
+ copySetAttribute, /* 64 restore model clip volume */
+ copySetAttribute, /* 65 view index */
+ copyLightState, /* 66 light source state */
+ copySetAttribute, /* 67 depth cue index */
+ copySetAttribute, /* 68 pick id */
+ copySetAttribute, /* 69 hlhsr identifier */
+ copySetAttribute, /* 70 colour approx index */
+ copySetAttribute, /* 71 rendering colour model */
+ copyPSurfaceChars, /* 72 parametric surface attributes */
+ copySetAttribute, /* 73 add names to name set */
+ copySetAttribute, /* 74 remove names from name set */
+ copySetAttribute, /* 75 execute structure */
+ copySetAttribute, /* 76 label */
+ copySetAttribute, /* 77 application data */
+ copySetAttribute, /* 78 gse */
+ copyMarker, /* 79 marker 3d */
+ copyMarker2D, /* 80 marker 2d */
+ copyText, /* 81 text3d */
+ copyText2D, /* 82 text2d */
+ copyAnnotationText, /* 83 annotation text3d */
+ copyAnnotationText2D, /* 84 annotation text2d */
+ copyPolyline, /* 85 polyline3d */
+ copyPolyline2D, /* 86 polyline2d */
+ copyPolylineSet, /* 87 polyline set 3d with data */
+ copyNurbCurve, /* 88 non-uniform b spline curve */
+ copyFillArea, /* 89 fill area 3d */
+ copyFillArea2D, /* 90 fill area 2d */
+ copyExtFillArea, /* 91 fill area 3d with data */
+ copyFillAreaSet, /* 92 fill area set 3d */
+ copyFillAreaSet2D, /* 93 fill area set 2d */
+ copyExtFillAreaSet, /* 94 fill area set 3d with data */
+ copyTriangleStrip, /* 95 triangle strip */
+ copyQuadrilateralMesh, /* 96 quadrilateral mesh */
+ copySOFAS, /* 97 set of fill area sets */
+ copyNurbSurface, /* 98 non-uniform b spline surface */
+ copyCellArray, /* 99 cell array 3d */
+ copyCellArray2D, /* 100 cell array 2d */
+ copyExtCellArray, /* 101 extended cell array 3d */
+ copyGdp, /* 102 gdp 3d */
+ copyGdp2D, /* 103 gdp 2d */
+ copySetAttribute /* 104 Noop */
+};
+
+
+extern ddpex2rtn
+ inquireAnnotationText(),
+ inquireAnnotationText2D(),
+ inquireCellArray(),
+ inquireCellArray2D(),
+ inquireColourIndexOC(),
+ inquireColourOC(),
+ inquireExtCellArray(),
+ inquireExtFillArea(),
+ inquireExtFillAreaSet(),
+ inquireFillArea(),
+ inquireFillArea2D(),
+ inquireFillAreaSet(),
+ inquireFillAreaSet2D(),
+ inquireGdp(),
+ inquireGdp2D(),
+ inquireLightState(),
+ inquireMarker(),
+ inquireMarker2D(),
+ inquireMCVolume(),
+ inquireMCVolume2D(),
+ inquireNurbCurve(),
+ inquireNurbSurface(),
+ inquirePolyline(),
+ inquirePolyline2D(),
+ inquirePolylineSet(),
+ inquirePSurfaceChars(),
+ inquireQuadrilateralMesh(),
+ inquireSetAttribute(),
+ inquirePropOC(),
+ inquireSOFAS(),
+ inquireText(),
+ inquireText2D(),
+ inquireTriangleStrip(),
+ inquireMCVolume(),
+ inquireMCVolume2D();
+
+
+ocTableType InquireOCTable[] = {
+ inquirePropOC, /* 0 dummy entry */
+ inquireSetAttribute, /* 1 marker type */
+ inquireSetAttribute, /* 2 marker scale */
+ inquireColourIndexOC, /* 3 marker colour index */
+ inquireColourOC, /* 4 marker colour */
+ inquireSetAttribute, /* 5 marker bundle index */
+ inquireSetAttribute, /* 6 text font index */
+ inquireSetAttribute, /* 7 text precision */
+ inquireSetAttribute, /* 8 character expansion */
+ inquireSetAttribute, /* 9 character spacing */
+ inquireColourIndexOC, /* 10 text colour index */
+ inquireColourOC, /* 11 text colour */
+ inquireSetAttribute, /* 12 character height */
+ inquireSetAttribute, /* 13 character up vector */
+ inquireSetAttribute, /* 14 text path */
+ inquireSetAttribute, /* 15 text alignment */
+ inquireSetAttribute, /* 16 annotation text height */
+ inquireSetAttribute, /* 17 annotation text up vector */
+ inquireSetAttribute, /* 18 annotation text path */
+ inquireSetAttribute, /* 19 annotation text alignment */
+ inquireSetAttribute, /* 20 annotation text style */
+ inquireSetAttribute, /* 21 text bundle index */
+ inquireSetAttribute, /* 22 line type */
+ inquireSetAttribute, /* 23 line width */
+ inquireColourIndexOC, /* 24 line colour index */
+ inquireColourOC, /* 25 line colour */
+ inquireSetAttribute, /* 26 curve approximation method */
+ inquireSetAttribute, /* 27 polyline interpolation method */
+ inquireSetAttribute, /* 28 line bundle index */
+ inquireSetAttribute, /* 29 surface interior style */
+ inquireSetAttribute, /* 30 surface interior style index */
+ inquireColourIndexOC, /* 31 surface colour index */
+ inquireColourOC, /* 32 surface colour */
+ inquireSetAttribute, /* 33 surface reflection attributes */
+ inquireSetAttribute, /* 34 surface reflection model */
+ inquireSetAttribute, /* 35 surface interpolation method */
+ inquireSetAttribute, /* 36 backface surface interior style */
+ inquireSetAttribute, /* 37 backface surface interior style index */
+ inquireColourIndexOC, /* 38 backface surface colour index */
+ inquireColourOC, /* 39 backface surface colour */
+ inquireSetAttribute, /* 40 backface surface reflection attributes */
+ inquireSetAttribute, /* 41 backface surface reflection model */
+ inquireSetAttribute, /* 42 backface surface interpolation method */
+ inquireSetAttribute, /* 43 surface approximation */
+ inquireSetAttribute, /* 44 facet culling mode */
+ inquireSetAttribute, /* 45 facet distinguish flag */
+ inquireSetAttribute, /* 46 pattern size */
+ inquireSetAttribute, /* 47 pattern reference point */
+ inquireSetAttribute, /* 48 pattern reference point and vectors */
+ inquireSetAttribute, /* 49 interior bundle index */
+ inquireSetAttribute, /* 50 surface edge flag */
+ inquireSetAttribute, /* 51 surface edge type */
+ inquireSetAttribute, /* 52 surface edge width */
+ inquireColourIndexOC, /* 53 surface edge colour index */
+ inquireColourOC, /* 54 surface edge colour */
+ inquireSetAttribute, /* 55 edge bundle index */
+ inquireSetAttribute, /* 56 set individual asf */
+ inquireSetAttribute, /* 57 local transform 3d */
+ inquireSetAttribute, /* 58 local transform 2d */
+ inquireSetAttribute, /* 59 global transform 3d */
+ inquireSetAttribute, /* 60 global transform 2d */
+ inquireSetAttribute, /* 61 model clip */
+ inquireMCVolume, /* 62 model clip volume 3d */
+ inquireMCVolume2D, /* 63 model clip volume 2d */
+ inquireSetAttribute, /* 64 restore model clip volume */
+ inquireSetAttribute, /* 65 view index */
+ inquireLightState, /* 66 light source state */
+ inquireSetAttribute, /* 67 depth cue index */
+ inquireSetAttribute, /* 68 pick id */
+ inquireSetAttribute, /* 69 hlhsr identifier */
+ inquireSetAttribute, /* 70 colour approx index */
+ inquireSetAttribute, /* 71 rendering colour model */
+ inquirePSurfaceChars, /* 72 parametric surface attributes */
+ inquireSetAttribute, /* 73 add names to name set */
+ inquireSetAttribute, /* 74 remove names from name set */
+ inquireSetAttribute, /* 75 execute structure */
+ inquireSetAttribute, /* 76 label */
+ inquireSetAttribute, /* 77 application data */
+ inquireSetAttribute, /* 78 gse */
+ inquireMarker, /* 79 marker 3d */
+ inquireMarker2D, /* 80 marker 2d */
+ inquireText, /* 81 text3d */
+ inquireText2D, /* 82 text2d */
+ inquireAnnotationText, /* 83 annotation text3d */
+ inquireAnnotationText2D, /* 84 annotation text2d */
+ inquirePolyline, /* 85 polyline3d */
+ inquirePolyline2D, /* 86 polyline2d */
+ inquirePolylineSet, /* 87 polyline set 3d with data */
+ inquireNurbCurve, /* 88 non-uniform b spline curve */
+ inquireFillArea, /* 89 fill area 3d */
+ inquireFillArea2D, /* 90 fill area 2d */
+ inquireExtFillArea, /* 91 fill area 3d with data */
+ inquireFillAreaSet, /* 92 fill area set 3d */
+ inquireFillAreaSet2D, /* 93 fill area set 2d */
+ inquireExtFillAreaSet, /* 94 fill area set 3d with data */
+ inquireTriangleStrip, /* 95 triangle strip */
+ inquireQuadrilateralMesh, /* 96 quadrilateral mesh */
+ inquireSOFAS, /* 97 set of fill area sets */
+ inquireNurbSurface, /* 98 non-uniform b spline surface */
+ inquireCellArray, /* 99 cell array 3d */
+ inquireCellArray2D, /* 100 cell array 2d */
+ inquireExtCellArray, /* 101 extended cell array 3d */
+ inquireGdp, /* 102 gdp 3d */
+ inquireGdp2D, /* 103 gdp 2d */
+ inquireSetAttribute /* 104 Noop */
+};
+
+
+
+extern ddpex2rtn
+ replaceNurbSurface(),
+ replaceLightState(),
+ replaceSOFAS();
+
+
+ocTableType ReplaceOCTable[] = {
+ parsePropOC, /* 0 dummy entry */
+ parseSetAttribute, /* 1 marker type */
+ parseSetAttribute, /* 2 marker scale */
+ parseColourIndexOC, /* 3 marker colour index */
+ parseColourOC, /* 4 marker colour */
+ parseSetAttribute, /* 5 marker bundle index */
+ parseSetAttribute, /* 6 text font index */
+ parseSetAttribute, /* 7 text precision */
+ parseSetAttribute, /* 8 character expansion */
+ parseSetAttribute, /* 9 character spacing */
+ parseColourIndexOC, /* 10 text colour index */
+ parseColourOC, /* 11 text colour */
+ parseSetAttribute, /* 12 character height */
+ parseSetAttribute, /* 13 character up vector */
+ parseSetAttribute, /* 14 text path */
+ parseSetAttribute, /* 15 text alignment */
+ parseSetAttribute, /* 16 annotation text height */
+ parseSetAttribute, /* 17 annotation text up vector */
+ parseSetAttribute, /* 18 annotation text path */
+ parseSetAttribute, /* 19 annotation text alignment */
+ parseSetAttribute, /* 20 annotation text style */
+ parseSetAttribute, /* 21 text bundle index */
+ parseSetAttribute, /* 22 line type */
+ parseSetAttribute, /* 23 line width */
+ parseColourIndexOC, /* 24 line colour index */
+ parseColourOC, /* 25 line colour */
+ parseSetAttribute, /* 26 curve approximation method */
+ parseSetAttribute, /* 27 polyline interpolation method */
+ parseSetAttribute, /* 28 line bundle index */
+ parseSetAttribute, /* 29 surface interior style */
+ parseSetAttribute, /* 30 surface interior style index */
+ parseColourIndexOC, /* 31 surface colour index */
+ parseColourOC, /* 32 surface colour */
+ parseSetAttribute, /* 33 surface reflection attributes */
+ parseSetAttribute, /* 34 surface reflection model */
+ parseSetAttribute, /* 35 surface interpolation method */
+ parseSetAttribute, /* 36 backface surface interior style */
+ parseSetAttribute, /* 37 backface surface interior style index */
+ parseColourIndexOC, /* 38 backface surface colour index */
+ parseColourOC, /* 39 backface surface colour */
+ parseSetAttribute, /* 40 backface surface reflection attributes */
+ parseSetAttribute, /* 41 backface surface reflection model */
+ parseSetAttribute, /* 42 backface surface interpolation method */
+ parseSetAttribute, /* 43 surface approximation */
+ parseSetAttribute, /* 44 facet culling mode */
+ parseSetAttribute, /* 45 facet distinguish flag */
+ parseSetAttribute, /* 46 pattern size */
+ parseSetAttribute, /* 47 pattern reference point */
+ parseSetAttribute, /* 48 pattern reference point and vectors */
+ parseSetAttribute, /* 49 interior bundle index */
+ parseSetAttribute, /* 50 surface edge flag */
+ parseSetAttribute, /* 51 surface edge type */
+ parseSetAttribute, /* 52 surface edge width */
+ parseColourIndexOC, /* 53 surface edge colour index */
+ parseColourOC, /* 54 surface edge colour */
+ parseSetAttribute, /* 55 edge bundle index */
+ parseSetAttribute, /* 56 set individual asf */
+ parseSetAttribute, /* 57 local transform 3d */
+ parseSetAttribute, /* 58 local transform 2d */
+ parseSetAttribute, /* 59 global transform 3d */
+ parseSetAttribute, /* 60 global transform 2d */
+ parseSetAttribute, /* 61 model clip */
+ parseSetMCVolume, /* 62 set model clip volume 3d */
+ parseSetMCVolume2D, /* 63 set model clip volume 2d */
+ parseSetAttribute, /* 64 restore model clip volume */
+ parseSetAttribute, /* 65 view index */
+ replaceLightState, /* 66 light source state */
+ parseSetAttribute, /* 67 depth cue index */
+ parseSetAttribute, /* 68 pick id */
+ parseSetAttribute, /* 69 hlhsr identifier */
+ parseSetAttribute, /* 70 colour approx index */
+ parseSetAttribute, /* 71 rendering colour model */
+ parsePSurfaceChars, /* 72 parametric surface attributes */
+ parseSetAttribute, /* 73 add names to name set */
+ parseSetAttribute, /* 74 remove names from name set */
+ parseSetAttribute, /* 75 execute structure */
+ parseSetAttribute, /* 76 label */
+ parseSetAttribute, /* 77 application data */
+ parseSetAttribute, /* 78 gse */
+ parseMarker, /* 79 marker 3d */
+ parseMarker2D, /* 80 marker 2d */
+ parseText, /* 81 text3d */
+ parseText2D, /* 82 text2d */
+ parseAnnotationText, /* 83 annotation text3d */
+ parseAnnotationText2D, /* 84 annotation text2d */
+ parsePolyline, /* 85 polyline3d */
+ parsePolyline2D, /* 86 polyline2d */
+ parsePolylineSet, /* 87 polyline set 3d with data */
+ parseNurbCurve, /* 88 non-uniform b spline curve */
+ parseFillArea, /* 89 fill area 3d */
+ parseFillArea2D, /* 90 fill area 2d */
+ parseExtFillArea, /* 91 fill area 3d with data */
+ parseFillAreaSet, /* 92 fill area set 3d */
+ parseFillAreaSet2D, /* 93 fill area set 2d */
+ parseExtFillAreaSet, /* 94 fill area set 3d with data */
+ parseTriangleStrip, /* 95 triangle strip */
+ parseQuadrilateralMesh, /* 96 quadrilateral mesh */
+ replaceSOFAS, /* 97 set of fill area sets */
+ replaceNurbSurface, /* 98 non-uniform b spline surface */
+ parseCellArray, /* 99 cell array 3d */
+ parseCellArray2D, /* 100 cell array 2d */
+ parseExtCellArray, /* 101 extended cell array 3d */
+ parseGdp, /* 102 gdp 3d */
+ parseGdp2D, /* 103 gdp 2d */
+ parseSetAttribute /* 104 Noop */
+};
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level2/miMarkers.c b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miMarkers.c
new file mode 100644
index 000000000..49f427708
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miMarkers.c
@@ -0,0 +1,146 @@
+/* $TOG: miMarkers.c /main/6 1998/02/10 12:41:39 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level2/miMarkers.c,v 3.5 1998/10/04 09:34:21 dawes Exp $ */
+
+#include "mipex.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "ddpex3.h"
+#include "PEXErr.h"
+#include "miRender.h"
+#include "miStruct.h"
+#include "gcstruct.h"
+#include "ddpex2.h"
+#include "miMarkers.h"
+#include "miClip.h"
+
+
+/*++
+ |
+ | Function Name: miPolyMarker
+ |
+ | Function Description:
+ | Handles the Polymarker 3D, and Polymarker 2D ocs.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+miPolyMarker(pRend, pExecuteOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pExecuteOC;
+{
+/* calls */
+ ddpex3rtn miTransform();
+ ddpex3rtn miClipPointList();
+
+/* Local variable definitions */
+ miMarkerStruct *ddmarker = (miMarkerStruct *)(pExecuteOC+1);
+ miListHeader *input_list = (miListHeader *)ddmarker;
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ ddpex3rtn status;
+ miListHeader *mc_list,
+ *mc_clist,
+ *cc_list,
+ *clip_list,
+ *dc_list;
+ ddUSHORT clip_mode; /* view or model clipping */
+ ddPointType out_type;
+
+ /* Check for Model clipping */
+
+ if (pddc->Dynamic->pPCAttr->modelClip == PEXClip) {
+
+ ComputeMCVolume(pRend, pddc); /* Compute modelling coord version
+ of clipping volume */
+ clip_mode = MI_MCLIP;
+
+ /* Tranform points to 4D for clipping */
+ out_type = input_list->type;
+ if (status = miTransform(pddc, input_list, &mc_clist,
+ ident4x4,
+ ident4x4,
+ DD_SetVert4D(out_type)))
+ return (status);
+
+ if (status = miClipPointList(pddc, mc_clist, &mc_list, clip_mode))
+ return(status);
+
+ } else mc_list = input_list;
+
+ clip_mode = MI_VCLIP;
+
+
+ /*
+ * Transform and clip the input list of marker positions.
+ */
+ if (status = miTransform(pddc, mc_list, &cc_list,
+ pddc->Dynamic->mc_to_cc_xform,
+ NULL4x4,
+ DD_HOMOGENOUS_POINT))
+ return (status);
+
+ /* Note that miClipPointList discards clipped points */
+ if (status = miClipPointList(pddc, cc_list, &clip_list, clip_mode))
+ return(status);
+
+ /* if nothing left, return early */
+ if (clip_list->numLists <= 0) return(Success);
+
+
+ /* Transform to DC coordinates */
+ if (status = miTransform(pddc, clip_list, &dc_list,
+ pddc->Dynamic->cc_to_dc_xform,
+ NULL4x4,
+ DD_2DS_POINT))
+ return (status);
+
+
+ return (pddc->Static.RenderProcs[MARKER_RENDER_TABLE_INDEX](pRend,
+ pddc,
+ dc_list));
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level2/miNCurve.c b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miNCurve.c
new file mode 100644
index 000000000..c422157da
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miNCurve.c
@@ -0,0 +1,743 @@
+/* $TOG: miNCurve.c /main/4 1998/02/10 12:41:43 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level2/miNCurve.c,v 3.6 1998/10/04 09:34:22 dawes Exp $ */
+
+#include "mipex.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "ddpex3.h"
+#include "PEXErr.h"
+#include "miStruct.h"
+#include "PEXprotost.h"
+#include "miRender.h"
+#include "gcstruct.h"
+#include "ddpex2.h"
+#include "miNurbs.h"
+#include "pexos.h"
+
+
+/*++
+ |
+ | Function Name: miNurbsCurve
+ |
+ | Function Description:
+ | Handles the Nurbs Curve Pex OC.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+miNurbsCurve(pRend, pExecuteOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pExecuteOC;
+{
+/* calls */
+ ddpex3rtn tessellate_curve();
+ extern ocTableType InitExecuteOCTable[];
+
+/* Local variable definitions */
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ miNurbStruct *ddCurve = (miNurbStruct *)(pExecuteOC+1);
+ miGenericStr *pGStr;
+ miListHeader *tesselated_list;
+ miListHeader *polyline_list;
+ ddpex3rtn status;
+
+ switch(pddc->Static.attrs->curveApprox.approxMethod) {
+
+ case PEXApproxImpDep:
+ case PEXApproxConstantBetweenKnots:
+ case PEXApproxDcChordalSize:
+ case PEXCurveApproxDcChordalDev:
+ case PEXApproxDcRelative:
+ default:
+
+ case PEXApproxWcsChordalSize:
+ case PEXCurveApproxWcsChordalDev:
+ case PEXApproxWcsRelative:
+
+ /* apply curve approximation criteria in wc */
+ if (status = tessellate_curve( pddc, ddCurve,
+ &tesselated_list,
+ pddc->Dynamic->mc_to_wc_xform ))
+ return (status);
+
+ break;
+
+
+ case PEXApproxNpcChordalSize:
+ case PEXCurveApproxNpcChordalDev:
+ case PEXApproxNpcRelative:
+
+ /* apply curve approximation criteria in wc */
+ if (status = tessellate_curve( pddc, ddCurve,
+ &tesselated_list,
+ pddc->Dynamic->mc_to_npc_xform ))
+ return (status);
+
+ break;
+ }
+
+ /* allocate polyline command block */
+ if (!(pGStr = (miGenericStr *) (xalloc(sizeof(miGenericStr) +
+ sizeof(miListHeader)))))
+ return(BadAlloc);
+
+ pGStr->elementType = PEXOCPolylineSet;
+ /* The length data is ignored by the rendering routine and hence is */
+ /* left as whatever GARBAGE that will be present at the alloc time. */
+
+ polyline_list = (miListHeader *) (pGStr + 1);
+ *polyline_list = *tesselated_list;
+
+ /* render tesselated curve */
+ status = InitExecuteOCTable[(int)(pGStr->elementType)](pRend, pGStr);
+
+ xfree(pGStr);
+
+ return (status);
+
+}
+
+/*++
+ |
+ | Function Name: multiply_basis_func_control_pts
+ |
+ | Function Description:
+ |
+ | Multiply nurb basis func and control points to get polynomial coeffs
+ |
+ | |poly[0]| |C0,0 C0,1 C0,2 C0,3| |Pxi+3|
+ | |poly[1]| = |C1,0 C1,1 C1,2 C1,3| |Pxi+2|
+ | |poly[2]| |C2,0 C2,1 C2,2 C2,3| |Pxi+1|
+ | |poly[3]| |C3,0 C3,1 C3,2 C3,3| |Pxi |
+ |
+ |
+ | Note(s):
+ |
+ --*/
+static
+void
+multiply_basis_func_control_pts( pt_type, order, span, pts, C, poly )
+ ddPointType pt_type;
+ ddUSHORT order;
+ int span;
+ char *pts; /* control points */
+ double C[MAXORD][MAXORD]; /* span basis matrix */
+ double poly[4][MAXORD]; /* computed polynomial basis mtx */
+{
+ int i, k;
+ double x, y, z, w;
+ char *pt;
+ int point_size;
+
+ DD_VertPointSize(pt_type, point_size);
+
+ for ( k = 0; k < order; k++ ) {
+ x = y = z = w = 0.0;
+ pt = pts + point_size * (span - order);
+ for ( i = 0; i < order; i++ ) { /* for all coeffs */
+ pt += point_size;
+ x += C[k][i] * ((ddCoord4D *)pt)->x;
+ y += C[k][i] * ((ddCoord4D *)pt)->y;
+ if ( !DD_IsVert2D(pt_type) ) {
+ z += C[k][i] * ((ddCoord4D *)pt)->z;
+ if ( DD_IsVert4D(pt_type) )
+ w += C[k][i] * ((ddCoord4D *)pt)->w;
+ }
+ }
+ poly[XX][k] = x;
+ poly[YY][k] = y;
+ poly[ZZ][k] = z;
+ poly[WW][k] = w;
+ }
+}
+
+
+
+/*++
+ |
+ | Function Name: compute_fwd_matrix2D
+ |
+ | Function Description:
+ |
+ | initial scale and convert coefficients to forward difference basis
+ |
+ | |1 0 0 0 | |1 0 0 0 | |polyx[0]|
+ | |fdx[0]| |0 1 1 1 | |0 dt 0 0 | |polyx[1]|
+ | |fdx[1]| = | | | 2 | | |
+ | |fdx[2]| |0 0 2 6 | |0 0 dt 0 | |polyx[2]|
+ | |fdx[3]| | | | 3| | |
+ | |0 0 0 6 | |0 0 0 dt | |polyx[3]|
+ |
+ |
+ | Note(s):
+ |
+ --*/
+static
+void
+compute_fwd_matrix2D( pt_type, order, dt, poly )
+ ddPointType pt_type;
+ ddUSHORT order;
+ float dt;
+ double poly[MAXORD][MAXORD];
+{
+ int i, j, k;
+ double fd[MAXORD];
+ double sptofd[MAXORD][MAXORD];
+ double dtpow[MAXORD];
+
+ register double a0;
+
+ dtpow[0] = 1.0; /* make scale matrix */
+ for ( i = 1; i < order; i++ )
+ dtpow[i] = dtpow[i-1] * dt;
+
+ for ( i = 0; i < order; i++ ) /* scale matrix x fwd matrix */
+ for (j = i; j < order; j++ )
+ sptofd[i][j] = mi_nu_ptofd[i][j] * dtpow[j];
+
+ for ( i = 0; i < 3; i++ ) { /* x, y, z */
+ for ( j = 0; j < order; j++ ) {
+ a0 = 0.0;
+ for ( k = j; k < order; k++ )
+ a0 += sptofd[j][k] * poly[i][k];
+ fd[j] = a0;
+ }
+ for ( j = 0; j < order; j++ )
+ poly[i][j] = fd[j];
+ }
+
+ if ( DD_IsVert4D(pt_type) ) {
+ for ( j = 0; j < order; j++ ) {
+ a0 = 0.0;
+ for ( k = j; k < order; k++ )
+ a0 += sptofd[j][k] * poly[WW][k];
+ fd[j] = a0;
+ }
+ for ( j = 0; j < order; j++ )
+ poly[WW][j] = fd[j];
+ }
+}
+
+
+
+/*++
+ |
+ | Function Name: ofd_curve
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+static
+void
+ofd_curve( pt_type, order, knot, num_segs, dt, A, pts )
+ ddPointType pt_type;
+ ddUSHORT order;
+ ddFLOAT *knot;
+ int num_segs;
+ float dt;
+ register double A[4][MAXORD];
+ char *pts;
+{
+ register int i, j;
+ register int point_size;
+
+ DD_VertPointSize(pt_type, point_size);
+
+ /* Move to the first point of the span. */
+ ((ddCoord4D *)pts)->x = A[XX][0];
+ ((ddCoord4D *)pts)->y = A[YY][0];
+ ((ddCoord4D *)pts)->z = A[ZZ][0];
+ ((ddCoord4D *)pts)->w = A[WW][0];
+ pts += point_size;
+
+ for ( i = 1; i <= num_segs; i++ ) { /* number of steps */
+ for ( j = 0; j < order - 1; j++ ) { /* forward difference */
+ A[XX][j] += A[XX][j+1];
+ A[YY][j] += A[YY][j+1];
+ }
+
+ ((ddCoord4D *)pts)->x = A[XX][0];
+ ((ddCoord4D *)pts)->y = A[YY][0];
+
+ if ( !DD_IsVert2D(pt_type) ) {
+
+ for ( j = 0; j < order - 1; j++ )
+ A[ZZ][j] += A[ZZ][j+1];
+
+ ((ddCoord4D *)pts)->z = A[ZZ][0];
+
+ if ( DD_IsVert4D(pt_type) ) {
+
+ for ( j = 0; j < order - 1; j++ )
+ A[WW][j] += A[WW][j+1];
+
+ ((ddCoord4D *)pts)->w = A[WW][0];
+ }
+ }
+
+ pts += point_size;
+ }
+
+ return;
+}
+
+
+
+/*++
+ |
+ | Function Name: nu_compute_nurb_curve
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+static
+ddpex3rtn
+nu_compute_nurb_curve( pddc, curve, aptype, apval, curve_list )
+ miDDContext *pddc;
+ miNurbStruct *curve;
+ int aptype;
+ ddFLOAT apval;
+ miListHeader **curve_list;
+{
+ ddUSHORT order = curve->order;
+ int i;
+
+ miListHeader *control_points = &curve->points;
+ ddFLOAT (*rknots)[MAXORD]=0; /* reciprocal of knot diff */
+ double C[MAXORD][MAXORD]; /* bspline to poly matrix */
+ double A[4][MAXORD]; /* xyzw curve coefficients */
+ int numKnots; /* number of knots aftetr insertion */
+ int numnewKnots;
+ ddFLOAT *knots = 0; /* new knots after insertion */
+ ddCoord4D *cpts = 0; /* new ctrl pts after insertion */
+ ddCoord4D *out_pts; /* output data pointer */
+ listofddPoint *pddlist; /* data list pointer */
+ int num_cpts, num_subsegs, num_additional_knots;
+ float additional_knots[2];
+ float dt;
+
+ if (curve->numKnots != control_points->ddList->numPoints + order)
+ return 0;
+
+ if ( !(curve->numKnots > 0 && control_points->ddList->numPoints > 0) )
+ return 0;
+
+ /* Trimming by knot insertion (if needed). */
+ num_additional_knots = 0;
+ if ( curve->uMin > curve->pKnots[order-1] )
+ additional_knots[num_additional_knots++] = curve->uMin;
+
+ if ( curve->uMax < curve->pKnots[curve->numKnots - order] )
+ additional_knots[num_additional_knots++] = curve->uMax;
+
+ if ( num_additional_knots > 0 ) {
+
+ if ( !( knots = (ddFLOAT *)
+ xalloc((num_additional_knots + curve->numKnots)*sizeof(float))))
+ goto no_mem;
+
+ if ( !( cpts = (ddCoord4D *)
+ xalloc( (num_additional_knots + control_points->ddList->numPoints)
+ * sizeof(ddCoord4D))) )
+ goto no_mem;
+
+ numnewKnots = num_additional_knots;
+ for ( i = 0; i < num_additional_knots; i++ )
+ knots[i] = additional_knots[i];
+
+ if ( !mi_nu_insert_knots( order, control_points->type,
+ curve->numKnots, curve->pKnots,
+ (ddFLOAT *)(control_points->ddList->pts.ptr),
+ &numnewKnots, knots,
+ (ddFLOAT *)cpts ) )
+ goto no_mem;
+
+ numKnots = numnewKnots;
+ num_cpts = numnewKnots - order;
+
+ } else {
+
+ numKnots = curve->numKnots;
+ knots = curve->pKnots;
+ num_cpts = numKnots - order;
+ cpts = control_points->ddList->pts.p4Dpt;
+ }
+
+
+
+ /* Build the tessellation. */
+ if ( order > MAXORD || order == 1 ) {
+
+ /*
+ * if order > MAXORD, Draw only the control polygon.
+ * if order == 1, draw point at each control point.
+ */
+ *curve_list = MI_NEXTTEMPDATALIST(pddc);
+ MI_ALLOCLISTHEADER((*curve_list), 1);
+
+ if ( DD_IsVert4D(control_points->type) ) {
+
+ ddCoord4D *in_pt4D, *out_pt4D;
+
+ (*curve_list)->type = DDPT_4D;
+ MI_ALLOCLISTOFDDPOINT( (*curve_list)->ddList, num_cpts,
+ sizeof(ddCoord4D) );
+ out_pt4D = (*curve_list)->ddList->pts.p4Dpt;
+ if ( !out_pt4D ) return(BadAlloc);
+ in_pt4D = cpts;
+
+ for ( i = 0; i < num_cpts; i++ ) *(out_pt4D++) = *(in_pt4D++);
+
+ } else if ( DD_IsVert3D(control_points->type) ) {
+
+ ddCoord3D *in_pt3D, *out_pt3D;
+
+ (*curve_list)->type = DDPT_3D;
+ MI_ALLOCLISTOFDDPOINT( (*curve_list)->ddList, num_cpts,
+ sizeof(ddCoord3D) );
+ out_pt3D = (*curve_list)->ddList->pts.p3Dpt;
+ if ( !out_pt3D ) return(BadAlloc);
+ in_pt3D = (ddCoord3D *)cpts;
+
+ for ( i = 0; i < num_cpts; i++ ) *(out_pt3D++) = *(in_pt3D++);
+
+ } else {
+
+ ddCoord2D *in_pt2D, *out_pt2D;
+
+ (*curve_list)->type = DDPT_2D;
+ MI_ALLOCLISTOFDDPOINT( (*curve_list)->ddList, num_cpts,
+ sizeof(ddCoord2D) );
+ out_pt2D = (*curve_list)->ddList->pts.p2Dpt;
+ if ( !out_pt2D ) return(BadAlloc);
+ in_pt2D = (ddCoord2D *)cpts;
+
+ for ( i = 0; i < num_cpts; i++ ) *(out_pt2D++) = *(in_pt2D++);
+
+ }
+
+ } else { /* ( order > 1 and <= MAXORD ) */
+
+ switch( aptype ) {
+ case PEXApproxImpDep:
+ case PEXApproxConstantBetweenKnots:
+ default:
+ if ( apval <= 0.0 ) {
+ dt = 1.0;
+ num_subsegs = 1;
+
+ } else {
+ dt = 1.0 / (apval + 1.0);
+ num_subsegs = apval + 1; /* assume it's been clamped */
+ }
+
+ if ( !( rknots = (ddFLOAT (*)[MAXORD])
+ xalloc( MAXORD * numKnots * sizeof(float))) )
+ goto no_mem;
+
+ mi_nu_preprocess_knots( order, numKnots, knots, rknots );
+
+ /* build a new list for each span */
+ (*curve_list) = MI_NEXTTEMPDATALIST(pddc);
+ (*curve_list)->type = control_points->type;
+ (*curve_list)->numLists = 0;
+ MI_ALLOCLISTHEADER((*curve_list), num_cpts);
+ if (!(pddlist = (*curve_list)->ddList )) return(BadAlloc);
+
+ for ( i = order - 1; i < num_cpts; i++ ) {
+ if ( knots[i+1] > knots[i]
+ && knots[i] >= curve->uMin
+ && knots[i+1] <= curve->uMax )
+ {
+ mi_nu_compute_nurb_basis_function( order, i,
+ knots, rknots, C );
+ multiply_basis_func_control_pts( control_points->type,
+ order, i,
+ (char *)cpts, C, A );
+ compute_fwd_matrix2D( control_points->type,order,dt,A );
+
+ MI_ALLOCLISTOFDDPOINT(pddlist, num_subsegs + 1,
+ sizeof(ddCoord4D));
+ if (!(out_pts = pddlist->pts.p4Dpt))
+ return(BadAlloc);
+
+ ofd_curve( control_points->type, order, &knots[i],
+ num_subsegs, dt, A, (char *)out_pts );
+
+ (pddlist++)->numPoints = num_subsegs + 1;
+ (*curve_list)->numLists += 1;
+ }
+ }
+
+ break;
+ } /* end switch on approx type */
+ }
+
+ if (knots != curve->pKnots) xfree(knots);
+ if (cpts != control_points->ddList->pts.p4Dpt) xfree(cpts);
+ xfree(rknots);
+
+ return 0;
+
+no_mem:
+ if ((knots)&&(knots != curve->pKnots)) xfree(knots);
+ if ((cpts)&&(cpts != control_points->ddList->pts.p4Dpt)) xfree(cpts);
+ if (rknots) xfree(rknots);
+
+ return (BadAlloc);
+}
+
+
+
+/*++
+ |
+ | Function Name: compute_adaptive_crv_interval
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+static
+ddpex3rtn
+compute_adaptive_crv_interval( pddc, curve, xform, apxval )
+ miDDContext *pddc;
+ miNurbStruct *curve;
+ ddFLOAT xform[4][4];
+ ddFLOAT *apxval;
+{
+ ddFLOAT a_coeff, b_coeff, c_coeff, denom, z1, z2, z3;
+ int i, use_z_coord = 0;
+ int npts = curve->points.ddList->numPoints;
+ ddCoord4D *xpts, *pa, *pb, *pc;
+ ddPointUnion in_pt;
+ double w, perp_d, max_perp_d = 0.0;
+ miListHeader *tmp_list;
+ int point_size;
+ ddpex3rtn status;
+
+ /*
+ * Compute the constant parametric between knots interval needed to
+ * come close to meeting the specified approximation criteria. The
+ * method used is a gross compromise for the adaptive approximation
+ * criteria, but fulfills the basic need for an adaptive approximation
+ * method.
+ * Note that for the NPC approximation criteria NPC isn't even the space
+ * being used, it's clipping space, which is [-1,1], [-1,1], [0,1].
+ * The Z component is ignored in this case though since the Z dimension
+ * is perpendicular to the screen.
+ */
+ *apxval = 0.0;
+ switch ( pddc->Static.attrs->curveApprox.approxMethod ) {
+ case PEXApproxNpcChordalSize:
+ case PEXCurveApproxNpcChordalDev:
+ use_z_coord = 0;
+ break;
+
+ case PEXApproxWcsChordalSize:
+ case PEXCurveApproxWcsChordalDev:
+ use_z_coord = 1;
+ break;
+ }
+
+ if ( xform ) {
+ if (status = miTransform( pddc, &curve->points, &tmp_list,
+ xform, NULL4x4, DD_HOMOGENOUS_POINT))
+ return (status);
+
+ /* Normalize result by w */
+ xpts = tmp_list->ddList->pts.p4Dpt;
+ for ( i = 0, pa = xpts; i < npts; i++, pa++ ) {
+ w = 1.0 / pa->w;
+ pa->x *= w; pa->y *= w;
+ if ( use_z_coord ) pa->z *= w;
+ }
+
+ } else {
+
+ DD_VertPointSize(curve->points.type, point_size);
+
+ if ( !( xpts = (ddCoord4D *)xalloc(npts * sizeof(ddCoord4D))) ) {
+ return BadAlloc;
+ }
+
+ if ( DD_IsVert4D(curve->points.type) ) {
+
+ /* if homogeneous values, then normalize by w */
+ for ( i = 0, in_pt.p4Dpt = curve->points.ddList->pts.p4Dpt, pa = xpts;
+ i < npts;
+ i++ ) {
+
+ w = 1.0 / in_pt.p4Dpt->w;
+ pa->x = in_pt.p4Dpt->x * w;
+ pa->y = in_pt.p4Dpt->y * w;
+ if ( use_z_coord ) pa->z = in_pt.p4Dpt->z * w;
+
+ in_pt.ptr += point_size;
+ pa++;
+ }
+
+ } else {
+
+ if ( DD_IsVert2D(curve->points.type) ) use_z_coord = 0;
+
+ /* Copy 2D or 3D points into 4D array */
+ for ( i = 0, in_pt.p4Dpt = curve->points.ddList->pts.p4Dpt, pa = xpts;
+ i < npts;
+ i++ ) {
+
+ pa->x = in_pt.p4Dpt->x;
+ pa->y = in_pt.p4Dpt->y;
+ if ( use_z_coord ) pa->z = in_pt.p4Dpt->z;
+
+ in_pt.ptr += point_size;
+ pa++;
+ }
+
+ }
+
+ }
+
+ /*
+ * For the above approx. types, the approx. value is the max. allowable
+ * distance between the actual curve and the generated chord.
+ * The distance of the ctrl point from the line joining the ctrl pts on
+ * either side of it is calculated for every ctrl pt. This is calculated
+ * in 2D. For approx. in WC, the 3D length is got from the 2D-length
+ * and the z values of the ctrl pts. The max of all these lengths is
+ * found. The final approx. value is obtd. from the ratio of the max length
+ * and the required approx. value.
+ */
+
+ pa = xpts; pb = pa + 2, pc = pa + 1;
+ for ( i = 1; i < npts-1; i++, pa++, pb++, pc++ ) {
+ a_coeff = pb->y - pa->y;
+ b_coeff = pa->x - pb->x;
+ c_coeff = pb->x * pa->y - pa->x * pb->y;
+ denom = ( a_coeff * a_coeff + b_coeff * b_coeff );
+ perp_d = (a_coeff * pc->x + b_coeff * pc->y + c_coeff);
+ if ( use_z_coord ) {
+ z1 = pc->z;
+ z2 = (pa->z + pb->z) /2.0;
+ z3 = z1 - z2;
+ perp_d = sqrt( (perp_d * perp_d + z3 * z3 * denom) /denom );
+ } else
+ perp_d = perp_d/ (sqrt(denom));
+ perp_d = fabs(perp_d);
+ if ( perp_d > max_perp_d )
+ max_perp_d = perp_d;
+ }
+
+ *apxval = (int)(1 + sqrt( 10*max_perp_d /
+ (pddc->Static.attrs->curveApprox.tolerance > 0.0
+ ? pddc->Static.attrs->curveApprox.tolerance : 0.01)));
+
+ if (xpts != tmp_list->ddList->pts.p4Dpt) xfree(xpts);
+
+ return Success;
+}
+
+/*++
+ |
+ | Function Name: tessellate_curve
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+ddpex3rtn
+tessellate_curve( pddc, curve, curve_list, xform )
+ miDDContext *pddc;
+ miNurbStruct *curve;
+ miListHeader **curve_list;
+ ddFLOAT xform[4][4];
+{
+ int approx_type;
+ ddFLOAT approx_value;
+ ddpex3rtn status = 0; /* !0 if successful */
+
+ if ( curve->points.ddList->numPoints <= 0 )
+ return status;
+
+ switch ( pddc->Static.attrs->curveApprox.approxMethod ) {
+ case PEXApproxImpDep:
+ case PEXApproxConstantBetweenKnots:
+ approx_type = PEXApproxConstantBetweenKnots;
+ approx_value=MAX((int)pddc->Static.attrs->curveApprox.tolerance,0);
+ break;
+
+ case PEXApproxWcsChordalSize:
+ case PEXApproxNpcChordalSize:
+ case PEXCurveApproxWcsChordalDev:
+ case PEXCurveApproxNpcChordalDev:
+ /* The same approximation method is used for all these
+ * approximation types, and it's not exactly any of them.
+ * But the method used serves the same purpose and
+ * PHIGS PLUS allows us to approximate the defined methods.
+ */
+ approx_type = PEXApproxConstantBetweenKnots;
+ compute_adaptive_crv_interval( pddc, curve, xform,
+ &approx_value );
+ break;
+
+ default:
+ approx_type = PEXApproxConstantBetweenKnots;
+ approx_value = 1.0;
+ break;
+ }
+
+ return(nu_compute_nurb_curve( pddc, curve,
+ approx_type, approx_value,
+ curve_list ));
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level2/miNSTrim.c b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miNSTrim.c
new file mode 100644
index 000000000..30354c1b9
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miNSTrim.c
@@ -0,0 +1,1943 @@
+/* $TOG: miNSTrim.c /main/6 1998/02/10 12:41:47 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level2/miNSTrim.c,v 3.5 1998/10/04 09:34:22 dawes Exp $ */
+
+#include "mipex.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "miRender.h"
+#include "PEXErr.h"
+#include "gcstruct.h"
+#include "ddpex2.h"
+#include "miNurbs.h"
+#include "pexos.h"
+
+#define INACTIVE 0
+
+#define NEW_SEG( _td ) \
+ ((Nurb_trim_segment *)xalloc( sizeof(Nurb_trim_segment) ))
+
+/*++
+ |
+ | Function Name: phg_nt_free_trim_data
+ |
+ | Function Description:
+ |
+ | frees data allocated during the triming process.
+ |
+ | Note(s):
+ |
+ --*/
+
+void
+phg_nt_free_trim_data( tdata )
+ register Nurb_trim_data *tdata;
+{
+
+ register int i;
+ register Nurb_trim_segment *seg, *next_seg;
+
+ for ( i = 0; i < tdata->nloops; i++ ) {
+ for ( seg = tdata->loops[i].segs; seg; seg = next_seg ) {
+ next_seg = seg->next;
+ xfree( seg );
+ }
+ }
+ tdata->nloops = 0;
+
+ if ( tdata->vertices ) {
+ xfree( tdata->vertices );
+ tdata->vertices = (Nurb_param_point *)NULL;
+ }
+ if ( tdata->loops ) {
+ xfree( tdata->loops );
+ tdata->loops = (Nurb_trim_loop_rep *)NULL;
+ }
+ if ( tdata->ep_list_size > 0 ) {
+ xfree( tdata->ep_list );
+ tdata->ep_list_size = 0;
+ tdata->ep_list = (Nurb_edge_point *)NULL;
+ }
+}
+
+
+
+#define CHUNK_SIZE 5
+
+/*++
+ |
+ | Function Name: grow_range_list
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+static int
+grow_range_list( itr, inters )
+ int itr;
+ double **inters;
+{
+ if ( itr == 0 )
+ *inters = (double *)xalloc( CHUNK_SIZE * sizeof(double) );
+ else
+ *inters = (double *)xrealloc( *inters,
+ (itr + CHUNK_SIZE) * sizeof(double) );
+
+ return (*inters ? Success : BadAlloc);
+}
+
+/*++
+ |
+ | Function Name: compute_intersections
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+static int
+compute_intersections( state, dir, s, inters, inter_count )
+ Nurb_surf_state *state;
+ int dir; /* coordinate direction, 1 ==> U, 2 ==> V */
+ double s;
+ double **inters;
+ int *inter_count;
+{
+ register int i, j;
+ register int itr;
+ register Nurb_trim_data *tdata;
+ register Nurb_trim_segment *cur;
+ register Nurb_param_limit *ext;
+ register Nurb_param_point *trim_pts;
+ register double pa, pb, pc, pd;
+ register double alpha;
+
+ itr = 0;
+ tdata = &state->trim_data;
+ trim_pts = tdata->vertices;
+
+ for ( i = 0; i < tdata->nloops; i++ ) {
+ ext = &tdata->loops[i].extent;
+ if ( (dir == 1 && s > ext->umin && s <= ext->umax )
+ || (dir == 2 && s > ext->vmin && s <= ext->vmax ) ) {
+ for ( cur = tdata->loops[i].segs; cur; cur = cur->next ) {
+ ext = &cur->extent;
+ if ( (dir == 1 && s > ext->umin && s <= ext->umax )
+ || (dir == 2 && s > ext->vmin && s <= ext->vmax ) ) {
+ for ( j = cur->first; j < cur->last; j++ ) {
+ if ( dir == 1 ) { /* U direction */
+ pa = trim_pts[j].u; pb = trim_pts[j+1].u;
+ pc = trim_pts[j].v; pd = trim_pts[j+1].v;
+ } else { /* V direction */
+ pa = trim_pts[j].v; pb = trim_pts[j+1].v;
+ pc = trim_pts[j].u; pd = trim_pts[j+1].u;
+ }
+ if ( s > pa && s <= pb || s > pb && s <= pa ) {
+ if ( itr % CHUNK_SIZE == 0 )
+ if ( grow_range_list( itr, inters ) ) {
+ return (BadAlloc);
+ }
+ alpha = (s - pa) / (pb - pa);
+ (*inters)[itr++] = pc + alpha * (pd - pc);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ *inter_count = itr;
+ return ( Success );
+}
+#undef CHUNK_SIZE
+
+
+
+/*++
+ |
+ | Function Name: phg_nt_compute_trim_range
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+int
+phg_nt_compute_trim_range( state, dir, s, knot_min, knot_max,
+ ranges, trim_range_count )
+ Nurb_surf_state *state;
+ int dir; /* coordinate direction, 1 ==> U, 2 ==> V */
+ double s;
+ double knot_min;
+ double knot_max;
+ Nurb_limitlst *ranges;
+ int *trim_range_count;
+{
+ /* -1 ==> paint entire curve
+ * 0 ==> discard the curve
+ * >0 ==> paint in between trim ranges
+ */
+
+ int inter_count;
+ double tmp;
+ double *intersections = (double *)NULL;
+ int trim_ranges = -1;
+ int status;
+
+ register int i, j;
+
+ if ( state->trim_data.nloops <= 0 ) {
+ *trim_range_count = -1;
+ return ( Success );
+ }
+
+ if ( status = compute_intersections( state, dir, s,
+ &intersections, &inter_count ))
+ return(status);
+
+ if ( inter_count == -1 || inter_count == 0 ) {
+ /* All painted or none painted. */
+ trim_ranges = inter_count;
+
+ } else if ( inter_count == 1 && intersections[0] <= knot_min ) {
+ /* All painted */
+ trim_ranges = -1;
+
+ } else {
+ ranges->number = 0;
+ if ( inter_count % 2 == 1 ) {
+ /* Odd number of intersections. */
+ intersections[inter_count] = 1.0E30;
+ }
+
+ if ( inter_count > 0 ) {
+ /* Get space for range values. */
+ if ( inter_count > ranges->size ) {
+ if ( ranges->size <= 0 ) {
+ ranges->size = inter_count;
+ ranges->limits = (Nurb_limit *)
+ xalloc( ranges->size * sizeof(Nurb_limit) );
+ } else {
+ ranges->size = inter_count;
+ ranges->limits = (Nurb_limit *) xrealloc( ranges->limits,
+ ranges->size * sizeof(Nurb_limit) );
+ }
+
+ if ( ! ranges->limits ) {
+ ranges->size = 0;
+ xfree( intersections );
+ return ( BadAlloc );
+ }
+ }
+ }
+
+ if ( inter_count > 1 ) {
+ /* Sort intersections, lowest to highest. */
+ for ( j = 0; j < inter_count-1; j++ ) {
+ for ( i = j+1; i < inter_count; i++ ) {
+ if ( intersections[j] > intersections[i] ) {
+ tmp = intersections[i];
+ intersections[i] = intersections[j];
+ intersections[j] = tmp;
+ }
+ }
+ }
+ }
+
+ /* Compute trim ranges. */
+ for ( j = 0; j < inter_count; ) {
+ if ( intersections[j] >= knot_max ) {
+ /* Out of range, not painted. */
+ break;
+ } else {
+ if ( intersections[j] <= knot_min )
+ ranges->limits[ranges->number].lmin = knot_min;
+ else
+ ranges->limits[ranges->number].lmin = intersections[j];
+ ++j;
+
+ if ( intersections[j] >= knot_min ) {
+ if ( intersections[j] >= knot_max)
+ ranges->limits[ranges->number].lmax = knot_max;
+ else
+ ranges->limits[ranges->number].lmax = intersections[j];
+ ++ranges->number;
+ }
+ ++j;
+ }
+ }
+ trim_ranges = ranges->number;
+ }
+
+ if ( intersections )
+ xfree( intersections );
+
+ *trim_range_count = trim_ranges;
+
+ return( Success );
+}
+
+
+
+/*++
+ |
+ | Function Name: evaluate_trim_curve
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+static void
+evaluate_trim_curve( crv, span, t, p )
+ ddTrimCurve *crv;
+ int span;
+ double t;
+ ddCoord3D *p;
+{
+ ddCoord3D temp_points[MAXORD] ;
+ double alpha;
+
+ register int i, j, k, left;
+ register int order = crv->order;
+ register ddFLOAT *knots = crv->pKnots;
+ register ddCoord3D *tmp;
+ char rat;
+
+ /* Find the span where t belongs if not specified. */
+ if ( span )
+ left = span - order;
+ else {
+ left = crv->numKnots - 1;
+ if ( knots[left] == t )
+ while ( knots[left] >= t )
+ --left;
+ else
+ while ( knots[left] > t )
+ --left;
+ left -= order - 1;
+ }
+
+ /* Note that 3D implies homogeneous for trim curves */
+ rat = DD_IsVert3D(crv->pttype);
+
+ if (rat) {
+ ddCoord3D *cpts3;
+
+ /* Copy points to temp space. */
+ cpts3 = &crv->points.pts.p3Dpt[left];
+ tmp = temp_points;
+ memcpy( (char *)tmp, (char *)cpts3, order * sizeof(ddCoord3D) );
+
+ } else {
+ ddCoord2D *cpts2;
+
+ /* Copy points to temp space. */
+ cpts2 = &crv->points.pts.p2Dpt[left];
+ tmp = temp_points;
+ for ( i = 0; i < order; i++, cpts2++, tmp++ ) {
+ tmp->x = cpts2->x;
+ tmp->y = cpts2->y;
+ tmp->z = 1.0;
+ }
+
+ }
+
+ /* Evaluate the span. */
+ tmp = temp_points;
+ for ( k = 1; k < order; k++ ) {
+ for ( j = order-1; j >= k; j-- ) {
+ i = left + j;
+ alpha = (t - knots[i]) / (knots[i+order-k] - knots[i]);
+ tmp[j].x = tmp[j-1].x + alpha * (tmp[j].x - tmp[j-1].x);
+ tmp[j].y = tmp[j-1].y + alpha * (tmp[j].y - tmp[j-1].y);
+ if ( rat )
+ tmp[j].z = tmp[j-1].z + alpha * (tmp[j].z - tmp[j-1].z);
+ }
+ }
+
+ p->x = tmp[order-1].x;
+ p->y = tmp[order-1].y;
+ p->z = ( ( rat ) ? tmp[order-1].z : 1.0 );
+}
+
+
+
+#define ADD_TRIM_POINT( _r, _u, _v, _w ) \
+ { \
+ if ( (_r) ) { \
+ tdata->vertices[tdata->cur_vertex].u = (_u) / (_w); \
+ tdata->vertices[tdata->cur_vertex].v = (_v) / (_w); \
+ } else { \
+ tdata->vertices[tdata->cur_vertex].u = (_u); \
+ tdata->vertices[tdata->cur_vertex].v = (_v); \
+ } \
+ ++tdata->cur_vertex; \
+ }
+
+/*++
+ |
+ | Function Name: add_trim_curve
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+static void
+add_trim_curve( state, crv, tdata, seg )
+ Nurb_surf_state *state;
+ ddTrimCurve *crv;
+ Nurb_trim_data *tdata;
+ Nurb_trim_segment *seg;
+{
+ double t, dt;
+ double tmin = crv->uMin;
+ double tmax = crv->uMax;
+ double left, right;
+ ddCoord3D p;
+ char rat;
+
+ int i;
+ ddFLOAT *knots = crv->pKnots;
+ ddFLOAT tolerance;
+
+ /* Initialize segment and store location of first curve vertex. */
+ seg->vis = crv->visibility;
+ seg->start = tdata->cur_vertex;
+ seg->first = seg->start;
+
+ /* Note that 3D implies homogeneous for trim curves */
+ rat = DD_IsVert3D(crv->pttype);
+
+ /* Tessellate the trim curve and add the points to the vertex list. */
+
+ /* Special case second order (linear) curves. */
+ if ( crv->order == 2 ) {
+ double alpha, beta;
+
+ if (rat) {
+
+ ddCoord3D *pts3 = crv->points.pts.p3Dpt;
+
+ /* Find first interval of interest. */
+ if (tmin < knots[1]) tmin = knots[1];
+ for ( i = 2; knots[i] <= tmin; i++ )
+ ;
+
+ /* First point. */
+ alpha = (tmin - knots[i-1]) / (knots[i] - knots[i-1]);
+ beta = 1.0 - alpha;
+ p.x = beta * pts3[i-2].x + alpha * pts3[i-1].x;
+ p.y = beta * pts3[i-2].y + alpha * pts3[i-1].y;
+ p.z = beta * pts3[i-2].z + alpha * pts3[i-1].z;
+ ADD_TRIM_POINT( rat, p.x, p.y, p.z );
+
+ /* Interior points. */
+ if (tmax > knots[crv->numKnots - 2]) tmax = knots[crv->numKnots - 2];
+ for ( ; knots[i] < tmax; i++ ) {
+ ADD_TRIM_POINT( rat, pts3[i-1].x, pts3[i-1].y, pts3[i-1].z )
+ }
+
+ /* Last point. */
+ alpha = (tmax - knots[i-1]) / (knots[i] - knots[i-1]);
+ beta = 1.0 - alpha;
+ p.x = beta * pts3[i-2].x + alpha * pts3[i-1].x;
+ p.y = beta * pts3[i-2].y + alpha * pts3[i-1].y;
+ p.z = beta * pts3[i-2].z + alpha * pts3[i-1].z;
+ ADD_TRIM_POINT( rat, p.x, p.y, p.z );
+
+ } else {
+
+ ddCoord2D *pts2 = crv->points.pts.p2Dpt;
+
+ /* Find first interval of interest. */
+ if (tmin < knots[1]) tmin = knots[1];
+ for ( i = 2; knots[i] <= tmin; i++ )
+ ;
+
+ /* First point. */
+ alpha = (tmin - knots[i-1]) / (knots[i] - knots[i-1]);
+ beta = 1.0 - alpha;
+ p.x = beta * pts2[i-2].x + alpha * pts2[i-1].x;
+ p.y = beta * pts2[i-2].y + alpha * pts2[i-1].y;
+ ADD_TRIM_POINT( rat, p.x, p.y, 1.0 );
+
+ /* Interior points. */
+ if (tmax > knots[crv->numKnots - 2]) tmax = knots[crv->numKnots - 2];
+ for ( ; knots[i] < tmax; i++ ) {
+ ADD_TRIM_POINT( rat, pts2[i-1].x, pts2[i-1].y, 1.0 )
+ }
+
+ /* Last point. */
+ alpha = (tmax - knots[i-1]) / (knots[i] - knots[i-1]);
+ beta = 1.0 - alpha;
+ p.x = beta * pts2[i-2].x + alpha * pts2[i-1].x;
+ p.y = beta * pts2[i-2].y + alpha * pts2[i-1].y;
+ ADD_TRIM_POINT( rat, p.x, p.y, 1.0 );
+ }
+
+ } else if ( crv->order > MAXTCORD || crv->order < 2) { /* unsupported */
+ /* Use untrimmed control polygon. */
+ if (rat) {
+ ddCoord3D *pts3 = crv->points.pts.p3Dpt;
+ for ( i = 0; i < crv->points.numPoints; i++ )
+ ADD_TRIM_POINT(rat, pts3[i].x, pts3[i].y, pts3[i].z );
+ } else {
+ ddCoord2D *pts2 = crv->points.pts.p2Dpt;
+ for ( i = 0; i < crv->points.numPoints; i++ )
+ ADD_TRIM_POINT(rat, pts2[i].x, pts2[i].y, 1.0 );
+ }
+
+ } else { /* supported order > 2 */
+ GET_TRIM_CURVE_TOLERANCE(crv, tolerance);
+
+#ifdef BWEE
+ if ( crv->curveApprox.approxMethod == PCURV_CONSTANT_PARAMETRIC ) {
+ /* First point. */
+ evaluate_trim_curve( crv, 0, tmin, &p );
+ ADD_TRIM_POINT( rat, p.x, p.y, p.z );
+
+ /* Interior points. */
+ dt = (tmax - tmin) / (tolerance + 1);
+ for ( t = tmin + dt; t < tmax; t += dt ) {
+ evaluate_trim_curve( crv, 0, t, &p );
+ ADD_TRIM_POINT( rat, p.x, p.y, p.z );
+ }
+
+ /* Last point. */
+ evaluate_trim_curve( crv, 0, tmax, &p );
+ ADD_TRIM_POINT( rat, p.x, p.y, p.z );
+
+ } else
+#endif /* BWEE */
+
+ {
+
+ for ( i = crv->order - 1; i < crv->points.numPoints; i++ ) {
+ if ( knots[i] != knots[i+1]
+ && knots[i] <= tmax && knots[i+1] >= tmin ) {
+ left = knots[i];
+ right = knots[i+1];
+ dt = (right - left) / (tolerance + 1);
+ t = left;
+
+ /* If interval contains tmin get first point(s). */
+ if ( left <= tmin && right >= tmin ) {
+ while ( t < tmin )
+ t += dt;
+ evaluate_trim_curve( crv, i+1, tmin, &p );
+ ADD_TRIM_POINT( rat, p.x, p.y, p.z );
+ if ( t > tmin ) {
+ evaluate_trim_curve( crv, i+1, t, &p );
+ ADD_TRIM_POINT( rat, p.x, p.y, p.z );
+ }
+ t += dt;
+ }
+
+ /* Interior points. */
+ while ( t < right && t < tmax ) {
+ evaluate_trim_curve( crv, i+1, t, &p );
+ ADD_TRIM_POINT( rat, p.x, p.y, p.z );
+ t += dt;
+ }
+
+ /* If interval contains tmax get last point. */
+ if ( left <= tmax && right >= tmax ) {
+ evaluate_trim_curve( crv, i+1, tmax, &p );
+ ADD_TRIM_POINT( rat, p.x, p.y, p.z );
+ break; /* all done */
+ }
+ }
+ }
+ }
+ }
+
+ /* Store location of last vertex */
+ seg->end = tdata->cur_vertex - 1;
+ seg->last = seg->end;
+ seg->next = NULL;
+}
+
+
+
+#define CONNECT(_pa, _pb) \
+ { \
+ (_pb).u = (_pa).u; \
+ (_pb).v = (_pa).v; \
+ }
+
+/*++
+ |
+ | Function Name: connect_trim_endpoints
+ |
+ | Function Description:
+ |
+ | Insures that a list of tesselated trim curve segments
+ | forms a closed loop.
+ |
+ | Note(s):
+ |
+ --*/
+
+static void
+connect_trim_endpoints( tdata, seglist )
+ Nurb_trim_data *tdata;
+ register Nurb_trim_segment *seglist; /* linked list of segments */
+{
+ register Nurb_param_point *trim_pts = tdata->vertices;
+ register Nurb_trim_segment *cur;
+
+ /* Connect the tail of each curve to the head of the following curve. */
+ for ( cur = seglist; cur; cur = cur->next ) {
+ if ( cur->next )
+ CONNECT( trim_pts[cur->last], trim_pts[cur->next->first] )
+ else /* tail of last one to head of first one */
+ CONNECT( trim_pts[seglist->first], trim_pts[cur->last] )
+ }
+}
+
+
+
+/*++
+ |
+ | Function Name: make_segments_monotonic
+ |
+ | Function Description:
+ |
+ | Each curve segment description is traversed and, if
+ | necessary, subdivided into smaller segments until
+ | each remaining segment in the list of segments contains
+ | only monotonically increasing or decreasing (in both u & v)
+ | line segments (in other words, there are no changes in sign
+ | in the slope in either u and v in any segment).
+ |
+ | Note(s):
+ |
+ --*/
+
+static int
+make_segments_monotonic( tdata, tdloop )
+ Nurb_trim_data *tdata;
+ Nurb_trim_loop_rep *tdloop;
+{
+ unsigned old_u, old_v, u_direc, v_direc;
+
+ register int top, bot, mid;
+ register Nurb_param_point *trim_pts = tdata->vertices;
+ register Nurb_trim_segment *cur, *new;
+
+ for ( cur = tdloop->segs; cur; cur = cur->next ) {
+ top = cur->first;
+ mid = top;
+ bot = cur->last;
+ old_u = old_v = 0;
+ while (1) {
+ ++mid ;
+ if ( trim_pts[mid].u > trim_pts[top].u)
+ u_direc = 1;
+ else if ( trim_pts[mid].u < trim_pts[top].u )
+ u_direc = 2;
+ else
+ u_direc = old_u;
+
+ if ( trim_pts[mid].v > trim_pts[top].v )
+ v_direc = 1;
+ else if ( trim_pts[mid].v < trim_pts[top].v )
+ v_direc = 2;
+ else
+ v_direc = old_v;
+
+ if ( (u_direc | old_u) == 3 || (v_direc | old_v) == 3 ) {
+ cur->dir = ((old_u < 2) << 1) | (old_v < 2);
+ if ( !(new = NEW_SEG( tdata )) )
+ return BadAlloc; /* RETURN */
+
+ new->next = cur->next;
+ cur->next = new;
+ cur->end = cur->last = top;
+ new->start = new->first = top;
+ new->end = new->last = bot;
+ new->vis = cur->vis;
+ cur = new;
+ old_u = old_v = 0;
+ }
+ old_u = u_direc;
+ old_v = v_direc;
+ if ( mid == bot ) { /* LOOP EXIT CONDITION */
+ cur->dir = ((old_u < 2) << 1) | (old_v < 2);
+ break;
+ }
+ top = mid;
+ } /* while (1) */
+ }
+
+ return Success;
+}
+
+
+
+/*++
+ |
+ | Function Name: compute_trim_curve_extents
+ |
+ | Function Description:
+ |
+ | This function computes a trim loop extent
+ | as well as the extents of each of the segments
+ | in the loop.
+ |
+ | Note(s):
+ |
+ --*/
+
+static void
+compute_trim_curve_extents( tdata, tdloop )
+ Nurb_trim_data *tdata;
+ Nurb_trim_loop_rep *tdloop;
+{
+ double umin, vmin, umax, vmax;
+
+ register int top, bot;
+ register Nurb_param_point *trim_pts = tdata->vertices;
+ register Nurb_trim_segment *cur;
+
+ umin = vmin = 1.0E30; /* large number */
+ umax = vmax = -umin;
+ /* Assumes each segment is monotonic in both directions. */
+ for ( cur = tdloop->segs; cur; cur = cur->next ) {
+ if ( cur->start == INACTIVE || cur->end == INACTIVE )
+ continue;
+ top = cur->start;
+ bot = cur->end;
+
+ if ( trim_pts[top].u >= trim_pts[bot].u ) {
+ cur->extent.umin = trim_pts[bot].u;
+ cur->extent.umax = trim_pts[top].u;
+ } else {
+ cur->extent.umin = trim_pts[top].u;
+ cur->extent.umax = trim_pts[bot].u;
+ }
+
+ if ( trim_pts[top].v >= trim_pts[bot].v ) {
+ cur->extent.vmin = trim_pts[bot].v;
+ cur->extent.vmax = trim_pts[top].v;
+ } else {
+ cur->extent.vmin = trim_pts[top].v;
+ cur->extent.vmax = trim_pts[bot].v;
+ }
+
+ if ( cur->extent.umin < umin )
+ umin = cur->extent.umin;
+ if ( cur->extent.umax > umax )
+ umax = cur->extent.umax;
+ if ( cur->extent.vmin < vmin )
+ vmin = cur->extent.vmin;
+ if ( cur->extent.vmax > vmax )
+ vmax = cur->extent.vmax;
+ }
+ tdloop->extent.umin = umin;
+ tdloop->extent.umax = umax;
+ tdloop->extent.vmin = vmin;
+ tdloop->extent.vmax = vmax;
+}
+
+
+
+/*++
+ |
+ | Function Name: phg_nt_install_trim_loops
+ |
+ | Function Description:
+ |
+ | this routine creates a linked list of sorted tesselated
+ | curve segments as a prelude to trimming.
+ |
+ | Note(s):
+ |
+ --*/
+
+int
+phg_nt_install_trim_loops( surface, state )
+ miNurbSurfaceStruct *surface;
+ Nurb_surf_state *state;
+{
+ int interval_count;
+ listofTrimCurve *loop;
+ Nurb_trim_segment *seg;
+
+ int i, j;
+ Nurb_trim_data *tdata = &state->trim_data;
+ ddTrimCurve *crv;
+ Nurb_trim_loop_rep *tdloop;
+ Nurb_trim_segment **last_segp;
+ ddFLOAT tolerance;
+
+ /* Determine sizes for initial memory allocations. */
+ interval_count = 0;
+ loop = surface->trimCurves;
+ for ( i = 0; i < surface->numTrimCurveLists; i++, loop++ ) {
+ crv = loop->pTC;
+ for (j = 0; j < loop->count; j++, crv++) {
+ GET_TRIM_CURVE_TOLERANCE( crv, tolerance );
+ interval_count += (crv->points.numPoints * (tolerance + 4));
+ }
+ }
+
+ if ( ! (tdata->vertices = (Nurb_param_point *)
+ xalloc( interval_count * sizeof(tdata->vertices[0]) )) )
+ goto abort;
+
+ if ( ! (tdata->loops = (Nurb_trim_loop_rep *)
+ xalloc( surface->numTrimCurveLists * sizeof(tdata->loops[0]) )) )
+ goto abort;
+
+ /* Initialize the loop structures. */
+ for ( i = 0; i < surface->numTrimCurveLists; i++ )
+ tdata->loops[i].segs = (Nurb_trim_segment *)NULL;
+
+ /* Build the initial (non-monotonic) trim curve segments. */
+ for ( i = 0, loop = surface->trimCurves;
+ i < surface->numTrimCurveLists; i++, loop++ ) {
+
+ tdloop = &tdata->loops[i];
+ for ( j = 0, crv = loop->pTC; j < loop->count; j++, crv++ ) {
+ if ( !(seg = NEW_SEG( tdata )) )
+ goto abort;
+ add_trim_curve( state, crv, tdata, seg );
+ /* Add the new segment to the end of the list. */
+ last_segp = &tdloop->segs;
+ while ( *last_segp )
+ last_segp = &(*last_segp)->next;
+ *last_segp = seg;
+
+ }
+
+ ++tdata->nloops;
+ connect_trim_endpoints( tdata, tdloop->segs );
+ if ( make_segments_monotonic( tdata, tdloop ) )
+ goto abort;
+ compute_trim_curve_extents( tdata, tdloop );
+ }
+
+ return Success;
+
+abort:
+ phg_nt_free_trim_data( &state->trim_data );
+ return BadAlloc;
+}
+
+
+
+#ifdef NDEBUG
+
+#define PRINT_EXTENT( _e ) \
+ fprintf( stderr, "extent: u = ( %f, %f), v = ( %f, %f)\n", \
+ (_e).umin, (_e).umax, (_e).vmin, (_e).vmax );
+
+/*++
+ |
+ | Function Name: phg_nt_print_trim_rep_data
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+void
+phg_nt_print_trim_rep_data( state )
+ Nurb_surf_state *state;
+{
+ Nurb_trim_data *tdata = &state->trim_data;
+ Nurb_trim_loop_rep *loop;
+ Nurb_trim_segment *cur;
+
+ register int i, j;
+
+ fprintf( stderr, "Trim data: %d loops\n", tdata->nloops );
+ loop = tdata->loops;
+ for ( i = 0; i < tdata->nloops; i++, loop++ ) {
+ fprintf( stderr, "loop %d\n", i );
+ PRINT_EXTENT( loop->extent )
+ for ( cur = loop->segs; cur; cur = cur->next ) {
+ fprintf( stderr, "\n\tsegment: visibility = %s, direction = %d\n",
+ cur->vis ? "PON" : "POFF", cur->dir );
+ fprintf( stderr, "\tfirst = %d, last = %d, start = %d, end = %d\n",
+ cur->first, cur->last, cur->start, cur->end );
+ fprintf( stderr, "\t" );
+ PRINT_EXTENT( cur->extent )
+ for ( j = cur->first; j <= cur->last; j++ )
+ fprintf( stderr, "\t\t%3d: ( %10f, %10f)\n", j,
+ tdata->vertices[j].u, tdata->vertices[j].v );
+ }
+ }
+}
+#endif /* NDEBUG */
+
+
+
+/* Polygon Trimming Code */
+
+#define INACTIVE 0
+
+#define VISITED 4
+#define NEXT 2
+#define LAST 1
+
+#define EP_LIST_CHUNK 10 /* must be >= 5 */
+
+#define xin(_a,_b,_x) ((_x) >= (_a) && (_x) <= (_b))
+
+
+#define ROOM_IN_EP_LIST( _td ) \
+ ( (_td)->ep_index < (_td)->ep_list_size || !grow_ep_list(_td) )
+
+/*++
+ |
+ | Function Name: grow_ep_list
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+static int
+grow_ep_list( tdata )
+ Nurb_trim_data *tdata;
+{
+ /* TODO: Error reporting for failed allocations. */
+ tdata->ep_list_size += EP_LIST_CHUNK;
+ if ( tdata->ep_list_size == EP_LIST_CHUNK )
+ tdata->ep_list = (Nurb_edge_point *) xalloc(
+ EP_LIST_CHUNK * sizeof(Nurb_edge_point) );
+ else
+ tdata->ep_list = (Nurb_edge_point *) xrealloc( tdata->ep_list,
+ tdata->ep_list_size * sizeof(Nurb_edge_point) );
+
+ if ( !tdata->ep_list )
+ tdata->ep_list_size = 0;
+
+ return (tdata->ep_list ? Success : BadAlloc);
+}
+
+
+
+/*++
+ |
+ | Function Name: linear_interpolate
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+static void
+linear_interpolate( alpha, rat, normflag, a, b, out )
+ double alpha;
+ char rat;
+ unsigned normflag;
+ register Nurb_edge_point *a, *b, *out;
+{
+ out->pt.x = a->pt.x + (b->pt.x - a->pt.x) * alpha;
+ out->pt.y = a->pt.y + (b->pt.y - a->pt.y) * alpha;
+ out->pt.z = a->pt.z + (b->pt.z - a->pt.z) * alpha;
+ if ( rat )
+ out->pt.w = a->pt.w + (b->pt.w - a->pt.w) * alpha;
+ if ( normflag ) {
+ out->normal.x = a->normal.x + (b->normal.x - a->normal.x) * alpha;
+ out->normal.y = a->normal.y + (b->normal.y - a->normal.y) * alpha;
+ out->normal.z = a->normal.z + (b->normal.z - a->normal.z) * alpha;
+ }
+}
+
+/*++
+ |
+ | Function Name: bilinear
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+static void
+bilinear( alpha, beta, rat, normflag, a, b, c, d, out )
+ double alpha, beta;
+ char rat;
+ unsigned normflag;
+ Nurb_edge_point *a, *b, *c, *d;
+ Nurb_edge_point *out;
+{
+ Nurb_edge_point top, bot;
+
+ linear_interpolate( alpha, rat, normflag, a, b, &top );
+ linear_interpolate( alpha, rat, normflag, d, c, &bot );
+ linear_interpolate( beta, rat, normflag, &top, &bot, out );
+}
+
+
+
+/*++
+ |
+ | Function Name: append_pt
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+static int
+append_pt( tdata, normflag, rat, u, v, epa, epb, epc, epd )
+ Nurb_trim_data *tdata;
+ unsigned normflag;
+ char rat;
+ double u, v;
+ int epa, epb, epc, epd;
+{
+ double alpha, beta;
+ int status = BadAlloc;
+
+ register Nurb_edge_point *ep_list;
+ register Nurb_edge_point *cur_ep;
+
+ if ( ROOM_IN_EP_LIST(tdata) ) {
+ ep_list = tdata->ep_list;
+ cur_ep = &ep_list[tdata->ep_index];
+ cur_ep->u = u; cur_ep->v = v;
+ cur_ep->flags = 0;
+ alpha = (v - ep_list[epa].v) / (ep_list[epc].v - ep_list[epa].v);
+ beta = (u - ep_list[epa].u) / (ep_list[epc].u - ep_list[epa].u);
+ bilinear( alpha, beta, rat, normflag, &ep_list[epa], &ep_list[epb],
+ &ep_list[epc], &ep_list[epd], cur_ep );
+ cur_ep->branch = 0;
+ cur_ep->prev = tdata->ep_index - 1;
+ cur_ep->next = tdata->ep_index + 1;
+ ++tdata->ep_index;
+ status = Success;
+ }
+
+ return status;
+}
+
+
+
+/*++
+ |
+ | Function Name: insert_pt
+ |
+ | Function Description:
+ |
+ | This routine takes two indices into the
+ | Nurb_edge_point list, a point along one of the
+ | segment between the two edge points indicated
+ | by the two indices, and inserts a new edge
+ | point into the list corresponding to the
+ | supplied point.
+ |
+ | Inserting a new point means that the next and
+ | previous indices of the neighboring edge points are
+ | updated, and (x,y,z) and (if necessary) normal data
+ | is computed from the neighboring points for the new point.
+ |
+ | Note(s):
+ |
+ --*/
+
+static int
+insert_pt( tdata, normflag, rat, u, v, epa, epb, edge, branch )
+ Nurb_trim_data *tdata;
+ unsigned normflag;
+ char rat;
+ int epa, epb;
+ double u, v;
+ int edge, branch;
+{
+ double alpha;
+ int status = BadAlloc;
+
+ register int eptr;
+ register Nurb_edge_point *ep_list;
+ register Nurb_edge_point *cur_ep;
+
+ if ( ROOM_IN_EP_LIST(tdata) ) {
+ ep_list = tdata->ep_list;
+ cur_ep = &ep_list[tdata->ep_index];
+ cur_ep->u = u; cur_ep->v = v;
+ cur_ep->flags = 0;
+ switch ( edge ) {
+ case 0:
+ case 2:
+ alpha = (v - ep_list[epa].v)/(ep_list[epb].v - ep_list[epa].v);
+ break;
+ case 1:
+ case 3:
+ alpha = (u - ep_list[epa].u)/(ep_list[epb].u - ep_list[epa].u);
+ break;
+ default:
+ break;
+ }
+ linear_interpolate( alpha, rat, normflag, &ep_list[epa],
+ &ep_list[epb], cur_ep );
+ eptr = epa;
+ while ( eptr != epb ) {
+ double a, e, b;
+
+ switch ( edge ) {
+ case 0:
+ a = ep_list[eptr].v;
+ e = v;
+ b = ep_list[ep_list[eptr].next].v;
+ break;
+ case 1:
+ a = ep_list[eptr].u;
+ e = u;
+ b = ep_list[ep_list[eptr].next].u;
+ break;
+ case 2:
+ a = ep_list[ep_list[eptr].next].v;
+ e = v;
+ b = ep_list[eptr].v;
+ break;
+ case 3:
+ a = ep_list[ep_list[eptr].next].u;
+ e = u;
+ b = ep_list[eptr].u;
+ break;
+ default:
+ break;
+ }
+ if (xin(a, b, e) ) {
+ cur_ep->prev = eptr;
+ cur_ep->next = ep_list[eptr].next;
+ ep_list[ep_list[eptr].next].prev = tdata->ep_index;
+ ep_list[eptr].next = tdata->ep_index;
+ break; /* out of while */
+ }
+ eptr = ep_list[eptr].next;
+ }
+ cur_ep->branch = branch ? tdata->ep_index - 1 : tdata->ep_index + 1;
+ ++tdata->ep_index;
+ status = Success;
+ }
+
+ return status;
+}
+
+
+
+/*++
+ |
+ | Function Name: traverse
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+static void
+traverse( state, surface, output, ddSOFAS, el, winding )
+ Nurb_surf_state *state;
+ miNurbSurfaceStruct *surface;
+ ddpex3rtn (*output)();
+ miSOFASStruct *ddSOFAS;
+ int el;
+ int winding;
+{
+ int inside, branch, forward;
+ int more = 1;
+ Nurb_facet_op start = NURB_NEW_FACET;
+
+ register int i, ep, epstart, ep_index;
+ register Nurb_edge_point *ep_list = state->trim_data.ep_list;
+
+ ep = epstart = el;
+ inside = winding & 1;
+ /* Preprocess to mark edges. */
+ do {
+ if ( ep_list[ep].branch ) {
+ ep_list[ep].flags = (inside) ? LAST : NEXT;
+ inside = !inside;
+ }
+ ep = ep_list[ep].next;
+ } while ( ep != epstart );
+
+ inside = winding & 1;
+ branch = 0;
+ forward = 1;
+ /* Currently ep = epstart = el. */;
+ do { /* for all loops */
+ if ( start != NURB_NEW_FACET )
+ start = NURB_NEW_CONTOUR;
+ do { /* for all points in loop */
+ ep_list[ep].flags |= VISITED;
+ if ( branch ) { /* when on a branch */
+ (*output)( state, surface, ddSOFAS, start, &ep_list[ep] );
+ start = NURB_SAME_CONTOUR;
+ if ( ep_list[ep].branch ) { /* branch hits edge */
+ branch = 0;
+ forward = (ep_list[ep].flags & NEXT);
+ ep = (forward) ? ep_list[ep].next : ep_list[ep].prev;
+ } else { /* continue along branch */
+ ep = (forward) ? ep_list[ep].next : ep_list[ep].prev;
+ }
+ } else { /* when on the u,v quad boundary */
+ if ( ep_list[ep].branch ) { /* edge hits branch */
+ (*output)( state, surface, ddSOFAS, start, &ep_list[ep] );
+ start = NURB_SAME_CONTOUR;
+ branch = 1;
+ if ( !inside ) {
+ inside = 1;
+ epstart = ep;
+ }
+ forward = (ep_list[ ep_list[ep].branch].prev == ep);
+ ep = ep_list[ep].branch;
+ } else { /* continue along edge */
+ if ( inside ) {
+ (*output)(state, surface, ddSOFAS, start, &ep_list[ep]);
+ start = NURB_SAME_CONTOUR;
+ }
+ ep = (forward) ? ep_list[ep].next : ep_list[ep].prev;
+ }
+ }
+ } while ( ep != epstart );
+ forward = 1;
+ branch = 0;
+ inside = 1;
+ if ( more ) {
+ do { /* find next edge start pt */
+ if ( !(ep_list[epstart].flags & VISITED) &&
+ (ep_list[epstart].flags & LAST) )
+ break;
+ else
+ epstart = ep_list[epstart].next;
+ } while ( more = epstart != el );
+ }
+ /* Find next inside start pt. */
+ if ( !more ) {
+ epstart = 0;
+ /* Note: the first ep_index starts at 5. */
+ ep_index = state->trim_data.ep_index;
+ for ( i = 5; i < ep_index; i++ ) {
+ if ( !(ep_list[i].flags & VISITED) )
+ epstart = i;
+ }
+ branch = 1;
+ }
+ } while ( ep = epstart );
+}
+
+
+
+/* NEXT_TRIM_POINT gets next trim_pt and assign a bit pattern = <l b r t >
+ *
+ * 1001 | 0001 | 0011 9 | 1 | 3
+ * -------------------- u0 ------------
+ * 1000 | 0000 | 0010 8 | 0 | 2
+ * -------------------- u1 ------------
+ * 1100 | 0100 | 0110 12 | 4 | 6
+ * v0 v1
+ */
+#define NEXT_TRIM_POINT( _idx, _ptrn, _u, _v ) \
+ { \
+ (_u) = trim_pts[_idx].u; (_v) = trim_pts[_idx].v; \
+ if ( (_u) < u0 ) \
+ (_ptrn) = (_v) < v0 ? 9 : (_v) <= v1 ? 1 : 3 ; \
+ else if ( (_u) <= u1 ) \
+ (_ptrn) = (_v) < v0 ? 8 : (_v) <= v1 ? 0 : 2 ; \
+ else \
+ (_ptrn) = (_v) < v0 ? 12 : (_v) <= v1 ? 4 : 6 ; \
+ }
+
+/* NOTE: These are different than the ones in the surface code. */
+#define LL 1
+#define LR 4
+#define UR 3
+#define UL 2
+
+#define INSERT_PT( _u, _v, _ea, _eb, _ed, _br ) \
+ ( insert_pt( tdata, state->reps.normals, \
+ rat, (_u), (_v), (_ea), (_eb), (_ed), (_br) ) )
+
+#define APPEND_PT( _u, _v, _ea, _eb, _ec, _ed ) \
+ ( append_pt( tdata, state->reps.normals, \
+ rat, (_u), (_v), (_ea), (_eb), (_ec), (_ed) ) )
+
+
+
+
+/*++
+ |
+ | Function Name: phg_nt_trim_rect
+ |
+ | Function Description:
+ |
+ | This routine takes as input a list of trim curves
+ | (each trim curve loop described as a linked list
+ | of tesselated line segments broken into montonic
+ | sections), and a rectangle in u,v space, and creates
+ | a SOFAS description of the intersection of the rectangle
+ | and the trim curve loops.
+ |
+ | Note(s):
+ |
+ --*/
+
+int
+phg_nt_trim_rect( state, surface, rect, output, ddSOFAS )
+ Nurb_surf_state *state;
+ miNurbSurfaceStruct *surface;
+ Nurb_edge_point **rect;
+ ddpex3rtn (*output)();
+ miSOFASStruct *ddSOFAS;
+{
+ double u0, u1, v0, v1; /* rectangle in u,v space */
+ double itr;
+ double oldu, oldv, newu, newv;
+ int winding;
+ int old_out, new_out, tmp, index, first_pt;
+ Nurb_param_limit *ext;
+ char rat;
+
+ register int j;
+ register Nurb_trim_data *tdata = &state->trim_data;
+ register Nurb_edge_point *ep_list;
+ register Nurb_trim_segment *seg;
+ register Nurb_param_point *trim_pts = tdata->vertices;
+
+ /* Note that 3D implies homogeneous for trim curves */
+ rat = DD_IsVert3D(surface->points.type);
+
+ /* Make room for at least 4 points. */
+ if ( tdata->ep_list_size < 5 )
+ if ( grow_ep_list( tdata ) )
+ goto abort;
+
+ /* Copy the rectangle into ep_list[1,2,3,4] */
+ ep_list = tdata->ep_list;
+ for ( j = 1; j < 5; j++, rect++ ) {
+ ep_list[j].u = (*rect)->u;
+ ep_list[j].v = (*rect)->v;
+ ep_list[j].flags = 0;
+ ep_list[j].branch = 0;
+ ep_list[j].pt.x = (*rect)->pt.x;
+ ep_list[j].pt.y = (*rect)->pt.y;
+ ep_list[j].pt.z = (*rect)->pt.z;
+ if ( rat )
+ ep_list[j].pt.w = (*rect)->pt.w;
+ if ( state->reps.normals ) {
+ ep_list[j].normal.x = (*rect)->normal.x;
+ ep_list[j].normal.y = (*rect)->normal.y;
+ ep_list[j].normal.z = (*rect)->normal.z;
+ }
+ ep_list[j].next = j+1;
+ ep_list[j].prev = j-1;
+ }
+ /* Link the first and last elements */
+ ep_list[1].prev = 4;
+ ep_list[4].next = 1;
+ tdata->ep_index = 5; /* elements 1 to 4 used */
+
+ if ( tdata->nloops > 0 ) {
+ winding = 0;
+ u0 = ep_list[LL].u; v0 = ep_list[LL].v;
+ u1 = ep_list[UR].u; v1 = ep_list[UR].v;
+ } else
+ winding = 1; /* if no trim curves, default winding = 1 */
+
+ /* Intersect each trim loop against the rectangle bounds */
+ for ( j = 0; j < tdata->nloops ; j++ ) {
+
+ /* First, check against trim loop extent. */
+ if ( (tdata->loops[j].extent.umin > u1) ||
+ (tdata->loops[j].extent.umax < u0) ||
+ (tdata->loops[j].extent.vmin > v1) ||
+ (tdata->loops[j].extent.vmax < v0) )
+ /* Cannot intersect rectangle */
+ continue;
+
+ seg = tdata->loops[j].segs;
+ if ( seg ) { /* first point of the loop */
+ NEXT_TRIM_POINT( seg->start, new_out, newu, newv );
+ first_pt = new_out ? 0 : tdata->ep_index;
+ }
+ for ( ; seg; seg = seg->next ) {
+ if ( seg->start == 0 )
+ continue;
+ ext = &seg->extent;
+ if ( ext->umin > u1 || ext->vmin > v1 || ext->umax < u0 )
+ continue;
+ if ( ext->vmax < v0 ) {
+ if ( ext->umin < u0 && ext->umax >= u0 )
+ ++ winding;
+ continue;
+ }
+ index = seg->start;
+ NEXT_TRIM_POINT( index, new_out, newu, newv );
+ /* Note: first point is not inserted because trim_loop is closed */
+ while ( index != seg->end ) {
+ oldu = newu;
+ oldv = newv;
+ old_out = new_out;
+ ++index;
+ NEXT_TRIM_POINT( index, new_out, newu, newv );
+ if ( tmp = (new_out & old_out) ) { /* in same region */
+ if ( (tmp & 010)
+ && (newu < u0 && oldu >= u0 || newu >= u0 && oldu < u0))
+ ++ winding;
+ continue;
+ }
+ if ( old_out ) {
+ /* Intersects top edge between a and b? */
+ if ( (old_out & 01) && xin( v0, v1,
+ itr = oldv+(u0-oldu)*(newv-oldv)/(newu-oldu)) ) {
+ if ( INSERT_PT( u0, itr, LL, UL, 0, 0 ) )
+ goto abort;
+ } else {
+ if ( (old_out & 01) && itr < v0)
+ ++winding;
+ /* Intersects right edge between b and c? */
+ if ( (old_out & 02) && xin( u0, u1,
+ itr = oldu+(v1-oldv)*(newu-oldu)/(newv-oldv))){
+ if ( INSERT_PT(itr, v1, UL, UR, 1, 0) )
+ goto abort;
+ /* Intersects bottom edge between c and d? */
+ } else if ((old_out & 04) && xin(v0, v1,
+ itr = oldv+(u1-oldu)*(newv-oldv)/(newu-oldu))){
+ if ( INSERT_PT( u1, itr, UR, LR, 2, 0 ) )
+ goto abort;
+ /* intersects left edge between d and a? */
+ } else if ((old_out & 010) && xin( u0, u1,
+ itr = oldu+(v0-oldv)*(newu-oldu)/(newv-oldv))){
+ if ( INSERT_PT( itr, v0, LR, LL, 3, 0 ) )
+ goto abort;
+ }
+ }
+ }
+
+ if ( new_out == 0 ) {
+ if ( APPEND_PT( newu, newv, LL, UL, UR, LR ) )
+ goto abort;
+ } else {
+ /* Intersect top edge? */
+ if (( new_out & 01) && xin( v0, v1,
+ itr = oldv+(u0-oldu)*(newv-oldv)/(newu-oldu))) {
+ if ( INSERT_PT( u0, itr, LL, UL, 0, 1 ) )
+ goto abort;
+ } else {
+ if ( (new_out & 01) && itr < v0 )
+ ++winding;
+ /* Intersects right edge? */
+ if ( (new_out & 02) && xin( u0, u1,
+ itr = oldu+(v1-oldv)*(newu-oldu)/(newv-oldv))){
+ if ( INSERT_PT(itr, v1, UL, UR, 1, 1) )
+ goto abort;
+ /* Intersects bottom? */
+ } else if ( (new_out&04) && xin( v0, v1,
+ itr = oldv+(u1-oldu)*(newv-oldv)/(newu-oldu))){
+ if ( INSERT_PT(u1, itr, UR, LR, 2, 1) )
+ goto abort;
+ /* Intersects left edge? */
+ } else if ( (new_out & 010) && xin( u0, u1,
+ itr = oldu+(v0-oldv)*(newu-oldu)/(newv-oldv))){
+ if ( INSERT_PT(itr, v0, LR, LL, 3, 1) )
+ goto abort;
+ }
+ /* Left region? */
+ if ( (new_out & 010) && newu >= u0
+ && trim_pts[seg->end].u < u0 )
+ ++winding;
+ }
+ break; /* Skip remaining points in segment. */
+ }
+ } /* while ( not at end of segment ) */
+ } /* for all segments */
+
+ if ( first_pt ) {
+ index = tdata->ep_index - 1; /* back upto the last edge pt */
+ if ( tdata->ep_list[index].branch )
+ tdata->ep_list[index].branch = first_pt;
+ else
+ tdata->ep_list[index].next = first_pt;
+
+ if ( tdata->ep_list[first_pt].branch )
+ tdata->ep_list[first_pt].branch = index;
+ else
+ tdata->ep_list[first_pt].prev = index;
+ }
+ }
+
+ /* Traverse net and generate polygons. */
+ traverse( state, surface, output, ddSOFAS, LL, winding );
+
+ return Success;
+
+abort:
+ return BadAlloc;
+}
+
+
+
+#ifdef NDEBUG
+
+/*++
+ |
+ | Function Name: print_rect
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+static int
+print_rect( rat, rect )
+ char rat;
+ Nurb_edge_point **rect;
+{
+ fprintf( stderr, "\n" );
+ if ( rat ) {
+ fprintf( stderr, "LL: ( %f, %f) ==> ( %f, %f, %f, %f)\n",
+ rect[LL-1]->u, rect[LL-1]->v,
+ rect[LL-1]->pt.x, rect[LL-1]->pt.y, rect[LL-1]->pt.z,
+ rect[LL-1]->pt.w );
+ fprintf( stderr, "LR: ( %f, %f) ==> ( %f, %f, %f, %f)\n",
+ rect[LR-1]->u, rect[LR-1]->v,
+ rect[LR-1]->pt.x, rect[LR-1]->pt.y, rect[LR-1]->pt.z,
+ rect[LR-1]->pt.w );
+ fprintf( stderr, "UR: ( %f, %f) ==> ( %f, %f, %f, %f)\n",
+ rect[UR-1]->u, rect[UR-1]->v,
+ rect[UR-1]->pt.x, rect[UR-1]->pt.y, rect[UR-1]->pt.z,
+ rect[UR-1]->pt.w );
+ fprintf( stderr, "UL: ( %f, %f) ==> ( %f, %f, %f, %f)\n",
+ rect[UL-1]->u, rect[UL-1]->v,
+ rect[UL-1]->pt.x, rect[UL-1]->pt.y, rect[UL-1]->pt.z,
+ rect[UL-1]->pt.w );
+ } else {
+ fprintf( stderr, "LL: ( %f, %f) ==> ( %f, %f, %f)\n",
+ rect[LL-1]->u, rect[LL-1]->v,
+ rect[LL-1]->pt.x, rect[LL-1]->pt.y, rect[LL-1]->pt.z );
+ fprintf( stderr, "LR: ( %f, %f) ==> ( %f, %f, %f)\n",
+ rect[LR-1]->u, rect[LR-1]->v,
+ rect[LR-1]->pt.x, rect[LR-1]->pt.y, rect[LR-1]->pt.z );
+ fprintf( stderr, "UR: ( %f, %f) ==> ( %f, %f, %f)\n",
+ rect[UR-1]->u, rect[UR-1]->v,
+ rect[UR-1]->pt.x, rect[UR-1]->pt.y, rect[UR-1]->pt.z );
+ fprintf( stderr, "UL: ( %f, %f) ==> ( %f, %f, %f)\n",
+ rect[UL-1]->u, rect[UL-1]->v,
+ rect[UL-1]->pt.x, rect[UL-1]->pt.y, rect[UL-1]->pt.z );
+ }
+}
+#endif
+
+
+
+#define IN_SAME_REGION( _oca, _ocb ) ((_oca) & (_ocb))
+
+#define MORE_TRIM_POINTS( _s ) \
+ ((_s) && ((_s)->current != (_s)->last || (_s)->next))
+
+#define NEXT_POINT( _pts, _s, _p, _v ) \
+ { if ((_s)->current < 0) \
+ (_s)->current = (_s)->first; \
+ else if ((_s)->current != (_s)->last) \
+ ++(_s)->current; \
+ else { \
+ (_s) = (_s)->next; \
+ if ( (_s) ) \
+ (_s)->current = (_s)->first; \
+ } \
+ if ( _s ) { \
+ (_p).u = (_pts)[(_s)->current].u; \
+ (_p).v = (_pts)[(_s)->current].v; \
+ (_v) = (_s)->vis; \
+ } \
+ }
+
+/* Outcodes */
+#define IN 0
+#define OUT_TL 3
+#define OUT_TC 2
+#define OUT_TR 6
+#define OUT_CL 1
+#define OUT_CR 4
+#define OUT_BL 9
+#define OUT_BC 8
+#define OUT_BR 12
+
+#define LEFT OUT_CL
+#define RIGHT OUT_CR
+#define TOP OUT_TC
+#define BOTTOM OUT_BC
+
+#define OUTCODE( _e, _p, _c ) \
+ { if ( (_p).u < (_e).umin ) \
+ (_c) = (_p).v < (_e).vmin ? OUT_BL : \
+ (_p).v <= (_e).vmax ? OUT_CL : OUT_TL; \
+ else if ( (_p).u <= (_e).umax ) \
+ (_c) = (_p).v < (_e).vmin ? OUT_BC : \
+ (_p).v <= (_e).vmax ? IN : OUT_TC; \
+ else \
+ (_c) = (_p).v < (_e).vmin ? OUT_BR : \
+ (_p).v <= (_e).vmax ? OUT_CR : OUT_TR; \
+ }
+
+#define ADJACENT_RECT( _g, _e, _r ) \
+ switch ( _e ) { \
+ case LEFT: \
+ --(_r)[LL]; --(_r)[LR]; --(_r)[UL]; --(_r)[UR]; \
+ break; \
+ case RIGHT: \
+ ++(_r)[LL]; ++(_r)[LR]; ++(_r)[UL]; ++(_r)[UR]; \
+ break; \
+ case TOP: \
+ (_r)[LL]+=(_g)->nu; (_r)[LR]+=(_g)->nu; \
+ (_r)[UL]+=(_g)->nu; (_r)[UR]+=(_g)->nu; \
+ break; \
+ case BOTTOM: \
+ (_r)[LL]-=(_g)->nu; (_r)[LR]-=(_g)->nu; \
+ (_r)[UL]-=(_g)->nu; (_r)[UR]-=(_g)->nu; \
+ break; \
+ }
+
+#define RECT_EXTENT( _r, _e ) \
+ { \
+ (_e).umin = (_r)[LL]->u; (_e).umax = (_r)[UR]->u; \
+ (_e).vmin = (_r)[LL]->v; (_e).vmax = (_r)[UR]->v; \
+ }
+
+#define AT_EDGE( _g, _e, _p ) \
+ ( ((_e) & LEFT && (_p).u <= (_g)->extent.umin) \
+ || ((_e) & RIGHT && (_p).u >= (_g)->extent.umax) \
+ || ((_e) & BOTTOM && (_p).v <= (_g)->extent.vmin) \
+ || ((_e) & TOP && (_p).v >= (_g)->extent.vmax))
+
+
+/*++
+ |
+ | Function Name: intersect
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+static int
+intersect( ext, old_out, new_out, old, new, inter )
+ Nurb_param_limit *ext;
+ unsigned old_out, new_out;
+ Nurb_param_point *old, *new, *inter;
+{
+ double t;
+ int edge;
+
+ if ( ((old_out == IN && new_out & OUT_CL) || (old_out & OUT_CL))
+ && xin( ext->vmin, ext->vmax,
+ t = old->v + (ext->umin-old->u) * (new->v-old->v)/(new->u-old->u))){
+ inter->u = ext->umin;
+ inter->v = t;
+ edge = LEFT;
+ } else if ( ((old_out == IN && new_out & OUT_TC) || (old_out & OUT_TC))
+ && xin( ext->umin, ext->umax,
+ t = old->u + (ext->vmax-old->v) * (new->u-old->u)/(new->v-old->v))){
+ inter->u = t;
+ inter->v = ext->vmax;
+ edge = TOP;
+ } else if ( ((old_out == IN && new_out & OUT_CR) || (old_out & OUT_CR))
+ && xin( ext->vmin, ext->vmax,
+ t = old->v + (ext->umax-old->u) * (new->v-old->v)/(new->u-old->u))){
+ inter->u = ext->umax;
+ inter->v = t;
+ edge = RIGHT;
+ } else if ( ((old_out == IN && new_out & OUT_BC) || (old_out & OUT_BC))
+ && xin( ext->umin, ext->umax,
+ t = old->u + (ext->vmin-old->v) * (new->u-old->u)/(new->v-old->v))){
+ inter->u = t;
+ inter->v = ext->vmin;
+ edge = BOTTOM;
+ } else
+ edge = 0;
+
+ return edge;
+}
+
+
+
+/*++
+ |
+ | Function Name: find_containing_rect
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+static void
+find_containing_rect( pt, grid, rect )
+ register Nurb_param_point *pt;
+ register Nurb_grid *grid;
+ Nurb_edge_point *rect[5];
+{
+ register Nurb_edge_point *gpt = &grid->pts[grid->nu+1];
+
+ for ( ; gpt->u < pt->u; gpt++ )
+ ;
+ for ( ; gpt->v < pt->v; gpt += grid->nu )
+ ;
+ rect[UR] = gpt;
+ rect[UL] = gpt - 1;
+ rect[LL] = rect[UL] - grid->nu;
+ rect[LR] = rect[UR] - grid->nu;
+}
+
+
+
+/*++
+ |
+ | Function Name: add_point
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+static void
+add_point( state, surface, vert_list, op, pt, edge, rect )
+ Nurb_surf_state *state;
+ miNurbSurfaceStruct *surface;
+ miListHeader *vert_list;
+ Nurb_path_op op;
+ Nurb_param_point *pt;
+ int edge;
+ Nurb_edge_point *rect[5];
+{
+ Nurb_edge_point new, *pa, *pb;
+ double alpha, beta;
+ char rat;
+
+ rat = DD_IsVert4D(surface->points.type);
+
+ new.u = pt->u; new.v = pt->v;
+ if ( edge ) {
+ switch ( edge ) {
+ case LEFT:
+ alpha = (pt->v - rect[LL]->v)/(rect[UL]->v - rect[LL]->v);
+ pa = rect[LL]; pb = rect[UL];
+ break;
+ case RIGHT:
+ alpha = (pt->v - rect[LR]->v)/(rect[UR]->v - rect[LR]->v);
+ pa = rect[LR]; pb = rect[UR];
+ break;
+ case TOP:
+ alpha = (pt->u - rect[UL]->u)/(rect[UR]->u - rect[UL]->u);
+ pa = rect[UL]; pb = rect[UR];
+ break;
+ case BOTTOM:
+ alpha = (pt->u - rect[LL]->u)/(rect[LR]->u - rect[LL]->u);
+ pa = rect[LL]; pb = rect[LR];
+ break;
+ }
+ linear_interpolate( alpha, rat, 0, pa, pb, &new );
+ } else {
+ alpha = (pt->v - rect[LL]->v)/(rect[UR]->v - rect[LL]->v);
+ beta = (pt->u - rect[LL]->u)/(rect[UR]->u - rect[LL]->u);
+ bilinear( alpha, beta, rat, 0, rect[LL], rect[UL],
+ rect[UR], rect[LR], &new );
+ }
+
+ ADD_POINT_TO_LIST( vert_list, rat, op, &new.pt );
+
+}
+
+
+
+#define NPATH_OP( _o, _n ) \
+ ((_o) ? ((_n) ? PT_LINE : PT_NOP) : ((_n) ? PT_MOVE : PT_NOP))
+
+/*++
+ |
+ | Function Name: follow_segs
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+static Nurb_trim_segment *
+follow_segs(state, surface, grid, tpts, seg, vert_list, start_pt,use_edge_flags)
+ Nurb_surf_state *state;
+ miNurbSurfaceStruct *surface;
+ Nurb_grid *grid;
+ Nurb_param_point *tpts;
+ Nurb_trim_segment *seg;
+ miListHeader *vert_list;
+ Nurb_param_point *start_pt;
+ int use_edge_flags;
+{
+ Nurb_edge_point *rect[5];
+ Nurb_param_limit extent;
+ unsigned old_out, new_out;
+ Nurb_param_point old, new;
+ int edge, done = 0;
+ ddULONG new_vis, old_vis;
+ Nurb_path_op op;
+
+ find_containing_rect( start_pt, grid, rect );
+
+ RECT_EXTENT( rect, extent )
+
+ op = use_edge_flags ? NPATH_OP( 0, seg->vis ) : PT_MOVE;
+ if ( op != PT_NOP )
+ add_point( state, surface, vert_list, op, start_pt, 0, rect );
+
+ old = *start_pt;
+ old_vis = seg->vis;
+ NEXT_POINT( tpts, seg, new, new_vis )
+ op = use_edge_flags ? NPATH_OP( old_vis, new_vis ) : PT_LINE;
+ while ( !done ) {
+ OUTCODE( extent, new, new_out )
+ if ( new_out == IN ) {
+ if ( op != PT_NOP )
+ add_point( state, surface, vert_list, op, &new, 0, rect );
+ old = new; old_vis = new_vis;
+ if ( MORE_TRIM_POINTS(seg) ) {
+ NEXT_POINT( tpts, seg, new, new_vis )
+ if ( use_edge_flags )
+ op = NPATH_OP( old_vis, new_vis );
+ } else
+ done = 1;
+ } else {
+ OUTCODE( extent, old, old_out )
+ edge = intersect( &extent, old_out, new_out, &old, &new, &old );
+ if ( op != PT_NOP )
+ add_point( state, surface, vert_list, op, &old, edge, rect );
+ if ( !AT_EDGE( grid, edge, old ) ) {
+ ADJACENT_RECT( grid, edge, rect )
+ RECT_EXTENT( rect, extent )
+ } else /* hit an edge of the grid */
+ done = 1;
+ }
+ }
+
+ /* Segments are monotonic so we're done with this one when an
+ * edge is hit.
+ */
+ seg = seg->next;
+ if ( seg )
+ seg->current = -1;
+ return seg;
+}
+
+
+
+/*++
+ |
+ | Function Name: phg_nt_draw_segs
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+int
+phg_nt_draw_segs( state, surface, grid, seg, spts, use_edge_flags, vert_list )
+ Nurb_surf_state *state;
+ miNurbSurfaceStruct *surface;
+ Nurb_grid *grid;
+ register Nurb_trim_segment *seg;
+ Nurb_param_point *spts;
+ int use_edge_flags;
+ miListHeader *vert_list;
+{
+ unsigned old_out, new_out;
+ Nurb_param_point old, new;
+ Nurb_param_limit *ext;
+ ddULONG vis;
+
+ ext = &grid->extent;
+ seg->current = -1;
+ old_out = IN;
+ for ( ; MORE_TRIM_POINTS(seg); old = new, old_out = new_out ) {
+ NEXT_POINT( spts, seg, new, vis )
+ OUTCODE( *ext, new, new_out )
+ if ( new_out == IN ) {
+ if ( old_out ) {
+ (void)intersect( ext, old_out, new_out, &old, &new, &new );
+ }
+ --seg->current;
+ seg = follow_segs( state, surface, grid, spts, seg, vert_list,
+ &new, use_edge_flags );
+ old_out = IN;
+ continue;
+ } else if ( old_out ) {
+ if ( IN_SAME_REGION(old_out, new_out) )
+ continue;
+ if ( intersect( ext, old_out, new_out, &old, &new, &new )) {
+ --seg->current;
+ seg = follow_segs( state, surface, grid, spts, seg, vert_list,
+ &new, use_edge_flags );
+ old_out = IN;
+ continue;
+ }
+ }
+ }
+}
+
+#define WS_NTRM_BOTTOM
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level2/miNSurf.c b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miNSurf.c
new file mode 100644
index 000000000..06da5fb96
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miNSurf.c
@@ -0,0 +1,2466 @@
+/* $TOG: miNSurf.c /main/11 1998/02/10 12:41:53 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level2/miNSurf.c,v 3.6 1998/10/04 09:34:23 dawes Exp $ */
+
+#define TRIMING 1
+
+#include <math.h>
+#include "mipex.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "PEXErr.h"
+#include "miStruct.h"
+#include "miRender.h"
+#include "gcstruct.h"
+#include "ddpex2.h"
+#include "miNurbs.h"
+#include "pexos.h"
+
+
+static ddpex3rtn build_surf_reps();
+static int add_grid();
+static int uniform_isocurves();
+static int nonuniform_isocurves();
+static void nurb_surf_state_free();
+static ddpex3rtn compute_adaptive_surf_interval();
+static void determine_reps_required();
+static ddpex3rtn compute_nurb_surface();
+static ddpex3rtn build_facets();
+static ddpex3rtn build_control_polygon();
+static ddpex3rtn build_surf_markers();
+static ddpex3rtn span_grids();
+static void compute_edge_point_normals();
+static void build_edge_reps();
+static void make_edge_segments();
+static void span_evaluation_points();
+#ifdef TRIMING
+static ddpex3rtn add_pgon_point();
+#endif
+
+
+/*
+ * This convention is established in the trimming code.
+ * Note that it's clockwise from lower left.
+ */
+#define LL 0
+#define LR 3
+#define UR 2
+#define UL 1
+
+#define xin(_a,_b,_x) ((_x) >= (_a) && (_x) <= (_b))
+
+/*++
+ |
+ | Function Name: miNurbsSurface
+ |
+ | Function Description:
+ | Handles the Nurbs Surface Pex OC.
+ |
+ | Rendering a surface path is a 4 step process in this
+ | implementation.
+ |
+ | The first step is to determine the proper parametric step
+ | size according to the specified surface tolerance. Note
+ | that tesselation is performed in Model Coordinates in this
+ | implementation. However, surface tolerances are specified
+ | in one of WC, NPC, or DC. Thus the control points are tranformed
+ | in a temporary buffer into the specified space for determination
+ | of the maximum parametric step size.
+ |
+ | Once this step size is determined, a series of grid descriptions
+ | are created - one grid per knot interval. In other words,
+ | each grid describes the area specified by the four knot pairs
+ | (u,v), (u+1,v), (u,v+1), (u+1,v+1). These grids are then
+ | subdivided according to the u,v step size computed above
+ | and the (x,y,z,w) coordinates corresponding to each of the
+ | (u,v) steps computed. The result of this operation is a linked
+ | list of (u,v) (x,y,z,w) pairs for each span in the surface.
+ |
+ | The third step in the process is to trim this surface according
+ | to the supplied trim curve bounds. NEED MORE TEXT HERE.
+ |
+ | The fourth and last step in the procedure is to convert
+ | the (potentially trimmed) grid description od the surface
+ | into miListHeader point lists that can be used by the
+ | rest of the system. Note that no "direct" rendering is performed
+ | by this routine. Rather, the data that resulted from the
+ | previous steps are converted into one of the other primitive
+ | in the system (ie SOFAS, quad mesh, polyline, etc...) and
+ | rendered by one of these routines.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+miNurbsSurface(pRend, pExecuteOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pExecuteOC;
+{
+/* calls */
+ ddpex3rtn build_surf_reps();
+ extern ocTableType InitExecuteOCTable[];
+
+/* Local variable definitions */
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ miNurbSurfaceStruct *ddSurface = (miNurbSurfaceStruct *)(pExecuteOC+1);
+ miListHeader *input_list = &ddSurface->points;
+ miListHeader *listheader;
+ Nurb_surf_state surface_state;
+ miGenericStr *pGStr;
+ miMarkerStruct *ddMarker;
+ miPolylineStruct *ddPolyline;
+ miFillAreaStruct *ddFillArea;
+ Nurb_grid *grid;
+ miQuadMeshStruct *ddQuad;
+ miSOFASStruct *ddSOFAS;
+ listofddFacet facet_list;
+ ddUSHORT save_edges;
+ ddEnumTypeIndex save_intStyle;
+ int num_points;
+ int i, j;
+ ddpex3rtn status = Success;
+
+
+
+ switch(pddc->Static.attrs->surfApprox.approxMethod) {
+
+ case PEXApproxImpDep:
+ case PEXApproxConstantBetweenKnots:
+ case PEXApproxDcChordalSize:
+ case PEXSurfaceApproxDcPlanarDev:
+ case PEXApproxDcRelative:
+ default:
+
+ case PEXApproxWcsChordalSize:
+ case PEXSurfaceApproxWcsPlanarDev:
+ case PEXApproxWcsRelative:
+
+ /* Transform to WC prior to tesselation */
+ /* tesselate surface into facets */
+ if (status = build_surf_reps( pddc, ddSurface, &surface_state,
+ pddc->Dynamic->mc_to_wc_xform ))
+ goto exit;
+
+ break;
+
+
+ case PEXApproxNpcChordalSize:
+ case PEXSurfaceApproxNpcPlanarDev:
+ case PEXApproxNpcRelative:
+
+ /* tesselate surface into facets */
+ if (status = build_surf_reps( pddc, ddSurface, &surface_state,
+ pddc->Dynamic->mc_to_npc_xform ))
+ goto exit;
+
+ break;
+ }
+
+
+ /*
+ * render the computed structures.
+ *
+ * Note that the final structure can be rendered in many ways
+ * according to the surface data and rendering attributes.
+ * the surface_state.reps structure contains flags to indicate
+ * the data created during the tesselation process.
+ */
+ if ( surface_state.reps.markers ) {
+
+ /* allocate polyline command block */
+ if (!(pGStr = (miGenericStr *) (xalloc(sizeof(miGenericStr) +
+ sizeof(miMarkerStruct))))) {
+ status = BadAlloc;
+ goto exit;
+ }
+
+ pGStr->elementType = PEXOCMarker;
+ /* The length data is ignored by the rendering routine and hence is */
+ /* left as whatever GARBAGE that will be present at the alloc time. */
+
+ ddMarker = (miMarkerStruct *) (pGStr + 1);
+ *ddMarker = *((miMarkerStruct *)(surface_state.markers));
+ status = InitExecuteOCTable[(int)(pGStr->elementType)](pRend, pGStr);
+
+ xfree(pGStr);
+
+ } else {
+
+ if ( surface_state.reps.facets ) {
+
+ /* Don't draw edges here - they are drawn seperately */
+ save_edges = pddc->Static.attrs->edges;
+ pddc->Static.attrs->edges = PEXOff;
+
+ if ( ddSurface->numTrimCurveLists <= 0 ) {
+ /*
+ * If no trimming, then each tesselated surface
+ * is described by a number of grids, each grid containing
+ * a single quad mesh. Therefore, loop through the
+ * grid list in the surface state, and call quad mesh
+ * for each grid.
+ */
+
+ /* allocate polyline command block */
+ if (!(pGStr = (miGenericStr *) (xalloc(sizeof(miGenericStr) +
+ sizeof(miQuadMeshStruct))))) {
+ status = BadAlloc;
+ goto exit;
+ }
+
+ pGStr->elementType = PEXOCQuadrilateralMesh;
+ /* The length data is ignored by the rendering routine and hence is */
+ /* left as whatever GARBAGE that will be present at the alloc time. */
+
+ ddQuad = (miQuadMeshStruct *) (pGStr + 1);
+
+ /* Initialize quad mesh structure */
+ /*** ddQuad->shape = ***/
+
+ facet_list.numFacets = 0;
+ facet_list.type = DD_FACET_NONE;
+ facet_list.facets.pNoFacet = NULL;
+ facet_list.maxData = 0;
+ ddQuad->pFacets = &facet_list;
+
+ grid = surface_state.grids.grids;
+ listheader = surface_state.facets;
+
+ for (i = 0; i < surface_state.grids.number; i++) {
+
+ ddQuad->mPts = grid->nu;
+ ddQuad->nPts = (grid++)->nv;
+ ddQuad->points = *(listheader++);
+
+ if(status=InitExecuteOCTable[(int)(pGStr->elementType)](pRend,pGStr))
+ break;
+
+ }
+
+ } else {
+ /*
+ * If trimming is enabled, then SOFAS are output from
+ * the tesselation code.
+ * The SOFAS structure is already built, so just call the
+ * SOFAS routine.
+ */
+
+ /* allocate polyline command block */
+ if (!(pGStr = (miGenericStr *) (xalloc(sizeof(miGenericStr) +
+ sizeof(miSOFASStruct))))) {
+ status = BadAlloc;
+ goto exit;
+ }
+
+ pGStr->elementType = PEXOCSOFAS;
+ /* The length data is ignored by the rendering routine and hence is */
+ /* left as whatever GARBAGE that will be present at the alloc time. */
+
+ ddSOFAS = (miSOFASStruct *) (pGStr + 1);
+ *ddSOFAS = *((miSOFASStruct *)(surface_state.sofas));
+
+ status = InitExecuteOCTable[(int)(pGStr->elementType)](pRend, pGStr);
+
+ }
+
+ xfree(pGStr);
+ /* restore edge flag */
+ pddc->Static.attrs->edges = save_edges;
+
+ } else if ( surface_state.reps.hollow ) {
+
+ /* allocate fill area command block */
+ if (!(pGStr = (miGenericStr *) (xalloc(sizeof(miGenericStr) +
+ sizeof(miFillAreaStruct))))) {
+ status = BadAlloc;
+ goto exit;
+ }
+
+ pGStr->elementType = PEXOCFillAreaSet;
+ /* The length data is ignored by the rendering routine and hence is */
+ /* left as whatever GARBAGE that will be present at the alloc time. */
+
+ ddFillArea = (miFillAreaStruct *) (pGStr + 1);
+ ddFillArea->shape = PEXUnknownShape;
+ ddFillArea->ignoreEdges = PEXOn;
+ ddFillArea->contourHint = PEXUnknownContour;
+ facet_list.numFacets = 0;
+ facet_list.type = DD_FACET_NONE;
+ facet_list.facets.pNoFacet = NULL;
+ facet_list.maxData = 0;
+ ddFillArea->pFacets = &facet_list;
+ ddFillArea->points = *(surface_state.hollow);
+ status = InitExecuteOCTable[(int)(pGStr->elementType)](pRend, pGStr);
+
+ xfree(pGStr);
+
+ }
+
+ if ( surface_state.reps.isocrvs ) {
+
+ /* allocate polyline command block */
+ if (!(pGStr = (miGenericStr *) (xalloc(sizeof(miGenericStr) +
+ sizeof(miPolylineStruct))))) {
+ status = BadAlloc;
+ goto exit;
+ }
+
+ pGStr->elementType = PEXOCPolylineSet;
+ /* The length data is ignored by the rendering routine and hence is */
+ /* left as whatever GARBAGE that will be present at the alloc time. */
+
+ ddPolyline = (miPolylineStruct *) (pGStr + 1);
+ *ddPolyline = *((miPolylineStruct *)(surface_state.isocrvs));
+ status = InitExecuteOCTable[(int)(pGStr->elementType)](pRend, pGStr);
+
+ xfree(pGStr);
+
+ }
+
+ if ( surface_state.reps.edges ) {
+
+ /* set edge flag and interior style such that only edges are drawn */
+ save_edges = pddc->Static.attrs->edges;
+ pddc->Static.attrs->edges = PEXOn;
+
+ save_intStyle = pddc->Static.attrs->intStyle;
+ pddc->Static.attrs->intStyle = PEXInteriorStyleEmpty;
+
+ /* allocate fill area command block */
+ if (!(pGStr = (miGenericStr *) (xalloc(sizeof(miGenericStr) +
+ sizeof(miFillAreaStruct))))) {
+ status = BadAlloc;
+ goto exit;
+ }
+
+ pGStr->elementType = PEXOCFillAreaSet;
+ /* The length data is ignored by the rendering routine and hence is */
+ /* left as whatever GARBAGE that will be present at the alloc time. */
+
+ ddFillArea = (miFillAreaStruct *) (pGStr + 1);
+ ddFillArea->shape = PEXUnknownShape;
+ ddFillArea->ignoreEdges = PEXOff;
+ ddFillArea->contourHint = PEXUnknownContour;
+ facet_list.numFacets = 0;
+ facet_list.type = DD_FACET_NONE;
+ facet_list.facets.pNoFacet = NULL;
+ facet_list.maxData = 0;
+ ddFillArea->pFacets = &facet_list;
+ ddFillArea->points = *(surface_state.edges);
+ status = InitExecuteOCTable[(int)(pGStr->elementType)](pRend, pGStr);
+
+ xfree(pGStr);
+
+ /* restore edge flag */
+ pddc->Static.attrs->edges = save_edges;
+ /* restore interior style */
+ pddc->Static.attrs->intStyle = save_intStyle;
+
+ }
+ }
+
+exit:
+
+ /* free all temporary storage */
+ nurb_surf_state_free(&surface_state);
+
+ return (status);
+
+}
+
+
+
+#define ANY_REP_NEEDED(_st) \
+ ( (_st)->reps.edges || (_st)->reps.facets || (_st)->reps.isocrvs \
+ || (_st)->reps.markers || (_st)->reps.hollow )
+
+#define NEED_NORMALS(_st) ( (_st)->reps.facets )
+
+/*++
+ |
+ | Function Name: build_surf_reps
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+static
+ddpex3rtn
+build_surf_reps( pddc, surface, state, trans )
+ miDDContext *pddc;
+ miNurbSurfaceStruct *surface;
+ Nurb_surf_state *state;
+ ddFLOAT trans[4][4];
+{
+ /* uses */
+ ddpex3rtn status = Success; /* assume success */
+
+ if ( surface->mPts <= 0 || surface->nPts <= 0 )
+ return 0;
+
+ NURB_SURF_STATE_INIT(state);
+
+ switch ( pddc->Static.attrs->surfApprox.approxMethod ) {
+ case PEXApproxConstantBetweenKnots:
+ case PEXApproxImpDep:
+ default:
+ state->approx_type = PEXApproxConstantBetweenKnots;
+ state->approx_value[0] =
+ MAX((int)pddc->Static.attrs->surfApprox.uTolerance,0);
+ state->approx_value[1] =
+ MAX((int)pddc->Static.attrs->surfApprox.vTolerance,0);
+ break;
+
+ case PEXApproxWcsChordalSize:
+ case PEXApproxNpcChordalSize:
+ case PEXSurfaceApproxWcsPlanarDev:
+ case PEXSurfaceApproxNpcPlanarDev:
+ case PEXApproxWcsRelative:
+ case PEXApproxNpcRelative:
+ /* The same approximation method is used for all these
+ * approximation types, and it's not exactly any of them.
+ * But the method used serves the same purpose and
+ * PHIGS PLUS allows us to approximate the defined methods.
+ */
+ state->approx_type = PEXApproxConstantBetweenKnots;
+ compute_adaptive_surf_interval( pddc, surface, state, trans );
+ break;
+ }
+
+ determine_reps_required( pddc, surface, state );
+
+ if ( ANY_REP_NEEDED(state) ) {
+ status = compute_nurb_surface( pddc, surface, state );
+ }
+
+ return ( status );
+}
+
+
+
+/*++
+ |
+ | Function Name: compute_adaptive_surf_interval
+ |
+ | Function Description:
+ |
+ | This routine computes the number of steps that must
+ | be taken in the u & v directions. Note that although
+ | the actual tesselation takes place in model coordinates
+ | (to ease integration with the remainder of the rendering code),
+ | the control points must be transformed here to the
+ | space specified by the curve approximation criteria
+ | to guarantee the proper number of steps are computed.
+ |
+ | Note(s):
+ |
+ --*/
+
+static
+ddpex3rtn
+compute_adaptive_surf_interval( pddc, surface, state, trans )
+ miDDContext *pddc;
+ miNurbSurfaceStruct *surface;
+ Nurb_surf_state *state;
+ ddFLOAT trans[4][4];
+{
+/* uses */
+ ddFLOAT uval, vval, a_coeff, b_coeff, c_coeff, denom,
+ z1, z2, z3;
+ ddCoord4D p;
+ double perp_d, max_u_perp_d = 0.0, max_v_perp_d = 0.0;
+
+ int i, j, use_z_coord = 0;
+ int nu = surface->mPts;
+ int nv = surface->nPts;
+ ddCoord4D *upper, *lower, *middle, *pa, *pb, *pc, *coord_buf;
+ char *ctlpts, *pin;
+ double w;
+ miListHeader *input = &surface->points;
+ char rat;
+ int point_size;
+ ddPointType out_type;
+ ddpex3rtn status;
+
+ /*
+ * Compute the constant parametric between knots interval needed to
+ * come close to meeting the specified approximation criteria. The
+ * method used is a gross compromise for the adaptive approximation
+ * criteria, but fulfills the basic need for an adaptive approximation
+ * method.
+ * Note that for the NPC approximation criteria NPC isn't even the space
+ * being used, it's clipping space, which is [-1,1], [-1,1], [0,1].
+ * The Z component is ignored in this case though since the Z dimension
+ * is perpendicular to the screen.
+ */
+ state->approx_value[0] = 0.0;
+ state->approx_value[1] = 0.0;
+ switch ( pddc->Static.attrs->surfApprox.approxMethod ) {
+ case PEXApproxNpcChordalSize:
+ case PEXSurfaceApproxNpcPlanarDev:
+ use_z_coord = 0;
+ break;
+ case PEXApproxWcsChordalSize:
+ case PEXSurfaceApproxWcsPlanarDev:
+ use_z_coord = 1;
+ break;
+ }
+
+ /*
+ * transform comtrol points into space specified by
+ * approximation tolerance
+ */
+ if ( trans ) {
+ miListHeader *temp;
+
+ /* Transform to WC prior to applying lighting */
+ out_type = input->type;
+ if (status = miTransform( pddc, input, &temp,
+ trans, NULL4x4, DD_SetVert4D(out_type)))
+ return (status);
+ input = temp;
+ }
+
+ rat = DD_IsVert4D(input->type);
+ ctlpts = input->ddList->pts.ptr;
+ DD_VertPointSize(input->type, point_size);
+
+
+ /* Allocate temporary control point store */
+ if (!(coord_buf = (ddCoord4D *)xalloc(3 * nu * sizeof(ddCoord4D))))
+ return(BadAlloc);
+
+ /*
+ * For the above approx. types, the approx. value is the max. allowable
+ * distance between the actual surface and the generated segments.
+ * The distance of the ctrl point from the line joining the ctrl pts on
+ * either side of it is calculated for every ctrl pt. This is calculated
+ * in 2D. For approx. in WC, the 3D length is got from the 2D-length
+ * and the z values of the ctrl pts. The max of all these lengths is
+ * found. This is repeated for all the ctrl pts in the u and v directions.
+ * The final approx. value is obtd. from the ratio of the max length
+ * and the required approx. value.
+ */
+
+ upper = coord_buf; middle = coord_buf + nu; lower = coord_buf + 2*nu;
+ for ( j = 0; j < nv-1; j++, ctlpts += nu*point_size ) {
+
+ /*
+ * project the points from homogeneous space.
+ */
+ if ( rat ) {
+ for ( i = 0, pin = ctlpts, pa = lower;
+ i < nu;
+ i++, pa++, pin += point_size ) {
+ if (((ddCoord4D *)pin)->w == 1.0) *pa = *((ddCoord4D *)pin);
+ else {
+ w = 1.0 / ((ddCoord4D *)pin)->w;
+ pa->x = ((ddCoord4D *)pin)->x * w;
+ pa->y = ((ddCoord4D *)pin)->y * w;
+ if ( use_z_coord ) pa->z = ((ddCoord4D *)pin)->z * w;
+ }
+ }
+ } else {
+ for ( i = 0, pin = ctlpts, pa = lower;
+ i < nu;
+ i++, pa++, pin += point_size ) {
+ memcpy( (char *)pa, pin, point_size);
+ pa->w = 1.0;
+ }
+ }
+
+ /* Find the required u interval between points of this row. */
+ pa = lower; pb = pa + 2, pc = pa + 1;
+ for ( i = 1; i < nu-1; i++, pa++, pb++,pc++) {
+ a_coeff = pb->y - pa->y;
+ b_coeff = pa->x - pb->x;
+ c_coeff = pb->x * pa->y - pa->x * pb->y;
+ denom = ( a_coeff * a_coeff + b_coeff * b_coeff );
+ perp_d = (a_coeff * pc->x + b_coeff * pc->y + c_coeff);
+ if ( use_z_coord ) {
+ z1 = pc->z;
+ z2 = (pa->z + pb->z) /2.0;
+ z3 = z1-z2;
+ perp_d = sqrt( (perp_d * perp_d + z3 * z3 * denom) /denom );
+ } else {
+ perp_d = perp_d/ (sqrt(denom));
+ }
+ perp_d = fabs(perp_d);
+ if ( perp_d > max_u_perp_d )
+ max_u_perp_d = perp_d;
+ }
+
+ if ( j > 1 ) {
+ /* Find the required v interval between these two rows. */
+ pa = upper; pb = lower, pc = middle;
+ for ( i = 0; i < nu; i++, pa++, pb++, pc++ ) {
+ a_coeff = pb->y - pa->y;
+ b_coeff = pa->x - pb->x;
+ c_coeff = pb->x * pa->y - pa->x * pb->y;
+ denom = ( a_coeff * a_coeff + b_coeff * b_coeff );
+ perp_d = (a_coeff * pc->x + b_coeff * pc->y + c_coeff);
+ if ( use_z_coord ) {
+ z1 = pc->z;
+ z2 = (pa->z + pb->z) /2.0;
+ z3 = z1-z2;
+ perp_d = sqrt( (perp_d * perp_d + z3 * z3 * denom) /denom );
+ } else {
+ perp_d = perp_d/ (sqrt(denom));
+ }
+ perp_d = fabs(perp_d);
+ if ( perp_d > max_v_perp_d )
+ max_v_perp_d = perp_d;
+ }
+ }
+
+ /* Swap row pointers so that next row is the "lower" row. */
+ pa = upper;
+ upper = middle;
+ middle = lower;
+ lower = pa;
+ }
+
+ switch ( pddc->Static.attrs->surfApprox.approxMethod ) {
+ case PEXApproxWcsChordalSize:
+ case PEXApproxNpcChordalSize:
+ uval = pddc->Static.attrs->surfApprox.uTolerance;
+ vval = pddc->Static.attrs->surfApprox.vTolerance;
+ break;
+ case PEXSurfaceApproxWcsPlanarDev:
+ case PEXSurfaceApproxNpcPlanarDev:
+ uval = pddc->Static.attrs->surfApprox.uTolerance;
+ vval = pddc->Static.attrs->surfApprox.uTolerance;
+ break;
+ }
+ state->approx_value[0] = (int)( 1 + sqrt(10*max_u_perp_d
+ / (uval > 0.0 ? uval : 0.01)));
+ state->approx_value[1] = (int)( 1 + sqrt(10*max_v_perp_d
+ / (vval > 0.0 ? vval : 0.01)));
+
+ xfree(coord_buf);
+
+ return(Success);
+}
+
+
+
+/*++
+ |
+ | Function Name: determine_reps_required
+ |
+ | Function Description:
+ |
+ | This routine selects the format of the data
+ | created for rendering the speecified surface patch.
+ | Different data descriptions are generated according
+ | to both the surface data and the current rendering
+ | attributes. For example, quad mesh data is created
+ | to describe an un-trimmed solid surface; polyline
+ | data, however, is created if surface iso-curves
+ | are enabled.
+ |
+ | Note(s):
+ |
+ --*/
+
+static void
+determine_reps_required( pddc, surface, state )
+ miDDContext *pddc;
+ miNurbSurfaceStruct *surface;
+ Nurb_surf_state *state;
+{
+ if ( surface->uOrder <= 1 && surface->vOrder <= 1 ) {
+ state->reps.markers = 1;
+
+ } else if ( (surface->uOrder > MAXORD) || (surface->vOrder > MAXORD) ) {
+ /* Order is not supported; just draw the control net. */
+ state->reps.isocrvs = 1;
+ state->isocount[0] = 1;
+ state->isocount[1] = 1;
+
+ } else {
+
+ /*
+ * First evaluate interior style
+ */
+ switch ( pddc->Static.attrs->intStyle ) {
+ case PEXInteriorStyleSolid:
+ state->reps.facets = 1;
+ /* Only compute normals if lighting enabled */
+ if (pddc->Static.attrs->reflModel != PEXReflectionNoShading)
+ state->reps.normals = 1;
+ break;
+ case PEXInteriorStyleHollow:
+ state->reps.hollow = 1;
+ break;
+ case PEXInteriorStylePattern:
+ case PEXInteriorStyleHatch:
+ state->reps.facets = 1;
+ /* Only compute normals if lighting enabled */
+ if (pddc->Static.attrs->reflModel != PEXReflectionNoShading)
+ state->reps.normals = 1;
+ break;
+ case PEXInteriorStyleEmpty:
+ /* No addtional action required. */
+ break;
+ }
+
+ /*
+ * Next, parametric surface characteristics.
+ */
+ switch ( pddc->Dynamic->pPCAttr->psc.type ) {
+ case PEXPSCNone:
+ case PEXPSCImpDep:
+ break;
+ case PEXPSCIsoCurves:
+ state->reps.isocrvs = 1;
+ /* Negative curve counts mean no curves between knots. */
+ state->isocount[0] =
+ MAX(pddc->Dynamic->pPCAttr->psc.data.isoCurves.numUcurves,0);
+ state->isocount[1] =
+ MAX(pddc->Dynamic->pPCAttr->psc.data.isoCurves.numVcurves,0);
+ break;
+ case PEXPSCMcLevelCurves:
+ case PEXPSCWcLevelCurves:
+ /* Note that level curves are not implemented */
+ break;
+ }
+
+ if ( pddc->Static.attrs->edges == PEXOn )
+ state->reps.edges = 1;
+ }
+}
+
+
+
+/*++
+ |
+ | Function Name: compute_nurb_surface
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+static
+ddpex3rtn
+compute_nurb_surface( pddc, surface, state )
+ miDDContext *pddc;
+ miNurbSurfaceStruct *surface;
+ Nurb_surf_state *state;
+{
+
+/* calls */
+#ifdef TRIMING
+ ddpex3rtn phg_nt_install_trim_loops();
+#endif
+
+/* uses */
+ ddpex3rtn status = Success;
+ int i;
+
+ state->range.umin = surface->pUknots[surface->uOrder - 1];
+ state->range.umax = surface->pUknots[surface->numUknots - surface->uOrder];
+ state->range.vmin = surface->pVknots[surface->vOrder - 1];
+ state->range.vmax = surface->pVknots[surface->numVknots - surface->vOrder];
+
+ state->param_limits.umin = state->range.umin;
+ state->param_limits.umax = state->range.umax;
+ state->param_limits.vmin = state->range.vmin;
+ state->param_limits.vmax = state->range.vmax;
+
+ /* Check for unsupported order. */
+ if ( surface->uOrder > MAXORD || surface->uOrder > MAXORD ) {
+ /* Draw *only* the control polygon. */
+ return build_control_polygon( surface, state );
+ }
+
+ if ( state->reps.markers ) {
+ return build_surf_markers( surface, state );
+ }
+
+ /*
+ * build initial grid description
+ */
+ if (status = span_grids( state, surface ))
+ goto abort;
+
+ if ( state->reps.normals ) {
+ for ( i = 0; i < state->grids.number; i++ )
+ compute_edge_point_normals( surface, &state->grids.grids[i] );
+ state->grids.flags.normals = 1;
+ }
+
+ if ( surface->numTrimCurveLists > 0 ) {
+#ifdef TRIMING
+ if ( status = phg_nt_install_trim_loops( surface, state ) )
+ goto abort;
+#endif /* TRIMING */
+ }
+
+ if ( state->reps.edges || state->reps.hollow ) {
+ if ( surface->numTrimCurveLists <= 0 )
+ make_edge_segments( state );
+ if ( state->reps.edges )
+ build_edge_reps( pddc, state, surface, &state->edges, 1 );
+ if ( state->reps.hollow )
+ build_edge_reps( pddc, state, surface, &state->hollow, 0 );
+ }
+
+ if ( state->reps.facets ) {
+ status = build_facets( state, surface );
+ }
+
+ if ( state->reps.isocrvs ) {
+ switch( pddc->Dynamic->pPCAttr->psc.data.isoCurves.placementType ) {
+ default:
+ case 0 /* PEXPSCUniform */:
+ status = uniform_isocurves( state, surface );
+ break;
+ case 1 /* PEXPSCNonUniform */:
+ status = nonuniform_isocurves( state, surface );
+ break;
+ }
+ }
+
+abort:
+ return (status);
+
+}
+
+
+
+/*++
+ |
+ | Function Name: span_grids
+ |
+ | Function Description:
+ |
+ | This routine is the first step in creating a tesselated
+ | polygon description of a surface patch. The rendering
+ |
+ |
+ | Note(s):
+ |
+ --*/
+
+static
+ddpex3rtn
+span_grids( state, surface )
+ Nurb_surf_state *state;
+ miNurbSurfaceStruct *surface;
+{
+/* uses */
+ double *uvals = 0,
+ *vvals = 0; /* need double precision */
+ int num_uvals, num_vvals;
+ int ucount, vcount;
+ int uspan, vspan;
+ int *uspans = 0,
+ *vspans = 0;
+ int num_uspans, num_vspans;
+
+ int i, j;
+ ddFLOAT *uknots = surface->pUknots;
+ ddFLOAT *vknots = surface->pVknots;
+ ddpex3rtn status = Success;
+
+ /* Small inaccuracies sometimes cause span_evaluation_points() to
+ * generate an extra point or two, so allocate the arrays two sizes
+ * larger than the expected need.
+ */
+ ucount = state->approx_value[0] + 4;
+ vcount = state->approx_value[1] + 4;
+
+ if ( !( uvals = (double *) xalloc(ucount * sizeof(double))) ) {
+ status = BadAlloc;
+ goto abort;
+ }
+
+ if ( !( vvals = (double *) xalloc(vcount * sizeof(double))) ) {
+ status = BadAlloc;
+ goto abort;
+ }
+
+ num_uspans = 1; uspans = &uspan;
+ num_vspans = 1; vspans = &vspan;
+ for ( i = surface->uOrder - 1; i < surface->mPts; i++ ) {
+ if ( uknots[i] != uknots[i+1] ) {
+ uspan = i + 1;
+ span_evaluation_points( uknots, i,
+ state->range.umin, state->range.umax,
+ state->approx_value[0],
+ &num_uvals, uvals );
+ if ( num_uvals <= 0 )
+ continue;
+
+ for ( j = surface->vOrder - 1; j < surface->nPts; j++ ) {
+ if ( vknots[j] != vknots[j+1] ) {
+ vspan = j + 1;
+ span_evaluation_points( vknots, j,
+ state->range.vmin,state->range.vmax,
+ state->approx_value[1],
+ &num_vvals, vvals );
+ if ( num_vvals <= 0 )
+ continue;
+
+ if ( status = add_grid( state, surface,
+ num_uvals, num_vvals,
+ uvals, vvals,
+ num_uspans, num_vspans,
+ uspans, vspans ) )
+ goto abort;
+ }
+ }
+ }
+ }
+
+abort:
+ if (uvals) xfree(uvals);
+ if (vvals) xfree(vvals);
+
+ return (status);
+}
+
+
+
+/*++
+ |
+ | Function Name: span_evaluation_points
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+static void
+span_evaluation_points( knots, span, tmin, tmax, apxval, num_vals, vals )
+ ddFLOAT *knots;
+ int span;
+ double tmin, tmax;
+ double apxval;
+ int *num_vals;
+ double *vals;
+{
+ double t, dt;
+ double left, right;
+
+ int count = 0, maxvals;
+ double *ep = vals;
+
+ if ( knots[span] < tmax && knots[span+1] > tmin ) {
+ /* maxvals is used to control the number of positions generated so
+ * that very small nearly zero-width intervals aren't generated
+ * due to small floating point inaccuracies.
+ */
+ maxvals = apxval + 2;
+ left = knots[span];
+ right = knots[span+1];
+ dt = (right - left) / (double)(maxvals - 1);
+ t = left;
+
+ /* If tmin is in the interval then start with it. */
+ if ( tmin > left && tmin < right ) {
+ ep[count++] = tmin;
+ while ( t <= tmin ) {
+ t += dt; --maxvals;
+ }
+ }
+ ep[count++] = t;
+ t += dt; --maxvals;
+
+ /* Interior values. */
+ for ( ; maxvals > 1 && t < tmax; t += dt, --maxvals )
+ ep[count++] = t;
+
+ /* Last value. */
+ if ( right > tmax )
+ ep[count++] = tmax;
+ else
+ ep[count++] = right;
+ }
+ *num_vals = count;
+}
+
+
+
+#define GRID_LIST_CHUNK 5
+
+/*++
+ |
+ | Function Name: add_grid
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+static int
+add_grid( state, surface, ucount, vcount, uvals, vvals,
+ num_uspans, num_vspans, uspans, vspans )
+ Nurb_surf_state *state;
+ miNurbSurfaceStruct *surface;
+ int ucount, vcount;
+ double *uvals, *vvals;
+ int num_uspans, num_vspans;
+ int *uspans, *vspans;
+{
+/* calls */
+ void phg_ns_evaluate_surface_in_span();
+
+/* uses */
+ int uspan, vspan;
+ int i, j;
+ Nurb_edge_point *ep;
+ Nurb_grid *grid;
+
+ if ( ucount <= 0 || vcount <= 0 )
+ return 1;
+
+ if ( state->grids.number % GRID_LIST_CHUNK == 0 ) {
+ if ( state->grids.number == 0 )
+ state->grids.grids = (Nurb_grid *)xalloc(
+ GRID_LIST_CHUNK * sizeof(Nurb_grid) );
+ else
+ state->grids.grids = (Nurb_grid *)xrealloc( state->grids.grids,
+ (state->grids.number + GRID_LIST_CHUNK) * sizeof(Nurb_grid) );
+ }
+ if ( !state->grids.grids ) {
+ return (BadAlloc);
+ }
+
+ ++state->grids.number;
+
+ grid = &state->grids.grids[state->grids.number-1];
+ if ( !( grid->pts = (Nurb_edge_point *)
+ xalloc(ucount * vcount * sizeof(Nurb_edge_point))) ) {
+ return (BadAlloc);
+ }
+
+ /* Calculate vertex coordinates. */
+ ep = grid->pts;
+ for ( j = 0; j < vcount; j++ ) {
+ vspan = (num_vspans > 1) ? vspans[j] : vspans[0];
+ for ( i = 0; i < ucount; i++, ep++ ) {
+ ep->count = 0;
+ ep->u = uvals[i]; ep->v = vvals[j];
+ uspan = (num_uspans > 1) ? uspans[i]:uspans[0];
+ phg_ns_evaluate_surface_in_span( surface, ep->u, ep->v,
+ uspan, vspan, &ep->pt );
+ }
+ }
+ grid->nu = ucount; grid->nv = vcount;
+ grid->extent.umin = uvals[0]; grid->extent.umax = uvals[ucount-1];
+ grid->extent.vmin = vvals[0]; grid->extent.vmax = vvals[vcount-1];
+
+ return (Success);
+}
+
+
+
+/*++
+ |
+ | Function Name: phg_ns_evaluate_surface_in_span
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+void
+phg_ns_evaluate_surface_in_span( surface, u, v, uspan, vspan, spt )
+ miNurbSurfaceStruct *surface;
+ register double u, v;
+ int uspan, vspan;
+ ddCoord4D *spt;
+{
+ ddCoord4D npt[MAXORD], tmppts[MAXORD];
+ int iu, iv;
+ int i;
+ double alpha, alpha1;
+ int nu, nv, j, k;
+ int uorder = surface->uOrder;
+ int vorder = surface->vOrder;
+ ddFLOAT *uknots = surface->pUknots;
+ ddFLOAT *vknots = surface->pVknots;
+ ddCoord4D *tmp;
+ char rat;
+
+ rat = DD_IsVert4D(surface->points.type);
+
+ iu = uspan - uorder; iv = vspan - vorder;
+ for ( nv = 0; nv < vorder; nv++ ) {
+
+ if ( rat ) {
+ for ( nu = 0; nu < uorder; nu++ )
+ tmppts[nu] = surface->points.ddList->pts.p4Dpt[(iv + nv) * surface->mPts + (iu + nu)];
+ } else {
+ for ( nu = 0; nu < uorder; nu++ ) {
+ tmppts[nu].x = surface->points.ddList->pts.p3Dpt[(iv + nv) * surface->mPts + (iu + nu)].x;
+ tmppts[nu].y = surface->points.ddList->pts.p3Dpt[(iv + nv) * surface->mPts + (iu + nu)].y;
+ tmppts[nu].z = surface->points.ddList->pts.p3Dpt[(iv + nv) * surface->mPts + (iu + nu)].z;
+ }
+ }
+
+ for ( k = 1; k < uorder; k++ ) {
+ for ( j = uorder-1, tmp = &tmppts[j]; j >= k; j--, tmp--) {
+ i= j + iu;
+ alpha = (u - uknots[i]) / (uknots[i+uorder-k] - uknots[i]);
+ alpha1 = 1.0 - alpha;
+ tmp->x = alpha * tmp->x + alpha1 * (tmp-1)->x;
+ tmp->y = alpha * tmp->y + alpha1 * (tmp-1)->y;
+ tmp->z = alpha * tmp->z + alpha1 * (tmp-1)->z;
+ if ( rat )
+ tmp->w = alpha * tmp->w + alpha1 * (tmp-1)->w;
+ }
+ }
+
+ npt[nv] = tmppts[uorder - 1];
+ }
+
+ for ( nv = 0; nv < vorder; nv++ ) {
+ tmppts[nv] = npt[nv];
+ }
+
+ for ( k = 1; k < vorder; k++ ) {
+ for ( j = vorder - 1, tmp = &tmppts[j]; j >= k; j--, tmp--) {
+ i= j + iv;
+ alpha = (v - vknots[i]) / (vknots[i+vorder-k] - vknots[i]);
+ alpha1 = 1.0 - alpha;
+ tmp->x = alpha * tmp->x + alpha1 * (tmp-1)->x;
+ tmp->y = alpha * tmp->y + alpha1 * (tmp-1)->y;
+ tmp->z = alpha * tmp->z + alpha1 * (tmp-1)->z;
+ if ( rat )
+ tmp->w = alpha * tmp->w + alpha1 * (tmp-1)->w;
+ }
+ }
+
+ *spt = tmppts[vorder-1];
+ if ( !rat )
+ spt->w = 1.0;
+}
+
+
+
+/*++
+ |
+ | Function Name: phg_ns_evaluate_surface
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+void
+phg_ns_evaluate_surface( surface, u, v, spt )
+ miNurbSurfaceStruct *surface;
+ register double u, v;
+ ddCoord4D *spt;
+{
+ int iu, iv;
+
+ register ddFLOAT *uknots = surface->pUknots;
+ register ddFLOAT *vknots = surface->pVknots;
+
+ iu = surface->numUknots - 1;
+ iv = surface->numVknots - 1;
+
+ /* Ensure parameters are within range. */
+ if ( u < uknots[0] )
+ u = uknots[0];
+ else if ( u > uknots[iu] )
+ u = uknots[iu];
+
+ if ( v < vknots[0] )
+ v = vknots[0];
+ else if ( v > vknots[iv] )
+ v = vknots[iv];
+
+ /* Find the span where u,v belong. */
+ if ( uknots[iu] == u )
+ while ( uknots[iu] >= u ) --iu;
+ else
+ while ( uknots[iu] > u ) --iu;
+
+ if ( vknots[iv] == v )
+ while ( vknots[iv] >= v ) --iv;
+ else
+ while ( vknots[iv] > v ) --iv;
+ phg_ns_evaluate_surface_in_span( surface, u, v, ++iu, ++iv, spt );
+}
+
+
+
+/*++
+ |
+ | Function Name: avg_vertex_normal
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+static void
+avg_vertex_normal( count, pt, ptp, ptq, nout )
+ int count;
+ ddCoord3D *pt, *ptp, *ptq;
+ ddVector3D *nout;
+{
+ ddVector3D pvec, qvec;
+ ddVector3D nscratch;
+ double h;
+
+ ddVector3D *p = &pvec,
+ *q = &qvec;
+ ddVector3D *n;
+
+ /* Calculate the vertex normal for the specified vertex by computing
+ * the cross product of the vectors connecting "pt" to "ptp" and "ptq,"
+ * N = (ptp - pt) X (ptq - pt). If the count is > 0 average this normal
+ * into the vertex normal rather than just writing it there. This
+ * facilitates computing the average normal derived from all polygons
+ * adjacent to the vertex.
+ */
+ p->x = ptp->x - pt->x; p->y = ptp->y - pt->y; p->z = ptp->z - pt->z;
+ q->x = ptq->x - pt->x; q->y = ptq->y - pt->y; q->z = ptq->z - pt->z;
+ n = count > 0 ? &nscratch : nout;
+ n->x = p->y * q->z - q->y * p->z;
+ n->y = q->x * p->z - p->x * q->z;
+ n->z = p->x * q->y - q->x * p->y;
+ /* Normalize. */
+ h = 1.0 / sqrt(n->x * n->x + n->y * n->y + n->z * n->z);
+ n->x *= h; n->y *= h; n->z *= h;
+ if ( count > 0 ) {
+ /* Average in this normal. */
+ h = 1.0 / (double)(count + 1);
+ nout->x = h * ((double)count * nout->x + n->x);
+ nout->y = h * ((double)count * nout->y + n->y);
+ nout->z = h * ((double)count * nout->z + n->z);
+ /* Normalize the new average. */
+ n = nout;
+ h = 1.0 / sqrt(n->x * n->x + n->y * n->y + n->z * n->z);
+ n->x *= h; n->y *= h; n->z *= h;
+ }
+}
+
+
+
+/*++
+ |
+ | Function Name: build_facets
+ |
+ | Function Description:
+ |
+ | The purpose of this function is to take the surface internal
+ | descriptions of the grids and trim curves and convert them
+ | into descriptions of either quad meshes or SOFAS for
+ | rendering.
+ |
+ | Note that quad meshes are output if there are no trim curves,
+ | otherwise SOFAS are used.
+ |
+ | Note(s):
+ |
+ --*/
+
+static ddpex3rtn
+build_facets( state, surface )
+ Nurb_surf_state *state;
+ miNurbSurfaceStruct *surface;
+{
+
+#ifdef TRIMING
+ ddpex3rtn phg_nt_trim_rect();
+#endif /* TRIMING */
+
+ Nurb_edge_point *rect[4];
+ int g;
+ int i, j;
+ int ucount, vcount;
+ Nurb_grid *grid;
+ miListHeader *listheader;
+ char rat;
+ ddpex3rtn status;
+
+ /* Set the Path_d flags. */
+ if ( state->grids.number <= 0 ) return (Success);
+
+ rat = DD_IsVert4D(surface->points.type);
+
+ if ( surface->numTrimCurveLists > 0 ) {
+#ifdef TRIMING
+ /*
+ * If trim curves are present, build a SOFAS description
+ * of the trimmed surface.
+ */
+
+ /* Initialize output SOFAS structure */
+ state->sofas = (miSOFASStruct *)xalloc(sizeof(miSOFASStruct));
+ state->sofas->edgeAttribs = 0;
+ state->sofas->numFAS = state->sofas->numEdges = 0;
+ state->sofas->pFacets.type = DD_FACET_NONE;
+ state->sofas->pFacets.numFacets = state->sofas->pFacets.maxData = 0;
+ state->sofas->pFacets.facets.pNoFacet = 0;
+ state->sofas->points.numLists = state->sofas->points.maxLists = 0;
+ state->sofas->points.ddList = 0;
+ state->sofas->connects.numListLists = state->sofas->connects.maxData = 0;
+ state->sofas->connects.data = 0;
+
+ /* Note that each rectangle of each grid is trimmed separately */
+ for ( g = 0; g < state->grids.number; g++ ) {
+ grid = &state->grids.grids[g];
+ ucount = grid->nu; vcount = grid->nv;
+ if ( surface->numTrimCurveLists > 0 ) {
+ register Nurb_edge_point *ll, *lr, *ur, *ul;
+
+ /* Determine the facets and pass them to the trimming code. */
+ ll = &grid->pts[0]; lr = ll + 1;
+ ul = &grid->pts[ucount]; ur = ul + 1;
+ for ( j = 0; j < vcount-1; j++, ll++, lr++, ur++, ul++ ) {
+ for ( i = 0; i < ucount-1; i++, ll++, lr++, ur++, ul++ ) {
+ rect[LL] = ll;
+ rect[LR] = lr;
+ rect[UR] = ur;
+ rect[UL] = ul;
+ if ( status = phg_nt_trim_rect( state, surface, rect,
+ add_pgon_point,
+ state->sofas ) )
+ return status;
+ }
+ }
+ }
+ }
+#endif /* TRIMING */
+ } else {
+
+ /*
+ * no triming
+ * Create a list of quad meshes from the grid data.
+ */
+
+ state->facets =
+ (miListHeader *)xalloc(state->grids.number*sizeof(miListHeader));
+
+ listheader = state->facets;
+ grid = state->grids.grids;
+
+ /*
+ * Create a quad mesh for each grid
+ */
+ for ( g = 0; g < state->grids.number; g++ ) {
+
+ int j;
+ ddPointUnion new_point;
+ int num_pts = grid->nu * grid->nv;
+ Nurb_edge_point *ep = grid->pts;
+
+ listheader->flags = 0;
+ listheader->numLists = 0;
+ listheader->maxLists = 0;
+ listheader->ddList = 0;
+
+ MI_ALLOCLISTHEADER( listheader, 1);
+
+ /*
+ * Note that the data in the grid is already organized
+ * in quad mesh order. Therefore, all that needs to be
+ * done is to copy the data from the list of edge_points to
+ * a listofddPoints.
+ */
+ if ( rat ) {
+
+ if (state->reps.normals) {
+ listheader->type = DD_NORM_POINT4D;
+ MI_ALLOCLISTOFDDPOINT( listheader->ddList,
+ num_pts, sizeof(ddNormalPoint4D));
+ } else {
+ listheader->type = DD_HOMOGENOUS_POINT;
+ MI_ALLOCLISTOFDDPOINT( listheader->ddList,
+ num_pts, sizeof(ddCoord4D));
+ }
+
+ new_point = listheader->ddList->pts;
+ if (!(new_point.ptr)) return(BadAlloc);
+
+ for ( j = 0; j < num_pts; j++, ep++ ) {
+ *(new_point.p4Dpt++) = ep->pt;
+ if (state->reps.normals) *(new_point.pNormal++) = ep->normal;
+ }
+
+ listheader->ddList->numPoints = num_pts;
+
+ } else {
+
+ if (state->reps.normals) {
+ listheader->type = DD_NORM_POINT;
+ MI_ALLOCLISTOFDDPOINT( listheader->ddList,
+ num_pts, sizeof(ddNormalPoint));
+ } else {
+ listheader->type = DD_3D_POINT;
+ MI_ALLOCLISTOFDDPOINT( listheader->ddList,
+ num_pts, sizeof(ddCoord3D));
+ }
+
+ new_point = listheader->ddList->pts;
+ if (!(new_point.ptr)) return(BadAlloc);
+
+ for ( j = 0; j < num_pts; j++, ep++ ) {
+ *(new_point.p3Dpt++) = *((ddCoord3D *)(&ep->pt));
+ if (state->reps.normals) *(new_point.pNormal++) = ep->normal;
+ }
+
+ listheader->ddList->numPoints = num_pts;
+
+ }
+
+ /* skip to next grid and point list */
+ listheader++;
+ grid++;
+
+ }
+ }
+
+ return ( Success );
+}
+
+
+
+/*++
+ |
+ | Function Name: build_edge_reps
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+static void
+build_edge_reps( pddc, state, surface, edge_list, use_edge_flags )
+ miDDContext *pddc;
+ Nurb_surf_state *state;
+ miNurbSurfaceStruct *surface;
+ miListHeader **edge_list;
+ int use_edge_flags;
+{
+ Nurb_grid *grid = state->grids.grids;
+ miListHeader *out_list;
+ register int i, j;
+
+ /* Initialize output structure */
+ out_list = (miListHeader *)xalloc(sizeof(miListHeader));
+ *edge_list = out_list;
+ out_list->type = surface->points.type;
+ out_list->numLists = out_list->maxLists = 0;
+ out_list->ddList = 0;
+
+ if ( surface->numTrimCurveLists > 0 ) {
+#ifdef TRIMING
+ Nurb_trim_data *tdata = &state->trim_data;
+ Nurb_trim_segment *seg;
+
+ for ( i = 0; i < state->grids.number; i++, grid++ ) {
+ for ( j = 0; j < tdata->nloops; j++ ) {
+ if ( !EXTENTS_OVERLAP( grid->extent, tdata->loops[j].extent) )
+ continue;
+ if ( !(seg = tdata->loops[j].segs) )
+ continue;
+ phg_nt_draw_segs( state, surface, grid, seg, tdata->vertices,
+ use_edge_flags, out_list );
+ }
+ }
+#endif /* TRIMING */
+ } else {
+ for ( i = 0; i < state->grids.number; i++, grid++ ) {
+ phg_nt_draw_segs( state, surface, grid, state->edge_segs,
+ state->corners, use_edge_flags, out_list );
+ }
+ }
+}
+
+
+/*++
+ |
+ | Function Name: isocurve
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+static int
+isocurve( state, surface, dir, val, tmin, tmax, curve_list )
+ Nurb_surf_state *state;
+ miNurbSurfaceStruct *surface;
+ int dir; /* 1 ==> constant U, 2 ==> constant V */
+ double val;
+ double tmin, tmax;
+ miListHeader *curve_list;
+{
+ Nurb_trim_segment seg;
+ Nurb_param_point spts[2];
+ int i, j;
+ Nurb_grid *grid;
+ ddpex3rtn status;
+
+ /* Dummy up one or more trimming segments for this iso curve and pass
+ * them to the trim segment drawer.
+ */
+ seg.first = seg.start = 0; seg.last = seg.end = 1;
+ seg.next = (Nurb_trim_segment *)NULL;
+ if ( dir == 2 ) { /* constant V */
+ spts[0].v = spts[1].v = val;
+ seg.extent.vmin = seg.extent.vmax = val;
+ } else { /* constant U */
+ spts[0].u = spts[1].u = val;
+ seg.extent.umin = seg.extent.umax = val;
+ }
+
+ if ( surface->numTrimCurveLists > 0 ) {
+#ifdef TRIMING
+ ddpex3rtn phg_nt_compute_trim_range();
+ Nurb_limitlst ranges;
+ Nurb_limit no_limit;
+ int tc;
+
+ /* Get the trimming intervals. */
+ NURB_INIT_RANGE_LIST(&ranges);
+ if (status = phg_nt_compute_trim_range( state, dir, val,
+ tmin, tmax, &ranges, &tc ))
+ return( status );
+
+ if ( tc == -1) {
+ tc = 1;
+ ranges.limits = &no_limit;
+ no_limit.lmin = tmin;
+ no_limit.lmax = tmax;
+ }
+
+ for ( i = 0; i < tc; i++ ) {
+ if ( dir == 2 ) { /* constant V */
+ spts[0].u = seg.extent.umin = ranges.limits[i].lmin;
+ spts[1].u = seg.extent.umax = ranges.limits[i].lmax;
+ } else { /* constant U */
+ spts[0].v = seg.extent.vmin = ranges.limits[i].lmin;
+ spts[1].v = seg.extent.vmax = ranges.limits[i].lmax;
+ }
+ grid = state->grids.grids;
+ for ( j = 0; j < state->grids.number; j++, grid++ ) {
+ if ( dir == 1 && xin(grid->extent.umin,grid->extent.umax,val)
+ || dir == 2 && xin(grid->extent.vmin,grid->extent.vmax,val))
+ phg_nt_draw_segs(state, surface, grid, &seg, spts, 0, curve_list);
+ }
+ }
+
+ if ( ranges.size > 0 )
+ xfree( ranges.limits );
+
+#endif /* TRIMING */
+ } else { /* no trimming */
+ if ( dir == 2 ) { /* constant V */
+ spts[0].u = seg.extent.umin = tmin;
+ spts[1].u = seg.extent.umax = tmax;
+ } else { /* constant U */
+ spts[0].v = seg.extent.vmin = tmin;
+ spts[1].v = seg.extent.vmax = tmax;
+ }
+
+ grid = state->grids.grids;
+ for ( i = 0; i < state->grids.number; i++, grid++ ) {
+ if ( dir == 1 && xin(grid->extent.umin,grid->extent.umax,val)
+ || dir == 2 && xin(grid->extent.vmin,grid->extent.vmax,val))
+ phg_nt_draw_segs( state, surface, grid, &seg, spts, 0, curve_list );
+ }
+ }
+
+ return Success;
+}
+
+
+
+/*++
+ |
+ | Function Name: uniform_isocurves
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+static int
+uniform_isocurves( state, surface )
+ Nurb_surf_state *state;
+ miNurbSurfaceStruct *surface;
+{
+ double t, dt;
+ int j;
+ Nurb_param_limit *range = &state->param_limits;
+
+ /* Initialize output structure */
+ state->isocrvs = (miListHeader *)xalloc(sizeof(miListHeader));
+ state->isocrvs->type = surface->points.type;
+ state->isocrvs->numLists = state->isocrvs->maxLists = 0;
+ state->isocrvs->ddList = 0;
+
+ /* Place curves uniformly between the specified parameter limits.
+ * Also place curves at the parameter limits, only if there is no
+ * trimming.
+ */
+
+ /* First curve of constant U. */
+ t = range->umin;
+#ifdef CADAM
+ if ( surface->numTrimCurveLists <= 0 ) { /* no trimming */
+#endif /* CADAM */
+ (void)isocurve( state, surface, 1, t, range->vmin, range->vmax,
+ state->isocrvs );
+#ifdef CADAM
+ }
+#endif /* CADAM */
+
+ /* Interior curves of constant U. */
+ dt = (range->umax - range->umin) / (state->isocount[0] + 1);
+ for ( j = 0, t += dt; j < state->isocount[0]; j++, t += dt ) {
+ (void)isocurve( state, surface, 1, t, range->vmin, range->vmax,
+ state->isocrvs );
+ }
+
+ /* Last curve of constant U. */
+ t = range->umax;
+#ifdef CADAM
+ if ( surface->numTrimCurveLists <= 0 ) { /* no trimming */
+#endif /* CADAM */
+ (void)isocurve( state, surface, 1, t, range->vmin, range->vmax,
+ state->isocrvs );
+#ifdef CADAM
+ }
+#endif /* CADAM */
+
+
+ /* First curve of constant V. */
+ t = range->vmin;
+#ifdef CADAM
+ if ( surface->numTrimCurveLists <= 0 ) { /* no trimming */
+#endif /* CADAM */
+ (void)isocurve( state, surface, 2, t, range->umin, range->umax,
+ state->isocrvs );
+#ifdef CADAM
+ }
+#endif /* CADAM */
+
+ /* Interior curves of constant V. */
+ dt = (range->vmax - range->vmin) / (state->isocount[1] + 1);
+ for ( j = 0, t += dt; j < state->isocount[1]; j++, t += dt ) {
+ (void)isocurve( state, surface, 2, t, range->umin, range->umax,
+ state->isocrvs );
+ }
+
+ /* Last curve of constant V. */
+ t = range->vmax;
+#ifdef CADAM
+ if ( surface->numTrimCurveLists <= 0 ) { /* no trimming */
+#endif /* CADAM */
+ (void)isocurve( state, surface, 2, t, range->umin, range->umax,
+ state->isocrvs );
+#ifdef CADAM
+ }
+#endif /* CADAM */
+
+ return Success;
+}
+
+
+/*++
+ |
+ | Function Name: nonuniform_isocurves
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+static int
+nonuniform_isocurves( state, surface )
+ Nurb_surf_state *state;
+ miNurbSurfaceStruct *surface;
+{
+ ddFLOAT *uknots = surface->pUknots;
+ ddFLOAT *vknots = surface->pVknots;
+ double t, dt;
+
+ int i, j;
+ Nurb_param_limit *range = &state->range;
+
+ /* Initialize output structure */
+ state->isocrvs = (miListHeader *)xalloc(sizeof(miListHeader));
+ state->isocrvs->type = surface->points.type;
+ state->isocrvs->numLists = state->isocrvs->maxLists = 0;
+ state->isocrvs->ddList = 0;
+
+ /*
+ * Place curves uniformly between each non-vacuous span.
+ * For each non-vacuous U span draw the iso U curves for all
+ * surface V.
+ */
+ for ( i = surface->uOrder - 1; i < surface->mPts; i++ ) {
+ if ( uknots[i] != uknots[i+1] ) {
+ /* First curve of span. */
+ t = uknots[i];
+#ifdef CADAM
+ if ( surface->numTrimCurveLists <= 0 ) { /* no trimming
+*/
+#endif /* CADAM */
+ if ( t >= range->umin && t <= range->umax )
+ (void)isocurve( state, surface, 1, t,
+ range->vmin, range->vmax,
+ state->isocrvs );
+#ifdef CADAM
+ } else {
+ if ( t > range->umin && t < range->umax )
+ (void)isocurve( state, surface, 1, t,
+ range->vmin, range->vmax,
+ state->isocrvs );
+ }
+#endif /* CADAM */
+
+ /* Interior curves of span. */
+ dt = (uknots[i+1] - uknots[i]) / (state->isocount[0] +
+1);
+ for ( j = 0, t += dt; j < state->isocount[0]; j++, t +=
+dt ) {
+ if ( t >= range->umin && t <= range->umax )
+ (void)isocurve( state, surface, 1, t,
+ range->vmin, range->vmax,
+ state->isocrvs );
+ }
+
+ /* Last curve of span. */
+ t = uknots[i+1];
+#ifdef CADAM
+ if ( surface->numTrimCurveLists <= 0 ) { /* no trimming
+*/
+#endif /* CADAM */
+ if ( t >= range->umin && t <= range->umax )
+ (void)isocurve( state, surface, 1, t,
+ range->vmin, range->vmax,
+ state->isocrvs );
+#ifdef CADAM
+ } else {
+ if ( t > range->umin && t < range->umax )
+ (void)isocurve( state, surface, 1, t,
+ range->vmin, range->vmax,
+ state->isocrvs );
+ }
+#endif /* CADAM */
+ }
+ }
+
+ /* For each non-vacuous V span draw the iso V curves for all
+surface U. */
+ for ( i = surface->vOrder - 1; i < surface->nPts; i++ ) {
+ if ( vknots[i] != vknots[i+1] ) {
+ /* First curve of span. */
+ t = vknots[i];
+#ifdef CADAM
+ if ( surface->numTrimCurveLists <= 0 ) { /* no trimming
+*/
+#endif /* CADAM */
+ if ( t >= range->vmin && t <= range->vmax )
+ (void)isocurve( state, surface, 2, t,
+ range->umin, range->umax,
+ state->isocrvs );
+#ifdef CADAM
+ } else {
+ if ( t > range->vmin && t < range->vmax )
+ (void)isocurve( state, surface, 2, t,
+ range->umin, range->umax,
+ state->isocrvs );
+ }
+#endif /* CADAM */
+
+ /* Inteior curves of span. */
+ dt = (vknots[i+1] - vknots[i]) / (state->isocount[1] +
+1);
+ for ( j = 0, t += dt; j < state->isocount[1]; j++, t +=
+dt ) {
+ if ( t >= range->vmin && t <= range->vmax )
+ (void)isocurve( state, surface, 2, t,
+ range->umin, range->umax,
+ state->isocrvs );
+ }
+
+ /* Last curve of span. */
+ t = vknots[i+1];
+#ifdef CADAM
+ if ( surface->numTrimCurveLists <= 0 ) { /* no trimming
+*/
+#endif /* CADAM */
+ if ( t >= range->vmin && t <= range->vmax )
+ (void)isocurve( state, surface, 2, t,
+ range->umin, range->umax,
+ state->isocrvs );
+#ifdef CADAM
+ } else {
+ if ( t > range->vmin && t < range->vmax )
+ (void)isocurve( state, surface, 2, t,
+ range->umin, range->umax,
+ state->isocrvs );
+ }
+#endif /* CADAM */
+ }
+ }
+
+ return Success;
+}
+
+
+
+/*++
+ |
+ | Function Name: compute_average_edge_point_normals
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+static void
+compute_average_edge_point_normals( surface, grid )
+ miNurbSurfaceStruct *surface;
+ Nurb_grid *grid;
+{
+ int i, j;
+ int ucount = grid->nu,
+ vcount = grid->nv;
+ Nurb_edge_point *ll, *lr, *ur, *ul;
+ char rat;
+
+ rat = DD_IsVert4D(surface->points.type);
+
+ /* Step along the surface and calculate averaged normals. */
+ ll = &grid->pts[0]; lr = ll + 1;
+ ul = &grid->pts[ucount]; ur = ul + 1;
+ for ( j = 0; j < vcount-1; j++, ll++, lr++, ul++, ur++ ) {
+ for ( i = 0; i < ucount-1; i++, ll++, lr++, ul++, ur++ ) {
+ /* Calculate and average vertex normals. */
+ if ( rat ) {
+ ddCoord3D pll, plr, pur, pul;
+ register ddCoord4D *pt;
+ register double h;
+
+ pt = &ll->pt; h = 1.0 / pt->w;
+ pll.x = h * pt->x; pll.y = h * pt->y; pll.z = h * pt->z;
+ pt = &lr->pt; h = 1.0 / pt->w;
+ plr.x = h * pt->x; plr.y = h * pt->y; plr.z = h * pt->z;
+ pt = &ur->pt; h = 1.0 / pt->w;
+ pur.x = h * pt->x; pur.y = h * pt->y; pur.z = h * pt->z;
+ pt = &ul->pt; h = 1.0 / pt->w;
+ pul.x = h * pt->x; pul.y = h * pt->y; pul.z = h * pt->z;
+ avg_vertex_normal( ll->count, &pll, &plr, &pul, &ll->normal );
+ avg_vertex_normal( lr->count, &plr, &pur, &pll, &lr->normal );
+ avg_vertex_normal( ur->count, &pur, &pul, &plr, &ur->normal );
+ avg_vertex_normal( ul->count, &pul, &pll, &pur, &ul->normal );
+ } else {
+ avg_vertex_normal( ll->count, (ddCoord3D*)&ll->pt,
+ (ddCoord3D*)&lr->pt, (ddCoord3D*)&ul->pt, &ll->normal );
+ avg_vertex_normal( lr->count, (ddCoord3D*)&lr->pt,
+ (ddCoord3D*)&ur->pt, (ddCoord3D*)&ll->pt, &lr->normal );
+ avg_vertex_normal( ur->count, (ddCoord3D*)&ur->pt,
+ (ddCoord3D*)&ul->pt, (ddCoord3D*)&lr->pt, &ur->normal );
+ avg_vertex_normal( ul->count, (ddCoord3D*)&ul->pt,
+ (ddCoord3D*)&ll->pt, (ddCoord3D*)&ur->pt, &ul->normal );
+ }
+ ++ll->count; ++lr->count; ++ur->count; ++ul->count;
+ }
+ }
+}
+
+
+/*++
+ |
+ | Function Name: compute_edge_point_normals
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+static void
+compute_edge_point_normals( surface, grid )
+ miNurbSurfaceStruct *surface;
+ Nurb_grid *grid;
+{
+ register int i, j;
+ register int ucount = grid->nu, vcount = grid->nv;
+ register Nurb_edge_point *ll, *lr, *ur, *ul;
+ char rat;
+
+ rat = DD_IsVert4D(surface->points.type);
+
+ /* Step along the surface and calculate normals. */
+ ll = &grid->pts[0]; lr = ll + 1;
+ ul = &grid->pts[ucount]; ur = ul + 1;
+ for ( j = 0; j < vcount-1; j++, ll++, lr++, ul++, ur++ ) {
+ for ( i = 0; i < ucount-1; i++, ll++, lr++, ul++, ur++ ) {
+ /* Calculate vertex normals. */
+ if ( rat ) {
+ ddCoord3D pll, plr, pur, pul;
+ register ddCoord4D *pt;
+ register double h;
+
+ pt = &ll->pt; h = 1.0 / pt->w;
+ pll.x = h * pt->x; pll.y = h * pt->y; pll.z = h * pt->z;
+ pt = &lr->pt; h = 1.0 / pt->w;
+ plr.x = h * pt->x; plr.y = h * pt->y; plr.z = h * pt->z;
+ pt = &ul->pt; h = 1.0 / pt->w;
+ pul.x = h * pt->x; pul.y = h * pt->y; pul.z = h * pt->z;
+ avg_vertex_normal( 0, &pll, &plr, &pul, &ll->normal );
+
+ /* Calculate normals at edge of grid. */
+ if ( i == ucount-2 || j == vcount-2 ) {
+ pt = &ur->pt; h = 1.0 / pt->w;
+ pur.x = h * pt->x; pur.y = h * pt->y; pur.z = h * pt->z;
+ }
+ if ( i == ucount-2 )
+ avg_vertex_normal( 0, &plr, &pur, &pll, &lr->normal );
+ if ( j == vcount-2 )
+ avg_vertex_normal( 0, &pul, &pll, &pur, &ul->normal );
+ if ( i == ucount-2 && j == vcount-2 )
+ avg_vertex_normal( 0, &pur, &pul, &plr, &ur->normal );
+ } else {
+ avg_vertex_normal( 0, (ddCoord3D*)&ll->pt,
+ (ddCoord3D*)&lr->pt, (ddCoord3D*)&ul->pt, &ll->normal );
+
+ /* Calculate normals at edge of grid. */
+ if ( i == ucount-2 )
+ avg_vertex_normal( 0, (ddCoord3D*)&lr->pt,
+ (ddCoord3D*)&ur->pt, (ddCoord3D*)&ll->pt, &lr->normal );
+ if ( j == vcount-2 )
+ avg_vertex_normal( 0, (ddCoord3D*)&ul->pt,
+ (ddCoord3D*)&ll->pt, (ddCoord3D*)&ur->pt, &ul->normal );
+ if ( i == ucount-2 && j == vcount-2 )
+ avg_vertex_normal( 0, (ddCoord3D*)&ur->pt,
+ (ddCoord3D*)&ul->pt, (ddCoord3D*)&lr->pt, &ur->normal );
+ }
+ }
+ }
+}
+
+
+
+/*++
+ |
+ | Function Name: make_edge_segments
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+static void
+make_edge_segments( state )
+ Nurb_surf_state *state;
+{
+ int i;
+ Nurb_param_point *corners = state->corners;
+ Nurb_trim_segment *segs = state->edge_segs;
+ Nurb_trim_segment *seg;
+
+ /* Generate the edges by building a fake trimming segment for each edge
+ * and calling the trim edge generator.
+ */
+ corners[0].u = state->range.umin; corners[0].v = state->range.vmin;
+ corners[1].u = state->range.umax; corners[1].v = state->range.vmin;
+ corners[2].u = state->range.umax; corners[2].v = state->range.vmax;
+ corners[3].u = state->range.umin; corners[3].v = state->range.vmax;
+ corners[4].u = state->range.umin; corners[4].v = state->range.vmin;
+ segs[0].first = segs[0].start = 0; segs[0].last = segs[0].end = 1;
+ segs[1].first = segs[1].start = 1; segs[1].last = segs[1].end = 2;
+ segs[2].first = segs[2].start = 2; segs[2].last = segs[2].end = 3;
+ segs[3].first = segs[3].start = 3; segs[3].last = segs[3].end = 4;
+ segs[0].next = &segs[1];
+ segs[1].next = &segs[2];
+ segs[2].next = &segs[3];
+ segs[3].next = (Nurb_trim_segment *)NULL;
+
+ for ( i = 0, seg = segs; i < 4; i++, seg++ ) {
+ seg->vis = ~0;
+ if ( corners[seg->first].u <= corners[seg->last].u ) {
+ seg->extent.umin = corners[seg->first].u;
+ seg->extent.umax = corners[seg->last].u;
+ } else {
+ seg->extent.umin = corners[seg->last].u;
+ seg->extent.umax = corners[seg->first].u;
+ }
+ if ( corners[seg->first].v <= corners[seg->last].v ) {
+ seg->extent.vmin = corners[seg->first].v;
+ seg->extent.vmax = corners[seg->last].v;
+ } else {
+ seg->extent.vmin = corners[seg->last].v;
+ seg->extent.vmax = corners[seg->first].v;
+ }
+ }
+}
+
+
+
+/*++
+ |
+ | Function Name: build_surf_markers
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+static ddpex3rtn
+build_surf_markers( surface, state )
+ miNurbSurfaceStruct *surface;
+ Nurb_surf_state *state;
+{
+
+ if (!state->markers)
+ state->markers = (miListHeader *)xalloc(sizeof(miListHeader));
+
+ *state->markers = surface->points;
+
+ return Success;
+}
+
+
+
+/*++
+ |
+ | Function Name: build_control_polygon
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+static ddpex3rtn
+build_control_polygon( surface, state )
+ miNurbSurfaceStruct *surface;
+ Nurb_surf_state *state;
+{
+ int i, j;
+ listofddPoint *pddolist;
+ ddCoord3D *cpts3, *out_pt3;
+ ddCoord4D *cpts4, *out_pt4;
+ char rat;
+
+ rat = DD_IsVert4D(surface->points.type);
+
+ if (!state->isocrvs)
+ if (!(state->isocrvs = (miListHeader *)xalloc(sizeof(miListHeader))))
+ return(BadAlloc);
+
+ MI_ALLOCLISTHEADER(state->isocrvs, surface->mPts * surface->nPts);
+ if (!(pddolist = state->isocrvs->ddList)) return(BadAlloc);
+
+ state->isocrvs->type = surface->points.type;
+ state->isocrvs->flags = surface->points.flags;
+ state->isocrvs->numLists = surface->mPts * surface->nPts;
+
+ /* Connect the points in the U dimension. */
+ if ( rat ) {
+
+ for ( j = 0; j < surface->mPts; j++ ) {
+ cpts4 = &surface->points.ddList->pts.p4Dpt[j * surface->mPts];
+ MI_ALLOCLISTOFDDPOINT(pddolist, surface->mPts, sizeof(ddCoord4D));
+ if (!(out_pt4 = pddolist->pts.p4Dpt)) return(BadAlloc);
+ for ( i = 1; i < surface->mPts; i++ ) {
+ *(out_pt4++) = *(cpts4++);
+ }
+ (pddolist++)->numPoints = surface->mPts;
+ }
+
+ } else {
+
+ for ( j = 0; j < surface->mPts; j++ ) {
+ cpts3 = &surface->points.ddList->pts.p3Dpt[j * surface->mPts];
+ MI_ALLOCLISTOFDDPOINT(pddolist, surface->mPts, sizeof(ddCoord3D));
+ if (!(out_pt3 = pddolist->pts.p3Dpt)) return(BadAlloc);
+ for ( i = 1; i < surface->mPts; i++ ) {
+ *(out_pt3++) = *(cpts3++);
+ }
+ (pddolist++)->numPoints = surface->mPts;
+ }
+
+ }
+
+ /* Connect the points in the V dimension. */
+ if ( rat ) {
+
+ for ( j = 0; j < surface->nPts; j++ ) {
+ cpts4 = &surface->points.ddList->pts.p4Dpt[j];
+ MI_ALLOCLISTOFDDPOINT(pddolist, surface->nPts, sizeof(ddCoord4D));
+ if (!(out_pt4 = pddolist->pts.p4Dpt)) return(BadAlloc);
+ for ( i = 1; i < surface->nPts; i++ ) {
+ *(out_pt4++) = *cpts4;
+ cpts4 += surface->mPts;
+ }
+ (pddolist++)->numPoints = surface->nPts;
+ }
+
+ } else {
+
+ for ( j = 0; j < surface->nPts; j++ ) {
+ cpts3 = &surface->points.ddList->pts.p3Dpt[j];
+ MI_ALLOCLISTOFDDPOINT(pddolist, surface->nPts, sizeof(ddCoord3D));
+ if (!(out_pt3 = pddolist->pts.p3Dpt)) return(BadAlloc);
+ for ( i = 1; i < surface->nPts; i++ ) {
+ *(out_pt3++) = *cpts3;
+ cpts3 += surface->mPts;
+ }
+ (pddolist++)->numPoints = surface->nPts;
+ }
+
+ }
+
+ return Success;
+}
+
+
+
+/*++
+ |
+ | Function Name: free_grids
+ |
+ | Function Description:
+ |
+ | free the allocated data associated with a list of grids.
+ |
+ | Note(s):
+ |
+ --*/
+
+static void
+free_grids( grids )
+ Nurb_gridlst *grids;
+{
+ int i;
+
+ if ( grids && grids->number > 0 ) {
+ for ( i = 0; i < grids->number; i++ ) {
+ if ( grids->grids[i].pts )
+ xfree( grids->grids[i].pts );
+ }
+ xfree( grids->grids );
+ }
+}
+
+
+
+/*++
+ |
+ | Function Name: nurb_surf_state_free
+ |
+ | Function Description:
+ |
+ | free all of the allocated data associated with a surface
+ | Nurb_surf_state data structure.
+ |
+ | Note(s):
+ |
+ --*/
+
+static void
+nurb_surf_state_free( state )
+ Nurb_surf_state *state;
+{
+ int facet;
+
+ /* Free everything but the cache data. */
+ if ( state->ruknots )
+ xfree( state->ruknots );
+ if ( state->rvknots )
+ xfree( state->rvknots );
+
+#ifdef TRIMING
+ phg_nt_free_trim_data( &state->trim_data );
+#endif /* TRIMING */
+
+ if ( state->reps.facets ) {
+ if ( state->facets ) {
+ MI_FREELISTHEADER(state->facets);
+ for (facet = 0; facet < state->grids.number; facet++)
+ MI_FREELISTHEADER(state->facets + facet);
+ xfree(state->facets);
+ }
+ else if ( state->sofas ) {
+ MI_FREELISTHEADER(&(state->sofas->points));
+ xfree(state->sofas);
+ }
+ }
+ if ( state->reps.edges && state->edges ) {
+ MI_FREELISTHEADER(state->edges);
+ xfree(state->edges);
+ }
+ if ( state->reps.isocrvs && state->isocrvs ) {
+ MI_FREELISTHEADER(state->isocrvs);
+ xfree(state->isocrvs);
+ }
+ if ( state->reps.markers && state->markers) {
+ /* Note that markers are a copy of the input data - DON`T FREE IT */
+ xfree(state->markers);
+ }
+ if ( state->reps.hollow && state->hollow ) {
+ MI_FREELISTHEADER(state->hollow);
+ xfree(state->hollow);
+ }
+
+ if ( state->grids.number > 0 ) {
+ free_grids( &state->grids );
+ state->grids.number = 0;
+ state->grids.grids = (Nurb_grid *)NULL;
+ }
+}
+
+
+
+#ifdef TRIMING
+
+/*++
+ |
+ | Function Name: add_pgon_point
+ |
+ | Function Description:
+ |
+ | Enter the specified edge point into a miSOFASStruct
+ | according to the specified operation.
+ |
+ | Note(s):
+ |
+ --*/
+
+static ddpex3rtn
+add_pgon_point( state, surface, ddSOFAS, op, ep )
+ Nurb_surf_state *state;
+ miNurbSurfaceStruct *surface;
+ miSOFASStruct *ddSOFAS;
+ Nurb_facet_op op;
+ Nurb_edge_point *ep;
+{
+ miConnListList *ConnListList;
+ miConnList *ConnList;
+ int num_points, data_count, i;
+
+ /* a new point for the vertex list */
+ if (ddSOFAS->points.ddList)
+ num_points = ddSOFAS->points.ddList->numPoints;
+ else num_points = 0;
+
+ switch (op) {
+
+ /*
+ * A new facet is to be started in the SOFAS output structure.
+ * The first task to complete is to insure that there is sufficient
+ * space for the new list od list of indices in the connection lists.
+ */
+ case NURB_NEW_FACET:
+ ddSOFAS->connects.numListLists++;
+ data_count = MI_ROUND_LISTHEADERCOUNT(ddSOFAS->connects.numListLists)
+ * sizeof(miConnListList);
+
+ if (data_count > ddSOFAS->connects.maxData) {
+ if (ddSOFAS->connects.data) {
+ ddSOFAS->connects.data =
+ (miConnListList *)xrealloc(ddSOFAS->connects.data, data_count);
+ ddSOFAS->connects.maxData = data_count;
+ } else {
+ ddSOFAS->connects.data = (miConnListList *)xalloc(data_count);
+ ddSOFAS->connects.maxData = data_count;
+ }
+
+ if (!(ddSOFAS->connects.data)) return(BadAlloc);
+
+ /* Initialize newly created entries */
+ ConnListList = &ddSOFAS->connects.data[ddSOFAS->numFAS];
+ for (i = MI_ROUND_LISTHEADERCOUNT(ddSOFAS->connects.numListLists) -
+ ddSOFAS->numFAS;
+ i > 0;
+ i--) {
+ ConnListList->numLists = ConnListList->maxData = 0;
+ (ConnListList++)->pConnLists = 0;
+
+ }
+ }
+
+ ddSOFAS->numFAS++;
+
+
+ /*
+ * a new contour is to be started in the SOFAS output structure.
+ * The first task is to insure that there is sufficient output
+ * space for the contour is the list of contour index lists
+ */
+ case NURB_NEW_CONTOUR:
+ ConnListList = &ddSOFAS->connects.data[ddSOFAS->numFAS - 1];
+
+ data_count = MI_ROUND_LISTHEADERCOUNT( ConnListList->numLists+1 )
+ * sizeof(miConnList);
+
+ if (data_count > ConnListList->maxData) {
+
+ if (ConnListList->pConnLists) {
+ ConnListList->pConnLists =
+ (miConnList *)xrealloc(ConnListList->pConnLists,
+ data_count );
+ ConnListList->maxData = data_count;
+ } else {
+ ConnListList->pConnLists = (miConnList *)xalloc(data_count);
+ ConnListList->maxData = data_count;
+ }
+
+ if (!(ConnListList->pConnLists)) return (BadAlloc);
+
+ /* Initialize newly created entries */
+ ConnList = &ConnListList->pConnLists[ConnListList->numLists];
+ for (i = MI_ROUND_LISTHEADERCOUNT( ConnListList->numLists+1 ) -
+ ConnListList->numLists;
+ i > 0;
+ i--) {
+ ConnList->numLists = ConnList->maxData = 0;
+ (ConnList++)->pConnects = 0;
+
+ }
+ }
+
+ ConnListList->numLists++;
+
+ /*
+ * Finally, insure sufficent space for the index!
+ */
+ case NURB_SAME_CONTOUR:
+ ConnListList = &ddSOFAS->connects.data[ddSOFAS->numFAS - 1];
+ ConnList = &ConnListList->pConnLists[ConnListList->numLists - 1];
+
+ data_count = MI_ROUND_LISTHEADERCOUNT( ConnList->numLists+1 )
+ * sizeof(ddUSHORT);
+
+ if (data_count > ConnList->maxData) {
+ if (ConnList->pConnects) {
+ ConnList->pConnects = (ddUSHORT *)xrealloc( ConnList->pConnects,
+ data_count);
+ ConnList->maxData = data_count;
+ } else {
+ ConnList->pConnects = (ddUSHORT *)xalloc(data_count);
+ ConnList->maxData = data_count;
+ }
+
+ if (!(ConnList->pConnects)) return (BadAlloc);
+ }
+
+ /* Lastly, enter the index into the appropriate list */
+ ConnList->pConnects[ConnList->numLists] = num_points;
+ ConnList->numLists++;
+
+
+ }
+
+
+ /* Insure there is a list for the vertex data */
+ if (!(ddSOFAS->points.ddList)) {
+
+ MI_ALLOCLISTHEADER(&ddSOFAS->points, 1)
+ if (!(ddSOFAS->points.ddList)) return(BadAlloc);
+
+ if (state->reps.normals) ddSOFAS->points.type = DD_NORM_POINT4D;
+ else ddSOFAS->points.type = DD_HOMOGENOUS_POINT;
+
+ ddSOFAS->points.flags = 0;
+ ddSOFAS->points.numLists = 1;
+
+ }
+
+ /* Now, enter the point information into the point array */
+ if (state->reps.normals) {
+
+ MI_ALLOCLISTOFDDPOINT(ddSOFAS->points.ddList,
+ MI_ROUND_LISTHEADERCOUNT(num_points + 1),
+ sizeof(ddNormalPoint4D));
+ if (!(ddSOFAS->points.ddList->pts.ptr))
+ return(BadAlloc);
+
+ ddSOFAS->points.ddList->pts.pNpt4D[num_points].pt = ep->pt;
+ ddSOFAS->points.ddList->pts.pNpt4D[num_points].normal = ep->normal;
+
+ } else {
+
+ MI_ALLOCLISTOFDDPOINT(ddSOFAS->points.ddList,
+ MI_ROUND_LISTHEADERCOUNT(num_points + 1),
+ sizeof(ddCoord4D));
+ if (!(ddSOFAS->points.ddList->pts.ptr))
+ return(BadAlloc);
+
+ ddSOFAS->points.ddList->pts.p4Dpt[num_points] = ep->pt;
+ }
+
+ ddSOFAS->points.ddList->numPoints = num_points + 1;
+
+}
+
+#endif /* TRIMING */
+
+#define WS_NSRF_BOTTOM
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level2/miNurbs.c b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miNurbs.c
new file mode 100644
index 000000000..f5a2530ef
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miNurbs.c
@@ -0,0 +1,378 @@
+/* $TOG: miNurbs.c /main/6 1998/02/10 12:42:00 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level2/miNurbs.c,v 3.6 1999/01/31 12:21:28 dawes Exp $ */
+
+#include "X.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "PEXErr.h"
+#include "PEXproto.h"
+#include "PEXprotost.h"
+#include "ddpex.h"
+#include "ddpex3.h"
+#include "miRender.h"
+#include "ddpex2.h"
+#include "miNurbs.h"
+#include "pexos.h"
+
+
+/*
+ * mtx to convert polynomial coeffs ai, to fwd basis coeffs Aj is
+ * D j+1 k i
+ * Aj = Sum [Sum (-1) * (j!/k!(j-k)!)*(j-k) ] * ai where D=degree
+ * i=0 k=0
+ */
+
+#if MAXORD == 4
+/* Debugging is often easier if MAXORD is made small. */
+
+double mi_nu_ptofd[MAXORD][MAXORD] = {
+{ 1.0, 0.0, 0.0, 0.0},
+{ 0.0, 1.0, 1.0, 1.0},
+{ 0.0, 0.0, 2.0, 6.0},
+{ 0.0, 0.0, 0.0, 6.0}
+};
+
+#else
+
+double mi_nu_ptofd[MAXORD][MAXORD] = {
+{ 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+{ 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0},
+{ 0.0, 0.0, 2.0, 6.0, 14.0, 30.0, 62.0, 126.0, 254.0, 510.0},
+{ 0.0, 0.0, 0.0, 6.0, 36.0, 150.0, 540.0, 1806.0, 5796.0, 18150.0},
+{ 0.0, 0.0, 0.0, 0.0, 24.0, 240.0, 1560.0, 8400.0, 40824.0, 186480.0},
+{ 0.0, 0.0, 0.0, 0.0, 0.0, 120.0, 1800.0, 16800.0, 126000.0, 834120.0},
+{ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 720.0, 15120.0, 191520.0, 1905120.0},
+{ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 5040.0, 141120.0, 2328480.0},
+{ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 40320.0, 1451520.0},
+{ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 362880.0}
+};
+
+#endif
+
+#undef HUGE
+#define HUGE 10E30
+
+
+
+/*++
+ |
+ | Function Name: mi_nu_preprocess_knots
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+void
+mi_nu_preprocess_knots( order, nk, knots, rp )
+ ddUSHORT order;
+ int nk;
+ ddFLOAT *knots;
+ ddFLOAT rp[][MAXORD]; /* reciprocal of knots diff */
+{
+ double x;
+
+ register int i, j;
+
+ for ( i = 0; i < nk; i++ )
+ rp[i][0] = 1.0 ;
+ for ( j = 1; j < order; j++ ) {
+ for ( i = 0; i <= nk - j; i++ ) {
+ if ( (x = knots[i+j] - knots[i]) == 0.0 ) {
+ rp[i][j] = HUGE;
+ } else {
+ rp[i][j] = 1.0 / x;
+ }
+ }
+ }
+}
+
+
+
+/*++
+ |
+ | Function Name: mi_nu_compute_nurb_basis_function
+ |
+ | Function Description:
+ |
+ | Recursive definition of polynomial coefficients for span (0<= s <=1).
+ | C(i,j,k) = a*C(i,j-1,k-1) + b*C(i,j,k-1) + c*C(i+1,j-1,k-1) + d*C(i+1,j,k-1)
+ | a = (s(l+1) - s(l))/(s(i+k-1) - s(i)), b = (s(l) - s(i))/(s(i+k-1) - s(i))
+ | c = -(s(l+1) - s(l))/(s(i+k) - s(i+1)), d = (s(i+k) - s(l))/(s(i+k) - s(i+1))
+ |
+ | Note(s):
+ |
+ --*/
+
+void
+mi_nu_compute_nurb_basis_function( order, span, knots, kr, C )
+ ddUSHORT order;
+ int span;
+ ddFLOAT *knots;
+ ddFLOAT kr[][MAXORD]; /* reciprocal of knots diff */
+ double C[MAXORD][MAXORD];
+{
+ int i, j, k, m, im, degree = order - 1;
+ double t0, t1, t2, t3;
+
+ if ( order == 2 ) {
+ C[0][0] = 1.0;
+ C[0][1] = 0.0;
+ C[1][0] = -1.0;
+ C[1][1] = 1.0;
+ return;
+ }
+
+ /* Compute the coefficients of Nik in polynomial basis, for the span
+ * knots[i] to knots[i+1] where s goes from 0 to 1.0
+ */
+ t1 = knots[span+1] - knots[span];
+ C[0][degree] = 1.0; /* Ni1 = 1.0 within span */
+ for ( k = 1; k < order; k++ ) { /* recurse on order for Cj,i,k */
+ t0 = t1 * kr[span-k+1][k];
+ im = degree - k;
+ C[0][im] = t0 * C[0][im+1]; /* top left coeff */
+ for ( j = k-1; j > 0; j-- )
+ C[j][im] = t0 * ( C[j][im+1] - C[j-1][im+1] ); /*middle*/
+ C[k][im] = -t0 * C[k-1][im+1]; /* top right coeff */
+ for (m=k-1; m>0; m--) { /* central section */
+ i = span - m; /* right edge first */
+ im = degree - m;
+ C[k][im] = t1 * (kr[i][k] * C[k-1][im] - kr[i+1][k] * C[k-1][im+1]);
+ t2 = knots[i+k+1] - knots[span];
+ t3 = knots[span] - knots[i];
+ for ( j = k-1; j > 0; j-- ) /* then j down to 1 */
+ C[j][im] =
+ kr[i][k] * (t1 * C[j-1][im]
+ + t3 * C[j][im])
+ + kr[i+1][k] * (t2 * C[j][im+1] - t1 * C[j-1][im+1]);
+ C[0][im] = kr[i][k] * t3 * C[0][im]
+ + kr[i+1][k] * t2 * C[0][im+1]; /* left edge */
+ }
+ t0 = t1 * kr[span][k]; /* bottom rt,middle coeffs */
+ for ( j = k; j > 0; j-- )
+ C[j][degree] = t0 * C[j-1][degree];
+ C[0][degree] = 0.0; /* bottom left coeff */
+ }
+}
+
+
+
+/*++
+ |
+ | Function Name: mi_nu_insert_knots
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+int
+mi_nu_insert_knots( order, pt_type,
+ numinknots, oknots, opoints,
+ numoutknots, nknots, npoints )
+ ddUSHORT order;
+ ddPointType pt_type;
+ ddUSHORT numinknots;
+ ddFLOAT *oknots; /* original knots */
+ ddFLOAT *opoints; /* original control points */
+ int *numoutknots;
+ ddFLOAT *nknots; /* new knots */
+ ddFLOAT *npoints; /* new control points */
+{
+ /*
+ * Assumptions: - inserted knots are within range of original knots.
+ */
+ int i, k, iok, ink, mult, num_pts;
+ int numtmpknots;
+ ddFLOAT *tmpknots;
+ ddFLOAT alpha, alph1;
+ ddCoord2D *npts2;
+ ddCoord3D *npts3;
+ ddCoord4D *npts4;
+
+ /* Check to see if new knots needed. Copy and return if not. */
+ if ( *numoutknots <= 0 ) {
+ *numoutknots = numinknots;
+ memcpy( (char *)nknots, (char *)oknots, (int)numinknots * sizeof(ddFLOAT) );
+ return 1;
+ }
+
+ /* Copy old control points into new space. */
+ num_pts = numinknots - order;
+ if ( DD_IsVert2D(pt_type) ) {
+ memcpy( (char *)npoints, (char *)opoints, num_pts * sizeof(ddCoord2D));
+ npts2 = (ddCoord2D *)npoints;
+ } else if ( DD_IsVert3D(pt_type) ) {
+ memcpy( (char *)npoints, (char *)opoints, num_pts * sizeof(ddCoord3D));
+ npts3 = (ddCoord3D *)npoints;
+ } else if ( DD_IsVert4D(pt_type) ) {
+ memcpy( (char *)npoints, (char *)opoints, num_pts * sizeof(ddCoord4D));
+ npts4 = (ddCoord4D *)npoints;
+ } else return (1);
+
+ if ( !(tmpknots = (ddFLOAT *)
+ xalloc( (numinknots + *numoutknots) * sizeof(float))) )
+ return 0;
+
+ /* Insert new knots and control points, starting from the end of the
+ * original lists.
+ */
+ memcpy( (char *)tmpknots, (char *)oknots, (int)numinknots * sizeof(ddFLOAT) );
+ numtmpknots = numinknots;
+ ink = *numoutknots;
+ iok = numinknots - 1;
+
+ while ( ink > 0 ) {
+
+ mult = 1;
+ --ink;
+ /* Count mutiplicity of the new knot to be inserted. */
+ while ( ink > 0 && nknots[ink] == nknots[ink-1] ) {
+ ++mult;
+ --ink;
+ }
+
+ /* Find position of knot(s) to insert. */
+ while ( iok >= 0 && tmpknots[iok] >= nknots[ink] )
+ --iok;
+
+ /* Move control points down to make space for inserted ones.
+ * Use memove so that the overlap is handled.
+ */
+ /* note that the funky &blah[...] notation is equivalent
+ to blah+... since blah is a pointer. JSH 4-10-91
+ */
+ if ( DD_IsVert2D(pt_type) )
+ memmove((char *)(&npts2[iok + 1 + mult]),(char *)(&npts2[iok + 1]),
+ ((num_pts - iok) - 1) * sizeof(ddCoord2D) );
+ else if ( DD_IsVert3D(pt_type) )
+ memmove((char *)(&npts3[iok + 1 + mult]),(char *)(&npts3[iok + 1]),
+ ((num_pts - iok) - 1) * sizeof(ddCoord3D) );
+ else
+ memmove((char *)(&npts4[iok + 1 + mult]),(char *)(&npts4[iok + 1]),
+ ((num_pts - iok) - 1) * sizeof(ddCoord4D) );
+
+ /* Do de Boor to insert new knot with multiplicity `mult'. */
+ if ( DD_IsVert2D(pt_type) ) {
+ for ( k = 1; k <= mult; k++ ) {
+ /* Move pts down recursively. */
+ for ( i = iok + k; i > iok; i-- ) {
+ npts2[i].x = npts2[i-1].x;
+ npts2[i].y = npts2[i-1].y;
+/********************************************************
+ if ( rat == PRATIONAL )
+ npts2[i].z = npts2[i-1].z;
+********************************************************/
+ }
+ for ( i = iok; i > iok - order + k; i-- ) {
+ alpha = (nknots[ink] - tmpknots[i])
+ / (tmpknots[i + order - k] - tmpknots[i]);
+ alph1 = 1.0 - alpha;
+ npts2[i].x = alpha * npts2[i].x + alph1 * npts2[i-1].x;
+ npts2[i].y = alpha * npts2[i].y + alph1 * npts2[i-1].y;
+/********************************************************
+ if ( rat == PRATIONAL )
+ npts2[i].z = alpha * npts2[i].z + alph1 * npts2[i-1].z;
+********************************************************/
+ }
+ }
+
+ } else if ( DD_IsVert3D(pt_type) ) { /* dim is 3 */
+ for ( k = 1; k <= mult; k++ ) {
+ for ( i = iok + k; i > iok; i-- ) {
+ npts3[i].x = npts3[i-1].x;
+ npts3[i].y = npts3[i-1].y;
+ npts3[i].z = npts3[i-1].z;
+ }
+ for ( i = iok; i > iok - order + k; i-- ) {
+ alpha = (nknots[ink] - tmpknots[i])
+ / (tmpknots[i + order - k] - tmpknots[i]);
+ alph1 = 1.0 - alpha;
+ npts3[i].x = alpha * npts3[i].x + alph1 * npts3[i-1].x;
+ npts3[i].y = alpha * npts3[i].y + alph1 * npts3[i-1].y;
+ npts3[i].z = alpha * npts3[i].z + alph1 * npts3[i-1].z;
+ }
+ }
+ } else /* if ( DD_IsVert4D(pt_type) ) */ { /* dim is 4 */
+ for ( k = 1; k <= mult; k++ ) {
+ for ( i = iok + k; i > iok; i-- ) {
+ npts4[i].x = npts4[i-1].x;
+ npts4[i].y = npts4[i-1].y;
+ npts4[i].z = npts4[i-1].z;
+ npts4[i].w = npts4[i-1].w;
+ }
+ for ( i = iok; i > iok - order + k; i-- ) {
+ alpha = (nknots[ink] - tmpknots[i])
+ / (tmpknots[i + order - k] - tmpknots[i]);
+ alph1 = 1.0 - alpha;
+ npts4[i].x = alpha * npts4[i].x + alph1 * npts4[i-1].x;
+ npts4[i].y = alpha * npts4[i].y + alph1 * npts4[i-1].y;
+ npts4[i].z = alpha * npts4[i].z + alph1 * npts4[i-1].z;
+ npts4[i].w = alpha * npts4[i].w + alph1 * npts4[i-1].w;
+ }
+ }
+ }
+
+ /* Total number of points and knots increased by `mult'. */
+ for ( k = numtmpknots - 1; k > iok; k-- )
+ tmpknots[k + mult] = tmpknots[k];
+ for ( k = 1; k <= mult; k++ )
+ tmpknots[iok + k] = nknots[ink];
+ numtmpknots += mult;
+ num_pts +=mult;
+ }
+
+
+ /* copy results into output buffers */
+ *numoutknots = numtmpknots; /* resulting total knots */
+ memcpy( (char *)nknots, (char *)tmpknots, numtmpknots * sizeof(ddFLOAT) );
+
+ xfree( (char *)tmpknots );
+ return 1;
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level2/miOCs.c b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miOCs.c
new file mode 100644
index 000000000..2c9b78133
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miOCs.c
@@ -0,0 +1,1614 @@
+/* $TOG: miOCs.c /main/7 1998/02/10 12:42:05 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level2/miOCs.c,v 3.5 1998/10/04 09:34:24 dawes Exp $ */
+
+#include "miLUT.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "PEXErr.h"
+#include "PEXprotost.h"
+#include "ddpex2.h"
+#include "miRender.h"
+#include "miStruct.h"
+#include "gcstruct.h"
+#include "miLight.h"
+#include "pexos.h"
+
+
+/* Level II Output Command Attributes */
+
+/*
+ * Marker type
+ */
+ddpex2rtn
+miMarkerType(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexMarkerType *pMT = (pexMarkerType *)(pOC+1);
+
+ pddc->Dynamic->pPCAttr->markerType = pMT->markerType;
+ /* Update DDC rendering attributes if not bundled */
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXMarkerTypeAsf) != PEXBundled)
+ pddc->Static.attrs->markerType = pMT->markerType;
+
+ return(Success);
+}
+
+/*
+ * Marker scale
+ */
+ddpex2rtn
+miMarkerScale(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexMarkerScale *pMS = (pexMarkerScale *)(pOC+1);
+
+ pddc->Dynamic->pPCAttr->markerScale = pMS->scale;
+ /* Update DDC rendering attributes if not bundled */
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXMarkerScaleAsf) != PEXBundled)
+ pddc->Static.attrs->markerScale = pMS->scale;
+
+ return(Success);
+}
+
+/*
+ * Marker Bundle Index
+ */
+ddpex2rtn
+miMarkerBundleIndex(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexMarkerBundleIndex *pMBI = (pexMarkerBundleIndex *)(pOC+1);
+ ddBitmask tables, namesets, attrs;
+
+ if (pddc->Dynamic->pPCAttr->markerIndex != pMBI->index) {
+ pddc->Dynamic->pPCAttr->markerIndex = pMBI->index;
+
+ namesets = attrs = 0;
+ tables = PEXDynMarkerBundle;
+ ValidateDDContextAttrs(pRend, pddc, tables, namesets, attrs);
+ }
+ return(Success);
+}
+
+/*
+ * Text Font Index
+ */
+ddpex2rtn
+miTextFontIndex(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexTextFontIndex *pMBI = (pexTextFontIndex *)(pOC+1);
+ pddc->Dynamic->pPCAttr->textFont = pMBI->index;
+ /* Update DDC rendering attributes if not bundled */
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXTextFontIndexAsf) != PEXBundled)
+ pddc->Static.attrs->textFont = pMBI->index;
+ return(Success);
+}
+
+/*
+ * Text Precision
+ */
+ddpex2rtn
+miTextPrecision(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexTextPrecision *pMBI = (pexTextPrecision *)(pOC+1);
+ pddc->Dynamic->pPCAttr->textPrecision = pMBI->precision;
+ /* Update DDC rendering attributes if not bundled */
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXTextPrecAsf) != PEXBundled)
+ pddc->Static.attrs->textPrecision = pMBI->precision;
+ return(Success);
+}
+
+/*
+ * Character Expansion
+ */
+ddpex2rtn
+miCharExpansion(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexCharExpansion *pMBI = (pexCharExpansion *)(pOC+1);
+ pddc->Dynamic->pPCAttr->charExpansion = pMBI->expansion;
+ /* Update DDC rendering attributes if not bundled */
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXCharExpansionAsf) != PEXBundled)
+ pddc->Static.attrs->charExpansion = pMBI->expansion;
+ return(Success);
+}
+
+/*
+ * Character Spacing
+ */
+ddpex2rtn
+miCharSpacing(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexCharSpacing *pMBI = (pexCharSpacing *)(pOC+1);
+ pddc->Dynamic->pPCAttr->charSpacing = pMBI->spacing;
+ /* Update DDC rendering attributes if not bundled */
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXCharSpacingAsf) != PEXBundled)
+ pddc->Static.attrs->charSpacing = pMBI->spacing;
+ return(Success);
+}
+
+/*
+ * Character Height
+ */
+ddpex2rtn
+miCharHeight(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexCharHeight *pMBI = (pexCharHeight *)(pOC+1);
+ pddc->Dynamic->pPCAttr->charHeight = pMBI->height;
+ pddc->Static.attrs->charHeight = pMBI->height;
+ return(Success);
+}
+
+/*
+ * Character Up Vector
+ */
+ddpex2rtn
+miCharUpVector(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexCharUpVector *pMBI = (pexCharUpVector *)(pOC+1);
+ pddc->Dynamic->pPCAttr->charUp.x = pMBI->up.x;
+ pddc->Dynamic->pPCAttr->charUp.y = pMBI->up.y;
+ pddc->Static.attrs->charUp = pddc->Dynamic->pPCAttr->charUp;
+ return(Success);
+}
+
+/*
+ * Text Path
+ */
+ddpex2rtn
+miTextPath(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexTextPath *pMBI = (pexTextPath *)(pOC+1);
+ pddc->Dynamic->pPCAttr->textPath = pMBI->path;
+ pddc->Static.attrs->textPath = pMBI->path;
+ return(Success);
+}
+
+/*
+ * Text Alignment
+ */
+ddpex2rtn
+miTextAlignment(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexTextAlignment *pMBI = (pexTextAlignment *)(pOC+1);
+ pddc->Dynamic->pPCAttr->textAlignment.vertical =
+ (ddUSHORT) pMBI->alignment.vertical;
+ pddc->Dynamic->pPCAttr->textAlignment.horizontal =
+ (ddUSHORT) pMBI->alignment.horizontal;
+ pddc->Static.attrs->textAlignment =
+ pddc->Dynamic->pPCAttr->textAlignment;
+
+ return(Success);
+}
+
+/*
+ * Annotation Text Height
+ */
+ddpex2rtn
+miAtextHeight(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexAtextHeight *pMBI = (pexAtextHeight *)(pOC+1);
+ pddc->Dynamic->pPCAttr->atextHeight = pMBI->height;
+ pddc->Static.attrs->atextHeight = pMBI->height;
+ return(Success);
+}
+
+/*
+ * Annotation Text Up Vector
+ */
+ddpex2rtn
+miAtextUpVector(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexAtextUpVector *pMBI = (pexAtextUpVector *)(pOC+1);
+ pddc->Dynamic->pPCAttr->atextUp.x = pMBI->up.x;
+ pddc->Dynamic->pPCAttr->atextUp.y = pMBI->up.y;
+ pddc->Static.attrs->atextUp = pddc->Dynamic->pPCAttr->atextUp;
+ return(Success);
+}
+
+/*
+ * Annotation Text Path
+ */
+ddpex2rtn
+miAtextPath(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexAtextPath *pMBI = (pexAtextPath *)(pOC+1);
+ pddc->Dynamic->pPCAttr->atextPath = pMBI->path;
+ pddc->Static.attrs->atextPath = pMBI->path;
+ return(Success);
+}
+
+/*
+ * Annotation Text Alignment
+ */
+ddpex2rtn
+miAtextAlignment(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexAtextAlignment *pMBI = (pexAtextAlignment *)(pOC+1);
+ pddc->Dynamic->pPCAttr->atextAlignment.vertical =
+ (ddUSHORT) pMBI->alignment.vertical;
+ pddc->Dynamic->pPCAttr->atextAlignment.horizontal =
+ (ddUSHORT) pMBI->alignment.horizontal;
+ pddc->Static.attrs->atextAlignment =
+ pddc->Dynamic->pPCAttr->atextAlignment;
+ return(Success);
+}
+
+/*
+ * Annotation Text Style
+ */
+ddpex2rtn
+miAtextStyle(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexAtextStyle *pMT = (pexAtextStyle *)(pOC+1);
+ pddc->Dynamic->pPCAttr->atextStyle = pMT->style;
+ pddc->Static.attrs->atextStyle = pMT->style;
+ return(Success);
+}
+
+/*
+ * Text Bundle Index
+ */
+ddpex2rtn
+miTextBundleIndex(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexTextBundleIndex *pTBI = (pexTextBundleIndex *)(pOC+1);
+ ddBitmask tables, namesets, attrs;
+
+ if (pddc->Dynamic->pPCAttr->textIndex != pTBI->index) {
+ pddc->Dynamic->pPCAttr->textIndex = pTBI->index;
+
+ namesets = attrs = 0;
+ tables = PEXDynTextBundle;
+ ValidateDDContextAttrs(pRend, pddc, tables, namesets, attrs);
+ }
+ return(Success);
+}
+
+/*
+ * Line type (Dashing style)
+ */
+ddpex2rtn
+miLineType(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexLineType *pLT = (pexLineType *)(pOC+1);
+ pddc->Dynamic->pPCAttr->lineType = pLT->lineType;
+ /* Update DDC rendering attributes if not bundled */
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXLineTypeAsf) != PEXBundled) {
+ pddc->Static.attrs->lineType = pLT->lineType;
+ pddc->Static.misc.flags |= POLYLINEGCFLAG;
+ }
+ return(Success);
+}
+
+
+/*
+ * Line Width
+ */
+ddpex2rtn
+miLineWidth(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexLineWidth *pLW = (pexLineWidth *)(pOC+1);
+ pddc->Dynamic->pPCAttr->lineWidth = pLW->width;
+ /* Update DDC rendering attributes if not bundled */
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXLineWidthAsf) != PEXBundled) {
+ pddc->Static.attrs->lineWidth = pLW->width;
+ pddc->Static.misc.flags |= POLYLINEGCFLAG;
+ }
+ return(Success);
+}
+
+/*
+ * Line Bundle Index
+ */
+ddpex2rtn
+miLineBundleIndex(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexLineBundleIndex *pLBI = (pexLineBundleIndex *)(pOC+1);
+ ddBitmask tables, namesets, attrs;
+
+ if (pddc->Dynamic->pPCAttr->lineIndex != pLBI->index) {
+ pddc->Dynamic->pPCAttr->lineIndex = pLBI->index;
+
+ namesets = attrs = 0;
+ tables = PEXDynLineBundle;
+ ValidateDDContextAttrs(pRend, pddc, tables, namesets, attrs);
+ }
+ return(Success);
+}
+
+/*
+ * curve approximation method
+ */
+ddpex2rtn
+miCurveApproximation(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexCurveApproximation *pCA = (pexCurveApproximation *)(pOC+1);
+ pddc->Dynamic->pPCAttr->curveApprox.approxMethod = pCA->approx.approxMethod;
+ pddc->Dynamic->pPCAttr->curveApprox.tolerance = pCA->approx.tolerance;
+ /* Update DDC rendering attributes if not bundled */
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXLineWidthAsf) != PEXBundled)
+ pddc->Static.attrs->curveApprox=pddc->Dynamic->pPCAttr->curveApprox;
+
+ return(Success);
+}
+
+
+/*
+ * Surface interior style
+ */
+ddpex2rtn
+miInteriorStyle(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexInteriorStyle *pIS = (pexInteriorStyle *)(pOC+1);
+ pddc->Dynamic->pPCAttr->intStyle = pIS->interiorStyle;
+ /* Update DDC rendering attributes if not bundled */
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXInteriorStyleAsf) != PEXBundled) {
+ pddc->Static.attrs->intStyle = pIS->interiorStyle;
+ pddc->Static.misc.flags |= FILLAREAGCFLAG;
+ }
+ return(Success);
+}
+
+/*
+ * Depth Cue Bundle Index
+ */
+ddpex2rtn
+miDepthCueIndex(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexDepthCueIndex *pDCI = (pexDepthCueIndex *)(pOC+1);
+ ddBitmask tables, namesets, attrs;
+
+ pddc->Dynamic->pPCAttr->depthCueIndex = pDCI->index;
+
+ /* Mark as invalid cc version of depth cue entry in dd context */
+ pddc->Static.misc.flags |= CC_DCUEVERSION;
+
+ namesets = attrs = 0;
+ tables = PEXDynDepthCueTableContents;
+ ValidateDDContextAttrs(pRend, pddc, tables, namesets, attrs);
+
+ return(Success);
+}
+
+/*
+ * Interior Bundle Index
+ */
+ddpex2rtn
+miInteriorBundleIndex(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexInteriorBundleIndex *pIBI = (pexInteriorBundleIndex *)(pOC+1);
+ ddBitmask tables, namesets, attrs;
+
+ if (pddc->Dynamic->pPCAttr->intIndex != pIBI->index) {
+ pddc->Dynamic->pPCAttr->intIndex = pIBI->index;
+
+ namesets = attrs = 0;
+ tables = PEXDynInteriorBundle;
+ ValidateDDContextAttrs(pRend, pddc, tables, namesets, attrs);
+ }
+ return(Success);
+}
+
+/*
+ * Surface reflection attributes
+ */
+ddpex2rtn
+miSurfaceReflAttr(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexSurfaceReflAttr *pSRA = (pexSurfaceReflAttr *)(pOC+1);
+ ddColourSpecifier *pSC =
+ (ddColourSpecifier *)&pSRA->reflectionAttr.specularColour;
+
+ pddc->Dynamic->pPCAttr->reflAttr.ambient =
+ (ddFLOAT)pSRA->reflectionAttr.ambient;
+ pddc->Dynamic->pPCAttr->reflAttr.diffuse =
+ (ddFLOAT)pSRA->reflectionAttr.diffuse;
+ pddc->Dynamic->pPCAttr->reflAttr.specular =
+ (ddFLOAT)pSRA->reflectionAttr.specular;
+ pddc->Dynamic->pPCAttr->reflAttr.specularConc =
+ (ddFLOAT)pSRA->reflectionAttr.specularConc;
+ pddc->Dynamic->pPCAttr->reflAttr.transmission =
+ (ddFLOAT)pSRA->reflectionAttr.transmission;
+
+ switch (pddc->Dynamic->pPCAttr->reflAttr.specularColour.colourType =
+ pSC->colourType) {
+ case PEXIndexedColour:
+ pddc->Dynamic->pPCAttr->reflAttr.specularColour.colour.indexed =
+ pSC->colour.indexed;
+ break;
+ case PEXRgbFloatColour:
+ case PEXCieFloatColour:
+ case PEXHsvFloatColour:
+ case PEXHlsFloatColour:
+ pddc->Dynamic->pPCAttr->reflAttr.specularColour.colour.rgbFloat =
+ pSC->colour.rgbFloat;
+ break;
+ case PEXRgb8Colour:
+ pddc->Dynamic->pPCAttr->reflAttr.specularColour.colour.rgb8 =
+ pSC->colour.rgb8;
+ break;
+ case PEXRgb16Colour:
+ pddc->Dynamic->pPCAttr->reflAttr.specularColour.colour.rgb16 =
+ pSC->colour.rgb16;
+ break;
+ }
+
+ /* Update DDC rendering attributes if not bundled */
+ if((pddc->Dynamic->pPCAttr->asfs & PEXReflectionAttrAsf) != PEXBundled)
+ pddc->Static.attrs->reflAttr = pddc->Dynamic->pPCAttr->reflAttr;
+
+ return(Success);
+}
+/*
+ * Surface reflection model
+ */
+ddpex2rtn
+miSurfaceReflModel(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexSurfaceReflModel *pSRM = (pexSurfaceReflModel *)(pOC+1);
+ pddc->Dynamic->pPCAttr->reflModel = pSRM->reflectionModel;
+ /* Update DDC rendering attributes if not bundled */
+ if((pddc->Dynamic->pPCAttr->asfs & PEXReflectionModelAsf)!=PEXBundled)
+ pddc->Static.attrs->reflModel = pSRM->reflectionModel;
+ return(Success);
+}
+
+/*
+ * Surface interpolation scheme
+ */
+ddpex2rtn
+miSurfaceInterp(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexSurfaceInterp *pSI = (pexSurfaceInterp *)(pOC+1);
+ pddc->Dynamic->pPCAttr->surfInterp = pSI->surfaceInterp;
+ /* Update DDC rendering attributes if not bundled */
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXSurfaceInterpAsf) != PEXBundled)
+ pddc->Static.attrs->surfInterp = pSI->surfaceInterp;
+ return(Success);
+}
+
+/*
+ * Surface approximation criteria
+ */
+ddpex2rtn
+miSurfaceApproximation(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexSurfaceApproximation *pSA = (pexSurfaceApproximation *)(pOC+1);
+ pddc->Dynamic->pPCAttr->surfApprox.approxMethod = pSA->approx.approxMethod;
+ pddc->Dynamic->pPCAttr->surfApprox.uTolerance = pSA->approx.uTolerance;
+ pddc->Dynamic->pPCAttr->surfApprox.vTolerance = pSA->approx.vTolerance;
+ /* Update DDC rendering attributes if not bundled */
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXSurfaceApproxAsf) != PEXBundled)
+ pddc->Static.attrs->surfApprox = pddc->Dynamic->pPCAttr->surfApprox;
+ return(Success);
+}
+
+/*
+ * Cull back or front facing facets.
+ */
+ddpex2rtn
+miCullingMode(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexCullingMode *pCM = (pexCullingMode *)(pOC+1);
+ pddc->Dynamic->pPCAttr->cullMode = pCM->cullMode;
+ return(Success);
+}
+
+/*
+ * Surface edge flag (enable/disable dispaly of fill area edges)
+ */
+ddpex2rtn
+miSurfaceEdgeFlag(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexSurfaceEdgeFlag *pSEF = (pexSurfaceEdgeFlag *)(pOC+1);
+ pddc->Dynamic->pPCAttr->edges = pSEF->onoff;
+ /*set the dd context edge visibility flag if not a bundled attribute*/
+ if((pddc->Dynamic->pPCAttr->asfs & PEXSurfaceEdgesAsf) != PEXBundled) {
+ pddc->Static.attrs->edges = pSEF->onoff;
+ pddc->Static.misc.flags |= EDGEGCFLAG;
+ }
+ return(Success);
+}
+/*
+ * Surface edge type (Dashing style)
+ */
+ddpex2rtn
+miSurfaceEdgeType(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexSurfaceEdgeType *pSET = (pexSurfaceEdgeType *)(pOC+1);
+ pddc->Dynamic->pPCAttr->edgeType = pSET->edgeType;
+ /* Update DDC rendering attributes if not bundled */
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXSurfaceEdgeTypeAsf)!=PEXBundled) {
+ pddc->Static.attrs->edgeType = pSET->edgeType;
+ pddc->Static.misc.flags |= EDGEGCFLAG;
+ }
+ return(Success);
+}
+
+
+/*
+ * Surface edge Width
+ */
+ddpex2rtn
+miSurfaceEdgeWidth(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexSurfaceEdgeWidth *pSEW = (pexSurfaceEdgeWidth *)(pOC+1);
+ pddc->Dynamic->pPCAttr->edgeWidth = pSEW->width;
+ /* Update DDC rendering attributes if not bundled */
+ if((pddc->Dynamic->pPCAttr->asfs & PEXSurfaceEdgeWidthAsf)!=PEXBundled) {
+ pddc->Static.attrs->edgeWidth = pSEW->width;
+ pddc->Static.misc.flags |= EDGEGCFLAG;
+ }
+ return(Success);
+}
+/*
+ * Surface edge Bundle Index
+ */
+ddpex2rtn
+miEdgeBundleIndex(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexEdgeBundleIndex *pEBI = (pexEdgeBundleIndex *)(pOC+1);
+ ddBitmask tables, namesets, attrs;
+
+ if (pddc->Dynamic->pPCAttr->edgeIndex != pEBI->index) {
+ pddc->Dynamic->pPCAttr->edgeIndex = pEBI->index;
+
+ namesets = attrs = 0;
+ tables = PEXDynEdgeBundle;
+ ValidateDDContextAttrs(pRend, pddc, tables, namesets, attrs);
+ }
+ return(Success);
+}
+
+/*
+ * Set ASF values
+ */
+ddpex2rtn
+miSetAsfValues(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexSetAsfValues *pSAV = (pexSetAsfValues *)(pOC+1);
+ ddBitmask tables, namesets, attrs;
+
+ if (pSAV->source == PEXBundled) { /* Note that PEXBundled == 0 */
+ pddc->Dynamic->pPCAttr->asfs &= ~(pSAV->attribute);
+
+ } else {
+ pddc->Dynamic->pPCAttr->asfs |= pSAV->attribute;
+
+ }
+
+ /* changing the table behaves the same as changing
+ * the asf, so use that for ValidateDDContext
+ */
+ tables = namesets = attrs = 0;
+ if (pSAV->attribute & ( PEXMarkerTypeAsf |
+ PEXMarkerScaleAsf |
+ PEXMarkerColourAsf))
+ tables |= PEXDynMarkerBundle;
+ if (pSAV->attribute & (PEXTextFontIndexAsf |
+ PEXTextPrecAsf |
+ PEXCharExpansionAsf |
+ PEXCharSpacingAsf |
+ PEXTextColourAsf))
+ tables |= PEXDynTextBundle;
+ if (pSAV->attribute & (PEXLineTypeAsf |
+ PEXLineWidthAsf |
+ PEXLineColourAsf |
+ PEXCurveApproxAsf |
+ PEXPolylineInterpAsf))
+ tables |= PEXDynLineBundle;
+ if (pSAV->attribute & (PEXInteriorStyleAsf |
+ PEXInteriorStyleIndexAsf |
+ PEXSurfaceColourAsf |
+ PEXSurfaceInterpAsf |
+ PEXReflectionModelAsf |
+ PEXReflectionAttrAsf |
+ PEXBfInteriorStyleAsf |
+ PEXBfInteriorStyleIndexAsf |
+ PEXBfSurfaceColourAsf |
+ PEXBfSurfaceInterpAsf |
+ PEXBfReflectionModelAsf |
+ PEXBfReflectionAttrAsf |
+ PEXSurfaceApproxAsf))
+ tables |= PEXDynInteriorBundle;
+ if (pSAV->attribute & ( PEXSurfaceEdgeTypeAsf |
+ PEXSurfaceEdgeWidthAsf |
+ PEXSurfaceEdgeColourAsf |
+ PEXSurfaceEdgesAsf ))
+ tables |= PEXDynEdgeBundle;
+
+ /* Re-initialize the dd context rendering attributes */
+ ValidateDDContextAttrs(pRend, pddc, tables, namesets, attrs);
+
+ return(Success);
+}
+
+/*
+ * Local transformations
+ */
+ddpex2rtn
+miLocalTransform(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexLocalTransform *pLT = (pexLocalTransform *)(pOC+1);
+
+ switch (pLT->compType) {
+ case PEXPreConcatenate:
+ miMatMult( pddc->Dynamic->pPCAttr->localMat,
+ pLT->matrix, pddc->Dynamic->pPCAttr->localMat);
+ break;
+ case PEXPostConcatenate:
+ miMatMult( pddc->Dynamic->pPCAttr->localMat,
+ pddc->Dynamic->pPCAttr->localMat, pLT->matrix);
+ break;
+ case PEXReplace:
+ memcpy( (char *)(pddc->Dynamic->pPCAttr->localMat),
+ (char *)(pLT->matrix),
+ 16*sizeof(ddFLOAT));
+ break;
+ }
+
+ /* Update composite transforms */
+ /* First, composite [CMM] */
+ miMatMult( pddc->Dynamic->mc_to_wc_xform,
+ pddc->Dynamic->pPCAttr->localMat,
+ pddc->Dynamic->pPCAttr->globalMat);
+
+ /* Next, composite [VCM] next */
+ miMatMult( pddc->Dynamic->mc_to_cc_xform,
+ pddc->Dynamic->mc_to_wc_xform,
+ pddc->Dynamic->wc_to_cc_xform);
+
+ /* Lastly, Compute the composite mc -> dc transform */
+ miMatMult( pddc->Dynamic->mc_to_dc_xform,
+ pddc->Dynamic->mc_to_cc_xform,
+ pddc->Dynamic->cc_to_dc_xform);
+
+ /* Mark as invalid appropriate inverse transforms in dd context */
+ pddc->Static.misc.flags |= (INVTRMCTOWCXFRMFLAG | INVTRWCTOCCXFRMFLAG);
+
+ return(Success);
+}
+
+ddpex2rtn
+miLocalTransform2D(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexLocalTransform2D *pLT = (pexLocalTransform2D *)(pOC+1);
+ ddFLOAT *s, *d;
+ ddFLOAT temp[4][4];
+
+ /*
+ * 2D -> 3D transform as follows:
+ *
+ * a d g a d 0 g
+ * b e h b e 0 h
+ * c f i 0 0 1 0
+ * c f 0 i
+ *
+ */
+ s = (ddFLOAT *)pLT->matrix3X3;
+ d = (ddFLOAT *)temp;
+
+ *d++ = *s++; /* [0][0] */
+ *d++ = *s++; /* [0][1] */
+ *d++ = 0.0; /* [0][2] */
+ *d++ = *s++; /* [0][3] */
+ *d++ = *s++; /* [1][0] */
+ *d++ = *s++; /* [1][1] */
+ *d++ = 0.0; /* [1][2] */
+ *d++ = *s++; /* [1][3] */
+ *d++ = 0.0; /* [2][0] */
+ *d++ = 0.0; /* [2][1] */
+ *d++ = 1.0; /* [2][2] */
+ *d++ = 0.0; /* [2][3] */
+ *d++ = *s++; /* [3][0] */
+ *d++ = *s++; /* [3][0] */
+ *d++ = 0.0; /* [3][0] */
+ *d++ = *s++; /* [3][0] */
+
+ switch (pLT->compType) {
+ case PEXPreConcatenate:
+ miMatMult( pddc->Dynamic->pPCAttr->localMat,
+ temp, pddc->Dynamic->pPCAttr->localMat);
+ break;
+ case PEXPostConcatenate:
+ miMatMult( pddc->Dynamic->pPCAttr->localMat,
+ pddc->Dynamic->pPCAttr->localMat, temp);
+ break;
+ case PEXReplace:
+ memcpy( (char *)(pddc->Dynamic->pPCAttr->localMat), (char *)temp,
+ 16*sizeof(ddFLOAT));
+ break;
+ }
+
+ /* Update composite transforms */
+ /* First, composite [CMM] */
+ miMatMult( pddc->Dynamic->mc_to_wc_xform,
+ pddc->Dynamic->pPCAttr->localMat,
+ pddc->Dynamic->pPCAttr->globalMat);
+
+ /* Next, composite [VCM] next */
+ miMatMult( pddc->Dynamic->mc_to_cc_xform,
+ pddc->Dynamic->mc_to_wc_xform,
+ pddc->Dynamic->wc_to_cc_xform);
+
+ /* Lastly, Compute the composite mc -> dc transform */
+ miMatMult( pddc->Dynamic->mc_to_dc_xform,
+ pddc->Dynamic->mc_to_cc_xform,
+ pddc->Dynamic->cc_to_dc_xform);
+
+ /* Mark as invalid appropriate inverse transforms in dd context */
+ pddc->Static.misc.flags |= (INVTRMCTOWCXFRMFLAG | INVTRWCTOCCXFRMFLAG);
+
+ return(Success);
+}
+
+
+/*
+ * Global transformations
+ */
+ddpex2rtn
+miGlobalTransform(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexGlobalTransform *pGT = (pexGlobalTransform *)(pOC+1);
+
+ memcpy( (char *)(pddc->Dynamic->pPCAttr->globalMat), (char *)(pGT->matrix),
+ 16 * sizeof(ddFLOAT));
+
+ /* Update composite transforms */
+ /* First, composite [CMM] */
+ miMatMult( pddc->Dynamic->mc_to_wc_xform,
+ pddc->Dynamic->pPCAttr->localMat,
+ pddc->Dynamic->pPCAttr->globalMat);
+
+ /* Next, composite [VCM] next */
+ miMatMult( pddc->Dynamic->mc_to_cc_xform,
+ pddc->Dynamic->mc_to_wc_xform,
+ pddc->Dynamic->wc_to_cc_xform);
+
+ /* Lastly, Compute the composite mc -> dc transform */
+ miMatMult( pddc->Dynamic->mc_to_dc_xform,
+ pddc->Dynamic->mc_to_cc_xform,
+ pddc->Dynamic->cc_to_dc_xform);
+
+ /* Mark as invalid appropriate inverse transforms in dd context */
+ pddc->Static.misc.flags |= (INVTRMCTOWCXFRMFLAG | INVTRWCTOCCXFRMFLAG);
+
+ return(Success);
+}
+
+ddpex2rtn
+miGlobalTransform2D(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexGlobalTransform2D *pGT = (pexGlobalTransform2D *)(pOC+1);
+ ddFLOAT *s, *d;
+
+ /*
+ * 2D -> 3D transform as follows:
+ *
+ * a d g a d 0 g
+ * b e h b e 0 h
+ * c f i 0 0 1 0
+ * c f 0 i
+ *
+ */
+ s = (ddFLOAT *)pGT->matrix3X3;
+ d = (ddFLOAT *)pddc->Dynamic->pPCAttr->globalMat;
+
+ *d++ = *s++; /* [0][0] */
+ *d++ = *s++; /* [0][1] */
+ *d++ = 0.0; /* [0][2] */
+ *d++ = *s++; /* [0][3] */
+ *d++ = *s++; /* [1][0] */
+ *d++ = *s++; /* [1][1] */
+ *d++ = 0.0; /* [1][2] */
+ *d++ = *s++; /* [1][3] */
+ *d++ = 0.0; /* [2][0] */
+ *d++ = 0.0; /* [2][1] */
+ *d++ = 1.0; /* [2][2] */
+ *d++ = 0.0; /* [2][3] */
+ *d++ = *s++; /* [3][0] */
+ *d++ = *s++; /* [3][0] */
+ *d++ = 0.0; /* [3][0] */
+ *d++ = *s++; /* [3][0] */
+
+ /* Update composite transforms */
+ /* First, composite [CMM] */
+ miMatMult( pddc->Dynamic->mc_to_wc_xform,
+ pddc->Dynamic->pPCAttr->localMat,
+ pddc->Dynamic->pPCAttr->globalMat);
+
+ /* Next, composite [VCM] next */
+ miMatMult( pddc->Dynamic->mc_to_cc_xform,
+ pddc->Dynamic->mc_to_wc_xform,
+ pddc->Dynamic->wc_to_cc_xform);
+
+ /* Lastly, Compute the composite mc -> dc transform */
+ miMatMult( pddc->Dynamic->mc_to_dc_xform,
+ pddc->Dynamic->mc_to_cc_xform,
+ pddc->Dynamic->cc_to_dc_xform);
+
+ /* Mark as invalid appropriate inverse transforms in dd context */
+ pddc->Static.misc.flags |= (INVTRMCTOWCXFRMFLAG | INVTRWCTOCCXFRMFLAG);
+
+ return(Success);
+}
+
+ddpex2rtn
+miModelClip(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexModelClip *pMC = (pexModelClip *)(pOC+1);
+ pddc->Dynamic->pPCAttr->modelClip = pMC->onoff;
+
+ return(Success);
+}
+
+
+
+ddpex2rtn
+miViewIndex(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexViewIndex *pVI = (pexViewIndex *)(pOC+1);
+
+ /* first, make sure this is a new index */
+ if (pddc->Dynamic->pPCAttr->viewIndex == pVI->index) return(Success);
+
+ /* Copy new index into ddContext */
+ pddc->Dynamic->pPCAttr->viewIndex = pVI->index;
+
+ /* Now, update internal transform cache to reflect new index */
+ miBldCC_xform(pRend, pddc);
+
+ return(Success);
+}
+
+
+
+ddpex2rtn
+miPickId(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexPickId *pPI = (pexPickId *)(pOC+1);
+
+ pddc->Dynamic->pPCAttr->pickId = pPI->pickId;
+ return(Success);
+}
+
+
+ddpex2rtn
+miColourApproxIndex(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexColourApproxIndex *pCAI = (pexColourApproxIndex *)(pOC+1);
+ pddc->Dynamic->pPCAttr->colourApproxIndex = pCAI->index;
+ return(Success);
+}
+
+
+ddpex2rtn
+miRenderingColourModel(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexRenderingColourModel *pRCM = (pexRenderingColourModel *)(pOC+1);
+ pddc->Dynamic->pPCAttr->rdrColourModel = pRCM->model;
+ return(Success);
+}
+
+
+ddpex2rtn
+miParaSurfCharacteristics(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ miPSurfaceCharsStruct *pPSC = (miPSurfaceCharsStruct *)(pOC+1);
+ switch (pddc->Dynamic->pPCAttr->psc.type = pPSC->type) {
+ case PEXPSCNone:
+ case PEXPSCImpDep:
+ break;
+ case PEXPSCIsoCurves:
+ pddc->Dynamic->pPCAttr->psc.data.isoCurves = *pPSC->data.pIsoCurves;
+ break;
+ case PEXPSCMcLevelCurves:
+ /* Note that level curves are not implemented */
+ pddc->Dynamic->pPCAttr->psc.data.mcLevelCurves =
+ *pPSC->data.pMcLevelCurves;
+ break;
+ case PEXPSCWcLevelCurves:
+ /* Note that level curves are not implemented */
+ pddc->Dynamic->pPCAttr->psc.data.wcLevelCurves =
+ *pPSC->data.pWcLevelCurves;
+ break;
+ default:
+ break;
+ }
+ return(Success);
+
+}
+
+ddpex2rtn
+miAddToNameSet(pRend, pOC) /* and RemoveNameFromNameSet */
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ pexAddToNameSet *pANS = (pexAddToNameSet *)(pOC+1);
+ ddULONG *pName = (ddULONG *)(pANS + 1);
+ register int num = (pANS->head.length) - 1;
+ ddUSHORT save_flags = pddc->Dynamic->filter_flags;
+ ddBitmask namesets;
+ extern void ValidateFilters();
+
+ for (; num>0; num--, pName++)
+ /* ignore values that are out of range */
+ if ( MINS_VALID_NAME(*pName) ) {
+ if (pANS->head.elementType == PEXOCAddToNameSet) {
+ MINS_ADD_TO_NAMESET(*pName, pddc->Dynamic->currentNames);
+ } else {
+ MINS_REMOVE_FROM_NAMESET(*pName, pddc->Dynamic->currentNames);
+ }
+ }
+
+ /* changing current namesset, so update all filters */
+ namesets = PEXDynHighlightNameset |
+ PEXDynInvisibilityNameset |
+ PEXDynHighlightNamesetContents |
+ PEXDynInvisibilityNamesetContents;
+
+
+ ValidateFilters(pRend, pddc, namesets);
+
+ return(Success);
+}
+
+
+ddpex2rtn
+miExecuteStructure(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ extern void execute_structure_OC();
+
+ execute_structure_OC(pRend, (pexExecuteStructure *)(pOC+1));
+ return(Success);
+}
+
+
+ddpex2rtn
+miNoop(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+ return (Success);
+}
+
+
+ddpex2rtn
+miUndefined(pRend, pOC)
+ ddRendererPtr pRend;
+ miGenericStr *pOC;
+{
+#ifdef PR_INFO
+ ErrorF( "Attribute is not implemented\n");
+#endif
+ return (PEXNYI);
+}
+
+
+
+/*++
+ |
+ | Function Name: miLightStateOC
+ |
+ | Function Description:
+ | Handles PEXOCLightState OC
+ |
+ | Note(s):
+ |
+ --*/
+ddpex2rtn
+miLightStateOC(pRend, pOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pOC; /* output command */
+/* out */
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ miLightStateStruct *pLS = (miLightStateStruct *)(pOC+1);
+ ddUSHORT *ptr;
+ int i;
+
+ /*
+ * Merge in a new set of light source indices
+ */
+ if (pLS->enableList->numObj > 0)
+ puMergeLists( pddc->Dynamic->pPCAttr->lightState, pLS->enableList,
+ pddc->Dynamic->pPCAttr->lightState);
+
+ if (pLS->disableList->numObj > 0)
+ for (i = pLS->disableList->numObj,
+ ptr = (ddUSHORT *)pLS->disableList->pList;
+ i > 0;
+ --i, ptr++)
+ puRemoveFromList(ptr, pddc->Dynamic->pPCAttr->lightState);
+
+ return (Success);
+}
+
+/*++
+ |
+ | Function Name: SetMCVolume
+ |
+ | Function Description:
+ | Handles Handles SetModelClipVolume and
+ | SetModelClipVolume2D OCs
+ |
+ | Note(s): Although model clipping half spaces are specified
+ | in modelling space, the pipeline stores the current clipping
+ | volume in world coordinates. This is because the modelling
+ | transformation matrix can change independently of this particular
+ | OC, and world coordinates are the the only common coordinates to
+ | intersect. HOWEVER, when model clipping is enabled, this
+ | intersect volume is transferred BACK to model space and stored
+ | in pddc->Static->ms_MCV for the actual clipping. This is done
+ | in order to "prune" out as many primitives as early as possible
+ | in the pipeline.
+ |
+ | Whenever the modelling transformation matrix is changed, or
+ | when a new renderer is created, the model space version of
+ | the model clipping volume is invalidated; the world
+ | coordinate volume is the "reference." The validation flag is
+ | the INVMCXFRMFLAG defined in ddpex/mi/include/miRender.h
+ |
+ --*/
+ddpex2rtn
+miSetMCVolume(pRend, pOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pOC; /* output command */
+/* out */
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ miMCVolume_Struct *OC_MCV = (miMCVolume_Struct *)(pOC+1);
+ listofObj *pc_MCV;
+ ddHalfSpace *OC_HS, tmp_HS;
+ int i, count;
+ ddFLOAT length;
+
+ static ddFLOAT vect_xform[4][4];
+
+
+ pc_MCV = pddc->Dynamic->pPCAttr->modelClipVolume;
+ if (!(OC_MCV->operator == PEXModelClipIntersection)) pc_MCV->numObj = 0;
+ /* invalidate flag */
+ pddc->Static.misc.flags |= MCVOLUMEFLAG;
+
+
+ /* overwrite list */
+ OC_HS = (ddHalfSpace *)(OC_MCV->halfspaces->pList);
+ count = OC_MCV->halfspaces->numObj;
+ for(i = 0; i < count; i++) {
+
+ /* transform ref point and vector to world coords */
+ /* transform ref point */
+
+ miTransformPoint(&OC_HS->orig_point, pddc->Dynamic->mc_to_wc_xform,
+ &tmp_HS.point);
+
+ /* transform ref vector
+ * Vectors are transformed using the inverse transpose
+ */
+
+ miMatCopy(pddc->Dynamic->mc_to_wc_xform,
+ vect_xform);
+
+ miMatInverse(vect_xform);
+
+ miMatTranspose(vect_xform);
+
+ miTransformVector(&OC_HS->orig_vector, vect_xform,
+ &tmp_HS.vector);
+
+ puAddToList(&tmp_HS, 1, pc_MCV);
+ OC_HS++;
+ }
+
+ return(Success);
+}
+
+/*++
+ |
+ | Function Name: miRestoreMCV
+ |
+ | Function Description:
+ | Restores the model clipping volume to that of the
+ | parent, or nil if this is the first structure.
+ |
+ | Note(s):
+ |
+ --*/
+ddpex2rtn
+miRestoreMCV(pRend, pOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pOC; /* output command */
+{
+
+
+ miDDContext *thispddc = (miDDContext *)(pRend->pDDContext);
+ miDynamicDDContext *parentpddc =
+ (miDynamicDDContext *)(thispddc->Dynamic->next);
+
+ if (!(thispddc->Dynamic->next)) /* First structure */
+ thispddc->Dynamic->pPCAttr->modelClipVolume->numObj = 0;
+ else {
+ /* invalidate flag */
+ thispddc->Static.misc.flags |= MCVOLUMEFLAG;
+ if (puCopyList(parentpddc->pPCAttr->modelClipVolume,
+ thispddc->Dynamic->pPCAttr->modelClipVolume ))
+
+ return (BadAlloc);
+ }
+
+ return(Success);
+}
+
+/*++
+ |
+ | Function Name: miMarkerColourOC
+ |
+ | Function Description:
+ | Handles PEXOCMarkerColourIndex and PEXOCMarkerColour.
+ |
+ | Note(s):
+ |
+ --*/
+ddpex2rtn
+miMarkerColourOC(pRend, pOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pOC; /* output command */
+/* out */
+{
+ ddpex3rtn miConvertColor();
+
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ miColourStruct *pMC = (miColourStruct *)(pOC+1);
+
+
+ switch (pddc->Dynamic->pPCAttr->markerColour.colourType = pMC->colourType)
+ {
+ case PEXIndexedColour:
+ pddc->Dynamic->pPCAttr->markerColour.colour.indexed =
+ *pMC->colour.pIndex;
+ break;
+
+ case PEXRgbFloatColour:
+ case PEXCieFloatColour:
+ case PEXHsvFloatColour:
+ case PEXHlsFloatColour:
+ pddc->Dynamic->pPCAttr->markerColour.colour.rgbFloat =
+ *pMC->colour.pRgbFloat;
+ break;
+
+ case PEXRgb8Colour:
+ pddc->Dynamic->pPCAttr->markerColour.colour.rgb8 =
+ *pMC->colour.pRgb8;
+ break;
+
+ case PEXRgb16Colour:
+ pddc->Dynamic->pPCAttr->markerColour.colour.rgb16 =
+ *pMC->colour.pRgb16;
+ break;
+ }
+
+ if (!(MI_DDC_IS_HIGHLIGHT(pddc))) {
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXMarkerColourAsf) != PEXBundled) {
+ miConvertColor(pRend,
+ &pddc->Dynamic->pPCAttr->markerColour,
+ pddc->Dynamic->pPCAttr->rdrColourModel,
+ &pddc->Static.attrs->markerColour);
+ pddc->Static.misc.flags |= MARKERGCFLAG;
+ }
+ }
+ return(Success);
+}
+
+
+/*++
+ |
+ | Function Name: miTextColourOC
+ |
+ | Function Description:
+ | Handles PEXOCTextColourIndex and PEXOCTextColour.
+ |
+ | Note(s):
+ |
+ --*/
+ddpex2rtn
+miTextColourOC(pRend, pOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pOC; /* output command */
+/* out */
+{
+ ddpex3rtn miConvertColor();
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ miColourStruct *pTC = (miColourStruct *)(pOC+1);
+
+ switch (pddc->Dynamic->pPCAttr->textColour.colourType = pTC->colourType)
+ {
+ case PEXIndexedColour:
+ pddc->Dynamic->pPCAttr->textColour.colour.indexed =
+ *pTC->colour.pIndex;
+ break;
+
+ case PEXRgbFloatColour:
+ case PEXCieFloatColour:
+ case PEXHsvFloatColour:
+ case PEXHlsFloatColour:
+ pddc->Dynamic->pPCAttr->textColour.colour.rgbFloat =
+ *pTC->colour.pRgbFloat;
+ break;
+
+ case PEXRgb8Colour:
+ pddc->Dynamic->pPCAttr->textColour.colour.rgb8 =
+ *pTC->colour.pRgb8;
+ break;
+ case PEXRgb16Colour:
+ pddc->Dynamic->pPCAttr->textColour.colour.rgb16 =
+ *pTC->colour.pRgb16;
+ break;
+ }
+
+ if (!(MI_DDC_IS_HIGHLIGHT(pddc))) {
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXTextColourAsf) != PEXBundled) {
+ miConvertColor(pRend,
+ &pddc->Dynamic->pPCAttr->textColour,
+ pddc->Dynamic->pPCAttr->rdrColourModel,
+ &pddc->Static.attrs->textColour);
+ pddc->Static.misc.flags |= TEXTGCFLAG;
+ }
+ }
+ return(Success);
+}
+
+
+/*++
+ |
+ | Function Name: miLineColourOC
+ |
+ | Function Description:
+ | Handles PEXOCLineColourIndex and PEXOCLineColour.
+ |
+ | Note(s):
+ |
+ --*/
+ddpex2rtn
+miLineColourOC(pRend, pOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pOC; /* output command */
+/* out */
+{
+ ddpex3rtn miConvertColor();
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ miColourStruct *pLC = (miColourStruct *)(pOC+1);
+
+ switch (pddc->Dynamic->pPCAttr->lineColour.colourType = pLC->colourType)
+ {
+ case PEXIndexedColour:
+ pddc->Dynamic->pPCAttr->lineColour.colour.indexed =
+ *pLC->colour.pIndex;
+ break;
+
+ case PEXRgbFloatColour:
+ case PEXCieFloatColour:
+ case PEXHsvFloatColour:
+ case PEXHlsFloatColour:
+ pddc->Dynamic->pPCAttr->lineColour.colour.rgbFloat =
+ *pLC->colour.pRgbFloat;
+ break;
+
+ case PEXRgb8Colour:
+ pddc->Dynamic->pPCAttr->lineColour.colour.rgb8 = *pLC->colour.pRgb8;
+ break;
+
+ case PEXRgb16Colour:
+ pddc->Dynamic->pPCAttr->lineColour.colour.rgb16 =
+ *pLC->colour.pRgb16;
+ break;
+ }
+
+ if (!(MI_DDC_IS_HIGHLIGHT(pddc))) {
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXLineColourAsf) != PEXBundled) {
+ miConvertColor(pRend,
+ &pddc->Dynamic->pPCAttr->lineColour,
+ pddc->Dynamic->pPCAttr->rdrColourModel,
+ &pddc->Static.attrs->lineColour);
+ pddc->Static.misc.flags |= POLYLINEGCFLAG;
+ }
+ }
+ return(Success);
+}
+
+/*++
+ |
+ | Function Name: miSurfaceColourOC
+ |
+ | Function Description:
+ | Handles PEXOCSurfaceColourIndex and PEXOCSurfaceColour.
+ |
+ | Note(s):
+ |
+ --*/
+ddpex2rtn
+miSurfaceColourOC(pRend, pOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pOC; /* output command */
+/* out */
+{
+ ddpex3rtn miConvertColor();
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ miColourStruct *pSC = (miColourStruct *)(pOC+1);
+
+ switch (pddc->Dynamic->pPCAttr->surfaceColour.colourType=pSC->colourType)
+ {
+ case PEXIndexedColour:
+ pddc->Dynamic->pPCAttr->surfaceColour.colour.indexed =
+ *pSC->colour.pIndex;
+ break;
+
+ case PEXRgbFloatColour:
+ case PEXCieFloatColour:
+ case PEXHsvFloatColour:
+ case PEXHlsFloatColour:
+ pddc->Dynamic->pPCAttr->surfaceColour.colour.rgbFloat =
+ *pSC->colour.pRgbFloat;
+ break;
+ case PEXRgb8Colour:
+ pddc->Dynamic->pPCAttr->surfaceColour.colour.rgb8 =
+ *pSC->colour.pRgb8;
+ break;
+
+ case PEXRgb16Colour:
+ pddc->Dynamic->pPCAttr->surfaceColour.colour.rgb16 =
+ *pSC->colour.pRgb16;
+ break;
+ }
+
+ if (!(MI_DDC_IS_HIGHLIGHT(pddc))) {
+ if ((pddc->Dynamic->pPCAttr->asfs & PEXSurfaceColourAsf)!=PEXBundled) {
+ miConvertColor(pRend,
+ &pddc->Dynamic->pPCAttr->surfaceColour,
+ pddc->Dynamic->pPCAttr->rdrColourModel,
+ &pddc->Static.attrs->surfaceColour);
+ pddc->Static.misc.flags |= FILLAREAGCFLAG;
+ }
+ }
+ return(Success);
+}
+
+/*++
+ |
+ | Function Name: miEdgeColourOC
+ |
+ | Function Description:
+ | Handles PEXOCSurfaceEdgeColourIndex and PEXOCSurfaceEdgeColour.
+ |
+ | Note(s):
+ |
+ --*/
+ddpex2rtn
+miEdgeColourOC(pRend, pOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pOC; /* output command */
+/* out */
+{
+ ddpex3rtn miConvertColor();
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ miColourStruct *pSEC = (miColourStruct *)(pOC+1);
+
+ switch (pddc->Dynamic->pPCAttr->edgeColour.colourType = pSEC->colourType)
+ {
+ case PEXIndexedColour:
+ pddc->Dynamic->pPCAttr->edgeColour.colour.indexed =
+ *pSEC->colour.pIndex;
+ break;
+
+ case PEXRgbFloatColour:
+ case PEXCieFloatColour:
+ case PEXHsvFloatColour:
+ case PEXHlsFloatColour:
+ pddc->Dynamic->pPCAttr->edgeColour.colour.rgbFloat =
+ *pSEC->colour.pRgbFloat;
+ break;
+
+ case PEXRgb8Colour:
+ pddc->Dynamic->pPCAttr->edgeColour.colour.rgb8 = *pSEC->colour.pRgb8;
+ break;
+ case PEXRgb16Colour:
+ pddc->Dynamic->pPCAttr->edgeColour.colour.rgb16 =
+ *pSEC->colour.pRgb16;
+ break;
+ }
+
+ if (!(MI_DDC_IS_HIGHLIGHT(pddc))) {
+ if ((pddc->Dynamic->pPCAttr->asfs &PEXSurfaceEdgeColourAsf)!=PEXBundled)
+ {
+ miConvertColor(pRend,
+ &pddc->Dynamic->pPCAttr->edgeColour,
+ pddc->Dynamic->pPCAttr->rdrColourModel,
+ &pddc->Static.attrs->edgeColour);
+ pddc->Static.misc.flags |= EDGEGCFLAG;
+ }
+ }
+ return(Success);
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level2/miPickPrim.c b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miPickPrim.c
new file mode 100644
index 000000000..6183580b6
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miPickPrim.c
@@ -0,0 +1,1242 @@
+/* $TOG: miPickPrim.c /main/9 1998/02/10 12:42:11 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level2/miPickPrim.c,v 3.6 1998/10/04 09:34:25 dawes Exp $ */
+
+#include "miWks.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "PEXErr.h"
+#include "miRender.h"
+#include "miStruct.h"
+#include "ddpex2.h"
+#include "miFont.h"
+#include "miText.h"
+#include "miClip.h"
+#include "pexos.h"
+
+#define MAX(a,b) (((a)>(b))?(a):(b))
+#define MIN(a,b) (((a)<(b))?(a):(b))
+
+extern ocTableType InitExecuteOCTable[];
+extern int atx_el_to_path();
+extern void text2_xform();
+extern void text3_xform();
+
+/*
+ * Function Name: compute_pick_volume
+ *
+ * Purpose: Compute the intersection of the clip limits and the
+ * pick aperture. PEX-SI's pick aperture can be a DC_HitBox
+ * or an NPC_HitVolume. However, for pick correllation purposes,
+ * the pick aperture will always be a NPC subvolume. i.e., the
+ * DC_HitBox has been mapped into NPC.
+ * Return:
+ * pick volume, if any.
+ */
+ddpex2rtn
+compute_pick_volume(aperture, view, pDDC, pick_volume)
+/* in */
+register ddNpcSubvolume *aperture; /* NPC Pick Aperture */
+ ddViewEntry *view; /* View clipping info.
+ * view->clipLimits contains
+ * the desired clip limits */
+ miDDContext *pDDC; /* Pointer to DDContext */
+/* out */
+register ddNpcSubvolume *pick_volume; /* Intersection to use */
+{
+ register ddNpcSubvolume *clip_limit;
+ ddUSHORT all_clipped;
+ ddCoord4D NPC_Min, NPC_Max;
+/* calls */
+
+ all_clipped = 0;
+ clip_limit = &(view->clipLimits);
+
+ NPC_Max.x = clip_limit->maxval.x;
+ NPC_Max.y = clip_limit->maxval.y;
+ NPC_Max.z = clip_limit->maxval.z;
+ NPC_Max.w = 1.0;
+ NPC_Min.x = clip_limit->minval.x;
+ NPC_Min.y = clip_limit->minval.y;
+ NPC_Min.z = clip_limit->minval.z;
+ NPC_Min.w = 1.0;
+
+ if (view->clipFlags != 0) {
+ /*
+ * only test intersection of volumes if any view clipping flags are on
+ */
+ all_clipped =
+ ( (aperture->minval.x > NPC_Max.x) ||
+ (aperture->minval.y > NPC_Max.y) ||
+ (aperture->minval.z > NPC_Max.z) ||
+ (aperture->maxval.x < NPC_Min.x) ||
+ (aperture->maxval.y < NPC_Min.y) ||
+ (aperture->maxval.z < NPC_Min.z) );
+
+ if (all_clipped) {
+ /*
+ * the intersection of the volumes is null;
+ * everything is always clipped.
+ */
+ return (all_clipped); /*
+ * I.E., trivial reject situation, nothing
+ * will be picked
+ */
+ }
+ }
+
+ /* look at X-Y */
+ if (view->clipFlags >= PEXClipXY) {
+ /* not clipping to the clip limit so use all of aperture */
+ pick_volume->minval.x = aperture->minval.x;
+ pick_volume->minval.y = aperture->minval.y;
+ pick_volume->maxval.x = aperture->maxval.x;
+ pick_volume->maxval.y = aperture->maxval.y;
+ }
+ else {
+ pick_volume->minval.x = MAX(aperture->minval.x, NPC_Min.x);
+ pick_volume->minval.y = MAX(aperture->minval.y, NPC_Min.y);
+ pick_volume->maxval.x = MIN(aperture->maxval.x, NPC_Max.x);
+ pick_volume->maxval.y = MIN(aperture->maxval.y, NPC_Max.y);
+ }
+
+ /* look at Z */
+ if (view->clipFlags >= PEXClipBack)
+ pick_volume->maxval.z = aperture->maxval.z;
+ else
+ pick_volume->maxval.z = MIN(aperture->maxval.z, NPC_Max.z);
+
+ if (view->clipFlags >= PEXClipFront)
+ pick_volume->minval.z = aperture->minval.z;
+ else
+ pick_volume->minval.z = MAX(aperture->minval.z, NPC_Min.z);
+
+ return (Success);
+}
+
+
+/*
+ * Function Name: compute_pick_volume_xform
+ *
+ * Purpose: Compute the transformation that transform the primitive
+ * to be picked from pick_volume to CC. Remember that we
+ * will use the standard primitive clipping functions to figure
+ * out whether a given primitive lies within the pick aperture.
+ * Return:
+ * pv_to_cc_xform to be used to figure out pick hits.
+ */
+void
+compute_pick_volume_xform(pick_volume, pv_to_cc_xform)
+/* in */
+ ddNpcSubvolume *pick_volume;
+/* out */
+ ddFLOAT pv_to_cc_xform[4][4];
+/* calls */
+{
+ /* The transformation needed here is to go from pick_volume to clip_volume
+ * as shown in 2D below. We extend the transform to handle the 3D case
+ * trivially.
+ *
+ * pick_volume clip_volume
+ * ----------- -----------
+ *
+ * +-----+(c,d) +---------+(1,1)
+ * | | | |
+ * | | =======> | |
+ * | | | |
+ * (a,b)+-----+ (-1,-1)+---------+
+ *
+ * pv_to_cc_xform (2D): 2/(c-a) 0 (c+a)/(a-c)
+ * 0 2/(d-b) (d+b)/(b-d)
+ * 0 0 0
+ */
+
+ memcpy( (char *)pv_to_cc_xform, (char *)ident4x4, 16 * sizeof(ddFLOAT));
+ pv_to_cc_xform[0][0] =
+ 2.0 / (pick_volume->maxval.x - pick_volume->minval.x);
+ pv_to_cc_xform[1][1] =
+ 2.0 / (pick_volume->maxval.y - pick_volume->minval.y);
+ pv_to_cc_xform[2][2] =
+ 2.0 / (pick_volume->maxval.z - pick_volume->minval.z);
+ pv_to_cc_xform[0][3] =
+ (pick_volume->maxval.x + pick_volume->minval.x) /
+ (pick_volume->minval.x - pick_volume->maxval.x);
+ pv_to_cc_xform[1][3] =
+ (pick_volume->maxval.y + pick_volume->minval.y) /
+ (pick_volume->minval.y - pick_volume->maxval.y);
+ pv_to_cc_xform[2][3] =
+ (pick_volume->maxval.z + pick_volume->minval.z) /
+ (pick_volume->minval.z - pick_volume->maxval.z);
+}
+
+
+/*
+ * Function Name: convert_dcHitBox_to_npc
+ *
+ * Purpose: Convert a dcHitBox into an equivalent NPCHitVolume. This
+ * is to facilitate picking to be done always in NPC.
+ * Return:
+ * NPCHitVolume to be used as the aperture.
+ */
+void
+convert_dcHitBox_to_npc (pRend, aperture)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+/* out */
+ ddPC_NPC_HitVolume *aperture;
+{
+/* calls */
+ void miTransformPoint();
+
+/* Local variable definitions */
+ miDDContext *pDDC = (miDDContext *)(pRend->pDDContext);
+ ddCoord4D DC_Min, DC_Max, NPC_Min, NPC_Max;
+ ddFLOAT inv_xform[4][4];
+ ddPC_DC_HitBox dcHitBox;
+
+ /* Get the DC pick aperture first */
+
+ dcHitBox = pDDC->Static.pick.input_rec.dc_hit_box;
+
+ /* Figure out the square aperture centered around the DC_HitBox */
+ /* position and sides along X and Y equal to twice the distance */
+ /* specified in the DC_HitBox. */
+
+ DC_Min.x = (ddFLOAT)(dcHitBox.position.x - dcHitBox.distance);
+ DC_Min.y = (ddFLOAT)(dcHitBox.position.y - dcHitBox.distance);
+ DC_Min.z = 0.0; /* This is a DONT CARE value */
+ DC_Min.w = 1.0;
+ DC_Max.x = (ddFLOAT)(dcHitBox.position.x + dcHitBox.distance);
+ DC_Max.y = (ddFLOAT)(dcHitBox.position.y + dcHitBox.distance);
+ DC_Max.z = 0.0; /* This is a DONT CARE value */
+ DC_Max.w = 1.0;
+
+ /* Now get the inverse viewport transform to transform the DC_HitBox */
+ /* into NPC_HitVolume. */
+
+ memcpy( (char *)inv_xform, (char *)pDDC->Static.misc.inv_vpt_xform,
+ 16*sizeof(ddFLOAT));
+
+ /* Compute the corners of the DC_HitBox in NPC */
+
+ miTransformPoint (&DC_Min, inv_xform, &NPC_Min);
+ miTransformPoint (&DC_Max, inv_xform, &NPC_Max);
+
+ /* Use the z coordinates of the current NPC subvolume in use to */
+ /* set up the DC aperture as an equivalent NPC sub-volume. */
+
+ aperture->minval.x = NPC_Min.x;
+ aperture->minval.y = NPC_Min.y;
+ aperture->minval.z = pRend->viewport.minval.z;
+ aperture->maxval.x = NPC_Max.x;
+ aperture->maxval.y = NPC_Max.y;
+ aperture->maxval.z = pRend->viewport.maxval.z;
+}
+
+
+/*
+ * Function Name: ClipNPCPoint4D
+ *
+ * Purpose: Dtermine if the 4D NPC point is within the current NPC
+ * sub-volume and set the outcode accordingly.
+ * Return:
+ * outcode to indicate whether the 4D point is in or out.
+ */
+static ddpex2rtn
+ClipNPCPoint4D (pRend, in_pt, oc)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ ddCoord4D *in_pt;
+/* out */
+ ddUSHORT *oc;
+{
+/* Local variables */
+ ddCoord3D npc_pt;
+ ddNpcSubvolume *cliplimits;
+ int j;
+ ddUSHORT status;
+ miViewEntry *view_entry;
+ ddUSHORT cur_index;
+
+ /* Get the actual 3D point by dividing by w first */
+
+ npc_pt.x = (in_pt->x)/(in_pt->w);
+ npc_pt.y = (in_pt->y)/(in_pt->w);
+ npc_pt.z = (in_pt->z)/(in_pt->w);
+
+ /* Get the next defined view entry from the View LUT */
+
+ cur_index = ((miDDContext *)pRend->pDDContext)->Dynamic
+ ->pPCAttr->viewIndex;
+
+ if ((InquireLUTEntryAddress (PEXViewLUT, pRend->lut[PEXViewLUT],
+ cur_index, &status, (ddPointer *)&view_entry))
+ == PEXLookupTableError)
+ return (PEXLookupTableError);
+
+ /* Get the pointer to current NPC subvolume clip limits */
+
+ cliplimits = &(view_entry->entry.clipLimits);
+
+ *oc = 0; /* Initialize oc to NOT CLIPPED state */
+
+ /* Compare the npc_pt against these cliplimits and set the oc */
+
+ if (npc_pt.x < cliplimits->minval.x)
+ *oc |= MI_CLIP_LEFT;
+ else if (npc_pt.x > cliplimits->maxval.x)
+ *oc |= MI_CLIP_RIGHT;
+ if (npc_pt.y < cliplimits->minval.y)
+ *oc |= MI_CLIP_BOTTOM;
+ else if (npc_pt.y > cliplimits->maxval.y)
+ *oc |= MI_CLIP_TOP;
+ if (npc_pt.z < cliplimits->minval.z)
+ *oc |= MI_CLIP_FRONT;
+ else if (npc_pt.z > cliplimits->maxval.z)
+ *oc |= MI_CLIP_BACK;
+}
+
+
+/*++
+ |
+ | Function Name: miPickAnnoText2D
+ |
+ | Function Description:
+ | Handles the picking of Annotation text 2D ocs.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex2rtn
+miPickAnnoText2D(pRend, pExecuteOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pExecuteOC;
+/* out */
+{
+ /* local */
+ miAnnoText2DStruct *ddText = (miAnnoText2DStruct *)(pExecuteOC+1);
+ miTextElement text_el; /* text element */
+ ddUSHORT numEncodings = ddText->numEncodings;
+ ddCoord2D *pOrigin = ddText->pOrigin; /* string origin */
+ ddCoord2D *pOffset = ddText->pOffset;
+ pexMonoEncoding *pText = ddText->pText; /* text string */
+
+/* calls */
+ extern ddpex3rtn miTransform();
+ extern ddpex3rtn miClipPolyLines();
+ extern void miTransformPoint();
+
+/* Define required temporary variables */
+
+ ddPC_NPC_HitVolume aperture;
+ ddNpcSubvolume pv;
+ miViewEntry *view_entry;
+ ddViewEntry *view;
+ ddULONG numChars; /* Needed for xalloc */
+ pexMonoEncoding *pMono;
+ ddCoord2D align; /* alignment info */
+ ddFLOAT tc_to_npc_xform[4][4];
+ ddFLOAT buf_xform[4][4], buf1_xform[4][4];
+ ddFLOAT buf2_xform[4][4];
+ miDDContext *pDDC, *pddc;
+ ddFLOAT exp, tx, ty;
+ ddFLOAT ptx, pty, ptx_first, pty_first;
+ int i, j, k;
+ int count; /* Count of characters to be picked */
+ ddFLOAT ei0npc, ei1npc, ei3npc;
+ miCharPath *save_ptr;
+ miListHeader *cc_path, *clip_path;
+ listofddPoint *sp;
+ XID temp;
+ int status;
+ ddUSHORT aflag, LUTstatus;
+ ddCoord4D MC_Origin, CC_Origin, NPC_Origin;
+ ddUSHORT oc; /* Outcode for 4D point clipping */
+ ddUSHORT Pick_Flag, cur_index;
+
+ /* Get the DDContext handle for local use */
+
+ pddc = pDDC = (miDDContext *)pRend->pDDContext;
+
+ /* Transform and clip the text origin first to see if any picking */
+ /* needs to be done at all. If the NPC subvolume does not contain */
+ /* the origin, the annotation text is not picked. */
+
+ MC_Origin.x = pOrigin->x;
+ MC_Origin.y = pOrigin->y;
+ MC_Origin.z = 0.0;
+ MC_Origin.w = 1.0;
+
+ if (pDDC->Dynamic->pPCAttr->modelClip == PEXClip) {
+
+ ComputeMCVolume(pRend, pddc); /* Compute modelling coord version
+ of clipping volume */
+ CLIP_POINT4D(&MC_Origin, oc, MI_MCLIP);
+
+ if (oc) {
+ pDDC->Static.pick.status = PEXNoPick;
+ return (Success); /* origin model clipped out */
+ }
+ }
+
+ /* Get the current view index and the corresponding transforms */
+
+ cur_index = pDDC->Dynamic->pPCAttr->viewIndex;
+
+ if ((InquireLUTEntryAddress (PEXViewLUT, pRend->lut[PEXViewLUT],
+ cur_index, &LUTstatus, (ddPointer *)&view_entry))
+ == PEXLookupTableError)
+ return (PEXLookupTableError);
+
+ /* Compute the mc_to_npc for the current view */
+
+ miMatMult (pDDC->Dynamic->mc_to_npc_xform,
+ pDDC->Dynamic->mc_to_wc_xform,
+ view_entry->vom);
+
+ miTransformPoint (&MC_Origin, pDDC->Dynamic->mc_to_npc_xform,
+ &NPC_Origin);
+
+ if ((ClipNPCPoint4D (pRend, &NPC_Origin, &oc)) == PEXLookupTableError)
+ return (PEXLookupTableError);
+ if (oc) {
+ pDDC->Static.pick.status = PEXNoPick;
+ return (Success); /* Don't pick anything; origin clipped out */
+ }
+
+
+ /* Keep the NPC_Origin computed above for later use */
+
+ /* Get the pick aperture and convert into NPC, if required. */
+
+ if (pDDC->Static.pick.type == PEXPickDeviceDC_HitBox) {
+
+ /* Convert the dcHitBox into a NPCHitVolume */
+
+ convert_dcHitBox_to_npc (pRend, &aperture);
+ }
+ else {
+
+ /* Copy data straight from the NPC pick aperture input record */
+
+ aperture = pDDC->Static.pick.input_rec.npc_hit_volume;
+ }
+
+ /* Set the annotation text flag to one */
+
+ aflag = 1;
+
+ /* Determine the total number of characters in the ISTRING */
+
+ numChars = 0;
+ pMono = pText;
+ for (i=0; i<numEncodings; i++) {
+ int bytes = pMono->numChars * ((pMono->characterSetWidth == PEXCSByte) ?
+ sizeof(CARD8) : ((pMono->characterSetWidth == PEXCSShort) ?
+ sizeof(CARD16) : sizeof(CARD32)));
+ numChars += (ddULONG)pMono->numChars;
+ pMono = (pexMonoEncoding *) ((char *) (pMono + 1) +
+ bytes + PADDING (bytes));
+ }
+
+ if (numChars == 0)
+ {
+ pDDC->Static.pick.status = PEXNoPick;
+ return (Success);
+ }
+
+
+ /* Convert text string into required paths */
+
+ if ((status = atx_el_to_path (pRend, pDDC, numEncodings, pText,
+ numChars, &text_el, &align, &count)) != Success) {
+ return (status);
+ }
+
+ /* Compute the required Character Space to Modelling Space Transform */
+
+ text2_xform (pOrigin, pDDC->Static.attrs, &align, text_el.xform, aflag);
+
+ /* Set up the new composite transform first. Note that in the case */
+ /* of annotation text, only the text origin is transformed by the */
+ /* complete pipeline transform. The text itself is affected only by*/
+ /* the transformed origin in NPC, the NPC offset , npc_to_cc, and */
+ /* the workstation transform. */
+
+ /* Now compute the initial composite transform for the first char. */
+ /* The required transforms for characters are - text space to model */
+ /* space transform, transformation of the annotation text origin, if*/
+ /* any. Note the ABSENCE of npc to cc transform here because of the */
+ /* PICKING as opposed to rendering. */
+
+ /* Get the translation due to the transformation of the annotation */
+ /* text origin by mc_to_npc_xform into buf1_xform. */
+
+ memcpy( (char *)buf1_xform, (char *) ident4x4, 16 * sizeof(ddFLOAT));
+ buf1_xform[0][3] += NPC_Origin.x - MC_Origin.x;
+ buf1_xform[1][3] += NPC_Origin.y - MC_Origin.y;
+
+ miMatMult (buf2_xform, text_el.xform, buf1_xform);
+
+ /* Add the offset in NPC */
+
+ buf2_xform[0][3] += pOffset->x;
+ buf2_xform[1][3] += pOffset->y;
+
+ /* Pick the paths in text_el as polylines */
+
+ /* Get the current character expansion factor */
+
+ exp = ABS((ddFLOAT)pDDC->Static.attrs->charExpansion);
+
+ /* Save the pointer to the beginning of the character data */
+
+ save_ptr = text_el.paths;
+
+ Pick_Flag = 0; /* Initialize flag to indicate NO_PICK */
+
+ /* Get the current defined view entry from the View LUT */
+
+ view = &(view_entry->entry);
+
+ /* Compute the intersection of the pick aperture with the NPC */
+ /* sub-volume defined for the current view. */
+
+ if (compute_pick_volume (&aperture, view, pDDC, &pv)) {
+
+ /* We have NO intersection between the pick aperture */
+ /* and the NPC subvolume defined for the current view */
+
+ goto TextHit; /* NoPick, Skip everything else */
+ }
+
+ /* Get the transform to go from pick volume to CC - buf1_xform */
+
+ compute_pick_volume_xform (&pv, buf1_xform);
+
+ /* Do for all characters (paths) in the text_el */
+
+ /* Initialize the previous translation components */
+
+ ptx = pty = 0.0;
+
+ for (k=0; k<count; k++) { /* Pick characters one by one */
+
+ /* Check if the character is not renderable, for e.g., space */
+ /* char. If so just skip to next character in the ISTRING and*/
+ /* continue. */
+
+ if (!(text_el.paths->path->ddList)) {
+ ptx = (ddFLOAT)(((text_el.paths)->trans).x);
+ pty = (ddFLOAT)(((text_el.paths)->trans).y);
+ text_el.paths++;
+ continue;
+ }
+
+ /* Modify the composite transform by the previous translation */
+ /* and the current scaling in x realizing the char expansion */
+
+ tx = ptx;
+ ty = pty;
+
+ ptx = (ddFLOAT)(((text_el.paths)->trans).x);
+ pty = (ddFLOAT)(((text_el.paths)->trans).y);
+
+ /* Check to see if this is the very first character and the */
+ /* text path is Up or Down. If so, we need to modify tx by */
+ /* first character translation to align with the rest of the*/
+ /* characters in the string. */
+
+ if ((pDDC->Static.attrs->atextPath == PEXPathUp ||
+ pDDC->Static.attrs->atextPath == PEXPathDown) && k == 0)
+ tx += ptx;
+
+ /* NOTE THAT THE ABOVE COMPUTATION WILL ONLY WORK FOR THE */
+ /* FIRST CHARACTER IN THE STRING. ptx FOR ALL OTHERS WILL */
+ /* BE RELATIVE TO THE TEXT ORIGIN AND SO WILL NOT GIVE THE*/
+ /* REQUIRED EFFECTIVE CHARACTER WIDTH. HOWEVER, THIS IS */
+ /* NOT A PROBLEM HERE SINCE WE NEED THIS SPECIAL CASE ONLY*/
+ /* FOR THE FIRST CHARACTER. */
+ /* */
+ /* FURTHER, NOTE THAT ptx WILL BE NEGATIVE AND HENCE USE */
+ /* OF += */
+
+ if (k == 0) {
+ ptx_first = ptx; /* Get the first character translation */
+
+ /* Adjust the translation by character spacing factor to*/
+ /* get just the character width. */
+
+ ptx_first += (pDDC->Static.attrs->charSpacing) *
+ FONT_COORD_HEIGHT;
+
+ pty_first = pty; /* Save first character height */
+
+ /* Adjust the translation by character spacing factor to*/
+ /* get just the character height. */
+
+ pty_first += (pDDC->Static.attrs->charSpacing) *
+ FONT_COORD_HEIGHT;
+ }
+
+ /* Check to see if the text path is Left. If so, we need */
+ /* to modify tx by the first character width so as to start*/
+ /* the string to the left of the text origin. */
+
+ if (pDDC->Static.attrs->atextPath == PEXPathLeft)
+ tx += ptx_first;
+
+ /* Buffer the tc_to_npc_xform first */
+
+ memcpy( (char *)tc_to_npc_xform, (char *)buf2_xform,16*sizeof(ddFLOAT));
+
+ /* Apply the per character translation and scaling by */
+ /* directly modifying the concerned matrix elements. */
+
+ for (i=0; i<4; ++i) {
+ /* Buffer the element values */
+ ei0npc = tc_to_npc_xform[i][0];
+ ei1npc = tc_to_npc_xform[i][1];
+ ei3npc = tc_to_npc_xform[i][3];
+ /* Modify the transform */
+ tc_to_npc_xform[i][0] = exp * ei0npc;
+ tc_to_npc_xform[i][3] = tx * ei0npc + ty * ei1npc + ei3npc;
+ }
+
+ /* Get buf_xform = (tc_to_npc_xform * buf1_xform) */
+
+ miMatMult (buf_xform, tc_to_npc_xform, buf1_xform);
+
+ /* Transform and clip the paths corresponding to current */
+ /* character. */
+
+ if (status = miTransform(pDDC, text_el.paths->path, &cc_path,
+ buf_xform,
+ NULL4x4,
+ DD_HOMOGENOUS_POINT))
+ return (status);
+
+ /* Now pass the paths through the line clipper to see if */
+ /* it lies within the pick aperture. If anything remains,*/
+ /* then return a PICK. Otherwise, return a NO_PICK. */
+
+ if (status = miClipPolyLines (pDDC, cc_path, &clip_path,
+ MI_VCLIP)) {
+
+ /* BadAlloc, or NOT 4D points */
+
+ return (status);
+ }
+ else {
+ /* Check if anything is remaining. If so, the pick volume */
+ /* intersects the text string. If not, this char has been */
+ /* clipped out. Accordingly, update the Pick_Flag. */
+
+ if (clip_path->numLists > 0) {
+ Pick_Flag = 1;
+ goto TextHit;
+ }
+ }
+
+ /* Update the pointer to next character */
+
+ text_el.paths++;
+
+ } /* Loop for all characters in the text string */
+
+ TextHit:
+
+ if (Pick_Flag)
+
+ /* Update the ddContext pick status to PICK */
+
+ pDDC->Static.pick.status = PEXOk;
+ else
+ /* Update the ddContext pick status to NO_PICK */
+
+ pDDC->Static.pick.status = PEXNoPick;
+
+ /* Free up space allocated for text stroke data */
+
+ xfree ((char *)save_ptr);
+
+ return (Success);
+}
+
+
+/*++
+ |
+ | Function Name: miPickAnnoText3D
+ |
+ | Function Description:
+ | Handles the picking of Annotation text 3D ocs.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex2rtn
+miPickAnnoText3D(pRend, pExecuteOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pExecuteOC;
+/* out */
+{
+ /* local */
+ miAnnoTextStruct *ddText = (miAnnoTextStruct *)(pExecuteOC+1);
+ miTextElement text_el; /* text element */
+ ddUSHORT numEncodings = ddText->numEncodings;
+ ddCoord3D *pOrigin = ddText->pOrigin; /* string origin */
+ ddCoord3D *pOffset = ddText->pOffset;
+ pexMonoEncoding *pText = ddText->pText; /* text string */
+
+/* calls */
+ extern ddpex3rtn miTransform();
+ extern ddpex3rtn miClipPolyLines();
+ extern void miTransformPoint();
+
+/* Define required temporary variables */
+
+ ddPC_NPC_HitVolume aperture;
+ ddNpcSubvolume pv;
+ miViewEntry *view_entry;
+ ddViewEntry *view;
+ ddULONG numChars; /* Needed for xalloc */
+ pexMonoEncoding *pMono;
+ ddCoord2D align; /* alignment info */
+ ddFLOAT tc_to_npc_xform[4][4];
+ ddFLOAT buf_xform[4][4], buf1_xform[4][4];
+ ddFLOAT buf2_xform[4][4];
+ miDDContext *pDDC, *pddc;
+ ddFLOAT exp, tx, ty;
+ ddFLOAT ptx, pty, ptx_first, pty_first;
+ int i, j, k;
+ int count; /* Count of characters to be picked */
+ ddFLOAT ei0npc, ei1npc, ei3npc;
+ miCharPath *save_ptr;
+ miListHeader *cc_path, *clip_path;
+ listofddPoint *sp;
+ XID temp;
+ int status;
+ ddUSHORT aflag, LUTstatus;
+ static ddVector3D Directions[2] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0};
+ ddCoord3D *pDirections = (ddCoord3D *)Directions;
+ ddCoord4D MC_Origin, CC_Origin, NPC_Origin;
+ ddUSHORT oc; /* Outcode for 4D point clipping */
+ ddUSHORT Pick_Flag, cur_index;
+
+ /* Get the DDContext handle for local use */
+
+ pddc = pDDC = (miDDContext *)pRend->pDDContext;
+
+ /* Transform and clip the text origin first to see if any picking */
+ /* needs to be done at all. If the NPC subvolume does not contain */
+ /* the origin, the annotation text is not picked. */
+
+ MC_Origin.x = pOrigin->x;
+ MC_Origin.y = pOrigin->y;
+ MC_Origin.z = pOrigin->z;
+ MC_Origin.w = 1.0;
+
+ if (pDDC->Dynamic->pPCAttr->modelClip == PEXClip) {
+
+ ComputeMCVolume(pRend, pddc); /* Compute modelling coord version
+ of clipping volume */
+ CLIP_POINT4D(&MC_Origin, oc, MI_MCLIP);
+
+ if (oc) {
+ pDDC->Static.pick.status = PEXNoPick;
+ return (Success); /* origin model clipped out */
+ }
+ }
+
+ /* Get the current view index and the corresponding transforms */
+
+ cur_index = pDDC->Dynamic->pPCAttr->viewIndex;
+
+ if ((InquireLUTEntryAddress (PEXViewLUT, pRend->lut[PEXViewLUT],
+ cur_index, &LUTstatus, (ddPointer *)&view_entry))
+ == PEXLookupTableError)
+ return (PEXLookupTableError);
+
+ /* Compute the mc_to_npc for the current view */
+
+ miMatMult (pDDC->Dynamic->mc_to_npc_xform,
+ pDDC->Dynamic->mc_to_wc_xform,
+ view_entry->vom);
+
+ miTransformPoint (&MC_Origin, pDDC->Dynamic->mc_to_npc_xform,
+ &NPC_Origin);
+
+ if ((ClipNPCPoint4D (pRend, &NPC_Origin, &oc)) == PEXLookupTableError)
+ return (PEXLookupTableError);
+ if (oc) {
+ pDDC->Static.pick.status = PEXNoPick;
+ return (Success); /* Don't pick anything; origin clipped out */
+ }
+
+ /* Keep the NPC_Origin computed above for later use */
+
+ /* Get the pick aperture and convert into NPC, if required. */
+
+ if (pDDC->Static.pick.type == PEXPickDeviceDC_HitBox) {
+
+ /* Convert the dcHitBox into a NPCHitVolume */
+
+ convert_dcHitBox_to_npc (pRend, &aperture);
+ }
+ else {
+
+ /* Copy data straight from the NPC pick aperture input record */
+
+ aperture = pDDC->Static.pick.input_rec.npc_hit_volume;
+ }
+
+ /* Set the annotation text flag to one */
+
+ aflag = 1;
+
+ /* Determine the total number of characters in the ISTRING */
+
+ numChars = 0;
+ pMono = pText;
+ for (i=0; i<numEncodings; i++) {
+ int bytes = pMono->numChars * ((pMono->characterSetWidth == PEXCSByte) ?
+ sizeof(CARD8) : ((pMono->characterSetWidth == PEXCSShort) ?
+ sizeof(CARD16) : sizeof(CARD32)));
+ numChars += (ddULONG)pMono->numChars;
+ pMono = (pexMonoEncoding *) ((char *) (pMono + 1) +
+ bytes + PADDING (bytes));
+ }
+
+ if (numChars == 0)
+ {
+ pDDC->Static.pick.status = PEXNoPick;
+ return (Success);
+ }
+
+
+ /* Convert text string into required paths */
+
+ if ((status = atx_el_to_path (pRend, pDDC, numEncodings, pText,
+ numChars, &text_el, &align, &count)) != Success) {
+ return (status);
+ }
+
+ /* Compute the required Character Space to Modelling Space Transform */
+
+ text3_xform (pOrigin,pDirections, (pDirections+1),
+ pDDC->Static.attrs, &align, text_el.xform, aflag);
+
+ /* Set up the new composite transform first. Note that in the case */
+ /* of annotation text, only the text origin is transformed by the */
+ /* complete pipeline transform. The text itself is affected only by*/
+ /* the transformed origin in NPC, the NPC offset , npc_to_cc, and */
+ /* the workstation transform. */
+
+ /* Now compute the initial composite transform for the first char. */
+ /* The required transforms for characters are - text space to model */
+ /* space transform, transformation of the annotation text origin, if*/
+ /* any. Note the ABSENCE of npc to cc transform here because of the */
+ /* PICKING as opposed to rendering. */
+
+ /* Get the translation due to the transformation of the annotation */
+ /* text origin by mc_to_npc_xform into buf1_xform. */
+
+ memcpy( (char *)buf1_xform, (char *) ident4x4, 16 * sizeof(ddFLOAT));
+ buf1_xform[0][3] += NPC_Origin.x - MC_Origin.x;
+ buf1_xform[1][3] += NPC_Origin.y - MC_Origin.y;
+ buf1_xform[2][3] += NPC_Origin.z - MC_Origin.z;
+
+ miMatMult (buf2_xform, text_el.xform, buf1_xform);
+
+ /* Add the offset in NPC */
+
+ buf2_xform[0][3] += pOffset->x;
+ buf2_xform[1][3] += pOffset->y;
+ buf2_xform[2][3] += pOffset->z;
+
+ /* Pick the paths in text_el as polylines */
+
+ /* Get the current character expansion factor */
+
+ exp = ABS((ddFLOAT)pDDC->Static.attrs->charExpansion);
+
+ /* Save the pointer to the beginning of the character data */
+
+ save_ptr = text_el.paths;
+
+ Pick_Flag = 0; /* Initialize flag to indicate NO_PICK */
+
+ /* Get the current defined view entry from the View LUT */
+
+ view = &(view_entry->entry);
+
+ /* Compute the intersection of the pick aperture with the NPC */
+ /* sub-volume defined for the current view. */
+
+ if (compute_pick_volume (&aperture, view, pDDC, &pv)) {
+
+ /* We have NO intersection between the pick aperture */
+ /* and the NPC subvolume defined for the current view */
+
+ goto TextHit; /* NoPick, Skip everything else */
+ }
+
+ /* Get the transform to go from pick volume to CC - buf1_xform */
+
+ compute_pick_volume_xform (&pv, buf1_xform);
+
+ /* Do for all characters (paths) in the text_el */
+
+ /* Initialize the previous translation components */
+
+ ptx = pty = 0.0;
+
+ for (k=0; k<count; k++) { /* Pick characters one by one */
+
+ /* Check if the character is not renderable, for e.g., space */
+ /* char. If so just skip to next character in the ISTRING and*/
+ /* continue. */
+
+ if (!(text_el.paths->path->ddList)) {
+ ptx = (ddFLOAT)(((text_el.paths)->trans).x);
+ pty = (ddFLOAT)(((text_el.paths)->trans).y);
+ text_el.paths++;
+ continue;
+ }
+
+ /* Modify the composite transform by the previous translation */
+ /* and the current scaling in x realizing the char expansion */
+
+ tx = ptx;
+ ty = pty;
+
+ ptx = (ddFLOAT)(((text_el.paths)->trans).x);
+ pty = (ddFLOAT)(((text_el.paths)->trans).y);
+
+ /* Check to see if this is the very first character and the */
+ /* text path is Up or Down. If so, we need to modify tx by */
+ /* first character translation to align with the rest of the*/
+ /* characters in the string. */
+
+ if ((pDDC->Static.attrs->atextPath == PEXPathUp ||
+ pDDC->Static.attrs->atextPath == PEXPathDown) && k == 0)
+ tx += ptx;
+
+ /* NOTE THAT THE ABOVE COMPUTATION WILL ONLY WORK FOR THE */
+ /* FIRST CHARACTER IN THE STRING. ptx FOR ALL OTHERS WILL */
+ /* BE RELATIVE TO THE TEXT ORIGIN AND SO WILL NOT GIVE THE*/
+ /* REQUIRED EFFECTIVE CHARACTER WIDTH. HOWEVER, THIS IS */
+ /* NOT A PROBLEM HERE SINCE WE NEED THIS SPECIAL CASE ONLY*/
+ /* FOR THE FIRST CHARACTER. */
+ /* */
+ /* FURTHER, NOTE THAT ptx WILL BE NEGATIVE AND HENCE USE */
+ /* OF += */
+
+ if (k == 0) {
+ ptx_first = ptx; /* Get the first character translation */
+
+ /* Adjust the translation by character spacing factor to*/
+ /* get just the character width. */
+
+ ptx_first += (pDDC->Static.attrs->charSpacing) *
+ FONT_COORD_HEIGHT;
+
+ pty_first = pty; /* Save first character height */
+
+ /* Adjust the translation by character spacing factor to*/
+ /* get just the character height. */
+
+ pty_first += (pDDC->Static.attrs->charSpacing) *
+ FONT_COORD_HEIGHT;
+ }
+
+ /* Check to see if the text path is Left. If so, we need */
+ /* to modify tx by the first character width so as to start*/
+ /* the string to the left of the text origin. */
+
+ if (pDDC->Static.attrs->atextPath == PEXPathLeft)
+ tx += ptx_first;
+
+ /* Buffer the tc_to_npc_xform first */
+
+ memcpy( (char *)tc_to_npc_xform, (char *)buf2_xform,16*sizeof(ddFLOAT));
+
+ /* Apply the per character translation and scaling by */
+ /* directly modifying the concerned matrix elements. */
+
+ for (i=0; i<4; ++i) {
+ /* Buffer the element values */
+ ei0npc = tc_to_npc_xform[i][0];
+ ei1npc = tc_to_npc_xform[i][1];
+ ei3npc = tc_to_npc_xform[i][3];
+ /* Modify the transform */
+ tc_to_npc_xform[i][0] = exp * ei0npc;
+ tc_to_npc_xform[i][3] = tx * ei0npc + ty * ei1npc + ei3npc;
+ }
+
+ /* Get buf_xform = (tc_to_npc_xform * buf1_xform) */
+
+ miMatMult (buf_xform, tc_to_npc_xform, buf1_xform);
+
+ /* Transform and clip the paths corresponding to current */
+ /* character. */
+
+ if (status = miTransform(pDDC, text_el.paths->path, &cc_path,
+ buf_xform,
+ NULL4x4,
+ DD_HOMOGENOUS_POINT))
+ return (status);
+
+ /* Now pass the paths through the line clipper to see if */
+ /* it lies within the pick aperture. If anything remains,*/
+ /* then return a PICK. Otherwise, return a NO_PICK. */
+
+ if (status = miClipPolyLines (pDDC, cc_path, &clip_path,
+ MI_VCLIP)) {
+
+ /* BadAlloc, or NOT 4D points */
+
+ return (status);
+ }
+ else {
+ /* Check if anything is remaining. If so, the pick volume */
+ /* intersects the text string. If not, this char has been */
+ /* clipped out. Accordingly, update the Pick_Flag. */
+
+ if (clip_path->numLists > 0) {
+ Pick_Flag = 1;
+ goto TextHit;
+ }
+ }
+
+ /* Update the pointer to next character */
+
+ text_el.paths++;
+
+ } /* Loop for all characters in the text string */
+
+ TextHit:
+
+ if (Pick_Flag)
+
+ /* Update the ddContext pick status to PICK */
+
+ pDDC->Static.pick.status = PEXOk;
+ else
+ /* Update the ddContext pick status to NO_PICK */
+
+ pDDC->Static.pick.status = PEXNoPick;
+
+ /* Free up space allocated for text stroke data */
+
+ xfree ((char *)save_ptr);
+
+ return (Success);
+}
+
+
+/*++
+ |
+ | Function Name: miPickPrimitives
+ |
+ | Function Description:
+ | Handles the picking of most primitives in a generic fashion.
+ |
+ | Note(s):
+ |
+ ++*/
+
+ddpex2rtn
+miPickPrimitives(pRend, pExecuteOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pExecuteOC;
+{
+/* calls */
+
+/* Local variable definitions */
+ miDDContext *pDDC = (miDDContext *)(pRend->pDDContext);
+ ddPC_NPC_HitVolume aperture;
+ ddNpcSubvolume pv;
+ miViewEntry *view_entry;
+ ddViewEntry *view;
+ ddFLOAT buf1_xform[4][4];
+ ddUSHORT cur_index;
+ ddUSHORT status;
+
+ /* Get the pick aperture and convert into NPC, if required. */
+
+ if (pDDC->Static.pick.type == PEXPickDeviceDC_HitBox) {
+
+ /* Convert the dcHitBox into a NPCHitVolume */
+
+ convert_dcHitBox_to_npc (pRend, &aperture);
+
+ }
+ else {
+
+ /* Copy data straight from the NPC pick aperture input record */
+
+ aperture = pDDC->Static.pick.input_rec.npc_hit_volume;
+ }
+
+ /* Clear out the cc_to_dc_xform, since we will not be going to DC */
+
+ memcpy( (char *) pDDC->Dynamic->cc_to_dc_xform,
+ (char *) ident4x4, 16 * sizeof(ddFLOAT));
+
+ /* Get the current defined view entry from the View LUT */
+
+ cur_index = pDDC->Dynamic->pPCAttr->viewIndex;
+
+ if ((InquireLUTEntryAddress (PEXViewLUT, pRend->lut[PEXViewLUT],
+ cur_index, &status, (ddPointer *)&view_entry))
+ == PEXLookupTableError)
+ return (PEXLookupTableError);
+
+ view = &(view_entry->entry);
+
+ /* Compute the intersection of the pick aperture with the NPC */
+ /* sub-volume defined for the current view. */
+
+ if (compute_pick_volume (&aperture, view, pDDC, &pv)) {
+
+ /* We have NO intersection between the pick aperture */
+ /* and the NPC subvolume defined for the current view */
+
+ return (Success); /* NoPick, Just return */
+ }
+
+ /* Get the transform to go from pick volume to CC - buf1_xform */
+
+ compute_pick_volume_xform (&pv, buf1_xform);
+
+ /* Compute the mc_to_npc for the current view */
+
+ miMatMult (pDDC->Dynamic->mc_to_npc_xform,
+ pDDC->Dynamic->mc_to_wc_xform,
+ view_entry->vom);
+
+ /* Get wc_to_cc_xform = (wc_to_npc_xform * buf1_xform) */
+ /* Note that wc_to_npc_xform == view_entry->vom. */
+
+ miMatMult (pDDC->Dynamic->wc_to_cc_xform,
+ view_entry->vom, buf1_xform);
+
+ /* Get mc_to_cc_xform = (mc_to_npc_xform * buf1_xform) */
+
+ miMatMult (pDDC->Dynamic->mc_to_cc_xform,
+ pDDC->Dynamic->mc_to_npc_xform, buf1_xform);
+
+ /* Now, call the level 2 rendering function to transform and */
+ /* clip the primitive. Note that the level 1 function vector */
+ /* now has PICKING routines instead of rendering routines. If*/
+ /* a pick is detected the GLOBAL PICK FLAG will have been up-*/
+ /* dated. Check this flag to determine if anything was indeed*/
+ /* picked by the level 1 picking routines. */
+
+ InitExecuteOCTable[(int)(pExecuteOC->elementType)]
+ (pRend, pExecuteOC);
+
+ /* If successful PICK, just return */
+
+ if (pDDC->Static.pick.status == PEXOk) ;; /* For debug */
+
+ return (Success);
+}
+
+
+/*++
+ |
+ | Function Name: miTestPickGdp3d
+ |
+ | Function Description:
+ | Provides the dummy test routine for picking 3d Gdps.
+ | with data OCs.
+ |
+ | Note(s):
+ |
+ ++*/
+
+ddpex2rtn
+miTestPickGdp3d(pRend, pExecuteOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pExecuteOC;
+/* out */
+{
+ ErrorF ("miTestPickGdp3d\n");
+ return (Success);
+}
+
+
+/*++
+ |
+ | Function Name: miTestPickGdp2d
+ |
+ | Function Description:
+ | Provides the dummy test routine for picking 2d Gdps.
+ | with data OCs.
+ |
+ | Note(s):
+ |
+ ++*/
+
+ddpex2rtn
+miTestPickGdp2d(pRend, pExecuteOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pExecuteOC;
+/* out */
+{
+ ErrorF ("miTestPickGdp2d\n");
+ return (Success);
+}
+
+
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level2/miPolyLine.c b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miPolyLine.c
new file mode 100644
index 000000000..7b8d6ff5e
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miPolyLine.c
@@ -0,0 +1,530 @@
+/* $TOG: miPolyLine.c /main/6 1998/02/10 12:42:19 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level2/miPolyLine.c,v 3.5 1998/10/04 09:34:25 dawes Exp $ */
+
+#include "mipex.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "ddpex3.h"
+#include "PEXErr.h"
+#include "miStruct.h"
+#include "PEXprotost.h"
+#include "miRender.h"
+#include "gcstruct.h"
+#include "ddpex2.h"
+#include "miClip.h"
+#include "pexos.h"
+
+
+/*++
+ |
+ | Function Name: miPolyLines
+ |
+ | Function Description:
+ | Handles the Polyline 3D, Polyline 2D, Polyline set 3D with data ocs.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+miPolyLines(pRend, pExecuteOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pExecuteOC;
+{
+/* calls */
+ ddpex3rtn miTransform();
+ ddpex3rtn miConvertVertexColors();
+ ddpex3rtn miClipPolyLines();
+ ddpex3rtn miRenderPolyLine();
+
+/* Local variable definitions */
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ miPolylineStruct *ddPoly = (miPolylineStruct *)(pExecuteOC+1);
+ miListHeader *input_list = (miListHeader *)ddPoly;
+ miListHeader *color_list,
+ *mc_list,
+ *mc_clist,
+ *cc_list,
+ *clip_list,
+ *dcue_list,
+ *dc_list;
+ ddpex3rtn status;
+ ddPointType out_type;
+ ddUSHORT clip_mode; /* view or model clipping */
+
+ /*
+ * Convert per-vertex colors to rendering color model.
+ * Note that this implementation only supports rgb float.
+ */
+
+ if (DD_IsVertColour(input_list->type)) {
+ if (status = miConvertVertexColors(pRend,
+ input_list, PEXRdrColourModelRGB,
+ &color_list))
+ return (status);
+ } else {
+ color_list = input_list;
+ }
+
+ /* Check for Model clipping */
+
+ if (pddc->Dynamic->pPCAttr->modelClip == PEXClip) {
+
+ ComputeMCVolume(pRend, pddc); /* Compute modelling coord version
+ of clipping volume */
+ clip_mode = MI_MCLIP;
+
+
+ /* Tranform points to 4D for clipping */
+ out_type = color_list->type;
+ if (status = miTransform(pddc, color_list, &mc_clist,
+ ident4x4,
+ ident4x4,
+ DD_SetVert4D(out_type)))
+ return (status);
+
+
+ if (status = miClipPolyLines(pddc, mc_clist, &mc_list, clip_mode))
+ return(status);
+
+ /* if nothing left, return early */
+ if (mc_list->numLists <= 0) return(Success);
+
+
+ } else mc_list = color_list;
+
+ clip_mode = MI_VCLIP;
+
+
+ /* Transform and clip the paths created */
+ out_type = mc_list->type;
+ if (status = miTransform(pddc, mc_list, &cc_list,
+ pddc->Dynamic->mc_to_cc_xform,
+ NULL4x4,
+ DD_SetVert4D(out_type)))
+ return (status);
+
+ if (status = miClipPolyLines(pddc, cc_list, &clip_list, clip_mode))
+ return(status);
+
+ /* if nothing left, return early */
+ if (clip_list->numLists <= 0) return(Success);
+
+ /* DEPTH CUEING */
+ if (pddc->Dynamic->pPCAttr->depthCueIndex) {
+ miDepthCuePLine(pRend, clip_list, &dcue_list);
+ clip_list = dcue_list;
+ }
+
+ /* Transform to DC coordinates */
+ out_type = clip_list->type;
+ DD_SetVert2D(out_type);
+ DD_SetVertShort(out_type);
+ if (status = miTransform(pddc, clip_list, &dc_list,
+ pddc->Dynamic->cc_to_dc_xform,
+ NULL4x4,
+ out_type))
+ return (status);
+
+
+ return (pddc->Static.RenderProcs[POLYLINE_RENDER_TABLE_INDEX](pRend,
+ pddc,
+ dc_list));
+}
+
+/*++
+ |
+ | Function Name: miClipPolyLines
+ |
+ | Function Description:
+ | Handles the Polyline 3D, Polyline 2D, Polyline set 3D with data ocs.
+ |
+ | Note(s):
+ | This routine modifies both the input and output
+ | data structures - the input had better not
+ | be pointing at the CSS data store!
+ |
+ --*/
+
+ddpex3rtn
+miClipPolyLines(pddc, vinput, voutput, clip_mode)
+/* in */
+ miDDContext *pddc;
+ miListHeader *vinput;
+ miListHeader **voutput;
+ ddUSHORT clip_mode; /* view or model clipping */
+{
+
+/* uses */
+ ddPointUnion in_ptP, in_ptQ;
+ ddPointUnion out_pt;
+ float t_ptP, t_ptQ;
+ miListHeader *input, *output, *list1, *list2;
+ listofddPoint *pddilist;
+ listofddPoint *pddolist;
+ int num_lists;
+ int vert_count;
+ int point_size, num_planes;
+ int current_plane,j,k,
+ clip_code, pts_in_list;
+ ddHalfSpace *MC_HSpace;
+ ddUSHORT current_clip;
+ char new_list;
+
+
+ /* Vertex data must be homogeneous for view clipping */
+ if ((clip_mode == MI_VCLIP) && !(DD_IsVert4D(vinput->type)))
+ return(1);
+
+
+ /* Allocate an initial number of headers */
+ list1 = MI_NEXTTEMPDATALIST(pddc);
+ MI_ALLOCLISTHEADER(list1, MI_ROUND_LISTHEADERCOUNT(vinput->numLists));
+ if (!list1->ddList) return(BadAlloc);
+ list1->type = vinput->type;
+ list1->flags = vinput->flags;
+ input = vinput;
+
+ list2 = MI_NEXTTEMPDATALIST(pddc);
+ MI_ALLOCLISTHEADER(list2, MI_ROUND_LISTHEADERCOUNT(vinput->numLists));
+ if (!list2->ddList) return(BadAlloc);
+ list2->type = vinput->type;
+ list2->flags = vinput->flags;
+
+ *voutput = output = list2;
+
+ DD_VertPointSize(vinput->type, point_size);
+
+ num_lists = 0;
+
+ /* Now, clip each list */
+
+ /* Get point size so that this works for all point types */
+ DD_VertPointSize(vinput->type, point_size);
+
+ /*
+ * Each list is now clipped in turn against each (enabled) boundary.
+ */
+
+
+ if (clip_mode == MI_MCLIP) {
+ num_planes = pddc->Static.misc.ms_MCV->numObj;
+ MC_HSpace = (ddHalfSpace *)(pddc->Static.misc.ms_MCV->pList);
+ }
+
+ else num_planes = 6; /* view clipping to a cube */
+
+ for (current_plane = 0; current_plane < num_planes; current_plane++) {
+ current_clip = 1 << current_plane;
+
+ num_lists = 0; /* Restart list counter each pass */
+
+ for (j = 0, pddilist = input->ddList, pddolist = output->ddList,
+ output->numLists = 0, num_lists = 0, new_list = 1;
+ j < input->numLists; j++) {
+
+
+ /* Don't process if no points */
+ if ((vert_count = pddilist->numPoints) <= 0) {
+ pddilist++;
+ continue;
+ }
+
+ /*
+ * Insure sufficient room for each vertex.
+ * Note that twice the vertex count is an upper-bound for
+ * a clipped polygon (although there is probably a "tighter fit").
+ */
+ MI_ALLOCLISTOFDDPOINT(pddolist, 2*vert_count, point_size);
+ if (!(out_pt.ptr = (char *)pddolist->pts.ptr)) return(BadAlloc);
+ pts_in_list = 0;
+ clip_code = 0;
+
+ /* Aquire two points */
+ /* and generate clip code */
+ in_ptP.ptr = pddilist->pts.ptr;
+ COMPUTE_CLIP_PARAMS(in_ptP,t_ptP,0,clip_mode,
+ current_clip,MC_HSpace,clip_code);
+ /*
+ * Initialize the output array. If the first point is
+ * inside the bounds, load it.
+ */
+
+ if(!(clip_code)) {
+ COPY_POINT(in_ptP, out_pt, point_size);
+ ++pts_in_list;
+ out_pt.ptr += point_size;
+ }
+
+ in_ptQ.ptr = in_ptP.ptr + point_size;
+
+ for (k = 1; k < pddilist->numPoints; k++){
+
+ COMPUTE_CLIP_PARAMS(in_ptQ, t_ptQ, 1, clip_mode,
+ current_clip,MC_HSpace,clip_code);
+
+ switch(clip_code) {
+ case 0: /* both P and Q are in bounds */
+ COPY_POINT(in_ptQ, out_pt, point_size);
+ out_pt.ptr += point_size;
+ ++pts_in_list;
+ break;
+
+ case 1: /* P is out, Q is in */
+ CLIP_AND_COPY(input->type, in_ptP, t_ptP,
+ in_ptQ, t_ptQ, out_pt);
+ out_pt.ptr += point_size;
+ COPY_POINT(in_ptQ, out_pt, point_size);
+ out_pt.ptr += point_size;
+ pts_in_list = 2;
+ break;
+
+ case 2: /* P is in, Q is out */
+ CLIP_AND_COPY(input->type, in_ptQ, t_ptQ,
+ in_ptP, t_ptP, out_pt);
+ out_pt.ptr += point_size;
+ ++pts_in_list;
+ pddolist->numPoints = pts_in_list;
+ pddolist++;
+ output->numLists++;
+ num_lists++;
+ MI_ALLOCLISTHEADER(output,
+ MI_ROUND_LISTHEADERCOUNT(output->numLists));
+ /* skip to next output list */
+ pddolist = output->ddList + num_lists;
+
+ /* Insure sufficient room for remaining verts
+ and degenerate points */
+ MI_ALLOCLISTOFDDPOINT(pddolist,
+ ((pddilist->numPoints - k)+1),
+ point_size);
+
+ out_pt.ptr = pddolist->pts.ptr;
+ if (!out_pt.ptr) return(BadAlloc);
+ pts_in_list = 0; /*start a new list*/
+ break;
+
+ case 3: /* both are out; do nothing */
+ break;
+
+ }
+ in_ptP.ptr = in_ptQ.ptr;
+ t_ptP = t_ptQ;
+ in_ptQ.ptr += point_size;
+ clip_code >>= 1;
+ }
+ if (pts_in_list > 1) {
+ pddolist->numPoints = pts_in_list;
+ pddolist++;
+ num_lists++;
+ } /* else use the same output list */
+
+ /* Now, skip to next input list */
+ pddilist++;
+ }
+
+
+
+ /* Complete initialization of output list header */
+ output->numLists = num_lists;
+
+ /* Use result of previous clip for input to next clip */
+ input = output;
+ if (output == list2)
+ output = list1;
+ else output = list2;
+
+ if (clip_mode == MI_MCLIP) MC_HSpace++;
+
+ } /* end of processing for all planes */
+
+ /* Current input list is last processed (clipped) list */
+ *voutput = input;
+
+ return (Success);
+
+}
+
+
+/*++
+ |
+ | DepthCuePLine(pRend, input_vert, output_vert)
+ |
+ | Applies depth cueing to the vertex colors in a data list
+ |
+ --*/
+ddpex3rtn
+miDepthCuePLine(pRend, input_vert, output_vert)
+ ddRendererPtr pRend; /* renderer handle */
+ miListHeader *input_vert; /* input vertex data */
+ miListHeader **output_vert; /* output vertex data */
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ miListHeader *out_vert;
+ listofddPoint *pddilist;
+ listofddPoint *pddolist;
+ ddPointUnion in_pt, out_pt;
+ ddRgbFloatColour *in_color;
+ int point_size, facet_size;
+ int numPoints;
+ int i,j,outpoint_size;
+ miColourEntry *pintcolour;
+ ddFLOAT pt_depth;
+ ddULONG colourindex;
+ ddColourSpecifier intcolour;
+ ddUSHORT status;
+ ddDepthCueEntry *dcue_entry;
+
+ /* look for empty list header */
+ if (input_vert->numLists == 0) return(Success);
+
+ /* validate CC version of Depth Cue information */
+ if (pddc->Static.misc.flags & CC_DCUEVERSION)
+ Compute_CC_Dcue(pRend, pddc);
+
+ /* check to make sure depth cuing is enabled */
+ if (pddc->Static.misc.cc_dcue_entry.mode == PEXOff) {
+ *output_vert = input_vert;
+ return(Success);
+ }
+
+ /* Else, depth cue! Use one of the pre-defined 4D list for output */
+ *output_vert = out_vert = MI_NEXTTEMPDATALIST(pddc);
+
+ /* Insure sufficient room for each header */
+ MI_ALLOCLISTHEADER(out_vert, input_vert->numLists)
+ if (!out_vert->ddList) return(BadAlloc);
+
+ out_vert->type = input_vert->type;
+ DD_SetVertRGBFLOAT(out_vert->type);
+ out_vert->numLists = input_vert->numLists;
+ out_vert->flags = input_vert->flags;
+
+ pddilist = input_vert->ddList;
+ pddolist = out_vert->ddList;
+ DD_VertPointSize(input_vert->type, point_size);
+
+ /* Get current line color if appropriate */
+ if (!(DD_IsVertColour(input_vert->type)) &&
+ (pddc->Static.attrs->lineColour.colourType
+ == PEXIndexedColour)) {
+ if ((InquireLUTEntryAddress (PEXColourLUT, pRend->lut[PEXColourLUT],
+ pddc->Static.attrs->lineColour.colour.indexed.index,
+ &status, (ddPointer *)&pintcolour)) == PEXLookupTableError)
+ return (PEXLookupTableError);
+ }
+
+ DD_VertPointSize(out_vert->type, outpoint_size);
+
+ for (i = 0; i < input_vert->numLists; i++) {
+
+ pddolist->numPoints = pddilist->numPoints;
+
+ MI_ALLOCLISTOFDDPOINT(pddolist,(pddilist->numPoints+1),
+ outpoint_size);
+ if (!(out_pt.ptr = pddolist->pts.ptr)) return(BadAlloc);
+ in_pt = pddilist->pts;
+
+ for (j = 0; j < pddilist->numPoints; j++)
+ {
+ /* First copy over coordinate data */
+ pt_depth = in_pt.p4Dpt->z;
+ *out_pt.p4Dpt = *in_pt.p4Dpt;
+ in_pt.p4Dpt++;
+ out_pt.p4Dpt++;
+
+ /*
+ * Next color
+ * Colour is derived first from the vertex, second from the
+ * from the current PC attributes.
+ */
+
+ if (DD_IsVertColour(input_vert->type)){
+ in_color = in_pt.pRgbFloatClr;
+ in_pt.pRgbFloatClr++;
+ }
+ else {
+ if (pddc->Static.attrs->lineColour.colourType
+ == PEXIndexedColour)
+ in_color = &pintcolour->entry.colour.rgbFloat;
+ else in_color =
+ &(pddc->Static.attrs->lineColour.colour.rgbFloat);
+ }
+
+ APPLY_DEPTH_CUEING(pddc->Static.misc.cc_dcue_entry,
+ pt_depth, in_color, out_pt.pRgbFloatClr)
+
+ out_pt.pRgbFloatClr++;
+
+ /*
+ * Next normals
+ * Colour is derived first from the vertex, second from the
+ * facet (note that we insured above that there were facet normals).
+ */
+
+ if DD_IsVertNormal(input_vert->type) {
+ *out_pt.pNormal = *in_pt.pNormal;
+ in_pt.pNormal++;
+ out_pt.pNormal++;
+ }
+
+ /* Next pass along edge info if there is any */
+ if (DD_IsVertEdge(out_vert->type)) {
+ *out_pt.pEdge = *in_pt.pEdge;
+ in_pt.pEdge++;
+ out_pt.pEdge++;
+ }
+
+
+ }
+
+ pddilist++;
+ pddolist++;
+ }
+
+ return(Success);
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level2/miQuadMesh.c b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miQuadMesh.c
new file mode 100644
index 000000000..7597cd9b6
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miQuadMesh.c
@@ -0,0 +1,265 @@
+/* $TOG: miQuadMesh.c /main/6 1998/02/10 12:42:23 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level2/miQuadMesh.c,v 3.6 1998/10/04 09:34:25 dawes Exp $ */
+
+#include "miLUT.h"
+#include "ddpex2.h"
+#include "ddpex3.h"
+#include "PEXErr.h"
+#include "miStruct.h"
+#include "PEXprotost.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "miRender.h"
+#include "gcstruct.h"
+#include "miClip.h"
+#include "pexos.h"
+
+
+/*++
+ |
+ | Function Name: miQuadMesh
+ |
+ | Function Description:
+ | Handles the Quad Mesh OC
+ |
+ | Note(s):This routine decomposes Quad Meshes to a series of triangle
+ | meshes for rendering
+ |
+ --*/
+
+ddpex3rtn
+miQuadMesh(pRend, pExecuteOC)
+/* in */
+ ddRendererPtr pRend;
+ miGenericStr *pExecuteOC;
+
+
+{
+
+/* Calls */
+ extern ocTableType InitExecuteOCTable[];
+
+/* Local variable definitions */
+ miQuadMeshStruct *ddQuad = (miQuadMeshStruct *)(pExecuteOC+1);
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+
+ miGenericStr *pGStr;
+ miTriangleStripStruct
+ *ddTri; /*pointer to temporary
+ |triangle strip structure
+ |for decomposed QuadMesh
+ |row of cells
+ */
+ miListHeader *tri_list;
+
+ ddPointUnion in_pt, out_pt;
+
+ listofddFacet *tri_facets;
+
+ char *quad_fptr, /* pointers to */
+ *tri_fptr; /* facet data */
+
+ ddpex3rtn status;
+
+ int inpoint_size,
+ outpoint_size,
+ facet_size,
+ row_size,
+ edge_offset,
+ i,j,
+ num_cols,
+ num_rows;
+
+/***********************************************************************/
+
+
+ /* Initialize status */
+
+ status = Success;
+
+ /* Allocate space for a Generic Structure Element */
+
+ if (!(pGStr = (miGenericStr *) (xalloc(sizeof(miGenericStr) +
+ sizeof(miTriangleStripStruct))))) {
+ status = BadAlloc;
+ goto exit;
+ }
+
+ /* Initialize the header data into allocated generic struct */
+
+ pGStr->elementType = PEXOCTriangleStrip;
+
+ /* The length data is ignored by the rendering routine and hence is */
+ /* left as whatever GARBAGE that will be present at the alloc time. */
+
+ ddTri = (miTriangleStripStruct *) (pGStr + 1);
+
+ num_cols = (ddQuad->mPts - 1);
+ num_rows = (ddQuad->nPts - 1);
+
+ /* At this point, we need to check if the edges are visible or not. */
+ /* If they are we need to explicitly add them. This is part of the */
+ /* because they are in the FillArea primitive, and we didn't wish */
+ /* to have special cases all over the code. (particularly structure */
+ /* storage and readback on both sides of the wire) */
+
+ DD_VertPointSize(ddQuad->points.type, inpoint_size);
+
+ in_pt.ptr = ddQuad->points.ddList->pts.ptr;
+ row_size = (inpoint_size * (num_cols+ 1));
+ quad_fptr = (char *)ddQuad->pFacets->facets.pNoFacet;
+
+ for (i = 1; i <= num_rows ; i++) {
+
+ /* All temporary storage must be reallocated
+ * each time, since the allocation routines rotate through
+ * the headers, and will overwrite any particular header
+ * after four calls. This coould perhaps be avoided by
+ * directly using xalloc, but we do it this way for
+ * consistency.
+ */
+
+
+ tri_list = MI_NEXTTEMPDATALIST(pddc); /* get new miListHeader */
+ MI_ALLOCLISTHEADER(tri_list, 1); /* get new ddList attached */
+
+ tri_list->ddList->numPoints = 2 * (num_cols + 1);
+ tri_list->type = ddQuad->points.type;
+ if ((pddc->Static.attrs->edges != PEXOff) &&
+ (!(DD_IsVertEdge(ddQuad->points.type)))) {
+ DD_SetVertEdge(tri_list->type);
+ DD_VertOffsetEdge(tri_list->type, edge_offset);
+ }
+ DD_VertPointSize(tri_list->type, outpoint_size);
+ tri_list->flags = ddQuad->points.flags;
+ tri_list->numLists = 1;
+ MI_ALLOCLISTOFDDPOINT( /* get vertex storage */
+ tri_list->ddList, (2 * (num_cols + 1)), (outpoint_size));
+
+ /* Allocate triangle strip facet storage if necessary*/
+ if (ddQuad->pFacets) {
+ if (ddQuad->pFacets->numFacets > 0) {
+ DDFacetSIZE(ddQuad->pFacets->type, facet_size);
+ tri_facets = MI_NEXTTEMPFACETLIST(pddc);
+ tri_facets->type = ddQuad->pFacets->type;
+ MI_ALLOCLISTOFDDFACET(tri_facets, 2 * num_cols, facet_size);
+ if (!tri_facets->facets.pFacetRgbFloatN) {
+ status = BadAlloc;
+ goto exit;
+ }
+ tri_fptr = (char *)tri_facets->facets.pNoFacet;
+ tri_facets->numFacets = 2 * num_cols;
+ ddTri->pFacets = tri_facets;
+ }
+ else {
+ quad_fptr = 0;
+ tri_fptr = 0;
+ tri_facets = 0;
+ ddTri->pFacets = 0;
+ }
+
+ } else {
+ quad_fptr = 0;
+ tri_fptr = 0;
+ tri_facets = 0;
+ ddTri->pFacets = 0;
+ }
+
+ out_pt.ptr = tri_list->ddList->pts.ptr;
+
+ memcpy( out_pt.ptr, in_pt.ptr, inpoint_size);
+ if (pddc->Static.attrs->edges != PEXOff) {
+ *(out_pt.ptr + edge_offset) = ~0;
+ }
+ out_pt.ptr += outpoint_size;
+
+ memcpy( out_pt.ptr, (in_pt.ptr + row_size), inpoint_size);
+ if (pddc->Static.attrs->edges != PEXOff) {
+ *(out_pt.ptr + edge_offset) = ~0;
+ CLEAR_FWD_EDGE(out_pt.ptr, edge_offset);
+ }
+ in_pt.ptr += inpoint_size;
+ out_pt.ptr += outpoint_size;
+
+ /* Build up a triangle strip */
+ for (j = 1; j <= num_cols; j++) {
+
+ memcpy( out_pt.ptr, in_pt.ptr, inpoint_size);
+ if (pddc->Static.attrs->edges != PEXOff) {
+ *(out_pt.ptr + edge_offset) = ~0;
+ }
+ out_pt.ptr += outpoint_size;
+ memcpy( out_pt.ptr, (in_pt.ptr + row_size), inpoint_size);
+ if (pddc->Static.attrs->edges != PEXOff){
+ *(out_pt.ptr + edge_offset) = ~0;
+ CLEAR_FWD_EDGE(out_pt.ptr, edge_offset);
+ }
+ in_pt.ptr += inpoint_size;
+ out_pt.ptr += outpoint_size;
+
+ if (ddQuad->pFacets->numFacets > 0) {
+ memcpy( tri_fptr, quad_fptr, facet_size);
+ tri_fptr += facet_size;
+ memcpy( tri_fptr, quad_fptr, facet_size);
+ tri_fptr += facet_size;
+ quad_fptr += facet_size;
+ }
+ }
+
+ ddTri->points = *tri_list;
+
+ /*fire off the triangle strip routine*/
+ if (status = InitExecuteOCTable[(int)(pGStr->elementType)](pRend, pGStr))
+ goto exit;
+ }
+
+ /* Free up allocated space for generic struct and return */
+
+ exit:
+
+ xfree((char *)pGStr);
+ return (status);
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level2/miReplace.c b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miReplace.c
new file mode 100644
index 000000000..febda7820
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miReplace.c
@@ -0,0 +1,309 @@
+/* $TOG: miReplace.c /main/6 1998/02/10 12:42:28 kaleb $ */
+
+/***********************************************************
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution of
+the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level2/miReplace.c,v 3.6 1998/10/04 09:34:26 dawes Exp $ */
+
+
+#include "ddpex2.h"
+#include "miStruct.h"
+#include "pexExtract.h"
+#include "pexUtils.h"
+#include "miLight.h"
+#include "pexos.h"
+
+
+/** Replace functions:
+ ** Each takes two parameters: a pointer to the element to be
+ ** parsed (in PEX format) and a pointer to a pointer to return the
+ ** parsed element (in server native internal format).
+ **
+ ** See comments in pexOCParse.c
+ **
+ ** The routines in this file are exceptions to the symmetry
+ ** in parsing that allows us to use the same routines for creation
+ ** and replacement.
+ **
+ ** Note that these routines DO NOT allocate any memory; the calling
+ ** routines must ensure that sufficient memory has been allocated
+ ** in which to store the parsed element. Coders adding routines
+ ** to this file must obide by this rule.
+ **/
+
+
+extern void ParseFacetOptData();
+extern void ParseVertexData();
+extern int CountFacetOptData();
+extern int CountVertexData();
+
+#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
+#define CAT(a,b) a##b
+#else
+#define CAT(a,b) a/**/b
+#endif
+
+#define OC_REPLACE_FUNC_HEADER(suffix) \
+ ddpex2rtn CAT(replace,suffix)(pPEXOC, ppExecuteOC) \
+ ddElementInfo *pPEXOC; /* PEX format */ \
+ miGenericElementPtr *ppExecuteOC; /* internal format */
+
+#define OC_REPLACE_RETURN(ANSWER) \
+ return(Success);
+
+#define PARSER_PTR(PTR) \
+ ddPointer PTR = (ddPointer)(pPEXOC + 1)
+
+#define LEN_WO_HEADER(OCtype) (pPEXOC->length * sizeof(CARD32) - sizeof(OCtype))
+
+/* Note this macro assumes that if the old size is the same as the new
+ size, then the replace in place can happen. This may not be sufficient
+ proof. Counterexamples are dealt with on a case by case basis
+ (e.g., see replaceLightState below).
+ */
+#define CHECK_REPLACE(DD_ST, TYPE) \
+ if (!*ppExecuteOC) return (BadAlloc); \
+ if (pPEXOC->length != (*ppExecuteOC)->element.pexOClength) \
+ return (BadAlloc); \
+ (DD_ST) = (TYPE *)((*ppExecuteOC)+1);
+
+
+
+OC_REPLACE_FUNC_HEADER(LightState)
+{
+ miLightStateStruct *ddLightState;
+ pexLightState *pLight = (pexLightState *)pPEXOC;
+ extern ddpex2rtn parseLightState();
+
+ CHECK_REPLACE( ddLightState, miLightStateStruct);
+
+ /*
+ may have padding due to pointer alignment insurance
+ */
+ if ((MAKE_EVEN(pLight->numEnable) + MAKE_EVEN(pLight->numDisable))
+ != (MAKE_EVEN(ddLightState->enableList->numObj)
+ + MAKE_EVEN(ddLightState->disableList->numObj)))
+ return(BadAlloc);
+
+ return(parseLightState(pPEXOC, ppExecuteOC));
+}
+
+
+OC_REPLACE_FUNC_HEADER(SOFAS)
+{
+ miSOFASStruct *ddFill;
+ pexSOFAS *pFill = (pexSOFAS *)pPEXOC;
+ PARSER_PTR(ptr);
+ CARD16 i,j;
+ miConnListList *pCLL;
+ miConnList *pCList;
+ ddPointer rptr = 0;
+ ddPointer vertexPtr = 0;
+ ddPointer facetPtr = 0;
+ int edgeSize = 0;
+ int facetSize = 0;
+ int vertexSize = 0;
+ ddpex2rtn err = Success;
+
+ CHECK_REPLACE( ddFill, miSOFASStruct);
+ if ( (pFill->numFAS != ddFill->numFAS)
+ || (pFill->numEdges != ddFill->numEdges)
+ || (pFill->numVertices != ddFill->points.ddList->maxData))
+ return(BadAlloc); /* still not a sufficient check... */
+
+ facetSize = CountFacetOptData( ptr, (CARD16)(pFill->colourType),
+ (CARD32)(pFill->numFAS),
+ pFill->FAS_Attributes);
+ vertexSize = CountVertexData( ptr, pFill->colourType,
+ (CARD32)(pFill->numVertices),
+ pFill->vertexAttributes);
+ if (pFill->edgeAttributes){
+ edgeSize = pFill->numEdges * sizeof(ddUCHAR);
+ edgeSize += ((4 - (edgeSize & 3)) & 3);
+ }
+
+ EXTRACT_CARD16(ddFill->shape, ptr);
+ ddFill->contourHint = pFill->contourHint;
+ ddFill->contourCountsFlag = pFill->contourCountsFlag;
+ ddFill->numFAS = pFill->numFAS;
+ ddFill->numEdges = pFill->numEdges;
+ ptr = (ddPointer)(pFill+1);
+ ddFill->points.ddList = (listofddPoint *)(ddFill + 1);
+ ddFill->points.flags = 0;
+ ddFill->points.numLists = 1;
+ ddFill->points.maxLists = 1;
+
+ facetPtr = (ddPointer)(ddFill->points.ddList + 1);
+ ParseFacetOptData( ptr, (CARD16)(pFill->colourType),
+ (CARD32)(pFill->numFAS),
+ pFill->FAS_Attributes, &(ddFill->pFacets),
+ facetPtr, &rptr);
+ ptr = rptr;
+
+ vertexPtr = facetPtr + facetSize;
+ ParseVertexData( ptr, pFill->colourType, (CARD32)(pFill->numVertices),
+ pFill->vertexAttributes, ddFill->points.ddList,
+ &vertexPtr, &(ddFill->points.type), &rptr);
+ ptr = rptr;
+
+ ddFill->edgeAttribs = pFill->edgeAttributes;
+ if (pFill->edgeAttributes) {
+ ddFill->edgeData = (ddUCHAR *)vertexPtr;
+ EXTRACT_STRUCT(ddFill->numEdges, ddUCHAR, ddFill->edgeData, ptr);
+ SKIP_PADDING( ptr, ((4 - (ddFill->numEdges & 3)) & 3) );
+ }
+ else { ddFill->edgeData = 0; }
+ vertexPtr += edgeSize;
+
+ ddFill->connects.numListLists = pFill->numFAS;
+ ddFill->connects.data = (miConnListList *)vertexPtr;
+ ddFill->connects.maxData = ddFill->numFAS * sizeof(miConnListList);
+ for (i=0, pCLL = ddFill->connects.data; i<pFill->numFAS; i++, pCLL++) {
+ EXTRACT_CARD16(pCLL->numLists,ptr);
+ pCLL->maxData = pCLL->numLists * sizeof(miConnList);
+ for (j=0, pCList=pCLL->pConnLists; j<pCLL->numLists; j++, pCList++) {
+ EXTRACT_CARD16(pCList->numLists,ptr);
+ EXTRACT_STRUCT(pCList->numLists, ddUSHORT, pCList->pConnects, ptr);
+ pCList->maxData = pCList->numLists * sizeof(ddUSHORT);
+ }
+ }
+ OC_REPLACE_RETURN(ddFill);
+
+}
+
+
+
+OC_REPLACE_FUNC_HEADER(NurbSurface)
+{
+ miNurbSurfaceStruct *ddNurb;
+ PARSER_PTR(ptr);
+ pexNurbSurface *pNurb = (pexNurbSurface *)pPEXOC;
+ ddULONG i, j, k;
+ listofTrimCurve *ddTrim;
+ ddTrimCurve *ddtc;
+ ddUSHORT type;
+
+ CHECK_REPLACE( ddNurb, miNurbSurfaceStruct);
+ if ( (pNurb->numUknots != ddNurb->numUknots)
+ || (pNurb->numVknots != ddNurb->numVknots)
+ || (pNurb->mPts != ddNurb->mPts)
+ || (pNurb->nPts != ddNurb->nPts)
+ || (pNurb->numLists != ddNurb->numTrimCurveLists)
+ || (pNurb->uOrder != ddNurb->uOrder)
+ || (pNurb->vOrder != ddNurb->vOrder)
+ || ( (pNurb->type == PEXRational)
+ && (ddNurb->points.type != DD_HOMOGENOUS_POINT))
+ || ( (pNurb->type == PEXNonRational)
+ && (ddNurb->points.type != DD_3D_POINT)))
+ return(BadAlloc); /* still not a sufficient check... */
+
+ ddNurb->pUknots = (ddFLOAT *)(ddNurb+1);
+ ddNurb->pVknots = (ddFLOAT *)((ddNurb->pUknots) + pNurb->numUknots);
+ ddNurb->points.ddList =
+ (listofddPoint *)((ddNurb->pVknots) + pNurb->numVknots);
+ ddNurb->points.ddList->pts.ptr = (char *)(ddNurb->points.ddList + 1);
+ ddNurb->trimCurves =
+ (listofTrimCurve *)((ddNurb->points.ddList->pts.ptr)
+ + (pNurb->mPts * pNurb->nPts) * sizeof(ddCoord4D));
+
+ SKIP_PADDING(ptr, 2); /* place holder for type */
+ EXTRACT_CARD16(ddNurb->uOrder, ptr);
+ EXTRACT_CARD16(ddNurb->vOrder, ptr);
+ SKIP_PADDING(ptr, 2);
+ EXTRACT_CARD32(ddNurb->numUknots, ptr);
+ EXTRACT_CARD32(ddNurb->numVknots, ptr);
+ EXTRACT_CARD16(ddNurb->mPts, ptr);
+ EXTRACT_CARD16(ddNurb->nPts, ptr);
+ EXTRACT_CARD32(ddNurb->numTrimCurveLists, ptr); /* is pNurb->numLists */
+
+ EXTRACT_STRUCT(ddNurb->numUknots, PEXFLOAT, ddNurb->pUknots, ptr);
+ EXTRACT_STRUCT(ddNurb->numVknots, PEXFLOAT, ddNurb->pVknots, ptr);
+
+ ddNurb->points.numLists = 1;
+ ddNurb->points.maxLists = 1;
+ if (pNurb->type == PEXRational) {
+ ddNurb->points.type = DD_HOMOGENOUS_POINT;
+ EXTRACT_STRUCT( ddNurb->mPts * ddNurb->nPts, ddCoord4D,
+ ddNurb->points.ddList->pts.p4Dpt, ptr);
+ } else {
+ ddNurb->points.type = DD_3D_POINT;
+ EXTRACT_STRUCT( ddNurb->mPts * ddNurb->nPts, ddCoord3D,
+ ddNurb->points.ddList->pts.p3Dpt, ptr);
+ }
+
+ for ( i=0, ddTrim = ddNurb->trimCurves;
+ i<ddNurb->numTrimCurveLists;
+ i++, ddTrim++) {
+ EXTRACT_CARD32(ddTrim->count, ptr);
+
+ for ( j=0, ddtc = ddTrim->pTC;
+ j < ddTrim->count;
+ j++, ddtc++) {
+ EXTRACT_CARD8(ddtc->visibility, ptr);
+ SKIP_PADDING(ptr, 1);
+ EXTRACT_CARD16(ddtc->order, ptr);
+ EXTRACT_CARD16(type, ptr);
+ EXTRACT_CARD16(ddtc->curveApprox.approxMethod, ptr);
+ EXTRACT_FLOAT(ddtc->curveApprox.tolerance, ptr);
+ EXTRACT_FLOAT(ddtc->uMin, ptr);
+ EXTRACT_FLOAT(ddtc->uMax, ptr);
+ EXTRACT_CARD32(ddtc->numKnots, ptr);
+ EXTRACT_CARD32(ddtc->points.numPoints, ptr);
+ EXTRACT_STRUCT( ddtc->numKnots, PEXFLOAT, ddtc->pKnots, ptr);
+ if (type == PEXRational) {
+ /* Note this only works because these points are never
+ transformed */
+ ddtc->pttype = DD_3D_POINT;
+ ddtc->points.pts.p3Dpt = 0;
+ EXTRACT_STRUCT( ddtc->points.numPoints, ddCoord3D,
+ ddtc->points.pts.p3Dpt, ptr);
+ } else {
+ ddtc->pttype = DD_2D_POINT;
+ ddtc->points.pts.p2Dpt = 0;
+ EXTRACT_STRUCT( ddtc->points.numPoints, ddCoord2D,
+ ddtc->points.pts.p2Dpt, ptr);
+ }
+ }
+ }
+ OC_REPLACE_RETURN(ddNurb);
+
+}
+
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level2/miSOFAS.c b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miSOFAS.c
new file mode 100644
index 000000000..46080f59c
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miSOFAS.c
@@ -0,0 +1,216 @@
+/* $TOG: miSOFAS.c /main/5 1998/02/10 12:42:32 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level2/miSOFAS.c,v 3.6 1998/10/04 09:34:26 dawes Exp $ */
+
+#include "mipex.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "ddpex3.h"
+#include "PEXErr.h"
+#include "miStruct.h"
+#include "PEXprotost.h"
+#include "miRender.h"
+#include "gcstruct.h"
+#include "ddpex2.h"
+#include "miLight.h"
+#include "pexos.h"
+
+
+/*++
+ |
+ | Function Name: miSOFAS
+ |
+ | Function Description:
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+miSOFAS(pRend, pExecuteOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pExecuteOC;
+/* out */
+{
+/* calls */
+ extern ocTableType InitExecuteOCTable[];
+
+/* Local variable definitions */
+ miSOFASStruct *ddSOFAS = (miSOFASStruct *)(pExecuteOC+1);
+ miFillAreaStruct *ddFill;
+ miGenericStr *pGStr;
+ listofddFacet *input_facet = &ddSOFAS->pFacets; /* facets */
+ miConnHeader *index_list_hdr = &ddSOFAS->connects; /* vertex index */
+ miConnListList *index_list_list = index_list_hdr->data;
+ miConnList *index_list;
+ ddUSHORT *index;
+ ddUCHAR *edge_ptr = ddSOFAS->edgeData;
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ miListHeader *fillarea;
+ listofddFacet *fillareafacet;
+ listofddPoint *pddilist, *pddolist;
+ char *in_pt;
+ ddPointUnion out_pt;
+ ddPointer in_fct, out_fct;
+ int i, j, k;
+ int point_size, out_point_size, facet_size;
+ ddpex3rtn status = Success;
+
+ /*
+ * This implementation does not implement SOFAS directly.
+ * Instead, the SOFAS data is re-organized to describe a
+ * fill area set, and the fill area set code is then called
+ * to perform the rendering.
+ */
+ /* Allocate storage for the fill area command block */
+ if (!(pGStr = (miGenericStr *) (xalloc(sizeof(miGenericStr) +
+ sizeof(miFillAreaStruct)))))
+ return(BadAlloc);
+
+ pGStr->elementType = PEXOCFillAreaSet;
+ /* The length data is ignored by the rendering routine and hence is */
+ /* left as whatever GARBAGE that will be present at the alloc time. */
+
+ ddFill = (miFillAreaStruct *) (pGStr + 1);
+
+ /* Initialize constant part of fill area command structure */
+ ddFill->shape = ddSOFAS->shape; /* shape hint */
+ ddFill->ignoreEdges = PEXOff; /* edge flag */
+ ddFill->contourHint = ddSOFAS->contourHint;/* contour hint */
+ ddFill->points.type = ddSOFAS->points.type;
+ if (ddSOFAS->edgeAttribs) DD_SetVertEdge(ddFill->points.type);
+ ddFill->points.flags = ddSOFAS->points.flags;
+ ddFill->pFacets = NULL;
+
+ DD_VertPointSize( ddSOFAS->points.type, point_size);
+ DD_VertPointSize( ddFill->points.type, out_point_size);
+ DDFacetSIZE( input_facet->type, facet_size);
+
+ /* Only one input vertex list */
+ pddilist = ddSOFAS->points.ddList;
+ in_pt = pddilist->pts.ptr;
+ if (input_facet->type != DD_FACET_NONE)
+ in_fct = input_facet->facets.pNoFacet;
+ else in_fct = NULL;
+
+ /* one fill area set call per facet */
+ for (i = 0; i < ddSOFAS->numFAS; i++) {
+
+ /* get next set of vertex indices */
+ index_list = index_list_list->pConnLists;
+ ddFill->points.numLists = index_list_list->numLists;
+
+ /* Get next free vertex list header */
+ fillarea = MI_NEXTTEMPDATALIST(pddc);
+ MI_ALLOCLISTHEADER(fillarea,
+ MI_ROUND_LISTHEADERCOUNT(index_list_list->numLists));
+ if (!(pddolist = fillarea->ddList)) {
+ status = BadAlloc;
+ goto exit;
+ }
+
+ /* get next free facet list header */
+ if (in_fct) {
+ fillareafacet = MI_NEXTTEMPFACETLIST(pddc);
+ MI_ALLOCLISTOFDDFACET(fillareafacet, 1, facet_size);
+ ddFill->pFacets = fillareafacet;
+ fillareafacet->type = input_facet->type;
+ fillareafacet->numFacets = 1;
+ out_fct = fillareafacet->facets.pNoFacet;
+ }
+
+ /* Now, transform each list */
+ for (j = 0; j < index_list_list->numLists; j++) {
+ /*
+ * Insure sufficient room for each vertex
+ */
+ MI_ALLOCLISTOFDDPOINT(pddolist,index_list->numLists,out_point_size);
+ if (!(pddolist->pts.ptr)) {
+ status = BadAlloc;
+ goto exit;
+ }
+
+ out_pt = pddolist->pts;
+
+ index = index_list->pConnects;
+
+ for (k = 0; k < index_list->numLists; k++) {
+ memcpy( out_pt.ptr, (in_pt+(*index * point_size)), point_size);
+ out_pt.ptr += point_size;
+ if (ddSOFAS->edgeAttribs) *(out_pt.pEdge++) = *(edge_ptr++);
+ index++;
+ }
+
+ pddolist->numPoints = index_list->numLists;
+
+ /* Prepare for next bound */
+ pddolist++;
+ /* get indices for next bound */
+ index_list++;
+ }
+
+ /* Copy facet data for FAS */
+ if (in_fct) {
+ memcpy( (char *)out_fct, (char *)in_fct, facet_size);
+ out_fct += facet_size;
+ in_fct += facet_size;
+ }
+
+ /* Render fill area */
+ ddFill->points.numLists = index_list_list->numLists;
+ ddFill->points.ddList = fillarea->ddList;
+ if (status=InitExecuteOCTable[(int)(pGStr->elementType)](pRend, pGStr))
+ goto exit;
+
+ index_list_list++;
+ }
+
+exit:
+ xfree(pGStr);
+
+ return(status);
+
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level2/miSearch.c b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miSearch.c
new file mode 100644
index 000000000..ab119a907
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miSearch.c
@@ -0,0 +1,295 @@
+/* $TOG: miSearch.c /main/7 1998/02/10 12:42:37 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level2/miSearch.c,v 3.5 1998/10/04 09:34:27 dawes Exp $ */
+
+#include "miWks.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "PEXErr.h"
+#include "miRender.h"
+#include "miStruct.h"
+#include "ddpex2.h"
+#include "miFont.h"
+#include "miText.h"
+#include "miClip.h"
+#include "pexos.h"
+
+#define MAX(a,b) (((a)>(b))?(a):(b))
+#define MIN(a,b) (((a)<(b))?(a):(b))
+
+extern ocTableType InitExecuteOCTable[];
+
+/*
+ * Function Name: compute_search_volume
+ *
+ * Purpose: Compute the intersection of the clip limits and the
+ * search aperture. The search aperture is defined as
+ * a cube centered around search position and search
+ * distance being the distance between the center and the
+ * faces of the cube.
+ * Return:
+ * search volume.
+ */
+ddpex2rtn
+compute_search_volume(pDDC, search_volume)
+/* in */
+ miDDContext *pDDC;
+
+/* out */
+register ddNpcSubvolume *search_volume; /* Intersection to use */
+{
+/* calls */
+
+/* Local variable definitions */
+ ddCoord3D pos;
+ ddFLOAT dis;
+
+ /* Get the search position and distance first */
+
+ pos = pDDC->Static.search.position;
+ dis = pDDC->Static.search.distance;
+
+ if (dis <= 0.0) dis = 0.0001; /* Make sure we have the search volume */
+ /* collapsing almost to reference point */
+ /* when the distance is negative or zero*/
+
+ /* Compute a search volume centered around the search position and */
+ /* of half width, half height, and half length equal to the search */
+ /* distance. */
+
+ search_volume->minval.x = pos.x - dis;
+ search_volume->maxval.x = pos.x + dis;
+
+ search_volume->minval.y = pos.y - dis;
+ search_volume->maxval.y = pos.y + dis;
+
+ search_volume->minval.z = pos.z - dis;
+ search_volume->maxval.z = pos.z + dis;
+
+ return (Success);
+}
+
+
+/*
+ * Function Name: compute_search_volume_xform
+ *
+ * Purpose: Compute the transformation that transform the primitive
+ * to be searched from search_volume to CC. Remember that we
+ * will use the standard primitive clipping functions to figure
+ * out whether a given primitive lies within the search aperture.
+ * Return:
+ * sv_to_cc_xform to be used to figure out search hits.
+ */
+void
+compute_search_volume_xform(search_volume, sv_to_cc_xform)
+/* in */
+ ddNpcSubvolume *search_volume;
+/* out */
+ ddFLOAT sv_to_cc_xform[4][4];
+/* calls */
+{
+ /* The transformation needed here is to go from search_volume to clip_
+ * volume as shown in 2D below. We extend the transform to handle the 3D
+ * trivially.
+ *
+ * search_volume clip_volume
+ * ------------- -----------
+ *
+ * +-----+(c,d) +---------+(1,1)
+ * | | | |
+ * | | =======> | |
+ * | | | |
+ * (a,b)+-----+ (-1,-1)+---------+
+ *
+ * sv_to_cc_xform (2D): 2/(c-a) 0 (c+a)/(a-c)
+ * 0 2/(d-b) (d+b)/(b-d)
+ * 0 0 0
+ */
+
+ memcpy( (char *)sv_to_cc_xform, (char *)ident4x4, 16 * sizeof(ddFLOAT));
+
+ /* Check for trivial search volume, I.E., a point or a cube with */
+ /* zero dimensions. If so, initialize the transform to ? ? ? */
+
+ if (search_volume->maxval.x == search_volume->minval.x) {
+
+ /* Plug in the special ? ? ? */
+
+ return;
+ }
+
+ /* The search volume is NOT trivially a point; it is a finite */
+ /* volume for which a transform can be computed to go to CC. */
+
+ sv_to_cc_xform[0][0] =
+ 2.0 / (search_volume->maxval.x - search_volume->minval.x);
+ sv_to_cc_xform[1][1] =
+ 2.0 / (search_volume->maxval.y - search_volume->minval.y);
+ sv_to_cc_xform[2][2] =
+ 2.0 / (search_volume->maxval.z - search_volume->minval.z);
+ sv_to_cc_xform[0][3] =
+ (search_volume->maxval.x + search_volume->minval.x) /
+ (search_volume->minval.x - search_volume->maxval.x);
+ sv_to_cc_xform[1][3] =
+ (search_volume->maxval.y + search_volume->minval.y) /
+ (search_volume->minval.y - search_volume->maxval.y);
+ sv_to_cc_xform[2][3] =
+ (search_volume->maxval.z + search_volume->minval.z) /
+ (search_volume->minval.z - search_volume->maxval.z);
+}
+
+
+/*++
+ |
+ | Function Name: miSearchPrimitives
+ |
+ | Function Description:
+ | Handles the searching of most primitives in a generic fashion.
+ |
+ | Note(s):
+ |
+ ++*/
+
+ddpex2rtn
+miSearchPrimitives(pRend, pExecuteOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pExecuteOC;
+{
+/* calls */
+
+/* Local variable definitions */
+ miDDContext *pDDC = (miDDContext *)(pRend->pDDContext);
+ ddNpcSubvolume sv;
+ ddFLOAT buf1_xform[4][4];
+
+ /* Compute the search volume to do the ISS */
+
+ compute_search_volume (pDDC, &sv);
+
+ /* Get the transform to go from search volume to CC - buf1_xform */
+
+ compute_search_volume_xform (&sv, buf1_xform);
+
+ /* Get wc_to_cc_xform = (wc_to_npc_xform * buf1_xform) */
+
+ miMatMult (pDDC->Dynamic->wc_to_cc_xform,
+ pDDC->Dynamic->wc_to_npc_xform, buf1_xform);
+
+ /* Get mc_to_cc_xform = (mc_to_wc_xform * wc_to_cc_xform) */
+
+ miMatMult (pDDC->Dynamic->mc_to_cc_xform,
+ pDDC->Dynamic->mc_to_wc_xform,
+ pDDC->Dynamic->wc_to_cc_xform);
+
+ /* Now, call the level 2 rendering function to transform and */
+ /* clip the primitive. Note that the level 1 function vector */
+ /* now has PICKING routines instead of rendering routines. If*/
+ /* a search is detected the GLOBAL FLAG will have been up- */
+ /* dated. Check this flag to determine if anything was indeed*/
+ /* searched by the level 1 searching routines. */
+
+ InitExecuteOCTable[(int)(pExecuteOC->elementType)]
+ (pRend, pExecuteOC);
+
+ /* If successful PICK, set the search status flag */
+
+ if (pDDC->Static.pick.status == PEXOk)
+ pDDC->Static.search.status = PEXFound;
+
+ return (Success);
+}
+
+
+/*++
+ |
+ | Function Name: miTestSearchGdp3d
+ |
+ | Function Description:
+ | Provides the dummy test routine for searching 3d Gdps.
+ | with data OCs.
+ |
+ | Note(s):
+ |
+ ++*/
+
+ddpex2rtn
+miTestSearchGdp3d(pRend, pExecuteOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pExecuteOC;
+/* out */
+{
+ ErrorF ("miTestSearchGdp3d\n");
+ return (Success);
+}
+
+
+/*++
+ |
+ | Function Name: miTestSearchGdp2d
+ |
+ | Function Description:
+ | Provides the dummy test routine for searching 2d Gdps.
+ | with data OCs.
+ |
+ | Note(s):
+ |
+ ++*/
+
+ddpex2rtn
+miTestSearchGdp2d(pRend, pExecuteOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pExecuteOC;
+/* out */
+{
+ ErrorF ("miSearchPickGdp2d\n");
+ return (Success);
+}
+
+
+
+
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level2/miTestOCs.c b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miTestOCs.c
new file mode 100644
index 000000000..3022e42ad
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miTestOCs.c
@@ -0,0 +1,269 @@
+/* $TOG: miTestOCs.c /main/3 1998/02/10 12:42:41 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS 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 "mipex.h"
+#include "ddpex3.h"
+#include "miStruct.h"
+#include "miRender.h"
+#include "PEXErr.h"
+#include "PEXprotost.h"
+
+
+/* Level III Output Command Primitives */
+
+static char *ptTypeNames[] = {
+ "DD_2D_POINT", /* 2D point */
+ "DD_3D_POINT", /* 3D point */
+ "DD_INDEX_POINT", /* 3D point w/ colour */
+ "DD_RGB8_POINT", /* 3D point w/ colour */
+ "DD_RGB16_POINT", /* 3D point w/ colour */
+ "DD_RGBFLOAT_POINT", /* 3D point w/ colour */
+ "DD_HSV_POINT", /* 3D point w/ colour */
+ "DD_HLS_POINT", /* 3D point w/ colour */
+ "DD_CIE_POINT", /* 3D point w/ colour */
+ "DD_NORM_POINT", /* 3D point w/ normal */
+ "DD_EDGE_POINT", /* 3D point w/ edge flag */
+ "DD_INDEX_NORM_POINT", /* 3D point w/ colour & normal */
+ "DD_RGB8_NORM_POINT", /* 3D point w/ colour & normal */
+ "DD_RGB16_NORM_POINT", /* 3D point w/ colour & normal */
+ "DD_RGBFLOAT_NORM_POINT", /* 3D point w/ colour & normal */
+ "DD_HSV_NORM_POINT", /* 3D point w/ colour & normal */
+ "DD_HLS_NORM_POINT", /* 3D point w/ colour & normal */
+ "DD_CIE_NORM_POINT", /* 3D point w/ colour & normal */
+ "DD_INDEX_EDGE_POINT", /* 3D point w/ colour & edge flag */
+ "DD_RGB8_EDGE_POINT", /* 3D point w/ colour & edge flag */
+ "DD_RGB16_EDGE_POINT", /* 3D point w/ colour & edge flag */
+ "DD_RGBFLOAT_EDGE_POINT", /* 3D point w/ colour & edge flag */
+ "DD_HSV_EDGE_POINT", /* 3D point w/ colour & edge flag */
+ "DD_HLS_EDGE_POINT", /* 3D point w/ colour & edge flag */
+ "DD_CIE_EDGE_POINT", /* 3D point w/ colour & edge flag */
+ "DD_NORM_EDGE_POINT", /* 3D point w/ normal & edge flag */
+ "DD_INDEX_NORM_EDGE_POINT", /* 3D point w/ colour, normal & edge */
+ "DD_RGB8_NORM_EDGE_POINT", /* 3D point w/ colour, normal & edge */
+ "DD_RGB16_NORM_EDGE_POINT", /* 3D point w/ colour, normal & edge */
+ "DD_RGBFLOAT_NORM_EDGE_POINT",/* 3D point w/ colour, normal & edge */
+ "DD_HSV_NORM_EDGE_POINT", /* 3D point w/ colour, normal & edge */
+ "DD_HLS_NORM_EDGE_POINT", /* 3D point w/ colour, normal & edge */
+ "DD_CIE_NORM_EDGE_POINT", /* 3D point w/ colour, normal & edge */
+ "DD_HOMOGENOUS_POINT" /* homogenous point (4D) */
+};
+
+static char *pfTypeNames[] = {
+ "DD_FACET_NONE", /* no facet attributes */
+ "DD_FACET_INDEX", /* facet colour */
+ "DD_FACET_RGB8", /* facet colour */
+ "DD_FACET_RGB16", /* facet colour */
+ "DD_FACET_RGBFLOAT", /* facet colour */
+ "DD_FACET_HSV", /* facet colour */
+ "DD_FACET_HLS", /* facet colour */
+ "DD_FACET_CIE", /* facet colour */
+ "DD_FACET_NORM", /* facet normal */
+ "DD_FACET_INDEX_NORM", /* facet colour & normal */
+ "DD_FACET_RGB8_NORM", /* facet colour & normal */
+ "DD_FACET_RGB16_NORM", /* facet colour & normal */
+ "DD_FACET_RGBFLOAT_NORM", /* facet colour & normal */
+ "DD_FACET_HSV_NORM", /* facet colour & normal */
+ "DD_FACET_HLS_NORM", /* facet colour & normal */
+ "DD_FACET_CIE_NORM" /* facet colour & normal */
+};
+
+static char *piTypeNames[] = {
+ "DD_VERTEX",
+ "DD_VERTEX_EDGE"
+};
+
+static int test_print_flag = 0;
+
+#define PRINT_POINT_INFO( pt ) \
+\
+ ErrorF( "\tPoint Type: %d %s\tNum Lists: %d\n", \
+ (pt)->type, ptTypeNames[(int)((pt)->type)], (pt)->numLists )
+
+#define PRINT_FACET_INFO( pf ) \
+\
+ ErrorF( "\tFacet Type: %d %s\tNum Facets: %d\n", \
+ (pf)->type, pfTypeNames[(int)((pf)->type)], (pf)->numFacets )
+
+#define PRINT_INDEX_INFO( pi ) \
+\
+ ErrorF( "\tIndex Type: %d %s\tNum Index: %d\n", \
+ (pi)->type, piTypeNames[(int)((pi)->type)], (pi)->numIndex )
+
+/*++
+ |
+ | Function Name: miTestNurbSurface
+ |
+ | Function Description:
+ | Handles the Non-uniform B-spline surfac ocs.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex2rtn
+miTestNurbSurface(pRend, pSurf, numCurves, pTrimCurve)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ ddNurbSurface *pSurf; /* surface data */
+ ddULONG numCurves;/* number of trim curves */
+ listofTrimCurve *pTrimCurve; /* trim curve */
+/* out */
+{
+ if (test_print_flag) ErrorF( "miTestNurbSurface\n");
+ return (Success);
+}
+
+/*++
+ |
+ | Function Name: miTestCellArrays
+ |
+ | Function Description:
+ | Handles the Cell array 3D, Cell array 2D ocs.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex2rtn
+miTestCellArrays(pRend, pExecuteOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pExecuteOC;
+/* out */
+{
+ if (test_print_flag) ErrorF( "miTestCellArrays\n");
+ return (Success);
+}
+
+/*++
+ |
+ | Function Name: miTestExtCellArray
+ |
+ | Function Description:
+ | Handles the Extended Cell array ocs
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex2rtn
+miTestExtCellArray(pRend, pExecuteOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pExecuteOC;
+/* out */
+{
+ if (test_print_flag) ErrorF( "miTestExtCellArray\n");
+ return (Success);
+}
+
+/*++
+ |
+ | Function Name: miTestGDP
+ |
+ | Function Description:
+ | Handles the GDP 3D, GDP 2D ocs.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex2rtn
+miTestGDP(pRend, pExecuteOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pExecuteOC;
+/* out */
+{
+ if (test_print_flag) ErrorF( "miTestGDP\n");
+ return (Success);
+}
+
+/*++
+ |
+ | Function Name: miTestSetAttribute
+ |
+ | Function Description:
+ | Handles the All Other ocs (to set attributes).
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex2rtn
+miTestSetAttribute(pRend, pExecuteOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pExecuteOC; /* output command */
+/* out */
+{
+ if (test_print_flag) ErrorF( "miTestSetAttribute\n");
+ return (Success);
+}
+
+
+
+/*++
+ |
+ | Function Name: miTestColourOC
+ |
+ | Function Description:
+ | Handles the Colour setting OC's.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex2rtn
+miTestColourOC(pRend, pExecuteOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pExecuteOC;
+/* out */
+{
+ if (test_print_flag) ErrorF( "miTestColourOC\n");
+ return (Success);
+}
+
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level2/miText.c b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miText.c
new file mode 100644
index 000000000..45b415eed
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miText.c
@@ -0,0 +1,2168 @@
+/* $TOG: miText.c /main/14 1998/02/10 12:42:46 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level2/miText.c,v 3.6 1998/10/04 09:34:28 dawes Exp $ */
+
+#include "miLUT.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "PEXErr.h"
+#include "miStruct.h"
+#include "PEXprotost.h"
+#include "ddpex3.h"
+#include "ddpex2.h"
+#include "miRender.h"
+#include "miFont.h"
+#include "miText.h"
+#include "miClip.h"
+#include "gcstruct.h"
+#include "pexos.h"
+
+#ifndef PADDING
+#define PADDING(n) ( (n)%4 ? (4 - ((n)%4)) : 0)
+#endif
+
+extern ddpex3rtn ComputeMCVolume();
+
+ddpex2rtn
+tx_el_to_path(pRend, pddc, numFragments, pString, numChars, tx_el,
+ align_pt, count_ret)
+/* in */
+ ddRendererPtr pRend; /* Renderer handle */
+ miDDContext *pddc; /* Context handle */
+ ddUSHORT numFragments; /* # of mono encodings */
+ pexMonoEncoding *pString; /* Pointer to ISTRING */
+ ddULONG numChars; /* Total # of chars in ISTRING */
+/* out */
+ miTextElement *tx_el; /* text element data */
+ ddCoord2D *align_pt; /* text alignment */
+ ddULONG *count_ret; /* return character count */
+{
+/* Define required temporary variables */
+
+ miCharPath *CharPtr;
+ ddUSHORT fontIndex;
+ ddUSHORT path;
+ ddFLOAT expansion;
+ ddFLOAT spacing;
+ ddTextAlignmentData *pAlignment;
+ diLUTHandle fontTable;
+ register ddPointer ptr, save_ptr;
+ miTextFontEntry *ptr1;
+ pexMonoEncoding *mono_enc;
+ int fragnum, charnum, some_characters, signum, bytes;
+ CARD32 charval;
+ diFontHandle font_handle;
+ miFontHeader *font;
+ Ch_stroke_data *char_data;
+ ddFLOAT sp;
+ Meta_font meta_font;
+ pexCoord2D cur, end, cpt;
+ float xmin, xmax, ymin, ymax;
+ ddTextFontEntry *fontEntry;
+ ddUSHORT es, clip_mode;
+ extern void micalc_cpt_and_align();
+
+ *count_ret = 0;
+
+ fontIndex = pddc->Static.attrs->textFont;
+ expansion = ABS(pddc->Static.attrs->charExpansion);
+ spacing = pddc->Static.attrs->charSpacing;
+ path = pddc->Static.attrs->textPath;
+ sp = spacing * FONT_COORD_HEIGHT;
+ pAlignment = &(pddc->Static.attrs->textAlignment);
+
+ /* Get the handle for font table */
+
+ fontTable = pRend->lut[PEXTextFontLUT];
+
+ /* Inquire the Font table to get the ddTextFontEntry member */
+
+ if ((InquireLUTEntryAddress (PEXTextFontLUT, fontTable, fontIndex, &es,
+ (ddPointer *)&ptr1)) == PEXLookupTableError)
+ return (PEXLookupTableError);
+
+ fontEntry = &ptr1->entry;
+
+ /* Allocate space for stroke definitions of all chars in ISTRING */
+
+ if (!((tx_el->paths) = (miCharPath *) xalloc(numChars *
+ sizeof(miCharPath))))
+ return (BadAlloc);
+
+ /* signum is used later on to encapsulate addition vs. subtraction */
+
+ if (path == PEXPathRight || path == PEXPathUp)
+ signum = 1;
+ else
+ signum = -1;
+
+ ptr = (ddPointer) pString;
+
+ /* Process the input ISTRING */
+
+ meta_font.top = -1.0e20;
+ meta_font.bottom = 1.0e20;
+ meta_font.width = 1.0e-20;
+
+ xmin = xmax = ymin = ymax = 0.0;
+ cpt.x = cpt.y = 0.0;
+ cur.x = end.x = cur.y = end.y = 0.0;
+
+ some_characters = 0; /* Make TRUE when a valid character is found */
+
+ save_ptr = ptr; /* Save this for later use */
+
+ /* First determine the largest character box size within ISTRING */
+ /* Do for each MONO_ENCODING fragment within the ISTRING */
+
+ for (fragnum = 0; fragnum < numFragments; fragnum++) {
+
+ mono_enc = (pexMonoEncoding *)ptr;
+ ptr += sizeof(pexMonoEncoding);
+
+ if (mono_enc->characterSet < 1 ||
+ mono_enc->characterSet > fontEntry->numFonts)
+ mono_enc->characterSet = 1;
+
+ font_handle = fontEntry->fonts[mono_enc->characterSet - 1];
+
+ /* This is the font that this MONO_ENCODING would be rendered with */
+
+ font = (miFontHeader *)(font_handle->deviceData);
+
+ /* Bump up ISTRINGS extremes if appropriate */
+
+ if (font->top > meta_font.top)
+ meta_font.top = font->top;
+ if (font->bottom < meta_font.bottom)
+ meta_font.bottom = font->bottom;
+ if (font->max_width > meta_font.width)
+ meta_font.width = font->max_width;
+
+ bytes = mono_enc->numChars *
+ ((mono_enc->characterSetWidth == PEXCSByte) ?
+ sizeof(CARD8) : ((mono_enc->characterSetWidth == PEXCSShort) ?
+ sizeof(CARD16) : sizeof(CARD32)));
+
+ ptr += (bytes + PADDING (bytes));
+ }
+
+ /* Now get the character definition and the required per character */
+ /* translation component required to be applied during rendering. */
+
+ ptr = save_ptr; /* Restore the ptr */
+ CharPtr = tx_el->paths; /* Initialize the pointer to character data */
+
+ for (fragnum = 0; fragnum < numFragments; fragnum++) {
+
+ mono_enc = (pexMonoEncoding *)ptr;
+ ptr += sizeof(pexMonoEncoding);
+
+ font_handle = fontEntry->fonts[mono_enc->characterSet - 1];
+ font = (miFontHeader *)(font_handle->deviceData);
+
+ /* Do for each character within the MONO_ENCODING */
+
+ for (charnum = 0; charnum < mono_enc->numChars; charnum++) {
+
+ switch (mono_enc->characterSetWidth) {
+ case PEXCSByte :
+ charval = (CARD32)(*(CARD8 *)ptr);
+ ptr += sizeof(CARD8);
+ break;
+ case PEXCSShort :
+ charval = (CARD32)(*(CARD16 *)ptr);
+ ptr += sizeof(CARD16);
+ break;
+ case PEXCSLong :
+ charval = *(CARD32 *)ptr;
+ ptr += sizeof(CARD32);
+ break;
+ }
+
+ if (!(font->ch_data[charval])) /* undefined character */
+ if (font->font_info.defaultGlyph == 0 &&
+ font->font_info.firstGlyph > 0) /* no default */
+ /* no extent info is calculated for undefined indices
+ * in charsets where there is no default glyph */
+ continue;
+ else
+ charval = font->font_info.defaultGlyph;
+
+ some_characters = 1;
+ char_data = font->ch_data[charval]; /* Get strokes for char */
+
+ switch (path) {
+
+ case PEXPathRight :
+ case PEXPathLeft :
+ end.x = cur.x + signum*(char_data->right)*expansion;
+ if (cur.x > xmax) xmax = cur.x;
+ if (cur.x < xmin) xmin = cur.x;
+ if (end.x > xmax) xmax = end.x;
+ if (end.x < xmin) xmin = end.x;
+ cur.x = end.x + signum * sp;
+ break;
+
+ case PEXPathUp :
+ case PEXPathDown :
+ end.y = cur.y + signum * (meta_font.top -
+ meta_font.bottom);
+ if (cur.y > ymax) ymax = cur.y;
+ if (cur.y < ymin) ymin = cur.y;
+ if (end.y > ymax) ymax = end.y;
+ if (end.y < ymin) ymin = end.y;
+ cur.y = end.y + signum * sp;
+ cur.x += -char_data->right * 0.5 * expansion;
+ break;
+ }
+
+ /* Save the stroke definitions for the character */
+
+ CharPtr->path = &(char_data->strokes);
+
+ /* Save the translation per character */
+
+ (CharPtr->trans).x = cur.x;
+ (CharPtr->trans).y = cur.y;
+
+ /* Set cur.x back to lower left corner of character box */
+ /* for the cases of PEXPathUp and PEXPathDown. */
+
+ if (path==PEXPathUp || path==PEXPathDown)
+ cur.x -= -char_data->right * 0.5 * expansion;
+
+ CharPtr++; (*count_ret)++; /* Update pointer and count */
+
+ } /* for each character */
+
+ ptr += PADDING(mono_enc->numChars *
+ ((mono_enc->characterSetWidth == PEXCSByte)
+ ? sizeof(CARD8)
+ : ((mono_enc->characterSetWidth == PEXCSShort)
+ ? sizeof(CARD16)
+ : sizeof(CARD32))));
+
+ } /* for each MONO_ENCODING (fragment) */
+
+ /* Compute the alignment and concatenation point; however, */
+ /* the concatenation point (cpt) can be ignored here ! */
+
+ if (some_characters) {
+
+ micalc_cpt_and_align(&meta_font, &xmin, &xmax, &ymin, &ymax, path,
+ expansion, pAlignment, &cpt, align_pt);
+
+ } else {
+ /* no valid characters */
+ xmin = xmax = ymin = ymax = 0.0;
+ cpt.x = cpt.y = align_pt->x = align_pt->y = 0.0;
+ }
+
+ return (Success);
+}
+
+
+ddpex2rtn
+atx_el_to_path(pRend, pddc, numFragments, pString, numChars, tx_el,
+ align_pt, count_ret)
+/* in */
+ ddRendererPtr pRend; /* Renderer handle */
+ miDDContext *pddc; /* Context handle */
+ ddUSHORT numFragments; /* # of mono encodings */
+ pexMonoEncoding *pString; /* Pointer to ISTRING */
+ ddULONG numChars; /* Total # of chars in ISTRING */
+/* out */
+ miTextElement *tx_el; /* text element data */
+ ddCoord2D *align_pt; /* text alignment */
+ ddULONG *count_ret; /* return character count */
+{
+/* Define required temporary variables */
+
+ miCharPath *CharPtr;
+ ddUSHORT fontIndex;
+ ddUSHORT path;
+ ddFLOAT expansion;
+ ddFLOAT spacing;
+ ddTextAlignmentData *pAlignment;
+ diLUTHandle fontTable;
+ register ddPointer ptr, save_ptr;
+ miTextFontEntry *ptr1;
+ pexMonoEncoding *mono_enc;
+ int fragnum, charnum, some_characters, signum, bytes;
+ CARD32 charval;
+ diFontHandle font_handle;
+ miFontHeader *font;
+ Ch_stroke_data *char_data;
+ ddFLOAT sp;
+ Meta_font meta_font;
+ pexCoord2D cur, end, cpt;
+ float xmin, xmax, ymin, ymax;
+ ddTextFontEntry *fontEntry;
+ ddUSHORT es;
+ extern void micalc_cpt_and_align();
+
+ *count_ret = 0;
+
+ fontIndex = pddc->Static.attrs->textFont;
+ expansion = ABS(pddc->Static.attrs->charExpansion);
+ spacing = pddc->Static.attrs->charSpacing;
+ path = pddc->Static.attrs->atextPath;
+ sp = spacing * FONT_COORD_HEIGHT;
+ pAlignment = &(pddc->Static.attrs->atextAlignment);
+
+ /* Get the handle for font table */
+
+ fontTable = pRend->lut[PEXTextFontLUT];
+
+ /* Inquire the Font table to get the ddTextFontEntry member */
+
+ if ((InquireLUTEntryAddress (PEXTextFontLUT, fontTable, fontIndex, &es,
+ (ddPointer *)&ptr1)) == PEXLookupTableError)
+ return (PEXLookupTableError);
+
+ fontEntry = &ptr1->entry;
+
+ /* Allocate space for stroke definitions of all chars in ISTRING */
+
+ if (!((tx_el->paths) = (miCharPath *) xalloc(numChars *
+ sizeof(miCharPath))))
+ return (BadAlloc);
+
+ /* signum is used later on to encapsulate addition vs. subtraction */
+
+ if (path == PEXPathRight || path == PEXPathUp)
+ signum = 1;
+ else
+ signum = -1;
+
+ ptr = (ddPointer) pString;
+
+ /* Process the input ISTRING */
+
+ meta_font.top = -1.0e20;
+ meta_font.bottom = 1.0e20;
+ meta_font.width = 1.0e-20;
+
+ xmin = xmax = ymin = ymax = 0.0;
+ cpt.x = cpt.y = 0.0;
+ cur.x = end.x = cur.y = end.y = 0.0;
+
+ some_characters = 0; /* Make TRUE when a valid character is found */
+
+ save_ptr = ptr; /* Save this for later use */
+
+ /* First determine the largest character box size within ISTRING */
+ /* Do for each MONO_ENCODING fragment within the ISTRING */
+
+ for (fragnum = 0; fragnum < numFragments; fragnum++) {
+
+ mono_enc = (pexMonoEncoding *)ptr;
+ ptr += sizeof(pexMonoEncoding);
+
+ if (mono_enc->characterSet < 1 ||
+ mono_enc->characterSet > fontEntry->numFonts)
+ mono_enc->characterSet = 1;
+
+ font_handle = fontEntry->fonts[mono_enc->characterSet - 1];
+
+ /* This is the font that this MONO_ENCODING would be rendered with */
+
+ font = (miFontHeader *)(font_handle->deviceData);
+
+ /* Bump up ISTRINGS extremes if appropriate */
+
+ if (font->top > meta_font.top)
+ meta_font.top = font->top;
+ if (font->bottom < meta_font.bottom)
+ meta_font.bottom = font->bottom;
+ if (font->max_width > meta_font.width)
+ meta_font.width = font->max_width;
+
+ bytes = mono_enc->numChars *
+ ((mono_enc->characterSetWidth == PEXCSByte) ?
+ sizeof(CARD8) : ((mono_enc->characterSetWidth == PEXCSShort) ?
+ sizeof(CARD16) : sizeof(CARD32)));
+
+ ptr += (bytes + PADDING (bytes));
+ }
+
+ /* Now get the character definition and the required per character */
+ /* translation component required to be applied during rendering. */
+
+ ptr = save_ptr; /* Restore the ptr */
+ CharPtr = tx_el->paths; /* Initialize the pointer to character data */
+
+ for (fragnum = 0; fragnum < numFragments; fragnum++) {
+
+ mono_enc = (pexMonoEncoding *)ptr;
+ ptr += sizeof(pexMonoEncoding);
+
+ font_handle = fontEntry->fonts[mono_enc->characterSet - 1];
+ font = (miFontHeader *)(font_handle->deviceData);
+
+ /* Do for each character within the MONO_ENCODING */
+
+ for (charnum = 0; charnum < mono_enc->numChars; charnum++) {
+
+ switch (mono_enc->characterSetWidth) {
+ case PEXCSByte :
+ charval = (CARD32)(*(CARD8 *)ptr);
+ ptr += sizeof(CARD8);
+ break;
+ case PEXCSShort :
+ charval = (CARD32)(*(CARD16 *)ptr);
+ ptr += sizeof(CARD16);
+ break;
+ case PEXCSLong :
+ charval = *(CARD32 *)ptr;
+ ptr += sizeof(CARD32);
+ break;
+ }
+
+ if (!(font->ch_data[charval])) /* undefined character */
+ if (font->font_info.defaultGlyph == 0 &&
+ font->font_info.firstGlyph > 0) /* no default */
+ /* no extent info is calculated for undefined indices
+ * in charsets where there is no default glyph */
+ continue;
+ else
+ charval = font->font_info.defaultGlyph;
+
+ some_characters = 1;
+ char_data = font->ch_data[charval]; /* Get strokes for char */
+
+ switch (path) {
+
+ case PEXPathRight :
+ case PEXPathLeft :
+ end.x = cur.x + signum*(char_data->right)*expansion;
+ if (cur.x > xmax) xmax = cur.x;
+ if (cur.x < xmin) xmin = cur.x;
+ if (end.x > xmax) xmax = end.x;
+ if (end.x < xmin) xmin = end.x;
+ cur.x = end.x + signum * sp;
+ break;
+
+ case PEXPathUp :
+ case PEXPathDown :
+ end.y = cur.y + signum * (meta_font.top -
+ meta_font.bottom);
+ if (cur.y > ymax) ymax = cur.y;
+ if (cur.y < ymin) ymin = cur.y;
+ if (end.y > ymax) ymax = end.y;
+ if (end.y < ymin) ymin = end.y;
+ cur.y = end.y + signum * sp;
+ cur.x += -char_data->right * 0.5 * expansion;
+ break;
+ }
+
+ /* Save the stroke definitions for the character */
+
+ CharPtr->path = &(char_data->strokes);
+
+ /* Save the translation per character */
+
+ (CharPtr->trans).x = cur.x;
+ (CharPtr->trans).y = cur.y;
+
+ /* Set cur.x back to lower left corner of character box */
+ /* for the cases of PEXPathUp and PEXPathDown. */
+
+ if (path==PEXPathUp || path==PEXPathDown)
+ cur.x -= -char_data->right * 0.5 * expansion;
+
+ CharPtr++; (*count_ret)++; /* Update pointer and count */
+
+ } /* for each character */
+
+ ptr += PADDING(mono_enc->numChars *
+ ((mono_enc->characterSetWidth == PEXCSByte)
+ ? sizeof(CARD8)
+ : ((mono_enc->characterSetWidth == PEXCSShort)
+ ? sizeof(CARD16)
+ : sizeof(CARD32))));
+
+ } /* for each MONO_ENCODING (fragment) */
+
+ /* Compute the alignment and concatenation point; however, */
+ /* the concatenation point (cpt) can be ignored here ! */
+
+ if (some_characters) {
+
+ micalc_cpt_and_align(&meta_font, &xmin, &xmax, &ymin, &ymax, path,
+ expansion, pAlignment, &cpt, align_pt);
+
+ } else {
+ /* no valid characters */
+ xmin = xmax = ymin = ymax = 0.0;
+ cpt.x = cpt.y = align_pt->x = align_pt->y = 0.0;
+ }
+
+ return (Success);
+}
+
+
+void
+text2_xform( pos, attrs, align, xf, aflag)
+ ddCoord2D *pos;
+ miDDContextRendAttrs *attrs;
+ ddVector2D *align;
+ register ddFLOAT xf[4][4];
+ ddUSHORT aflag;
+{
+ ddFLOAT ht_scale, inv_mag;
+ ddCoord2D vup;
+ ddCoord2D vbase;
+ register ddFLOAT a, b;
+ ddFLOAT temp[4][4], temp1[4][4];
+
+ /* Get the text or annotation text attribute values */
+
+ if (aflag == 0) {
+ ht_scale = ABS(attrs->charHeight / HEIGHT);
+ vup.x = attrs->charUp.x;
+ vup.y = attrs->charUp.y;
+ }
+ else {
+ ht_scale = ABS(attrs->atextHeight / HEIGHT);
+ vup.x = attrs->atextUp.x;
+ vup.y = attrs->atextUp.y;
+ }
+
+ inv_mag = 1.0 / sqrt( vup.x * vup.x + vup.y * vup.y);
+ vup.x *= inv_mag;
+ vup.y *= inv_mag;
+
+ /* Compute base vector = up vector rotated by 90 in Z */
+
+ vbase.x = vup.y;
+ vbase.y = -vup.x;
+
+ inv_mag = 1.0 / sqrt( vbase.x * vbase.x + vbase.y * vbase.y);
+ vbase.x *= inv_mag;
+ vbase.y *= inv_mag;
+
+ a = -ht_scale * align->x;
+ b = -ht_scale * align->y;
+
+ /* Initialize temp to identity */
+
+ miMatIdent (temp);
+
+ /* Store the scaling components */
+
+ temp[0][0] = temp[1][1] = ht_scale;
+
+ /* Store the translation components */
+
+ temp[0][3] = a;
+ temp[1][3] = b;
+
+ /* Let temp1 hold the base vector, the up vector, and the
+ text position. */
+
+ temp1[0][0] = vbase.x;
+ temp1[0][1] = vup.x;
+ temp1[0][2] = 0.0;
+ temp1[0][3] = pos->x;
+
+ temp1[1][0] = vbase.y;
+ temp1[1][1] = vup.y;
+ temp1[1][2] = 0.0;
+ temp1[1][3] = pos->y;
+
+ temp1[2][0] = temp1[3][0] = 0.0;
+ temp1[2][1] = temp1[3][1] = 0.0;
+ temp1[2][2] = temp1[3][3] = 1.0;
+ temp1[2][3] = 0.0;
+ temp1[3][2] = 0.0;
+
+ miMatMult( xf, temp, temp1 );
+}
+
+
+void
+text3_xform( pos, u, v, attrs, align, xf, aflag)
+ ddCoord3D *pos;
+ register ddVector3D *u, *v;
+ miDDContextRendAttrs *attrs;
+ ddVector2D *align;
+ register ddFLOAT xf[4][4];
+ ddUSHORT aflag;
+{
+ ddFLOAT ht_scale, inv_mag;
+ ddCoord3D vup;
+ ddCoord3D vbase;
+ register ddFLOAT a, b;
+ ddFLOAT temp[4][4], temp1[4][4];
+ ddFLOAT temp2[4][4], temp3[4][4];
+ ddVector3D e_one, e_two, e_three;
+ register ddVector3D *e3 = &e_three, *e2 = &e_two, *e1 = &e_one;
+
+ /* Get the text or annotation text attribute values */
+
+ if (aflag == 0) {
+ ht_scale = ABS(attrs->charHeight / HEIGHT);
+ vup.x = attrs->charUp.x;
+ vup.y = attrs->charUp.y;
+ vup.z = 0.0;
+ }
+ else {
+ ht_scale = ABS(attrs->atextHeight / HEIGHT);
+ vup.x = attrs->atextUp.x;
+ vup.y = attrs->atextUp.y;
+ vup.z = 0.0;
+ }
+
+ inv_mag = 1.0 / sqrt( vup.x * vup.x + vup.y * vup.y);
+ vup.x *= inv_mag;
+ vup.y *= inv_mag;
+
+ /* Compute base vector = up vector rotated by 90 in Z */
+
+ vbase.x = vup.y;
+ vbase.y = -vup.x;
+ vbase.z = 0.0;
+
+ inv_mag = 1.0 / sqrt( vbase.x * vbase.x + vbase.y * vbase.y);
+ vbase.x *= inv_mag;
+ vbase.y *= inv_mag;
+
+ a = -align->x * ht_scale;
+ b = -align->y * ht_scale;
+
+ /* Initialize temp to identity */
+
+ miMatIdent (temp);
+
+ /* Store the scaling components */
+
+ temp[0][0] = temp[1][1] = ht_scale;
+
+ /* Store the translation components */
+
+ temp[0][3] = a;
+ temp[1][3] = b;
+
+ /* Let temp1 hold the base vector and the up vector */
+
+ temp1[0][0] = vbase.x;
+ temp1[0][1] = vup.x;
+ temp1[0][2] = 0.0;
+ temp1[0][3] = 0.0;
+
+ temp1[1][0] = vbase.y;
+ temp1[1][1] = vup.y;
+ temp1[1][2] = 0.0;
+ temp1[1][3] = 0.0;
+
+ temp1[2][0] = temp1[3][0] = 0.0;
+ temp1[2][1] = temp1[3][1] = 0.0;
+ temp1[2][2] = temp1[3][3] = 1.0;
+ temp1[2][3] = 0.0;
+ temp1[3][2] = 0.0;
+
+ /* e3 is the cross-product of direction vectors u and v */
+
+ e3->x = u->y * v->z - u->z * v->y;
+ e3->y = u->z * v->x - u->x * v->z;
+ e3->z = u->x * v->y - u->y * v->x;
+
+ inv_mag = sqrt(e3->x * e3->x + e3->y * e3->y + e3->z * e3->z);
+
+ /* See if the direction is valid or if we can get by with a 2D
+ transform, i.e. if u and v are collinear. */
+
+ if ( MI_ZERO_MAG( inv_mag) ) {
+ miMatMult( xf, temp, temp1 );
+
+ } else { /* Build a 3D transform. */
+
+/* The rotation matrix, temp2, for orienting the text
+ coordinate space consists of the row vectors, e1, e2 and e3,
+ and the position. */
+
+/* Normalized vector e3 is row 3 of the rotation matrix */
+
+ inv_mag = 1.0 / inv_mag;
+ temp2[0][2] = e3->x*inv_mag;
+ temp2[1][2] = e3->y*inv_mag;
+ temp2[2][2] = e3->z*inv_mag;
+ temp2[3][2] = 0.0;
+
+/* e1 is the normalized u vector and is row 1 of the rotation
+ matrix. */
+
+ inv_mag = 1.0 / sqrt(u->x * u->x + u->y * u->y + u->z * u->z);
+ temp2[0][0] = e1->x = u->x * inv_mag;
+ temp2[1][0] = e1->y = u->y * inv_mag;
+ temp2[2][0] = e1->z = u->z * inv_mag;
+ temp2[3][0] = 0.0;
+
+/* e2 is the normalized v vector, (u X v) X u, and is row 2
+ of the rotation matrix. */
+
+ e2->x = e3->y * e1->z - e3->z * e1->y;
+ e2->y = e3->z * e1->x - e3->x * e1->z;
+ e2->z = e3->x * e1->y - e3->y * e1->x;
+ inv_mag = 1.0 / sqrt(e2->x * e2->x + e2->y * e2->y + e2->z * e2->z);
+ temp2[0][1] = (e2->x *= inv_mag);
+ temp2[1][1] = (e2->y *= inv_mag);
+ temp2[2][1] = (e2->z *= inv_mag);
+ temp2[3][1] = 0.0;
+
+ temp2[0][3] = pos->x;
+ temp2[1][3] = pos->y;
+ temp2[2][3] = pos->z;
+ temp2[3][3] = 1.0;
+
+/* The final transformation matrix, xf, is the product of the
+ 3 matrices: temp2 x temp1 x temp. */
+
+ miMatMult( temp3, temp1, temp2 );
+ miMatMult( xf, temp, temp3 );
+ }
+}
+
+
+/*++
+ |
+ | Function Name: miText3D
+ |
+ | Function Description:
+ | Handles the Text 3D ocs.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+miText3D(pRend, pExecuteOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pExecuteOC;
+/* out */
+{
+/* local */
+ miTextStruct *ddText = (miTextStruct *)(pExecuteOC+1);
+ miTextElement text_el; /* text element */
+ ddUSHORT numEncodings = ddText->numEncodings;
+ ddCoord3D *pOrigin = ddText->pOrigin; /* string origin */
+ ddCoord3D *pDirections = ddText->pDirections;/* orientation */
+ pexMonoEncoding *pText = ddText->pText; /* text string */
+
+/* calls */
+ extern ddpex3rtn miTransform();
+ extern ddpex3rtn miClipPolyLines();
+
+/* Define required temporary variables */
+
+ ddULONG numChars; /* Needed for xalloc */
+ pexMonoEncoding *pMono;
+ ddCoord2D align; /* alignment info */
+ ddFLOAT tc_to_cc_xform[4][4];
+ ddFLOAT tc_to_mc_xform[4][4];
+ ddFLOAT buf_xform[4][4];
+ miDDContext *pddc;
+ ddFLOAT exp, tx, ty;
+ ddFLOAT ptx, pty, ptx_first;
+ int i, j, k;
+ int count; /* Count of characters to be rendered */
+ ddFLOAT ei0cc, ei1cc, ei3cc;
+ ddFLOAT ei0mc, ei1mc, ei3mc;
+ miCharPath *save_ptr;
+ miListHeader *mc_path, *mclip_path, *cc_path, *clip_path, *dc_path;
+ listofddPoint *sp;
+ XID temp;
+ int status;
+ ddUSHORT aflag, clip_mode;
+
+ /* Set the annotation text flag to zero */
+
+ aflag = 0;
+
+ /* Get the DDContext handle for local use */
+
+ pddc = (miDDContext *)pRend->pDDContext;
+
+ /* Determine the total number of characters in the ISTRING */
+
+ numChars = 0;
+ pMono = pText;
+ for (i=0; i<numEncodings; i++) {
+ int bytes = pMono->numChars * ((pMono->characterSetWidth == PEXCSByte) ?
+ sizeof(CARD8) : ((pMono->characterSetWidth == PEXCSShort) ?
+ sizeof(CARD16) : sizeof(CARD32)));
+ numChars += (ddULONG)pMono->numChars;
+ pMono = (pexMonoEncoding *) ((char *) (pMono + 1) +
+ bytes + PADDING (bytes));
+ }
+
+ if (numChars == 0)
+ return (Success);
+
+
+ /* Convert text string into required paths */
+
+ if ((status = tx_el_to_path (pRend, pddc, numEncodings, pText,
+ numChars, &text_el, &align, &count)) != Success) {
+ return (status);
+ }
+
+ /* Compute the required Character Space to Modelling Space Transform */
+
+ text3_xform (pOrigin, pDirections, (pDirections+1),
+ pddc->Static.attrs, &align, text_el.xform, aflag);
+
+ /* Render the paths in text_el as polylines */
+
+ /* Set up the new composite transform first */
+
+ miMatMult (buf_xform, text_el.xform,
+ pddc->Dynamic->mc_to_cc_xform);
+
+ /* Get the current character expansion factor */
+
+ exp = ABS((ddFLOAT)pddc->Static.attrs->charExpansion);
+
+ /* Save the pointer to the beginning of the character data */
+
+ save_ptr = text_el.paths;
+
+ /* Check for modelling clip and set up the volume if required */
+
+ if (pddc->Dynamic->pPCAttr->modelClip == PEXClip) {
+ ComputeMCVolume(pRend, pddc); /* Get the current model clip volume */
+ }
+
+ /* Do for all characters (paths) in the text_el */
+
+ /* Initialize the previous translation components */
+
+ ptx = pty = 0.0;
+
+ for (k=0; k<count; k++) { /* Render characters one by one */
+
+ /* Check if the character is not renderable, for e.g., space char. */
+ /* If so just skip to next character in the ISTRING and continue. */
+
+ if (!(text_el.paths->path->ddList)) {
+ ptx = (ddFLOAT)(((text_el.paths)->trans).x);
+ pty = (ddFLOAT)(((text_el.paths)->trans).y);
+ text_el.paths++;
+ continue;
+ }
+
+ /* Modify the composite transform by the previous translation */
+ /* and the current scaling in x realizing the char expansion */
+
+ tx = ptx;
+ ty = pty;
+
+ ptx = (ddFLOAT)(((text_el.paths)->trans).x);
+ pty = (ddFLOAT)(((text_el.paths)->trans).y);
+
+ /* Check to see if this is the very first character and the text */
+ /* path is Up or Down. If so, we need to modify tx by the first */
+ /* character translation to align with the rest of the characters*/
+ /* in the string. */
+
+ if ((pddc->Static.attrs->textPath == PEXPathUp ||
+ pddc->Static.attrs->textPath == PEXPathDown) && k == 0)
+ tx += ptx;
+
+ /* NOTE THAT THE ABOVE COMPUTATION WILL ONLY WORK FOR THE FIRST */
+ /* CHARACTER IN THE STRING. ptx FOR ALL OTHER CHARACTERS WILL BE */
+ /* RELATIVE TO THE TEXT ORIGIN AND SO WILL NOT GIVE THE REQUIRED */
+ /* EFFECTIVE CHARACTER WIDTH. HOWEVER, THIS IS NOT A PROBLEM HERE*/
+ /* SINCE WE NEED THIS SPECIAL CASE ONLY FOR THE FIRST CHARACTER. */
+ /* */
+ /* FURTHER, NOTE THAT ptx WILL BE NEGATIVE AND HENCE USE OF += */
+
+ /* Check to see if the text path is Left. If so, we need to modify */
+ /* tx by the first character width so as to start the string to the*/
+ /* left of the text origin. */
+
+ if (k == 0) {
+ ptx_first = ptx; /* Get the first character translation */
+
+ /* Adjust the translation by character spacing factor to get */
+ /* just the character width. */
+
+ ptx_first += (pddc->Static.attrs->charSpacing) * FONT_COORD_HEIGHT;
+ }
+
+ if (pddc->Static.attrs->textPath == PEXPathLeft)
+ tx += ptx_first;
+
+ /* Check to see if modelling clip is required. If so, apply it */
+
+ if (pddc->Dynamic->pPCAttr->modelClip == PEXClip) {
+
+ /* Buffer the tc_to_mc_xform first */
+
+ memcpy( (char *)tc_to_mc_xform, (char *)text_el.xform, 16*sizeof(ddFLOAT));
+
+ /* Apply the per character translation and scaling by directly */
+ /* modifying the concerned matrix elements. */
+
+ for (i=0; i<4; ++i) {
+ /* Buffer the element values */
+ ei0mc = tc_to_mc_xform[i][0];
+ ei1mc = tc_to_mc_xform[i][1];
+ ei3mc = tc_to_mc_xform[i][3];
+ /* Modify the transform */
+ tc_to_mc_xform[i][0] = exp * ei0mc;
+ tc_to_mc_xform[i][3] = tx * ei0mc + ty * ei1mc + ei3mc;
+ }
+ /* Transform the character strokes into Model space */
+
+ if (status = miTransform(pddc, text_el.paths->path, &mc_path,
+ tc_to_mc_xform,
+ NULL4x4,
+ DD_HOMOGENOUS_POINT))
+ return (status);
+
+ if (status = miClipPolyLines(pddc, mc_path, &mclip_path, MI_MCLIP))
+ return (status);
+
+ }
+ else {
+ mclip_path = text_el.paths->path;
+ }
+
+ /* Buffer the tc_to_cc_xform first */
+
+ memcpy( (char *)tc_to_cc_xform, (char *)buf_xform, 16*sizeof(ddFLOAT));
+
+ /* Apply the per character translation and scaling by directly */
+ /* modifying the concerned matrix elements. */
+
+ for (i=0; i<4; ++i) {
+ /* Buffer the element values */
+ ei0cc = tc_to_cc_xform[i][0];
+ ei1cc = tc_to_cc_xform[i][1];
+ ei3cc = tc_to_cc_xform[i][3];
+ /* Modify the transform */
+ tc_to_cc_xform[i][0] = exp * ei0cc;
+ tc_to_cc_xform[i][3] = tx * ei0cc + ty * ei1cc + ei3cc;
+ }
+
+ /* Transform and clip the paths corresponding to current character */
+
+ if (pddc->Dynamic->pPCAttr->modelClip == PEXClip) {
+
+ /* Note that we are already in Model space here */
+
+ if (status = miTransform(pddc, mclip_path, &cc_path,
+ pddc->Dynamic->mc_to_cc_xform,
+ NULL4x4,
+ DD_HOMOGENOUS_POINT))
+ return (status);
+ }
+ else {
+
+ /* Note that we are still in text local space here ! */
+
+ if (status = miTransform(pddc, mclip_path, &cc_path,
+ tc_to_cc_xform,
+ NULL4x4,
+ DD_HOMOGENOUS_POINT))
+ return (status);
+ }
+
+ clip_mode = MI_VCLIP;
+ if (status = miClipPolyLines(pddc, cc_path, &clip_path, clip_mode))
+ return (status);
+
+ /* if nothing left, then update pointers and continue */
+ if (clip_path->numLists <= 0) {
+ text_el.paths++;
+ continue;
+ }
+
+ /* Transform to DC coordinates */
+
+ if (status = miTransform(pddc, clip_path, &dc_path,
+ pddc->Dynamic->cc_to_dc_xform,
+ NULL4x4,
+ DD_2DS_POINT))
+ return (status);
+
+ /* Render Text to screen */
+
+ pddc->Static.RenderProcs[TEXT_RENDER_TABLE_INDEX](pRend,
+ pddc,
+ dc_path);
+ /* Update the pointer to next character */
+
+ text_el.paths++;
+ }
+
+ /* Free up space allocated for text stroke data */
+
+ xfree ((char *)save_ptr);
+
+ return (Success);
+}
+
+/*++
+ |
+ | Function Name: miText2D
+ |
+ | Function Description:
+ | Handles the Text 2D ocs.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+miText2D(pRend, pExecuteOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pExecuteOC;
+/* out */
+{
+/* local */
+ miText2DStruct *ddText = (miText2DStruct *)(pExecuteOC+1);
+ miTextElement text_el; /* text element */
+ ddCoord2D *pOrigin = ddText->pOrigin; /* string origin */
+ ddUSHORT numEncodings = ddText->numEncodings;
+ pexMonoEncoding *pText = ddText->pText; /* text string */
+
+/* calls */
+ extern ddpex3rtn miTransform();
+ extern ddpex3rtn miClipPolyLines();
+
+/* Define required temporary variables */
+
+ ddULONG numChars; /* Needed for xalloc */
+ pexMonoEncoding *pMono;
+ ddCoord2D align; /* alignment info */
+ ddFLOAT tc_to_cc_xform[4][4];
+ ddFLOAT tc_to_mc_xform[4][4];
+ ddFLOAT buf_xform[4][4];
+ miDDContext *pddc;
+ ddFLOAT exp, tx, ty;
+ ddFLOAT ptx, pty, ptx_first;
+ int i, j, k;
+ int count; /* Count of characters to be rendered */
+ ddFLOAT ei0cc, ei1cc, ei3cc;
+ ddFLOAT ei0mc, ei1mc, ei3mc;
+ miCharPath *save_ptr;
+ miListHeader *mc_path, *mclip_path, *cc_path, *clip_path, *dc_path;
+ listofddPoint *sp;
+ XID temp;
+ int status;
+ ddUSHORT aflag, clip_mode;
+
+ /* Set the annotation text flag to zero */
+
+ aflag = 0;
+
+ /* Get the DDContext handle for local use */
+
+ pddc = (miDDContext *)pRend->pDDContext;
+
+ /* Determine the total number of characters in the ISTRING */
+
+ numChars = 0;
+ pMono = pText;
+ for (i=0; i<numEncodings; i++) {
+ int bytes = pMono->numChars * ((pMono->characterSetWidth == PEXCSByte) ?
+ sizeof(CARD8) : ((pMono->characterSetWidth == PEXCSShort) ?
+ sizeof(CARD16) : sizeof(CARD32)));
+ numChars += (ddULONG)pMono->numChars;
+ pMono = (pexMonoEncoding *) ((char *) (pMono + 1) +
+ bytes + PADDING (bytes));
+ }
+
+ if (numChars == 0)
+ return (Success);
+
+
+ /* Convert text string into required paths */
+
+ if ((status = tx_el_to_path (pRend, pddc, numEncodings, pText,
+ numChars, &text_el, &align, &count)) != Success) {
+ return (status);
+ }
+
+ /* Compute the required Character Space to Modelling Space Transform */
+
+ text2_xform (pOrigin, pddc->Static.attrs, &align, text_el.xform, aflag);
+
+ /* Render the paths in text_el as polylines */
+
+ /* Set up the new composite transform first */
+
+ miMatMult (buf_xform, text_el.xform,
+ pddc->Dynamic->mc_to_cc_xform);
+
+ /* Get the current character expansion factor */
+
+ exp = ABS((ddFLOAT)pddc->Static.attrs->charExpansion);
+
+ /* Save the pointer to the beginning of the character data */
+
+ save_ptr = text_el.paths;
+
+ /* Check for modelling clip and set up the volume if required */
+
+ if (pddc->Dynamic->pPCAttr->modelClip == PEXClip) {
+ ComputeMCVolume(pRend, pddc); /* Get the current model clip volume */
+ }
+
+ /* Do for all characters (paths) in the text_el */
+
+ /* Initialize the previous translation components */
+
+ ptx = pty = 0.0;
+
+ for (k=0; k<count; k++) { /* Render characters one by one */
+
+ /* Check if the character is not renderable, for e.g., space char. */
+ /* If so just skip to next character in the ISTRING and continue. */
+
+ if (!(text_el.paths->path->ddList)) {
+ ptx = (ddFLOAT)(((text_el.paths)->trans).x);
+ pty = (ddFLOAT)(((text_el.paths)->trans).y);
+ text_el.paths++;
+ continue;
+ }
+
+ /* Modify the composite transform by the previous translation */
+ /* and the current scaling in x realizing the char expansion */
+
+ tx = ptx;
+ ty = pty;
+
+ ptx = (ddFLOAT)(((text_el.paths)->trans).x);
+ pty = (ddFLOAT)(((text_el.paths)->trans).y);
+
+ /* Check to see if this is the very first character and the text */
+ /* path is Up or Down. If so, we need to modify tx by the first */
+ /* character translation to align with the rest of the characters*/
+ /* in the string. */
+
+ if ((pddc->Static.attrs->textPath == PEXPathUp ||
+ pddc->Static.attrs->textPath == PEXPathDown) && k == 0)
+ tx += ptx;
+
+ /* NOTE THAT THE ABOVE COMPUTATION WILL ONLY WORK FOR THE FIRST */
+ /* CHARACTER IN THE STRING. ptx FOR ALL OTHER CHARACTERS WILL BE */
+ /* RELATIVE TO THE TEXT ORIGIN AND SO WILL NOT GIVE THE REQUIRED */
+ /* EFFECTIVE CHARACTER WIDTH. HOWEVER, THIS IS NOT A PROBLEM HERE*/
+ /* SINCE WE NEED THIS SPECIAL CASE ONLY FOR THE FIRST CHARACTER. */
+ /* */
+ /* FURTHER, NOTE THAT ptx WILL BE NEGATIVE AND HENCE USE OF += */
+
+ /* Check to see if the text path is Left. If so, we need to modify */
+ /* tx by the first character width so as to start the string to the*/
+ /* left of the text origin. */
+
+ if (k == 0) {
+ ptx_first = ptx; /* Get the first character translation */
+
+ /* Adjust the translation by character spacing factor to get */
+ /* just the character width. */
+
+ ptx_first += (pddc->Static.attrs->charSpacing) * FONT_COORD_HEIGHT;
+ }
+
+ if (pddc->Static.attrs->textPath == PEXPathLeft)
+ tx += ptx_first;
+
+ /* Check to see if modelling clip is required. If so, apply it */
+
+ if (pddc->Dynamic->pPCAttr->modelClip == PEXClip) {
+
+ /* Buffer the tc_to_mc_xform first */
+
+ memcpy( (char *)tc_to_mc_xform, (char *)text_el.xform, 16*sizeof(ddFLOAT));
+
+ /* Apply the per character translation and scaling by directly */
+ /* modifying the concerned matrix elements. */
+
+ for (i=0; i<4; ++i) {
+ /* Buffer the element values */
+ ei0mc = tc_to_mc_xform[i][0];
+ ei1mc = tc_to_mc_xform[i][1];
+ ei3mc = tc_to_mc_xform[i][3];
+ /* Modify the transform */
+ tc_to_mc_xform[i][0] = exp * ei0mc;
+ tc_to_mc_xform[i][3] = tx * ei0mc + ty * ei1mc + ei3mc;
+ }
+ /* Transform the character strokes into Model space */
+
+ if (status = miTransform(pddc, text_el.paths->path, &mc_path,
+ tc_to_mc_xform,
+ NULL4x4,
+ DD_HOMOGENOUS_POINT))
+ return (status);
+
+ if (status = miClipPolyLines(pddc, mc_path, &mclip_path, MI_MCLIP))
+ return (status);
+ }
+ else {
+ mclip_path = text_el.paths->path;
+ }
+
+ /* Buffer the tc_to_cc_xform first */
+
+ memcpy( (char *)tc_to_cc_xform, (char *)buf_xform, 16*sizeof(ddFLOAT));
+
+ /* Apply the per character translation and scaling by directly */
+ /* modifying the concerned matrix elements. */
+
+ for (i=0; i<4; ++i) {
+ /* Buffer the element values */
+ ei0cc = tc_to_cc_xform[i][0];
+ ei1cc = tc_to_cc_xform[i][1];
+ ei3cc = tc_to_cc_xform[i][3];
+ /* Modify the transform */
+ tc_to_cc_xform[i][0] = exp * ei0cc;
+ tc_to_cc_xform[i][3] = tx * ei0cc + ty * ei1cc + ei3cc;
+ }
+
+ /* Transform and clip the paths corresponding to current character */
+
+ if (pddc->Dynamic->pPCAttr->modelClip == PEXClip) {
+
+ /* Note that we are already in Model space here */
+
+ if (status = miTransform(pddc, mclip_path, &cc_path,
+ pddc->Dynamic->mc_to_cc_xform,
+ NULL4x4,
+ DD_HOMOGENOUS_POINT))
+ return (status);
+
+ }
+ else {
+
+ /* Note that we are still in text local space here ! */
+
+ if (status = miTransform(pddc, mclip_path, &cc_path,
+ tc_to_cc_xform,
+ NULL4x4,
+ DD_HOMOGENOUS_POINT))
+ return (status);
+ }
+
+ clip_mode = MI_VCLIP;
+ if (status = miClipPolyLines(pddc, cc_path, &clip_path, clip_mode))
+ return (status);
+
+ /* if nothing left, then update pointers and continue */
+ if (clip_path->numLists <= 0) {
+ text_el.paths++;
+ continue;
+ }
+
+ /* Transform to DC coordinates */
+
+ if (status = miTransform(pddc, clip_path, &dc_path,
+ pddc->Dynamic->cc_to_dc_xform,
+ NULL4x4,
+ DD_2DS_POINT))
+ return (status);
+
+ /* Render Text to screen */
+
+ pddc->Static.RenderProcs[TEXT_RENDER_TABLE_INDEX](pRend,
+ pddc,
+ dc_path);
+
+ /* Update the pointer to next character */
+
+ text_el.paths++;
+ }
+
+ /* Free up space allocated for text stroke data */
+
+ xfree ((char *)save_ptr);
+
+ return (Success);
+}
+
+
+/*++
+ |
+ | Function Name: miAnnoText3D
+ |
+ | Function Description:
+ | Handles the Annotation text 3D ocs.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+miAnnoText3D(pRend, pExecuteOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pExecuteOC;
+/* out */
+{
+ /* local */
+ miAnnoTextStruct *ddText = (miAnnoTextStruct *)(pExecuteOC+1);
+ miTextElement text_el; /* text element */
+ ddUSHORT numEncodings = ddText->numEncodings;
+ ddCoord3D *pOrigin = ddText->pOrigin; /* string origin */
+ ddCoord3D *pOffset = ddText->pOffset;
+ pexMonoEncoding *pText = ddText->pText; /* text string */
+
+/* calls */
+ extern ddpex3rtn miTransform();
+ extern ddpex3rtn miClipPolyLines();
+
+/* Define required temporary variables */
+
+ ddULONG numChars; /* Needed for xalloc */
+ pexMonoEncoding *pMono;
+ ddCoord2D align; /* alignment info */
+ ddFLOAT tc_to_cc_xform[4][4];
+ ddFLOAT tc_to_mc_xform[4][4];
+ ddFLOAT buf_xform[4][4];
+ ddFLOAT buf1_xform[4][4];
+ miDDContext *pddc;
+ ddFLOAT exp, tx, ty;
+ ddFLOAT ptx, pty, ptx_first, pty_first;
+ int i, j, k;
+ int count; /* Count of characters to be rendered */
+ ddFLOAT ei0cc, ei1cc, ei3cc;
+ ddFLOAT ei0mc, ei1mc, ei3mc;
+ miCharPath *save_ptr;
+ miListHeader *mc_path, *mclip_path, *cc_path, *clip_path, *dc_path;
+ listofddPoint *sp;
+ XID temp;
+ int status;
+ ddUSHORT aflag;
+ static ddVector3D Directions[2] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0};
+ ddCoord3D *pDirections = (ddCoord3D *)Directions;
+ miListHeader Connector;
+ ddCoord4D CC_Offset; /* Offset in Clipping Coordinates */
+ ddCoord4D MC_Origin, CC_Origin, NPC_Origin;
+ ddUSHORT oc; /* Outcode for 4D point clipping */
+ ddUSHORT clip_mode; /* distinguish model from view " */
+
+ /* Get the DDContext handle for local use */
+
+ pddc = (miDDContext *)pRend->pDDContext;
+
+ /* Transform and clip the text origin first to see if any rendering*/
+ /* needs to be done at all. If the NPC sub-volume does not contain */
+ /* the origin, the annotation text is not rendered. */
+
+ MC_Origin.x = pOrigin->x;
+ MC_Origin.y = pOrigin->y;
+ MC_Origin.z = pOrigin->z;
+ MC_Origin.w = 1.0;
+
+ if (pddc->Dynamic->pPCAttr->modelClip == PEXClip) {
+
+ ComputeMCVolume(pRend, pddc); /* Compute modelling coord version
+ of clipping volume */
+ clip_mode = MI_MCLIP;
+ CLIP_POINT4D(&MC_Origin, oc, clip_mode);
+
+ if (oc) return (Success); /* origin model clipped out */
+ }
+
+ miTransformPoint (&MC_Origin, pddc->Dynamic->mc_to_cc_xform,
+ &CC_Origin);
+
+ clip_mode = MI_VCLIP;
+ CLIP_POINT4D(&CC_Origin, oc, clip_mode);
+ if (oc) {
+ return (Success); /* origin view clipped out */
+ }
+
+ /* Compute the NPC_Origin for later use */
+
+ miMatMult (buf_xform, pddc->Dynamic->mc_to_wc_xform,
+ pddc->Dynamic->wc_to_npc_xform);
+ miTransformPoint (&MC_Origin, buf_xform, &NPC_Origin);
+
+ /* Set the annotation text flag to one */
+
+ aflag = 1;
+
+ /* Transform the NPC Offset to CC. Note that we are transforming a */
+ /* vector. i.e., only scaling components of the viewport transform */
+ /* need be applied. This is simply done by multiplication of the x */
+ /* and y components by the respective scale factors. */
+
+ CC_Offset.x = pOffset->x * pddc->Dynamic->npc_to_cc_xform[0][0];
+ CC_Offset.y = pOffset->y * pddc->Dynamic->npc_to_cc_xform[1][1];
+ CC_Offset.z = pOffset->z * pddc->Dynamic->npc_to_cc_xform[2][2];
+ CC_Offset.w = 0.0;
+
+ /* Determine the total number of characters in the ISTRING */
+
+ numChars = 0;
+ pMono = pText;
+ for (i=0; i<numEncodings; i++) {
+ int bytes = pMono->numChars * ((pMono->characterSetWidth == PEXCSByte) ?
+ sizeof(CARD8) : ((pMono->characterSetWidth == PEXCSShort) ?
+ sizeof(CARD16) : sizeof(CARD32)));
+ numChars += (ddULONG)pMono->numChars;
+ pMono = (pexMonoEncoding *) ((char *) (pMono + 1) +
+ bytes + PADDING (bytes));
+ }
+
+ if (numChars == 0)
+ return (Success);
+
+
+ /* Convert text string into required paths */
+
+ if ((status = atx_el_to_path (pRend, pddc, numEncodings, pText,
+ numChars, &text_el, &align, &count)) != Success) {
+ return (status);
+ }
+
+ /* Compute the required Character Space to Modelling Space Transform */
+
+ text3_xform (pOrigin, pDirections, (pDirections+1),
+ pddc->Static.attrs, &align, text_el.xform, aflag);
+
+ /* Set up the new composite transform first. Note that in the case */
+ /* of annotation text, only the text origin is transformed by the */
+ /* complete pipeline transform. The text itself is affected only by*/
+ /* the transformed origin in NPC, the NPC offset , npc_to_cc, and */
+ /* the workstation transform. */
+
+ /* Now compute the initial composite transform for the first char. */
+ /* The required transforms for characters are - text space to model */
+ /* space transform, transformation of the annotation text origin, if*/
+ /* any, and the npc to cc transform. */
+
+ /* Get the translation due to the transformation of the annotation */
+ /* text origin by mc_to_npc_xform into buf1_xform. */
+
+ memcpy( (char *)buf1_xform, (char *) ident4x4, 16 * sizeof(ddFLOAT));
+ buf1_xform[0][3] += NPC_Origin.x - MC_Origin.x;
+ buf1_xform[1][3] += NPC_Origin.y - MC_Origin.y;
+ buf1_xform[2][3] += NPC_Origin.z - MC_Origin.z;
+
+ miMatMult (buf_xform, text_el.xform, buf1_xform);
+ miMatMult (buf_xform, buf_xform, pddc->Dynamic->npc_to_cc_xform);
+
+ /* Add the offset in CC */
+
+ buf_xform[0][3] += CC_Offset.x;
+ buf_xform[1][3] += CC_Offset.y;
+ buf_xform[2][3] += CC_Offset.z;
+
+ /******** Render the text string first, and then the connector ********/
+
+ /* Render the paths in text_el as polylines */
+
+ /* Get the current character expansion factor */
+
+ exp = ABS((ddFLOAT)pddc->Static.attrs->charExpansion);
+
+ /* Save the pointer to the beginning of the character data */
+
+ save_ptr = text_el.paths;
+
+ /* Do for all characters (paths) in the text_el */
+
+ /* Initialize the previous translation components */
+
+ ptx = pty = 0.0;
+
+ for (k=0; k<count; k++) { /* Render characters one by one */
+
+ /* Check if the character is not renderable, for e.g., space char. */
+ /* If so just skip to next character in the ISTRING and continue. */
+
+ if (!(text_el.paths->path->ddList)) {
+ ptx = (ddFLOAT)(((text_el.paths)->trans).x);
+ pty = (ddFLOAT)(((text_el.paths)->trans).y);
+ text_el.paths++;
+ continue;
+ }
+
+ /* Modify the composite transform by the previous translation */
+ /* and the current scaling in x realizing the char expansion */
+
+ tx = ptx;
+ ty = pty;
+
+ ptx = (ddFLOAT)(((text_el.paths)->trans).x);
+ pty = (ddFLOAT)(((text_el.paths)->trans).y);
+
+ /* Check to see if this is the very first character and the text */
+ /* path is Up or Down. If so, we need to modify tx by the first */
+ /* character translation to align with the rest of the characters*/
+ /* in the string. */
+
+ if ((pddc->Static.attrs->atextPath == PEXPathUp ||
+ pddc->Static.attrs->atextPath == PEXPathDown) && k == 0)
+ tx += ptx;
+
+ /* NOTE THAT THE ABOVE COMPUTATION WILL ONLY WORK FOR THE FIRST */
+ /* CHARACTER IN THE STRING. ptx FOR ALL OTHER CHARACTERS WILL BE */
+ /* RELATIVE TO THE TEXT ORIGIN AND SO WILL NOT GIVE THE REQUIRED */
+ /* EFFECTIVE CHARACTER WIDTH. HOWEVER, THIS IS NOT A PROBLEM HERE*/
+ /* SINCE WE NEED THIS SPECIAL CASE ONLY FOR THE FIRST CHARACTER. */
+ /* */
+ /* FURTHER, NOTE THAT ptx WILL BE NEGATIVE AND HENCE USE OF += */
+
+ if (k == 0) {
+ ptx_first = ptx; /* Get the first character translation */
+
+ /* Adjust the translation by character spacing factor to get */
+ /* just the character width. */
+
+ ptx_first += (pddc->Static.attrs->charSpacing) * FONT_COORD_HEIGHT;
+
+ pty_first = pty; /* Save first character height */
+ }
+
+ /* Check to see if the text path is Left. If so, we need to modify */
+ /* tx by the first character width so as to start the string to the*/
+ /* left of the text origin. */
+
+ if (pddc->Static.attrs->atextPath == PEXPathLeft)
+ tx += ptx_first;
+
+ /* Check to see if modelling clip is required. If so, apply it */
+
+ if (pddc->Dynamic->pPCAttr->modelClip == PEXClip) {
+
+ /* Buffer the tc_to_mc_xform first */
+
+ memcpy( (char *)tc_to_mc_xform, (char *)text_el.xform, 16*sizeof(ddFLOAT));
+
+ /* Apply the per character translation and scaling by directly */
+ /* modifying the concerned matrix elements. */
+
+ for (i=0; i<4; ++i) {
+ /* Buffer the element values */
+ ei0mc = tc_to_mc_xform[i][0];
+ ei1mc = tc_to_mc_xform[i][1];
+ ei3mc = tc_to_mc_xform[i][3];
+ /* Modify the transform */
+ tc_to_mc_xform[i][0] = exp * ei0mc;
+ tc_to_mc_xform[i][3] = tx * ei0mc + ty * ei1mc + ei3mc;
+ }
+ /* Transform the character strokes into Model space */
+
+ if (status = miTransform(pddc, text_el.paths->path, &mc_path,
+ tc_to_mc_xform,
+ NULL4x4,
+ DD_HOMOGENOUS_POINT))
+ return (status);
+
+ if (status = miClipPolyLines(pddc, mc_path, &mclip_path, MI_MCLIP))
+ return (status);
+ }
+ else {
+ mclip_path = text_el.paths->path;
+ }
+
+ /* Buffer the tc_to_cc_xform first */
+ memcpy( (char *)tc_to_cc_xform, (char *)buf_xform, 16*sizeof(ddFLOAT));
+
+ /* Apply the per character translation and scaling by directly */
+ /* modifying the concerned matrix elements. */
+
+ for (i=0; i<4; ++i) {
+ /* Buffer the element values */
+ ei0cc = tc_to_cc_xform[i][0];
+ ei1cc = tc_to_cc_xform[i][1];
+ ei3cc = tc_to_cc_xform[i][3];
+ /* Modify the transform */
+ tc_to_cc_xform[i][0] = exp * ei0cc;
+ tc_to_cc_xform[i][3] = tx * ei0cc + ty * ei1cc + ei3cc;
+ }
+
+ /* Transform and clip the paths corresponding to current character */
+
+ if (pddc->Dynamic->pPCAttr->modelClip == PEXClip) {
+
+ /* Note that we are already in Model space here */
+
+ if (status = miTransform(pddc, mclip_path, &cc_path,
+ pddc->Dynamic->mc_to_cc_xform,
+ NULL4x4,
+ DD_HOMOGENOUS_POINT))
+ return (status);
+ }
+ else {
+
+ /* Note that we are still in text local space here ! */
+
+ if (status = miTransform(pddc, mclip_path, &cc_path,
+ tc_to_cc_xform,
+ NULL4x4,
+ DD_HOMOGENOUS_POINT))
+ return (status);
+ }
+
+ /* Clip */
+
+ clip_mode = MI_VCLIP;
+ if (status = miClipPolyLines(pddc, cc_path, &clip_path, clip_mode))
+ return (status);
+
+ /* if nothing left, then update pointers and continue */
+ if (clip_path->numLists <= 0) {
+ text_el.paths++;
+ continue;
+ }
+
+ /* Transform to DC coordinates */
+
+ if (status = miTransform(pddc, clip_path, &dc_path,
+ pddc->Dynamic->cc_to_dc_xform,
+ NULL4x4,
+ DD_2DS_POINT))
+ return (status);
+
+ /* Render Text to screen */
+
+ pddc->Static.RenderProcs[TEXT_RENDER_TABLE_INDEX](pRend,
+ pddc,
+ dc_path);
+
+ /* Update the pointer to next character */
+
+ text_el.paths++;
+ }
+
+ /* Check the annotation style and draw a connecting line to the text */
+
+ if (pddc->Static.attrs->atextStyle == 2) {
+
+ /* Use the offset and text origin to build a polyline */
+
+ Connector.type = DD_3D_POINT;
+ Connector.numLists = 1;
+ if (!(Connector.ddList = (listofddPoint *)
+ xalloc(sizeof(listofddPoint))))
+ return (BadAlloc);
+ Connector.ddList->numPoints = 2;
+ if (!((Connector.ddList->pts.p3Dpt) = (ddCoord3D *)
+ xalloc(sizeof(ddCoord3D) * 2)))
+ return (BadAlloc);
+
+ Connector.ddList->pts.p3Dpt->x = pOrigin->x;
+ Connector.ddList->pts.p3Dpt->y = pOrigin->y;
+ Connector.ddList->pts.p3Dpt->z = pOrigin->z;
+ Connector.ddList->pts.p3Dpt++;
+ Connector.ddList->pts.p3Dpt->x = pOrigin->x;
+ Connector.ddList->pts.p3Dpt->y = pOrigin->y;
+ Connector.ddList->pts.p3Dpt->z = pOrigin->z;
+ Connector.ddList->pts.p3Dpt--; /* Reset pointer to head of the list */
+
+ /* Render the connector as a polyline */
+
+ /* Transform and clip the connector polyline */
+
+ if (status = miTransform(pddc, &Connector, &cc_path,
+ pddc->Dynamic->mc_to_cc_xform,
+ NULL4x4,
+ DD_HOMOGENOUS_POINT))
+ return (status);
+
+ /* Modify the second point by the amount of transformed offset. */
+
+ cc_path->ddList->pts.p4Dpt++;
+ cc_path->ddList->pts.p4Dpt->x += CC_Offset.x;
+ cc_path->ddList->pts.p4Dpt->y += CC_Offset.y;
+ cc_path->ddList->pts.p4Dpt->z += CC_Offset.z;
+ cc_path->ddList->pts.p4Dpt--; /* Reset pointer to head of the list */
+
+ /* Clip */
+
+ clip_mode = MI_VCLIP;
+ if (status = miClipPolyLines(pddc, cc_path, &clip_path, clip_mode))
+ return (status);
+
+ /* Transform to DC coordinates */
+
+ if (status = miTransform(pddc, clip_path, &dc_path,
+ pddc->Dynamic->cc_to_dc_xform,
+ NULL4x4,
+ DD_2DS_POINT))
+ return (status);
+
+ /* Render Connector to screen */
+
+ pddc->Static.RenderProcs[POLYLINE_RENDER_TABLE_INDEX](pRend,
+ pddc,
+ dc_path);
+
+ } /* if atextStyle == 2 */
+
+ /* Free up space allocated for text stroke data */
+
+ xfree ((char *)save_ptr);
+
+ return (Success);
+}
+
+/*++
+ |
+ | Function Name: miAnnoText2D
+ |
+ | Function Description:
+ | Handles the Annotation text 2D ocs.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+miAnnoText2D(pRend, pExecuteOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pExecuteOC;
+/* out */
+{
+ /* local */
+ miAnnoText2DStruct *ddText = (miAnnoText2DStruct *)(pExecuteOC+1);
+ miTextElement text_el; /* text element */
+ ddUSHORT numEncodings = ddText->numEncodings;
+ ddCoord2D *pOrigin = ddText->pOrigin; /* string origin */
+ ddCoord2D *pOffset = ddText->pOffset;
+ pexMonoEncoding *pText = ddText->pText; /* text string */
+
+/* calls */
+ extern ddpex3rtn miTransform();
+ extern ddpex3rtn miClipPolyLines();
+
+/* Define required temporary variables */
+
+ ddULONG numChars; /* Needed for xalloc */
+ pexMonoEncoding *pMono;
+ ddCoord2D align; /* alignment info */
+ ddFLOAT tc_to_cc_xform[4][4];
+ ddFLOAT tc_to_mc_xform[4][4];
+ ddFLOAT buf_xform[4][4];
+ ddFLOAT buf1_xform[4][4];
+ miDDContext *pddc;
+ ddFLOAT exp, tx, ty;
+ ddFLOAT ptx, pty, ptx_first, pty_first;
+ int i, j, k;
+ int count; /* Count of characters to be rendered */
+ ddFLOAT ei0cc, ei1cc, ei3cc;
+ ddFLOAT ei0mc, ei1mc, ei3mc;
+ miCharPath *save_ptr;
+ miListHeader *mc_path, *mclip_path, *cc_path, *clip_path, *dc_path;
+ listofddPoint *sp;
+ XID temp;
+ int status;
+ ddUSHORT aflag;
+ miListHeader Connector;
+ ddCoord4D CC_Offset; /* Offset in Clipping Coordinates */
+ ddCoord4D MC_Origin, CC_Origin, NPC_Origin;
+ ddUSHORT oc; /* Outcode for 4D point clipping */
+ ddUSHORT clip_mode;
+
+ /* Get the DDContext handle for local use */
+
+ pddc = (miDDContext *)pRend->pDDContext;
+
+ /* Transform and clip the text origin first to see if any rendering*/
+ /* needs to be done at all. If the NPC sub-volume does not contain */
+ /* the origin, the annotation text is not rendered. */
+
+ MC_Origin.x = pOrigin->x;
+ MC_Origin.y = pOrigin->y;
+ MC_Origin.z = 0.0;
+ MC_Origin.w = 1.0;
+
+ if (pddc->Dynamic->pPCAttr->modelClip == PEXClip) {
+
+ ComputeMCVolume(pRend, pddc); /* Compute modelling coord version
+ of clipping volume */
+ clip_mode = MI_MCLIP;
+ CLIP_POINT4D(&MC_Origin, oc, clip_mode);
+
+ if (oc) return (Success); /* origin model clipped out */
+ }
+
+ miTransformPoint (&MC_Origin, pddc->Dynamic->mc_to_cc_xform,
+ &CC_Origin);
+
+ clip_mode = MI_VCLIP;
+ CLIP_POINT4D(&CC_Origin, oc, clip_mode);
+ if (oc) {
+ return (Success); /* Don't render anything; origin clipped out */
+ }
+
+ /* Compute the NPC_Origin for later use */
+
+ miMatMult (buf_xform, pddc->Dynamic->mc_to_wc_xform,
+ pddc->Dynamic->wc_to_npc_xform);
+ miTransformPoint (&MC_Origin, buf_xform, &NPC_Origin);
+
+ /* Set the annotation text flag to one */
+
+ aflag = 1;
+
+ /* Transform the NPC Offset to CC. Note that we are transforming a */
+ /* vector. i.e., only scaling components of the viewport transform */
+ /* need be applied. This is simply done by multiplication of the x */
+ /* and y components by the respective scale factors. */
+
+ CC_Offset.x = pOffset->x * pddc->Dynamic->npc_to_cc_xform[0][0];
+ CC_Offset.y = pOffset->y * pddc->Dynamic->npc_to_cc_xform[1][1];
+ CC_Offset.z = 0.0;
+ CC_Offset.w = 0.0;
+
+ /* Determine the total number of characters in the ISTRING */
+
+ numChars = 0;
+ pMono = pText;
+ for (i=0; i<numEncodings; i++) {
+ int bytes = pMono->numChars * ((pMono->characterSetWidth == PEXCSByte) ?
+ sizeof(CARD8) : ((pMono->characterSetWidth == PEXCSShort) ?
+ sizeof(CARD16) : sizeof(CARD32)));
+ numChars += (ddULONG)pMono->numChars;
+ pMono = (pexMonoEncoding *) ((char *) (pMono + 1) +
+ bytes + PADDING (bytes));
+ }
+
+ if (numChars == 0)
+ return (Success);
+
+
+ /* Convert text string into required paths */
+
+ if ((status = atx_el_to_path (pRend, pddc, numEncodings, pText,
+ numChars, &text_el, &align, &count)) != Success) {
+ return (status);
+ }
+
+ /* Compute the required Character Space to Modelling Space Transform */
+
+ text2_xform (pOrigin, pddc->Static.attrs, &align, text_el.xform, aflag);
+
+ /* Set up the new composite transform first. Note that in the case */
+ /* of annotation text, only the text origin is transformed by the */
+ /* complete pipeline transform. The text itself is affected only by*/
+ /* the transformed origin in NPC, the NPC offset , npc_to_cc, and */
+ /* the workstation transform. */
+
+ /* Now compute the initial composite transform for the first char. */
+ /* The required transforms for characters are - text space to model */
+ /* space transform, transformation of the annotation text origin, if*/
+ /* any, and the npc to cc transform. */
+
+ /* Get the translation due to the transformation of the annotation */
+ /* text origin by mc_to_npc_xform into buf1_xform. */
+
+ memcpy( (char *)buf1_xform, (char *) ident4x4, 16 * sizeof(ddFLOAT));
+ buf1_xform[0][3] += NPC_Origin.x - MC_Origin.x;
+ buf1_xform[1][3] += NPC_Origin.y - MC_Origin.y;
+
+ miMatMult (buf_xform, text_el.xform, buf1_xform);
+ miMatMult (buf_xform, buf_xform, pddc->Dynamic->npc_to_cc_xform);
+
+ /* Add the offset in CC */
+
+ buf_xform[0][3] += CC_Offset.x;
+ buf_xform[1][3] += CC_Offset.y;
+
+ /******** Render the text string first, and then the connector ********/
+
+ /* Render the paths in text_el as polylines */
+
+ /* Get the current character expansion factor */
+
+ exp = ABS((ddFLOAT)pddc->Static.attrs->charExpansion);
+
+ /* Save the pointer to the beginning of the character data */
+
+ save_ptr = text_el.paths;
+
+ /* Do for all characters (paths) in the text_el */
+
+ /* Initialize the previous translation components */
+
+ ptx = pty = 0.0;
+
+ for (k=0; k<count; k++) { /* Render characters one by one */
+
+ /* Check if the character is not renderable, for e.g., space char. */
+ /* If so just skip to next character in the ISTRING and continue. */
+
+ if (!(text_el.paths->path->ddList)) {
+ ptx = (ddFLOAT)(((text_el.paths)->trans).x);
+ pty = (ddFLOAT)(((text_el.paths)->trans).y);
+ text_el.paths++;
+ continue;
+ }
+
+ /* Modify the composite transform by the previous translation */
+ /* and the current scaling in x realizing the char expansion */
+
+ tx = ptx;
+ ty = pty;
+
+ ptx = (ddFLOAT)(((text_el.paths)->trans).x);
+ pty = (ddFLOAT)(((text_el.paths)->trans).y);
+
+ /* Check to see if this is the very first character and the text */
+ /* path is Up or Down. If so, we need to modify tx by the first */
+ /* character translation to align with the rest of the characters*/
+ /* in the string. */
+
+ if ((pddc->Static.attrs->atextPath == PEXPathUp ||
+ pddc->Static.attrs->atextPath == PEXPathDown) && k == 0)
+ tx += ptx;
+
+ /* NOTE THAT THE ABOVE COMPUTATION WILL ONLY WORK FOR THE FIRST */
+ /* CHARACTER IN THE STRING. ptx FOR ALL OTHER CHARACTERS WILL BE */
+ /* RELATIVE TO THE TEXT ORIGIN AND SO WILL NOT GIVE THE REQUIRED */
+ /* EFFECTIVE CHARACTER WIDTH. HOWEVER, THIS IS NOT A PROBLEM HERE*/
+ /* SINCE WE NEED THIS SPECIAL CASE ONLY FOR THE FIRST CHARACTER. */
+ /* */
+ /* FURTHER, NOTE THAT ptx WILL BE NEGATIVE AND HENCE USE OF += */
+
+ if (k == 0) {
+ ptx_first = ptx; /* Get the first character translation */
+
+ /* Adjust the translation by character spacing factor to get */
+ /* just the character width. */
+
+ ptx_first += (pddc->Static.attrs->charSpacing) * FONT_COORD_HEIGHT;
+
+ pty_first = pty; /* Save first character height */
+
+ /* Adjust the translation by character spacing factor to get */
+ /* just the character height. */
+
+ pty_first += (pddc->Static.attrs->charSpacing) * FONT_COORD_HEIGHT;
+ }
+
+ /* Check to see if the text path is Left. If so, we need to modify */
+ /* tx by the first character width so as to start the string to the*/
+ /* left of the text origin. */
+
+ if (pddc->Static.attrs->atextPath == PEXPathLeft)
+ tx += ptx_first;
+
+ /* Check to see if modelling clip is required. If so, apply it */
+
+ if (pddc->Dynamic->pPCAttr->modelClip == PEXClip) {
+
+ /* Buffer the tc_to_mc_xform first */
+
+ memcpy( (char *)tc_to_mc_xform, (char *)text_el.xform, 16*sizeof(ddFLOAT));
+
+ /* Apply the per character translation and scaling by directly */
+ /* modifying the concerned matrix elements. */
+
+ for (i=0; i<4; ++i) {
+ /* Buffer the element values */
+ ei0mc = tc_to_mc_xform[i][0];
+ ei1mc = tc_to_mc_xform[i][1];
+ ei3mc = tc_to_mc_xform[i][3];
+ /* Modify the transform */
+ tc_to_mc_xform[i][0] = exp * ei0mc;
+ tc_to_mc_xform[i][3] = tx * ei0mc + ty * ei1mc + ei3mc;
+ }
+ /* Transform the character strokes into Model space */
+
+ if (status = miTransform(pddc, text_el.paths->path, &mc_path,
+ tc_to_mc_xform,
+ NULL4x4,
+ DD_HOMOGENOUS_POINT))
+ return (status);
+
+ if (status = miClipPolyLines(pddc, mc_path, &mclip_path, MI_MCLIP))
+ return (status);
+ }
+ else {
+ mclip_path = text_el.paths->path;
+ }
+
+ /* Buffer the tc_to_cc_xform first */
+
+ memcpy( (char *)tc_to_cc_xform, (char *)buf_xform, 16*sizeof(ddFLOAT));
+
+ /* Apply the per character translation and scaling by directly */
+ /* modifying the concerned matrix elements. */
+
+ for (i=0; i<4; ++i) {
+ /* Buffer the element values */
+ ei0cc = tc_to_cc_xform[i][0];
+ ei1cc = tc_to_cc_xform[i][1];
+ ei3cc = tc_to_cc_xform[i][3];
+ /* Modify the transform */
+ tc_to_cc_xform[i][0] = exp * ei0cc;
+ tc_to_cc_xform[i][3] = tx * ei0cc + ty * ei1cc + ei3cc;
+ }
+
+ /* Transform and clip the paths corresponding to current character */
+
+ if (pddc->Dynamic->pPCAttr->modelClip == PEXClip) {
+
+ /* Note that we are already in Model space here */
+
+ if (status = miTransform(pddc, mclip_path, &cc_path,
+ pddc->Dynamic->mc_to_cc_xform,
+ NULL4x4,
+ DD_HOMOGENOUS_POINT))
+ return (status);
+
+ }
+ else {
+
+ /* Note that we are still in text local space here ! */
+
+ if (status = miTransform(pddc, mclip_path, &cc_path,
+ tc_to_cc_xform,
+ NULL4x4,
+ DD_HOMOGENOUS_POINT))
+ return (status);
+ }
+
+ /* Clip */
+
+ clip_mode = MI_VCLIP;
+ if (status = miClipPolyLines(pddc, cc_path, &clip_path, clip_mode))
+ return (status);
+
+ /* if nothing left, then update pointers and continue */
+ if (clip_path->numLists <= 0) {
+ text_el.paths++;
+ continue;
+ }
+
+ /* Transform to DC coordinates */
+
+ if (status = miTransform(pddc, clip_path, &dc_path,
+ pddc->Dynamic->cc_to_dc_xform,
+ NULL4x4,
+ DD_2DS_POINT))
+ return (status);
+
+ /* Render Text to screen */
+
+ pddc->Static.RenderProcs[TEXT_RENDER_TABLE_INDEX](pRend,
+ pddc,
+ dc_path);
+
+ /* Update the pointer to next character */
+
+ text_el.paths++;
+ }
+
+ /* Check the annotation style and draw a connecting line to the text */
+
+ if (pddc->Static.attrs->atextStyle == 2) {
+
+ /* Use the offset and the text origin to build a polyline */
+
+ Connector.type = DD_2D_POINT;
+ Connector.numLists = 1;
+ if (!(Connector.ddList = (listofddPoint *) xalloc(sizeof(listofddPoint))))
+ return (BadAlloc);
+ Connector.ddList->numPoints = 2;
+ if (!((Connector.ddList->pts.p2Dpt) = (ddCoord2D *)
+ xalloc(sizeof(ddCoord2D) * 2)))
+ return (BadAlloc);
+ Connector.ddList->pts.p2Dpt->x = pOrigin->x;
+ Connector.ddList->pts.p2Dpt->y = pOrigin->y;
+ Connector.ddList->pts.p2Dpt++;
+ Connector.ddList->pts.p2Dpt->x = pOrigin->x;
+ Connector.ddList->pts.p2Dpt->y = pOrigin->y;
+ Connector.ddList->pts.p2Dpt--; /* Reset pointer to head of the list */
+
+ /* Render the connector as a polyline */
+
+ /* Transform and clip the connector polyline */
+
+ if (status = miTransform(pddc, &Connector, &cc_path,
+ pddc->Dynamic->mc_to_cc_xform,
+ NULL4x4,
+ DD_HOMOGENOUS_POINT))
+ return (status);
+
+ /* Modify the second point by the amount of transformed offset. */
+
+ cc_path->ddList->pts.p4Dpt++;
+ cc_path->ddList->pts.p4Dpt->x += CC_Offset.x;
+ cc_path->ddList->pts.p4Dpt->y += CC_Offset.y;
+ cc_path->ddList->pts.p4Dpt--; /* Reset pointer to head of the list */
+
+ /* Clip */
+
+ clip_mode = MI_VCLIP;
+ if (status = miClipPolyLines(pddc, cc_path, &clip_path, clip_mode))
+ return (status);
+
+ /* Transform to DC coordinates */
+
+ if (status = miTransform(pddc, clip_path, &dc_path,
+ pddc->Dynamic->cc_to_dc_xform,
+ NULL4x4,
+ DD_2DS_POINT))
+ return (status);
+
+ /* Render Connector to screen */
+
+ pddc->Static.RenderProcs[POLYLINE_RENDER_TABLE_INDEX](pRend,
+ pddc,
+ dc_path);
+ } /* if atextStyle == 2 */
+
+ /* Free up space allocated for text stroke data */
+
+ xfree ((char *)save_ptr);
+
+ return (Success);
+}
+
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level2/miTrans.c b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miTrans.c
new file mode 100644
index 000000000..8c5f041e7
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miTrans.c
@@ -0,0 +1,1024 @@
+/* $TOG: miTrans.c /main/4 1998/02/10 12:42:53 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level2/miTrans.c,v 1.7 1998/10/04 09:34:29 dawes Exp $ */
+
+#include "mipex.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "PEXErr.h"
+#include "miRender.h"
+#include "miLight.h"
+#include "pexos.h"
+
+#define IRINT(x) ( ((x) >= 0.0) ? ((int)((x) + 0.5)) : ((int)((x) - 0.5)) )
+
+/*++
+ |
+ | miTransform(pddc, vinput, voutput,
+ | vert_mat, norm_mat, outtype)
+ |
+ | Generalized vertex list transform routine.
+ |
+ | This routine takes in four parameters: a list of vertices,
+ | an output point type, and two matrices: one for transforming
+ | vertex data, the second for transforming normal data.
+ | The following assumptions are made:
+ | a) 2DS input is never used
+ | b) 2D input does not support normal, color or edge info
+ | c) output types do not have more attributes (color, normal or edge)
+ | than input data types
+ | d) only color specifiers with triplets of float values are
+ | supported
+ |
+ | All other cases produce undefined output
+ |
+ --*/
+
+ddpex3rtn
+miTransform(pddc, vinput, voutput, vert_mat, norm_mat, outtype)
+ miDDContext *pddc;
+ miListHeader *vinput;
+ miListHeader **voutput;
+ ddFLOAT vert_mat[4][4];
+ ddFLOAT norm_mat[4][4];
+ ddPointType outtype;
+{
+ ddCoord4D new_pt;
+ miListHeader *output;
+
+
+ register int i, j;
+ register listofddPoint *pddilist;
+ register listofddPoint *pddolist;
+
+ ddPointUnion in_pt,
+ out_pt;
+
+ ddCoord2D tmp_pt;
+
+ ddFLOAT length;
+
+ int output_size;
+
+ /* remember that ALL vertex types are of the form:
+ *
+ * |---------------------------|---------|----------|---------|
+ * coords color normal edge
+ * (opt) (opt) (opt)
+ */
+
+ /* Don't pass on normals unless valid xform */
+ if (norm_mat == NULL) DD_UnSetVertNormal(outtype);
+
+ DD_VertPointSize(outtype, output_size);
+
+
+ switch (outtype) {
+
+ case DD_RGBFLOAT_POINT4D:
+ case DD_HSV_POINT4D:
+ case DD_HLS_POINT4D:
+ case DD_CIE_POINT4D:
+ case DD_NORM_POINT4D:
+ case DD_EDGE_POINT4D:
+ case DD_RGBFLOAT_NORM_POINT4D:
+ case DD_HSV_NORM_POINT4D:
+ case DD_HLS_NORM_POINT4D:
+ case DD_CIE_NORM_POINT4D:
+ case DD_RGBFLOAT_EDGE_POINT4D:
+ case DD_HSV_EDGE_POINT4D:
+ case DD_HLS_EDGE_POINT4D:
+ case DD_CIE_EDGE_POINT4D:
+ case DD_NORM_EDGE_POINT4D:
+ case DD_RGBFLOAT_NORM_EDGE_POINT4D:
+ case DD_HSV_NORM_EDGE_POINT4D:
+ case DD_HLS_NORM_EDGE_POINT4D:
+ case DD_CIE_NORM_EDGE_POINT4D:
+ case DD_HOMOGENOUS_POINT:
+ {
+ switch (vinput->type) {
+ case DD_2D_POINT:
+ {
+
+ /* Use the pre-defined 4D list for output */
+ *voutput = output = MI_NEXTTEMPDATALIST(pddc);
+
+ /* Insure sufficient room for each header */
+ MI_ALLOCLISTHEADER(output, vinput->numLists)
+ if (!output->ddList) return(BadAlloc);
+
+ output->type = outtype;
+ output->numLists = vinput->numLists;
+ output->flags = vinput->flags;
+
+ pddilist = vinput->ddList;
+ pddolist = output->ddList;
+
+ /* Now, transform each list */
+ for(j=0; j < vinput->numLists; j++) {
+
+ if ((i = pddolist->numPoints = pddilist->numPoints) <= 0)
+ continue;
+
+ /*
+ * Insure sufficient room for each vertex
+ * Add one to leave room for possible polygon close.
+ */
+ MI_ALLOCLISTOFDDPOINT(pddolist,(i+1),output_size);
+ if(!(out_pt.p4Dpt = (pddolist->pts.p4Dpt)))
+ return(BadAlloc);
+
+ in_pt.p2Dpt = pddilist->pts.p2Dpt;
+
+ /* Note - just assume z = 0.0, w = 1.0 */
+ while (i--) {
+
+ out_pt.p4Dpt->x = vert_mat[0][0]*in_pt.p2Dpt->x;
+ out_pt.p4Dpt->x += vert_mat[0][1]*in_pt.p2Dpt->y;
+ out_pt.p4Dpt->x += vert_mat[0][3];
+
+ out_pt.p4Dpt->y = vert_mat[1][0]*in_pt.p2Dpt->x;
+ out_pt.p4Dpt->y += vert_mat[1][1]*in_pt.p2Dpt->y;
+ out_pt.p4Dpt->y += vert_mat[1][3];
+
+ out_pt.p4Dpt->z = vert_mat[2][0]*in_pt.p2Dpt->x;
+ out_pt.p4Dpt->z += vert_mat[2][1]*in_pt.p2Dpt->y;
+ out_pt.p4Dpt->z += vert_mat[2][3];
+
+ out_pt.p4Dpt->w = vert_mat[3][0]*in_pt.p2Dpt->x;
+ out_pt.p4Dpt->w += vert_mat[3][1]*in_pt.p2Dpt->y;
+ out_pt.p4Dpt->w += vert_mat[3][3];
+
+ in_pt.p2Dpt++;
+ out_pt.p4Dpt++;
+
+ /* At this point we should be pointing to
+ * to the beginning of the next vertex
+ */
+
+ }
+ pddilist++;
+ pddolist++;
+ }
+ break;
+ }
+ case DD_RGBFLOAT_POINT:
+ case DD_HSV_POINT:
+ case DD_HLS_POINT:
+ case DD_CIE_POINT:
+ case DD_NORM_POINT:
+ case DD_EDGE_POINT:
+ case DD_RGBFLOAT_NORM_POINT:
+ case DD_HSV_NORM_POINT:
+ case DD_HLS_NORM_POINT:
+ case DD_CIE_NORM_POINT:
+ case DD_RGBFLOAT_EDGE_POINT:
+ case DD_HSV_EDGE_POINT:
+ case DD_HLS_EDGE_POINT:
+ case DD_CIE_EDGE_POINT:
+ case DD_NORM_EDGE_POINT:
+ case DD_RGBFLOAT_NORM_EDGE_POINT:
+ case DD_HSV_NORM_EDGE_POINT:
+ case DD_HLS_NORM_EDGE_POINT:
+ case DD_CIE_NORM_EDGE_POINT:
+ case DD_3D_POINT:
+ {
+
+ /* Use the pre-defined 4D list for output */
+ *voutput = output = MI_NEXTTEMPDATALIST(pddc);
+
+ /* Insure sufficient room for each header */
+ MI_ALLOCLISTHEADER(output, vinput->numLists)
+ if (!output->ddList) return(BadAlloc);
+
+ output->type = outtype;
+ output->numLists = vinput->numLists;
+ output->flags = vinput->flags;
+
+ pddilist = vinput->ddList;
+ pddolist = output->ddList;
+
+ /* Now, transform each list */
+ for(j=0; j < vinput->numLists; j++) {
+
+ if ((i = pddolist->numPoints = pddilist->numPoints) <= 0)
+ continue;
+
+ /*
+ * Insure sufficient room for each vertex
+ * Add one to leave room for possible polygon close.
+ */
+ MI_ALLOCLISTOFDDPOINT(pddolist,(i+1),output_size);
+ if(!(out_pt.p4Dpt = (pddolist->pts.p4Dpt)))
+ return(BadAlloc);
+
+ in_pt.p3Dpt = pddilist->pts.p3Dpt;
+
+ /* Note - just assume w = 1.0 */
+ while (i--) {
+
+ /* cast operands & transform the coordinates
+ portions */
+
+
+ out_pt.p4Dpt->x = vert_mat[0][0]*in_pt.p3Dpt->x;
+ out_pt.p4Dpt->x += vert_mat[0][1]*in_pt.p3Dpt->y;
+ out_pt.p4Dpt->x += vert_mat[0][2]*in_pt.p3Dpt->z;
+ out_pt.p4Dpt->x += vert_mat[0][3];
+
+ out_pt.p4Dpt->y = vert_mat[1][0]*in_pt.p3Dpt->x;
+ out_pt.p4Dpt->y += vert_mat[1][1]*in_pt.p3Dpt->y;
+ out_pt.p4Dpt->y += vert_mat[1][2]*in_pt.p3Dpt->z;
+ out_pt.p4Dpt->y += vert_mat[1][3];
+
+ out_pt.p4Dpt->z = vert_mat[2][0]*in_pt.p3Dpt->x;
+ out_pt.p4Dpt->z += vert_mat[2][1]*in_pt.p3Dpt->y;
+ out_pt.p4Dpt->z += vert_mat[2][2]*in_pt.p3Dpt->z;
+ out_pt.p4Dpt->z += vert_mat[2][3];
+
+ out_pt.p4Dpt->w = vert_mat[3][0]*in_pt.p3Dpt->x;
+ out_pt.p4Dpt->w += vert_mat[3][1]*in_pt.p3Dpt->y;
+ out_pt.p4Dpt->w += vert_mat[3][2]*in_pt.p3Dpt->z;
+ out_pt.p4Dpt->w += vert_mat[3][3];
+
+ in_pt.p3Dpt++;
+ out_pt.p4Dpt++;
+
+ if (!DD_IsVertCoordsOnly(outtype)) {
+
+ if DD_IsVertColour(outtype) {
+ *out_pt.pRgbFloatClr =
+ *in_pt.pRgbFloatClr;
+ in_pt.pRgbFloatClr++;
+ out_pt.pRgbFloatClr++;
+ }
+
+
+ if DD_IsVertNormal(outtype) {
+
+
+ out_pt.pNormal->x = norm_mat[0][0]*in_pt.pNormal->x;
+ out_pt.pNormal->x += norm_mat[0][1]*in_pt.pNormal->y;
+ out_pt.pNormal->x += norm_mat[0][2]*in_pt.pNormal->z;
+ /* no translation */
+
+ out_pt.pNormal->y = norm_mat[1][0]*in_pt.pNormal->x;
+ out_pt.pNormal->y += norm_mat[1][1]*in_pt.pNormal->y;
+ out_pt.pNormal->y += norm_mat[1][2]*in_pt.pNormal->z;
+ /* no translation */
+
+ out_pt.pNormal->z = norm_mat[2][0]*in_pt.pNormal->x;
+ out_pt.pNormal->z += norm_mat[2][1]*in_pt.pNormal->y;
+ out_pt.pNormal->z += norm_mat[2][2]*in_pt.pNormal->z;
+ /* no translation */
+
+ NORMALIZE_VECTOR (out_pt.pNormal, length);
+
+ in_pt.pNormal++;
+ out_pt.pNormal++;
+ }
+
+ if (DD_IsVertEdge(outtype)) {
+ *out_pt.pEdge = *in_pt.pEdge;
+ in_pt.pEdge++;
+ out_pt.pEdge++;
+ }
+ }
+
+ /* At this point we should be pointing to
+ * to the beginning of the next vertex
+ */
+ }
+ pddilist++;
+ pddolist++;
+ }
+ break;
+ }
+ case DD_RGBFLOAT_POINT4D:
+ case DD_HSV_POINT4D:
+ case DD_HLS_POINT4D:
+ case DD_CIE_POINT4D:
+ case DD_NORM_POINT4D:
+ case DD_EDGE_POINT4D:
+ case DD_RGBFLOAT_NORM_POINT4D:
+ case DD_HSV_NORM_POINT4D:
+ case DD_HLS_NORM_POINT4D:
+ case DD_CIE_NORM_POINT4D:
+ case DD_RGBFLOAT_EDGE_POINT4D:
+ case DD_HSV_EDGE_POINT4D:
+ case DD_HLS_EDGE_POINT4D:
+ case DD_CIE_EDGE_POINT4D:
+ case DD_NORM_EDGE_POINT4D:
+ case DD_RGBFLOAT_NORM_EDGE_POINT4D:
+ case DD_HSV_NORM_EDGE_POINT4D:
+ case DD_HLS_NORM_EDGE_POINT4D:
+ case DD_CIE_NORM_EDGE_POINT4D:
+ case DD_HOMOGENOUS_POINT:
+ {
+
+ /* Use the pre-defined 4D list for output */
+ *voutput = output = MI_NEXTTEMPDATALIST(pddc);
+
+ /* Insure sufficient room for each header */
+ MI_ALLOCLISTHEADER(output, vinput->numLists)
+ if (!output->ddList) return(BadAlloc);
+
+ output->type = outtype;
+ output->numLists = vinput->numLists;
+ output->flags = vinput->flags;
+
+ pddilist = vinput->ddList;
+ pddolist = output->ddList;
+
+ /* Now, transform each list */
+ for(j=0; j < vinput->numLists; j++) {
+
+ if ((i = pddolist->numPoints = pddilist->numPoints) <= 0)
+ continue;
+
+ /*
+ * Insure sufficient room for each vertex
+ * Add one to leave room for possible polygon close.
+ */
+ MI_ALLOCLISTOFDDPOINT(pddolist,(i+1),output_size);
+ if(!(out_pt.p4Dpt = (pddolist->pts.p4Dpt)))
+ return(BadAlloc);
+
+ in_pt.p4Dpt = pddilist->pts.p4Dpt;
+
+ /* Note - just assume w = 1.0 */
+ while (i--) {
+
+ /* cast operands & transform the coordinates */
+
+ out_pt.p4Dpt->x = vert_mat[0][0]*in_pt.p4Dpt->x;
+ out_pt.p4Dpt->x += vert_mat[0][1]*in_pt.p4Dpt->y;
+ out_pt.p4Dpt->x += vert_mat[0][2]*in_pt.p4Dpt->z;
+ out_pt.p4Dpt->x += vert_mat[0][3]*in_pt.p4Dpt->w;
+
+ out_pt.p4Dpt->y = vert_mat[1][0]*in_pt.p4Dpt->x;
+ out_pt.p4Dpt->y += vert_mat[1][1]*in_pt.p4Dpt->y;
+ out_pt.p4Dpt->y += vert_mat[1][2]*in_pt.p4Dpt->z;
+ out_pt.p4Dpt->y += vert_mat[1][3]*in_pt.p4Dpt->w;
+
+ out_pt.p4Dpt->z = vert_mat[2][0]*in_pt.p4Dpt->x;
+ out_pt.p4Dpt->z += vert_mat[2][1]*in_pt.p4Dpt->y;
+ out_pt.p4Dpt->z += vert_mat[2][2]*in_pt.p4Dpt->z;
+ out_pt.p4Dpt->z += vert_mat[2][3]*in_pt.p4Dpt->w;
+
+ out_pt.p4Dpt->w = vert_mat[3][0]*in_pt.p4Dpt->x;
+ out_pt.p4Dpt->w += vert_mat[3][1]*in_pt.p4Dpt->y;
+ out_pt.p4Dpt->w += vert_mat[3][2]*in_pt.p4Dpt->z;
+ out_pt.p4Dpt->w += vert_mat[3][3]*in_pt.p4Dpt->w;
+
+ in_pt.p4Dpt++;
+ out_pt.p4Dpt++;
+
+ if (!DD_IsVertCoordsOnly(outtype)) {
+
+ if DD_IsVertColour(outtype) {
+ *out_pt.pRgbFloatClr =
+ *in_pt.pRgbFloatClr;
+ in_pt.pRgbFloatClr++;
+ out_pt.pRgbFloatClr++;
+ }
+
+ if DD_IsVertNormal(outtype) {
+
+ out_pt.pNormal->x = norm_mat[0][0]*in_pt.pNormal->x;
+ out_pt.pNormal->x += norm_mat[0][1]*in_pt.pNormal->y;
+ out_pt.pNormal->x += norm_mat[0][2]*in_pt.pNormal->z;
+ /* no translation */
+
+ out_pt.pNormal->y = norm_mat[1][0]*in_pt.pNormal->x;
+ out_pt.pNormal->y += norm_mat[1][1]*in_pt.pNormal->y;
+ out_pt.pNormal->y += norm_mat[1][2]*in_pt.pNormal->z;
+ /* no translation */
+
+ out_pt.pNormal->z = norm_mat[2][0]*in_pt.pNormal->x;
+ out_pt.pNormal->z += norm_mat[2][1]*in_pt.pNormal->y;
+ out_pt.pNormal->z += norm_mat[2][2]*in_pt.pNormal->z;
+
+ NORMALIZE_VECTOR (out_pt.pNormal, length);
+
+ in_pt.pNormal++;
+ out_pt.pNormal++;
+ }
+
+ if (DD_IsVertEdge(outtype)) {
+ *out_pt.pEdge= *in_pt.pEdge;
+ in_pt.pEdge++;
+ out_pt.pEdge++;
+ }
+ }
+
+ }
+
+ pddilist++;
+ pddolist++;
+ }
+ break;
+ }
+ default:
+ *voutput = NULL;
+ return(1);
+ }
+
+ return(0);
+ }
+
+ /*
+ * Next case output a 2DS point. Note that this point is
+ * normalized by w if necessary.
+ */
+ case DD_2DS_POINT:
+ case DD_RGBFLOAT_POINT2DS:
+ case DD_HSV_POINT2DS:
+ case DD_HLS_POINT2DS:
+ case DD_CIE_POINT2DS:
+ case DD_NORM_POINT2DS:
+ case DD_EDGE_POINT2DS:
+ case DD_RGBFLOAT_NORM_POINT2DS:
+ case DD_HSV_NORM_POINT2DS:
+ case DD_HLS_NORM_POINT2DS:
+ case DD_CIE_NORM_POINT2DS:
+ case DD_RGBFLOAT_EDGE_POINT2DS:
+ case DD_HSV_EDGE_POINT2DS:
+ case DD_HLS_EDGE_POINT2DS:
+ case DD_CIE_EDGE_POINT2DS:
+ case DD_NORM_EDGE_POINT2DS:
+ case DD_RGBFLOAT_NORM_EDGE_POINT2DS:
+ case DD_HSV_NORM_EDGE_POINT2DS:
+ case DD_HLS_NORM_EDGE_POINT2DS:
+ case DD_CIE_NORM_EDGE_POINT2DS:
+ {
+ ddFLOAT w;
+ switch (vinput->type) {
+ case DD_2D_POINT:
+ {
+
+ /* Use the pre-defined 2D list for output */
+ *voutput = output = &pddc->Static.misc.list2D;
+
+ /* Insure sufficient room for each header */
+ MI_ALLOCLISTHEADER(output, vinput->numLists)
+ if (!output->ddList) return(BadAlloc);
+
+ output->type = outtype;
+ output->numLists = vinput->numLists;
+ output->flags = vinput->flags;
+
+ pddilist = vinput->ddList;
+ pddolist = output->ddList;
+
+ /* Now, transform each list */
+ for(j=0; j < vinput->numLists; j++) {
+
+ if ((i = pddolist->numPoints = pddilist->numPoints) <= 0)
+ continue;
+
+ /*
+ * Insure sufficient room for each vertex
+ * Add one to leave room for possible polygon close.
+ */
+ MI_ALLOCLISTOFDDPOINT(pddolist,(i+1),output_size);
+ if(!(out_pt.p2DSpt = (pddolist->pts.p2DSpt)))
+ return(BadAlloc);
+
+
+ in_pt.p2DSpt = pddilist->pts.p2DSpt;
+
+ /* Note - just assume z = 0.0, w = 1.0 */
+ while (i--) {
+
+ /* cast operands & transform the coordinates */
+
+ tmp_pt.x = vert_mat[0][0]*in_pt.p2Dpt->x;
+ tmp_pt.x += vert_mat[0][1]*in_pt.p2Dpt->y;
+ tmp_pt.x += vert_mat[0][3];
+
+ tmp_pt.y = vert_mat[1][0]*in_pt.p2Dpt->x;
+ tmp_pt.y += vert_mat[1][1]*in_pt.p2Dpt->y;
+ tmp_pt.y += vert_mat[1][3];
+
+ /* Skip Z transformation */
+
+ /* The w must be computed to normalize the result */
+ w = vert_mat[3][0]*in_pt.p2Dpt->x;
+ w += vert_mat[3][1]*in_pt.p2Dpt->y;
+ w += vert_mat[3][3];
+
+ /* Now round and normalize the result */
+ if (w != 1.0) {
+ out_pt.p2DSpt->x = (ddSHORT)(tmp_pt.x / w);
+ out_pt.p2DSpt->y = (ddSHORT)(tmp_pt.y / w);
+ } else {
+ out_pt.p2DSpt->x = (ddSHORT)(tmp_pt.x);
+ out_pt.p2DSpt->y = (ddSHORT)(tmp_pt.y);
+ }
+ in_pt.p2Dpt++;
+ out_pt.p2DSpt++;
+
+
+ /* At this point we should be pointing to
+ * to the beginning of the next vertex
+ */
+
+ }
+ pddilist++;
+ pddolist++;
+ }
+ break;
+ }
+ case DD_3D_POINT:
+ case DD_RGBFLOAT_POINT:
+ case DD_HSV_POINT:
+ case DD_HLS_POINT:
+ case DD_CIE_POINT:
+ case DD_NORM_POINT:
+ case DD_EDGE_POINT:
+ case DD_RGBFLOAT_NORM_POINT:
+ case DD_HSV_NORM_POINT:
+ case DD_HLS_NORM_POINT:
+ case DD_CIE_NORM_POINT:
+ case DD_RGBFLOAT_EDGE_POINT:
+ case DD_HSV_EDGE_POINT:
+ case DD_HLS_EDGE_POINT:
+ case DD_CIE_EDGE_POINT:
+ case DD_NORM_EDGE_POINT:
+ case DD_RGBFLOAT_NORM_EDGE_POINT:
+ case DD_HSV_NORM_EDGE_POINT:
+ case DD_HLS_NORM_EDGE_POINT:
+ case DD_CIE_NORM_EDGE_POINT:
+ {
+
+ /* Use the pre-defined 2D list for output */
+ *voutput = output = &pddc->Static.misc.list2D;
+
+ /* Insure sufficient room for each header */
+ MI_ALLOCLISTHEADER(output, vinput->numLists)
+ if (!output->ddList) return(BadAlloc);
+
+ output->type = outtype;
+ output->numLists = vinput->numLists;
+ output->flags = vinput->flags;
+
+ pddilist = vinput->ddList;
+ pddolist = output->ddList;
+
+ /* Now, transform each list */
+ for(j=0; j < vinput->numLists; j++) {
+
+ if ((i = pddolist->numPoints = pddilist->numPoints) <= 0)
+ continue;
+
+ /*
+ * Insure sufficient room for each vertex
+ * Add one to leave room for possible polygon close.
+ */
+ MI_ALLOCLISTOFDDPOINT(pddolist,(i+1),output_size);
+ if(!(out_pt.p2DSpt = (pddolist->pts.p2DSpt)))
+ return(BadAlloc);
+
+
+ in_pt.p3Dpt = pddilist->pts.p3Dpt;
+
+ /* Note - just assume z = 0.0, w = 1.0 */
+ while (i--) {
+
+ /* cast operands & transform the coordinates */
+
+ tmp_pt.x = vert_mat[0][0]*in_pt.p3Dpt->x;
+ tmp_pt.x += vert_mat[0][1]*in_pt.p3Dpt->y;
+ tmp_pt.x += vert_mat[0][2]*in_pt.p3Dpt->z;
+ tmp_pt.x += vert_mat[0][3];
+
+ tmp_pt.y = vert_mat[1][0]*in_pt.p3Dpt->x;
+ tmp_pt.y += vert_mat[1][1]*in_pt.p3Dpt->y;
+ tmp_pt.y += vert_mat[1][2]*in_pt.p3Dpt->z;
+ tmp_pt.y += vert_mat[1][3];
+
+ /* Skip Z transformation */
+
+ /* The w must be computed to normalize the result */
+ w = vert_mat[3][0]*in_pt.p3Dpt->x;
+ w += vert_mat[3][1]*in_pt.p3Dpt->y;
+ w += vert_mat[3][2]*in_pt.p3Dpt->z;
+ w += vert_mat[3][3];
+
+ /* Now round and normalize the result */
+ if (w != 1.0) {
+ out_pt.p2DSpt->x = IRINT(tmp_pt.x / w);
+ out_pt.p2DSpt->y = IRINT(tmp_pt.y / w);
+ } else {
+ out_pt.p2DSpt->x = IRINT(tmp_pt.x);
+ out_pt.p2DSpt->y = IRINT(tmp_pt.y);
+ }
+ in_pt.p3Dpt++;
+ out_pt.p2DSpt++;
+
+
+ if (!DD_IsVertCoordsOnly(outtype)) {
+
+ if DD_IsVertColour(outtype) {
+ *out_pt.pRgbFloatClr =
+ *in_pt.pRgbFloatClr;
+ in_pt.pRgbFloatClr++;
+ out_pt.pRgbFloatClr++;
+ }
+
+ if DD_IsVertNormal(outtype) {
+
+ out_pt.pNormal->x = norm_mat[0][0]*in_pt.pNormal->x;
+ out_pt.pNormal->x += norm_mat[0][1]*in_pt.pNormal->y;
+ out_pt.pNormal->x += norm_mat[0][2]*in_pt.pNormal->z;
+ /* no translation */
+
+ out_pt.pNormal->y = norm_mat[1][0]*in_pt.pNormal->x;
+ out_pt.pNormal->y += norm_mat[1][1]*in_pt.pNormal->y;
+ out_pt.pNormal->y += norm_mat[1][2]*in_pt.pNormal->z;
+ /* no translation */
+
+ out_pt.pNormal->z = norm_mat[2][0]*in_pt.pNormal->x;
+ out_pt.pNormal->z += norm_mat[2][1]*in_pt.pNormal->y;
+ out_pt.pNormal->z += norm_mat[2][2]*in_pt.pNormal->z;
+
+ NORMALIZE_VECTOR (out_pt.pNormal, length);
+
+ in_pt.pNormal++;
+ out_pt.pNormal++;
+ }
+
+ if (DD_IsVertEdge(outtype)) {
+ *out_pt.pEdge= *in_pt.pEdge;
+ in_pt.pEdge++;
+ out_pt.pEdge++;
+ }
+
+ }
+
+ }
+ pddilist++;
+ pddolist++;
+ }
+ break;
+ }
+ case DD_RGBFLOAT_POINT4D:
+ case DD_HSV_POINT4D:
+ case DD_HLS_POINT4D:
+ case DD_CIE_POINT4D:
+ case DD_NORM_POINT4D:
+ case DD_EDGE_POINT4D:
+ case DD_RGBFLOAT_NORM_POINT4D:
+ case DD_HSV_NORM_POINT4D:
+ case DD_HLS_NORM_POINT4D:
+ case DD_CIE_NORM_POINT4D:
+ case DD_RGBFLOAT_EDGE_POINT4D:
+ case DD_HSV_EDGE_POINT4D:
+ case DD_HLS_EDGE_POINT4D:
+ case DD_CIE_EDGE_POINT4D:
+ case DD_NORM_EDGE_POINT4D:
+ case DD_RGBFLOAT_NORM_EDGE_POINT4D:
+ case DD_HSV_NORM_EDGE_POINT4D:
+ case DD_HLS_NORM_EDGE_POINT4D:
+ case DD_CIE_NORM_EDGE_POINT4D:
+ case DD_HOMOGENOUS_POINT:
+ {
+
+ /* Use the pre-defined 2D list for output */
+ *voutput = output = &pddc->Static.misc.list2D;
+
+ /* Insure sufficient room for each header */
+ MI_ALLOCLISTHEADER(output, vinput->numLists)
+ if (!output->ddList) return(BadAlloc);
+
+ output->type = outtype;
+ output->flags = vinput->flags;
+ output->numLists = vinput->numLists;
+
+ pddilist = vinput->ddList;
+ pddolist = output->ddList;
+
+ /* Now, transform each list */
+ for(j = 0; j < vinput->numLists; j++) {
+
+ if ((i = pddolist->numPoints = pddilist->numPoints) <= 0)
+ continue;
+
+ /*
+ * Insure sufficient room for each vertex
+ * Add one to leave room for possible polygon close.
+ */
+ MI_ALLOCLISTOFDDPOINT(pddolist, (i+1), output_size);
+ if(!(out_pt.p2DSpt = (pddolist->pts.p2DSpt)))
+ return(BadAlloc);
+
+ in_pt.p4Dpt = pddilist->pts.p4Dpt;
+
+ /* Note - just assume w = 1.0 */
+ while (i--) {
+
+ /* cast operands & transform the coordinates */
+
+ tmp_pt.x = vert_mat[0][0]*in_pt.p4Dpt->x;
+ tmp_pt.x += vert_mat[0][1]*in_pt.p4Dpt->y;
+ tmp_pt.x += vert_mat[0][2]*in_pt.p4Dpt->z;
+ tmp_pt.x += vert_mat[0][3]*in_pt.p4Dpt->w;
+
+ tmp_pt.y = vert_mat[1][0]*in_pt.p4Dpt->x;
+ tmp_pt.y += vert_mat[1][1]*in_pt.p4Dpt->y;
+ tmp_pt.y += vert_mat[1][2]*in_pt.p4Dpt->z;
+ tmp_pt.y += vert_mat[1][3]*in_pt.p4Dpt->w;
+
+ /* Skip Z transformation */
+
+ w = vert_mat[3][0]*in_pt.p4Dpt->x;
+ w += vert_mat[3][1]*in_pt.p4Dpt->y;
+ w += vert_mat[3][2]*in_pt.p4Dpt->z;
+ w += vert_mat[3][3]*in_pt.p4Dpt->w;
+
+ /* Now round and normal->ze the result */
+ if (w != 1.0) {
+ out_pt.p2DSpt->x = IRINT(tmp_pt.x / w);
+ out_pt.p2DSpt->y = IRINT(tmp_pt.y / w);
+ } else {
+ out_pt.p2DSpt->x = IRINT(tmp_pt.x);
+ out_pt.p2DSpt->y = IRINT(tmp_pt.y);
+ }
+
+ in_pt.p4Dpt++;
+ out_pt.p2DSpt++;
+
+
+ if (!DD_IsVertCoordsOnly(outtype)) {
+
+ if DD_IsVertColour(outtype) {
+ *out_pt.pRgbFloatClr =
+ *in_pt.pRgbFloatClr;
+ in_pt.pRgbFloatClr++;
+ out_pt.pRgbFloatClr++;
+ }
+
+ if DD_IsVertNormal(outtype) {
+
+ out_pt.pNormal->x = norm_mat[0][0]*in_pt.pNormal->x;
+ out_pt.pNormal->x += norm_mat[0][1]*in_pt.pNormal->y;
+ out_pt.pNormal->x += norm_mat[0][2]*in_pt.pNormal->z;
+ /* no translation */
+
+ out_pt.pNormal->y = norm_mat[1][0]*in_pt.pNormal->x;
+ out_pt.pNormal->y += norm_mat[1][1]*in_pt.pNormal->y;
+ out_pt.pNormal->y += norm_mat[1][2]*in_pt.pNormal->z;
+ /* no translation */
+
+ out_pt.pNormal->z = norm_mat[2][0]*in_pt.pNormal->x;
+ out_pt.pNormal->z += norm_mat[2][1]*in_pt.pNormal->y;
+ out_pt.pNormal->z += norm_mat[2][2]*in_pt.pNormal->z;
+
+ NORMALIZE_VECTOR (out_pt.pNormal, length);
+
+ in_pt.pNormal++;
+ out_pt.pNormal++;
+ }
+
+ if (DD_IsVertEdge(outtype)) {
+ *out_pt.pEdge= *in_pt.pEdge;
+ in_pt.pEdge++;
+ out_pt.pEdge++;
+ }
+
+ }
+
+ }
+ pddilist++;
+ pddolist++;
+ }
+ break;
+ }
+
+ /* no more input types for 2DS outputs*/
+ default:
+ *voutput = NULL;
+ return(1);
+ break;
+ }
+
+ return(0);
+ }
+
+ /* no more output types left */
+ default:
+ *voutput = NULL;
+ return(1);
+ break;
+ }
+
+
+}
+
+/*++
+ |
+ | miFacetTransform(pddc, finput, foutput, norm_mat)
+ |
+ | Facet list transform routine.
+ |
+ | General transform routine for PEX.
+ |
+ | This routine takes in four parameters: a list of vertices,
+ | an output point type, and two matrices: one for transforming
+ | vertex data, the second for transforming normal data.
+ | The following assumptions are made:
+ | a) 2DS input is never used
+ | b) 2D input does not support normal, color or edge info
+ | c) output types do not have more attributes (color, normal or edge)
+ | than input data types
+ | d) only color specifiers with triplets of float values are
+ | supported
+ |
+ | All other cases produce undefined output
+ |
+ --*/
+
+ddpex3rtn
+miFacetTransform(pddc, finput, foutput, norm_mat)
+ miDDContext *pddc;
+ listofddFacet *finput;
+ listofddFacet **foutput;
+ ddFLOAT norm_mat[4][4];
+{
+
+ listofddFacet *fct_list;
+ ddFacetUnion in_fct;
+ ddFacetUnion out_fct;
+ ddFLOAT length;
+ char color_flag;
+ int j;
+ int facet_size;
+
+ /* Some quick error checking */
+ if (!DD_IsFacetNormal(finput->type)) {
+ *foutput = finput;
+ return(Success);
+ }
+
+ /*
+ * First, allocate storage for the facet list
+ */
+ fct_list = MI_NEXTTEMPFACETLIST(pddc);
+ fct_list->type = finput->type;
+
+ DDFacetSIZE(finput->type, facet_size);
+ MI_ALLOCLISTOFDDFACET(fct_list, finput->numFacets, facet_size);
+ if (!(out_fct.pNoFacet = fct_list->facets.pNoFacet)) return(BadAlloc);
+
+ color_flag = DD_IsFacetColour(finput->type);
+
+ in_fct = finput->facets;
+
+
+
+ /* Remember, facet data is of the form:
+ *
+ * |--------------|--------------------------|
+ * color (opt) normal (opt)
+ */
+
+ for (j = 0; j < finput->numFacets; j++) {
+
+ /* Copy the input facet color */
+ if (color_flag)
+ *(out_fct.pFacetRgbFloat++) = *(in_fct.pFacetRgbFloat++);
+
+ out_fct.pFacetN->x = norm_mat[0][0]*in_fct.pFacetN->x;
+ out_fct.pFacetN->x += norm_mat[0][1]*in_fct.pFacetN->y;
+ out_fct.pFacetN->x += norm_mat[0][2]*in_fct.pFacetN->z;
+ /* no translation */
+
+ out_fct.pFacetN->y = norm_mat[1][0]*in_fct.pFacetN->x;
+ out_fct.pFacetN->y += norm_mat[1][1]*in_fct.pFacetN->y;
+ out_fct.pFacetN->y += norm_mat[1][2]*in_fct.pFacetN->z;
+ /* no translation */
+
+ out_fct.pFacetN->z = norm_mat[2][0]*in_fct.pFacetN->x;
+ out_fct.pFacetN->z += norm_mat[2][1]*in_fct.pFacetN->y;
+ out_fct.pFacetN->z += norm_mat[2][2]*in_fct.pFacetN->z;
+
+ NORMALIZE_VECTOR (out_fct.pFacetN, length);
+
+ /* Process next facet */
+ in_fct.pFacetN++;
+ out_fct.pFacetN++;
+ }
+
+ fct_list->numFacets = finput->numFacets;
+ *foutput = fct_list;
+
+ return(Success);
+
+}
+
+/*++
+ |
+ | miBoundsTransform(pddc, ibounds, obounds, mat)
+ |
+ | Transforms a ddListBounds stucture by the specified matrix.
+ |
+ --*/
+
+ddpex3rtn
+miBoundsTransform(pddc, ibounds, obounds, mat)
+ miDDContext *pddc;
+ ddListBounds *ibounds;
+ ddListBounds *obounds;
+ ddFLOAT *mat;
+{
+
+ ddFLOAT *f = mat;
+
+ obounds->xmin = (*f++)*ibounds->xmin;
+ obounds->xmin += (*f++)*ibounds->ymin;
+ obounds->xmin += (*f++)*ibounds->zmin;
+ obounds->xmin += (*f++)*ibounds->wmin;
+
+ obounds->ymin = (*f++)*ibounds->xmin;
+ obounds->ymin += (*f++)*ibounds->ymin;
+ obounds->ymin += (*f++)*ibounds->zmin;
+ obounds->ymin += (*f++)*ibounds->wmin;
+
+ obounds->zmin = (*f++)*ibounds->xmin;
+ obounds->zmin += (*f++)*ibounds->ymin;
+ obounds->zmin += (*f++)*ibounds->zmin;
+ obounds->zmin += (*f++)*ibounds->wmin;
+
+ obounds->wmin = (*f++)*ibounds->xmin;
+ obounds->wmin += (*f++)*ibounds->ymin;
+ obounds->wmin += (*f++)*ibounds->zmin;
+ obounds->wmin += (*f++)*ibounds->wmin;
+
+ f = mat;
+
+ obounds->xmax = (*f++)*ibounds->xmax;
+ obounds->xmax += (*f++)*ibounds->ymax;
+ obounds->xmax += (*f++)*ibounds->zmax;
+ obounds->xmax += (*f++)*ibounds->wmax;
+
+ obounds->ymax = (*f++)*ibounds->xmax;
+ obounds->ymax += (*f++)*ibounds->ymax;
+ obounds->ymax += (*f++)*ibounds->zmax;
+ obounds->ymax += (*f++)*ibounds->wmax;
+
+ obounds->zmax = (*f++)*ibounds->xmax;
+ obounds->zmax += (*f++)*ibounds->ymax;
+ obounds->zmax += (*f++)*ibounds->zmax;
+ obounds->zmax += (*f++)*ibounds->wmax;
+
+ obounds->wmax = (*f++)*ibounds->xmax;
+ obounds->wmax += (*f++)*ibounds->ymax;
+ obounds->wmax += (*f++)*ibounds->zmax;
+ obounds->wmax += (*f++)*ibounds->wmax;
+
+ return(Success);
+
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level2/miTriStrip.c b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miTriStrip.c
new file mode 100644
index 000000000..5ab54c137
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level2/miTriStrip.c
@@ -0,0 +1,2219 @@
+/* $TOG: miTriStrip.c /main/13 1998/02/10 12:42:58 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level2/miTriStrip.c,v 3.5 1998/10/04 09:34:30 dawes Exp $ */
+
+#include "miClip.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "ddpex3.h"
+#include "PEXErr.h"
+#include "miStruct.h"
+#include "PEXprotost.h"
+#include "miRender.h"
+#include "gcstruct.h"
+#include "miLight.h"
+#include "ddpex2.h"
+#include "pexos.h"
+
+
+static ddpex3rtn miClipTriStrip();
+static ddpex3rtn miCullTriStrip();
+static ddpex3rtn miDepthCueTriStrip();
+static ddpex3rtn Complete_TriFacetList();
+static ddpex3rtn Calculate_TriStrip_Facet_Normal();
+static ddpex3rtn Calculate_TriStrip_Vertex_Color_and_Normal();
+static ddpex3rtn Breakup_TriStrip();
+
+/*++
+ |
+ | Function Name: miTriangleStrip
+ |
+ | Function Description:
+ | Handles the triangle strip OC.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+miTriangleStrip(pRend, pExecuteOC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ miGenericStr *pExecuteOC;
+{
+
+/* calls */
+ ddpex3rtn miTransform();
+ ddpex3rtn miConvertVertexColors();
+ ddpex3rtn miConvertFacetColors();
+ ddpex3rtn miLightTriStrip();
+ ddpex3rtn miRenderTriStrip();
+ ddpex3rtn ComputeMCVolume();
+
+/* Local variable definitions */
+ miTriangleStripStruct *ddTri
+ = (miTriangleStripStruct *)(pExecuteOC+1);
+ miListHeader *input_list = &(ddTri->points); /* Input points */
+ listofddFacet *input_facet = ddTri->pFacets; /* facets */
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ miListHeader *color_list,
+ *mc_list,
+ *wc_list,
+ *mc_clist,
+ *light_list,
+ *cc_list,
+ *clip_list,
+ *cull_list,
+ *dcue_list,
+ *dc_list;
+
+ listofddFacet *color_facet,
+ *mc_facet,
+ *wc_facet,
+ *light_facet,
+ *cc_facet,
+ *clip_facet,
+ *cull_facet,
+ *dc_facet;
+ listofddPoint *sp;
+ int i, j;
+ ddpex3rtn status;
+ ddPointType out_type;
+ ddUSHORT clip_mode;
+
+
+ /*
+ * First, check data input
+ * At this point, the data is all in one list
+ */
+
+ if (input_list->numLists == 0) return(Success);
+
+ /*
+ * Convert per-vertex and per-facet colors to rendering color model.
+ * Note that this implementation only supports rgb float.
+ */
+
+ if (DD_IsVertColour(input_list->type)) {
+ if (status = miConvertVertexColors(pRend,
+ input_list, PEXRdrColourModelRGB,
+ &color_list))
+ return (status);
+ } else {
+ color_list = input_list;
+ }
+
+ if ((input_facet) && (DD_IsFacetColour(input_facet->type))) {
+ if (status = miConvertFacetColors(pRend,
+ input_facet, PEXRdrColourModelRGB,
+ &color_facet))
+ return (status);
+ } else {
+ color_facet = input_facet;
+ }
+
+ /* Check for Model clipping */
+
+ if (pddc->Dynamic->pPCAttr->modelClip == PEXClip) {
+
+ /* Compute modelling coord version of clipping volume */
+ ComputeMCVolume(pRend, pddc);
+
+ clip_mode = MI_MCLIP;
+
+ /* Tranform points to 4D for clipping */
+ out_type = color_list->type;
+ if (status = miTransform(pddc,
+ color_list, &mc_clist,
+ ident4x4,
+ ident4x4,
+ DD_SetVert4D(out_type)))
+ return (status);
+
+
+ if (status = miClipTriStrip(pddc, mc_clist, color_facet,
+ &mc_list, &mc_facet, clip_mode))
+ return (status);
+
+ /* if nothing left after model clip, return early */
+ if (mc_list->numLists <= 0) return(Success);
+
+ } else {
+ mc_list = color_list;
+ mc_facet = color_facet;
+ }
+
+ /* Note - After clipping the triangle strip may have
+ * decomposed into a number of separate triangle strips
+ */
+
+
+ /*
+ * Next, check lighting requirements
+ */
+
+ if (pddc->Static.attrs->reflModel != PEXReflectionNoShading) {
+
+ /* Transform to WC prior to applying lighting */
+ out_type = mc_list->type;
+ if (DD_IsVertNormal(out_type)) VALIDATEINVTRMCTOWCXFRM(pddc);
+ if (status = miTransform(pddc,
+ mc_list, &wc_list,
+ pddc->Dynamic->mc_to_wc_xform,
+ pddc->Static.misc.inv_tr_mc_to_wc_xform,
+ DD_SetVert4D(out_type)))
+ return (status);
+
+ /* Transform facet normals if necessary */
+ if ((mc_facet) &&
+ (mc_facet->numFacets > 0) &&
+ (DD_IsFacetNormal(mc_facet->type))) {
+ VALIDATEINVTRMCTOWCXFRM(pddc);
+ if (status = miFacetTransform(pddc,
+ mc_facet, &wc_facet,
+ pddc->Static.misc.inv_tr_mc_to_wc_xform))
+ return (status);
+ } else wc_facet = mc_facet;
+
+ /* Apply lighting */
+ if (status = miLightTriStrip(pRend, pddc,
+ wc_list, wc_facet,
+ &light_list, &light_facet))
+ return (status);
+
+
+ /* Transform to CC for clipping */
+ if (DD_IsVertNormal(light_list->type)) VALIDATEINVTRWCTOCCXFRM(pddc);
+ if (status = miTransform(pddc,
+ light_list, &cc_list,
+ pddc->Dynamic->wc_to_cc_xform,
+ pddc->Static.misc.inv_tr_wc_to_cc_xform,
+ light_list->type))
+ return (status);
+
+ /* Transform facet normals if necessary */
+ if ( (light_facet) &&
+ (light_facet->numFacets > 0) &&
+ (DD_IsFacetNormal(light_facet->type)) ) {
+ VALIDATEINVTRWCTOCCXFRM(pddc);
+ if (status = miFacetTransform(pddc,
+ light_facet, &cc_facet,
+ pddc->Static.misc.inv_tr_wc_to_cc_xform))
+ return (status);
+ } else cc_facet = light_facet;
+
+ } else {
+
+ /* PEXReflectionNoShading case */
+
+ /* Now transform points and facets normals to CC */
+ out_type = mc_list->type;
+ if (DD_IsVertNormal(out_type)) VALIDATEINVTRMCTOCCXFRM(pddc);
+ if (status = miTransform(pddc,
+ mc_list, &cc_list,
+ pddc->Dynamic->mc_to_cc_xform,
+ pddc->Static.misc.inv_tr_mc_to_cc_xform,
+ DD_SetVert4D(out_type)))
+ return (status);
+
+ if ( (mc_facet) &&
+ (mc_facet->numFacets > 0) &&
+ (DD_IsFacetNormal(mc_facet->type)) ) {
+ VALIDATEINVTRMCTOCCXFRM(pddc);
+ if (status = miFacetTransform(pddc,
+ mc_facet, &cc_facet,
+ pddc->Static.misc.inv_tr_mc_to_cc_xform))
+ return (status);
+ } else cc_facet = mc_facet;
+
+ }
+
+ /* View clip primitive */
+ clip_mode = MI_VCLIP;
+ if (status = miClipTriStrip(pddc, cc_list, cc_facet,
+ &clip_list, &clip_facet, clip_mode))
+ return (status);
+
+ /* if nothing left after view clip, return early */
+ if (clip_list->numLists <= 0) return(Success);
+
+ /* Note - After View clipping, the triangle strip may have
+ * decomposed into a number of separate triangle strips
+ */
+
+ if (pddc->Dynamic->pPCAttr->cullMode) {
+ /* Now cull according to current culling mode */
+ if (status = miCullTriStrip(pddc, clip_list, clip_facet,
+ &cull_list, &cull_facet))
+ return (status);
+
+ /* if nothing left after culling, return early */
+ if (cull_list->numLists <= 0) return(Success);
+ } else {
+ cull_list = clip_list;
+ cull_facet = clip_facet;
+ }
+
+ /* DEPTH CUEING */
+ if (pddc->Dynamic->pPCAttr->depthCueIndex) {
+ miDepthCueTriStrip(pRend, cull_list, cull_facet, &dcue_list);
+ cull_list = dcue_list;
+ }
+
+ /* Lastly, transform to DC coordinates */
+ out_type = cull_list->type;
+ DD_SetVert2D(out_type);
+ DD_SetVertShort(out_type);
+ if (DD_IsVertNormal(out_type)) VALIDATEINVTRCCTODCXFRM(pddc);
+ if (status = miTransform(pddc,
+ cull_list, &dc_list,
+ pddc->Dynamic->cc_to_dc_xform,
+ pddc->Static.misc.inv_tr_cc_to_dc_xform,
+ out_type) )
+ return (status);
+
+ /* Transform facet normals if necessary */
+ if ( (cull_facet) &&
+ (cull_facet->numFacets > 0) &&
+ (DD_IsFacetNormal(cull_facet->type)) ) {
+ VALIDATEINVTRCCTODCXFRM(pddc);
+ if (status = miFacetTransform(pddc,
+ cull_facet, &dc_facet,
+ pddc->Static.misc.inv_tr_cc_to_dc_xform))
+ return (status);
+ } else dc_facet = cull_facet;
+
+ return (pddc->Static.RenderProcs[TRISTRIP_RENDER_TABLE_INDEX](pRend,
+ pddc,
+ dc_list,
+ dc_facet));
+}
+/*************************************************************************/
+
+/*++
+ |
+ | Function Name: miClipTriStrip
+ |
+ | Function Description:
+ | Clips a triangle strip. Note that this routine
+ | will return a triangle strip, though it sometimes creates
+ | "degenerate" (ie colinear vertices) triangles to achieve
+ | this result. At this point "hollow" filled triangles will
+ | exhibit clipping artifacts, (degenerate triangles) whereas
+ | "empty" fill with edge visibility enabled will not.
+ |
+ | Note(s):
+ |
+ | This routine uses a Sutherland-Hodgman approach for
+ | polygon clipping. (See, for example, Rodger's "Procedural
+ | Elements for Computer Graphics", pp 169-179).
+ | Each triangle strip is clipped successively against each (enabled)
+ | clipping boundary.
+ |
+ --*/
+
+static
+ddpex3rtn
+miClipTriStrip(pddc, input_vert, input_fct, output_vert, output_fct,clip_mode)
+/* in */
+ miDDContext *pddc;
+ miListHeader *input_vert; /* input vertex data */
+ listofddFacet *input_fct; /* input facet data */
+ miListHeader **output_vert; /* output vertex data */
+ listofddFacet **output_fct; /* output facet data */
+ ddUSHORT clip_mode;
+{
+/* uses */
+ ddPointUnion in_ptP, in_ptQ, in_ptR;
+ ddPointUnion out_pt;
+ float t_ptP, t_ptQ, t_ptR;
+ char *in_fct, *out_fct;
+ miListHeader *vinput, *voutput, *list1, *list2;
+ listofddFacet *finput, *foutput, *fct_list1, *fct_list2;
+ listofddPoint *pddilist;
+ listofddPoint *pddolist;
+ int point_size;
+ int facet_size;
+ int pts_in_list;
+ int vert_count;
+ int new_facets;
+ int clip_plane, j, k, out_listnum;
+ ddUSHORT clipflags;
+ ddUSHORT current_clip;
+ int edge_offset;
+ ddHalfSpace *MC_HSpace;
+ ddVector3D PdotN, QdotN;
+ int clip_code;
+ ddULONG *edge_ptr;
+ char new_list;
+ ddpex3rtn status;
+ int num_planes;
+
+ /* Vertex data must be homogeneous and contain more than two points
+ * for clipper
+ */
+ if (!(DD_IsVert4D(input_vert->type))
+ || (input_vert->numLists == 0)) return(1);
+
+ /*
+ * Use the pre-defined clip lists for output
+ */
+
+ /*
+ * Must have edge flags in vertex if edges are to be drawn -
+ * otherwise, cannot determine wich edges are "original" and
+ * which edges where added by the clipper.
+ */
+ if ((pddc->Static.attrs->edges != PEXOff) &&
+ (!(DD_IsVertEdge(input_vert->type))))
+ {
+ if (status = miAddEdgeFlag(pddc, input_vert, &list1)) return(status);
+ vinput = list1;
+
+ } else {
+ /* Allocate an initial number of headers */
+ list1 = MI_NEXTTEMPDATALIST(pddc);
+ MI_ALLOCLISTHEADER(list1,
+ MI_ROUND_LISTHEADERCOUNT(input_vert->numLists));
+ if (!list1->ddList) return(BadAlloc);
+ list1->type = input_vert->type;
+ list1->flags = input_vert->flags;
+ vinput = input_vert; /* Initially set to input list */
+ }
+
+ list2 = MI_NEXTTEMPDATALIST(pddc);
+ MI_ALLOCLISTHEADER(list2,
+ MI_ROUND_LISTHEADERCOUNT(vinput->numLists));
+ if (!list2->ddList) return(BadAlloc);
+ list2->type = vinput->type;
+ list2->flags = vinput->flags;
+ voutput = list2;
+
+ /*
+ * Initialize an output facet list. Note that facet lists are only
+ * maintained if an initial one is supplied.
+ * Note that twice the number of input facets is an upper bound,
+ * although there is probably a tighter "fit".
+ */
+ if ((input_fct) && (input_fct->numFacets)) {
+ finput = input_fct;
+ DDFacetSIZE(input_fct->type, facet_size);
+ fct_list1 = MI_NEXTTEMPFACETLIST(pddc);
+ fct_list1->type = input_fct->type;
+ MI_ALLOCLISTOFDDFACET(fct_list1, 3*input_fct->numFacets, facet_size);
+ if (!fct_list1->facets.pFacetRgbFloatN)
+ return(BadAlloc);
+ foutput = fct_list1;
+
+ fct_list2 = MI_NEXTTEMPFACETLIST(pddc);
+ fct_list2->type = input_fct->type;
+ MI_ALLOCLISTOFDDFACET(fct_list2, 3*input_fct->numFacets, facet_size);
+ if (!fct_list2->facets.pFacetRgbFloatN)
+ return(BadAlloc);
+ } else
+ finput = foutput = fct_list1 = fct_list2 = 0;
+
+ /*
+ * Get point size so that this works for all point types
+ */
+ DD_VertPointSize(vinput->type, point_size);
+ if DD_IsVertEdge(vinput->type)
+ DD_VertOffsetEdge(vinput->type, edge_offset);
+
+ /*
+ * Each list is now clipped in turn against each (enabled) boundary.
+ */
+
+ if (clip_mode == MI_MCLIP)
+ num_planes = pddc->Static.misc.ms_MCV->numObj;
+ else num_planes = 6;
+
+ if (clip_mode == MI_MCLIP)
+ MC_HSpace = (ddHalfSpace *)(pddc->Static.misc.ms_MCV->pList);
+
+ for (clip_plane = 0; clip_plane < num_planes; clip_plane++) {
+
+ /* do entire list against one clipping plane at a time */
+ current_clip = 1 << clip_plane; /* current_clip is new clip bound */
+
+ /*
+ * Triangle strips begin with only one input and output
+ * vertex list. If a facet is found to be entirely out
+ * of bounds, A new list is started at the new included
+ * point. This new series of lists is clipped in turn
+ * against the next clipping planei, and may be decomposed into
+ * yet more lists. However, only a single facet list is
+ * maintained, at it is assumed that a one<->one correspondence
+ * exists between vertex triads and facets (within a single list)
+ * even if degenerate facets are added.
+ */
+
+ if (finput) {
+ in_fct = (char *)(finput->facets.pNoFacet);
+ MI_ALLOCLISTOFDDFACET(foutput,
+ (3*finput->numFacets), facet_size);
+ out_fct = (char *)(foutput->facets.pNoFacet);
+ }
+
+ for (j = 0, out_listnum = 0, new_list = 1, new_facets = 0,
+ pddilist = vinput->ddList, pddolist = voutput->ddList,
+ voutput->numLists = 0;
+ j < vinput->numLists; j++) {
+
+
+ /* Don't process if not enough points */
+ if ((vert_count = pddilist->numPoints) < 3) {
+ pddilist++;
+ continue;
+ }
+
+
+ /* Insure sufficient room for vertecies and degenerate points
+ * Note that twice the vertex count is an upper-bound for
+ * a clipped triangle(although there is probably a "tighter fit").
+ */
+
+ MI_ALLOCLISTOFDDPOINT(pddolist, 2*vert_count, point_size);
+ out_pt = pddolist->pts;
+ if (!out_pt.ptr) return(BadAlloc);
+
+ clip_code = 0;
+ /* Aquire first three points */
+ /* and generate clip code */
+ in_ptP.ptr = pddilist->pts.ptr;
+ COMPUTE_CLIP_PARAMS(in_ptP,t_ptP,0,clip_mode,
+ current_clip,MC_HSpace,clip_code);
+ in_ptQ.ptr = in_ptP.ptr + point_size;
+ COMPUTE_CLIP_PARAMS(in_ptQ, t_ptQ, 1, clip_mode,
+ current_clip,MC_HSpace,clip_code);
+ in_ptR.ptr = in_ptQ.ptr + point_size;
+ /*
+ * Initialize the output array. The output array is expected
+ * to always contain the first two points, so load them -
+ * clipped if necessary.
+ */
+ switch(clip_code)
+ {
+ case 0: /* both P and Q are in bounds */
+ COPY_POINT(in_ptP, out_pt, point_size);
+ out_pt.ptr += point_size;
+ COPY_POINT(in_ptQ, out_pt, point_size);
+ out_pt.ptr += point_size;
+ pts_in_list = 2;
+ break;
+ case 1: /* P is out, Q is in */
+ CLIP_AND_COPY(vinput->type, in_ptP, t_ptP,
+ in_ptQ, t_ptQ, out_pt);
+ out_pt.ptr += point_size;
+ COPY_POINT(in_ptQ, out_pt, point_size);
+ out_pt.ptr += point_size;
+ pts_in_list = 2;
+ break;
+ case 2: /* P is in, Q is out */
+ COPY_POINT(in_ptP, out_pt, point_size);
+ out_pt.ptr += point_size;
+ CLIP_AND_COPY(vinput->type, in_ptQ, t_ptQ,
+ in_ptP, t_ptP, out_pt);
+ out_pt.ptr += point_size;
+ pts_in_list = 2;
+ break;
+ case 3: /* both are out */
+ pts_in_list = 0;
+ break;
+ }
+
+ /*
+ * For each vertex, clip a triangle.
+ * Each case assumes that points P & Q (the first and
+ * second points in the triangle, pointed to in the input
+ * list by in_ptR & in_ptQ) are already copied
+ * into the output array (clipped, if necessary and except for
+ * case 3), while R will be copied into the output array (pointed
+ * to by out_pt) if necessary during execution of the case
+ * statement.
+ *
+ * It is important to note that if a facet is completely
+ * rejected, a new list is formed. Also, to maintain
+ * the correct "sense" of the normals, if the new
+ * list is about to begin on an even facet #, a
+ * degenerate facet is placed at the beginning of the
+ * new list.
+ *
+ * Also, note that if additional facets are generated
+ * (cases 1,2,3,4,& 6) the artifact edge flag is set to zero.
+ * Within an edge flag, there are two bits determining edge
+ * visibility. Bit zero determines whether an edge is drawn
+ * between the current vertex N and vertex N-2, while bit one
+ * determines if an edge is drawn between edge N and N+1.
+ * If N-2 < 0 or N+1 > numfacets the edge is not drawn.
+ *
+ * 2_________ _4
+ * /\ /|\
+ * / \ / \
+ * / \ / \
+ * / \ / \
+ * 1<--------+3+---------5
+ *
+ * So, for the third element in the edge list,
+ * bit 0 indicates presence of an edge from 3 -> 4
+ * (forward edge)
+ * bit 1 indicates presence of an edge from 3 -> 1
+ * (backward edge)
+ *
+ * Also note that clipping in PHIGS does NOT
+ * display clipped edges along the boundaries, whereas fill
+ * area attribute HOLLOW does. This implementation does
+ * not handle the HOLLOW fill style properly in that respect.
+ * One possible solution is to use additional bits in the
+ * edge flag field.
+ */
+
+ for (k = 2; k < vert_count; k++) {
+ /*
+ * Clip the new triangle
+ * There are 8 possible ways that the triangle (P, Q, R) can
+ * be intersected by a clipping plane:
+ *
+ * P, Q, R in P, Q, R out
+ * P in Q, R out P, Q in R out P, R in, Q out
+ * Q in P, R out Q, R in P out
+ * R in P, Q out
+ *
+ * Each of these cases are handled separately.
+ */
+
+ new_list = 0;
+ COMPUTE_CLIP_PARAMS(in_ptR, t_ptR, 2, clip_mode,
+ current_clip,MC_HSpace,clip_code);
+
+ switch(clip_code)
+ {
+ /*
+ * Case 0 - trivial accept P, Q, and R
+ * Proceed to next triangle.
+ */
+ case 0:
+ COPY_POINT(in_ptR, out_pt, point_size);
+ out_pt.ptr += point_size;
+ pts_in_list++;
+ if (finput) {
+ COPY_FACET(in_fct, out_fct, facet_size);
+ out_fct += facet_size;
+ ++new_facets;
+ }
+ break;
+
+ /*
+ * Case 1 - P is outside, Q & R are inside clip zone.
+ * This is a complex case which results in the creation
+ * of several new triangles including a "degenerate" triangle
+ * (two identical endpoints). Point "A" and point "Q" are
+ * already in the output list. Output vertex list is A-Q-B-Q-R
+ *
+ * |Q+ |Q+
+ * | /\ | /\
+ * |/ \ |/ \
+ * | \ ===> A+ \
+ * /| \ | \
+ * P+-|------+R B+------+R
+ * | |
+ * triangle PQR triangles AQB, QBQ(degenerate)
+ * & BQR
+ *
+ */
+ case 1:
+ /* If edges are visible,
+ * we wish to disable the edge from
+ * Q to B. This edge is specified
+ * by the forward edge of the first Q,
+ * the forward edge of B, and the
+ * backward edge of the second Q
+ */
+ if (pddc->Static.attrs->edges != PEXOff) {
+ out_pt.ptr -= point_size;
+ CLEAR_FWD_EDGE(out_pt.ptr, edge_offset);
+ /* edge from Q -> B */
+ out_pt.ptr += point_size;
+ }
+
+ CLIP_AND_COPY(vinput->type, in_ptP, t_ptP,
+ in_ptR, t_ptR, out_pt);
+ /* Places point "B" into output list */
+ if (pddc->Static.attrs->edges != PEXOff) {
+ CLEAR_FWD_EDGE(out_pt.ptr,edge_offset);
+ /* edge from B -> Q */
+ CLEAR_BKWD_EDGE(out_pt.ptr,edge_offset);
+ /* edge from B -> A */
+ }
+ out_pt.ptr += point_size;
+
+ COPY_POINT(in_ptQ, out_pt, point_size); /* degenerate point */
+ if (pddc->Static.attrs->edges != PEXOff)
+ CLEAR_BKWD_EDGE(out_pt.ptr,edge_offset);
+ out_pt.ptr += point_size;
+
+ COPY_POINT(in_ptR, out_pt, point_size);
+ out_pt.ptr += point_size;
+ pts_in_list += 3;
+
+ if (finput) {
+ /*
+ * Add three identical facets
+ */
+ COPY_FACET(in_fct, out_fct, facet_size);
+ out_fct += facet_size;
+ COPY_FACET(in_fct, out_fct, facet_size);
+ out_fct += facet_size;
+ COPY_FACET(in_fct, out_fct, facet_size);
+ out_fct += facet_size;
+ new_facets += 3;
+ }
+ break;
+
+ /*
+ * Case 2 - P is inside, Q is outside, R is inside.
+ * Points P and A are already in the output list.
+ * Output list is P-A-R-B-R : disable edges from
+ * A to R
+ *
+ * Q+
+ * /\ A B
+ * ---------- ---+--+---
+ * / \ ===> / \
+ * / \ / \
+ * P+--------+R P+--------+R
+ *
+ * triangle PQR triangles PAR, ARB, RBR
+ *
+ */
+ case 2:
+ if (pddc->Static.attrs->edges != PEXOff) {
+ out_pt.ptr -= point_size;
+ CLEAR_FWD_EDGE(out_pt.ptr,edge_offset);
+ /* Edge from A -> R */
+ out_pt.ptr += point_size;
+ }
+
+ COPY_POINT(in_ptR, out_pt, point_size);
+ /* Place point "R" into output list */
+ if (pddc->Static.attrs->edges != PEXOff)
+ CLEAR_FWD_EDGE(out_pt.ptr,edge_offset);
+ /* Edge from R -> B */
+ out_pt.ptr += point_size;
+
+ CLIP_AND_COPY(vinput->type, in_ptQ, t_ptQ,
+ in_ptR, t_ptR, out_pt);
+ /*place point "B" into output list */
+ if (pddc->Static.attrs->edges != PEXOff)
+ CLEAR_BKWD_EDGE(out_pt.ptr,edge_offset);
+ /* Edge from B -> A */
+ out_pt.ptr += point_size;
+
+ COPY_POINT(in_ptR, out_pt, point_size); /* degenerate point */
+ out_pt.ptr += point_size;
+ pts_in_list += 3;
+
+ if (finput) {
+ /*
+ * Add three identical facets
+ */
+ COPY_FACET(in_fct, out_fct, facet_size);
+ out_fct += facet_size;
+ COPY_FACET(in_fct, out_fct, facet_size);
+ out_fct += facet_size;
+ COPY_FACET(in_fct, out_fct, facet_size);
+ out_fct += facet_size;
+ new_facets += 3;
+ }
+ break;
+
+ /*
+ * Case 3 - P and Q outside, R inside.
+ * Note - this is the first triangle in a new list
+ *
+ * Output list is A-B-R. If beginning on odd facet
+ * output list is B-A-B-R
+ *
+ *
+ * Q+ | |
+ * /\ | |
+ * / \| |
+ * / | ===> B+
+ * / |\ |\
+ * P+------|-+R A+-+R
+ * | |
+ * triangle PQR triangle ABR or BABR
+ *
+ *
+ */
+ case 3:
+ /*
+ * Note - this is the first triangle in a
+ * list, so copy the first two points in
+ * addition to copying the last point. Also,
+ * in model clipping we must be careful to
+ * preserve the "sense" of the normals, so
+ * add a degenerate facet if necessary.
+ */
+
+ if(IS_ODD(k)) {
+ CLIP_AND_COPY(vinput->type, in_ptQ, t_ptQ,
+ in_ptR, t_ptR, out_pt);
+ /*Places point "B" into output list */
+ out_pt.ptr += point_size;
+ pts_in_list++;
+ if (finput) {
+ COPY_FACET(in_fct, out_fct, facet_size);
+ out_fct += facet_size;
+ ++new_facets;
+ }
+ }
+
+ CLIP_AND_COPY(vinput->type, in_ptP, t_ptP,
+ in_ptR, t_ptR, out_pt);
+ /*Places point "A" into output list */
+
+ if (pddc->Static.attrs->edges != PEXOff)
+ CLEAR_FWD_EDGE(out_pt.ptr,edge_offset);
+ /*Edge from A -> B */
+ out_pt.ptr += point_size;
+
+ CLIP_AND_COPY(vinput->type, in_ptQ, t_ptQ,
+ in_ptR, t_ptR, out_pt);
+ /*Places point "B" into output list */
+ out_pt.ptr += point_size;
+
+
+ COPY_POINT(in_ptR, out_pt, point_size);
+ /*Places point "R" into output list */
+ out_pt.ptr += point_size;
+
+ if (finput) {
+ COPY_FACET(in_fct, out_fct, facet_size);
+ out_fct += facet_size;
+ ++new_facets;
+ }
+ pts_in_list += 3;
+ break;
+
+ /*
+ * Case 4 - P and Q inside, R outside
+ * Output list is P-Q-B-Q-A
+ *
+ * Q+ | Q+ |
+ * /\ | /\ |
+ * / \| / \|
+ * / | ===> / +A
+ * / |\ / |
+ * P+------|-+R P+------+B
+ * | |
+ *
+ * triangle PQR triangles PQB, BQB, BQA
+ *
+ */
+ case 4:
+
+ if (pddc->Static.attrs->edges != PEXOff) {
+ out_pt.ptr -= point_size;
+ CLEAR_FWD_EDGE(out_pt.ptr, edge_offset);
+ /* edge from Q -> B */
+ out_pt.ptr += point_size;
+ }
+
+ CLIP_AND_COPY(vinput->type, in_ptR, t_ptR,
+ in_ptP, t_ptP, out_pt);
+ /* Places "B" into output */
+ if (pddc->Static.attrs->edges != PEXOff)
+ CLEAR_FWD_EDGE(out_pt.ptr,edge_offset);
+ /* Edge from B -> Q */
+ out_pt.ptr += point_size;
+
+ COPY_POINT(in_ptQ, out_pt, point_size);
+ /* Places "Q" into output */
+ if (pddc->Static.attrs->edges != PEXOff)
+ CLEAR_FWD_EDGE(out_pt.ptr,edge_offset);
+ /* Edge from Q -> B */
+ out_pt.ptr += point_size;
+
+ CLIP_AND_COPY(vinput->type, in_ptR, t_ptR,
+ in_ptQ, t_ptQ, out_pt);
+ /* Places "A" into output */
+ if (pddc->Static.attrs->edges != PEXOff)
+ CLEAR_BKWD_EDGE(out_pt.ptr,edge_offset);
+ /* Edge from A -> B */
+ out_pt.ptr += point_size;
+ pts_in_list += 3;
+
+ if (finput) {
+ /*
+ * Add three identical facets
+ */
+ COPY_FACET(in_fct, out_fct, facet_size);
+ out_fct += facet_size;
+ COPY_FACET(in_fct, out_fct, facet_size);
+ out_fct += facet_size;
+ COPY_FACET(in_fct, out_fct, facet_size);
+ out_fct += facet_size;
+ new_facets += 3;
+ }
+ break;
+
+ /*
+ * Case 5 - P and R are outside, Q in inside.
+ * Output list is A-Q-B. A and Q already in list
+ *
+ * Q+ Q+
+ * /\ /\
+ * ---------- ---+--+---
+ * / \ ===> A B
+ * / \
+ * P+--------+R
+ *
+ * triangle PQR triangles AQB
+ *
+ */
+ case 5:
+ CLIP_AND_COPY(vinput->type, in_ptR, t_ptR,
+ in_ptQ, t_ptQ, out_pt);
+ /*Places point "B" into output list */
+ if (pddc->Static.attrs->edges != PEXOff)
+ CLEAR_BKWD_EDGE(out_pt.ptr,edge_offset);
+ /* Edge from B -> A */
+ out_pt.ptr += point_size;
+ pts_in_list++;
+
+ if (finput) {
+ COPY_FACET(in_fct, out_fct, facet_size);
+ out_fct += facet_size;
+ ++new_facets;
+ }
+ break;
+
+ /*
+ * Case 6 - P is inside, R and Q are outside
+ * Output list is: P-A-B
+ *
+ * |Q+ |
+ * | /\ |
+ * |/ \ |
+ * | \ ===> +A
+ * /| \ /|
+ * P+-|------+R P+-+B
+ * | |
+ * triangle PQR triangles
+ *
+ */
+ case 6:
+ if (pddc->Static.attrs->edges != PEXOff) {
+ out_pt.ptr -= point_size;
+ CLEAR_FWD_EDGE(out_pt.ptr,edge_offset);
+ out_pt.ptr += point_size;
+ }
+
+ CLIP_AND_COPY(vinput->type, in_ptR, t_ptR,
+ in_ptP, t_ptP, out_pt);
+ /* Places "B" into output list */
+ out_pt.ptr += point_size;
+ pts_in_list += 1;
+
+ if (finput) {
+ COPY_FACET(in_fct, out_fct, facet_size);
+ out_fct += facet_size;
+ ++new_facets;
+ }
+ break;
+
+ /*
+ * Case 7 - P, Q, and R are outside
+ * trivial rejection; begin new list
+ * at first "included" point if
+ * sufficient number of points
+ *
+ * Q+
+ * /\
+ * / \
+ * / \ ===>
+ * / \
+ * P+--------+R
+ *
+ */
+ case 7:
+ /* Complete initialization of last list */
+ if (pts_in_list > 2) {
+ /* Generate a new output list, increment list count. */
+ pddolist->numPoints = pts_in_list;
+ voutput->numLists++;
+ out_listnum++;
+ MI_ALLOCLISTHEADER(voutput,
+ MI_ROUND_LISTHEADERCOUNT(voutput->numLists));
+ /* skip to next output list */
+ pddolist = voutput->ddList + out_listnum;
+
+ /* Insure sufficient room for remaining verts
+ and degenerate points */
+ MI_ALLOCLISTOFDDPOINT(pddolist,
+ 2*(vert_count - k), point_size);
+
+ out_pt.ptr = pddolist->pts.ptr;
+ if (!out_pt.ptr) return(BadAlloc);
+ }
+
+ else {
+ /* Not enough points for output list */
+ pddolist->numPoints = 0;
+ }
+
+ /* Look for next point inside bounds */
+ do {
+ clip_code = 0;
+ in_ptR.ptr += point_size;
+ if (finput) in_fct += facet_size;
+ k++;
+ if (k == vert_count)
+ break;
+ COMPUTE_CLIP_PARAMS(in_ptR, t_ptR, 2, clip_mode,
+ current_clip,MC_HSpace,clip_code);
+ } while(clip_code);
+ if (k < vert_count) {
+ /*
+ * k is incremented by the for loop, but because we have
+ * a new_list, the pointers won't get bumped. Therefore,
+ * k must be decremented to keep it consistent with the
+ * pointers for reentering the for loop.
+ *
+ * However, k must not be adjusted when k == vert_count,
+ * because in this case P, Q and R are all clipped and it
+ * is necessary to leave k == vert_count to terminate the
+ * for loop.
+ */
+ k--;
+
+ /* Get P & Q; re-enter loop.
+ * Next case encountered will be 3, which will
+ * handle the odd-even rule for normals.
+ */
+ in_ptQ.ptr = in_ptR.ptr - point_size;
+ in_ptP.ptr = in_ptQ.ptr - point_size;
+ clip_code = 0; /* Q's ORd in at top of loop */
+ COMPUTE_CLIP_PARAMS(in_ptP, t_ptP, 0, clip_mode,
+ current_clip,MC_HSpace,clip_code);
+ COMPUTE_CLIP_PARAMS(in_ptQ, t_ptQ, 1, clip_mode,
+ current_clip,MC_HSpace,clip_code);
+ }
+ new_list = 1;
+ pts_in_list = 0; /*start a new list*/
+ break;
+
+ } /* end of cases */
+
+ if (!new_list) {
+ /* Prepare for next point */
+ in_ptP = in_ptQ; t_ptP = t_ptQ;
+ in_ptQ = in_ptR; t_ptQ = t_ptR;
+ in_ptR.ptr += point_size;
+ if (finput) in_fct += facet_size;
+ clip_code >>= 1;
+ }
+
+ } /* end of single list processing */
+
+ if (pts_in_list > 2) { /* Got some points! */
+ /* skip to next list, increment list count. */
+ pddolist->numPoints = pts_in_list;
+ ++pddolist;
+ ++out_listnum;
+ ++voutput->numLists;
+ }
+ else pddolist->numPoints = 0; /* use same list */
+
+ pddilist++;
+ } /* end of list of lists processing */
+
+ if (foutput) foutput->numFacets = new_facets;
+
+ if (out_listnum > 0) {
+ /* Use result of previous clip for input to next clip */
+ vinput = voutput;
+ if (voutput == list2) voutput = list1; /* ping-pong */
+ else voutput = list2;
+
+ if (finput) {
+ /* Use result of previous clip for input to next clip */
+ finput = foutput;
+ if (foutput == fct_list2) foutput = fct_list1;
+ else foutput = fct_list2;
+ }
+ } else {
+ /* If no lists, exit loop */
+ vinput = voutput;
+ finput = foutput;
+ }
+ if (clip_mode == MI_MCLIP) MC_HSpace++;
+
+ } /* end of processing for all clip planes */
+
+
+ /* Current input list is last processed (clipped) list */
+ *output_vert = vinput;
+ if (finput) *output_fct = finput;
+ else *output_fct = input_fct;
+
+
+ return (Success);
+
+}
+
+
+
+/*++
+ |
+ | miLightTriStrip
+ |
+ | Perform lighting calculations for the vertex or facet
+ | data provided according to the current attributes.
+ |
+ --*/
+
+ddpex3rtn
+miLightTriStrip(pRend, pddc, input_vert, input_fct, output_vert, output_fct)
+ ddRendererPtr pRend; /* renderer handle */
+ miDDContext *pddc; /* dd Context pointer */
+ miListHeader *input_vert; /* input vertex data */
+ listofddFacet *input_fct; /* input facet data */
+ miListHeader **output_vert; /* output vertex data */
+ listofddFacet **output_fct; /* output facet data */
+{
+/* calls */
+ ddpex3rtn miApply_Lighting();
+ ddpex3rtn miFilterPath();
+
+/* uses */
+ listofddFacet *fct_list, *broken_fct;
+ miListHeader *out_vert, *broken_list;
+ ddVector3D in_vertnorm;
+ ddRgbFloatColour in_vertcolour;
+ ddRgbFloatNormal *in_fct;
+ ddRgbFloatColour *out_fct;
+ listofddPoint *pddilist;
+ listofddPoint *pddolist;
+ ddPointUnion in_pt, out_pt;
+ int i, j, k, num_facets,
+ inpoint_size, outpoint_size;
+ ddpex3rtn status;
+
+
+ /* Look for empty fill style. Still might have to render edges. */
+ if (pddc->Static.attrs->intStyle == PEXInteriorStyleEmpty)
+ return(Success);
+
+ /*
+ * First, Insure that the vertex and/or facet data
+ * is sufficient for the current Surface Interpolation method.
+ * Note that this implementation does not support
+ * PEXSurfaceInterpDotProduct and PEXSurfaceInterpNormal and
+ * that these surface interpolation types are approximated by
+ * PEXSurfaceInterpColour. The cases dealt with here, therefore,
+ * are constant surface color (thus a single color is computed
+ * per facet) and interpolated surface color (thus a color
+ * per vertex is required).
+ */
+
+ DD_VertPointSize(input_vert->type, inpoint_size);
+ switch(pddc->Static.attrs->surfInterp) {
+
+ case PEXSurfaceInterpNone: /* Flat shading */
+
+ if ((!input_fct) ||
+ (input_fct->numFacets == 0) ||
+ (!( (DD_IsFacetColour(input_fct->type)) &&
+ (DD_IsFacetNormal(input_fct->type))))) {
+
+ Complete_TriFacetList(pRend, input_vert, input_fct,
+ output_fct);
+
+ input_fct = *output_fct;
+ }
+
+ /*
+ * Should have facets with normals and surface colors now.
+ * Since we are flat shading, there is no further use
+ * for per-vertex color or normal data (however, leave
+ * any edge information). Remove it to prevent confusion
+ * further down the pipeline.
+ */
+ if ( (DD_IsVertNormal(input_vert->type)) ||
+ (DD_IsVertColour(input_vert->type)) ) {
+ if (status = miFilterPath(pddc, input_vert, output_vert,
+ ((1 << 3) | 1) ))
+ return(status);
+ } else {
+ *output_vert = input_vert;
+ }
+
+ /*
+ * Now allocate storage for the output facet list
+ * Note that the output facet list only contains colors.
+ */
+ *output_fct = fct_list = MI_NEXTTEMPFACETLIST(pddc);
+ fct_list->numFacets = input_fct->numFacets;
+ fct_list->type = DD_FACET_RGBFLOAT;
+ MI_ALLOCLISTOFDDFACET(fct_list, input_fct->numFacets,
+ sizeof(ddRgbFloatColour));
+ if (!(out_fct = fct_list->facets.pFacetRgbFloat)) return(BadAlloc);
+ in_fct = input_fct->facets.pFacetRgbFloatN;
+ pddilist = input_vert->ddList;
+ for(i = 0, in_pt.ptr = pddilist->pts.ptr;
+ i < input_vert->numLists; i++) {
+
+ /*
+ * Compute lighted facet color for each facet.
+ * Facet color is simply the sum of the lighting contributions
+ * from each light source.
+ */
+ for (k = 2; k < pddilist->numPoints; k++) {
+
+ /* One point at a time. Again, it is assumed there is a */
+ /* one<->one correspondence between the points in the lists */
+ /* and individual facets. Also note that we are associating */
+ /* arbitrarily the first point with the "position" of the */
+ /* facet. Perhaps a more correct method would use that average */
+
+ if (status = miApply_Lighting(pRend, pddc,
+ in_pt.p4Dpt,
+ &(in_fct->colour),
+ &(in_fct->normal),
+ out_fct ))
+ return(status);
+
+ in_pt.ptr += inpoint_size;
+ in_fct++;
+ out_fct++;
+ }
+ /* skip to next input vertex list */
+ pddilist++;
+ }
+ break;
+
+ case PEXSurfaceInterpColour:
+ case PEXSurfaceInterpDotProduct:
+ case PEXSurfaceInterpNormal:
+
+ if (!DD_IsVertNormal(input_vert->type)) {
+ /* Here, and only here, we must create a separate list for
+ * facet of the triangle strip. The reason for this is that
+ * we can only associate with each vertex a single normal,
+ * when in reality a vertex has different normals depending
+ * upon which facet is being rendered. The lighting effects
+ * only appear in positional lights, because the dot
+ * product with the vertex normals is indeed dependent upon
+ * position */
+
+ if (i = Breakup_TriStrip(pddc, input_vert, input_fct,
+ &broken_list, &broken_fct)) return (i);
+ input_vert = broken_list;
+ input_fct = broken_fct;
+ }
+
+ /* Insure sufficient info for calculation */
+ if ( (!DD_IsVertColour(input_vert->type)) ||
+ (!DD_IsVertNormal(input_vert->type)) ) {
+ Calculate_TriStrip_Vertex_Color_and_Normal(pRend, input_vert,
+ input_fct,
+ output_vert);
+ input_vert = *output_vert;
+ }
+
+ /* From here facet data only used in culling operation */
+ *output_fct = input_fct;
+
+ /* Use one of the pre-defined 4D list for output */
+ *output_vert = out_vert = MI_NEXTTEMPDATALIST(pddc);
+
+ /* Insure sufficient room for each header */
+ MI_ALLOCLISTHEADER(out_vert,
+ MI_ROUND_LISTHEADERCOUNT(input_vert->numLists))
+ if (!out_vert->ddList) return(BadAlloc);
+
+ out_vert->type = DD_RGBFLOAT_POINT4D;
+ if (pddc->Static.attrs->edges != PEXOff &&
+ DD_IsVertEdge(input_vert->type)) {
+ DD_SetVertEdge(out_vert->type);
+ }
+ out_vert->numLists = input_vert->numLists;
+ out_vert->flags = input_vert->flags;
+
+ DD_VertPointSize(out_vert->type, outpoint_size);
+ pddilist = input_vert->ddList;
+ pddolist = out_vert->ddList;
+
+ for(i = 0; i < input_vert->numLists; i++) {
+
+ pddolist->numPoints = pddilist->numPoints;
+ MI_ALLOCLISTOFDDPOINT(pddolist, pddolist->numPoints,
+ outpoint_size);
+ if (!(out_pt.ptr = pddolist->pts.ptr)) return(BadAlloc);
+
+ for (j = 0, in_pt.ptr = pddilist->pts.ptr;
+ j < pddilist->numPoints; j++) {
+
+ /* Copy over the coordinate info */
+ *out_pt.p4Dpt = *in_pt.p4Dpt;
+
+ /* move output pointer to colour field */
+ out_pt.p4Dpt++;
+
+ /* miApplyLighting works on a single point at a time */
+ if (status = miApply_Lighting(pRend, pddc,
+ in_pt.p4Dpt,
+ &(in_pt.pRgbFloatNpt4D->colour),
+ &(in_pt.pRgbFloatNpt4D->normal),
+ out_pt.pRgbFloatClr))
+ return(status);
+
+ /* increment pointers */
+ in_pt.pRgbFloatNpt4D++;
+ out_pt.pRgbFloatClr++;
+
+ if (DD_IsVertEdge(out_vert->type)) {
+ *out_pt.pEdge = *in_pt.pEdge;
+ out_pt.pEdge++;
+ in_pt.pEdge++;
+ }
+
+
+ }
+ /* skip to next input and output vertex list */
+ pddilist++;
+ pddolist++;
+ }
+
+ break;
+
+ default:
+ *output_vert = input_vert;
+ *output_fct = input_fct;
+
+ }
+
+ return(Success);
+}
+
+/*++
+ |
+ | Complete_TriFacetList(pRend, input_vert, output_fct)
+ |
+ | Generates a facet list with colors and normals
+ | This routine should get folded into one with
+ | Create_Normals, with some form of flag to signal
+ | the type of output required. It would also be the
+ | place to put back-face attribute distinction.
+ |
+ --*/
+/* calls */
+
+static
+ddpex3rtn
+Complete_TriFacetList(pRend, input_vert, input_fct, output_fct)
+ ddRendererPtr pRend; /* renderer handle */
+ miListHeader *input_vert; /* input vertex data */
+ listofddFacet *input_fct; /* input facet data */
+ listofddFacet **output_fct; /* output facet data */
+{
+/* local */
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ listofddFacet *fct_list;
+ ddRgbFloatNormal *out_fct;
+ listofddPoint *pddlist;
+ ddPointUnion in_pt, tmp_pt;
+ ddFacetUnion in_fct;
+ int point_size;
+ ddRgbFloatPoint4D *vert1, *vert2, *vert3;
+ int total_facets;
+ int i,j;
+ float length;
+ ddpex3rtn status;
+ char have_colors, have_normals;
+
+ have_colors = have_normals = 0;
+
+ /* What data must be added to output facet list ? */
+ if (!(input_fct) || (input_fct->type == DD_FACET_NONE)) {
+ /*
+ * Since we are creating the facet list for the first
+ * we need to learn how many verticies are in all the
+ * lists.
+ */
+ pddlist = input_vert->ddList;
+ for (i = 0, total_facets = 0; i < input_vert->numLists; pddlist++, i++)
+ total_facets += (pddlist->numPoints - 2);
+ } else {
+ /* use input facet information */
+ total_facets = input_fct->numFacets;
+ in_fct.pNoFacet = input_fct->facets.pNoFacet;
+ if DD_IsFacetNormal(input_fct->type) have_normals = ~0;
+ if DD_IsFacetColour(input_fct->type) have_colors = ~0;
+ }
+
+ if ((have_colors) && (have_normals)) { /* Why are we here? */
+ *output_fct = input_fct;
+ return(Success);
+ }
+
+ /*
+ * Allocate storage for the facet list
+ */
+ fct_list = MI_NEXTTEMPFACETLIST(pddc);
+ fct_list->type = DD_FACET_RGBFLOAT_NORM;
+ MI_ALLOCLISTOFDDFACET(fct_list, total_facets, sizeof(ddRgbFloatNormal));
+ if (!fct_list->facets.pNoFacet) return(BadAlloc);
+ out_fct = (ddRgbFloatNormal *)fct_list->facets.pFacetRgbFloatN;
+
+ DD_VertPointSize(input_vert->type, point_size);
+
+ /* Don't process if insufficient number of points */
+
+ if (input_vert->numLists > 0) {
+
+ pddlist = input_vert->ddList;
+
+ for (i = 0; i < input_vert->numLists; i++) {
+
+ in_pt.ptr = pddlist->pts.ptr;
+
+ for (j = 2; j < pddlist->numPoints; j++) {
+
+ /*
+ * Compute "intrinsic" color of facet.
+ * There is a "hierarchy" of sources for a facet's intrinsic
+ * color:
+ * vertex_colors present? facet_color =
+ * vertex_color of 1st point of facet
+ * else facet_color present? facet_color = facet_color
+ * else facet_color = PC_surface_color
+ * Note - this needs to be enhanced, using a dot product
+ * with the eye position to determine which surface color
+ * should be assigned in the case of front/back face
+ * distinguishing. this entire routine might get rolled into
+ * miLightTriStrip, and the correct color and reflectance
+ * model get passed into miApplyLighting.
+ */
+
+ if (DD_IsVertColour(input_vert->type)) {
+
+ out_fct->colour.red=out_fct->colour.green=out_fct->colour.blue=0.0;
+ vert1 = in_pt.pRgbFloatpt4D;
+ tmp_pt.ptr = in_pt.ptr + point_size;
+ vert2 = tmp_pt.pRgbFloatpt4D;
+ tmp_pt.ptr += point_size;
+ vert3 = tmp_pt.pRgbFloatpt4D;
+
+ out_fct->colour.red = ( vert1->colour.red +
+ vert2->colour.red +
+ vert3->colour.red )/3.0;
+ out_fct->colour.green = ( vert1->colour.green +
+ vert2->colour.green +
+ vert3->colour.green )/3.0;
+ out_fct->colour.blue = ( vert1->colour.blue +
+ vert2->colour.blue +
+ vert3->colour.blue )/3.0;
+
+ } else if (have_colors) {
+ out_fct->colour = *in_fct.pFacetRgbFloat;
+ in_fct.pFacetRgbFloat++;
+ } else {
+ /* use front face colors. This needs to get generalized
+ to deal with back-facing attributes*/
+ out_fct->colour =
+ (pddc->Static.attrs->surfaceColour.colour.rgbFloat);
+ }
+
+ if (!(have_normals)) {
+ /*
+ * Compute surface normal. Normals are required in
+ * Apply_Lighting for directional and positional lights,
+ * as well as culling (if enabled). One COULD check
+ * for ambient only, no culling, to optimize.
+ *
+ * The Surface normal is the cross product
+ * of three non-colinear points, in correct order.
+ */
+
+ vert1 = in_pt.pRgbFloatpt4D;
+ tmp_pt.ptr = in_pt.ptr + point_size;
+ vert2 = tmp_pt.pRgbFloatpt4D;
+ tmp_pt.ptr += point_size;
+ vert3 = tmp_pt.pRgbFloatpt4D;
+
+ if IS_ODD(j) {
+ CROSS_PRODUCT((&(vert3->pt)), (&(vert2->pt)), (&(vert1->pt)),
+ &(out_fct->normal));
+ }
+ else {
+ CROSS_PRODUCT((&(vert1->pt)), (&(vert2->pt)), (&(vert3->pt)),
+ &(out_fct->normal));
+ }
+
+ NORMALIZE_VECTOR(&(out_fct->normal), length);
+
+ /* Initialize to zero if triangle is
+ * degenerate and points are co-linear
+ */
+
+ if NEAR_ZERO(length) {
+ /* degenerate facet */
+ (out_fct->normal.x = 0.0);
+ (out_fct->normal.y = 0.0);
+ (out_fct->normal.z = 0.0);
+ }
+ } else {
+ /* use input facet normals */
+ out_fct->normal = *in_fct.pFacetN;
+ in_fct.pFacetN++;
+ }
+
+ /* Process next facet */
+ out_fct++;
+ in_pt.ptr += point_size;
+ }
+
+ pddlist++;
+ }
+
+ fct_list->numFacets = total_facets;
+ fct_list->type = DD_FACET_RGBFLOAT_NORM;
+
+ } else {
+ fct_list->type = DD_FACET_NONE;
+ fct_list->numFacets = 0;
+ }
+
+ *output_fct = fct_list;
+ return(Success);
+
+}
+
+/*++
+ |
+ | Calculate_TriStrip_Facet_Normal
+ |
+ | Add facet normals to a facet list.
+ | Here we are counting on the fact that there is a one to one
+ | correspondance between input facets and vertex ordering.
+ |
+ --*/
+static
+ddpex3rtn
+Calculate_TriStrip_Facet_Normal(pddc, input_vert, input_fct, output_fct)
+ miDDContext *pddc;
+ miListHeader *input_vert; /* input vertex data */
+ listofddFacet *input_fct; /* input facet data */
+ listofddFacet **output_fct; /* output facet data */
+{
+
+ listofddFacet *fct_list;
+ ddRgbFloatColour *in_fct;
+ ddFacetUnion out_fct;
+ listofddPoint *pddlist;
+ ddPointUnion in_pt, nxt_pt;
+ ddVector3D normal;
+ int point_size;
+ ddCoord3D *vert1, *vert2, *vert3;
+ int numfacets;
+ int i,j;
+ float length;
+
+
+ /* Some quick error checking */
+ if ((input_fct) && (DD_IsFacetNormal(input_fct->type))) return(Success);
+
+
+ /*
+ * First, allocate storage for the facet list
+ */
+ fct_list = MI_NEXTTEMPFACETLIST(pddc);
+ if ((input_fct) && DD_IsFacetColour(input_fct->type)) {
+ in_fct = input_fct->facets.pFacetRgbFloat;
+ fct_list->type = DD_FACET_RGBFLOAT_NORM;
+ numfacets = input_fct->numFacets;
+ MI_ALLOCLISTOFDDFACET(fct_list, numfacets, sizeof(ddRgbFloatNormal));
+ } else {
+ in_fct = 0;
+ fct_list->type = DD_FACET_NORM;
+
+
+ /* Determine the total number of facets in all the lists */
+ for (i = 0, numfacets = 0, pddlist = input_vert->ddList;
+ i < input_vert->numLists; pddlist++, i++)
+ numfacets += (pddlist->numPoints - 2);
+
+ MI_ALLOCLISTOFDDFACET(fct_list, numfacets, sizeof(ddVector3D));
+ }
+
+ fct_list->numFacets = numfacets;
+ if (!fct_list->facets.pNoFacet) return(BadAlloc);
+
+ /* Otherwise... */
+ out_fct = fct_list->facets;
+ DD_VertPointSize(input_vert->type, point_size);
+
+ /* Don't process if no facets (!) */
+ if (numfacets == 0) return(1);
+
+ else {
+ for(i = 0, pddlist = input_vert->ddList;
+ i < input_vert->numLists; i++) {
+ for (j = 2, in_pt.ptr = pddlist->pts.ptr;
+ j < pddlist->numPoints; j++) {
+
+ /* Copy the input facet color */
+ if (in_fct) {
+ *out_fct.pFacetRgbFloat = *in_fct;
+ in_fct++;
+ }
+
+ /* Calculate and copy normal */
+
+ vert1 = in_pt.p3Dpt;
+ nxt_pt.ptr = in_pt.ptr + point_size;
+ vert2 = nxt_pt.p3Dpt;
+ nxt_pt.ptr += point_size;
+ vert3 = nxt_pt.p3Dpt;
+
+ if (IS_ODD(j)) {
+ CROSS_PRODUCT(vert3, vert2, vert1, &normal);
+ } else {
+ CROSS_PRODUCT(vert1, vert2, vert3, &normal);
+ }
+
+ NORMALIZE_VECTOR(&normal, length)
+
+ /* Initialize to zero if triangle is
+ * degenerate and points are co-linear
+ */
+
+ if (length == 0.0) {
+ (normal.x = 0.0);
+ (normal.y = 0.0);
+ (normal.z = 0.0);
+ }
+
+
+ if (in_fct) (out_fct.pFacetRgbFloatN++)->normal = normal;
+ else *(out_fct.pFacetN++) = normal;
+
+ in_pt.ptr += point_size;
+ }
+ pddlist++;
+ }
+ }
+
+ *output_fct = fct_list;
+
+ return(Success);
+}
+
+
+/*++
+ |
+ | Breakup_TriStrip
+ |
+ | Breaks up a triangle strip into as many lists as there are facets.
+ | This is necessary for shading interpolation methods as we need to
+ | facilitate a set of normals per facet.
+ |
+ |
+ |
+ --*/
+static
+ddpex3rtn
+Breakup_TriStrip(pddc, input_vert, input_fct, output_vert, output_fct)
+ miDDContext *pddc;
+ miListHeader *input_vert;
+ miListHeader **output_vert;
+ listofddFacet *input_fct; /* input facet data */
+ listofddFacet **output_fct; /* output facet data */
+{
+ miListHeader *list1;
+ listofddFacet *fct_list;
+ ddRgbFloatColour *in_fct;
+ ddFacetUnion out_fct;
+ listofddPoint *pddilist, *pddolist;
+ ddPointUnion pt_in, nxt_pt;
+ char *in_vert, *out_vert;
+ int point_size;
+ int numfacets, facetofpoints;
+ int i,j;
+
+
+
+ /* make sure that we have a facet list, and that it has normals */
+ if (!((input_fct) && (DD_IsFacetNormal(input_fct->type)))) {
+ if (i = Calculate_TriStrip_Facet_Normal(pddc, input_vert,
+ input_fct, &fct_list))
+ return(i);
+ input_fct = fct_list;
+ }
+
+ list1 = MI_NEXTTEMPDATALIST(pddc);
+ MI_ALLOCLISTHEADER(list1,
+ MI_ROUND_LISTHEADERCOUNT(input_fct->numFacets));
+ if (!list1->ddList) return(BadAlloc);
+ list1->type = input_vert->type;
+ list1->flags = input_vert->flags;
+
+ list1->numLists = input_fct->numFacets;
+
+
+ DD_VertPointSize(input_vert->type, point_size);
+ facetofpoints = 3 * point_size;
+
+ for(i = 0, pddilist = input_vert->ddList,
+ pddolist = list1->ddList;
+ i < input_vert->numLists; i++) {
+
+ for (j = 2, pt_in.ptr = pddilist->pts.ptr;
+ j < pddilist->numPoints; j++) {
+
+ MI_ALLOCLISTOFDDPOINT(pddolist, 1, facetofpoints);
+
+ /*
+ * Note that to preserver correct normals, must
+ * flip the order of the vertices every other facet.
+ */
+ if IS_ODD(j) {
+
+ in_vert = pt_in.ptr + 2*point_size;
+ out_vert = pddolist->pts.ptr;
+ memcpy( out_vert, in_vert, point_size);
+ in_vert -= point_size; out_vert += point_size;
+ memcpy( out_vert, in_vert, point_size);
+ out_vert += point_size;
+ memcpy( out_vert, pt_in.ptr, point_size);
+
+ } else {
+
+ memcpy( pddolist->pts.ptr, pt_in.ptr, facetofpoints);
+
+ }
+
+ pddolist->numPoints = 3;
+ pddolist++; /* one list per facet */
+ pt_in.ptr += point_size;
+ }
+ pddilist++;
+ }
+
+ *output_fct = input_fct;
+ *output_vert = list1;
+ return(Success);
+}
+
+
+
+
+
+/*++
+ |
+ | Calculate_TriStrip_Vertex_Color_and_Normal
+ |
+ | Add vertex normals and colors to a vertex list.
+ |
+ --*/
+static
+ddpex3rtn
+Calculate_TriStrip_Vertex_Color_and_Normal(pRend, input_vert, input_fct,
+ output_vert)
+
+ ddRendererPtr pRend; /* renderer handle */
+ miListHeader *input_vert; /* input vertex data */
+ listofddFacet *input_fct; /* input facet data */
+ miListHeader **output_vert; /* output vertex data */
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ miListHeader *out_vert;
+ listofddFacet *fct_list;
+ ddRgbFloatNormal *out_fct;
+ listofddPoint *pddilist;
+ listofddPoint *pddolist;
+ ddPointUnion in_pt, out_pt;
+ ddFacetUnion in_fct;
+ int inpoint_size, outpoint_size;
+ int facet_size;
+ int numFacets=0;
+ int i,j;
+ ddpex3rtn status;
+
+
+ /* Some quick error checking */
+ if ((DD_IsVertNormal(input_vert->type)) &&
+ (DD_IsVertColour(input_vert->type)))
+ return(Success);
+
+ /* Use one of the pre-defined 4D list for output */
+ *output_vert = out_vert = MI_NEXTTEMPDATALIST(pddc);
+
+ /* Insure sufficient room for each header */
+ MI_ALLOCLISTHEADER(out_vert,
+ MI_ROUND_LISTHEADERCOUNT(input_vert->numLists))
+ if (!out_vert->ddList) return(BadAlloc);
+
+ out_vert->type = DD_RGBFLOAT_NORM_POINT4D;
+ if (pddc->Static.attrs->edges != PEXOff &&
+ DD_IsVertEdge(input_vert->type)) {
+ DD_SetVertEdge(out_vert->type);
+ }
+ out_vert->numLists = input_vert->numLists;
+ out_vert->flags = input_vert->flags;
+
+ pddilist = input_vert->ddList;
+ pddolist = out_vert->ddList;
+
+ DD_VertPointSize(input_vert->type, inpoint_size);
+ DD_VertPointSize(out_vert->type, outpoint_size);
+
+ /* Compute facet normals if no per-vertex normals with data */
+ if ( (!(DD_IsVertNormal(input_vert->type))) &&
+ ((!(input_fct)) || (!(DD_IsFacetNormal(input_fct->type)))) ) {
+
+ if (i = Calculate_TriStrip_Facet_Normal(pddc, input_vert,
+ input_fct, &fct_list))
+ return(i);
+
+ input_fct = fct_list;
+ }
+
+ if ((input_fct) && (input_fct->numFacets > 0)) {
+ in_fct = input_fct->facets;
+ DDFacetSIZE(input_fct->type, facet_size);
+ }
+ else in_fct.pNoFacet = 0;
+
+
+ for(i = 0; i < input_vert->numLists; i++) {
+ pddolist->numPoints = pddilist->numPoints;
+ in_pt.ptr = pddilist->pts.ptr;
+ MI_ALLOCLISTOFDDPOINT(pddolist,(pddilist->numPoints+1),
+ outpoint_size);
+ if (!(out_pt.ptr = pddolist->pts.ptr)) return(BadAlloc);
+
+ for (j = 0, in_pt.ptr = pddilist->pts.ptr,
+ out_pt.ptr = pddolist->pts.ptr;
+ j < pddilist->numPoints; j++) {
+
+ /* First copy over coordinate data */
+ *out_pt.p4Dpt = *in_pt.p4Dpt;
+ in_pt.p4Dpt++;
+ out_pt.p4Dpt++;
+
+ /*
+ * Next color
+ * Colour is derived first from the vertex, second from the
+ * facet, and third from the current PC attributes.
+ */
+ if (DD_IsVertColour(input_vert->type)){
+ *out_pt.pRgbFloatClr = *in_pt.pRgbFloatClr;
+ in_pt.pRgbFloatClr++;
+ }
+ else {
+ if ((in_fct.pNoFacet) && (DD_IsFacetColour(input_fct->type)))
+ *out_pt.pRgbFloatClr = *in_fct.pFacetRgbFloat;
+ else {
+ *out_pt.pRgbFloatClr =
+ (pddc->Static.attrs->surfaceColour.colour.rgbFloat);
+ }
+ }
+
+ out_pt.pRgbFloatClr++;
+
+ /*
+ * Next normals
+ * Normals are derived first from the vertex, second from the
+ * facet (note that we insured above that there were facet normals).
+ */
+ if DD_IsVertNormal(input_vert->type) {
+ *out_pt.pNormal = *in_pt.pNormal;
+ in_pt.pNormal++;
+ }
+ else if (DD_IsFacetColour(input_fct->type))
+ *out_pt.pNormal = in_fct.pFacetRgbFloatN->normal;
+ else *out_pt.pNormal = *in_fct.pFacetN;
+
+ out_pt.pNormal++;
+
+ /* Next pass along edge info if there is any */
+ if (DD_IsVertEdge(out_vert->type)) {
+ *out_pt.pEdge = *in_pt.pEdge;
+ in_pt.pEdge++;
+ out_pt.pEdge++;
+ }
+
+ }
+ if ((in_fct.pNoFacet)) in_fct.pNoFacet += facet_size;
+ pddilist++;
+ pddolist++;
+ }
+ return(Success);
+}
+
+/*++
+ |
+ | miCullTriStrip(pddc, input_vert, input_fct, output_vert, output_fct)
+ |
+ | Perform culling of facets, and their associated data points,
+ | according to the current culling mode.
+ |
+ --*/
+
+static
+ddpex3rtn
+miCullTriStrip(pddc, input_vert, input_fct, output_vert, output_fct)
+ miDDContext *pddc; /* dd Context pointer */
+ miListHeader *input_vert; /* input vertex data */
+ listofddFacet *input_fct; /* input facet data */
+ miListHeader **output_vert; /* output vertex data */
+ listofddFacet **output_fct; /* output facet data */
+{
+/* uses */
+ miListHeader *out_vert;
+ listofddPoint *pddilist;
+ listofddPoint *pddolist;
+ listofddFacet *fct_list;
+ ddFacetUnion in_fct;
+ ddFacetUnion out_fct;
+ ddPointUnion in_pt,out_pt;
+ listofddPoint temp;
+ int i, j;
+ char accept, new_list;
+ char return_facet_list;
+ int point_size, facet_size;
+ int verts_in_list, out_listnum;
+
+ /*
+ * Create facet normals if necessary. These are used to determine
+ * if the facet is to be culled. Note: only return a facet list
+ * if a valid facet list is input.
+ */
+ if ( (!input_fct) || (input_fct->numFacets <= 0) ) {
+ Calculate_TriStrip_Facet_Normal(pddc, input_vert,
+ (listofddFacet *)0, &input_fct);
+ return_facet_list = 0;
+ *output_fct = 0;
+ } else {
+ if (!(DD_IsFacetNormal(input_fct->type))) {
+ Calculate_TriStrip_Facet_Normal(pddc, input_vert,
+ input_fct, output_fct);
+ input_fct = *output_fct;
+ }
+ return_facet_list = 1;
+ }
+
+ /*
+ * allocate storage for the output vertex and facet list
+ */
+ *output_vert = out_vert = MI_NEXTTEMPDATALIST(pddc);
+ out_vert->type = input_vert->type;
+ out_vert->flags = input_vert->flags;
+ out_vert->numLists = 0;
+ MI_ALLOCLISTHEADER(out_vert,
+ MI_ROUND_LISTHEADERCOUNT(input_vert->numLists))
+ if (!out_vert->ddList) return(BadAlloc);
+
+
+ DD_VertPointSize(input_vert->type, point_size);
+
+ fct_list = MI_NEXTTEMPFACETLIST(pddc);
+ fct_list->type = input_fct->type;
+ DDFacetSIZE(input_fct->type, facet_size);
+ MI_ALLOCLISTOFDDFACET(fct_list, input_fct->numFacets, facet_size);
+ out_fct = fct_list->facets;
+ if (!out_fct.pNoFacet) return(BadAlloc);
+ in_fct = input_fct->facets;
+
+
+ /*
+ * This test is performed in NPC space. As a result,
+ * the sign of the z component of the facet normal
+ * indicates the direction in which the facet is pointing.
+ * Therefore if the cullmode is PEXBackFaces and the
+ * z component is negative, reject the facet. Similarily,
+ * if the z component of the normal is positive, and
+ * the cullmode is PEXFrontFaces, also reject the face.
+ */
+
+ for(i = 0, out_listnum = 1, fct_list->numFacets = 0,
+ out_vert->numLists = 0,
+ pddilist = input_vert->ddList, pddolist = out_vert->ddList;
+ i < input_vert->numLists; i++) {
+
+ MI_ALLOCLISTOFDDPOINT(pddolist,(pddilist->numPoints+1),point_size);
+ if (!pddolist->pts.ptr) return(BadAlloc);
+
+ for (j= 2, verts_in_list = 0, new_list = 1,
+ in_pt.ptr = pddilist->pts.ptr + (2 * point_size),
+ out_pt.ptr = pddolist->pts.ptr,
+ pddolist->numPoints = 0;
+ j < pddilist->numPoints; j++) {
+
+ accept = 0;
+
+ if (pddc->Dynamic->pPCAttr->cullMode == PEXBackFaces) {
+ if (DD_IsFacetColour(input_fct->type)) {
+ if (in_fct.pFacetRgbFloatN->normal.z >= 0) accept = 1;
+ } else if (in_fct.pFacetN->z >= 0) accept = 1;
+ } else /* pddc->Dynamic->pPCAttr->cullMode == PEXFrontFaces */ {
+ if (DD_IsFacetColour(input_fct->type)) {
+ if (in_fct.pFacetRgbFloatN->normal.z < 0) accept = 1;
+ } else if (in_fct.pFacetN->z < 0) accept = 1;
+ }
+
+ if (accept) {
+
+ if (new_list) { /* starting new list after facet(s) culled */
+ /*initialize first points for the first facet */
+ memcpy( out_pt.ptr, in_pt.ptr - (2 * point_size), (2*point_size));
+ out_pt.ptr += 2 * point_size;
+ new_list = 0;
+ verts_in_list += 2;
+ }
+
+ /* copy the vertex info associated with this facet */
+ memcpy( out_pt.ptr, in_pt.ptr, point_size);
+ out_pt.ptr += point_size;
+ ++verts_in_list;
+
+ /* copy the facet info */
+ if (DD_IsFacetColour(input_fct->type))
+ *out_fct.pFacetRgbFloatN = *in_fct.pFacetRgbFloatN;
+ else *out_fct.pFacetN = *in_fct.pFacetN;
+
+ /* increment the output pointer */
+ out_fct.pNoFacet += facet_size;
+ fct_list->numFacets++;
+
+ } else {
+ /* Facet culled; terminate output vertex list */
+ if (verts_in_list > 2) { /* facets in this list */
+ pddolist->numPoints = verts_in_list;
+ ++out_vert->numLists;
+ out_listnum++;
+ /* create a new output vertex list; load first points */
+ MI_ALLOCLISTHEADER(out_vert,
+ MI_ROUND_LISTHEADERCOUNT(out_listnum))
+ if (!out_vert->ddList) return(BadAlloc);
+
+ pddolist = out_vert->ddList + (out_listnum - 1);
+ pddolist->numPoints = 0;
+ MI_ALLOCLISTOFDDPOINT(pddolist,
+ (pddilist->numPoints - j + 2), point_size);
+ if (!pddolist->pts.ptr) return(BadAlloc);
+ out_pt.ptr = pddolist->pts.ptr;
+ verts_in_list = 0;
+ }
+ new_list = 1;
+ }
+ in_pt.ptr += point_size;
+ in_fct.pNoFacet += facet_size;
+ }
+ ++pddilist;
+ if (verts_in_list > 2) {
+ pddolist->numPoints = verts_in_list;
+ ++out_listnum;
+ ++out_vert->numLists;
+ ++pddolist;
+ }
+ }
+
+ /*
+ * Only return facet list if one was passed in. Reduces the
+ * information that must be processed by the rest of the pipeline.
+ */
+ if (return_facet_list) *output_fct = fct_list;
+
+ return(Success);
+}
+
+/*++
+ |
+ | miDepthCueTriStrip(pddc, input_vert, input_fct, output_vert, output_fct)
+ |
+ | Performs Depth cueing of triangle strips data lists..
+ | Assigns per-vertex colors to the data list according to the
+ | "Annex E - Informative" discussion of the ISO PHIGS PLUS spec.
+ |
+ |
+ --*/
+static
+ddpex3rtn
+miDepthCueTriStrip(pRend, input_vert, input_fct, output_vert)
+
+ ddRendererPtr pRend; /* renderer handle */
+ miListHeader *input_vert; /* input vertex data */
+ listofddFacet *input_fct; /* input facet data */
+ miListHeader **output_vert; /* output vertex data */
+{
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ miListHeader *out_vert;
+ listofddFacet *fct_list;
+ ddFLOAT pt_depth;
+ listofddPoint *pddilist;
+ listofddPoint *pddolist;
+ ddPointUnion in_pt, out_pt;
+ ddRgbFloatColour *in_color;
+ ddFacetUnion in_fct;
+ int inpoint_size, outpoint_size;
+ int facet_size;
+ int numFacets=0;
+ int i,j;
+ ddpex3rtn status;
+ ddDepthCueEntry *dcue_entry;
+
+ /* look for empty list header */
+ if (input_vert->numLists == 0) return(Success);
+
+ /* validate CC version of Depth Cue information */
+ if (pddc->Static.misc.flags & CC_DCUEVERSION)
+ Compute_CC_Dcue(pRend, pddc);
+
+ /* check to make sure depth cuing is enabled */
+ if (pddc->Static.misc.cc_dcue_entry.mode == PEXOff) {
+ *output_vert = input_vert;
+ return(Success);
+ }
+
+ /* Else, depth cue! Use one of the pre-defined 4D list for output */
+ *output_vert = out_vert = MI_NEXTTEMPDATALIST(pddc);
+
+ /* Insure sufficient room for each header */
+ MI_ALLOCLISTHEADER(out_vert,
+ MI_ROUND_LISTHEADERCOUNT(input_vert->numLists))
+ if (!out_vert->ddList) return(BadAlloc);
+
+ out_vert->type = input_vert->type;
+ if (!(DD_IsVertColour(input_vert->type)))
+ DD_SetVertRGBFLOAT(out_vert->type);
+ out_vert->numLists = input_vert->numLists;
+ out_vert->flags = input_vert->flags;
+
+ pddilist = input_vert->ddList;
+ pddolist = out_vert->ddList;
+
+ DD_VertPointSize(input_vert->type, inpoint_size);
+ DD_VertPointSize(out_vert->type, outpoint_size);
+
+ if ((input_fct) && (input_fct->numFacets > 0)) {
+ in_fct = input_fct->facets;
+ DDFacetSIZE(input_fct->type, facet_size);
+ } else in_fct.pNoFacet = 0;
+
+ for(i = 0; i < input_vert->numLists; i++) {
+ pddolist->numPoints = pddilist->numPoints;
+ in_pt.ptr = pddilist->pts.ptr;
+ MI_ALLOCLISTOFDDPOINT(pddolist,(pddilist->numPoints+1),
+ outpoint_size);
+ if (!(out_pt.ptr = pddolist->pts.ptr)) return(BadAlloc);
+
+ for (j = 0, in_pt.ptr = pddilist->pts.ptr,
+ out_pt.ptr = pddolist->pts.ptr;
+ j < pddilist->numPoints; j++) {
+
+ /* First copy over coordinate data */
+ pt_depth = in_pt.p4Dpt->z;
+ *out_pt.p4Dpt = *in_pt.p4Dpt;
+ in_pt.p4Dpt++;
+ out_pt.p4Dpt++;
+
+ /*
+ * Next color
+ * Colour is derived first from the vertex, second from the
+ * facet, and third from the current PC attributes.
+ */
+ if (DD_IsVertColour(input_vert->type)){
+ in_color = in_pt.pRgbFloatClr;
+ in_pt.pRgbFloatClr++;
+ }
+ else {
+ if ((in_fct.pNoFacet) && (DD_IsFacetColour(input_fct->type)))
+ in_color = in_fct.pFacetRgbFloat;
+ else {
+ in_color =
+ &(pddc->Static.attrs->surfaceColour.colour.rgbFloat);
+ }
+ }
+
+ APPLY_DEPTH_CUEING(pddc->Static.misc.cc_dcue_entry,
+ pt_depth, in_color, out_pt.pRgbFloatClr)
+
+ out_pt.pRgbFloatClr++;
+
+ /*
+ * Next normals
+ * Normals are derived first from the vertex, second from the
+ * facet (note that we insured above that there were facet normals).
+ */
+ if DD_IsVertNormal(input_vert->type) {
+ *out_pt.pNormal = *in_pt.pNormal;
+ in_pt.pNormal++;
+ out_pt.pNormal++;
+ }
+
+ /* Next pass along edge info if there is any */
+ if (DD_IsVertEdge(out_vert->type)) {
+ *out_pt.pEdge = *in_pt.pEdge;
+ in_pt.pEdge++;
+ out_pt.pEdge++;
+ }
+
+ }
+ if ((in_fct.pNoFacet)) in_fct.pNoFacet += facet_size;
+ pddilist++;
+ pddolist++;
+ }
+ return(Success);
+}
+
+
+
+
+
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level2/pexOCParse.c b/xc/programs/Xserver/PEX5/ddpex/mi/level2/pexOCParse.c
new file mode 100644
index 000000000..7719736f6
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level2/pexOCParse.c
@@ -0,0 +1,2249 @@
+/* $TOG: pexOCParse.c /main/11 1998/02/10 12:43:05 kaleb $ */
+
+/***********************************************************
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems,
+not be used in advertising or publicity pertaining to distribution of
+the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level2/pexOCParse.c,v 3.6 1998/10/04 09:34:30 dawes Exp $ */
+
+
+#include "miStruct.h"
+#include "ddpex2.h"
+#include "pexExtract.h"
+#include "pexUtils.h"
+#include "miLight.h"
+#include "pexos.h"
+
+
+/** Parsing functions:
+ ** Each function takes two parameters: a pointer to the element to be
+ ** parsed (in PEX format) and a pointer to a pointer to return the
+ ** parsed element (in server native internal format).
+ **
+ ** These routines may be used in most cases for both creation
+ ** and replacement of structure elements. If the second argument
+ ** points to a NULL, then the memory is allocated for the creation
+ ** of the structure element. Otherwise, no new memory is
+ ** allocated and the structure element is replaced in place.
+ ** This scheme requires that the calling routine ensure
+ ** that there is sufficient memory already allocated for replacing
+ ** in place.
+ **
+ ** To support this scheme, parse routine writers must calculate
+ ** the amount of memory required to store the element in server
+ ** native format before allocating it, and pass this number of
+ ** bytes as the 3rd argument to the below macro GET_DD_STORAGE.
+ ** Then the parse routine can be put in both the parse and
+ ** replace tables as the entry for handling the OC.
+ **
+ ** Note that there are 3 exceptions to this symmetry:
+ ** LightState
+ ** SOFAS
+ ** NurbSurfaces
+ **
+ ** For each of these, there are separate parse and replace
+ ** routines.
+ **
+ ** For any OC that follows the above scheme, the corresponding
+ ** entry in the destroy table can be the default (destroyOC_PEX),
+ ** since memory allocation is therefore in one chunk. If the
+ ** coder of a parse routine cannot write the routine so that all
+ ** of the memory is allocated at once, then they must also write
+ ** a special destroy routine for this element (to ensure no
+ ** memory leakage).
+ **
+ ** Coders of parsing routines must also provide corresponding
+ ** copy and inquire routines (see miCopy.c and miInquire.c).
+ **/
+
+#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
+#define CAT(a,b) a##b
+#else
+#define CAT(a,b) a/**/b
+#endif
+
+#define OC_PARSER_FUNC_HEADER(suffix) \
+ ddpex2rtn CAT(parse,suffix)(pPEXOC, ppExecuteOC)\
+ ddElementInfo *pPEXOC; /* PEX format */ \
+ miGenericElementPtr *ppExecuteOC; /* internal format */
+
+#define OC_PARSER_RETURN(ANSWER) \
+ return(Success);
+
+#define PARSER_PTR(PTR) \
+ ddPointer PTR = (ddPointer)(pPEXOC + 1)
+
+#define LEN_WO_HEADER(OCtype) (pPEXOC->length * sizeof(CARD32) - sizeof(OCtype))
+
+#define GET_DD_STORAGE(DD_ST, TYPE, SIZE) \
+ if (*ppExecuteOC == 0) { \
+ *ppExecuteOC = \
+ (miGenericElementPtr) xalloc((unsigned long)((SIZE) \
+ + sizeof(miGenericElementStr)));\
+ if (!(*ppExecuteOC)) return (BadAlloc); \
+ } \
+ (DD_ST) = (TYPE *)((*ppExecuteOC)+1);
+
+#define GET_MORE_STORAGE(DD_ST, TYPE, SIZE) \
+ if ((SIZE) > 0) { \
+ (DD_ST) = (TYPE *)xalloc((unsigned long)(SIZE)); \
+ if (!(DD_ST)) err = BadAlloc; } \
+ else DD_ST = 0;
+
+
+extern void freeTrimCurves();
+extern void freeKnots();
+
+
+/*
+ Returns number of bytes required to store the indicated data
+ */
+int
+CountFacetOptData(ptr, colourType, numFacets, facetMask)
+ddPointer ptr;
+CARD16 colourType;
+CARD32 numFacets;
+CARD16 facetMask;
+{
+ ASSURE(facetMask <= 3);
+
+ switch (facetMask) {
+ case PEXGAColour | PEXGANormal : {
+
+ switch (colourType) {
+
+ case PEXIndexedColour:
+ return(numFacets * sizeof(ddIndexNormal));
+
+ case PEXRgbFloatColour :
+ return(numFacets * sizeof(ddRgbFloatNormal));
+
+ case PEXCieFloatColour :
+ return(numFacets * sizeof(ddCieNormal));
+
+ case PEXHsvFloatColour :
+ return(numFacets * sizeof(ddHsvNormal));
+
+ case PEXHlsFloatColour :
+ return(numFacets * sizeof(ddHlsNormal));
+
+ case PEXRgb8Colour :
+ return(numFacets * sizeof(ddRgb8Normal));
+
+ case PEXRgb16Colour :
+ return(numFacets * sizeof(ddRgb16Normal));
+ default:
+ return(0);
+ }
+ break; }
+
+ case PEXGANormal :
+
+ return(numFacets * sizeof(ddVector3D));
+
+ case PEXGAColour : {
+
+ switch (colourType) {
+
+ case PEXIndexedColour:
+ return(numFacets * sizeof(ddIndexedColour));
+ /* force lword alignment for any adjacent pointers */
+
+ case PEXRgbFloatColour :
+ return(numFacets * sizeof(ddRgbFloatColour));
+
+ case PEXCieFloatColour :
+ return(numFacets * sizeof(ddCieColour));
+
+ case PEXHsvFloatColour :
+ return(numFacets * sizeof(ddHsvColour));
+
+ case PEXHlsFloatColour :
+ return(numFacets * sizeof(ddHlsColour));
+
+ case PEXRgb8Colour :
+ return(numFacets * sizeof(ddRgb8Colour));
+
+ case PEXRgb16Colour :
+ return(numFacets * sizeof(ddRgb16Colour));
+
+ default:
+ return(0);
+ }
+ break; }
+
+ case 0x0000 :
+ return(0);
+ default:
+ return(0);
+ }
+
+}
+
+
+/*
+ Parses facet data into already allocated memory (pFacetData)
+*/
+void
+ParseFacetOptData(ptr, colourType, numFacets, facetMask, pFacetList, pFacetData,rptr)
+ddPointer ptr;
+CARD16 colourType;
+CARD32 numFacets;
+CARD16 facetMask;
+listofddFacet *pFacetList;
+ddPointer pFacetData;
+ddPointer *rptr;
+{
+ ASSURE(facetMask <= 3);
+
+ switch (facetMask) {
+ case PEXGAColour | PEXGANormal : {
+
+ pFacetList->numFacets = numFacets;
+
+ switch (colourType) {
+
+ case PEXIndexedColour: {
+ pFacetList->type = DD_FACET_INDEX_NORM;
+ pFacetList->facets.pFacetIndexN
+ = (ddIndexNormal *)pFacetData;
+ pFacetList->maxData = numFacets * sizeof(ddIndexNormal);
+ EXTRACT_STRUCT( numFacets, ddIndexNormal,
+ pFacetList->facets.pFacetIndexN, ptr);
+
+ break; }
+
+ case PEXRgbFloatColour : {
+ pFacetList->type = DD_FACET_RGBFLOAT_NORM;
+ pFacetList->facets.pFacetRgbFloatN
+ = (ddRgbFloatNormal *)pFacetData;
+ pFacetList->maxData = numFacets * sizeof(ddRgbFloatNormal);
+ EXTRACT_STRUCT( numFacets, ddRgbFloatNormal,
+ pFacetList->facets.pFacetRgbFloatN, ptr);
+ break; }
+
+ case PEXCieFloatColour : {
+ pFacetList->type = DD_FACET_CIE_NORM;
+ pFacetList->facets.pFacetCieN = (ddCieNormal *)pFacetData;
+ pFacetList->maxData = numFacets * sizeof(ddCieNormal);
+ EXTRACT_STRUCT( numFacets, ddCieNormal,
+ pFacetList->facets.pFacetCieN, ptr);
+ break; }
+
+ case PEXHsvFloatColour : {
+ pFacetList->type = DD_FACET_HSV_NORM;
+ pFacetList->facets.pFacetHsvN = (ddHsvNormal *)pFacetData;
+ pFacetList->maxData = numFacets * sizeof(ddHsvNormal);
+ EXTRACT_STRUCT( numFacets, ddHsvNormal,
+ pFacetList->facets.pFacetHsvN, ptr);
+ break; }
+
+ case PEXHlsFloatColour : {
+ pFacetList->type = DD_FACET_HLS_NORM;
+ pFacetList->facets.pFacetHlsN = (ddHlsNormal *)pFacetData;
+ pFacetList->maxData = numFacets * sizeof(ddHlsNormal);
+ EXTRACT_STRUCT( numFacets, ddHlsNormal,
+ pFacetList->facets.pFacetHlsN, ptr);
+ break; }
+
+ case PEXRgb8Colour : {
+ pFacetList->type = DD_FACET_RGB8_NORM;
+ pFacetList->facets.pFacetRgb8N = (ddRgb8Normal *)pFacetData;
+ pFacetList->maxData = numFacets * sizeof(ddRgb8Normal);
+ EXTRACT_STRUCT( numFacets, ddRgb8Normal,
+ pFacetList->facets.pFacetRgb8N, ptr);
+ break; }
+
+ case PEXRgb16Colour : {
+ pFacetList->type = DD_FACET_RGB16_NORM;
+ pFacetList->facets.pFacetRgb16N
+ = (ddRgb16Normal *)pFacetData;
+ pFacetList->maxData = numFacets * sizeof(ddRgb16Normal);
+ EXTRACT_STRUCT( numFacets, ddRgb16Normal,
+ pFacetList->facets.pFacetRgb16N, ptr);
+ break; }
+
+ }
+ break; }
+
+ case PEXGANormal : {
+
+ pFacetList->type = DD_FACET_NORM;
+ pFacetList->numFacets = numFacets;
+ pFacetList->facets.pFacetN = (ddVector3D *)pFacetData;
+ pFacetList->maxData = numFacets * sizeof(ddVector3D);
+ EXTRACT_STRUCT( numFacets, ddVector3D, pFacetList->facets.pFacetN,
+ ptr);
+ break; }
+
+ case PEXGAColour : {
+
+ pFacetList->numFacets = numFacets;
+
+ switch (colourType) {
+
+ case PEXIndexedColour: {
+ pFacetList->type = DD_FACET_INDEX;
+ pFacetList->facets.pFacetIndex =
+ (ddIndexedColour *)pFacetData;
+ pFacetList->maxData = numFacets * sizeof(ddIndexedColour);
+ EXTRACT_STRUCT( numFacets, ddIndexedColour,
+ pFacetList->facets.pFacetIndex, ptr);
+
+ break; }
+
+ case PEXRgbFloatColour : {
+ pFacetList->type = DD_FACET_RGBFLOAT;
+ pFacetList->facets.pFacetRgbFloat =
+ (ddRgbFloatColour *)pFacetData;
+ pFacetList->maxData = numFacets * sizeof(ddRgbFloatColour);
+ EXTRACT_STRUCT( numFacets, ddRgbFloatColour,
+ pFacetList->facets.pFacetRgbFloat, ptr);
+ break; }
+
+ case PEXCieFloatColour : {
+ pFacetList->type = DD_FACET_CIE;
+ pFacetList->facets.pFacetCie = (ddCieColour *)pFacetData;
+ pFacetList->maxData = numFacets * sizeof(ddCieColour);
+ EXTRACT_STRUCT( numFacets, ddCieColour,
+ pFacetList->facets.pFacetCie, ptr);
+ break; }
+
+ case PEXHsvFloatColour : {
+ pFacetList->type = DD_FACET_HSV;
+ pFacetList->facets.pFacetHsv = (ddHsvColour *)pFacetData;
+ pFacetList->maxData = numFacets * sizeof(ddHsvColour);
+ EXTRACT_STRUCT( numFacets, ddHsvColour,
+ pFacetList->facets.pFacetHsv, ptr);
+ break; }
+
+ case PEXHlsFloatColour : {
+ pFacetList->type = DD_FACET_HLS;
+ pFacetList->facets.pFacetHls = (ddHlsColour *)pFacetData;
+ pFacetList->maxData = numFacets * sizeof(ddHlsColour);
+ EXTRACT_STRUCT( numFacets, ddHlsColour,
+ pFacetList->facets.pFacetHls, ptr);
+ break; }
+
+ case PEXRgb8Colour : {
+ pFacetList->type = DD_FACET_RGB8;
+ pFacetList->facets.pFacetRgb8 = (ddRgb8Colour *)pFacetData;
+ EXTRACT_STRUCT( numFacets, ddRgb8Colour,
+ pFacetList->facets.pFacetRgb8, ptr);
+ pFacetList->maxData = numFacets * sizeof(ddRgb8Colour);
+ break; }
+
+ case PEXRgb16Colour : {
+ pFacetList->type = DD_FACET_RGB16;
+ pFacetList->facets.pFacetRgb16 = (ddRgb16Colour *)pFacetData;
+ pFacetList->maxData = numFacets * sizeof(ddRgb16Colour);
+ EXTRACT_STRUCT( numFacets, ddRgb16Colour,
+ pFacetList->facets.pFacetRgb16, ptr);
+ break; }
+
+ }
+ break; }
+
+ case 0x0000 : {
+ /* neither Colour nor Normal specified */
+ pFacetList->numFacets = 0;
+ pFacetList->type = DD_FACET_NONE;
+ pFacetList->facets.pNoFacet = NULL;
+ pFacetList->maxData = 0;
+ break; }
+ }
+
+ *rptr = ptr;
+}
+
+
+/*
+ Returns number of bytes needed to store this vertex data
+ */
+int
+CountVertexData(ptr, colourType, numVertices, vertexMask)
+ddPointer ptr;
+INT16 colourType;
+CARD32 numVertices;
+CARD16 vertexMask;
+{
+ ASSURE(vertexMask <= 7);
+
+ switch (vertexMask) {
+
+ case PEXGAColour | PEXGANormal | PEXGAEdges : {
+
+ switch (colourType) {
+ case PEXIndexedColour:
+ return(numVertices * sizeof(ddIndexNormEdgePoint));
+
+ case PEXRgbFloatColour :
+ return(numVertices * sizeof(ddRgbFloatNormEdgePoint));
+
+ case PEXCieFloatColour :
+ return(numVertices *sizeof(ddCieNormEdgePoint));
+
+ case PEXHsvFloatColour :
+ return(numVertices *sizeof(ddHsvNormEdgePoint));
+
+ case PEXHlsFloatColour :
+ return(numVertices *sizeof(ddHlsNormEdgePoint));
+
+ case PEXRgb8Colour :
+ return(numVertices*sizeof(ddRgb8NormEdgePoint));
+
+ case PEXRgb16Colour :
+ return(numVertices * sizeof(ddRgb16NormEdgePoint));
+
+ default:
+ return(0);
+ }
+ break; }
+
+ case PEXGAColour | PEXGANormal : {
+
+ switch (colourType) {
+ case PEXIndexedColour:
+ return(numVertices* sizeof(ddIndexNormalPoint));
+
+ case PEXRgbFloatColour :
+ return(numVertices * sizeof(ddRgbFloatNormalPoint));
+
+ case PEXCieFloatColour :
+ return(numVertices * sizeof(ddCieNormalPoint));
+
+ case PEXHsvFloatColour :
+ return(numVertices * sizeof(ddHsvNormalPoint));
+
+ case PEXHlsFloatColour :
+ return(numVertices * sizeof(ddHlsNormalPoint));
+
+ case PEXRgb8Colour :
+ return(numVertices * sizeof(ddRgb8NormalPoint));
+
+ case PEXRgb16Colour :
+ return(numVertices * sizeof(ddRgb16NormalPoint));
+
+ default:
+ return(0);
+ }
+ break; }
+
+ case PEXGANormal | PEXGAEdges:
+ return(numVertices * sizeof(ddNormEdgePoint));
+
+ case PEXGANormal :
+ return(numVertices * sizeof(ddNormalPoint));
+
+ case PEXGAEdges :
+ return(numVertices * sizeof(ddEdgePoint));
+
+ case PEXGAColour | PEXGAEdges : {
+
+ switch (colourType) {
+ case PEXIndexedColour:
+ return(numVertices * sizeof(ddIndexEdgePoint));
+
+ case PEXRgbFloatColour :
+ return(numVertices*sizeof(ddRgbFloatEdgePoint));
+
+ case PEXCieFloatColour :
+ return(numVertices * sizeof(ddCieEdgePoint));
+
+ case PEXHsvFloatColour :
+ return(numVertices * sizeof(ddHsvEdgePoint));
+
+ case PEXHlsFloatColour :
+ return(numVertices * sizeof(ddHlsEdgePoint));
+
+ case PEXRgb8Colour :
+ return(numVertices * sizeof(ddRgb8EdgePoint));
+
+ case PEXRgb16Colour :
+ return(numVertices * sizeof(ddRgb16EdgePoint));
+
+ default:
+ return(0);
+ }
+ break; }
+
+ case PEXGAColour: {
+
+ switch (colourType) {
+ case PEXIndexedColour:
+ return(numVertices * sizeof(ddIndexPoint));
+
+ case PEXRgbFloatColour :
+ return(numVertices * sizeof(ddRgbFloatPoint));
+
+ case PEXCieFloatColour :
+ return(numVertices * sizeof(ddCiePoint));
+
+ case PEXHsvFloatColour :
+ return(numVertices * sizeof(ddHsvPoint));
+
+ case PEXHlsFloatColour :
+ return(numVertices * sizeof(ddHlsPoint));
+
+ case PEXRgb8Colour :
+ return(numVertices * sizeof(ddRgb8Point));
+
+ case PEXRgb16Colour :
+ return(numVertices * sizeof(ddRgb16Point));
+
+ default:
+ return(0);
+ }
+ break; }
+
+ case 0x0000 :
+ /* none of Colour nor Normal nor Edge specified */
+ return(numVertices * sizeof(ddCoord3D));
+
+ default:
+ return(0);
+ }
+
+}
+
+
+/*
+ Parses vertex data into already allocated memory (pVertexData)
+*/
+void
+ParseVertexData(ptr, colourType, numVertices, vertexMask, pVertexList, pVertexData, rtype, rptr)
+ddPointer ptr;
+INT16 colourType;
+CARD32 numVertices;
+CARD16 vertexMask;
+listofddPoint *pVertexList; /* out */
+ddPointer *pVertexData; /* out */
+ddPointType *rtype; /* out */
+ddPointer *rptr; /* out */
+{
+ ASSURE(vertexMask <= 7);
+
+ pVertexList->numPoints = numVertices;
+ switch (vertexMask) {
+
+ case PEXGAColour | PEXGANormal | PEXGAEdges : {
+
+ switch (colourType) {
+ case PEXIndexedColour: {
+ *rtype = DD_INDEX_NORM_EDGE_POINT;
+ pVertexList->pts.pIndexNEpt
+ = (ddIndexNormEdgePoint *)(*pVertexData);
+ (*pVertexData) += numVertices* sizeof(ddIndexNormEdgePoint);
+ EXTRACT_STRUCT( numVertices, ddIndexNormEdgePoint,
+ pVertexList->pts.pIndexNEpt, ptr);
+ pVertexList->maxData = numVertices * sizeof(ddIndexNormEdgePoint);
+ break; }
+
+ case PEXRgbFloatColour : {
+ *rtype = DD_RGBFLOAT_NORM_EDGE_POINT;
+ pVertexList->pts.pRgbFloatNEpt
+ = (ddRgbFloatNormEdgePoint *)(*pVertexData);
+ (*pVertexData) += numVertices * sizeof(ddRgbFloatNormEdgePoint);
+ EXTRACT_STRUCT( numVertices, ddRgbFloatNormEdgePoint,
+ pVertexList->pts.pRgbFloatNEpt, ptr);
+ pVertexList->maxData = numVertices * sizeof(ddRgbFloatNormEdgePoint);
+ break; }
+
+ case PEXCieFloatColour : {
+ *rtype = DD_CIE_NORM_EDGE_POINT;
+ pVertexList->pts.pCieNEpt = (ddCieNormEdgePoint *)(*pVertexData);
+ (*pVertexData) += numVertices *sizeof(ddCieNormEdgePoint);
+ EXTRACT_STRUCT( numVertices, ddCieNormEdgePoint,
+ pVertexList->pts.pCieNEpt, ptr);
+ pVertexList->maxData = numVertices *sizeof(ddCieNormEdgePoint);
+ break; }
+
+ case PEXHsvFloatColour : {
+ *rtype = DD_HSV_NORM_EDGE_POINT;
+ pVertexList->pts.pHsvNEpt = (ddHsvNormEdgePoint *)(*pVertexData);
+ (*pVertexData) += numVertices *sizeof(ddHsvNormEdgePoint);
+ EXTRACT_STRUCT( numVertices, ddHsvNormEdgePoint,
+ pVertexList->pts.pHsvNEpt, ptr);
+ pVertexList->maxData = numVertices *sizeof(ddHsvNormEdgePoint);
+ break; }
+
+ case PEXHlsFloatColour : {
+ *rtype = DD_HLS_NORM_EDGE_POINT;
+ pVertexList->pts.pHlsNEpt = (ddHlsNormEdgePoint *)(*pVertexData);
+ (*pVertexData) += numVertices *sizeof(ddHlsNormEdgePoint);
+ EXTRACT_STRUCT( numVertices, ddHlsNormEdgePoint,
+ pVertexList->pts.pHlsNEpt, ptr);
+ pVertexList->maxData = numVertices *sizeof(ddHlsNormEdgePoint);
+ break; }
+
+ case PEXRgb8Colour : {
+ *rtype = DD_RGB8_NORM_EDGE_POINT;
+ pVertexList->pts.pRgb8NEpt
+ = (ddRgb8NormEdgePoint *)(*pVertexData);
+ (*pVertexData) += numVertices*sizeof(ddRgb8NormEdgePoint);
+ EXTRACT_STRUCT( numVertices, ddRgb8NormEdgePoint,
+ pVertexList->pts.pRgb8NEpt, ptr);
+ pVertexList->maxData = numVertices*sizeof(ddRgb8NormEdgePoint);
+ break; }
+
+ case PEXRgb16Colour : {
+ *rtype = DD_RGB16_NORM_EDGE_POINT;
+ pVertexList->pts.pRgb16NEpt
+ = (ddRgb16NormEdgePoint *)(*pVertexData);
+ (*pVertexData) += numVertices* sizeof(ddRgb16NormEdgePoint);
+ EXTRACT_STRUCT( numVertices, ddRgb16NormEdgePoint,
+ pVertexList->pts.pRgb16NEpt, ptr);
+ pVertexList->maxData = numVertices * sizeof(ddRgb16NormEdgePoint);
+ break; }
+
+ }
+ break; }
+
+ case PEXGAColour | PEXGANormal : {
+
+ switch (colourType) {
+ case PEXIndexedColour: {
+ *rtype = DD_INDEX_NORM_POINT;
+ pVertexList->pts.pIndexNpt
+ = (ddIndexNormalPoint *)(*pVertexData);
+ (*pVertexData) += numVertices* sizeof(ddIndexNormalPoint);
+ EXTRACT_STRUCT( numVertices, ddIndexNormalPoint,
+ pVertexList->pts.pIndexNpt, ptr);
+ pVertexList->maxData = numVertices* sizeof(ddIndexNormalPoint);
+ break; }
+
+ case PEXRgbFloatColour : {
+ *rtype = DD_RGBFLOAT_NORM_POINT;
+ pVertexList->pts.pRgbFloatNpt
+ = (ddRgbFloatNormalPoint *)(*pVertexData);
+ (*pVertexData) += numVertices * sizeof(ddRgbFloatNormalPoint);
+ EXTRACT_STRUCT( numVertices, ddRgbFloatNormalPoint,
+ pVertexList->pts.pRgbFloatNpt, ptr);
+ pVertexList->maxData = numVertices * sizeof(ddRgbFloatNormalPoint);
+ break; }
+
+ case PEXCieFloatColour : {
+ *rtype = DD_CIE_NORM_POINT;
+ pVertexList->pts.pCieNpt = (ddCieNormalPoint *)(*pVertexData);
+ (*pVertexData) += numVertices * sizeof(ddCieNormalPoint);
+ EXTRACT_STRUCT( numVertices, ddCieNormalPoint,
+ pVertexList->pts.pCieNpt, ptr);
+ pVertexList->maxData = numVertices * sizeof(ddCieNormalPoint);
+ break; }
+
+ case PEXHsvFloatColour : {
+ *rtype = DD_HSV_NORM_POINT;
+ pVertexList->pts.pHsvNpt = (ddHsvNormalPoint *)(*pVertexData);
+ (*pVertexData) += numVertices * sizeof(ddHsvNormalPoint);
+ EXTRACT_STRUCT( numVertices, ddHsvNormalPoint,
+ pVertexList->pts.pHsvNpt, ptr);
+ pVertexList->maxData = numVertices * sizeof(ddHsvNormalPoint);
+ break; }
+
+ case PEXHlsFloatColour : {
+ *rtype = DD_HLS_NORM_POINT;
+ pVertexList->pts.pHlsNpt = (ddHlsNormalPoint *)(*pVertexData);
+ (*pVertexData) += numVertices * sizeof(ddHlsNormalPoint);
+ EXTRACT_STRUCT( numVertices, ddHlsNormalPoint,
+ pVertexList->pts.pHlsNpt, ptr);
+ pVertexList->maxData = numVertices * sizeof(ddHlsNormalPoint);
+ break; }
+
+ case PEXRgb8Colour : {
+ *rtype = DD_RGB8_NORM_POINT;
+ pVertexList->pts.pRgb8Npt = (ddRgb8NormalPoint *)(*pVertexData);
+ (*pVertexData) += numVertices * sizeof(ddRgb8NormalPoint);
+ EXTRACT_STRUCT( numVertices, ddRgb8NormalPoint,
+ pVertexList->pts.pRgb8Npt, ptr);
+ pVertexList->maxData = numVertices * sizeof(ddRgb8NormalPoint);
+ break; }
+
+ case PEXRgb16Colour : {
+ *rtype = DD_RGB16_NORM_POINT;
+ pVertexList->pts.pRgb16Npt = (ddRgb16NormalPoint *)(*pVertexData);
+ (*pVertexData) += numVertices* sizeof(ddRgb16NormalPoint);
+ EXTRACT_STRUCT( numVertices, ddRgb16NormalPoint,
+ pVertexList->pts.pRgb16Npt, ptr);
+ pVertexList->maxData = numVertices* sizeof(ddRgb16NormalPoint);
+ break; }
+
+ }
+ break; }
+
+ case PEXGANormal | PEXGAEdges: {
+ *rtype = DD_NORM_EDGE_POINT;
+ pVertexList->pts.pNEpt = (ddNormEdgePoint *)(*pVertexData);
+ (*pVertexData) += numVertices * sizeof(ddNormEdgePoint);
+ EXTRACT_STRUCT( numVertices, ddNormEdgePoint,
+ pVertexList->pts.pNEpt, ptr);
+ pVertexList->maxData = numVertices * sizeof(ddNormEdgePoint);
+ break; }
+
+ case PEXGANormal : {
+ *rtype = DD_NORM_POINT;
+ pVertexList->pts.pNpt = (ddNormalPoint *)(*pVertexData);
+ (*pVertexData) += numVertices * sizeof(ddNormalPoint);
+ EXTRACT_STRUCT( numVertices, ddNormalPoint,
+ pVertexList->pts.pNpt, ptr);
+ pVertexList->maxData = numVertices * sizeof(ddNormalPoint);
+ break; }
+
+ case PEXGAEdges : {
+ *rtype = DD_EDGE_POINT;
+ pVertexList->pts.pEpt = (ddEdgePoint *)(*pVertexData);
+ (*pVertexData) += numVertices * sizeof(ddEdgePoint);
+ EXTRACT_STRUCT( numVertices, ddEdgePoint,
+ pVertexList->pts.pEpt, ptr);
+ pVertexList->maxData = numVertices * sizeof(ddEdgePoint);
+ break; }
+
+ case PEXGAColour | PEXGAEdges : {
+
+ switch (colourType) {
+ case PEXIndexedColour: {
+ *rtype = DD_INDEX_EDGE_POINT;
+ pVertexList->pts.pIndexEpt = (ddIndexEdgePoint *)(*pVertexData);
+ (*pVertexData) += numVertices * sizeof(ddIndexEdgePoint);
+ EXTRACT_STRUCT( numVertices, ddIndexEdgePoint,
+ pVertexList->pts.pIndexEpt, ptr);
+ pVertexList->maxData = numVertices * sizeof(ddIndexEdgePoint);
+ break; }
+
+ case PEXRgbFloatColour : {
+ *rtype = DD_RGBFLOAT_EDGE_POINT;
+ pVertexList->pts.pRgbFloatEpt = (ddRgbFloatEdgePoint *)(*pVertexData);
+ (*pVertexData) += numVertices*sizeof(ddRgbFloatEdgePoint);
+ EXTRACT_STRUCT( numVertices, ddRgbFloatEdgePoint,
+ pVertexList->pts.pRgbFloatEpt, ptr);
+ pVertexList->maxData = numVertices*sizeof(ddRgbFloatEdgePoint);
+ break; }
+
+ case PEXCieFloatColour : {
+ *rtype = DD_CIE_EDGE_POINT;
+ pVertexList->pts.pCieEpt = (ddCieEdgePoint *)(*pVertexData);
+ (*pVertexData) += numVertices * sizeof(ddCieEdgePoint);
+ EXTRACT_STRUCT( numVertices, ddCieEdgePoint,
+ pVertexList->pts.pCieEpt, ptr);
+ pVertexList->maxData = numVertices * sizeof(ddCieEdgePoint);
+ break; }
+
+ case PEXHsvFloatColour : {
+ *rtype = DD_HSV_EDGE_POINT;
+ pVertexList->pts.pHsvEpt = (ddHsvEdgePoint *)(*pVertexData);
+ (*pVertexData) += numVertices * sizeof(ddHsvEdgePoint);
+ EXTRACT_STRUCT( numVertices, ddHsvEdgePoint,
+ pVertexList->pts.pHsvEpt, ptr);
+ pVertexList->maxData = numVertices * sizeof(ddHsvEdgePoint);
+ break; }
+
+ case PEXHlsFloatColour : {
+ *rtype = DD_HLS_EDGE_POINT;
+ pVertexList->pts.pHlsEpt = (ddHlsEdgePoint *)(*pVertexData);
+ (*pVertexData) += numVertices * sizeof(ddHlsEdgePoint);
+ EXTRACT_STRUCT( numVertices, ddHlsEdgePoint,
+ pVertexList->pts.pHlsEpt, ptr);
+ pVertexList->maxData = numVertices * sizeof(ddHlsEdgePoint);
+ break; }
+
+ case PEXRgb8Colour : {
+ *rtype = DD_RGB8_EDGE_POINT;
+ pVertexList->pts.pRgb8Ept = (ddRgb8EdgePoint *)(*pVertexData);
+ (*pVertexData) += numVertices * sizeof(ddRgb8EdgePoint);
+ EXTRACT_STRUCT( numVertices, ddRgb8EdgePoint,
+ pVertexList->pts.pRgb8Ept, ptr);
+ pVertexList->maxData = numVertices * sizeof(ddRgb8EdgePoint);
+ break; }
+
+ case PEXRgb16Colour : {
+ *rtype = DD_RGB16_EDGE_POINT;
+ pVertexList->pts.pRgb16Ept = (ddRgb16EdgePoint *)(*pVertexData);
+ (*pVertexData) += numVertices * sizeof(ddRgb16EdgePoint);
+ EXTRACT_STRUCT( numVertices, ddRgb16EdgePoint,
+ pVertexList->pts.pRgb16Ept, ptr);
+ pVertexList->maxData = numVertices * sizeof(ddRgb16EdgePoint);
+ break; }
+
+ }
+ break; }
+
+ case PEXGAColour: {
+
+ switch (colourType) {
+ case PEXIndexedColour: {
+ *rtype = DD_INDEX_POINT;
+ pVertexList->pts.pIndexpt = (ddIndexPoint *)(*pVertexData);
+ (*pVertexData) += numVertices * sizeof(ddIndexPoint);
+ EXTRACT_STRUCT( numVertices, ddIndexPoint,
+ pVertexList->pts.pIndexpt, ptr);
+ pVertexList->maxData = numVertices * sizeof(ddIndexPoint);
+ break; }
+
+ case PEXRgbFloatColour : {
+ *rtype = DD_RGBFLOAT_POINT;
+ pVertexList->pts.pRgbFloatpt = (ddRgbFloatPoint *)(*pVertexData);
+ (*pVertexData) += numVertices * sizeof(ddRgbFloatPoint);
+ EXTRACT_STRUCT( numVertices, ddRgbFloatPoint,
+ pVertexList->pts.pRgbFloatpt, ptr);
+ pVertexList->maxData = numVertices * sizeof(ddRgbFloatPoint);
+ break; }
+
+ case PEXCieFloatColour : {
+ *rtype = DD_CIE_POINT;
+ pVertexList->pts.pCiept = (ddCiePoint *)(*pVertexData);
+ (*pVertexData) += numVertices * sizeof(ddCiePoint);
+ EXTRACT_STRUCT( numVertices, ddCiePoint,
+ pVertexList->pts.pCiept, ptr);
+ pVertexList->maxData = numVertices * sizeof(ddCiePoint);
+ break; }
+
+ case PEXHsvFloatColour : {
+ *rtype = DD_HSV_POINT;
+ pVertexList->pts.pHsvpt = (ddHsvPoint *)(*pVertexData);
+ (*pVertexData) += numVertices * sizeof(ddHsvPoint);
+ EXTRACT_STRUCT( numVertices, ddHsvPoint,
+ pVertexList->pts.pHsvpt, ptr);
+ pVertexList->maxData = numVertices * sizeof(ddHsvPoint);
+ break; }
+
+ case PEXHlsFloatColour : {
+ *rtype = DD_HLS_POINT;
+ pVertexList->pts.pHlspt = (ddHlsPoint *)(*pVertexData);
+ (*pVertexData) += numVertices * sizeof(ddHlsPoint);
+ EXTRACT_STRUCT( numVertices, ddHlsPoint,
+ pVertexList->pts.pHlspt, ptr);
+ pVertexList->maxData = numVertices * sizeof(ddHlsPoint);
+ break; }
+
+ case PEXRgb8Colour : {
+ *rtype = DD_RGB8_POINT;
+ pVertexList->pts.pRgb8pt = (ddRgb8Point *)(*pVertexData);
+ (*pVertexData) += numVertices * sizeof(ddRgb8Point);
+ EXTRACT_STRUCT( numVertices, ddRgb8Point,
+ pVertexList->pts.pRgb8pt, ptr);
+ pVertexList->maxData = numVertices * sizeof(ddRgb8Point);
+ break; }
+
+ case PEXRgb16Colour : {
+ *rtype = DD_RGB16_POINT;
+ pVertexList->pts.pRgb16pt = (ddRgb16Point *)(*pVertexData);
+ (*pVertexData) += numVertices * sizeof(ddRgb16Point);
+ EXTRACT_STRUCT( numVertices, ddRgb16Point,
+ pVertexList->pts.pRgb16pt, ptr);
+ pVertexList->maxData = numVertices * sizeof(ddRgb16Point);
+ break; }
+
+ }
+ break; }
+
+ case 0x0000 : {
+ /* none of Colour nor Normal nor Edge specified */
+ *rtype = DD_3D_POINT;
+ pVertexList->pts.p3Dpt = (ddCoord3D *)(*pVertexData);
+ (*pVertexData) += numVertices * sizeof(ddCoord3D);
+ EXTRACT_STRUCT( numVertices, ddCoord3D, pVertexList->pts.p3Dpt, ptr);
+ pVertexList->maxData = numVertices * sizeof(ddCoord3D);
+ break; }
+ }
+
+ *rptr = ptr;
+
+}
+
+
+OC_PARSER_FUNC_HEADER(ColourOC)
+{
+ CARD16 colourType;
+ miColourStruct *ddColour;
+ PARSER_PTR(ptr);
+
+ EXTRACT_CARD16(colourType,ptr);/*temp since we haven't alloc'd ddColour yet*/
+ SKIP_PADDING(ptr,2);
+ switch (colourType) {
+
+ case PEXIndexedColour: {
+ GET_DD_STORAGE( ddColour, miColourStruct,
+ (sizeof(miColourStruct) + sizeof(ddIndexedColour)))
+ ddColour->colour.pIndex = (ddIndexedColour *)(ddColour+1);
+ EXTRACT_STRUCT(1, ddIndexedColour, ddColour->colour.pIndex, ptr);
+ break; }
+
+ case PEXRgbFloatColour : {
+ GET_DD_STORAGE( ddColour, miColourStruct,
+ (sizeof(miColourStruct) + sizeof(ddRgbFloatColour)));
+ ddColour->colour.pRgbFloat = (ddRgbFloatColour *)(ddColour+1);
+ EXTRACT_STRUCT(1, ddRgbFloatColour, ddColour->colour.pRgbFloat, ptr);
+ break; }
+
+ case PEXCieFloatColour : {
+ GET_DD_STORAGE( ddColour, miColourStruct,
+ (sizeof(miColourStruct) + sizeof(ddCieColour)));
+ ddColour->colour.pCie = (ddCieColour *)(ddColour+1);
+ EXTRACT_STRUCT(1, ddCieColour, ddColour->colour.pCie, ptr);
+ break; }
+
+ case PEXHsvFloatColour : {
+ GET_DD_STORAGE( ddColour, miColourStruct,
+ (sizeof(miColourStruct) + sizeof(ddHsvColour)));
+ ddColour->colour.pHsv = (ddHsvColour *)(ddColour+1);
+ EXTRACT_STRUCT(1, ddHsvColour, ddColour->colour.pHsv, ptr);
+ break; }
+
+ case PEXHlsFloatColour : {
+ GET_DD_STORAGE( ddColour, miColourStruct,
+ (sizeof(miColourStruct) + sizeof(ddHlsColour)));
+ ddColour->colour.pHls = (ddHlsColour *)(ddColour+1);
+ EXTRACT_STRUCT(1, ddHlsColour, ddColour->colour.pHls, ptr);
+ break; }
+
+ case PEXRgb8Colour : {
+ GET_DD_STORAGE( ddColour, miColourStruct,
+ (sizeof(miColourStruct) + sizeof(ddRgb8Colour)));
+ ddColour->colour.pRgb8 = (ddRgb8Colour *)(ddColour+1);
+ EXTRACT_STRUCT(1, ddRgb8Colour, ddColour->colour.pRgb8, ptr);
+ break; }
+
+ case PEXRgb16Colour : {
+ GET_DD_STORAGE( ddColour, miColourStruct,
+ (sizeof(miColourStruct) + sizeof(ddRgb16Colour)));
+ ddColour->colour.pRgb16 = (ddRgb16Colour *)(ddColour+1);
+ EXTRACT_STRUCT(1, ddRgb16Colour, ddColour->colour.pRgb16, ptr);
+ break; }
+ }
+
+ ddColour->colourType = colourType;
+ OC_PARSER_RETURN(ddColour);
+}
+
+OC_PARSER_FUNC_HEADER(ColourIndexOC)
+{
+ miColourStruct *ddColour;
+ PARSER_PTR(ptr);
+
+ GET_DD_STORAGE( ddColour, miColourStruct,
+ (sizeof(miColourStruct) + sizeof(ddIndexedColour)));
+ ddColour->colour.pIndex = (ddIndexedColour *)(ddColour+1);
+ ddColour->colourType = PEXIndexedColour;
+ EXTRACT_CARD16(ddColour->colour.pIndex->index,ptr);
+
+ OC_PARSER_RETURN(ddColour);
+}
+
+OC_PARSER_FUNC_HEADER(LightState)
+{
+ miLightStateStruct *ddLightState;
+ PARSER_PTR(ptr);
+ ddSHORT enable_count, disable_count;
+ ddSHORT en_count, dis_count;
+ int listSize = 0;
+
+ EXTRACT_CARD16(enable_count, ptr);
+ EXTRACT_CARD16(disable_count, ptr);
+
+ /* must modify counts so they are always even to guarantee
+ * pointer alignment at 4 byte boundary
+ */
+ en_count = MAKE_EVEN(enable_count);
+ dis_count = MAKE_EVEN(disable_count); /* probably unnecessary */
+ listSize = puCountList(DD_INDEX, en_count) + puCountList(DD_INDEX,dis_count);
+ GET_DD_STORAGE( ddLightState,miLightStateStruct,
+ sizeof(miLightStateStruct) + listSize);
+
+ ddLightState->enableList = (listofObj *)(ddLightState + 1);
+ puInitList(ddLightState->enableList, DD_INDEX, en_count);
+ puAddToList(ptr, enable_count, ddLightState->enableList);
+
+ SKIP_PADDING(ptr, (en_count * sizeof(CARD16)) );
+
+ listSize = puCountList(DD_INDEX, en_count);
+ ddLightState->disableList =
+ (listofObj *)(((ddPointer)(ddLightState->enableList)) + listSize);
+ puInitList(ddLightState->disableList, DD_INDEX, dis_count);
+ puAddToList(ptr, disable_count, ddLightState->disableList);
+
+ OC_PARSER_RETURN(ddLightState);
+}
+
+OC_PARSER_FUNC_HEADER(SetMCVolume)
+{
+ miMCVolume_Struct *ddMCV;
+ PARSER_PTR(ptr);
+
+ ddHalfSpace ddHS;
+ INT16 i, count, operator;
+ int listSize = 0;
+ ddFLOAT length;
+
+ EXTRACT_INT16(operator, ptr);
+ EXTRACT_INT16(count, ptr);
+ listSize = puCountList(DD_HALF_SPACE, count);
+ GET_DD_STORAGE( ddMCV, miMCVolume_Struct,
+ sizeof(miMCVolume_Struct) + listSize);
+
+ ddMCV->operator = operator;
+ ddMCV->halfspaces = (listofObj *)(ddMCV + 1);
+ puInitList(ddMCV->halfspaces, DD_HALF_SPACE, count);
+
+ for (i = 0; i < count; i++){
+ EXTRACT_COORD3D(&ddHS.orig_point, ptr);
+ ddHS.orig_point.w = 0.0; /* JSH */
+ ddHS.point.w = 0.5; /* ? */
+ EXTRACT_VECTOR3D(&ddHS.orig_vector, ptr);
+
+ puAddToList(&ddHS, 1, ddMCV->halfspaces);
+ }
+
+ OC_PARSER_RETURN(ddMCV);
+}
+
+OC_PARSER_FUNC_HEADER(SetMCVolume2D)
+{
+
+ miMCVolume_Struct *ddMCV;
+ PARSER_PTR(ptr);
+ ddHalfSpace ddHS;
+ INT16 i, count, operator;
+ int listSize = 0;
+ ddFLOAT length;
+
+ EXTRACT_INT16(operator, ptr);
+ EXTRACT_INT16(count, ptr);
+ listSize = puCountList(DD_HALF_SPACE, count);
+ GET_DD_STORAGE( ddMCV, miMCVolume_Struct,
+ sizeof(miMCVolume_Struct) + listSize);
+
+ ddMCV->operator = operator;
+ ddMCV->halfspaces = (listofObj *)(ddMCV + 1);
+ puInitList(ddMCV->halfspaces, DD_HALF_SPACE, count);
+
+ for (i = 0; i < count; i++){
+ EXTRACT_COORD2D(&ddHS.orig_point, ptr);
+ ddHS.orig_point.z = 0.0;
+ ddHS.orig_point.w = 0.0;
+ ddHS.point.w = 0.5; /* ? */
+ EXTRACT_VECTOR2D(&ddHS.orig_vector, ptr);
+ ddHS.orig_vector.z = 0.0;
+
+ puAddToList(&ddHS, 1, ddMCV->halfspaces);
+ }
+
+ OC_PARSER_RETURN(ddMCV);
+}
+
+OC_PARSER_FUNC_HEADER(Marker)
+{
+ miMarkerStruct *ddMarker;
+ listofddPoint *ddPoint;
+ ddULONG numPoints;
+ PARSER_PTR(ptr);
+
+ numPoints = LEN_WO_HEADER(pexMarker) / sizeof(pexCoord3D);
+ GET_DD_STORAGE( ddMarker, miListHeader, (sizeof(miListHeader) +
+ sizeof(listofddPoint) + numPoints * sizeof(ddCoord3D)));
+ ddPoint = (listofddPoint *)(ddMarker+1);
+ ddMarker->type = DD_3D_POINT;
+ ddMarker->flags = 0;
+ ddMarker->numLists = 1;
+ ddMarker->maxLists = 1;
+ ddMarker->ddList = ddPoint;
+ ddPoint->numPoints = numPoints;
+ ddPoint->pts.p3Dpt = (ddCoord3D *)(ddPoint + 1);
+ EXTRACT_LISTOF_COORD3D(ddPoint->numPoints,ddPoint->pts.p3Dpt,ptr);
+
+ OC_PARSER_RETURN(ddMarker);
+}
+
+
+OC_PARSER_FUNC_HEADER(Marker2D)
+{
+ miMarkerStruct *ddMarker;
+ listofddPoint *ddPoint;
+ ddULONG numPoints;
+ PARSER_PTR(ptr);
+
+ numPoints = LEN_WO_HEADER(pexMarker2D) / sizeof(pexCoord2D);
+ GET_DD_STORAGE( ddMarker, miListHeader, (sizeof(miListHeader) +
+ sizeof(listofddPoint) + numPoints * sizeof(ddCoord2D)));
+ ddPoint = (listofddPoint *)(ddMarker+1);
+ ddMarker->type = DD_2D_POINT;
+ ddMarker->flags = 0;
+ ddMarker->numLists = 1;
+ ddMarker->maxLists = 1;
+ ddMarker->ddList = ddPoint;
+ ddPoint->numPoints = numPoints;
+ ddPoint->pts.p2Dpt = (ddCoord2D *)(ddPoint + 1);
+ EXTRACT_LISTOF_COORD2D(ddPoint->numPoints,ddPoint->pts.p2Dpt,ptr);
+
+ OC_PARSER_RETURN(ddMarker);
+}
+
+
+OC_PARSER_FUNC_HEADER(Text)
+{
+ miTextStruct *ddText;
+ PARSER_PTR(ptr);
+
+ GET_DD_STORAGE( ddText, miTextStruct, sizeof(miTextStruct)
+ + 3 * sizeof(ddCoord3D)
+ + ((pexText *)pPEXOC)->head.length * sizeof(CARD32)
+ - sizeof(pexText));
+ /* this also allocates any trailing pads, but so
+ much the better */
+ ddText->pOrigin = (ddCoord3D *)(ddText + 1);
+ ddText->pDirections = (ddText->pOrigin) + 1;
+ EXTRACT_LISTOF_COORD3D(1, ddText->pOrigin, ptr);
+ EXTRACT_LISTOF_COORD3D(2, ddText->pDirections, ptr);
+ EXTRACT_CARD16(ddText->numEncodings, ptr);
+ SKIP_PADDING(ptr, 2);
+ ddText->pText = (pexMonoEncoding *)((ddText->pDirections) + 2);
+ memcpy( (char *)(ddText->pText), (char *)ptr,
+ (int)( sizeof(CARD32) * ((pexText *)pPEXOC)->head.length
+ - sizeof(pexText)));
+
+ OC_PARSER_RETURN(ddText);
+}
+
+
+OC_PARSER_FUNC_HEADER(Text2D)
+{
+ miText2DStruct *ddText;
+ PARSER_PTR(ptr);
+
+ GET_DD_STORAGE( ddText, miText2DStruct, sizeof(miText2DStruct)
+ + sizeof(ddCoord2D)
+ + ((pexText2D *)pPEXOC)->head.length * sizeof(CARD32)
+ - sizeof(pexText2D));
+ /* this also allocates any trailing pads, but so
+ much the better */
+ ddText->pOrigin = (ddCoord2D *)(ddText + 1);
+ EXTRACT_LISTOF_COORD2D(1, ddText->pOrigin, ptr);
+ EXTRACT_CARD16(ddText->numEncodings, ptr);
+ SKIP_PADDING(ptr, 2);
+ ddText->pText = (pexMonoEncoding *)((ddText->pOrigin) + 1);
+ memcpy( (char *)(ddText->pText), (char *)ptr,
+ (int)( sizeof(CARD32) * ((pexText2D *)pPEXOC)->head.length
+ - sizeof(pexText2D)));
+
+ OC_PARSER_RETURN(ddText);
+}
+
+
+OC_PARSER_FUNC_HEADER(AnnotationText)
+{
+ miAnnoTextStruct *ddText;
+ PARSER_PTR(ptr);
+
+ GET_DD_STORAGE( ddText, miAnnoTextStruct, sizeof(miAnnoTextStruct)
+ + 2 * sizeof(ddCoord3D)
+ + ((pexAnnotationText *)pPEXOC)->head.length
+ * sizeof(CARD32)
+ - sizeof(pexAnnotationText));
+ /* this also allocates any trailing pads, but so
+ much the better */
+ ddText->pOrigin = (ddCoord3D *)(ddText + 1);
+ ddText->pOffset = (ddText->pOrigin) + 1;
+ EXTRACT_LISTOF_COORD3D(1, ddText->pOrigin, ptr);
+ EXTRACT_LISTOF_COORD3D(1, ddText->pOffset, ptr);
+ EXTRACT_CARD16(ddText->numEncodings, ptr);
+ SKIP_PADDING(ptr, 2);
+ ddText->pText = (pexMonoEncoding *)((ddText->pOffset) + 1);
+ memcpy( (char *)(ddText->pText), (char *)ptr,
+ (int)( sizeof(CARD32) * ((pexAnnotationText *)pPEXOC)->head.length
+ - sizeof(pexAnnotationText)));
+
+ OC_PARSER_RETURN(ddText);
+
+}
+
+
+
+
+OC_PARSER_FUNC_HEADER(AnnotationText2D)
+{
+ miAnnoText2DStruct *ddText;
+ PARSER_PTR(ptr);
+
+ GET_DD_STORAGE( ddText, miAnnoText2DStruct, sizeof(miAnnoText2DStruct)
+ + 2 * sizeof(ddCoord2D)
+ + ((pexAnnotationText2D *)pPEXOC)->head.length
+ * sizeof(CARD32)
+ - sizeof(pexAnnotationText2D));
+ /* this also allocates any trailing pads, but so
+ much the better */
+ ddText->pOrigin = (ddCoord2D *)(ddText + 1);
+ ddText->pOffset = (ddText->pOrigin) + 1;
+ EXTRACT_LISTOF_COORD2D(1, ddText->pOrigin, ptr);
+ EXTRACT_LISTOF_COORD2D(1, ddText->pOffset, ptr);
+ EXTRACT_CARD16(ddText->numEncodings, ptr);
+ SKIP_PADDING(ptr, 2);
+ ddText->pText = (pexMonoEncoding *)((ddText->pOffset) + 1);
+ memcpy( (char *)(ddText->pText), (char *)ptr,
+ (int)( sizeof(CARD32) * ((pexAnnotationText2D *)pPEXOC)->head.length
+ - sizeof(pexAnnotationText2D)));
+
+ OC_PARSER_RETURN(ddText);
+
+}
+
+
+OC_PARSER_FUNC_HEADER(Polyline2D)
+{
+ miPolylineStruct *ddPoly;
+ listofddPoint *ddPoint;
+ ddULONG numPoints;
+ PARSER_PTR(ptr);
+
+ numPoints = LEN_WO_HEADER(pexPolyline2D) / sizeof(pexCoord2D);
+ GET_DD_STORAGE( ddPoly, miListHeader, sizeof(miListHeader) +
+ sizeof(listofddPoint) + numPoints * sizeof(ddCoord2D));
+ ddPoint = (listofddPoint *)(ddPoly+1);
+ ddPoly->type = DD_2D_POINT;
+ ddPoly->flags = 0;
+ ddPoly->numLists = 1;
+ ddPoly->maxLists = 1;
+ ddPoly->ddList = ddPoint;
+ ddPoint->numPoints = numPoints;
+ ddPoint->maxData = numPoints * sizeof(ddCoord2D);
+ ddPoint->pts.p2Dpt = (ddCoord2D *)(ddPoint + 1);
+ EXTRACT_LISTOF_COORD2D(ddPoint->numPoints,ddPoint->pts.p2Dpt,ptr);
+
+ OC_PARSER_RETURN(ddPoly);
+
+}
+
+
+
+OC_PARSER_FUNC_HEADER(Polyline)
+{
+ miPolylineStruct *ddPoly;
+ listofddPoint *ddPoint;
+ ddULONG numPoints;
+ PARSER_PTR(ptr);
+
+ numPoints = LEN_WO_HEADER(pexPolyline) / sizeof(pexCoord3D);
+ GET_DD_STORAGE( ddPoly, miListHeader, sizeof(miListHeader) +
+ sizeof(listofddPoint) + numPoints * sizeof(ddCoord3D));
+ ddPoint = (listofddPoint *)(ddPoly+1);
+ ddPoly->type = DD_3D_POINT;
+ ddPoly->flags = 0;
+ ddPoly->numLists = 1;
+ ddPoly->maxLists = 1;
+ ddPoly->ddList = ddPoint;
+ ddPoint->numPoints = numPoints;
+ ddPoint->maxData = numPoints * sizeof(ddCoord3D);
+ ddPoint->pts.p3Dpt = (ddCoord3D *)(ddPoint + 1);
+ EXTRACT_LISTOF_COORD3D(ddPoint->numPoints,ddPoint->pts.p3Dpt,ptr);
+
+ OC_PARSER_RETURN(ddPoly);
+
+}
+
+
+OC_PARSER_FUNC_HEADER(PolylineSet)
+{
+ miPolylineStruct *ddPoly;
+ listofddPoint *ddPoint;
+ pexPolylineSet *pPoly = (pexPolylineSet *)pPEXOC;
+ PARSER_PTR(ptr);
+ ddULONG i;
+ CARD32 numPoints;
+ int vertexSize = 0;
+ ddPointer vertexPtr = 0;
+ ddPointer rptr = 0;
+ ddpex2rtn err = Success;
+
+ ptr = (ddPointer)(pPoly+1);
+ for (i=0; i<pPoly->numLists; i++) {
+ EXTRACT_CARD32(numPoints, ptr);
+ ptr += CountVertexData( ptr, pPoly->colourType, numPoints,
+ pPoly->vertexAttribs); }
+
+ vertexSize = ptr - (ddPointer)(pPoly+1) -
+ pPoly->numLists * sizeof(CARD32);
+
+ GET_DD_STORAGE( ddPoly, miListHeader,
+ (sizeof(miListHeader) + vertexSize
+ + pPoly->numLists * sizeof(listofddPoint)));
+ ddPoly->numLists = (ddULONG)(pPoly->numLists);
+ ddPoly->maxLists = ddPoly->numLists;
+ ddPoly->flags = 0;
+ ddPoly->ddList = (listofddPoint *)(ddPoly+1);
+ ptr = (ddPointer)(pPoly+1);
+
+ for (i=0, ddPoint = (listofddPoint *)(ddPoly+1),
+ vertexPtr = (ddPointer)(ddPoly->ddList + ddPoly->numLists);
+ i<ddPoly->numLists;
+ i++, ddPoint++) {
+
+ EXTRACT_CARD32(numPoints, ptr);
+ ParseVertexData( ptr, pPoly->colourType, numPoints,
+ pPoly->vertexAttribs, ddPoint,
+ &vertexPtr, &(ddPoly->type), &rptr);
+ ptr = rptr;
+ }
+
+ OC_PARSER_RETURN(ddPoly);
+
+}
+
+
+OC_PARSER_FUNC_HEADER(NurbCurve)
+{
+ miNurbStruct *ddNurb;
+ pexNurbCurve *pNurb = (pexNurbCurve *)pPEXOC;
+ ddUSHORT pointSize = 0;
+ PARSER_PTR(ptr);
+
+
+ pointSize = ((pNurb->coordType == PEXRational)
+ ? sizeof(ddCoord4D) : sizeof(ddCoord3D));
+ GET_DD_STORAGE( ddNurb, miNurbStruct, (sizeof(miNurbStruct)
+ + sizeof(listofddPoint) + pNurb->numKnots * sizeof(ddFLOAT)
+ + pNurb->numPoints) * pointSize);
+ ddNurb->pKnots = (ddFLOAT *)(ddNurb+1);
+ ddNurb->points.ddList = (listofddPoint *)(ddNurb->pKnots + pNurb->numKnots);
+ EXTRACT_CARD16(ddNurb->order, ptr);
+ SKIP_PADDING(ptr,2); /* place holder for type */
+ EXTRACT_FLOAT(ddNurb->uMin, ptr);
+ EXTRACT_FLOAT(ddNurb->uMax, ptr);
+ EXTRACT_CARD32(ddNurb->numKnots, ptr);
+ EXTRACT_CARD32(ddNurb->points.ddList->numPoints, ptr);
+
+ EXTRACT_STRUCT(ddNurb->numKnots, PEXFLOAT, ddNurb->pKnots, ptr);
+ if (pNurb->coordType == PEXRational) {
+ ddNurb->points.type = DDPT_4D;
+ ddNurb->points.ddList->pts.p4Dpt =
+ (ddCoord4D *)((ddNurb->points.ddList)+1);
+ EXTRACT_STRUCT( ddNurb->points.ddList->numPoints, ddCoord4D,
+ ddNurb->points.ddList->pts.p4Dpt, ptr);
+ } else {
+ ddNurb->points.type = DDPT_3D;
+ ddNurb->points.ddList->pts.p3Dpt =
+ (ddCoord3D *)((ddNurb->points.ddList)+1);
+ EXTRACT_STRUCT( ddNurb->points.ddList->numPoints, ddCoord3D,
+ ddNurb->points.ddList->pts.p3Dpt, ptr);
+ }
+
+ ddNurb->points.numLists = 1;
+ ddNurb->points.maxLists = 1;
+ ddNurb->points.flags = 0;
+
+ OC_PARSER_RETURN(ddNurb);
+}
+
+
+OC_PARSER_FUNC_HEADER(FillArea2D)
+{
+ miFillAreaStruct *ddFill;
+ ddULONG numPoints;
+ PARSER_PTR(ptr);
+
+ numPoints = LEN_WO_HEADER(pexFillArea2D) / sizeof(pexCoord2D);
+ GET_DD_STORAGE( ddFill, miFillAreaStruct, (sizeof(miFillAreaStruct) +
+ sizeof(listofddFacet) + sizeof(listofddPoint)
+ + numPoints * sizeof(ddCoord2D)));
+ ddFill->pFacets = (listofddFacet *)(ddFill+1);
+ ddFill->points.ddList = (listofddPoint *)((ddFill->pFacets)+1);
+ EXTRACT_CARD16(ddFill->shape, ptr);
+ EXTRACT_CARD8(ddFill->ignoreEdges, ptr);
+ SKIP_PADDING(ptr, 1);
+
+ ddFill->pFacets->type = DD_FACET_NONE;
+ ddFill->pFacets->numFacets = 0;
+ ddFill->pFacets->facets.pNoFacet = NULL;
+ ddFill->contourHint = 0;
+
+ ddFill->points.type = DD_2D_POINT;
+ ddFill->points.flags = 0;
+ ddFill->points.numLists = 1;
+ ddFill->points.maxLists = 1;
+ ddFill->points.ddList->numPoints = numPoints;
+ ddFill->points.ddList->pts.p2Dpt = (ddCoord2D *)((ddFill->points.ddList) +1);
+ EXTRACT_LISTOF_COORD2D( ddFill->points.ddList->numPoints,
+ ddFill->points.ddList->pts.p2Dpt,ptr);
+
+ OC_PARSER_RETURN(ddFill);
+}
+
+
+
+
+OC_PARSER_FUNC_HEADER(FillArea)
+{
+ miFillAreaStruct *ddFill;
+ ddULONG numPoints;
+ PARSER_PTR(ptr);
+
+ numPoints = LEN_WO_HEADER(pexFillArea) / sizeof(pexCoord3D);
+ GET_DD_STORAGE( ddFill, miFillAreaStruct, (sizeof(miFillAreaStruct) +
+ sizeof(listofddFacet) + sizeof(listofddPoint)
+ + numPoints * sizeof(ddCoord3D)));
+ ddFill->pFacets = (listofddFacet *)(ddFill+1);
+ ddFill->points.ddList = (listofddPoint *)((ddFill->pFacets)+1);
+ EXTRACT_CARD16(ddFill->shape, ptr);
+ EXTRACT_CARD8(ddFill->ignoreEdges, ptr);
+ SKIP_PADDING(ptr, 1);
+ ddFill->contourHint = 0;
+
+ ddFill->pFacets->type = DD_FACET_NONE;
+ ddFill->pFacets->numFacets = 0;
+ ddFill->pFacets->facets.pNoFacet = NULL;
+
+ ddFill->points.type = DD_3D_POINT;
+ ddFill->points.flags = 0;
+ ddFill->points.numLists = 1;
+ ddFill->points.maxLists = 1;
+ ddFill->points.ddList->numPoints = numPoints;
+ ddFill->points.ddList->pts.p3Dpt = (ddCoord3D *)((ddFill->points.ddList) +1);
+ EXTRACT_LISTOF_COORD3D( ddFill->points.ddList->numPoints,
+ ddFill->points.ddList->pts.p3Dpt,ptr);
+
+ OC_PARSER_RETURN(ddFill);
+}
+
+
+OC_PARSER_FUNC_HEADER(ExtFillArea)
+{
+ miFillAreaStruct *ddFill;
+ pexExtFillArea *pFill = (pexExtFillArea *)pPEXOC;
+ PARSER_PTR(ptr);
+ ddPointer rptr = 0;
+ ddPointer facetPtr = 0;
+ int facetSize = 0;
+ ddPointer vertexPtr = 0;
+ int vertexSize = 0;
+ ddpex2rtn err = Success;
+ CARD32 totalVertices;
+
+ ptr = (ddPointer)(pFill+1);
+ facetSize = CountFacetOptData( ptr, (CARD16)(pFill->colourType),
+ (CARD32)1, pFill->facetAttribs);
+
+ ptr += facetSize; /* this works because dd types == protocol types */
+ EXTRACT_CARD32(totalVertices, ptr);
+ vertexSize = CountVertexData( ptr, pFill->colourType, totalVertices,
+ pFill->vertexAttribs);
+ GET_DD_STORAGE( ddFill, miFillAreaStruct,
+ (sizeof(miFillAreaStruct) + sizeof(listofddFacet)
+ + sizeof(listofddPoint) + facetSize + vertexSize));
+ ddFill->pFacets = (listofddFacet *)(ddFill+1);
+ ddFill->points.ddList = (listofddPoint *)((ddFill->pFacets)+1);
+ ddFill->shape = pFill->shape;
+ ddFill->ignoreEdges = pFill->ignoreEdges;
+ ddFill->contourHint = 0;
+ ddFill->points.numLists = 1;
+ ddFill->points.maxLists = 1;
+ ddFill->points.flags = 0;
+
+ ptr = (ddPointer)(pFill+1);
+ facetPtr = (ddPointer)(ddFill->points.ddList + 1);
+ ParseFacetOptData( ptr, (CARD16)(pFill->colourType), (CARD32)1,
+ pFill->facetAttribs, ddFill->pFacets,
+ facetPtr, &rptr);
+ ptr = rptr;
+
+ vertexPtr = facetPtr + facetSize;
+ ParseVertexData( ptr, pFill->colourType, totalVertices,
+ pFill->vertexAttribs, ddFill->points.ddList,
+ &vertexPtr, &(ddFill->points.type), &rptr);
+ ptr = rptr;
+
+ OC_PARSER_RETURN(ddFill);
+}
+
+
+OC_PARSER_FUNC_HEADER(FillAreaSet2D)
+{
+ miFillAreaStruct *ddFill;
+ PARSER_PTR(ptr);
+ ddULONG i;
+ int listSize = 0, numPoints = 0;
+ listofddPoint *ddPoint;
+ ddPointer ddPtr;
+ pexFillAreaSet2D *pFill = (pexFillAreaSet2D *)pPEXOC;
+
+ ptr = (ddPointer)(pFill+1);
+ for (i=0; i<pFill->numLists; i++) {
+ EXTRACT_CARD32( numPoints, ptr);
+ listSize += numPoints * sizeof(ddCoord2D);
+ ptr += numPoints * sizeof(ddCoord2D); }
+
+ GET_DD_STORAGE( ddFill, miFillAreaStruct,
+ (sizeof(miFillAreaStruct) + sizeof(listofddFacet)
+ + (pFill->numLists * sizeof(listofddPoint))
+ + listSize ));
+ ddFill->pFacets = (listofddFacet *)(ddFill+1);
+ ddFill->points.ddList = (listofddPoint *)((ddFill->pFacets)+1);
+ ddFill->shape = pFill->shape;
+ ddFill->ignoreEdges = pFill->ignoreEdges;
+ ddFill->contourHint = pFill->contourHint;
+
+ ddFill->pFacets->type = DD_FACET_NONE;
+ ddFill->pFacets->numFacets = 0;
+ ddFill->pFacets->facets.pNoFacet = NULL;
+
+ ddFill->points.type = DD_2D_POINT;
+ ddFill->points.flags = 0;
+ ddFill->points.numLists = pFill->numLists;
+ ddFill->points.maxLists = ddFill->points.numLists;
+
+ ptr = (ddPointer)(pFill+1);
+ for (i=0, ddPoint = ddFill->points.ddList,
+ ddPtr = (ddPointer)(ddFill->points.ddList + ddFill->points.numLists);
+ i<ddFill->points.numLists;
+ i++, ddPoint++) {
+ EXTRACT_CARD32( ddPoint->numPoints, ptr);
+ ddPoint->pts.p2Dpt = (ddCoord2D *)ddPtr;
+ ddPtr += ddPoint->numPoints * sizeof(ddCoord2D);
+ EXTRACT_STRUCT( ddPoint->numPoints, ddCoord2D,
+ ddPoint->pts.p2Dpt, ptr);
+ }
+
+ OC_PARSER_RETURN(ddFill);
+}
+
+
+OC_PARSER_FUNC_HEADER(FillAreaSet)
+{
+ miFillAreaStruct *ddFill;
+ PARSER_PTR(ptr);
+ ddULONG i;
+ int listSize = 0, numPoints = 0;
+ listofddPoint *ddPoint;
+ ddPointer ddPtr;
+ pexFillAreaSet *pFill = (pexFillAreaSet *)pPEXOC;
+
+ ptr = (ddPointer)(pFill+1);
+ for (i=0; i<pFill->numLists; i++) {
+ EXTRACT_CARD32( numPoints, ptr);
+ listSize += numPoints * sizeof(ddCoord3D);
+ ptr += numPoints * sizeof(ddCoord3D); }
+
+ GET_DD_STORAGE( ddFill, miFillAreaStruct,
+ (sizeof(miFillAreaStruct)
+ + sizeof(listofddFacet)
+ + (pFill->numLists * sizeof(listofddPoint))
+ + listSize ));
+ ddFill->pFacets = (listofddFacet *)(ddFill+1);
+ ddFill->points.ddList = (listofddPoint *)((ddFill->pFacets)+1);
+ ddFill->shape = pFill->shape;
+ ddFill->ignoreEdges = pFill->ignoreEdges;
+ ddFill->contourHint = pFill->contourHint;
+
+ ddFill->pFacets->type = DD_FACET_NONE;
+ ddFill->pFacets->numFacets = 0;
+ ddFill->pFacets->facets.pNoFacet = NULL;
+
+ ddFill->points.type = DD_3D_POINT;
+ ddFill->points.flags = 0;
+ ddFill->points.numLists = pFill->numLists;
+ ddFill->points.maxLists = ddFill->points.numLists;
+
+ ptr = (ddPointer)(pFill+1);
+ for (i=0, ddPoint = ddFill->points.ddList,
+ ddPtr = (ddPointer)(ddFill->points.ddList + ddFill->points.numLists);
+ i<ddFill->points.numLists;
+ i++, ddPoint++) {
+ EXTRACT_CARD32( ddPoint->numPoints, ptr);
+ ddPoint->pts.p3Dpt = (ddCoord3D *)ddPtr;
+ ddPtr += ddPoint->numPoints * sizeof(ddCoord3D);
+ EXTRACT_STRUCT( ddPoint->numPoints, ddCoord3D,
+ ddPoint->pts.p3Dpt, ptr);
+ }
+
+ OC_PARSER_RETURN(ddFill);
+}
+
+
+OC_PARSER_FUNC_HEADER(ExtFillAreaSet)
+{
+ miFillAreaStruct *ddFill;
+ PARSER_PTR(ptr);
+ ddULONG i;
+ ddULONG numPoints;
+ listofddPoint *ddPoint;
+ pexExtFillAreaSet *pFill = (pexExtFillAreaSet *)(pPEXOC);
+ ddPointer rptr = 0;
+ ddPointer facetPtr = 0;
+ int facetSize = 0;
+ ddPointer vertexPtr = 0;
+ int vertexSize = 0;
+ ddpex2rtn err = Success;
+
+ ptr = (ddPointer)(pFill+1);
+ facetSize = CountFacetOptData( ptr, (CARD16)(pFill->colourType),
+ (CARD32)1, pFill->facetAttribs);
+ ptr += facetSize; /* this works because dd types == protocol types */
+ for (i=0; i<pFill->numLists; i++) {
+ EXTRACT_CARD32( numPoints, ptr);
+ ptr += CountVertexData( ptr, pFill->colourType, numPoints,
+ pFill->vertexAttribs); }
+
+ vertexSize = ptr - (ddPointer)(pFill+1) - facetSize;
+ GET_DD_STORAGE( ddFill, miFillAreaStruct,
+ (sizeof(miFillAreaStruct) + sizeof(listofddFacet)
+ + (pFill->numLists * sizeof(listofddPoint)
+ + facetSize + vertexSize)));
+ ddFill->pFacets = (listofddFacet *)(ddFill+1);
+ ddFill->points.ddList = (listofddPoint *)((ddFill->pFacets)+1);
+ ddFill->shape = pFill->shape;
+ ddFill->ignoreEdges = pFill->ignoreEdges;
+ ddFill->contourHint = pFill->contourHint;
+ ddFill->points.numLists = (ddULONG)(pFill->numLists);
+ ddFill->points.maxLists = ddFill->points.numLists;
+ ddFill->points.flags = 0;
+ ptr = (ddPointer)(pFill+1);
+
+ facetPtr = (ddPointer)(ddFill->points.ddList + pFill->numLists);
+ ParseFacetOptData( ptr, (CARD16)(pFill->colourType), (CARD32)1,
+ pFill->facetAttribs, ddFill->pFacets,
+ facetPtr, &rptr);
+ ptr = rptr;
+
+ vertexPtr = facetPtr + facetSize;
+ for (i=0, ddPoint = ddFill->points.ddList;
+ i<ddFill->points.numLists;
+ i++, ddPoint++) {
+
+ EXTRACT_CARD32( numPoints, ptr);
+ ParseVertexData( ptr, pFill->colourType, numPoints,
+ pFill->vertexAttribs, ddPoint, &vertexPtr,
+ &(ddFill->points.type), &rptr);
+ ptr = rptr;
+ }
+
+
+ OC_PARSER_RETURN(ddFill);
+}
+
+
+OC_PARSER_FUNC_HEADER(SOFAS)
+{
+ miSOFASStruct *ddFill;
+ pexSOFAS *pFill = (pexSOFAS *)pPEXOC;
+ PARSER_PTR(ptr);
+ CARD16 i,j,k;
+ miConnListList *pCLL;
+ miConnList *pCList;
+ ddPointer rptr = 0;
+ ddpex2rtn err = Success;
+ ddPointer facetPtr = 0;
+ ddPointer vertexPtr = 0;
+ int facetSize = 0;
+ int vertexSize = 0;
+ int edgeSize = 0;
+ extern void destroySOFAS();
+
+ facetSize = CountFacetOptData( ptr, (CARD16)(pFill->colourType),
+ (CARD32)(pFill->numFAS),
+ pFill->FAS_Attributes);
+ vertexSize = CountVertexData( ptr, pFill->colourType,
+ (CARD32)(pFill->numVertices),
+ pFill->vertexAttributes);
+ if (pFill->edgeAttributes) {
+ edgeSize = pFill->numEdges * sizeof(ddUCHAR);
+ edgeSize += ((4 - (edgeSize & 3)) & 3); /* force lword alignment for
+ connects data */
+ }
+
+ GET_DD_STORAGE( ddFill, miSOFASStruct, (sizeof(miSOFASStruct) +
+ sizeof(listofddPoint) +
+ facetSize + vertexSize + edgeSize +
+ (pFill->numFAS * sizeof(miConnListList))));
+ EXTRACT_CARD16(ddFill->shape, ptr);
+ ddFill->contourHint = pFill->contourHint;
+ ddFill->contourCountsFlag = pFill->contourCountsFlag;
+ ddFill->numFAS = pFill->numFAS;
+ ddFill->numEdges = pFill->numEdges;
+ ptr = (ddPointer)(pFill+1);
+ ddFill->points.ddList = (listofddPoint *)(ddFill + 1);
+ ddFill->points.flags = 0;
+ ddFill->points.numLists = 1;
+ ddFill->points.maxLists = 1;
+
+ facetPtr = (ddPointer)(ddFill->points.ddList + 1);
+ ParseFacetOptData( ptr, (CARD16)(pFill->colourType),
+ (CARD32)(pFill->numFAS),
+ pFill->FAS_Attributes, &(ddFill->pFacets),
+ facetPtr, &rptr);
+ ptr = rptr;
+
+ vertexPtr = facetPtr + facetSize;
+ ParseVertexData( ptr, pFill->colourType, (CARD32)(pFill->numVertices),
+ pFill->vertexAttributes, ddFill->points.ddList,
+ &vertexPtr, &(ddFill->points.type), &rptr);
+ ptr = rptr;
+
+ ddFill->edgeAttribs = pFill->edgeAttributes;
+ if (pFill->edgeAttributes){
+ ddFill->edgeData = (ddUCHAR *)vertexPtr;
+ EXTRACT_STRUCT(ddFill->numEdges, ddUCHAR, ddFill->edgeData, ptr);
+ SKIP_PADDING( ptr, ((4 - (ddFill->numEdges & 3)) & 3) );
+ }
+ else { ddFill->edgeData = 0; }
+ vertexPtr += edgeSize;
+
+ ddFill->connects.numListLists = pFill->numFAS;
+ ddFill->connects.data = (miConnListList *)vertexPtr;
+ ddFill->connects.maxData = ddFill->numFAS * sizeof(miConnListList);
+ for (i=0, pCLL = ddFill->connects.data; i<pFill->numFAS; i++, pCLL++) {
+ EXTRACT_CARD16(pCLL->numLists,ptr);
+ GET_MORE_STORAGE( pCLL->pConnLists, miConnList,
+ pCLL->numLists * sizeof(miConnList));
+ if (err) {
+ destroySOFAS(ddFill);
+ return(BadAlloc);
+ }
+ pCLL->maxData = pCLL->numLists * sizeof(miConnList);
+ for (j=0, pCList=pCLL->pConnLists; j<pCLL->numLists; j++, pCList++) {
+ EXTRACT_CARD16(pCList->numLists,ptr);
+ GET_MORE_STORAGE( pCList->pConnects, ddUSHORT,
+ pCList->numLists * sizeof(ddUSHORT));
+ if (err) {
+ destroySOFAS(ddFill);
+ return(BadAlloc);
+ }
+ EXTRACT_STRUCT(pCList->numLists, ddUSHORT, pCList->pConnects, ptr);
+ pCList->maxData = pCList->numLists * sizeof(ddUSHORT);
+ }
+ }
+
+ OC_PARSER_RETURN(ddFill);
+}
+
+
+
+OC_PARSER_FUNC_HEADER(TriangleStrip)
+{
+ miTriangleStripStruct *ddTriangle;
+ PARSER_PTR(ptr);
+ pexTriangleStrip *pTriangle = (pexTriangleStrip *)pPEXOC;
+ ddPointer rptr = 0;
+ ddpex2rtn err = Success;
+ ddPointer facetPtr = 0;
+ int facetSize = 0;
+ ddPointer vertexPtr = 0;
+ int vertexSize = 0;
+
+ facetSize = CountFacetOptData( ptr, (CARD16)(pTriangle->colourType),
+ (CARD32)(pTriangle->numVertices - 2),
+ pTriangle->facetAttribs);
+ vertexSize = CountVertexData( ptr, pTriangle->colourType,
+ pTriangle->numVertices,
+ pTriangle->vertexAttribs);
+ GET_DD_STORAGE( ddTriangle, miTriangleStripStruct,
+ (sizeof(miTriangleStripStruct) + sizeof(listofddFacet)
+ + sizeof(listofddPoint) + facetSize + vertexSize));
+ ddTriangle->pFacets = (listofddFacet *)(ddTriangle+1);
+ ddTriangle->points.numLists = 1;
+ ddTriangle->points.maxLists = 1;
+ ddTriangle->points.ddList = (listofddPoint *)((ddTriangle->pFacets)+1);
+ ptr = (ddPointer)(pTriangle +1);
+
+ facetPtr = (ddPointer)(ddTriangle->points.ddList + 1);
+ ParseFacetOptData( ptr, (CARD16)(pTriangle->colourType),
+ (pTriangle->numVertices - 2),
+ pTriangle->facetAttribs, ddTriangle->pFacets,
+ facetPtr, &rptr);
+ ptr = rptr;
+
+ vertexPtr = facetPtr + facetSize;
+ ParseVertexData( ptr, pTriangle->colourType, pTriangle->numVertices,
+ pTriangle->vertexAttribs, ddTriangle->points.ddList,
+ &vertexPtr, &(ddTriangle->points.type), &rptr);
+ ptr = rptr;
+
+ OC_PARSER_RETURN(ddTriangle);
+}
+
+
+OC_PARSER_FUNC_HEADER(QuadrilateralMesh)
+{
+ miQuadMeshStruct *ddQuad;
+ PARSER_PTR(ptr);
+ pexQuadrilateralMesh *pQuad = (pexQuadrilateralMesh *)pPEXOC;
+ ddPointer rptr = 0;
+ ddpex2rtn err = Success;
+ ddPointer facetPtr = 0;
+ int facetSize = 0;
+ ddPointer vertexPtr = 0;
+ int vertexSize = 0;
+
+ facetSize = CountFacetOptData( ptr, (CARD16)(pQuad->colourType),
+ (CARD32)((pQuad->mPts-1)*(pQuad->nPts-1)),
+ pQuad->facetAttribs);
+ vertexSize = CountVertexData( ptr, pQuad->colourType,
+ (CARD32)(pQuad->mPts * pQuad->nPts),
+ pQuad->vertexAttribs);
+ GET_DD_STORAGE( ddQuad, miQuadMeshStruct,
+ (sizeof(miQuadMeshStruct) + facetSize + vertexSize
+ + sizeof(listofddFacet) + sizeof(listofddPoint)));
+ ddQuad->pFacets = (listofddFacet *)(ddQuad+1);
+ ddQuad->points.numLists = 1;
+ ddQuad->points.maxLists = 1;
+ ddQuad->points.ddList = (listofddPoint *)((ddQuad->pFacets)+1);
+ ddQuad->mPts = pQuad->mPts;
+ ddQuad->nPts = pQuad->nPts;
+ ddQuad->shape = (ddUSHORT)(pQuad->shape);
+ ptr = (ddPointer)(pQuad+1);
+
+ /** Now we should be at the head of the opt data **/
+ facetPtr = (ddPointer)(ddQuad->points.ddList + 1);
+ ParseFacetOptData( ptr, (CARD16)(pQuad->colourType),
+ (CARD32)((pQuad->mPts-1)*(pQuad->nPts-1)),
+ pQuad->facetAttribs, ddQuad->pFacets,
+ facetPtr, &rptr);
+ ptr = rptr;
+
+ vertexPtr = facetPtr + facetSize;
+ ParseVertexData( ptr, pQuad->colourType,
+ (CARD32)(pQuad->mPts*pQuad->nPts),
+ pQuad->vertexAttribs, ddQuad->points.ddList,
+ &vertexPtr, &(ddQuad->points.type), &rptr);
+ ptr = rptr;
+
+ OC_PARSER_RETURN(ddQuad);
+}
+
+
+OC_PARSER_FUNC_HEADER(NurbSurface)
+{
+ miNurbSurfaceStruct *ddNurb;
+ PARSER_PTR(ptr);
+ pexNurbSurface *pNurb = (pexNurbSurface *)pPEXOC;
+ ddULONG i, j;
+ listofTrimCurve *ddTrim;
+ ddTrimCurve *ddtc;
+ ddUSHORT type;
+ ddpex2rtn err = Success;
+
+ GET_DD_STORAGE(ddNurb, miNurbSurfaceStruct, (sizeof(miNurbSurfaceStruct)
+ + (pNurb->numUknots * pNurb->numVknots) * (sizeof(ddFLOAT))
+ + (sizeof(listofddPoint))
+ + pNurb->mPts * pNurb->nPts * sizeof(ddCoord4D)
+ + (sizeof(listofTrimCurve))
+ + pNurb->numLists * sizeof(ddTrimCurve)));
+
+ ddNurb->pUknots = (ddFLOAT *)(ddNurb+1);
+ ddNurb->pVknots = (ddFLOAT *)((ddNurb->pUknots) + pNurb->numUknots);
+ ddNurb->points.ddList =
+ (listofddPoint *)((ddNurb->pVknots) + pNurb->numVknots);
+ ddNurb->points.ddList->pts.ptr = (char *)(ddNurb->points.ddList + 1);
+ ddNurb->trimCurves =
+ (listofTrimCurve *)((ddNurb->points.ddList->pts.ptr)
+ + (pNurb->mPts * pNurb->nPts) * sizeof(ddCoord4D));
+
+ SKIP_PADDING(ptr, 2); /* place holder for type */
+ EXTRACT_CARD16(ddNurb->uOrder, ptr);
+ EXTRACT_CARD16(ddNurb->vOrder, ptr);
+ SKIP_PADDING(ptr, 2);
+ EXTRACT_CARD32(ddNurb->numUknots, ptr);
+ EXTRACT_CARD32(ddNurb->numVknots, ptr);
+ EXTRACT_CARD16(ddNurb->mPts, ptr);
+ EXTRACT_CARD16(ddNurb->nPts, ptr);
+ EXTRACT_CARD32(ddNurb->numTrimCurveLists, ptr); /* is pNurb->numLists */
+
+ EXTRACT_STRUCT(ddNurb->numUknots, PEXFLOAT, ddNurb->pUknots, ptr);
+ EXTRACT_STRUCT(ddNurb->numVknots, PEXFLOAT, ddNurb->pVknots, ptr);
+
+ ddNurb->points.numLists = 1;
+ ddNurb->points.maxLists = 1;
+ ddNurb->points.ddList->numPoints = ddNurb->mPts * ddNurb->nPts;
+ if (pNurb->type == PEXRational) {
+ ddNurb->points.type = DD_HOMOGENOUS_POINT;
+ EXTRACT_STRUCT( ddNurb->points.ddList->numPoints, ddCoord4D,
+ ddNurb->points.ddList->pts.p4Dpt, ptr);
+ } else {
+ ddNurb->points.type = DD_3D_POINT;
+ EXTRACT_STRUCT( ddNurb->points.ddList->numPoints, ddCoord3D,
+ ddNurb->points.ddList->pts.p3Dpt, ptr);
+ }
+
+ for ( i=0, ddTrim = ddNurb->trimCurves;
+ i<ddNurb->numTrimCurveLists;
+ i++, ddTrim++) {
+ EXTRACT_CARD32(ddTrim->count, ptr);
+ GET_MORE_STORAGE( ddTrim->pTC, ddTrimCurve,
+ ddTrim->count*sizeof(ddTrimCurve));
+ if (err) {
+ destroyNurbSurface(ddNurb);
+ return (BadAlloc);
+ }
+
+ for ( j=0, ddtc = ddTrim->pTC;
+ j < ddTrim->count;
+ j++, ddtc++) {
+ EXTRACT_CARD8(ddtc->visibility, ptr);
+ SKIP_PADDING(ptr, 1);
+ EXTRACT_CARD16(ddtc->order, ptr);
+ EXTRACT_CARD16(type, ptr);
+ EXTRACT_CARD16(ddtc->curveApprox.approxMethod, ptr);
+ EXTRACT_FLOAT(ddtc->curveApprox.tolerance, ptr);
+ EXTRACT_FLOAT(ddtc->uMin, ptr);
+ EXTRACT_FLOAT(ddtc->uMax, ptr);
+ EXTRACT_CARD32(ddtc->numKnots, ptr);
+ EXTRACT_CARD32(ddtc->points.numPoints, ptr);
+ GET_MORE_STORAGE( ddtc->pKnots, ddFLOAT,
+ sizeof(ddFLOAT) * ddtc->numKnots );
+ if (err) {
+ ddtc->points.pts.ptr = 0;
+ destroyNurbSurface(ddNurb);
+ return(BadAlloc);
+ }
+ EXTRACT_STRUCT( ddtc->numKnots, PEXFLOAT, ddtc->pKnots, ptr);
+ if (type == PEXRational) {
+ /* Note this only works because these points are never
+ transformed */
+ ddtc->pttype = DD_3D_POINT;
+ ddtc->points.pts.p3Dpt = 0;
+ GET_MORE_STORAGE( ddtc->points.pts.p3Dpt, ddCoord3D,
+ sizeof(ddCoord3D)*ddtc->points.numPoints);
+ EXTRACT_STRUCT( ddtc->points.numPoints, ddCoord3D,
+ ddtc->points.pts.p3Dpt, ptr);
+ } else {
+ ddtc->pttype = DD_2D_POINT;
+ ddtc->points.pts.p2Dpt = 0;
+ GET_MORE_STORAGE( ddtc->points.pts.p2Dpt, ddCoord2D,
+ sizeof(ddCoord2D)*ddtc->points.numPoints );
+ EXTRACT_STRUCT( ddtc->points.numPoints, ddCoord2D,
+ ddtc->points.pts.p2Dpt, ptr);
+ }
+ if (err) {
+ destroyNurbSurface(ddNurb);
+ return(BadAlloc);
+ }
+ }
+ }
+
+ OC_PARSER_RETURN(ddNurb);
+
+}
+
+
+OC_PARSER_FUNC_HEADER(CellArray2D)
+{
+ miCellArrayStruct *ddCell;
+ PARSER_PTR(ptr);
+ pexCellArray2D *pCell = (pexCellArray2D *)pPEXOC;
+
+ GET_DD_STORAGE( ddCell, miCellArrayStruct, sizeof(miCellArrayStruct)
+ + sizeof(listofddPoint) + 2 * sizeof(ddCoord2D)
+ + pCell->dx * pCell->dy * sizeof(ddIndexedColour));
+ ddCell->point.ddList = (listofddPoint *)(ddCell+1);
+
+ ddCell->point.type = DD_2D_POINT;
+ ddCell->point.numLists = 1;
+ ddCell->point.maxLists = 1;
+ ddCell->point.ddList->numPoints = 2;
+ ddCell->point.ddList->pts.p2Dpt =
+ (ddCoord2D *)((ddCell->point.ddList) + 1);
+ EXTRACT_LISTOF_COORD2D(2, ddCell->point.ddList->pts.p2Dpt, ptr);
+
+ EXTRACT_CARD32(ddCell->dx, ptr);
+ EXTRACT_CARD32(ddCell->dy, ptr);
+ ddCell->colours.colour.pIndex =
+ (ddIndexedColour *)((ddCell->point.ddList->pts.p2Dpt) + 2);
+ EXTRACT_STRUCT( ddCell->dx * ddCell->dy, ddIndexedColour,
+ ddCell->colours.colour.pIndex, ptr);
+
+ OC_PARSER_RETURN(ddCell);
+}
+
+
+OC_PARSER_FUNC_HEADER(CellArray)
+{
+ miCellArrayStruct *ddCell;
+ PARSER_PTR(ptr);
+ pexCellArray *pCell = (pexCellArray *)pPEXOC;
+
+ GET_DD_STORAGE( ddCell, miCellArrayStruct, sizeof(miCellArrayStruct)
+ + sizeof(listofddPoint) + 3 * sizeof(ddCoord3D)
+ + pCell->dx * pCell->dy * sizeof(ddIndexedColour));
+ ddCell->point.ddList = (listofddPoint *)(ddCell+1);
+
+ ddCell->point.type = DD_3D_POINT;
+ ddCell->point.numLists = 1;
+ ddCell->point.maxLists = 1;
+ ddCell->point.ddList->numPoints = 3;
+ ddCell->point.ddList->pts.p3Dpt =
+ (ddCoord3D *)((ddCell->point.ddList) + 1);
+ EXTRACT_LISTOF_COORD3D(3, ddCell->point.ddList->pts.p3Dpt, ptr);
+
+ EXTRACT_CARD32(ddCell->dx, ptr);
+ EXTRACT_CARD32(ddCell->dy, ptr);
+ ddCell->colours.colour.pIndex =
+ (ddIndexedColour *)((ddCell->point.ddList->pts.p3Dpt) + 3);
+ EXTRACT_STRUCT( ddCell->dx * ddCell->dy, ddIndexedColour,
+ ddCell->colours.colour.pIndex, ptr);
+
+ OC_PARSER_RETURN(ddCell);
+}
+
+
+OC_PARSER_FUNC_HEADER(ExtCellArray)
+{
+ miCellArrayStruct *ddCell;
+ PARSER_PTR(ptr);
+ pexExtCellArray *pCell = (pexExtCellArray *)pPEXOC;
+ unsigned long size;
+
+ size = (((pCell->colourType==PEXIndexedColour)
+ || (pCell->colourType==PEXRgb8Colour)) ? 4 :
+ ((pCell->colourType==PEXRgb16Colour) ? 8 : 12 ));
+ GET_DD_STORAGE( ddCell, miCellArrayStruct, sizeof(miCellArrayStruct)
+ + sizeof(listofddPoint) + 3 * sizeof(ddCoord3D)
+ + pCell->dx * pCell->dy * size);
+ ddCell->point.ddList = (listofddPoint *)(ddCell+1);
+
+ EXTRACT_CARD16(ddCell->colours.colourType, ptr);
+ SKIP_PADDING(ptr, 2);
+
+ ddCell->point.type = DD_3D_POINT;
+ ddCell->point.numLists = 1;
+ ddCell->point.maxLists = 1;
+ ddCell->point.ddList->numPoints = 3;
+ ddCell->point.ddList->pts.p3Dpt =
+ (ddCoord3D *)((ddCell->point.ddList) + 1);
+ EXTRACT_LISTOF_COORD3D(3, ddCell->point.ddList->pts.p3Dpt, ptr);
+ EXTRACT_CARD32(ddCell->dx, ptr);
+ EXTRACT_CARD32(ddCell->dy, ptr);
+
+ switch (pCell->colourType) {
+
+ case PEXIndexedColour: {
+ ddCell->colours.colour.pIndex =
+ (ddIndexedColour *)((ddCell->point.ddList->pts.p3Dpt) + 3);
+ EXTRACT_STRUCT( ddCell->dx * ddCell->dy, ddIndexedColour,
+ ddCell->colours.colour.pIndex, ptr);
+ break; }
+
+ case PEXRgbFloatColour : {
+ ddCell->colours.colour.pRgbFloat =
+ (ddRgbFloatColour *)((ddCell->point.ddList->pts.p3Dpt) + 3);
+ EXTRACT_STRUCT( ddCell->dx * ddCell->dy, ddRgbFloatColour,
+ ddCell->colours.colour.pRgbFloat, ptr);
+ break; }
+
+ case PEXCieFloatColour : {
+ ddCell->colours.colour.pCie =
+ (ddCieColour *)((ddCell->point.ddList->pts.p3Dpt) + 3);
+ EXTRACT_STRUCT( ddCell->dx * ddCell->dy, ddCieColour,
+ ddCell->colours.colour.pCie, ptr);
+ break; }
+
+ case PEXHsvFloatColour : {
+ ddCell->colours.colour.pHsv =
+ (ddHsvColour *)((ddCell->point.ddList->pts.p3Dpt) + 3);
+ EXTRACT_STRUCT( ddCell->dx * ddCell->dy, ddHsvColour,
+ ddCell->colours.colour.pHsv, ptr);
+ break; }
+
+ case PEXHlsFloatColour : {
+ ddCell->colours.colour.pHls =
+ (ddHlsColour *)((ddCell->point.ddList->pts.p3Dpt) + 3);
+ EXTRACT_STRUCT( ddCell->dx * ddCell->dy, ddHlsColour,
+ ddCell->colours.colour.pHls, ptr);
+ break; }
+
+ case PEXRgb8Colour : {
+ ddCell->colours.colour.pRgb8 =
+ (ddRgb8Colour *)((ddCell->point.ddList->pts.p3Dpt) + 3);
+ EXTRACT_STRUCT( ddCell->dx * ddCell->dy, ddRgb8Colour,
+ ddCell->colours.colour.pRgb8, ptr);
+ break; }
+
+ case PEXRgb16Colour : {
+ ddCell->colours.colour.pRgb16 =
+ (ddRgb16Colour *) ((ddCell->point.ddList->pts.p3Dpt) + 3);
+ EXTRACT_STRUCT( ddCell->dx * ddCell->dy, ddRgb16Colour,
+ ddCell->colours.colour.pRgb16, ptr);
+ break; }
+
+ }
+
+ OC_PARSER_RETURN(ddCell);
+
+}
+
+
+OC_PARSER_FUNC_HEADER(PSurfaceChars)
+{
+ miPSurfaceCharsStruct *ddPSC;
+ ddULONG sType = 0;
+ ddPointer ptr = (ddPointer)pPEXOC;
+
+ sType = ((pexParaSurfCharacteristics *)pPEXOC)->characteristics;
+ SKIP_PADDING(ptr,sizeof(pexParaSurfCharacteristics));
+
+ switch (sType) {
+ case PEXPSCNone:
+ case PEXPSCImpDep:
+ GET_DD_STORAGE( ddPSC, miPSurfaceCharsStruct,
+ sizeof(miPSurfaceCharsStruct));
+ break;
+
+ case PEXPSCIsoCurves: {
+ GET_DD_STORAGE( ddPSC, miPSurfaceCharsStruct,
+ sizeof(miPSurfaceCharsStruct)
+ + sizeof(ddPSC_IsoparametricCurves));
+ ddPSC->data.pIsoCurves = (ddPSC_IsoparametricCurves *)(ddPSC + 1);
+ EXTRACT_CARD16(ddPSC->data.pIsoCurves->placementType, ptr);
+ SKIP_PADDING(ptr, 2);
+ EXTRACT_CARD16(ddPSC->data.pIsoCurves->numUcurves, ptr);
+ EXTRACT_CARD16(ddPSC->data.pIsoCurves->numVcurves, ptr);
+ break; }
+
+ case PEXPSCMcLevelCurves: {
+ GET_DD_STORAGE( ddPSC, miPSurfaceCharsStruct,
+ sizeof(miPSurfaceCharsStruct)
+ + sizeof(ddPSC_LevelCurves));
+ ddPSC->data.pMcLevelCurves = (ddPSC_LevelCurves *)(ddPSC + 1);
+ EXTRACT_STRUCT( 1,ddPSC_LevelCurves,ddPSC->data.pMcLevelCurves, ptr);
+ break; }
+
+ case PEXPSCWcLevelCurves: {
+ GET_DD_STORAGE( ddPSC, miPSurfaceCharsStruct,
+ sizeof(miPSurfaceCharsStruct)
+ + sizeof(ddPSC_LevelCurves));
+ ddPSC->data.pWcLevelCurves = (ddPSC_LevelCurves *)(ddPSC + 1);
+ EXTRACT_STRUCT( 1,ddPSC_LevelCurves,ddPSC->data.pWcLevelCurves, ptr);
+ break; }
+ }
+
+ ddPSC->type = sType;
+
+ OC_PARSER_RETURN(ddPSC);
+}
+
+
+
+
+OC_PARSER_FUNC_HEADER(Gdp2D)
+{
+ miGdpStruct *ddGdp;
+ pexGdp2D *pGdp = (pexGdp2D *)pPEXOC;
+ PARSER_PTR(ptr);
+
+ GET_DD_STORAGE( ddGdp, miGdpStruct, (sizeof(miGdpStruct) +
+ sizeof(listofddPoint) + pGdp->numBytes
+ + pGdp->numPoints * sizeof(ddCoord2D)));
+ ddGdp->points.ddList = (listofddPoint *)(ddGdp+1);
+ ddGdp->GDPid = pGdp->gdpId;
+ ddGdp->points.ddList->numPoints = pGdp->numPoints;
+ ddGdp->numBytes = pGdp->numBytes;
+ ddGdp->points.type = DD_2D_POINT;
+ ddGdp->points.numLists = 1;
+ ddGdp->points.maxLists = 1;
+ ddGdp->points.ddList->pts.p2Dpt = (ddCoord2D *)((ddGdp->points.ddList) + 1);
+ ptr = (ddPointer)(pGdp+1);
+ EXTRACT_LISTOF_COORD2D(ddGdp->points.ddList->numPoints,
+ ddGdp->points.ddList->pts.p2Dpt, ptr);
+ ddGdp->pData = ((ddUCHAR *)(ddGdp->points.ddList))
+ + pGdp->numPoints * sizeof(ddCoord2D);
+ EXTRACT_STRUCT( ddGdp->numBytes, ddUCHAR, ddGdp->pData, ptr);
+
+ OC_PARSER_RETURN(ddGdp);
+
+}
+
+
+OC_PARSER_FUNC_HEADER(Gdp)
+{
+ miGdpStruct *ddGdp;
+ pexGdp *pGdp = (pexGdp *)pPEXOC;
+ PARSER_PTR(ptr);
+
+ GET_DD_STORAGE( ddGdp, miGdpStruct, (sizeof(miGdpStruct) +
+ sizeof(listofddPoint) + pGdp->numBytes
+ + pGdp->numPoints * sizeof(ddCoord3D)));
+ ddGdp->points.ddList = (listofddPoint *)(ddGdp+1);
+ ddGdp->GDPid = pGdp->gdpId;
+ ddGdp->points.ddList->numPoints = pGdp->numPoints;
+ ddGdp->numBytes = pGdp->numBytes;
+ ddGdp->points.type = DD_3D_POINT;
+ ddGdp->points.numLists = 1;
+ ddGdp->points.maxLists = 1;
+ ddGdp->points.ddList->pts.p3Dpt = (ddCoord3D *)((ddGdp->points.ddList) + 1);
+ ptr = (ddPointer)(pGdp+1);
+ EXTRACT_LISTOF_COORD3D(ddGdp->points.ddList->numPoints,
+ ddGdp->points.ddList->pts.p3Dpt, ptr);
+ ddGdp->pData = ((ddUCHAR *)(ddGdp->points.ddList))
+ + pGdp->numPoints * sizeof(ddCoord3D);
+ EXTRACT_STRUCT( ddGdp->numBytes, ddUCHAR, ddGdp->pData, ptr);
+
+ OC_PARSER_RETURN(ddGdp);
+
+}
+
+
+OC_PARSER_FUNC_HEADER(SetAttribute)
+{
+ /** The function vector should be set up to have this
+ ** SetAttribute function as the entry for all of the OC entries other
+ ** than those listed above or those NULL'd out
+ **/
+
+ ddElementInfo *dstAttrib;
+
+ GET_DD_STORAGE( dstAttrib, ddElementInfo,
+ pPEXOC->length * sizeof(CARD32));
+
+ memcpy( (char *)dstAttrib, (char *)pPEXOC,
+ (int)(pPEXOC->length * sizeof(CARD32)));
+
+ OC_PARSER_RETURN(pPEXOC);
+}
+
+
+OC_PARSER_FUNC_HEADER(PropOC)
+{
+ /** This handles storing ProprietaryOC
+ **/
+
+ ddElementInfo *dstPropOC;
+
+ GET_DD_STORAGE( dstPropOC, ddElementInfo,
+ pPEXOC->length * sizeof(CARD32));
+
+ memcpy( (char *)dstPropOC, (char *)pPEXOC,
+ (int)(pPEXOC->length * sizeof(CARD32)));
+
+ OC_PARSER_RETURN(pPEXOC);
+}
+
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level3/Imakefile b/xc/programs/Xserver/PEX5/ddpex/mi/level3/Imakefile
new file mode 100644
index 000000000..d11e1e072
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level3/Imakefile
@@ -0,0 +1,63 @@
+XCOMM
+XCOMM $XConsortium: Imakefile /main/9 1996/09/28 16:54:20 rws $
+XCOMM $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level3/Imakefile,v 3.9 1999/04/17 09:08:16 dawes Exp $
+XCOMM
+XCOMM
+XCOMM Copyright 1989, 1990, 1991 by Sun Microsystems, Inc. and the X Consortium
+XCOMM
+XCOMM All Rights Reserved
+XCOMM
+XCOMM Permission to use, copy, modify, and distribute this software and its
+XCOMM documentation for any purpose and without fee is hereby granted,
+XCOMM provided that the above copyright notice appear in all copies and that
+XCOMM both that copyright notice and this permission notice appear in
+XCOMM supporting documentation, and that the names of Sun Microsystems
+XCOMM or the X Consortium not be used in advertising or publicity
+XCOMM pertaining to distribution of the software without specific, written
+XCOMM prior permission.
+XCOMM
+XCOMM SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+XCOMM INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+XCOMM EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+XCOMM CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+XCOMM USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+XCOMM OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+XCOMM PERFORMANCE OF THIS SOFTWARE.
+
+#define IHaveModules
+#include <Server.tmpl>
+
+#ifndef PexDdpexCDebugFlags
+#define PexDdpexCDebugFlags ServerCDebugFlags
+#endif
+
+XCOMM -D defines for ddpex:
+XCOMM DDTEST turns on some fprintf(stderr...)s for debugging
+
+ DEFINES = PexDdpexDefines
+CDEBUGFLAGS = PexDdpexCDebugFlags
+
+ PEXSERVINC = ../../../include
+DDPEXINCLUDE = ../include
+
+INCLUDES = -I. \
+ -I$(DDPEXINCLUDE) \
+ -I$(XINCLUDESRC) \
+ -I$(PEXSERVINC) \
+ -I$(SERVERSRC)/include
+
+SRCS = miRender.c miRndrPick.c
+
+OBJS = miRender.o miRndrPick.o
+
+ModuleObjectRule()
+
+SubdirLibraryRule($(OBJS))
+
+NormalLibraryTarget(ddpex3,$(OBJS))
+
+LintLibraryTarget(dp3, $(SRCS))
+NormalLintTarget($(SRCS))
+
+DependTarget()
+
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level3/miRender.c b/xc/programs/Xserver/PEX5/ddpex/mi/level3/miRender.c
new file mode 100644
index 000000000..037328e10
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level3/miRender.c
@@ -0,0 +1,1966 @@
+/* $TOG: miRender.c /main/22 1998/02/10 12:43:12 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level3/miRender.c,v 3.5 1998/10/04 09:34:37 dawes Exp $ */
+
+#include "miLUT.h"
+#include "dipex.h"
+#include "ddpex3.h"
+#include "PEXproto.h"
+#include "PEXprotost.h"
+#include "PEXErr.h"
+#include "pexUtils.h"
+#include "pixmap.h"
+#include "windowstr.h"
+#include "regionstr.h"
+#include "miscstruct.h"
+#include "dixstruct.h"
+#include "miRender.h"
+#include "miStruct.h"
+#include "miStrMacro.h"
+#include "miWks.h"
+#include "ddpex4.h"
+#include "gcstruct.h"
+#include "pexos.h"
+
+
+/* External variables used */
+
+extern void mi_set_filters();
+extern void miMatMult();
+extern ddpex3rtn miBldViewport_xform();
+extern ddpex3rtn miBldCC_xform();
+extern ocTableType ParseOCTable[];
+extern void (*DestroyOCTable[])();
+extern ocTableType InitExecuteOCTable[];
+extern ocTableType PickExecuteOCTable[];
+extern ocTableType SearchExecuteOCTable[];
+extern RendTableType RenderPrimitiveTable[];
+extern RendTableType PickPrimitiveTable[];
+
+/* pcflag is initialized in ddpexInit() */
+ddBOOL pcflag;
+ddPCAttr defaultPCAttr;
+#define MI_GET_DEFAULT_PC(pPC) \
+ if (!pcflag) { \
+ DefaultPC(pPC); \
+ pcflag = MI_TRUE; }
+
+ddFLOAT ident4x4[4][4] = {
+ {1.0, 0.0, 0.0, 0.0},
+ {0.0, 1.0, 0.0, 0.0},
+ {0.0, 0.0, 1.0, 0.0},
+ {0.0, 0.0, 0.0, 1.0}
+};
+
+
+/* Level III Rendering Procedures */
+
+/*++
+ |
+ | Function Name: InitRenderer
+ |
+ | Function Description:
+ | Initializes the dd stuff in the renderer for the
+ | PEXCreateRenderer request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+InitRenderer(pRend)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+/* out */
+{
+
+ extern GCPtr CreateScratchGC();
+ extern ddpex3rtn CreateDDContext();
+
+ ddpex3rtn err = Success;
+
+
+#ifdef DDTEST
+ ErrorF( " InitRenderer\n");
+#endif
+
+ /* set renderer dynamics */
+ /* for now, set them all to be dynamic regardless of drawable type
+ * bit value of 0 means dynamic modifications
+ * bit value of 1 means no dynamic modifications
+ * todo: change this to be easy to specify individual dynamics
+ * OR with PEXDynxxx for static; OR with ~PEXDynxxx for dynamics
+ */
+ /* since we don't actually make copies of namesets
+ * or luts so that their values are bound at BeginRendering,
+ * any change made in those tables/ns will be noticed anytime
+ * info is read from an lut/ns, therefore, the tables and namesets
+ * are dynamics and anytime a change is made, anything affected
+ * by that change must be updated. The update is done in
+ * ValidateRenderer, which is called at appropriate times to
+ * make sure everything is updated.
+ */
+ pRend->tablesMask = 0;
+ pRend->namesetsMask = 0;
+ pRend->attrsMask = 0;
+
+ /*
+ * Create a DDContext and associate it with the Renderer
+ */
+ if (err = CreateDDContext(pRend)) return(err);
+
+ /* copy the initial oc functions to the OC table */
+ pRend->render_mode = MI_REND_DRAWING;
+ memcpy( (char *)pRend->executeOCs,
+ (char *)InitExecuteOCTable,
+ sizeof(ocTableType)*OCTABLE_LENGTH);
+
+ MI_SET_ALL_CHANGES(pRend);
+ ValidateRenderer(pRend);
+
+ return (Success);
+}
+
+/*++
+ |
+ | Function Name: DefaultPC
+ |
+ | Function Description:
+ | Initializes a global static copy of the PC to the default values.
+ | This copy is, in turn, used to initialize PC's the the initial values.
+ |
+ | Note(s):
+ |
+ --*/
+
+void
+DefaultPC(pPC)
+ ddPCAttr *pPC;
+{
+ pPC->markerType = PEXMarkerAsterisk;
+ pPC->markerScale = 1.0;
+ pPC->markerColour.colourType = PEXIndexedColour;
+ pPC->markerColour.colour.indexed.index = 1;
+ pPC->markerIndex = 1;
+ pPC->textFont = 1;
+ pPC->textPrecision = PEXStringPrecision;
+ pPC->charExpansion = 1.0;
+ pPC->charSpacing = 0.0;
+ pPC->textColour.colourType = PEXIndexedColour;
+ pPC->textColour.colour.indexed.index = 1;
+ pPC->charHeight = 0.01;
+ pPC->charUp.x = 0.0;
+ pPC->charUp.y = 1.0;
+ pPC->textPath = PEXPathRight;
+ pPC->textAlignment.vertical = PEXValignNormal;
+ pPC->textAlignment.horizontal = PEXHalignNormal;
+ pPC->atextHeight = 0.01;
+ pPC->atextUp.x = 0.0;
+ pPC->atextUp.y = 1.0;
+ pPC->atextPath = PEXPathRight;
+ pPC->atextAlignment.vertical = PEXValignNormal;
+ pPC->atextAlignment.horizontal = PEXHalignNormal;
+ pPC->atextStyle = PEXATextNotConnected;
+ pPC->textIndex = 1;
+ pPC->lineType = PEXLineTypeSolid;
+ pPC->lineWidth = 1.0;
+ pPC->lineColour.colourType = PEXIndexedColour;
+ pPC->lineColour.colour.indexed.index = 1;
+ pPC->curveApprox.approxMethod = PEXApproxConstantBetweenKnots;
+ pPC->curveApprox.tolerance = 1.0;
+ pPC->lineInterp = PEXPolylineInterpNone;
+ pPC->lineIndex = 1;
+ pPC->intStyle = PEXInteriorStyleHollow;
+ pPC->intStyleIndex = 1;
+ pPC->surfaceColour.colourType = PEXIndexedColour;
+ pPC->surfaceColour.colour.indexed.index = 1;
+ pPC->reflAttr.ambient = 1.0;
+ pPC->reflAttr.diffuse = 1.0;
+ pPC->reflAttr.specular = 1.0;
+ pPC->reflAttr.specularConc = 0.0;
+ pPC->reflAttr.transmission = 0.0;
+ pPC->reflAttr.specularColour.colourType = PEXIndexedColour;
+ pPC->reflAttr.specularColour.colour.indexed.index = 1;
+ pPC->reflModel = PEXReflectionNoShading;
+ pPC->surfInterp = PEXSurfaceInterpNone;
+ pPC->bfIntStyle = PEXInteriorStyleHollow;
+ pPC->bfIntStyleIndex = 1;
+ pPC->bfSurfColour.colourType = PEXIndexedColour;
+ pPC->bfSurfColour.colour.indexed.index = 1;
+ pPC->bfReflAttr.ambient = 1.0;
+ pPC->bfReflAttr.diffuse = 1.0;
+ pPC->bfReflAttr.specular = 1.0;
+ pPC->bfReflAttr.specularConc = 0.0;
+ pPC->bfReflAttr.transmission = 0.0;
+ pPC->bfReflAttr.specularColour.colourType = PEXIndexedColour;
+ pPC->bfReflAttr.specularColour.colour.indexed.index = 1;
+ pPC->bfReflModel = PEXReflectionNoShading;
+ pPC->bfSurfInterp = PEXSurfaceInterpNone;
+
+ pPC->surfApprox.approxMethod = PEXApproxConstantBetweenKnots;
+ pPC->surfApprox.uTolerance = 1.0;
+ pPC->surfApprox.vTolerance = 1.0;
+
+ pPC->cullMode = 0;
+ pPC->distFlag = FALSE;
+ pPC->patternSize.x = 1.0;
+ pPC->patternSize.y = 1.0;
+ pPC->patternRefPt.x = 0.0;
+ pPC->patternRefPt.y = 0.0;
+ pPC->patternRefPt.z = 0.0;
+ pPC->patternRefV1.x = 1.0;
+ pPC->patternRefV1.y = 0.0;
+ pPC->patternRefV1.z = 0.0;
+ pPC->patternRefV2.x = 0.0;
+ pPC->patternRefV2.y = 1.0;
+ pPC->patternRefV2.z = 0.0;
+ pPC->intIndex = 1;
+ pPC->edges = PEXOff;
+ pPC->edgeType = PEXSurfaceEdgeSolid;
+ pPC->edgeWidth = 1.0;
+ pPC->edgeColour.colourType = PEXIndexedColour;
+ pPC->edgeColour.colour.indexed.index = 1;
+ pPC->edgeIndex = 1;
+ memcpy( (char *) pPC->localMat, (char *) ident4x4, 16 * sizeof(ddFLOAT));
+ memcpy( (char *) pPC->globalMat, (char *) ident4x4, 16 * sizeof(ddFLOAT));
+ pPC->modelClip = PEXNoClip;
+ pPC->modelClipVolume = puCreateList(DD_HALF_SPACE);
+ pPC->viewIndex = 0;
+ pPC->lightState = puCreateList(DD_INDEX);
+ pPC->depthCueIndex = 0;
+ pPC->colourApproxIndex = 0;
+ pPC->rdrColourModel = PEXRdrColourModelRGB;
+ pPC->psc.type = PEXPSCNone;
+ pPC->psc.data.none = '0';
+ pPC->asfs = ~0L;
+ pPC->pickId = 0;
+ pPC->hlhsrType = 0;
+ pPC->pCurrentNS = NULL;
+
+ return;
+}
+
+/*++
+ |
+ | Function Name: InquireRendererDynamics
+ |
+ | Function Description:
+ | Supports the PEXGetRendererDynamics request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+InquireRendererDynamics(pRend, pTablesMask, pNSMask, pAttrMask)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+/* out */
+ ddBitmask *pTablesMask; /* dynamics mask for luts */
+ ddBitmask *pNSMask; /* dynamics mask for name sets */
+ ddBitmask *pAttrMask;/* dynamics mask for renderer attributes */
+{
+
+#ifdef DDTEST
+ ErrorF( " InquireRendererDynamics\n");
+#endif
+
+ *pTablesMask = pRend->tablesMask;
+ *pNSMask = pRend->namesetsMask;
+ *pAttrMask = pRend->attrsMask;
+
+ return (Success);
+}
+
+/*++
+ |
+ | Function Name: RenderOCs
+ |
+ | Function Description:
+ | Supports the PEXRenderOutputCommands request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+RenderOCs(pRend, numOCs, pOCs)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ ddULONG numOCs;
+ ddElementInfo *pOCs;
+/* out */
+{
+ register ddElementInfo *poc;
+ miGenericElementPtr pexoc;
+ ddpex2rtn err = Success;
+ XID fakestr;
+ diStructHandle sh = 0, ph;
+ pexStructure *ps;
+ pexOutputCommandError *pErr;
+ ddULONG offset1, offset2, numberOCs;
+ miTraverserState trav_state;
+ diPMHandle pPM = (diPMHandle) NULL;
+ unsigned long PEXStructType;
+ miStructPtr pheader;
+ ddPickPath *strpp;
+ miPPLevel *travpp;
+ int i, ROCdepth;
+ ddUSHORT serverstate;
+
+
+#ifdef DDTEST
+ ErrorF( " RenderOCs\n");
+#endif
+
+ /* if renderer idle ignore.... */
+ if (pRend->state == PEXIdle)
+ return Success;
+
+ ValidateRenderer(pRend);
+
+ /* state == PEXPicking, call through traverser */
+ if (pRend->state == PEXPicking) {
+
+ /* get the structure handle from the last pickpath in the list of
+ fake structures (these are added by BeginStructure)
+ */
+ ROCdepth = (pRend->pickstr.fakeStrlist)->numObj-1;
+ strpp = (ddPickPath *)(pRend->pickstr.fakeStrlist)->pList;
+ sh = strpp[ROCdepth].structure;
+
+ /* set up incoming state properly for traverser */
+ if (ROCdepth > 0) {
+ travpp = (miPPLevel *) xalloc(sizeof(miPPLevel));
+ trav_state.p_pick_path = travpp;
+ travpp->pp = strpp[ROCdepth-1];
+ for (i = ROCdepth-2; i >= 0; i--) {
+ travpp->up = (miPPLevel *) xalloc(sizeof(miPPLevel));
+ travpp = travpp->up;
+ travpp->pp = strpp[i];
+ }
+ }
+
+
+ /* now do the work of storing stuff into the structure */
+ numberOCs = numOCs;
+ for ( poc=pOCs; numberOCs>0; numberOCs-- )
+ {
+
+ err = StoreElements( sh, 1, poc, &pErr);
+ if (err != Success) return(err);
+
+ poc += poc->length;
+ }
+
+ /* now call the traverser to traverse this structure */
+ /* set exec_str_flag */
+ trav_state.exec_str_flag = ES_YES;
+ trav_state.p_curr_pick_el = (ddPickPath *) NULL;
+ trav_state.p_curr_sc_el = (ddElementRef *) NULL;
+ trav_state.max_depth = ROCdepth;
+ trav_state.pickId = strpp[ROCdepth].pickid;
+ trav_state.ROCoffset = strpp[ROCdepth].offset;
+ pPM = pRend->pickstr.pseudoPM;
+
+ /* turn off this flag so BeginStructure calls made inside traverser
+ do not cause fake structures to be allocated
+ */
+ serverstate = pRend->pickstr.server;
+ pRend->pickstr.server = DD_NEITHER;
+ offset1 = 1;
+ offset2 = numOCs;
+
+ err = traverser(pRend, sh, offset1, offset2, pPM, NULL, &trav_state);
+
+ /* restore the state flag */
+ pRend->pickstr.server = serverstate;
+
+ /* save pickid returned by traverser */
+ strpp[ROCdepth].pickid = trav_state.pickId;
+ strpp[ROCdepth].offset += numOCs;
+
+ /* clean up structure */
+ {
+ miStructPtr pheader = (miStructPtr) sh->deviceData;
+ extern cssTableType DestroyCSSElementTable[];
+
+ MISTR_DEL_ELS(sh, pheader, 1, numOCs);
+ MISTR_CURR_EL_PTR(pheader) = MISTR_ZERO_EL(pheader);
+ MISTR_CURR_EL_OFFSET(pheader) = 0;
+
+ }
+
+ }
+ else {
+ /* state == PEXRendering, call directly to level 2 for efficiency */
+ for ( poc=pOCs; numOCs>0; numOCs-- )
+ {
+ switch( poc->elementType ) {
+ /* drawing primitives */
+ case PEXOCMarker:
+ case PEXOCMarker2D:
+ case PEXOCText:
+ case PEXOCText2D:
+ case PEXOCAnnotationText:
+ case PEXOCAnnotationText2D:
+ case PEXOCPolyline:
+ case PEXOCPolyline2D:
+ case PEXOCPolylineSet:
+ case PEXOCNurbCurve:
+ case PEXOCFillArea:
+ case PEXOCFillArea2D:
+ case PEXOCExtFillArea:
+ case PEXOCFillAreaSet:
+ case PEXOCFillAreaSet2D:
+ case PEXOCExtFillAreaSet:
+ case PEXOCTriangleStrip:
+ case PEXOCQuadrilateralMesh:
+ case PEXOCSOFAS:
+ case PEXOCNurbSurface:
+ case PEXOCCellArray:
+ case PEXOCCellArray2D:
+ case PEXOCExtCellArray:
+ case PEXOCGdp:
+ case PEXOCGdp2D:
+
+ /* drop out if not doing primitives
+ * otherwise fall through */
+ if (!MI_DDC_DO_PRIMS(pRend))
+ break;
+
+ default:
+ /* if a Proprietary OC bump the counter and continue */
+ if (MI_HIGHBIT_ON((int)poc->elementType)) {
+ ((ddElementRef *)pRend->curPath->pList)
+ [pRend->curPath->numObj - 1].offset++;
+ break;
+ }
+ else {
+ /* not Proprietary see if valid PEX OC */
+ if (MI_IS_PEX_OC((int)poc->elementType)){
+
+ pexoc = 0;
+ err = ParseOCTable[ (int)poc->elementType ]
+ ( (ddPointer)poc, &pexoc );
+ }
+ else
+ err = !Success;
+ }
+
+ if (err != Success)
+ return( PEXERR(PEXOutputCommandError) );
+
+ /* If we make it here it is a valid OC no more checking to do */
+
+ /* add one to the current_path's element offset if a
+ * begin structure has been done
+ */
+ if (pRend->curPath->numObj)
+ ((ddElementRef *)pRend->curPath->pList)[pRend->curPath->numObj - 1].offset++;
+ pRend->executeOCs[ (int)poc->elementType ]( pRend, &pexoc->element );
+
+ DestroyOCTable[ (int)poc->elementType ]( pexoc );
+ }
+
+ poc += poc->length; /* length is in four byte units & sizeof(poc) is 4 */
+ }
+ }
+
+ return (err);
+}
+
+ddpex3rtn
+convertoffset(pstruct, ppos, poffset)
+/* in */
+ miStructStr *pstruct; /* pointer to the structure involved */
+ ddElementPos *ppos; /* the position information */
+/* out */
+ ddULONG *poffset; /* valid offset calculated from the postition */
+
+{
+ /* shamelessly lifted from the pos2offset routine in miStruct.c */
+
+ ddUSHORT whence = ppos->whence;
+ ddLONG offset = ppos->offset, temp;
+
+ switch (whence) {
+ case PEXBeginning:
+ temp = offset;
+ break;
+
+ case PEXCurrent:
+ temp = MISTR_CURR_EL_OFFSET(pstruct) + offset;
+ break;
+
+ case PEXEnd:
+ /* numElements is the same as the last elements offset */
+ temp = MISTR_NUM_EL(pstruct) + offset;
+ break;
+
+ default:
+ /* value error */
+ return (BadValue);
+ break;
+ }
+
+ /* now check that the new offset is in range of the structure */
+ if (temp < 0)
+ *poffset = 0;
+ else if (temp > MISTR_NUM_EL(pstruct))
+ *poffset = MISTR_NUM_EL(pstruct);
+ else
+ *poffset = temp;
+
+ return (Success);
+
+}
+
+
+
+/*++
+ |
+ | Function Name: RenderElements
+ |
+ | Function Description:
+ | Supports the PEXRenderElements request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+RenderElements(pRend, pStr, range)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ diStructHandle pStr;
+ ddElementRange *range;
+/* out */
+{
+ ddpex3rtn err = Success;
+ miStructPtr pstruct;
+ miGenericElementPtr pel;
+ ddULONG offset1, offset2, i;
+ miTraverserState trav_state;
+ diPMHandle pPM = (diPMHandle) NULL;
+ miDDContext *pddc = (miDDContext *) pRend->pDDContext;
+ int eltype, ROCdepth, j;
+ ddPickPath *strpp, sIDpp, *sIDlist;
+ miPPLevel *travpp;
+ XID fakeStrID;
+ diStructHandle sh = 0, REfakeStr;
+ ddUSHORT serverstate;
+ ddElementPos REfakePos;
+
+
+
+
+ /* if renderer idle ignore.... */
+ if (pRend->state == PEXIdle)
+ return Success;
+
+ pstruct = (miStructPtr) pStr->deviceData;
+
+ /* convert the offset based on whence value */
+ if (convertoffset(pstruct, &(range->position1), &offset1))
+ return (BadValue); /* bad whence value */
+
+ if (convertoffset(pstruct, &(range->position2), &offset2))
+ return (BadValue); /* bad whence value */
+
+ /* flip the range if necessary */
+ if (offset1 > offset2) {
+ i = offset1;
+ offset1 = offset2;
+ offset2 = i;
+ }
+
+ /* return early if offsets out of range */
+ if (offset1 == 0)
+ if (offset2 == 0)
+ return(Success);
+ else
+ offset1 = 1;
+
+ ValidateRenderer(pRend);
+
+ if (pRend->state == PEXPicking) {
+
+ /* in client side picking RenderElements could be called
+ at different levels of nested Begin Structures. In
+ order to uniquely store a correspondence between
+ structure handles and the correct ID a fake structure
+ must be allocated
+ */
+
+ REfakeStr = (diStructHandle)xalloc((unsigned long)
+ sizeof(ddStructResource));
+ if (!REfakeStr) return (BadAlloc);
+ REfakeStr->id = -666;
+ err = CreateStructure(REfakeStr);
+ if (err != Success) {
+ xfree((pointer)(REfakeStr));
+ return (err);
+ }
+
+ /* now copy the desired elements out of the structure passed in
+ and into the fake structure
+ */
+ REfakePos.whence = PEXBeginning;
+ REfakePos.offset = 0;
+ err = CopyElements(pStr, range, REfakeStr, &REfakePos);
+ if (err != Success) {
+ xfree((pointer)(REfakeStr));
+ return (err);
+ }
+
+
+ /* need to handle case where RenderElements is called
+ after a ROC that may or may not have Begin/End structures
+ nested in it
+ */
+ ROCdepth = (pRend->pickstr.fakeStrlist)->numObj-1;
+ strpp = (ddPickPath *)(pRend->pickstr.fakeStrlist)->pList;
+ sh = strpp[ROCdepth].structure;
+
+
+ /* set up incoming state properly for traverser */
+ if (ROCdepth > 0) {
+ travpp = (miPPLevel *) xalloc(sizeof(miPPLevel));
+ trav_state.p_pick_path = travpp;
+ travpp->pp = strpp[ROCdepth-1];
+ for (j = ROCdepth-2; j >= 0; j--) {
+ travpp->up = (miPPLevel *) xalloc(sizeof(miPPLevel));
+ travpp = travpp->up;
+ travpp->pp = strpp[j];
+ }
+ }
+
+
+ /* set exec_str_flag */
+ trav_state.exec_str_flag = ES_YES;
+ trav_state.p_curr_pick_el = (ddPickPath *) NULL;
+ trav_state.p_curr_sc_el = (ddElementRef *) NULL;
+ trav_state.max_depth = ROCdepth;
+ trav_state.pickId = strpp[ROCdepth].pickid;
+ trav_state.ROCoffset = strpp[ROCdepth].offset;
+
+ pPM = pRend->pickstr.pseudoPM;
+
+ /* turn off this flag so BeginStructure calls made inside traverser
+ do not cause fake structures to be allocated
+ */
+ serverstate = pRend->pickstr.server;
+ pRend->pickstr.server = DD_NEITHER;
+ /* redefine the offsets into the fake structure from the originals */
+ offset2 = (offset2 - offset1 + 1);
+ offset1 = 1;
+
+ err = traverser(pRend, REfakeStr, offset1, offset2, pPM, NULL, &trav_state);
+
+ /* restore the state flag */
+ pRend->pickstr.server = serverstate;
+
+ /* save pickid returned by traverser */
+ strpp[ROCdepth].pickid = trav_state.pickId;
+ strpp[ROCdepth].offset += offset2;
+
+ /* now find the ID that corresponds to the handle sh and
+ save that as the corresponding ID for pStr in the sIDlist
+ note that the IDs ARE stored in the pickid field
+ */
+ sIDpp.structure = REfakeStr;
+ sIDpp.offset = 0;
+ sIDlist = (ddPickPath *) (pRend->pickstr.sIDlist)->pList;
+ for (j = 0; j < (pRend->pickstr.sIDlist)->numObj; j++, sIDlist++)
+ if (sh == sIDlist->structure) {
+ sIDpp.pickid = sIDlist->pickid;
+ break;
+ }
+
+ err = puAddToList((ddPointer) &sIDpp, (ddULONG) 1, pRend->pickstr.sIDlist);
+ if (err != Success) return (err);
+
+ /* clean up structure */
+ {
+ miStructPtr pheader = (miStructPtr) REfakeStr->deviceData;
+ extern cssTableType DestroyCSSElementTable[];
+
+ MISTR_DEL_ELS(REfakeStr, pheader, offset1, offset2);
+ MISTR_CURR_EL_PTR(pheader) = MISTR_ZERO_EL(pheader);
+ MISTR_CURR_EL_OFFSET(pheader) = 0;
+
+ }
+
+ }
+ else {
+ /* state == PEXRendering call directly into level 2 for efficiency */
+ for (i = offset1; i <= offset2; i++){
+
+ /* set the element pointer */
+ if ( i == offset1) {
+ MISTR_FIND_EL(pstruct, offset1, pel);
+ }
+ else
+ pel = MISTR_NEXT_EL(pel);
+
+ eltype = MISTR_EL_TYPE (pel);
+
+ switch (eltype) {
+ /* drawing primitives */
+ case PEXOCMarker:
+ case PEXOCMarker2D:
+ case PEXOCText:
+ case PEXOCText2D:
+ case PEXOCAnnotationText:
+ case PEXOCAnnotationText2D:
+ case PEXOCPolyline:
+ case PEXOCPolyline2D:
+ case PEXOCPolylineSet:
+ case PEXOCNurbCurve:
+ case PEXOCFillArea:
+ case PEXOCFillArea2D:
+ case PEXOCExtFillArea:
+ case PEXOCFillAreaSet:
+ case PEXOCFillAreaSet2D:
+ case PEXOCExtFillAreaSet:
+ case PEXOCTriangleStrip:
+ case PEXOCQuadrilateralMesh:
+ case PEXOCSOFAS:
+ case PEXOCNurbSurface:
+ case PEXOCCellArray:
+ case PEXOCCellArray2D:
+ case PEXOCExtCellArray:
+ case PEXOCGdp:
+
+ /* drop out if not doing primitives
+ * otherwise fall through */
+ if (!MI_DDC_DO_PRIMS(pRend))
+ break;
+ default:
+ /* if a Proprietary OC call the correct routine */
+ if (MI_HIGHBIT_ON(eltype)) {
+ pRend->executeOCs[MI_OC_PROP]( pRend,
+ (ddPointer)&(MISTR_EL_DATA (pel)));
+ }
+ else {
+ /* not Proprietary see if valid PEX OC */
+ if (MI_IS_PEX_OC(eltype))
+ pRend->executeOCs[ eltype]( pRend,
+ (ddPointer)&(MISTR_EL_DATA (pel)));
+ else
+ err = !Success;
+ }
+
+ if (err != Success)
+ return( PEXERR(PEXOutputCommandError) );
+
+ }
+ }
+ }
+
+ return(err);
+}
+
+/*++
+ |
+ | Function Name: AccumulateState
+ |
+ | Function Description:
+ | Supports the PEXAccumulateState request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+AccumulateState(pRend, pAccSt )
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ddAccStPtr pAccSt; /* accumulate state handle */
+/* out */
+{
+ register int depth, offset;
+ ddpex3rtn err = Success;
+ ddElementRef *elemRef;
+ miStructPtr structPtr;
+ miGenericElementPtr elemPtr;
+
+ /* if renderer idle ignore.... */
+ if (pRend->state == PEXIdle)
+ return Success;
+
+ ValidateRenderer(pRend);
+
+ /* The path has already been validated */
+
+ elemRef = (ddElementRef *) pAccSt->Path->pList;
+ for (depth = 1; depth <= pAccSt->numElRefs; depth++) {
+ structPtr = (miStructPtr) elemRef->structure->deviceData;
+ elemPtr = MISTR_NEXT_EL (MISTR_ZERO_EL (structPtr));
+ for (offset = 0; offset < elemRef->offset; offset++) {
+ switch (MISTR_EL_TYPE (elemPtr)) {
+ case PEXOCMarkerType:
+ case PEXOCMarkerScale:
+ case PEXOCMarkerColourIndex:
+ case PEXOCMarkerColour:
+ case PEXOCMarkerBundleIndex:
+ case PEXOCTextFontIndex:
+ case PEXOCTextPrecision:
+ case PEXOCCharExpansion:
+ case PEXOCCharSpacing:
+ case PEXOCTextColourIndex:
+ case PEXOCTextColour:
+ case PEXOCCharHeight:
+ case PEXOCCharUpVector:
+ case PEXOCTextPath:
+ case PEXOCTextAlignment:
+ case PEXOCAtextHeight:
+ case PEXOCAtextUpVector:
+ case PEXOCAtextPath:
+ case PEXOCAtextAlignment:
+ case PEXOCAtextStyle:
+ case PEXOCTextBundleIndex:
+ case PEXOCLineType:
+ case PEXOCLineWidth:
+ case PEXOCLineColourIndex:
+ case PEXOCLineColour:
+ case PEXOCCurveApproximation:
+ case PEXOCPolylineInterp:
+ case PEXOCLineBundleIndex:
+ case PEXOCInteriorStyle:
+ case PEXOCInteriorStyleIndex:
+ case PEXOCSurfaceColourIndex:
+ case PEXOCSurfaceColour:
+ case PEXOCSurfaceReflAttr:
+ case PEXOCSurfaceReflModel:
+ case PEXOCSurfaceInterp:
+ case PEXOCBfInteriorStyle:
+ case PEXOCBfInteriorStyleIndex:
+ case PEXOCBfSurfaceColourIndex:
+ case PEXOCBfSurfaceColour:
+ case PEXOCBfSurfaceReflAttr:
+ case PEXOCBfSurfaceReflModel:
+ case PEXOCBfSurfaceInterp:
+ case PEXOCSurfaceApproximation:
+ case PEXOCCullingMode:
+ case PEXOCDistinguishFlag:
+ case PEXOCPatternSize:
+ case PEXOCPatternRefPt:
+ case PEXOCPatternAttr:
+ case PEXOCInteriorBundleIndex:
+ case PEXOCSurfaceEdgeFlag:
+ case PEXOCSurfaceEdgeType:
+ case PEXOCSurfaceEdgeWidth:
+ case PEXOCSurfaceEdgeColourIndex:
+ case PEXOCSurfaceEdgeColour:
+ case PEXOCEdgeBundleIndex:
+ case PEXOCSetAsfValues:
+ case PEXOCLocalTransform:
+ case PEXOCLocalTransform2D:
+ case PEXOCGlobalTransform:
+ case PEXOCGlobalTransform2D:
+ case PEXOCModelClip:
+ case PEXOCModelClipVolume:
+ case PEXOCModelClipVolume2D:
+ case PEXOCRestoreModelClip:
+ case PEXOCViewIndex:
+ case PEXOCLightState:
+ case PEXOCDepthCueIndex:
+ case PEXOCPickId:
+ case PEXOCHlhsrIdentifier:
+ case PEXOCColourApproxIndex:
+ case PEXOCRenderingColourModel:
+ case PEXOCParaSurfCharacteristics:
+ case PEXOCAddToNameSet:
+ case PEXOCRemoveFromNameSet:
+ /* if a Proprietary OC call the correct routine */
+ if (MI_HIGHBIT_ON(MISTR_EL_TYPE (elemPtr))) {
+ pRend->executeOCs[MI_OC_PROP]( pRend,
+ (ddPointer)&(MISTR_EL_DATA (elemPtr)));
+ }
+ else {
+ /* not Proprietary see if valid PEX OC */
+ if (MI_IS_PEX_OC(MISTR_EL_TYPE (elemPtr)))
+ pRend->executeOCs[(int) MISTR_EL_TYPE (elemPtr)]( pRend,
+ (ddPointer)&(MISTR_EL_DATA (elemPtr)));
+ else
+ err = !Success;
+ }
+
+ if (err != Success)
+ return( PEXERR(PEXOutputCommandError) );
+
+ break;
+ default:
+ break;
+ }
+
+ elemPtr = MISTR_NEXT_EL (elemPtr);
+ }
+
+ elemRef++;
+ }
+
+ return(err);
+}
+
+
+/*++
+ |
+ | Function Name: init_def_matrix
+ |
+ | Note(s):
+ |
+ --*/
+
+void
+init_def_matrix (matrix)
+ddFLOAT matrix[4][4];
+{
+ memcpy( (char *) matrix, (char *) ident4x4, 16 * sizeof(ddFLOAT));
+}
+
+
+/*++
+ |
+ | Function Name: init_pipeline
+ |
+ | Function Description:
+ | does stuff common to BeginRendering, BeginPicking, BeginSearching
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+init_pipeline(pRend, pDrawable)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ DrawablePtr pDrawable;/* pointer to drawable */
+/* out */
+{
+ miDDContext *pddc = (miDDContext *) pRend->pDDContext;
+ ddPCAttr *ppca;
+ listofObj *pMC, *pLS;
+
+#ifdef DDTEST
+ ErrorF( " init_pipeline\n");
+#endif
+
+ /*
+ * check that drawable is OK for renderer this means it's ok for the
+ * luts, ns, and GC since they are ok for the example drawable
+ */
+
+ /* empty current path */
+ PU_EMPTY_LIST(pRend->curPath);
+
+ /*
+ * Initialize ddcontext.
+ */
+ ppca = pddc->Dynamic->pPCAttr;
+ pMC = ppca->modelClipVolume;
+ pLS = ppca->lightState;
+ if (pRend->pPC != NULL) {
+ *ppca = *pRend->pPC->pPCAttr;
+ /*
+ * don't forget the model clip half planes and list of
+ * light sources, which are only pointed to
+ */
+ if (puCopyList(pRend->pPC->pPCAttr->modelClipVolume, pMC))
+ return(BadAlloc);
+ if (puCopyList(pRend->pPC->pPCAttr->lightState, pLS))
+ return(BadAlloc);
+ } else { /* use default PC values */
+ MI_GET_DEFAULT_PC(&defaultPCAttr);
+ *ppca = defaultPCAttr;
+ /*
+ * don't forget the model clip half planes and list of
+ * light sources, which are only pointed to
+ */
+ if (puCopyList(defaultPCAttr.modelClipVolume, pMC))
+ return(BadAlloc);
+ if (puCopyList(defaultPCAttr.lightState, pLS))
+ return(BadAlloc);
+ }
+ ppca->modelClipVolume = pMC;
+ ppca->lightState = pLS;
+
+ /* copy the current name set from the ns resource to the renderer */
+ MINS_EMPTY_NAMESET(pddc->Dynamic->currentNames);
+ if (ppca->pCurrentNS)
+ {
+ miNSHeader *pns = (miNSHeader *)ppca->pCurrentNS->deviceData;
+
+ MINS_COPY_NAMESET(pns->names, pddc->Dynamic->currentNames);
+ }
+
+ /* set the filter_flags in pddc for high, invis, pick, search */
+ mi_set_filters(pRend, pddc);
+
+ MI_DDC_SET_DO_PRIMS(pRend, pddc);
+
+ /* this must be called before the rendering state is set
+ * and after the filters are set */
+
+ MI_SET_ALL_CHANGES(pRend);
+ ValidateRenderer(pRend);
+
+ /*
+ * Compute composite 4x4s for use in the rendering pipeline
+ * Computed composites: 1. [GM][LM] = [CMM] or mc_to_wc_xform
+ * 2. [VO][VM] = [VOM] or wc_to_npc_xform
+ * 3. [CMM][VOM] = [VCM] or mc_to_npc_xform
+ * Reminder: [GM] and [LM] are in pipeline context, [VO]
+ * and [VM] are in the View LUT indexed by the
+ * view index set in the pipeline context.
+ */
+
+ /* Compute the composite [CMM] next */
+ miMatMult (pddc->Dynamic->mc_to_wc_xform,
+ pddc->Dynamic->pPCAttr->localMat,
+ pddc->Dynamic->pPCAttr->globalMat);
+
+ return (Success);
+}
+
+/*++
+ |
+ | Function Name: BeginRendering
+ |
+ | Function Description:
+ | Supports the PEXBeginRendering request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+BeginRendering(pRend, pDrawable)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ DrawablePtr pDrawable;/* pointer to drawable */
+/* out */
+{
+ miDDContext *pddc = (miDDContext *) pRend->pDDContext;
+
+#ifdef DDTEST
+ ErrorF( " BeginRendering\n");
+#endif
+
+ pRend->render_mode = MI_REND_DRAWING;
+
+ init_pipeline(pRend, pDrawable);
+
+ /*
+ * Determine the npc -> dc viewport transform
+ */
+ miBldViewport_xform(pRend, pDrawable, pddc->Static.misc.viewport_xform, pddc );
+
+ /*
+ * compute cc xform, concatenate to appropriate dd context matrices.
+ */
+ miBldCC_xform(pRend, pddc);
+
+ /*
+ * Clear the window if clearI flag is on.
+ * Use the background color in the renderer attributes.
+ * The default (0) entry in the Color Approx Table is used
+ * to compute the pixel.
+ */
+ if (pRend->clearI) {
+
+ unsigned long colorindex, gcmask;
+ GCPtr pGC;
+ extern GCPtr CreateScratchGC();
+ extern int ChangeGC();
+ extern void ValidateGC();
+ xRectangle xrect;
+ DrawablePtr pDraw;
+ xRectangle *xrects, *p;
+ ddDeviceRect *ddrects;
+ ddLONG numrects;
+ int i;
+ ddTableIndex colourApproxIndex;
+
+ pDraw = pRend->pDrawable;
+ if ((!pRend->pPC) || (!pRend->pPC->pPCAttr)) colourApproxIndex = 0;
+ else colourApproxIndex = pRend->pPC->pPCAttr->colourApproxIndex;
+ miColourtoIndex(pRend, colourApproxIndex,
+ &pRend->backgroundColour, &colorindex);
+ pGC = CreateScratchGC(pDraw->pScreen, pDraw->depth);
+ gcmask = GCForeground;
+ ChangeGC(pGC, gcmask, &colorindex);
+ /* Set the Clip List if there is one */
+ numrects = pRend->clipList->numObj;
+ if (numrects) {
+ ddrects = (ddDeviceRect *) pRend->clipList->pList;
+ xrects = (xRectangle*) xalloc(numrects * sizeof(xRectangle));
+ if (!xrects) return BadAlloc;
+ /* Need to convert to XRectangle format and flip Y */
+ for (i = 0, p = xrects; i < numrects; i++, p++, ddrects++) {
+ p->x = ddrects->xmin;
+ p->y = pDraw->height - ddrects->ymax;
+ p->width = ddrects->xmax - ddrects->xmin + 1;
+ p->height = ddrects->ymax - ddrects->ymin + 1;
+ }
+ SetClipRects(pGC, 0, 0, (int)numrects, xrects, Unsorted);
+ xfree((char*)xrects);
+ }
+ ValidateGC(pDraw, pGC);
+ /* Now draw a filled rectangle to clear the image buffer */
+ xrect.x = 0;
+ xrect.y = 0;
+ xrect.width = pDraw->width;
+ xrect.height = pDraw->height;
+ (*pGC->ops->PolyFillRect) (pDraw, pGC, 1, &xrect);
+ gcmask = GCClipMask;
+ colorindex = 0;
+ ChangeGC(pGC, gcmask, &colorindex);
+ FreeScratchGC(pGC);
+ }
+
+ /* do double buffering stuff */
+ /* do hlhsr stuff */
+
+ pRend->state = PEXRendering;
+ return (Success);
+}
+
+/*++
+ |
+ | Function Name: EndRendering
+ |
+ | Function Description:
+ | Supports the PEXEndRendering request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+EndRendering(pRend)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+/* out */
+{
+
+#ifdef DDTEST
+ ErrorF( " EndRendering\n");
+#endif
+
+ pRend->state = PEXIdle;
+ /* switch display buffers if doing multi-buffers */
+
+ return (Success);
+}
+
+/*++
+ |
+ | Function Name: BeginStructure
+ |
+ | Function Description:
+ | Supports the PEXBeginStructure request.
+ |
+ | Note(s):
+ | This procedure creates a new ddcontext which looks like the
+ | old (current) context.
+ |
+ | Since some of these elements contain and/or are pointers to
+ | objects, the info cannot be copied directly, but new objects
+ | must be made to be pointed to and their contents copied.
+ | So, the sequence that this procedure goes through is this:
+ | create a new dd context data structure
+ | copy old context to the new context, but remember
+ | that pointers to objects will be replaced.
+ | create a new PCAttr structure and copy old to new
+ | update the current path and transform matrices
+ | push the new context onto the stack
+ |
+ --*/
+
+ddpex3rtn
+BeginStructure(pRend, sId)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ ddResourceId sId; /* structure id */
+/* out */
+{
+ ddpex3rtn PushddContext();
+ ddpex3rtn err = Success;
+ ddElementRef newRef;
+ ddpex3rtn status;
+ XID fakeStrID;
+ diStructHandle fakeStr;
+ ddPickPath fakeStrpp, sIDpp, *curpp;
+
+
+#ifdef DDTEST
+ ErrorF( " BeginStructure %d\n", sId);
+#endif
+
+ /* if renderer idle ignore.... */
+ if (pRend->state == PEXIdle)
+ return Success;
+
+ /*
+ * Push the current ddContext attributes onto the stack and create
+ * a new instance of these attributes.
+ */
+ if (status = PushddContext(pRend)) return(status);
+
+ /* update offset of existing path to count execute structure element */
+ if (pRend->curPath->numObj)
+ ((ddElementRef *)pRend->curPath->pList)[pRend->curPath->numObj-1].offset++;
+
+ /** Add a new element to the cur_path for the new structure **/
+ /* sid is really an id not a handle*/
+ newRef.structure = (diStructHandle)sId;
+ newRef.offset = 0;
+
+ /* puAddToList returns 0 if it's successful, other there's an error */
+ if (puAddToList((ddPointer)&newRef, (ddULONG)1, pRend->curPath))
+ {
+ return (BadAlloc);
+ }
+
+ /* when doing client side picking fake structures must be allocated
+ and the correspondence between their structure handles and IDs
+ saved for later lookup by the appropriate EndPick routine
+ */
+ if ((pRend->state == PEXPicking) && (pRend->pickstr.server == DD_CLIENT)) {
+
+ /* bump up the offset in the current element to simulate ExecStr */
+ curpp = (ddPickPath *)(pRend->pickstr.fakeStrlist)->pList;
+ curpp[(pRend->pickstr.fakeStrlist)->numObj-1].offset++;
+
+ /* allocate a new fake structure and add to both lists */
+ fakeStr = (diStructHandle)xalloc((unsigned long)
+ sizeof(ddStructResource));
+ if (!fakeStr) return (BadAlloc);
+ fakeStr->id = -666;
+ err = CreateStructure(fakeStr);
+ if (err != Success) {
+ xfree((pointer)(fakeStr));
+ return (err);
+ }
+
+ fakeStrpp.structure = fakeStr;
+ fakeStrpp.offset = 0;
+ fakeStrpp.pickid = 0;
+ err = puAddToList((ddPointer) &fakeStrpp, (ddULONG) 1, pRend->pickstr.fakeStrlist);
+ if (err != Success) {
+ xfree((pointer)(fakeStr));
+ return (err);
+ }
+
+ sIDpp.structure = fakeStr;
+ sIDpp.offset = 0;
+ /* Store the supplied structure ID here for retrieval at EndPick */
+ sIDpp.pickid = sId;
+ err = puAddToList((ddPointer) &sIDpp, (ddULONG) 1, pRend->pickstr.sIDlist);
+ if (err != Success) {
+ xfree((pointer)(fakeStr));
+ return (err);
+ }
+
+ }
+ return (Success);
+} /* BeginStructure */
+
+/*++
+ |
+ | Function Name: EndStructure
+ |
+ | Function Description:
+ | Supports the PEXEndStructure request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+EndStructure(pRend)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+/* out */
+{
+ ddpex3rtn PopddContext();
+ ddpex3rtn status;
+ miStructPtr pheader;
+ diStructHandle sh = 0;
+ ddPickPath *strpp;
+ miDDContext *pddc = (miDDContext *) pRend->pDDContext;
+
+
+
+
+#ifdef DDTEST
+ ErrorF( " EndStructure\n");
+#endif
+
+ /* if renderer idle ignore.... */
+ if (pRend->state == PEXIdle)
+ return Success;
+
+ /* if there is no next then BeginStructure has not been
+ called so simply ignore this EndStructure call....
+ */
+ if (pddc->Dynamic->next == NULL)
+ return Success;
+
+ /*
+ * Pop ddContext off stack - retrieve attributes for current structure */
+ if (status = PopddContext(pRend)) return (status);
+
+ /*
+ * could put more intelligence here,
+ * but for now assume everything changes
+ */
+ MI_SET_ALL_CHANGES(pRend);
+ ValidateRenderer(pRend);
+
+ /** Remove the last currentPath element from the renderer **/
+ PU_REMOVE_LAST_OBJ(pRend->curPath);
+
+ if ((pRend->state == PEXPicking) && (pRend->pickstr.server == DD_CLIENT)) {
+
+ /* the fake structure can not be freed until End Picking
+ since otherwise that chunk of memory could be allocated
+ to another client provided sID thus destroying the 1 to 1
+ mapping that the sIDlist counts up, so just remove the info
+ for the structure from the fakeStrlist. The handle and ID
+ must stay on the sID list until after the reply is processed
+ */
+ PU_REMOVE_LAST_OBJ(pRend->pickstr.fakeStrlist);
+ }
+
+ return (Success);
+
+} /* EndStructure */
+
+static void
+set_highlight_colours(pRend, pddc)
+ ddRendererPtr pRend;
+ miDDContext *pddc;
+{
+ pddc->Static.attrs->lineColour = pddc->Static.misc.highlight_colour;
+ pddc->Static.attrs->edgeColour = pddc->Static.misc.highlight_colour;
+ pddc->Static.attrs->markerColour = pddc->Static.misc.highlight_colour;
+ pddc->Static.attrs->surfaceColour = pddc->Static.misc.highlight_colour;
+ pddc->Static.attrs->textColour = pddc->Static.misc.highlight_colour;
+
+ pddc->Static.misc.flags |= POLYLINEGCFLAG;
+ pddc->Static.misc.flags |= EDGEGCFLAG;
+ pddc->Static.misc.flags |= MARKERGCFLAG;
+ pddc->Static.misc.flags |= FILLAREAGCFLAG;
+ pddc->Static.misc.flags |= TEXTGCFLAG;
+ return;
+}
+
+static void
+unset_highlight_colours(pRend, pddc)
+ ddRendererPtr pRend;
+ miDDContext *pddc;
+{
+ ddBitmask tables, namesets, attrs;
+
+ /* not too efficient: ValidateDDContextAttrs does more than
+ * just colours
+ */
+ tables = PEXDynMarkerBundle | PEXDynTextBundle | PEXDynLineBundle
+ | PEXDynInteriorBundle | PEXDynEdgeBundle;
+ namesets = 0;
+ attrs = 0;
+ ValidateDDContextAttrs(pRend, pddc, tables, namesets, attrs);
+ return;
+}
+
+/*++
+ |
+ | Function Name: ValidateFilters
+ |
+ | Function Description:
+ | updates filters flags
+ |
+ | Note(s):
+ |
+ --*/
+
+void
+ValidateFilters(pRend, pddc, namesets)
+ddRendererPtr pRend; /* renderer handle */
+miDDContext *pddc; /* ddPEX attribute structure */
+ddBitmask namesets;
+{
+ ddUSHORT save_flags;
+
+ if ((namesets & PEXDynHighlightNameset) ||
+ (namesets & PEXDynInvisibilityNameset) ||
+ (namesets & PEXDynHighlightNamesetContents) ||
+ (namesets & PEXDynInvisibilityNamesetContents)) {
+
+ save_flags = pddc->Dynamic->filter_flags;
+
+ mi_set_filters(pRend, pddc, namesets);
+
+ if ( (MI_DDC_IS_HIGHLIGHT(pddc)) &&
+ !(save_flags & MI_DDC_HIGHLIGHT_FLAG) )
+ /* just turned on highlighting */
+ set_highlight_colours(pRend, pddc);
+ else if ( (!(MI_DDC_IS_HIGHLIGHT(pddc))) &&
+ (save_flags & MI_DDC_HIGHLIGHT_FLAG) )
+ /* just turned off highlighting */
+ unset_highlight_colours(pRend, pddc);
+
+ MI_DDC_SET_DO_PRIMS(pRend, pddc);
+ }
+}
+
+/*++
+ |
+ | Function Name: ValidateRenderer
+ |
+ | Function Description:
+ | loads executeOC table in renderer correctly and calls
+ | to validate the ddcontext
+ |
+ | Note(s):
+ |
+ --*/
+
+ValidateRenderer(pRend)
+ ddRendererPtr pRend; /* renderer handle */
+{
+ ddpex3rtn ValidateDDContextAttrs();
+
+ miDDContext *pddc = (miDDContext *)pRend->pDDContext;
+ ddBitmask tables, namesets, attrs;
+ extern void inq_last_colour_entry();
+
+ /* load in different executeOCs if needed
+ * can do this here or in ValidateDDContextAttrs as needed
+ * eg, if there are multiple procs in a set for an oc (different
+ * ones for hollow fill areas and solid ones), then load
+ * them here or in ValidateDDContextAttrs when the attribute
+ * controlling it changes
+ */
+
+ /* set highlight colour if necessary */
+ if (pRend->tablesChanges & (PEXDynColourTable | PEXDynColourTableContents))
+ inq_last_colour_entry(pRend->lut[PEXColourLUT], &pddc->Static.misc.highlight_colour);
+
+ /* validate the attributes */
+ if (pRend->state == PEXRendering)
+ {
+ /* validate only dynamic attrs */
+ tables = pRend->tablesChanges & ~pRend->tablesMask;
+ namesets = pRend->namesetsChanges & ~pRend->namesetsMask;
+ attrs = pRend->attrsChanges & ~pRend->attrsMask;
+ ValidateFilters(pRend, pddc, namesets);
+ ValidateDDContextAttrs(pRend, pddc, tables, namesets, attrs);
+ pRend->tablesChanges &= (~tables);
+ pRend->namesetsChanges &= (~namesets);
+ pRend->attrsChanges &= (~attrs);
+ } else
+ {
+ /* validate all attrs */
+ tables = pRend->tablesChanges;
+ namesets = pRend->namesetsChanges;
+ attrs = pRend->attrsChanges;
+ ValidateDDContextAttrs(pRend, pddc, tables, namesets, attrs);
+ ValidateFilters(pRend, pddc, namesets);
+ /* reset change masks */
+ MI_ZERO_ALL_CHANGES(pRend);
+ }
+}
+
+/*++
+ |
+ | Function Name: BeginPicking
+ |
+ | Function Description:
+ | Sets up the pipeline to do Picking.
+ |
+ | Note(s): This is a copy of BeginRendering with extraneous rendering
+ | stuff removed. Wherever, the code has been removed, comments
+ | have been placed to identify the removals.
+ |
+ --*/
+
+ddpex3rtn
+BeginPicking(pRend, pPM)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ diPMHandle pPM; /* pick measure */
+/* out */
+{
+ miPickMeasureStr *ppm = (miPickMeasureStr *) pPM->deviceData;
+ miDDContext *pddc = (miDDContext *) pRend->pDDContext;
+ DrawablePtr pDrawable = pRend->pDrawable;
+ ddPCAttr *ppca;
+ ddFLOAT inv_xform[4][4];
+
+#ifdef DDTEST
+ ErrorF( " BeginPicking\n");
+#endif
+
+ /* set device info needed for picking */
+ pddc->Static.pick.type = ppm->type;
+ pddc->Static.pick.status = ppm->status;
+ switch (ppm->type)
+ {
+ case PEXPickDeviceDC_HitBox:
+ pddc->Static.pick.data_rec.dc_data_rec =
+ ppm->data_rec.dc_data_rec;
+ pddc->Static.pick.input_rec.dc_hit_box =
+ ppm->input_rec.dc_hit_box;
+ break;
+
+ case PEXPickDeviceNPC_HitVolume:
+ pddc->Static.pick.data_rec.npc_data_rec =
+ ppm->data_rec.npc_data_rec;
+ pddc->Static.pick.input_rec.npc_hit_volume =
+ ppm->input_rec.npc_hit_volume;
+ break;
+ }
+
+ MINS_EMPTY_NAMESET(pddc->Static.pick.inclusion);
+ MINS_EMPTY_NAMESET(pddc->Static.pick.exclusion);
+ if (ppm->incl_handle) {
+ miNSHeader *pns = (miNSHeader *)ppm->incl_handle->deviceData;
+ MINS_COPY_NAMESET(pns->names, pddc->Static.pick.inclusion);
+ }
+ if (ppm->excl_handle) {
+ miNSHeader *pns = (miNSHeader *)ppm->excl_handle->deviceData;
+ MINS_COPY_NAMESET(pns->names, pddc->Static.pick.exclusion);
+ }
+
+/* load picking procs into executeOCs */
+
+ memcpy( (char *)pRend->executeOCs,
+ (char *)PickExecuteOCTable,
+ sizeof(ocTableType)*OCTABLE_LENGTH);
+
+ pRend->render_mode = MI_REND_PICKING;
+
+ /* make sure this gets initialized for every pick */
+ pRend->pickstr.more_hits = PEXNoMoreHits;
+
+
+ /*
+ * Reinitialize level 1 procedure jump table for PICKING !
+ */
+ memcpy( (char *)pddc->Static.RenderProcs,
+ (char *)PickPrimitiveTable,
+ sizeof(RendTableType) * RENDER_TABLE_LENGTH);
+
+ init_pipeline(pRend, pDrawable);
+
+ /*
+ * Determine the npc -> dc viewport transform
+ */
+ miBldViewport_xform( pRend, pDrawable, pddc->Static.misc.viewport_xform, pddc );
+
+ /* Compute the inverse of the viewport transform to be used to */
+ /* convert DC_HitBoxes to NPC_HitVolumes. */
+
+ memcpy( (char *)inv_xform,
+ (char *)pddc->Static.misc.viewport_xform, 16*sizeof(ddFLOAT));
+ miMatInverse (inv_xform);
+ memcpy( (char *)pddc->Static.misc.inv_vpt_xform,
+ (char *) inv_xform, 16*sizeof(ddFLOAT));
+
+ /* Now, clear out the viewport transform computed above to identity */
+ /* since we are PICKING, and we do not need this to go to final ddx */
+ /* space. THIS IS IMPORTANT SINCE WE WILL BE USING THE LEVEL 2 REND-*/
+ /* ERING ROUTINES TO DO TRANSFORMATIONS AND CLIPPING. ONLY LEVEL 1 */
+ /* PICKING ROUTINES WILL ACTUALLY DO THE PICK HIT TEST IN CC. THUS */
+ /* BY MAKING THE viewport transform IDENTITY WE WILL STAY IN CC. */
+
+ memcpy( (char *) pddc->Static.misc.viewport_xform,
+ (char *) ident4x4, 16 * sizeof(ddFLOAT));
+
+ /* Clear out the cc_to_dc_xform also, since we will not be going to DC */
+
+ memcpy( (char *) pddc->Dynamic->cc_to_dc_xform,
+ (char *) ident4x4, 16 * sizeof(ddFLOAT));
+
+ /* Mark as invalid appropriate inverse transforms in dd context */
+ pddc->Static.misc.flags |= (INVTRMCTOWCXFRMFLAG | INVTRWCTOCCXFRMFLAG |
+ INVTRMCTOCCXFRMFLAG | INVTRCCTODCXFRMFLAG |
+ INVVIEWXFRMFLAG);
+
+ /* Mark as invalid any transform dependant fields in ddContext */
+ pddc->Static.misc.flags |= (MCVOLUMEFLAG | CC_DCUEVERSION);
+
+ /*
+ * Computation of the composite mc -> dc transform has been REMOVED.
+ */
+
+ /* do double buffering stuff */
+ /* do hlhsr stuff */
+
+ pRend->state = PEXPicking;
+
+ return (Success);
+}
+
+/*++
+ |
+ | Function Name: EndPicking
+ |
+ | Function Description:
+ | Handles the stuff to be done after a Pick traversal.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+EndPicking(pRend)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+/* out */
+{
+/* Locals */
+ miDDContext *pddc = (miDDContext *)(pRend->pDDContext);
+ ddPickPath *strpp;
+ diStructHandle sh = 0;
+ int i;
+
+
+#ifdef DDTEST
+ ErrorF( " EndPicking\n");
+#endif
+
+ if (pRend->immediateMode == TRUE) {
+ /* empty listoflist for Pick All
+ this assumes the individual pick paths lists that this
+ pointed to have already been deleted by the EndPickAll routine
+ */
+ PU_EMPTY_LIST(pRend->pickstr.list);
+
+ /* free all but the first the fake structure
+ it should always be there to support ROCs
+ */
+ strpp = (ddPickPath *)(pRend->pickstr.sIDlist)->pList;
+ for (i = 1; i < (pRend->pickstr.sIDlist)->numObj; i++) {
+ sh = strpp[i].structure;
+ DeleteStructure(sh, sh->id);
+ }
+
+ (pRend->pickstr.sIDlist)->numObj = 1;
+ }
+
+ pRend->state = PEXIdle;
+
+ pRend->render_mode = MI_REND_DRAWING;
+
+ /* copy the initial oc functions to the OC table */
+
+ memcpy( (char *)pRend->executeOCs,
+ (char *)InitExecuteOCTable,
+ sizeof(ocTableType)*OCTABLE_LENGTH);
+
+ /*
+ * Reinitialize level 1 procedure jump table for Rendering !
+ */
+ memcpy( (char *)pddc->Static.RenderProcs,
+ (char *)RenderPrimitiveTable,
+ sizeof(RendTableType) * RENDER_TABLE_LENGTH);
+
+ return (Success);
+}
+
+/*++
+ |
+ | Function Name: InquirePickStatus
+ |
+ | Function Description:
+ | returns current pick status
+ |
+ | Note(s):
+
+ |
+ --*/
+
+/*
+#define PEX_SI_FAKE_PICK
+*/
+#ifdef PEX_SI_FAKE_PICK
+/*dummy proc to use to fake hit:
+ hit occurs when traversal depth = 3, structure offset = 3,
+ current pick id = 4
+ need p_trav_state for this, but p_trav_state will not be a
+ parameter when real picking is done
+*/
+InquirePickStatus(pRend, pStatus, p_trav_state)
+ ddRendererPtr pRend;
+ ddUSHORT *pStatus;
+ miTraverserState *p_trav_state;
+{
+ if ( (p_trav_state->max_depth == 3) &&
+ (((ddElementRef *)pRend->curPath-> pList)[pRend->curPath->numObj - 1].offset == 3) &&
+ ( ((miDDContext *)pRend->pDDContext)->Dynamic->pPCAttr->pickId == 4) )
+ *pStatus = PEXOk;
+ else
+ *pStatus = PEXNoPick;
+ return;
+}
+#else
+
+void
+InquirePickStatus(pRend, pStatus, p_trav_state)
+ ddRendererPtr pRend;
+ ddUSHORT *pStatus;
+{
+ miDDContext *pddc = (miDDContext *) pRend->pDDContext;
+
+ *pStatus = pddc->Static.pick.status;
+ pddc->Static.pick.status = PEXNoPick;
+ return;
+}
+#endif
+
+/*++
+ |
+ | Function Name: BeginSearching
+ |
+ | Function Description:
+ | Sets up the pipeline to do spatial search
+ |
+ | Note(s): This is a copy of BeginRendering with extraneous rendering
+ | stuff removed. Wherever, the code has been removed, comments
+ | have been placed to identify the removals.
+ |
+ --*/
+
+ddpex3rtn
+BeginSearching(pRend, pSC)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+ ddSCStr *pSC; /* search context */
+/* out */
+{
+ miDDContext *pddc = (miDDContext *) pRend->pDDContext;
+ DrawablePtr pDrawable = pRend->pDrawable;
+ ddNSPair *pPairs;
+ miNSHeader *pns;
+ register int i;
+
+#ifdef DDTEST
+ ErrorF( " BeginSearching\n");
+#endif
+
+ /* set device info needed for searching */
+ pddc->Static.search.status = PEXNotFound;
+ pddc->Static.search.position = pSC->position;
+ pddc->Static.search.distance = pSC->distance;
+ pddc->Static.search.modelClipFlag = pSC->modelClipFlag;
+
+ MINS_EMPTY_NAMESET(pddc->Static.search.norm_inclusion);
+ MINS_EMPTY_NAMESET(pddc->Static.search.norm_exclusion);
+ MINS_EMPTY_NAMESET(pddc->Static.search.invert_inclusion);
+ MINS_EMPTY_NAMESET(pddc->Static.search.invert_exclusion);
+
+ if (pSC->normal.numPairs) {
+ pPairs = pSC->normal.pPairs;
+ for (i=0; i<pSC->normal.numPairs; i++, pPairs++ ) {
+
+ if (pPairs->incl) {
+ pns = (miNSHeader *)pPairs->incl->deviceData;
+ MINS_OR_NAMESETS(pns->names, pddc->Static.search.norm_inclusion);
+ }
+ if (pPairs->excl) {
+ pns = (miNSHeader *)pPairs->excl->deviceData;
+ MINS_OR_NAMESETS(pns->names, pddc->Static.search.norm_exclusion);
+ }
+ }
+ }
+ if (pSC->inverted.numPairs) {
+ pPairs = pSC->inverted.pPairs;
+ for (i=0; i<pSC->inverted.numPairs; i++, pPairs++ ) {
+
+ if (pPairs->incl) {
+ pns = (miNSHeader *)pPairs->incl->deviceData;
+ MINS_OR_NAMESETS(pns->names, pddc->Static.search.invert_inclusion);
+ }
+ if (pPairs->excl) {
+ pns = (miNSHeader *)pPairs->excl->deviceData;
+ MINS_OR_NAMESETS(pns->names, pddc->Static.search.invert_exclusion);
+ }
+ }
+ }
+
+ /* load searching procs into executeOCs */
+
+ memcpy( (char *)pRend->executeOCs,
+ (char *)SearchExecuteOCTable,
+ sizeof(ocTableType)*OCTABLE_LENGTH);
+
+ /*
+ * Reinitialize level 1 procedure jump table for Searching.
+ * Note that we use the same table as Picking.
+ */
+ memcpy( (char *)pddc->Static.RenderProcs,
+ (char *)PickPrimitiveTable,
+ sizeof(RendTableType) * RENDER_TABLE_LENGTH);
+
+ /* Set the model clipping flag to value in search context
+ resource */
+ pddc->Dynamic->pPCAttr->modelClip = pSC->modelClipFlag;
+
+ pRend->render_mode = MI_REND_SEARCHING;
+
+ init_pipeline(pRend, pDrawable);
+
+ /*
+ * Since searching is done in world coordinate space, we need NOT
+ * compute any of the rest of the matrices. They must all be set
+ * to identity.
+ */
+
+ memcpy( (char *) pddc->Static.misc.viewport_xform,
+ (char *) ident4x4, 16 * sizeof(ddFLOAT));
+
+ memcpy( (char *) pddc->Dynamic->wc_to_npc_xform,
+ (char *) ident4x4, 16 * sizeof(ddFLOAT));
+
+ memcpy( (char *) pddc->Dynamic->mc_to_npc_xform,
+ (char *) ident4x4, 16 * sizeof(ddFLOAT));
+
+ memcpy( (char *) pddc->Dynamic->wc_to_cc_xform,
+ (char *) ident4x4, 16 * sizeof(ddFLOAT));
+
+ memcpy( (char *) pddc->Dynamic->cc_to_dc_xform,
+ (char *) ident4x4, 16 * sizeof(ddFLOAT));
+
+ memcpy( (char *) pddc->Dynamic->mc_to_cc_xform,
+ (char *) ident4x4, 16 * sizeof(ddFLOAT));
+
+ memcpy( (char *) pddc->Dynamic->mc_to_dc_xform,
+ (char *) ident4x4, 16 * sizeof(ddFLOAT));
+
+ memcpy( (char *) pddc->Dynamic->npc_to_cc_xform,
+ (char *) ident4x4, 16 * sizeof(ddFLOAT));
+
+ /* Mark as invalid appropriate inverse transforms in dd context */
+ pddc->Static.misc.flags |= (INVTRMCTOWCXFRMFLAG | INVTRWCTOCCXFRMFLAG |
+ INVTRMCTOCCXFRMFLAG | INVTRCCTODCXFRMFLAG |
+ INVVIEWXFRMFLAG);
+
+ /* Mark as invalid any transform dependant fields in ddContext */
+ pddc->Static.misc.flags |= (MCVOLUMEFLAG | CC_DCUEVERSION);
+
+ /*
+ * Computation of the composite mc -> dc transform has been REMOVED.
+ */
+
+ /* do double buffering stuff */
+ /* do hlhsr stuff */
+
+ pRend->state = PEXRendering;
+
+ return (Success);
+}
+
+/*++
+ |
+ | Function Name: EndSearching
+ |
+ | Function Description:
+ | Handles the stuff to be done after a search traversal.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex3rtn
+EndSearching(pRend)
+/* in */
+ ddRendererPtr pRend; /* renderer handle */
+/* out */
+{
+
+#ifdef DDTEST
+ ErrorF( " EndSearching\n");
+#endif
+
+ pRend->state = PEXIdle;
+
+ pRend->render_mode = MI_REND_DRAWING;
+ /* copy the initial oc functions to the OC table */
+ memcpy( (char *)pRend->executeOCs,
+ (char *)InitExecuteOCTable,
+ sizeof(ocTableType)*OCTABLE_LENGTH);
+
+ return (Success);
+}
+
+/*++
+ |
+ | Function Name: InquireSearchStatus
+ |
+ | Function Description:
+ | returns current spatial search status
+ |
+ | Note(s):
+ |
+ --*/
+
+void
+InquireSearchStatus(pRend, pStatus)
+ ddRendererPtr pRend;
+ ddUSHORT *pStatus; /* PEXFound or PEXNotFound */
+{
+ miDDContext *pddc = (miDDContext *) pRend->pDDContext;
+
+ *pStatus = pddc->Static.search.status;
+ return;
+}
+
+
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level3/miRndrPick.c b/xc/programs/Xserver/PEX5/ddpex/mi/level3/miRndrPick.c
new file mode 100644
index 000000000..d3e7358fd
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level3/miRndrPick.c
@@ -0,0 +1,502 @@
+/* $TOG: miRndrPick.c /main/12 1998/02/10 12:43:20 kaleb $ */
+
+/************************************************************
+
+Copyright 1992, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+******************************************************************/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level3/miRndrPick.c,v 1.7 1998/10/04 09:34:37 dawes Exp $ */
+
+#include "miLUT.h"
+#include "ddpex3.h"
+#include "PEXproto.h"
+#include "PEXprotost.h"
+#include "pexExtract.h"
+#include "PEXErr.h"
+#include "pexUtils.h"
+#include "pixmap.h"
+#include "windowstr.h"
+#include "regionstr.h"
+#include "miscstruct.h"
+#include "miRender.h"
+#include "miStruct.h"
+#include "miStrMacro.h"
+#include "miWks.h"
+#include "ddpex4.h"
+#include "pexos.h"
+
+
+/* External variables used */
+
+extern void mi_set_filters();
+extern void miMatMult();
+extern ddpex3rtn miBldViewport_xform();
+extern ddpex3rtn miBldCC_xform();
+extern ocTableType ParseOCTable[];
+extern void (*DestroyOCTable[])();
+extern ocTableType InitExecuteOCTable[];
+extern ocTableType PickExecuteOCTable[];
+extern ocTableType SearchExecuteOCTable[];
+extern RendTableType RenderPrimitiveTable[];
+extern RendTableType PickPrimitiveTable[];
+
+
+/* Level III Renderer Pick Procedures */
+
+/*++
+|
+| Function Name: CreatePseudoPickMeasure
+|
+| Function Description:
+| Create a Pick Measure for Renderer Picking use
+|
+| Note(s):
+|
+--*/
+
+ddpex3rtn
+CreatePseudoPickMeasure( pRend)
+ddRendererPtr pRend; /* renderer handle */
+{
+ register miPickMeasureStr *ppm;
+
+ ppm = (miPickMeasureStr *) xalloc(sizeof(miPickMeasureStr));
+ if (!ppm) return (BadAlloc);
+
+ ppm->path = puCreateList(DD_PICK_PATH);
+ if (!ppm->path) {
+ xfree(ppm);
+ return (BadAlloc);
+ }
+
+ /* initialize pointers to NULL values */
+ ppm->pWks = 0;
+ /* initialize type to an out of range value */
+ ppm->type = -1;
+ ppm->status = PEXNoPick;
+ ppm->pathOrder = PEXTopFirst;
+ ppm->incl_handle = 0;
+ ppm->excl_handle = 0;
+ ppm->devPriv = (ddPointer) NULL;
+
+ (pRend->pickstr.pseudoPM)->deviceData = (ddPointer) ppm;
+ return(Success);
+}
+
+
+/*++
+|
+| Function Name: ChangePseudoPickMeasure
+|
+| Function Description:
+| Change a Pick Measure for Renderer Picking use
+|
+| Note(s):
+|
+--*/
+
+ddpex3rtn
+ChangePseudoPickMeasure( pRend, pRec)
+ddRendererPtr pRend; /* renderer handle */
+ddPickRecord *pRec; /* PickRecord */
+{
+ register miPickMeasureStr *ppm;
+
+ ppm = (miPickMeasureStr *) (pRend->pickstr.pseudoPM)->deviceData;
+
+ if (!ppm->path) {
+ ppm->path = puCreateList(DD_PICK_PATH);
+ if (!ppm->path) {
+ xfree(ppm);
+ return (BadAlloc);
+ }
+ } else {
+ if (puCopyList(pRend->pickStartPath, ppm->path)) {
+ puDeleteList(ppm->path);
+ xfree(ppm);
+ return (BadAlloc);
+ }
+ }
+ ppm->incl_handle = pRend->ns[DD_PICK_INCL_NS];
+ ppm->excl_handle = pRend->ns[DD_PICK_EXCL_NS];
+
+ if (ppm->incl_handle)
+ UpdateNSRefs( ppm->incl_handle, (diResourceHandle) NULL,
+ PICK_RESOURCE, ADD);
+
+ if (ppm->excl_handle)
+ UpdateNSRefs( ppm->excl_handle, (diResourceHandle) NULL,
+ PICK_RESOURCE, ADD);
+
+ /* now store the pick record */
+ ppm->type = pRec->pickType;
+ switch (ppm->type) {
+ case PEXPickDeviceDC_HitBox:
+ memcpy( (char *)&(ppm->input_rec.dc_hit_box),
+ (char *)&(pRec->hit_box.DC_HitBox),
+ sizeof(pexPD_DC_HitBox));
+ break;
+
+ case PEXPickDeviceNPC_HitVolume:
+ memcpy( (char *)&(ppm->input_rec.npc_hit_volume),
+ (char *)&(pRec->hit_box.NPC_HitVolume),
+ sizeof(pexPD_NPC_HitVolume));
+ break;
+ }
+
+
+ ppm->status = PEXNoPick;
+
+ return(Success);
+}
+
+ddpex3rtn
+EndPickOne( pRend, pBuffer, numPickElRefs, pickStatus, betterPick)
+/* in */
+ddRendererPtr pRend; /* renderer handle */
+/* out */
+ddBufferPtr pBuffer; /* list of pick element ref */
+ddULONG *numPickElRefs;
+ddUSHORT *pickStatus;
+ddUSHORT *betterPick;
+{
+ ddpex3rtn err = Success;
+ miPickMeasureStr *ppm;
+ int numbytes, i, j;
+ ddPickPath *per;
+ pexPickElementRef *dest;
+ ddPickPath *sIDpp;
+
+ ppm = (miPickMeasureStr *) (pRend->pickstr.pseudoPM)->deviceData;
+ *numPickElRefs = 0;
+ *pickStatus = ppm->status;
+ *betterPick = 0;
+
+ if (ppm->status == PEXOk && ppm->path) { /* we have a pick */
+
+ /* send back the number of objects */
+ *numPickElRefs = ppm->path->numObj;
+
+ /* Now, tack on the list of Element Refs to the back of the reply
+ Note that we do NOT include the length of the list.
+ The length is found in the reply itself.
+ */
+ numbytes = sizeof(ddPickPath) * ppm->path->numObj;
+
+ PU_CHECK_BUFFER_SIZE(pBuffer, numbytes);
+ /* Copy the Pick Path to the buffer */
+ for (per = (ddPickPath*) ppm->path->pList,
+ dest = (pexPickElementRef*) pBuffer->pBuf, i=0;
+ i < ppm->path->numObj; per++, dest++, i++) {
+
+ /* if returned structure handle is in the sIDlist
+ then the pick was on a path below an immediate OC
+ so return the struct id the user sent over in the BeginPick
+ request, otherwise return the resource ID as normal
+ */
+ sIDpp = (ddPickPath *) (pRend->pickstr.sIDlist)->pList;
+ for (j = 0; j < (pRend->pickstr.sIDlist)->numObj; j++, sIDpp++) {
+ if ((diStructHandle)(per->structure) == sIDpp->structure) {
+ /* this is CORRECT, pickid is used to store the client
+ provided structure id, yes it is a kludge...
+ */
+ dest->sid = sIDpp->pickid;
+ break;
+ }
+ else
+ dest->sid = ((ddStructResource*)(per->structure))->id;
+ }
+ dest->offset = per->offset;
+ dest->pickid = per->pickid;
+ }
+
+ pBuffer->dataSize = numbytes; /* tells dipex how long the reply is */
+ }
+
+ if (ppm->path) {
+ puDeleteList(ppm->path);
+ ppm->path = NULL;
+ }
+
+ if (ppm->incl_handle)
+ UpdateNSRefs( ppm->incl_handle, (diResourceHandle) NULL,
+ PICK_RESOURCE, ADD);
+
+ if (ppm->excl_handle)
+ UpdateNSRefs( ppm->excl_handle, (diResourceHandle) NULL,
+ PICK_RESOURCE, ADD);
+
+
+ return(err);
+}
+
+
+ddpex3rtn
+PickOne( pRend)
+/* in */
+ddRendererPtr pRend; /* renderer handle */
+{
+ ddpex3rtn err = Success;
+ ddElementRange range;
+ miStructPtr pstruct;
+ miTraverserState trav_state;
+ diPMHandle pPM = (diPMHandle) NULL;
+ ddULONG offset1, offset2;
+ diStructHandle psh = pRend->pickstr.strHandle;
+
+
+ pstruct = (miStructPtr) (pRend->pickstr.strHandle)->deviceData;
+
+
+ /* now call the traverser to traverse this structure */
+ /* set exec_str_flag */
+ trav_state.exec_str_flag = ES_YES;
+ trav_state.p_curr_pick_el = (ddPickPath *) NULL;
+ trav_state.p_curr_sc_el = (ddElementRef *) NULL;
+ trav_state.max_depth = 0;
+ trav_state.pickId = 0;
+ trav_state.ROCoffset = 0;
+ pPM = pRend->pickstr.pseudoPM;
+
+ offset1 = 1;
+ offset2 = MISTR_NUM_EL(pstruct);
+
+ err = traverser(pRend, psh, offset1, offset2, pPM, NULL, &trav_state);
+
+ return(err);
+}
+
+ddpex3rtn
+EndPickAll( pRend, pBuffer)
+/* in */
+ddRendererPtr pRend; /* renderer handle */
+/* out */
+ddBufferPtr pBuffer; /* list of pick element ref */
+{
+ ddpex3rtn err = Success;
+
+ pexEndPickAllReply *reply = (pexEndPickAllReply *)(pBuffer->pHead);
+ int i, j, k, numbytes = 0, pbytes, numObj;
+ listofObj *list;
+ listofObj **listofp;
+ ddPickPath *pp, *sIDpp;
+ ddPointer pplist;
+ ddPickElementRef ref;
+ miPickMeasureStr *ppm;
+
+ ppm = (miPickMeasureStr *) (pRend->pickstr.pseudoPM)->deviceData;
+
+ reply->numPicked = (pRend->pickstr.list)->numObj;
+ reply->pickStatus = ((pRend->pickstr.list)->numObj) ?1:0;
+ reply->morePicks = pRend->pickstr.more_hits;
+
+ numObj = (pRend->pickstr.list)->numObj;
+ listofp = (listofObj **)(pRend->pickstr.list)->pList;
+
+ /* convert the pick path to a pick element ref for return */
+ for (i = 0; i < numObj; i++) {
+ list = listofp[0];
+ pbytes = list->numObj * sizeof(ddPickElementRef);
+ numbytes += pbytes + sizeof(CARD32);
+ PU_CHECK_BUFFER_SIZE(pBuffer, numbytes);
+ PACK_CARD32(list->numObj, pBuffer->pBuf);
+ pplist = list->pList;
+
+ /* now convert each pick path to a pick element ref */
+ /* and pack it into the reply buffer */
+ for (j = 0; j < list->numObj; j++) {
+ pp = (ddPickPath *) pplist;
+ pplist = (ddPointer)(pp+1);
+ sIDpp = (ddPickPath *) (pRend->pickstr.sIDlist)->pList;
+ for (k = 0; k < (pRend->pickstr.sIDlist)->numObj; k++, sIDpp++) {
+ if ((diStructHandle)(pp->structure) == sIDpp->structure) {
+ /* this is CORRECT, pickid is used to store the client
+ provided structure id, yes it is a kludge...
+ */
+ ref.sid = sIDpp->pickid;
+ break;
+ }
+ else
+ ref.sid = ((ddStructResource *)(pp->structure))->id;
+ }
+ ref.offset = pp->offset;
+ ref.pickid = pp->pickid;
+ PACK_STRUCT(ddPickElementRef, &ref, pBuffer->pBuf);
+ }
+
+ /* remove the list from the list of list */
+ puRemoveFromList( (ddPointer) &list, pRend->pickstr.list);
+
+ /* if there are more hits when doing a server side pick all
+ save the last hit into the start path
+ */
+ if ((pRend->pickstr.more_hits == PEXMoreHits) && (i == numObj-1)
+ && (pRend->pickstr.server == DD_SERVER))
+ pRend->pickStartPath = list;
+ else
+ puDeleteList( list);
+
+ }
+
+ /* if there were no more hits empty the pickStartPath */
+ if (pRend->pickstr.more_hits == PEXNoMoreHits) {
+ PU_EMPTY_LIST(pRend->pickStartPath);
+ }
+
+ pRend->pickstr.more_hits = PEXNoMoreHits;
+ pBuffer->dataSize = numbytes;
+
+ if (ppm->incl_handle)
+ UpdateNSRefs( ppm->incl_handle, (diResourceHandle) NULL,
+ PICK_RESOURCE, ADD);
+
+ if (ppm->excl_handle)
+ UpdateNSRefs( ppm->excl_handle, (diResourceHandle) NULL,
+ PICK_RESOURCE, ADD);
+
+
+ return(err);
+}
+
+
+ddpex3rtn
+PickAll( pRend)
+/* in */
+ddRendererPtr pRend; /* renderer handle */
+{
+ ddpex3rtn err = Success;
+ miTraverserState trav_state;
+ ddULONG offset1, offset2, numberOCs;
+ diStructHandle pstruct = 0;
+ miStructPtr pheader;
+ ddPickPath *pp;
+ diPMHandle pPM = (diPMHandle) NULL;
+ ddpex3rtn ValidatePickPath();
+
+ if (!pRend->pickStartPath) return (PEXERR(PEXPathError));
+ err = ValidatePickPath(pRend->pickStartPath);
+ if (err != Success) return(err);
+
+ /* now call the traverser to traverse this structure */
+ /* set exec_str_flag */
+ trav_state.exec_str_flag = ES_FOLLOW_PICK;
+ trav_state.p_curr_pick_el = (ddPickPath *) pRend->pickStartPath->pList ;
+ trav_state.p_curr_sc_el = (ddElementRef *) NULL;
+ trav_state.max_depth = 0;
+ trav_state.pickId = 0;
+ trav_state.ROCoffset = 0;
+ pPM = pRend->pickstr.pseudoPM;
+
+ pp = (ddPickPath *) pRend->pickStartPath->pList ;
+ pstruct = pp->structure;
+ pheader = (miStructPtr) pstruct->deviceData;
+
+ offset1 = 1;
+ offset2 = MISTR_NUM_EL(pheader);
+
+ err = traverser(pRend, pstruct, offset1, offset2, pPM, NULL, &trav_state);
+
+ return(err);
+}
+
+ddpex3rtn
+AddPickPathToList( pRend, depth, path)
+ddRendererPtr pRend; /* renderer handle */
+int depth; /* pick path depth */
+miPPLevel *path; /* the path */
+{
+ listofObj *list;
+ int i, err;
+ ddPickPath *patharray;
+
+
+ /* dont know what this is supposed to do */
+ if ((pRend->pickstr.list)->numObj >= pRend->pickstr.max_hits) {
+ pRend->pickstr.more_hits = PEXMoreHits;
+ return;
+ }
+ else pRend->pickstr.more_hits = PEXNoMoreHits;
+
+ /* allocate space to store path while reversing */
+ patharray = (ddPickPath *) xalloc(depth * sizeof(ddPickPath));
+
+ /* create list to place the path into */
+ list = puCreateList(DD_PICK_PATH);
+
+ /* traverse the list from bottom up and copy into temp store */
+ for (i = 0; i < depth; i++){
+ patharray[i] = path->pp;
+ path = path->up;
+ }
+
+ /* now store the path from top down */
+ for (i = depth-1; i >= 0; i--){
+ err = puAddToList((ddPointer) &patharray[i], (ddULONG) 1, list);
+ if (err != Success) return(err);
+ }
+
+ xfree(patharray);
+
+ err = puAddToList( (ddPointer) &list, (ddULONG) 1, pRend->pickstr.list);
+ if (err != Success) return(err);
+
+ if ((pRend->pickstr.send_event) &&
+ ((pRend->pickstr.list)->numObj == pRend->pickstr.max_hits))
+ err = PEXMaxHitsReachedNotify( pRend->pickstr.client, pRend->rendId);
+
+ return(err);
+}
+
+ddpex3rtn
+ValidatePickPath(pPath)
+ listofObj *pPath;
+{
+ miGenericElementPtr p_element;
+ diStructHandle pStruct, pNextStruct;
+ miStructPtr pstruct;
+ ddULONG offset;
+ int i;
+ ddPickPath *pPickPath;
+
+
+ pPickPath = (ddPickPath *) pPath->pList;
+ pNextStruct = pPickPath->structure;
+
+ for (i = pPath->numObj; i > 0; i--, pPickPath++) {
+ pStruct = pPickPath->structure;
+ if (pNextStruct != pStruct) return (PEXERR(PEXPathError));
+
+ pstruct = (miStructPtr) pStruct->deviceData;
+
+ offset = pPickPath->offset;
+ if (offset > MISTR_NUM_EL(pstruct)) return (PEXERR(PEXPathError));
+
+ /* dont bother with the leaves */
+ if (i == 1) break;
+
+ MISTR_FIND_EL(pstruct, offset, p_element);
+
+ if (MISTR_EL_TYPE(p_element) != PEXOCExecuteStructure)
+ return (PEXERR(PEXPathError));
+
+ pNextStruct = (diStructHandle) MISTR_GET_EXSTR_STR(p_element);
+ }
+ return (Success);
+}
+
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level4/Imakefile b/xc/programs/Xserver/PEX5/ddpex/mi/level4/Imakefile
new file mode 100644
index 000000000..2d81ad09d
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level4/Imakefile
@@ -0,0 +1,82 @@
+XCOMM
+XCOMM $XConsortium: Imakefile /main/11 1996/09/28 16:54:25 rws $
+XCOMM $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level4/Imakefile,v 3.11 1999/07/04 06:38:31 dawes Exp $
+XCOMM
+XCOMM
+XCOMM Copyright 1989, 1990, 1991 by Sun Microsystems, Inc. and the X Consortium
+XCOMM
+XCOMM All Rights Reserved
+XCOMM
+XCOMM Permission to use, copy, modify, and distribute this software and its
+XCOMM documentation for any purpose and without fee is hereby granted,
+XCOMM provided that the above copyright notice appear in all copies and that
+XCOMM both that copyright notice and this permission notice appear in
+XCOMM supporting documentation, and that the names of Sun Microsystems
+XCOMM or the X Consortium not be used in advertising or publicity
+XCOMM pertaining to distribution of the software without specific, written
+XCOMM prior permission.
+XCOMM
+XCOMM SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+XCOMM INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+XCOMM EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+XCOMM CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+XCOMM USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+XCOMM OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+XCOMM PERFORMANCE OF THIS SOFTWARE.
+
+#define IHaveModules
+#include <Server.tmpl>
+
+#ifndef PexDdpexCDebugFlags
+#define PexDdpexCDebugFlags ServerCDebugFlags
+#endif
+
+XCOMM -D defines for ddpex:
+XCOMM DDTEST turns on some fprintf(stderr...)s for debugging
+
+ DEFINES = PexDdpexDefines
+EXT_DEFINES = ExtensionDefines
+DEPEND_DEFINES = $(EXT_DEFINES)
+CDEBUGFLAGS = PexDdpexCDebugFlags
+
+ PEXSERVINC = ../../../include
+DDPEXINCLUDE = ../include
+
+INCLUDES = -I. \
+ -I$(DDPEXINCLUDE) \
+ -I$(XINCLUDESRC) \
+ -I$(PEXSERVINC) \
+ -I$(SERVERSRC)/include
+
+SRCS = miPick.c \
+ miSC.c \
+ miStruct.c \
+ miTraverse.c \
+ miWks.c \
+ miDynamics.c \
+ css_plain.c \
+ css_ex_str.c \
+ css_tbls.c
+
+OBJS = miPick.o \
+ miSC.o \
+ miStruct.o \
+ miTraverse.o \
+ miWks.o \
+ miDynamics.o \
+ css_plain.o \
+ css_ex_str.o \
+ css_tbls.o
+
+ModuleObjectRule()
+
+SubdirLibraryRule($(OBJS))
+
+NormalLibraryTarget(ddpex4,$(OBJS))
+
+LintLibraryTarget(dp4,$(SRCS))
+NormalLintTarget($(SRCS))
+
+SpecialCObjectRule(miWks,$(ICONFIGFILES),$(EXT_DEFINES))
+
+DependTarget()
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level4/css_ex_str.c b/xc/programs/Xserver/PEX5/ddpex/mi/level4/css_ex_str.c
new file mode 100644
index 000000000..285f86f1f
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level4/css_ex_str.c
@@ -0,0 +1,309 @@
+/* $TOG: css_ex_str.c /main/3 1998/02/10 12:43:24 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level4/css_ex_str.c,v 1.8 1999/01/31 12:21:28 dawes Exp $ */
+/*
+ * this file contains the element handling procedures for
+ * the execute structure element. It is stored in PEX format
+ * but needs special handling
+ */
+
+#include "ddpex.h"
+#include "miStruct.h"
+#include "miStrMacro.h"
+#include "pexUtils.h"
+#include "pexos.h"
+
+
+extern ocTableType ParseOCTable[];
+extern ocTableType CopyOCTable[];
+extern ocTableType InquireOCTable[];
+
+extern void miRemoveWksFromAppearLists();
+extern int miAddWksToAppearLists();
+extern ddpex4rtn destroyCSS_Plain();
+
+#define SET_STR_HEADER(pStruct, pheader) \
+ register miStructPtr pheader = (miStructPtr) pStruct->deviceData
+
+#define PEX_EL_TYPE(POC) ((ddElementInfo *)(POC))->elementType
+
+/* must have err, i and ppwks defined to use this macro */
+#define ADD_WKS( plist, pstr ) \
+ if (puAddToList((ddPointer)(plist)->pList, (ddULONG)(plist)->numObj, \
+ ((miStructPtr)(pstr)->deviceData)->wksAppearOn) == MI_ALLOCERR) \
+ return(MI_ALLOCERR); \
+ for ( i=(plist)->numObj, ppwks=(diWKSHandle *)(plist)->pList; \
+ i > 0; \
+ i--, ppwks++) \
+ if ((err = miAddWksToAppearLists( (pstr), *ppwks )) != MI_SUCCESS) \
+ return(err)
+
+/* must have i and ppwks defined to use this macro */
+#define REMOVE_WKS( plist, pstr ) \
+ for ( i=(plist)->numObj, ppwks=(diWKSHandle *)(plist)->pList; \
+ i > 0; \
+ i--, ppwks++) { \
+ puRemoveFromList( (ddPointer)ppwks, \
+ ((miStructPtr)(pstr)->deviceData)->wksAppearOn); \
+ miRemoveWksFromAppearLists((pstr), *ppwks); }
+
+ddpex4rtn
+createCSS_Exec_Struct(pStruct, pPEXOC, ppCSSElement)
+/* in */
+ diStructHandle pStruct;
+ pexExecuteStructure *pPEXOC;
+/* out */
+ miGenericElementStr **ppCSSElement;
+{
+ SET_STR_HEADER(pStruct, pheader);
+ diStructHandle pexecstr;
+ ddpex4rtn err;
+ register ddULONG i;
+ register diWKSHandle *ppwks;
+
+ *ppCSSElement = (miGenericElementPtr) NULL;
+
+ err = (*ParseOCTable[PEX_EL_TYPE(pPEXOC)]) (pPEXOC, ppCSSElement);
+
+ if (err != Success)
+ return (err);
+
+ /*
+ * update the structure cross reference lists the id in execute
+ * structure elements was replaced with the diStructHandle by diPEX
+ */
+ pexecstr = *((diStructHandle *)&(pPEXOC->id));
+
+ /* update pStructs children list */
+ err = UpdateStructRefs(pStruct, (diResourceHandle) pexecstr,
+ CHILD_STRUCTURE_RESOURCE, ADD);
+ if (err != Success)
+ return (err);
+
+ /* update the executed structs parent list */
+ err = UpdateStructRefs(pexecstr, (diResourceHandle) pStruct,
+ PARENT_STRUCTURE_RESOURCE, ADD);
+ if (err != Success)
+ return (err);
+
+ /* update the wks appears on lists of the subordinate structure */
+ ADD_WKS(pheader->wksPostedTo, pexecstr);
+ ADD_WKS(pheader->wksAppearOn, pexecstr);
+
+ (*ppCSSElement)->pStruct = pStruct;
+ (*ppCSSElement)->element.pexOClength =
+ ((ddElementInfo *) pPEXOC)->length; /* protocol size, not
+ * parsed size */
+ (*ppCSSElement)->element.elementType =
+ ((ddElementInfo *) pPEXOC)->elementType;
+
+ MISTR_NUM_EL(pheader)++;
+ MISTR_LENGTH(pheader) += ((ddElementInfo *) pPEXOC)->length;
+
+ return (Success);
+}
+
+ddpex4rtn
+destroyCSS_Exec_Struct(pStruct, pCSSElement)
+/* in */
+ diStructHandle pStruct;
+ miGenericElementPtr pCSSElement;
+/* out */
+{
+ SET_STR_HEADER(pStruct, pheader);
+ diStructHandle pexecstr;
+ register int i;
+ register diWKSHandle *ppwks;
+
+ pexecstr = (diStructHandle) MISTR_GET_EXSTR_STR(pCSSElement);
+ /* Now remove this child from the parent's list of children */
+
+ UpdateStructRefs(pStruct, (diResourceHandle) pexecstr,
+ CHILD_STRUCTURE_RESOURCE, REMOVE);
+
+ /* and remove the parent from the childs list */
+
+ UpdateStructRefs(pexecstr, (diResourceHandle) pStruct,
+ PARENT_STRUCTURE_RESOURCE, REMOVE);
+
+ /* update the wks appears on lists of the subordinate structure */
+ REMOVE_WKS(pheader->wksPostedTo, pexecstr);
+ REMOVE_WKS(pheader->wksAppearOn, pexecstr);
+
+ return (destroyCSS_Plain(pStruct, pCSSElement));
+}
+
+ddpex4rtn
+copyCSS_Exec_Struct(pSrcCSSElement, pDestStruct, ppDestCSSElement)
+/* in */
+ miGenericElementPtr pSrcCSSElement;
+ diStructHandle pDestStruct;
+/* out */
+ miGenericElementStr **ppDestCSSElement;
+{
+ SET_STR_HEADER(pDestStruct, pheader);
+ diStructHandle pexecstr;
+ ddpex4rtn err;
+ register ddULONG i;
+ register diWKSHandle *ppwks;
+
+ *ppDestCSSElement = (miGenericElementPtr) NULL;
+
+ err = (*CopyOCTable[(int) (pSrcCSSElement->element.elementType)])
+ (pSrcCSSElement, ppDestCSSElement);
+ if (err != Success)
+ return (err);
+
+ /*
+ * update the structure cross reference lists the id in execute
+ * structure elements was replaced with the diStructHandle by diPEX
+ */
+ pexecstr = (diStructHandle) MISTR_GET_EXSTR_STR(pSrcCSSElement);
+
+ /* update pStructs children list */
+ err = UpdateStructRefs(pDestStruct, (diResourceHandle) pexecstr,
+ CHILD_STRUCTURE_RESOURCE, ADD);
+ if (err != Success)
+ return (err);
+
+ /* update the executed structs parent list */
+ err = UpdateStructRefs(pexecstr, (diResourceHandle) pDestStruct,
+ PARENT_STRUCTURE_RESOURCE, ADD);
+ if (err != Success)
+ return (err);
+
+ /* update the wks appears on lists of the subordinate structure */
+ ADD_WKS(pheader->wksPostedTo, pexecstr);
+ ADD_WKS(pheader->wksAppearOn, pexecstr);
+
+ MISTR_NUM_EL(pheader)++;
+ MISTR_LENGTH(pheader) += MISTR_EL_LENGTH(pSrcCSSElement);
+
+ (*ppDestCSSElement)->pStruct = pDestStruct;
+
+ MISTR_EL_LENGTH(*ppDestCSSElement) = MISTR_EL_LENGTH(pSrcCSSElement);
+ MISTR_EL_TYPE(*ppDestCSSElement) = MISTR_EL_TYPE(pSrcCSSElement);
+
+ return (Success);
+}
+
+ddpex4rtn
+replaceCSS_Exec_Struct(pStruct, pCSSElement, pPEXOC)
+/* in */
+ diStructHandle pStruct;
+ miGenericElementPtr pCSSElement;
+ pexExecuteStructure *pPEXOC;
+{
+ SET_STR_HEADER(pStruct, pheader);
+ diStructHandle pexecstr;
+ ddpex4rtn err;
+ register ddULONG i;
+ register diWKSHandle *ppwks;
+
+ pexecstr = (diStructHandle) MISTR_GET_EXSTR_STR(pCSSElement);
+ if (pexecstr != *((diStructHandle *)&(pPEXOC->id))) {
+
+ /*
+ * update the structure cross reference lists the id in
+ * execute structure elements was replaced with the
+ * diStructHandle by diPEX
+ */
+
+ /* update pStructs children list REMOVE the old element */
+ UpdateStructRefs(pStruct, (diResourceHandle) pexecstr,
+ CHILD_STRUCTURE_RESOURCE, REMOVE);
+
+ /* update the executed structs parent list REMOVE the parent */
+ UpdateStructRefs(pexecstr, (diResourceHandle) pStruct,
+ PARENT_STRUCTURE_RESOURCE, REMOVE);
+
+ /*
+ * update the wks appears on lists of the subordinate
+ * structure
+ */
+ REMOVE_WKS(pheader->wksPostedTo, pexecstr);
+ REMOVE_WKS(pheader->wksAppearOn, pexecstr);
+
+ /* update the new executed structs parent list */
+ err = UpdateStructRefs( *((diStructHandle *)&(pPEXOC->id)),
+ (diResourceHandle) pStruct,
+ PARENT_STRUCTURE_RESOURCE, ADD);
+ if (err != Success) return (err);
+
+ /* update pStructs children list with the new child */
+ err = UpdateStructRefs( pStruct,
+ *((diResourceHandle *)&(pPEXOC->id)),
+ CHILD_STRUCTURE_RESOURCE, ADD);
+ if (err != Success) return (err);
+
+ /*
+ * update the wks appears on lists of the subordinate
+ * structure
+ */
+ ADD_WKS(pheader->wksPostedTo,*((diStructHandle *)&(pPEXOC->id)));
+ ADD_WKS(pheader->wksAppearOn,*((diStructHandle *)&(pPEXOC->id)));
+
+ MISTR_PUT_EXSTR_STR(pCSSElement, pPEXOC->id);
+ }
+ return (Success);
+}
+
+
+ddpex4rtn
+inquireCSS_Exec_Struct(pCSSElement, pBuf, ppPEXOC)
+ miGenericElementPtr pCSSElement;
+ ddBuffer *pBuf;
+ ddElementInfo **ppPEXOC;
+{
+ ddpex4rtn err = Success;
+ pexExecuteStructure *pexstr;
+
+ err = (*InquireOCTable[(int) (pCSSElement->element.elementType)])
+ (pCSSElement, pBuf, ppPEXOC);
+
+ pexstr = (pexExecuteStructure *)*ppPEXOC;
+ pexstr->id = (*((diStructHandle *)&(pexstr->id)))->id;
+ return (err);
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level4/css_plain.c b/xc/programs/Xserver/PEX5/ddpex/mi/level4/css_plain.c
new file mode 100644
index 000000000..42363e44f
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level4/css_plain.c
@@ -0,0 +1,222 @@
+/* $TOG: css_plain.c /main/6 1998/02/10 12:43:29 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level4/css_plain.c,v 1.8 1999/01/31 12:21:29 dawes Exp $ */
+/*
+ * this file contains the element handling procedures for elements
+ * which are stored in the format they are received. This includes
+ * PEX elements stored in PEX format and any imp. dep. elements which
+ * are not defined by PEX.
+ */
+
+#include "ddpex.h"
+#include "miStrMacro.h"
+#include "pexos.h"
+
+
+extern ocTableType ParseOCTable[];
+extern destroyTableType DestroyOCTable[];
+extern ocTableType CopyOCTable[];
+extern ocTableType InquireOCTable[];
+extern ocTableType ReplaceOCTable[];
+
+#define SET_STR_HEADER(pStruct, pheader) \
+ register miStructPtr pheader = (miStructPtr) pStruct->deviceData
+
+#define PEX_EL_TYPE(POC) ((ddElementInfo *)(POC))->elementType
+
+
+ddpex4rtn
+createCSS_Plain(pStruct, pPEXOC, ppCSSElement)
+/* in */
+ diStructHandle pStruct;
+ ddPointer pPEXOC;
+/* out */
+ miGenericElementStr **ppCSSElement;
+{
+ ddpex4rtn err = Success;
+ SET_STR_HEADER(pStruct, pheader);
+
+ *ppCSSElement = (miGenericElementPtr) NULL;
+
+ /*
+ * Parse into server native format
+ * If we make it here OC is either proprietary or valid PEXOC
+ * still need to check proprietary to avoid Null Function Ptrs
+ */
+ if (MI_HIGHBIT_ON(PEX_EL_TYPE(pPEXOC)))
+ err = (*ParseOCTable[MI_OC_PROP]) (pPEXOC, ppCSSElement);
+ else
+ err = (*ParseOCTable[PEX_EL_TYPE(pPEXOC)])
+ (pPEXOC, ppCSSElement);
+
+ if (err != Success)
+ return (PEXERR(PEXOutputCommandError));
+
+ (*ppCSSElement)->pStruct = pStruct;
+ (*ppCSSElement)->element.pexOClength =
+ ((ddElementInfo *) pPEXOC)->length; /* protocol size, not
+ * parsed size */
+ (*ppCSSElement)->element.elementType =
+ ((ddElementInfo *) pPEXOC)->elementType;
+
+ MISTR_NUM_EL(pheader)++;
+ MISTR_LENGTH(pheader) += ((ddElementInfo *) pPEXOC)->length;
+
+ return (Success);
+}
+
+ddpex4rtn
+destroyCSS_Plain(pStruct, pCSSElement)
+/* in */
+ diStructHandle pStruct;
+ miGenericElementPtr pCSSElement;
+/* out */
+{
+ ddpex4rtn err = Success;
+ SET_STR_HEADER(pStruct, pheader);
+
+ MISTR_NUM_EL(pheader)--;
+ MISTR_LENGTH(pheader) -= MISTR_EL_LENGTH(pCSSElement);
+
+ /*
+ * Free the parsed format
+ * If we make it here OC is either proprietary or valid PEXOC
+ * still need to check proprietary to avoid Null Function Ptrs
+ * even though we use the same destroy routine
+ */
+
+ if (MI_HIGHBIT_ON(pCSSElement->element.elementType))
+ (*DestroyOCTable[MI_OC_PROP]) (pCSSElement);
+ else
+ (*DestroyOCTable[(int) (pCSSElement->element.elementType)])
+ (pCSSElement);
+
+ return (err);
+}
+
+ddpex4rtn
+copyCSS_Plain(pSrcCSSElement, pDestStruct, ppDestCSSElement)
+/* in */
+ miGenericElementPtr pSrcCSSElement;
+ diStructHandle pDestStruct;
+/* out */
+ miGenericElementStr **ppDestCSSElement;
+{
+ ddpex4rtn err = Success;
+ SET_STR_HEADER(pDestStruct, pheader);
+
+ *ppDestCSSElement = (miGenericElementPtr) NULL;
+
+ /*
+ * If we make it here OC is either proprietary or valid PEXOC
+ * still need to check proprietary to avoid Null Function Ptrs
+ */
+ if (MI_HIGHBIT_ON(pSrcCSSElement->element.elementType))
+ err = (*CopyOCTable[MI_OC_PROP])
+ (pSrcCSSElement, ppDestCSSElement);
+ else
+ err = (*CopyOCTable[(int) (pSrcCSSElement->element.elementType)])
+ (pSrcCSSElement, ppDestCSSElement);
+
+ if (err != Success)
+ return (err);
+
+ (*ppDestCSSElement)->pStruct = pDestStruct;
+ (*ppDestCSSElement)->element.pexOClength =
+ pSrcCSSElement->element.pexOClength;
+ (*ppDestCSSElement)->element.elementType =
+ pSrcCSSElement->element.elementType;
+
+ MISTR_NUM_EL(pheader)++;
+ MISTR_LENGTH(pheader) += MISTR_EL_LENGTH(*ppDestCSSElement);
+
+ return (Success);
+}
+
+ddpex4rtn
+replaceCSS_Plain(pStruct, pCSSElement, pPEXOC)
+ diStructHandle pStruct;
+ miGenericElementPtr pCSSElement;
+ ddElementInfo *pPEXOC;
+{
+ ddpex4rtn err = Success;
+
+ /*
+ * If we make it here OC is either proprietary or valid PEXOC
+ * still need to check proprietary to avoid Null Function Ptrs
+ */
+ if (MI_HIGHBIT_ON(pCSSElement->element.elementType))
+ err = (*ReplaceOCTable[MI_OC_PROP]) (pPEXOC, &pCSSElement);
+ else
+ err = (*ReplaceOCTable[(int) (pCSSElement->element.elementType)])
+ (pPEXOC, &pCSSElement);
+
+ if (err == Success) {
+ pCSSElement->pStruct = pStruct;
+ pCSSElement->element.elementType = pPEXOC->elementType;
+ pCSSElement->element.pexOClength = pPEXOC->length;
+ }
+ return (err);
+}
+
+ddpex4rtn
+inquireCSS_Plain(pCSSElement, pBuf, ppPEXOC)
+ miGenericElementPtr pCSSElement;
+ ddBuffer *pBuf;
+ ddElementInfo **ppPEXOC;
+{
+ ddpex4rtn err = Success;
+
+ /*
+ * If we make it here OC is either proprietary or valid PEXOC
+ * still need to check proprietary to avoid Null Function Ptrs
+ */
+ if (MI_HIGHBIT_ON(pCSSElement->element.elementType))
+ err = (*InquireOCTable[MI_OC_PROP]) (pCSSElement, pBuf, ppPEXOC);
+ else
+ err = (*InquireOCTable[(int) (pCSSElement->element.elementType)])
+ (pCSSElement, pBuf, ppPEXOC);
+ return (err);
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level4/css_tbls.c b/xc/programs/Xserver/PEX5/ddpex/mi/level4/css_tbls.c
new file mode 100644
index 000000000..39700d415
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level4/css_tbls.c
@@ -0,0 +1,607 @@
+/* $TOG: css_tbls.c /main/5 1998/02/10 12:43:33 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS 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.
+
+*/
+/* Automatically generated element handling tables */
+
+#include "ddpex.h"
+#include "miStruct.h"
+
+
+/* declarations for procs which handle elements stored in PEX format
+ * this includes elements stored in PEX format and any extra elements
+ * which are not defined in the protocol
+ */
+
+extern ddpex4rtn createCSS_Plain();
+extern ddpex4rtn destroyCSS_Plain();
+extern ddpex4rtn copyCSS_Plain();
+extern ddpex4rtn replaceCSS_Plain();
+extern ddpex4rtn inquireCSS_Plain();
+
+/* declarations for procs which handle execute structure elements */
+extern ddpex4rtn createCSS_Exec_Struct();
+extern ddpex4rtn destroyCSS_Exec_Struct();
+extern ddpex4rtn copyCSS_Exec_Struct();
+extern ddpex4rtn replaceCSS_Exec_Struct();
+extern ddpex4rtn inquireCSS_Exec_Struct();
+
+cssTableType CreateCSSElementTable[] = {
+ createCSS_Plain, /* 0 Propietary */
+ createCSS_Plain, /* 1 MarkerType */
+ createCSS_Plain, /* 2 MarkerScale */
+ createCSS_Plain, /* 3 MarkerColourIndex */
+ createCSS_Plain, /* 4 MarkerColour */
+ createCSS_Plain, /* 5 MarkerBundleIndex */
+ createCSS_Plain, /* 6 TextFontIndex */
+ createCSS_Plain, /* 7 TextPrecision */
+ createCSS_Plain, /* 8 CharExpansion */
+ createCSS_Plain, /* 9 CharSpacing */
+ createCSS_Plain, /* 10 TextColourIndex */
+ createCSS_Plain, /* 11 TextColour */
+ createCSS_Plain, /* 12 CharHeight */
+ createCSS_Plain, /* 13 CharUpVector */
+ createCSS_Plain, /* 14 TextPath */
+ createCSS_Plain, /* 15 TextAlignment */
+ createCSS_Plain, /* 16 AtextHeight */
+ createCSS_Plain, /* 17 AtextUpVector */
+ createCSS_Plain, /* 18 AtextPath */
+ createCSS_Plain, /* 19 AtextAlignment */
+ createCSS_Plain, /* 20 AtextStyle */
+ createCSS_Plain, /* 21 TextBundleIndex */
+ createCSS_Plain, /* 22 LineType */
+ createCSS_Plain, /* 23 LineWidth */
+ createCSS_Plain, /* 24 LineColourIndex */
+ createCSS_Plain, /* 25 LineColour */
+ createCSS_Plain, /* 26 CurveApproximation */
+ createCSS_Plain, /* 27 PolylineInterp */
+ createCSS_Plain, /* 28 LineBundleIndex */
+ createCSS_Plain, /* 29 InteriorStyle */
+ createCSS_Plain, /* 30 InteriorStyleIndex */
+ createCSS_Plain, /* 31 SurfaceColourIndex */
+ createCSS_Plain, /* 32 SurfaceColour */
+ createCSS_Plain, /* 33 SurfaceReflAttr */
+ createCSS_Plain, /* 34 SurfaceReflModel */
+ createCSS_Plain, /* 35 SurfaceInterp */
+ createCSS_Plain, /* 36 BfInteriorStyle */
+ createCSS_Plain, /* 37 BfInteriorStyleIndex */
+ createCSS_Plain, /* 38 BfSurfaceColourIndex */
+ createCSS_Plain, /* 39 BfSurfaceColour */
+ createCSS_Plain, /* 40 BfSurfaceReflAttr */
+ createCSS_Plain, /* 41 BfSurfaceReflModel */
+ createCSS_Plain, /* 42 BfSurfaceInterp */
+ createCSS_Plain, /* 43 SurfaceApproximation */
+ createCSS_Plain, /* 44 CullingMode */
+ createCSS_Plain, /* 45 DistinguishFlag */
+ createCSS_Plain, /* 46 PatternSize */
+ createCSS_Plain, /* 47 PatternRefPt */
+ createCSS_Plain, /* 48 PatternAttr */
+ createCSS_Plain, /* 49 InteriorBundleIndex */
+ createCSS_Plain, /* 50 SurfaceEdgeFlag */
+ createCSS_Plain, /* 51 SurfaceEdgeType */
+ createCSS_Plain, /* 52 SurfaceEdgeWidth */
+ createCSS_Plain, /* 53 SurfaceEdgeColourIndex */
+ createCSS_Plain, /* 54 SurfaceEdgeColour */
+ createCSS_Plain, /* 55 EdgeBundleIndex */
+ createCSS_Plain, /* 56 SetAsfValues */
+ createCSS_Plain, /* 57 LocalTransform */
+ createCSS_Plain, /* 58 LocalTransform2D */
+ createCSS_Plain, /* 59 GlobalTransform */
+ createCSS_Plain, /* 60 GlobalTransform2D */
+ createCSS_Plain, /* 61 ModelClip */
+ createCSS_Plain, /* 62 ModelClipVolume */
+ createCSS_Plain, /* 63 ModelClipVolume2D */
+ createCSS_Plain, /* 64 RestoreModelClip */
+ createCSS_Plain, /* 65 ViewIndex */
+ createCSS_Plain, /* 66 LightState */
+ createCSS_Plain, /* 67 DepthCueIndex */
+ createCSS_Plain, /* 68 PickId */
+ createCSS_Plain, /* 69 HlhsrIdentifier */
+ createCSS_Plain, /* 70 ColourApproxIndex */
+ createCSS_Plain, /* 71 RenderingColourModel */
+ createCSS_Plain, /* 72 PSurfaceCharacteristics */
+ createCSS_Plain, /* 73 AddToNameSet */
+ createCSS_Plain, /* 74 RemoveFromNameSet */
+ createCSS_Exec_Struct, /* 75 ExecuteStructure */
+ createCSS_Plain, /* 76 Label */
+ createCSS_Plain, /* 77 ApplicationData */
+ createCSS_Plain, /* 78 Gse */
+ createCSS_Plain, /* 79 Marker */
+ createCSS_Plain, /* 80 Marker2D */
+ createCSS_Plain, /* 81 Text */
+ createCSS_Plain, /* 82 Text2D */
+ createCSS_Plain, /* 83 AnnotationText */
+ createCSS_Plain, /* 84 AnnotationText2D */
+ createCSS_Plain, /* 85 Polyline */
+ createCSS_Plain, /* 86 Polyline2D */
+ createCSS_Plain, /* 87 PolylineSet */
+ createCSS_Plain, /* 88 NurbCurve */
+ createCSS_Plain, /* 89 FillArea */
+ createCSS_Plain, /* 90 FillArea2D */
+ createCSS_Plain, /* 91 ExtFillArea */
+ createCSS_Plain, /* 92 FillAreaSet */
+ createCSS_Plain, /* 93 FillAreaSet2D */
+ createCSS_Plain, /* 94 ExtFillAreaSet */
+ createCSS_Plain, /* 95 TriangleStrip */
+ createCSS_Plain, /* 96 QuadrilateralMesh */
+ createCSS_Plain, /* 97 SOFAS */
+ createCSS_Plain, /* 98 NurbSurface */
+ createCSS_Plain, /* 99 CellArray */
+ createCSS_Plain, /* 100 CellArray2D */
+ createCSS_Plain, /* 101 ExtCellArray */
+ createCSS_Plain, /* 102 Gdp */
+ createCSS_Plain, /* 103 Gdp2D */
+ createCSS_Plain /* 104 Noop */
+};
+
+cssTableType DestroyCSSElementTable[] = {
+ destroyCSS_Plain, /* 0 Propietary */
+ destroyCSS_Plain, /* 1 MarkerType */
+ destroyCSS_Plain, /* 2 MarkerScale */
+ destroyCSS_Plain, /* 3 MarkerColourIndex */
+ destroyCSS_Plain, /* 4 MarkerColour */
+ destroyCSS_Plain, /* 5 MarkerBundleIndex */
+ destroyCSS_Plain, /* 6 TextFontIndex */
+ destroyCSS_Plain, /* 7 TextPrecision */
+ destroyCSS_Plain, /* 8 CharExpansion */
+ destroyCSS_Plain, /* 9 CharSpacing */
+ destroyCSS_Plain, /* 10 TextColourIndex */
+ destroyCSS_Plain, /* 11 TextColour */
+ destroyCSS_Plain, /* 12 CharHeight */
+ destroyCSS_Plain, /* 13 CharUpVector */
+ destroyCSS_Plain, /* 14 TextPath */
+ destroyCSS_Plain, /* 15 TextAlignment */
+ destroyCSS_Plain, /* 16 AtextHeight */
+ destroyCSS_Plain, /* 17 AtextUpVector */
+ destroyCSS_Plain, /* 18 AtextPath */
+ destroyCSS_Plain, /* 19 AtextAlignment */
+ destroyCSS_Plain, /* 20 AtextStyle */
+ destroyCSS_Plain, /* 21 TextBundleIndex */
+ destroyCSS_Plain, /* 22 LineType */
+ destroyCSS_Plain, /* 23 LineWidth */
+ destroyCSS_Plain, /* 24 LineColourIndex */
+ destroyCSS_Plain, /* 25 LineColour */
+ destroyCSS_Plain, /* 26 CurveApproximation */
+ destroyCSS_Plain, /* 27 PolylineInterp */
+ destroyCSS_Plain, /* 28 LineBundleIndex */
+ destroyCSS_Plain, /* 29 InteriorStyle */
+ destroyCSS_Plain, /* 30 InteriorStyleIndex */
+ destroyCSS_Plain, /* 31 SurfaceColourIndex */
+ destroyCSS_Plain, /* 32 SurfaceColour */
+ destroyCSS_Plain, /* 33 SurfaceReflAttr */
+ destroyCSS_Plain, /* 34 SurfaceReflModel */
+ destroyCSS_Plain, /* 35 SurfaceInterp */
+ destroyCSS_Plain, /* 36 BfInteriorStyle */
+ destroyCSS_Plain, /* 37 BfInteriorStyleIndex */
+ destroyCSS_Plain, /* 38 BfSurfaceColourIndex */
+ destroyCSS_Plain, /* 39 BfSurfaceColour */
+ destroyCSS_Plain, /* 40 BfSurfaceReflAttr */
+ destroyCSS_Plain, /* 41 BfSurfaceReflModel */
+ destroyCSS_Plain, /* 42 BfSurfaceInterp */
+ destroyCSS_Plain, /* 43 SurfaceApproximation */
+ destroyCSS_Plain, /* 44 CullingMode */
+ destroyCSS_Plain, /* 45 DistinguishFlag */
+ destroyCSS_Plain, /* 46 PatternSize */
+ destroyCSS_Plain, /* 47 PatternRefPt */
+ destroyCSS_Plain, /* 48 PatternAttr */
+ destroyCSS_Plain, /* 49 InteriorBundleIndex */
+ destroyCSS_Plain, /* 50 SurfaceEdgeFlag */
+ destroyCSS_Plain, /* 51 SurfaceEdgeType */
+ destroyCSS_Plain, /* 52 SurfaceEdgeWidth */
+ destroyCSS_Plain, /* 53 SurfaceEdgeColourIndex */
+ destroyCSS_Plain, /* 54 SurfaceEdgeColour */
+ destroyCSS_Plain, /* 55 EdgeBundleIndex */
+ destroyCSS_Plain, /* 56 SetAsfValues */
+ destroyCSS_Plain, /* 57 LocalTransform */
+ destroyCSS_Plain, /* 58 LocalTransform2D */
+ destroyCSS_Plain, /* 59 GlobalTransform */
+ destroyCSS_Plain, /* 60 GlobalTransform2D */
+ destroyCSS_Plain, /* 61 ModelClip */
+ destroyCSS_Plain, /* 62 ModelClipVolume */
+ destroyCSS_Plain, /* 63 ModelClipVolume2D */
+ destroyCSS_Plain, /* 64 RestoreModelClip */
+ destroyCSS_Plain, /* 65 ViewIndex */
+ destroyCSS_Plain, /* 66 LightState */
+ destroyCSS_Plain, /* 67 DepthCueIndex */
+ destroyCSS_Plain, /* 68 PickId */
+ destroyCSS_Plain, /* 69 HlhsrIdentifier */
+ destroyCSS_Plain, /* 70 ColourApproxIndex */
+ destroyCSS_Plain, /* 71 RenderingColourModel */
+ destroyCSS_Plain, /* 72 PSurfaceCharacteristics */
+ destroyCSS_Plain, /* 73 AddToNameSet */
+ destroyCSS_Plain, /* 74 RemoveFromNameSet */
+ destroyCSS_Exec_Struct, /* 75 ExecuteStructure */
+ destroyCSS_Plain, /* 76 Label */
+ destroyCSS_Plain, /* 77 ApplicationData */
+ destroyCSS_Plain, /* 78 Gse */
+ destroyCSS_Plain, /* 79 Marker */
+ destroyCSS_Plain, /* 80 Marker2D */
+ destroyCSS_Plain, /* 81 Text */
+ destroyCSS_Plain, /* 82 Text2D */
+ destroyCSS_Plain, /* 83 AnnotationText */
+ destroyCSS_Plain, /* 84 AnnotationText2D */
+ destroyCSS_Plain, /* 85 Polyline */
+ destroyCSS_Plain, /* 86 Polyline2D */
+ destroyCSS_Plain, /* 87 PolylineSet */
+ destroyCSS_Plain, /* 88 NurbCurve */
+ destroyCSS_Plain, /* 89 FillArea */
+ destroyCSS_Plain, /* 90 FillArea2D */
+ destroyCSS_Plain, /* 91 ExtFillArea */
+ destroyCSS_Plain, /* 92 FillAreaSet */
+ destroyCSS_Plain, /* 93 FillAreaSet2D */
+ destroyCSS_Plain, /* 94 ExtFillAreaSet */
+ destroyCSS_Plain, /* 95 TriangleStrip */
+ destroyCSS_Plain, /* 96 QuadrilateralMesh */
+ destroyCSS_Plain, /* 97 SOFAS */
+ destroyCSS_Plain, /* 98 NurbSurface */
+ destroyCSS_Plain, /* 99 CellArray */
+ destroyCSS_Plain, /* 100 CellArray2D */
+ destroyCSS_Plain, /* 101 ExtCellArray */
+ destroyCSS_Plain, /* 102 Gdp */
+ destroyCSS_Plain, /* 103 Gdp2D */
+ destroyCSS_Plain /* 104 Noop */
+};
+
+cssTableType CopyCSSElementTable[] = {
+ copyCSS_Plain, /* 0 Propietary */
+ copyCSS_Plain, /* 1 MarkerType */
+ copyCSS_Plain, /* 2 MarkerScale */
+ copyCSS_Plain, /* 3 MarkerColourIndex */
+ copyCSS_Plain, /* 4 MarkerColour */
+ copyCSS_Plain, /* 5 MarkerBundleIndex */
+ copyCSS_Plain, /* 6 TextFontIndex */
+ copyCSS_Plain, /* 7 TextPrecision */
+ copyCSS_Plain, /* 8 CharExpansion */
+ copyCSS_Plain, /* 9 CharSpacing */
+ copyCSS_Plain, /* 10 TextColourIndex */
+ copyCSS_Plain, /* 11 TextColour */
+ copyCSS_Plain, /* 12 CharHeight */
+ copyCSS_Plain, /* 13 CharUpVector */
+ copyCSS_Plain, /* 14 TextPath */
+ copyCSS_Plain, /* 15 TextAlignment */
+ copyCSS_Plain, /* 16 AtextHeight */
+ copyCSS_Plain, /* 17 AtextUpVector */
+ copyCSS_Plain, /* 18 AtextPath */
+ copyCSS_Plain, /* 19 AtextAlignment */
+ copyCSS_Plain, /* 20 AtextStyle */
+ copyCSS_Plain, /* 21 TextBundleIndex */
+ copyCSS_Plain, /* 22 LineType */
+ copyCSS_Plain, /* 23 LineWidth */
+ copyCSS_Plain, /* 24 LineColourIndex */
+ copyCSS_Plain, /* 25 LineColour */
+ copyCSS_Plain, /* 26 CurveApproximation */
+ copyCSS_Plain, /* 27 PolylineInterp */
+ copyCSS_Plain, /* 28 LineBundleIndex */
+ copyCSS_Plain, /* 29 InteriorStyle */
+ copyCSS_Plain, /* 30 InteriorStyleIndex */
+ copyCSS_Plain, /* 31 SurfaceColourIndex */
+ copyCSS_Plain, /* 32 SurfaceColour */
+ copyCSS_Plain, /* 33 SurfaceReflAttr */
+ copyCSS_Plain, /* 34 SurfaceReflModel */
+ copyCSS_Plain, /* 35 SurfaceInterp */
+ copyCSS_Plain, /* 36 BfInteriorStyle */
+ copyCSS_Plain, /* 37 BfInteriorStyleIndex */
+ copyCSS_Plain, /* 38 BfSurfaceColourIndex */
+ copyCSS_Plain, /* 39 BfSurfaceColour */
+ copyCSS_Plain, /* 40 BfSurfaceReflAttr */
+ copyCSS_Plain, /* 41 BfSurfaceReflModel */
+ copyCSS_Plain, /* 42 BfSurfaceInterp */
+ copyCSS_Plain, /* 43 SurfaceApproximation */
+ copyCSS_Plain, /* 44 CullingMode */
+ copyCSS_Plain, /* 45 DistinguishFlag */
+ copyCSS_Plain, /* 46 PatternSize */
+ copyCSS_Plain, /* 47 PatternRefPt */
+ copyCSS_Plain, /* 48 PatternAttr */
+ copyCSS_Plain, /* 49 InteriorBundleIndex */
+ copyCSS_Plain, /* 50 SurfaceEdgeFlag */
+ copyCSS_Plain, /* 51 SurfaceEdgeType */
+ copyCSS_Plain, /* 52 SurfaceEdgeWidth */
+ copyCSS_Plain, /* 53 SurfaceEdgeColourIndex */
+ copyCSS_Plain, /* 54 SurfaceEdgeColour */
+ copyCSS_Plain, /* 55 EdgeBundleIndex */
+ copyCSS_Plain, /* 56 SetAsfValues */
+ copyCSS_Plain, /* 57 LocalTransform */
+ copyCSS_Plain, /* 58 LocalTransform2D */
+ copyCSS_Plain, /* 59 GlobalTransform */
+ copyCSS_Plain, /* 60 GlobalTransform2D */
+ copyCSS_Plain, /* 61 ModelClip */
+ copyCSS_Plain, /* 62 ModelClipVolume */
+ copyCSS_Plain, /* 63 ModelClipVolume2D */
+ copyCSS_Plain, /* 64 RestoreModelClip */
+ copyCSS_Plain, /* 65 ViewIndex */
+ copyCSS_Plain, /* 66 LightState */
+ copyCSS_Plain, /* 67 DepthCueIndex */
+ copyCSS_Plain, /* 68 PickId */
+ copyCSS_Plain, /* 69 HlhsrIdentifier */
+ copyCSS_Plain, /* 70 ColourApproxIndex */
+ copyCSS_Plain, /* 71 RenderingColourModel */
+ copyCSS_Plain, /* 72 PSurfaceCharacteristics */
+ copyCSS_Plain, /* 73 AddToNameSet */
+ copyCSS_Plain, /* 74 RemoveFromNameSet */
+ copyCSS_Exec_Struct, /* 75 ExecuteStructure */
+ copyCSS_Plain, /* 76 Label */
+ copyCSS_Plain, /* 77 ApplicationData */
+ copyCSS_Plain, /* 78 Gse */
+ copyCSS_Plain, /* 79 Marker */
+ copyCSS_Plain, /* 80 Marker2D */
+ copyCSS_Plain, /* 81 Text */
+ copyCSS_Plain, /* 82 Text2D */
+ copyCSS_Plain, /* 83 AnnotationText */
+ copyCSS_Plain, /* 84 AnnotationText2D */
+ copyCSS_Plain, /* 85 Polyline */
+ copyCSS_Plain, /* 86 Polyline2D */
+ copyCSS_Plain, /* 87 PolylineSet */
+ copyCSS_Plain, /* 88 NurbCurve */
+ copyCSS_Plain, /* 89 FillArea */
+ copyCSS_Plain, /* 90 FillArea2D */
+ copyCSS_Plain, /* 91 ExtFillArea */
+ copyCSS_Plain, /* 92 FillAreaSet */
+ copyCSS_Plain, /* 93 FillAreaSet2D */
+ copyCSS_Plain, /* 94 ExtFillAreaSet */
+ copyCSS_Plain, /* 95 TriangleStrip */
+ copyCSS_Plain, /* 96 QuadrilateralMesh */
+ copyCSS_Plain, /* 97 SOFAS */
+ copyCSS_Plain, /* 98 NurbSurface */
+ copyCSS_Plain, /* 99 CellArray */
+ copyCSS_Plain, /* 100 CellArray2D */
+ copyCSS_Plain, /* 101 ExtCellArray */
+ copyCSS_Plain, /* 102 Gdp */
+ copyCSS_Plain, /* 103 Gdp2D */
+ copyCSS_Plain /* 104 Noop */
+};
+
+cssTableType ReplaceCSSElementTable[] = {
+ replaceCSS_Plain, /* 0 Propietary */
+ replaceCSS_Plain, /* 1 MarkerType */
+ replaceCSS_Plain, /* 2 MarkerScale */
+ replaceCSS_Plain, /* 3 MarkerColourIndex */
+ replaceCSS_Plain, /* 4 MarkerColour */
+ replaceCSS_Plain, /* 5 MarkerBundleIndex */
+ replaceCSS_Plain, /* 6 TextFontIndex */
+ replaceCSS_Plain, /* 7 TextPrecision */
+ replaceCSS_Plain, /* 8 CharExpansion */
+ replaceCSS_Plain, /* 9 CharSpacing */
+ replaceCSS_Plain, /* 10 TextColourIndex */
+ replaceCSS_Plain, /* 11 TextColour */
+ replaceCSS_Plain, /* 12 CharHeight */
+ replaceCSS_Plain, /* 13 CharUpVector */
+ replaceCSS_Plain, /* 14 TextPath */
+ replaceCSS_Plain, /* 15 TextAlignment */
+ replaceCSS_Plain, /* 16 AtextHeight */
+ replaceCSS_Plain, /* 17 AtextUpVector */
+ replaceCSS_Plain, /* 18 AtextPath */
+ replaceCSS_Plain, /* 19 AtextAlignment */
+ replaceCSS_Plain, /* 20 AtextStyle */
+ replaceCSS_Plain, /* 21 TextBundleIndex */
+ replaceCSS_Plain, /* 22 LineType */
+ replaceCSS_Plain, /* 23 LineWidth */
+ replaceCSS_Plain, /* 24 LineColourIndex */
+ replaceCSS_Plain, /* 25 LineColour */
+ replaceCSS_Plain, /* 26 CurveApproximation */
+ replaceCSS_Plain, /* 27 PolylineInterp */
+ replaceCSS_Plain, /* 28 LineBundleIndex */
+ replaceCSS_Plain, /* 29 InteriorStyle */
+ replaceCSS_Plain, /* 30 InteriorStyleIndex */
+ replaceCSS_Plain, /* 31 SurfaceColourIndex */
+ replaceCSS_Plain, /* 32 SurfaceColour */
+ replaceCSS_Plain, /* 33 SurfaceReflAttr */
+ replaceCSS_Plain, /* 34 SurfaceReflModel */
+ replaceCSS_Plain, /* 35 SurfaceInterp */
+ replaceCSS_Plain, /* 36 BfInteriorStyle */
+ replaceCSS_Plain, /* 37 BfInteriorStyleIndex */
+ replaceCSS_Plain, /* 38 BfSurfaceColourIndex */
+ replaceCSS_Plain, /* 39 BfSurfaceColour */
+ replaceCSS_Plain, /* 40 BfSurfaceReflAttr */
+ replaceCSS_Plain, /* 41 BfSurfaceReflModel */
+ replaceCSS_Plain, /* 42 BfSurfaceInterp */
+ replaceCSS_Plain, /* 43 SurfaceApproximation */
+ replaceCSS_Plain, /* 44 CullingMode */
+ replaceCSS_Plain, /* 45 DistinguishFlag */
+ replaceCSS_Plain, /* 46 PatternSize */
+ replaceCSS_Plain, /* 47 PatternRefPt */
+ replaceCSS_Plain, /* 48 PatternAttr */
+ replaceCSS_Plain, /* 49 InteriorBundleIndex */
+ replaceCSS_Plain, /* 50 SurfaceEdgeFlag */
+ replaceCSS_Plain, /* 51 SurfaceEdgeType */
+ replaceCSS_Plain, /* 52 SurfaceEdgeWidth */
+ replaceCSS_Plain, /* 53 SurfaceEdgeColourIndex */
+ replaceCSS_Plain, /* 54 SurfaceEdgeColour */
+ replaceCSS_Plain, /* 55 EdgeBundleIndex */
+ replaceCSS_Plain, /* 56 SetAsfValues */
+ replaceCSS_Plain, /* 57 LocalTransform */
+ replaceCSS_Plain, /* 58 LocalTransform2D */
+ replaceCSS_Plain, /* 59 GlobalTransform */
+ replaceCSS_Plain, /* 60 GlobalTransform2D */
+ replaceCSS_Plain, /* 61 ModelClip */
+ replaceCSS_Plain, /* 62 ModelClipVolume */
+ replaceCSS_Plain, /* 63 ModelClipVolume2D */
+ replaceCSS_Plain, /* 64 RestoreModelClip */
+ replaceCSS_Plain, /* 65 ViewIndex */
+ replaceCSS_Plain, /* 66 LightState */
+ replaceCSS_Plain, /* 67 DepthCueIndex */
+ replaceCSS_Plain, /* 68 PickId */
+ replaceCSS_Plain, /* 69 HlhsrIdentifier */
+ replaceCSS_Plain, /* 70 ColourApproxIndex */
+ replaceCSS_Plain, /* 71 RenderingColourModel */
+ replaceCSS_Plain, /* 72 PSurfaceCharacteristics */
+ replaceCSS_Plain, /* 73 AddToNameSet */
+ replaceCSS_Plain, /* 74 RemoveFromNameSet */
+ replaceCSS_Exec_Struct, /* 75 ExecuteStructure */
+ replaceCSS_Plain, /* 76 Label */
+ replaceCSS_Plain, /* 77 ApplicationData */
+ replaceCSS_Plain, /* 78 Gse */
+ replaceCSS_Plain, /* 79 Marker */
+ replaceCSS_Plain, /* 80 Marker2D */
+ replaceCSS_Plain, /* 81 Text */
+ replaceCSS_Plain, /* 82 Text2D */
+ replaceCSS_Plain, /* 83 AnnotationText */
+ replaceCSS_Plain, /* 84 AnnotationText2D */
+ replaceCSS_Plain, /* 85 Polyline */
+ replaceCSS_Plain, /* 86 Polyline2D */
+ replaceCSS_Plain, /* 87 PolylineSet */
+ replaceCSS_Plain, /* 88 NurbCurve */
+ replaceCSS_Plain, /* 89 FillArea */
+ replaceCSS_Plain, /* 90 FillArea2D */
+ replaceCSS_Plain, /* 91 ExtFillArea */
+ replaceCSS_Plain, /* 92 FillAreaSet */
+ replaceCSS_Plain, /* 93 FillAreaSet2D */
+ replaceCSS_Plain, /* 94 ExtFillAreaSet */
+ replaceCSS_Plain, /* 95 TriangleStrip */
+ replaceCSS_Plain, /* 96 QuadrilateralMesh */
+ replaceCSS_Plain, /* 97 SOFAS */
+ replaceCSS_Plain, /* 98 NurbSurface */
+ replaceCSS_Plain, /* 99 CellArray */
+ replaceCSS_Plain, /* 100 CellArray2D */
+ replaceCSS_Plain, /* 101 ExtCellArray */
+ replaceCSS_Plain, /* 102 Gdp */
+ replaceCSS_Plain, /* 103 Gdp2D */
+ replaceCSS_Plain /* 104 Noop */
+};
+
+cssTableType InquireCSSElementTable[] = {
+ inquireCSS_Plain, /* 0 Propietary */
+ inquireCSS_Plain, /* 1 MarkerType */
+ inquireCSS_Plain, /* 2 MarkerScale */
+ inquireCSS_Plain, /* 3 MarkerColourIndex */
+ inquireCSS_Plain, /* 4 MarkerColour */
+ inquireCSS_Plain, /* 5 MarkerBundleIndex */
+ inquireCSS_Plain, /* 6 TextFontIndex */
+ inquireCSS_Plain, /* 7 TextPrecision */
+ inquireCSS_Plain, /* 8 CharExpansion */
+ inquireCSS_Plain, /* 9 CharSpacing */
+ inquireCSS_Plain, /* 10 TextColourIndex */
+ inquireCSS_Plain, /* 11 TextColour */
+ inquireCSS_Plain, /* 12 CharHeight */
+ inquireCSS_Plain, /* 13 CharUpVector */
+ inquireCSS_Plain, /* 14 TextPath */
+ inquireCSS_Plain, /* 15 TextAlignment */
+ inquireCSS_Plain, /* 16 AtextHeight */
+ inquireCSS_Plain, /* 17 AtextUpVector */
+ inquireCSS_Plain, /* 18 AtextPath */
+ inquireCSS_Plain, /* 19 AtextAlignment */
+ inquireCSS_Plain, /* 20 AtextStyle */
+ inquireCSS_Plain, /* 21 TextBundleIndex */
+ inquireCSS_Plain, /* 22 LineType */
+ inquireCSS_Plain, /* 23 LineWidth */
+ inquireCSS_Plain, /* 24 LineColourIndex */
+ inquireCSS_Plain, /* 25 LineColour */
+ inquireCSS_Plain, /* 26 CurveApproximation */
+ inquireCSS_Plain, /* 27 PolylineInterp */
+ inquireCSS_Plain, /* 28 LineBundleIndex */
+ inquireCSS_Plain, /* 29 InteriorStyle */
+ inquireCSS_Plain, /* 30 InteriorStyleIndex */
+ inquireCSS_Plain, /* 31 SurfaceColourIndex */
+ inquireCSS_Plain, /* 32 SurfaceColour */
+ inquireCSS_Plain, /* 33 SurfaceReflAttr */
+ inquireCSS_Plain, /* 34 SurfaceReflModel */
+ inquireCSS_Plain, /* 35 SurfaceInterp */
+ inquireCSS_Plain, /* 36 BfInteriorStyle */
+ inquireCSS_Plain, /* 37 BfInteriorStyleIndex */
+ inquireCSS_Plain, /* 38 BfSurfaceColourIndex */
+ inquireCSS_Plain, /* 39 BfSurfaceColour */
+ inquireCSS_Plain, /* 40 BfSurfaceReflAttr */
+ inquireCSS_Plain, /* 41 BfSurfaceReflModel */
+ inquireCSS_Plain, /* 42 BfSurfaceInterp */
+ inquireCSS_Plain, /* 43 SurfaceApproximation */
+ inquireCSS_Plain, /* 44 CullingMode */
+ inquireCSS_Plain, /* 45 DistinguishFlag */
+ inquireCSS_Plain, /* 46 PatternSize */
+ inquireCSS_Plain, /* 47 PatternRefPt */
+ inquireCSS_Plain, /* 48 PatternAttr */
+ inquireCSS_Plain, /* 49 InteriorBundleIndex */
+ inquireCSS_Plain, /* 50 SurfaceEdgeFlag */
+ inquireCSS_Plain, /* 51 SurfaceEdgeType */
+ inquireCSS_Plain, /* 52 SurfaceEdgeWidth */
+ inquireCSS_Plain, /* 53 SurfaceEdgeColourIndex */
+ inquireCSS_Plain, /* 54 SurfaceEdgeColour */
+ inquireCSS_Plain, /* 55 EdgeBundleIndex */
+ inquireCSS_Plain, /* 56 SetAsfValues */
+ inquireCSS_Plain, /* 57 LocalTransform */
+ inquireCSS_Plain, /* 58 LocalTransform2D */
+ inquireCSS_Plain, /* 59 GlobalTransform */
+ inquireCSS_Plain, /* 60 GlobalTransform2D */
+ inquireCSS_Plain, /* 61 ModelClip */
+ inquireCSS_Plain, /* 62 ModelClipVolume */
+ inquireCSS_Plain, /* 63 ModelClipVolume2D */
+ inquireCSS_Plain, /* 64 RestoreModelClip */
+ inquireCSS_Plain, /* 65 ViewIndex */
+ inquireCSS_Plain, /* 66 LightState */
+ inquireCSS_Plain, /* 67 DepthCueIndex */
+ inquireCSS_Plain, /* 68 PickId */
+ inquireCSS_Plain, /* 69 HlhsrIdentifier */
+ inquireCSS_Plain, /* 70 ColourApproxIndex */
+ inquireCSS_Plain, /* 71 RenderingColourModel */
+ inquireCSS_Plain, /* 72 PSurfaceCharacteristics */
+ inquireCSS_Plain, /* 73 AddToNameSet */
+ inquireCSS_Plain, /* 74 RemoveFromNameSet */
+ inquireCSS_Exec_Struct, /* 75 ExecuteStructure */
+ inquireCSS_Plain, /* 76 Label */
+ inquireCSS_Plain, /* 77 ApplicationData */
+ inquireCSS_Plain, /* 78 Gse */
+ inquireCSS_Plain, /* 79 Marker */
+ inquireCSS_Plain, /* 80 Marker2D */
+ inquireCSS_Plain, /* 81 Text */
+ inquireCSS_Plain, /* 82 Text2D */
+ inquireCSS_Plain, /* 83 AnnotationText */
+ inquireCSS_Plain, /* 84 AnnotationText2D */
+ inquireCSS_Plain, /* 85 Polyline */
+ inquireCSS_Plain, /* 86 Polyline2D */
+ inquireCSS_Plain, /* 87 PolylineSet */
+ inquireCSS_Plain, /* 88 NurbCurve */
+ inquireCSS_Plain, /* 89 FillArea */
+ inquireCSS_Plain, /* 90 FillArea2D */
+ inquireCSS_Plain, /* 91 ExtFillArea */
+ inquireCSS_Plain, /* 92 FillAreaSet */
+ inquireCSS_Plain, /* 93 FillAreaSet2D */
+ inquireCSS_Plain, /* 94 ExtFillAreaSet */
+ inquireCSS_Plain, /* 95 TriangleStrip */
+ inquireCSS_Plain, /* 96 QuadrilateralMesh */
+ inquireCSS_Plain, /* 97 SOFAS */
+ inquireCSS_Plain, /* 98 NurbSurface */
+ inquireCSS_Plain, /* 99 CellArray */
+ inquireCSS_Plain, /* 100 CellArray2D */
+ inquireCSS_Plain, /* 101 ExtCellArray */
+ inquireCSS_Plain, /* 102 Gdp */
+ inquireCSS_Plain, /* 103 Gdp2D */
+ inquireCSS_Plain /* 104 Noop */
+};
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level4/miDynamics.c b/xc/programs/Xserver/PEX5/ddpex/mi/level4/miDynamics.c
new file mode 100644
index 000000000..f97f33e25
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level4/miDynamics.c
@@ -0,0 +1,222 @@
+/* $TOG: miDynamics.c /main/4 1998/02/10 12:43:38 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS 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 "ddpex.h"
+#include "ddpex4.h"
+#include "pexUtils.h"
+#include "miWks.h"
+#include "miStruct.h"
+#include "miNS.h"
+
+
+/*++
+ |
+ | Function Name: miDealWithDynamics
+ |
+ | Function Description:
+ | Goes through each workstation in the given list and causes a Redraw
+ | of the workstation depending on the supplied dynamic and other values in
+ | the workstation state.
+ |
+ --*/
+
+
+ddpex4rtn
+miDealWithDynamics(dynamic, pwksToLookAt)
+/* in */
+ ddDynamic dynamic;
+ listofObj *pwksToLookAt;
+/* out */
+{
+ register int i;
+ diWKSHandle *pWKS;
+ miWksPtr wksPtr;
+ ddpex4rtn err4 = Success;
+
+ pWKS = (diWKSHandle *) pwksToLookAt->pList;
+ for (i = 0; i < pwksToLookAt->numObj; i++, pWKS++) {
+
+ wksPtr = (miWksPtr) ((*pWKS)->deviceData);
+
+ if (!wksPtr) continue; /* workstation has been freed */
+
+ switch (wksPtr->displayUpdate) {
+ case PEXVisualizeEach:
+ /* always make sure picture is correct */
+ if ( (wksPtr->dynamics[(int) dynamic] != PEXIMM)
+ || (wksPtr->visualState != PEXCorrect)) {
+ if (err4 = RedrawStructures(*pWKS)) return (err4);
+ wksPtr->visualState = PEXCorrect;
+ }
+ break;
+
+ case PEXVisualizeEasy:
+ case PEXVisualizeNone:
+ case PEXVisualizeWhenever:
+ /*
+ * for PEXIMM don't do anything (visual state doesn't change)
+ */
+ if (wksPtr->dynamics[(int) dynamic] != PEXIMM)
+ /* IRG and CBS, the action is deferred */
+ wksPtr->visualState = PEXDeferred;
+ break;
+
+ case PEXSimulateSome:
+
+ /*
+ * don't do anything if dynamic = PEXIMM (visual
+ * state doesn't change)
+ */
+ if (wksPtr->dynamics[(int) dynamic] == PEXIRG)
+ /* the action is deferred */
+ wksPtr->visualState = PEXDeferred;
+ else if (wksPtr->dynamics[(int) dynamic] == PEXCBS)
+
+ /*
+ * the action should not be deferred and the
+ * simulation should be done when the action
+ * is done
+ */
+ if (wksPtr->visualState != PEXDeferred)
+ wksPtr->visualState = PEXSimulated;
+ break;
+ }
+ }
+ return (Success);
+} /* miDealWithDynamics */
+
+/*++
+ |
+ | Function Name: miDealWithStructDynamics
+ |
+ | Function Description:
+ | Goes through each workstation that the structure appears on,
+ | and causes a Redraw of the workstation depending on the supplied
+ | dynamic and other values in the workstation state.
+ |
+ --*/
+
+ddpex4rtn
+miDealWithStructDynamics(dynamic, pStruct)
+/* in */
+ ddDynamic dynamic;
+ diStructHandle pStruct;
+/* out */
+{
+ miStructPtr pstruct = (miStructPtr) pStruct->deviceData;
+ listofObj *pwksToLookAt;
+ ddpex4rtn err = Success;
+
+ /** Build up a list of workstations from the PostedTo and AppearOn
+ ** lists in the structure structure. They are inserted in such a
+ ** manner that duplicates between the lists are eliminated.
+ **/
+
+ if (pstruct->wksPostedTo->numObj || pstruct->wksAppearOn->numObj) {
+ pwksToLookAt = puCreateList(DD_WKS);
+ if (!pwksToLookAt) return (BadAlloc);
+ err = puMergeLists( pstruct->wksPostedTo, pstruct->wksAppearOn,
+ pwksToLookAt);
+
+ err = miDealWithDynamics(dynamic, pwksToLookAt);
+ puDeleteList(pwksToLookAt);
+ }
+ return (err);
+} /* miDealWithStructDynamics */
+
+
+/*++
+ |
+ | Function Name: miDealWithNSDynamics
+ |
+ | Function Description:
+ | Goes through each workstation that uses the name set
+ | and causes a Redraw of the workstation depending on the supplied
+ | dynamic and other values in the workstation state.
+ |
+ --*/
+
+ddpex43rtn
+miDealWithNSDynamics(pNS)
+/* in */
+ diNSHandle pNS;
+/* out */
+{
+ miNSHeader *pns = (miNSHeader *) pNS->deviceData;
+ listofObj *pwksToLookAt;
+ diWKSHandle *pWks;
+ miWksPtr pwks;
+ register int i;
+ ddpex43rtn err = Success;
+
+ if (!pns->wksRefList->numObj) return (Success);
+
+ pwksToLookAt = puCreateList(DD_WKS);
+ if (!pwksToLookAt) return (BadAlloc);
+
+ pWks = (diWKSHandle *) pns->wksRefList->pList;
+ for (i = 0; i < pns->wksRefList->numObj; i++, pWks++) {
+ pwks = (miWksPtr) (*pWks)->deviceData;
+ if ( (pwks->pRend->ns[(int) DD_HIGH_INCL_NS] == pNS)
+ || (pwks->pRend->ns[(int) DD_HIGH_EXCL_NS] == pNS))
+ err = puAddToList((ddPointer) pWks, (ddULONG) 1, pwksToLookAt);
+ }
+
+ err = miDealWithDynamics(HIGH_FILTER_DYNAMIC, pwksToLookAt);
+ if (err == Success) {
+ pWks = (diWKSHandle *) pns->wksRefList->pList;
+ for (i = 0; i < pns->wksRefList->numObj; i++, pWks++) {
+ pwks = (miWksPtr) (*pWks)->deviceData;
+ if ( (pwks->pRend->ns[(int) DD_INVIS_INCL_NS] == pNS)
+ || (pwks->pRend->ns[(int) DD_INVIS_EXCL_NS] == pNS))
+ err = puAddToList((ddPointer) pWks, (ddULONG) 1, pwksToLookAt);
+ }
+
+ err = miDealWithDynamics(INVIS_FILTER_DYNAMIC, pwksToLookAt);
+ }
+ puDeleteList(pwksToLookAt);
+
+ return (err);
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level4/miPick.c b/xc/programs/Xserver/PEX5/ddpex/mi/level4/miPick.c
new file mode 100644
index 000000000..198f90ce8
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level4/miPick.c
@@ -0,0 +1,727 @@
+/* $TOG: miPick.c /main/9 1998/02/10 12:43:42 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level4/miPick.c,v 1.7 1998/10/04 09:34:40 dawes Exp $ */
+
+#include "miWks.h" /* miPickMeasureStr is defined in here */
+#include "miNS.h"
+#include "miStruct.h"
+#include "miStrMacro.h"
+#include "pexUtils.h"
+#include "PEXErr.h"
+#include "pexExtract.h"
+#include "pexos.h"
+
+
+extern ddpex4rtn UpdateStructRefs();
+extern ddpex43rtn UpdateNSRefs();
+extern ddpex3rtn BeginStructure();
+extern ddpex3rtn EndStructure();
+static unsigned char * copy_pick_path_to_buffer();
+void path_update_struct_refs();
+
+/* Level 4 Workstation Support */
+/* picking Procedures */
+
+/*++
+ |
+ | Function Name: InquirePickDevice
+ |
+ | Function Description:
+ | Handles the PEXGetPickDevice request.
+ |
+ | Note(s):
+ don't need pNumItems anymore, but it's not worth changing
+ the interface for now (post alpha release)
+ |
+ --*/
+
+/* depends on mask, num, and dsize being declared */
+#define COUNTBYTES(type,bytes) \
+ if (mask & (type)) \
+ { \
+ num++; \
+ dsize += (bytes); \
+ }
+
+ddpex4rtn
+InquirePickDevice(pWKS, devType, mask, pNumItems, pBuffer)
+/* in */
+ diWKSHandle pWKS; /* workstation handle */
+ ddEnumTypeIndex devType; /* pick device type */
+ ddBitmask mask; /* item bit mask */
+/* out */
+ ddULONG *pNumItems; /* number of items in list */
+ ddBufferPtr pBuffer; /* list of items */
+{
+
+ ddULONG num, dsize;
+ int dev_index;
+ register ddPointer pbuf;
+
+ miPickDevice *pPickDevice;
+
+#ifdef DDTEST
+ ErrorF(" InquirePickDevice\n");
+#endif
+
+ /* convert devType to index into devices array */
+ MIWKS_PICK_DEV_INDEX(dev_index, devType);
+
+ pPickDevice = &(((miWksPtr) pWKS->deviceData)->devices[dev_index]);
+ *pNumItems = 0;
+
+ num = 0;
+ dsize = 0;
+ COUNTBYTES(PEXPDPickStatus, 4);
+ COUNTBYTES(PEXPDPickPath, 4 + (pPickDevice->path->numObj * 12));
+ COUNTBYTES(PEXPDPickPathOrder, 4);
+ COUNTBYTES(PEXPDPickIncl, 4);
+ COUNTBYTES(PEXPDPickExcl, 4);
+ if (mask & PEXPDPickDataRec)
+ switch (dev_index) {
+ case 0:
+ num++;
+ dsize += MIWKS_SIZE_DATA_REC_1;
+ break;
+ case 1:
+ num++;
+ dsize += MIWKS_SIZE_DATA_REC_2;
+ break;
+ }
+ COUNTBYTES(PEXPDPickPromptEchoType, 4);
+ COUNTBYTES(PEXPDPickEchoVolume, sizeof(ddViewport));
+ COUNTBYTES(PEXPDPickEchoSwitch, 4);
+
+ /* Check the buffer size, and realloc if needed. */
+ PU_CHECK_BUFFER_SIZE(pBuffer, dsize);
+
+ *pNumItems = num;
+ pBuffer->dataSize = dsize;
+ pbuf = pBuffer->pBuf;
+
+ if (mask & PEXPDPickStatus) {
+ PACK_CARD32(pPickDevice->status, pbuf);
+ }
+
+ if (mask & PEXPDPickPath) {
+ PACK_CARD32(pPickDevice->path->numObj, pbuf);
+ pbuf = copy_pick_path_to_buffer(pPickDevice->path, pbuf);
+ }
+
+ if (mask & PEXPDPickPathOrder) {
+ PACK_CARD32(pPickDevice->pathOrder, pbuf);
+ }
+
+ if (mask & PEXPDPickIncl) {
+ ddULONG nsid;
+ if (pPickDevice->inclusion)
+ nsid = pPickDevice->inclusion->id;
+ else
+ nsid = 0;
+ PACK_CARD32(nsid, pbuf);
+ }
+
+ if (mask & PEXPDPickExcl) {
+ ddULONG nsid;
+ if (pPickDevice->inclusion)
+ nsid = pPickDevice->exclusion->id;
+ else
+ nsid = 0;
+ PACK_CARD32(nsid, pbuf);
+ }
+
+ /*
+ * no data recs are defined, so skip this - noone should expect to
+ * get data for this
+ */
+ if (mask & PEXPDPickDataRec) {
+ /* Sun says no data records defined, this is dummy code
+ * switch (dev_index) {
+ * case 0: bcopy((char *) &(MIWKS_PICK_DATA_REC_1(pPickDevice)),
+ * (char *) pbuf, MIWKS_SIZE_DATA_REC_1);
+ * pbuf += MIWKS_SIZE_DATA_REC_1;
+ * break;
+ * case 1: bcopy((char *) &(MIWKS_PICK_DATA_REC_2(pPickDevice)),
+ * (char *) pbuf, MIWKS_SIZE_DATA_REC_2);
+ * pbuf += MIWKS_SIZE_DATA_REC_2;
+ * break;
+ * }
+ */
+ /* if for some reason this bitflag is set return length
+ of zero bytes
+ */
+ PACK_CARD32(0,pbuf);
+ }
+
+ if (mask & PEXPDPickPromptEchoType) {
+ PACK_CARD32(pPickDevice->pet, pbuf);
+ }
+ if (mask & PEXPDPickEchoVolume) {
+ PACK_STRUCT(ddViewport,&(pPickDevice->echoVolume),pbuf);
+ }
+ if (mask & PEXPDPickEchoSwitch) {
+ PACK_CARD32(pPickDevice->echoSwitch,pbuf);
+ }
+ return (Success);
+} /* InquirePickDevice */
+
+/*++
+ |
+ | Function Name: ChangePickDevice
+ |
+ | Function Description:
+ | Handles the PEXChangePickDevice request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+ChangePickDevice(pWKS, devType, mask, pItems)
+/* in */
+ diWKSHandle pWKS; /* workstation handle */
+ ddEnumTypeIndex devType;/* pick device type */
+ ddBitmask mask; /* item bit mask */
+ ddPointer pItems; /* list of items */
+{
+
+ register ddPointer pbuf;
+ int dev_index;
+ miPickDevice *pPickDevice;
+ CARD16 pickStatus;
+ CARD16 pickPathOrder;
+ CARD16 pickEchoSwitch;
+ INT16 pickPromptEchoType;
+ ddULONG numPickPath;
+ ddpex4rtn err;
+ extern ddpex4rtn ValidateStructurePath();
+
+#ifdef DDTEST
+ ErrorF(" ChangePickDevice\n");
+#endif
+
+ /* convert devType to index into devices array */
+ MIWKS_PICK_DEV_INDEX(dev_index, devType);
+
+ pPickDevice = &(((miWksPtr) pWKS->deviceData)->devices[dev_index]);
+
+ pbuf = pItems;
+
+ /* go through and check for errors first */
+ if (mask & PEXPDPickStatus) {
+ EXTRACT_CARD16_FROM_4B(pickStatus,pbuf);
+ if (!((pickStatus == PEXNoPick) || (pickStatus == PEXOk)))
+ return (BadValue);
+ }
+
+ if (mask & PEXPDPickPath) {
+ /* valid path is checked when it's set */
+ EXTRACT_CARD32(numPickPath,pbuf);
+ SKIP_STRUCT(pbuf,numPickPath,ddPickPath);
+ }
+
+ if (mask & PEXPDPickPathOrder) {
+ EXTRACT_CARD16_FROM_4B(pickPathOrder,pbuf);
+ if (!((pickPathOrder == PEXTopFirst)||(pickPathOrder == PEXBottomFirst)))
+ return (BadValue);
+ }
+ if (mask & PEXPDPickIncl)
+ SKIP_PADDING(pbuf,4);
+
+ if (mask & PEXPDPickExcl)
+ SKIP_PADDING(pbuf,4);
+
+ /*
+ * no data recs are defined, so skip the bytes if they're there
+ */
+ if (mask & PEXPDPickDataRec) {
+ CARD32 i, skip;
+ EXTRACT_CARD32(i,pbuf);
+ skip = (i+3)/4;
+ SKIP_PADDING(pbuf,skip);
+ }
+
+ if (mask & PEXPDPickPromptEchoType) {
+ EXTRACT_INT16_FROM_4B(pickPromptEchoType,pbuf);
+ switch (pickPromptEchoType) {
+ case PEXEchoPrimitive:
+ case PEXEchoStructure:
+ case PEXEchoNetwork:
+ break;
+ default:
+ return (BadValue);
+ }
+ }
+
+ if (mask & PEXPDPickEchoVolume)
+ SKIP_PADDING(pbuf,sizeof(ddViewport));
+
+ if (mask & PEXPDPickEchoSwitch) {
+ EXTRACT_CARD16_FROM_4B(pickEchoSwitch,pbuf);
+ if (!((pickEchoSwitch == PEXOff) || (pickEchoSwitch == PEXOn)))
+ return (BadValue);
+ }
+
+ /* now set the values */
+ pbuf = pItems;
+
+ if (mask & PEXPDPickStatus) {
+ pPickDevice->status = pickStatus;
+ SKIP_PADDING(pbuf,4);
+ }
+
+ if (mask & PEXPDPickPath) {
+ SKIP_PADDING(pbuf,4);
+
+ /* before putting this path in, remove structure ref
+ * count of current path
+ */
+ if (pPickDevice->path->numObj)
+ path_update_struct_refs(pPickDevice->path, (diResourceHandle) NULL,
+ PICK_RESOURCE, REMOVE);
+
+ PU_EMPTY_LIST(pPickDevice->path);
+
+ /* dipex changes struct ids to handles */
+ puAddToList((ddPointer) pbuf, numPickPath, pPickDevice->path);
+ SKIP_STRUCT(pbuf,numPickPath,ddPickPath);
+
+ /*
+ * now go through the path and update the structures's ref. count
+ */
+ path_update_struct_refs( pPickDevice->path, (diResourceHandle) NULL,
+ PICK_RESOURCE, ADD);
+ /* make sure it's a valid path */
+ err = ValidateStructurePath(pPickDevice->path);
+ if (err != Success)
+ return (err);
+ }
+
+ if (mask & PEXPDPickPathOrder) {
+ pPickDevice->pathOrder = pickPathOrder;
+ SKIP_PADDING(pbuf,4);
+ }
+
+ if (mask & PEXPDPickIncl) {
+ /*
+ * dipex looked up the nameset handle and passed it to here
+ */
+ if (pPickDevice->inclusion != *(diNSHandle *)pbuf) {
+ if (pPickDevice->inclusion)
+ UpdateNSRefs( pPickDevice->inclusion, (diResourceHandle) NULL,
+ PICK_RESOURCE, REMOVE);
+
+ pPickDevice->inclusion = *(diNSHandle *) pbuf;
+ UpdateNSRefs( pPickDevice->inclusion, (diResourceHandle) NULL,
+ PICK_RESOURCE, ADD);
+ }
+ SKIP_PADDING(pbuf,4);
+ }
+
+ if (mask & PEXPDPickExcl) {
+ /*
+ * dipex looked up the nameset handle and passed it to here
+ */
+ if (pPickDevice->exclusion != *(diNSHandle *)pbuf) {
+ if (pPickDevice->exclusion)
+ UpdateNSRefs( pPickDevice->exclusion, (diResourceHandle) NULL,
+ PICK_RESOURCE, REMOVE);
+
+ pPickDevice->exclusion = *(diNSHandle *)pbuf;
+ UpdateNSRefs( pPickDevice->exclusion, (diResourceHandle) NULL,
+ PICK_RESOURCE, ADD);
+ }
+ SKIP_PADDING(pbuf,4);
+ }
+
+ /*
+ * no data recs are defined, so skip this - there'd better not be any
+ * data there for these
+ */
+ if (mask & PEXPDPickDataRec) {
+ /* This is dummy code from Sun,
+ * I am adding code to skip bytes if present - JSH
+ * switch (dev_index) { case 0: bcopy((char *) pbuf, (char *)
+ * &(MIWKS_PICK_DATA_REC_1(pPickDevice)), MIWKS_SIZE_DATA_REC_1);
+ * pbuf += MIWKS_SIZE_DATA_REC_1; break; case 1: bcopy((char *) pbuf,
+ * (char *) &(MIWKS_PICK_DATA_REC_2(pPickDevice)),
+ * MIWKS_SIZE_DATA_REC_2); pbuf += MIWKS_SIZE_DATA_REC_2; break; }
+ */
+
+ CARD32 i, skip;
+ EXTRACT_CARD32(i,pbuf);
+ skip = (i+3)/4;
+ SKIP_PADDING(pbuf,skip);
+ }
+
+ if (mask & PEXPDPickPromptEchoType) {
+ pPickDevice->pet = pickPromptEchoType;
+ SKIP_PADDING(pbuf,4);
+ }
+
+ if (mask & PEXPDPickEchoVolume) {
+ EXTRACT_STRUCT(1, ddViewport, &(pPickDevice->echoVolume), pbuf);
+ }
+
+ if (mask & PEXPDPickEchoSwitch) {
+ pPickDevice->echoSwitch = pickEchoSwitch;
+ }
+
+ return (Success);
+} /* ChangePickDevice */
+
+/*++
+ |
+ | Function Name: UpdatePickMeasure
+ |
+ | Function Description:
+ | Handles the PEXUpdatePickMeasure request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+UpdatePickMeasure(pPM, size, pInput)
+/* in */
+ diPMHandle pPM; /* pick measure */
+ ddULONG size; /* size of input record */
+ ddPointer pInput; /* input record */
+/* out */
+{
+ miPickMeasureStr *ppm = (miPickMeasureStr *) pPM->deviceData;
+ miWksStr *pwks = (miWksStr *) ppm->pWks->deviceData;
+ MIWKS_PM_INPUT_STR_1 *pIn1 = (MIWKS_PM_INPUT_STR_1 *)pInput;
+ MIWKS_PM_INPUT_STR_2 *pIn2 = (MIWKS_PM_INPUT_STR_2 *)pInput;
+ miTraverserState trav_state;
+ register ddOrdStruct *pos;
+ diStructHandle pstr;
+ ddULONG start_el;
+ ddULONG num_els;
+ ddpex4rtn err;
+ extern ddpex3rtn EndPicking();
+ extern ddpex4rtn traverser();
+
+#ifdef DDTEST
+ ErrorF(" UpdatePickMeasure\n");
+#endif
+
+ if ((pwks->pRend->pDrawable == NULL) ||
+ (pwks->pRend->drawableId == PEXAlreadyFreed))
+ return (BadDrawable);
+
+ if (!pwks->postedStructs.numStructs)
+ return (Success);
+
+ switch (ppm->type) {
+ case PEXPickDeviceDC_HitBox:
+ MIWKS_PM_INPUT_REC_1(ppm) = *pIn1;
+ break;
+ case PEXPickDeviceNPC_HitVolume:
+ MIWKS_PM_INPUT_REC_2(ppm) = *pIn2;
+ break;
+ }
+ ppm->status = PEXNoPick;
+
+ trav_state.exec_str_flag = ES_YES;
+ trav_state.p_curr_pick_el = (ddPickPath *) NULL;
+ trav_state.p_curr_sc_el = (ddElementRef *) NULL;
+ /* set to traverse all posted structs */
+ pos = pwks->postedStructs.postruct;
+ pos = pos->next;
+ pstr = pos->pstruct;
+ start_el = 1;
+ num_els = MISTR_NUM_EL((miStructPtr) pstr->deviceData);
+
+
+ BeginPicking(pwks->pRend, pPM);
+
+ /* traverse posted structs */
+ do {
+ /* reset for each structure */
+ trav_state.max_depth = 0;
+ trav_state.pickId = 0;
+ trav_state.ROCoffset = 0;
+
+ if (MISTR_NUM_EL((miStructPtr) pstr->deviceData)) {
+ BeginStructure(pwks->pRend, pstr->id);
+
+ err = traverser( pwks->pRend, pstr, start_el, num_els, pPM,
+ (ddSCStr *)NULL, &trav_state);
+
+ EndStructure(pwks->pRend);
+ }
+ if (pos)
+ if (pos = pos->next) {
+ pstr = pos->pstruct;
+ num_els = MISTR_NUM_EL((miStructPtr) pstr->deviceData);
+ }
+ } while (pos);
+
+ EndPicking(pwks->pRend);
+
+ if (ppm->status == PEXOk) {
+ /* now, update the structure ref counts */
+ path_update_struct_refs(ppm->path, (diResourceHandle) NULL,
+ PICK_RESOURCE, ADD);
+ } else {
+ /* reset pick path??? */
+ return(err);
+ }
+
+ return (Success);
+} /* UpdatePickMeasure */
+
+/*++
+ |
+ | Function Name: CreatePickMeasure
+ |
+ | Function Description:
+ | Handle the PEXCreatePickMeasure request
+ |
+ | Note(s):
+ |
+ --*/
+
+extern void UpdateWksRefs();
+
+ddpex4rtn
+CreatePickMeasure(pWKS, devType, pPM)
+/* in */
+ diWKSHandle pWKS;
+ ddEnumTypeIndex devType;/* pick device type */
+ diPMHandle pPM; /* pick measure handle */
+/* out */
+{
+ register miWksPtr pwks = (miWksPtr) pWKS->deviceData;
+ register miPickMeasureStr *ppm;
+ int dev_index;
+ register miPickDevice *pPickDevice;
+
+#ifdef DDTEST
+ ErrorF(" CreatePickMeasure\n");
+#endif
+
+ MIWKS_PICK_DEV_INDEX(dev_index, devType);
+
+ ppm = (miPickMeasureStr *) xalloc(sizeof(miPickMeasureStr));
+ if (!ppm) return (BadAlloc);
+
+ ppm->path = puCreateList(DD_PICK_PATH);
+ if (!ppm->path) {
+ xfree(ppm);
+ return (BadAlloc);
+ }
+ pPickDevice = &(pwks->devices[dev_index]);
+
+ ppm->pWks = pWKS;
+ ppm->type = devType;
+ ppm->status = pPickDevice->status;
+ ppm->pathOrder = pPickDevice->pathOrder;
+ ppm->incl_handle = pPickDevice->inclusion;
+ ppm->excl_handle = pPickDevice->exclusion;
+
+ if (ppm->incl_handle)
+ UpdateNSRefs( ppm->incl_handle, (diResourceHandle) NULL,
+ PICK_RESOURCE, ADD);
+
+ if (ppm->excl_handle)
+ UpdateNSRefs( ppm->excl_handle, (diResourceHandle) NULL,
+ PICK_RESOURCE, ADD);
+
+
+ if (puCopyList(pPickDevice->path, ppm->path)) {
+ puDeleteList(ppm->path);
+ xfree(ppm);
+ return (BadAlloc);
+ }
+ /* now go through the path and update the structures' ref. count */
+ path_update_struct_refs( ppm->path, (diResourceHandle) NULL,
+ PICK_RESOURCE, ADD);
+
+ switch (dev_index) {
+ case 0:
+ MIWKS_PM_DATA_REC_1(ppm) = MIWKS_PD_DATA_REC_1(pPickDevice);
+ break;
+ case 1:
+ MIWKS_PM_DATA_REC_2(ppm) = MIWKS_PD_DATA_REC_2(pPickDevice);
+ break;
+ }
+
+ /* no extra data for PEX-SI */
+ ppm->devPriv = (ddPointer) NULL;
+
+ UpdateWksRefs(pWKS, (diResourceHandle) ppm, PICK_RESOURCE, ADD);
+ pPM->deviceData = (ddPointer) ppm;
+ return (Success);
+}
+
+
+/*++
+ |
+ | Function Name: FreePickMeasure
+ |
+ | Function Description:
+ | Handles the PEXFreePickMeasure request
+ |
+ | Note(s):
+ pick measure is not used by other resources, so delete it now
+ |
+ --*/
+
+ddpex4rtn
+FreePickMeasure(pPM, PMid)
+/* in */
+ diPMHandle pPM; /* pick measure */
+ ddResourceId PMid; /* pick measure id */
+/* out */
+{
+ register miPickMeasureStr *ppm = (miPickMeasureStr *) pPM->deviceData;
+
+ if (ppm->devPriv) xfree(ppm->devPriv);
+
+ /* go through the path and update the structures' ref. count */
+ if (ppm->path) path_update_struct_refs( ppm->path, (diResourceHandle) NULL,
+ PICK_RESOURCE, REMOVE);
+
+ if (ppm->path) puDeleteList(ppm->path);
+
+ if (ppm->pWks)
+ UpdateWksRefs(ppm->pWks, (diResourceHandle) ppm, PICK_RESOURCE, REMOVE);
+
+ if (ppm->incl_handle)
+ UpdateNSRefs( ppm->incl_handle, (diResourceHandle) NULL,
+ PICK_RESOURCE, REMOVE);
+
+ if (ppm->excl_handle)
+ UpdateNSRefs( ppm->excl_handle, (diResourceHandle) NULL,
+ PICK_RESOURCE, REMOVE);
+
+ xfree(ppm);
+ xfree(pPM);
+
+ return (Success);
+} /* FreePickMeasure */
+
+/*++
+ |
+ | Function Name: InquirePickMeasure
+ |
+ | Function Description:
+ | Handles the PEXInquirePickMeasure request
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+InquirePickMeasure(pPM, itemMask, pNumItems, pBuffer)
+/* in */
+ diPMHandle pPM; /* pick measure */
+ ddBitmask itemMask; /* pick item bit mask */
+/* out */
+ ddULONG *pNumItems; /* number of items returned */
+ ddBufferPtr pBuffer;/* return buffer */
+{
+ register miPickMeasureStr *ppm = (miPickMeasureStr *) pPM->deviceData;
+ register ddULONG dsize = 0;
+ register ddPointer pbuf;
+
+ *pNumItems = 0;
+ pBuffer->dataSize = 0;
+
+ if (itemMask & PEXPMStatus) {
+ dsize += 4;
+ *pNumItems++;
+ }
+ if (itemMask & PEXPMPath) {
+ dsize += (4 + (ppm->path->numObj * 12));
+ *pNumItems++;
+ }
+ PU_CHECK_BUFFER_SIZE(pBuffer, dsize);
+ pBuffer->dataSize = dsize;
+ pbuf = pBuffer->pBuf;
+
+ if (itemMask & PEXPMStatus) {
+ PACK_CARD32(ppm->status,pbuf);
+ }
+ if (itemMask & PEXPMPath) {
+ PACK_CARD32(ppm->path->numObj,pbuf);
+ pbuf = copy_pick_path_to_buffer(ppm->path, pbuf);
+ }
+ return (Success);
+}
+
+static unsigned char *
+copy_pick_path_to_buffer(pPath, pBuf)
+ listofObj *pPath;
+ ddPointer pBuf;
+{
+ register int i;
+ ddPickPath *pp = (ddPickPath *)(pPath->pList);
+ unsigned char *ptr = pBuf;
+
+ for (i = 0; i < pPath->numObj; i++, pp++) {
+ PACK_CARD32(pp->structure->id, ptr);
+ PACK_CARD32(pp->offset, ptr);
+ PACK_CARD32(pp->pickid, ptr);
+ }
+ return (ptr);
+}
+
+/* pick devices and pick measures are counted */
+void
+path_update_struct_refs(pPath, pResource, which, action)
+ listofObj *pPath;
+ diResourceHandle pResource;
+ ddResourceType which;
+ ddAction action;
+{
+ ddPickPath *pp = (ddPickPath *) pPath->pList;
+ register int i;
+
+ for (i = 0; i < pPath->numObj; pp++, i++)
+ UpdateStructRefs(pp->structure, pResource, which, action);
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level4/miSC.c b/xc/programs/Xserver/PEX5/ddpex/mi/level4/miSC.c
new file mode 100644
index 000000000..4e58e5534
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level4/miSC.c
@@ -0,0 +1,212 @@
+/* $TOG: miSC.c /main/5 1998/02/10 12:43:47 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level4/miSC.c,v 1.8 1999/01/31 12:21:29 dawes Exp $ */
+
+
+#include "ddpex4.h"
+#include "mipex.h"
+#include "miStruct.h"
+#include "miStrMacro.h"
+#include "pexUtils.h"
+#include "pexos.h"
+
+
+/* Level 4 Workstation Support */
+/* Search Context procedures */
+
+/*++
+ |
+ | Function Name: SearchNetwork
+ |
+ | Function Description:
+ | Handles the PEXSearchNetwork request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+SearchNetwork(pSC, pNumRefs, pBuffer)
+/* in */
+ ddSCStr *pSC; /* search context */
+/* out */
+ ddULONG *pNumRefs; /* number of references returned in list */
+ ddBufferPtr pBuffer;/* list of element references */
+{
+ miTraverserState trav_state;
+ ddpex4rtn err = Success;
+ diStructHandle pstr;
+ register int i;
+ register pexElementRef *pb;
+ register ddElementRef *pr;
+
+#ifdef DDTEST
+ ErrorF(" SearchNetwork\n");
+#endif
+
+ pSC->status = PEXNotFound;
+ *pNumRefs = 0;
+
+ if (pSC->startPath->numObj) {
+ trav_state.exec_str_flag = ES_FOLLOW_SEARCH;
+ trav_state.p_curr_pick_el = (ddPickPath *) NULL;
+ trav_state.p_curr_sc_el = (ddElementRef *) pSC->startPath->pList;
+ trav_state.max_depth = 0;
+ trav_state.pickId = 0;
+ trav_state.ROCoffset = 0;
+ } else
+ return (PEXERR(PEXPathError));
+
+ pstr = (diStructHandle) trav_state.p_curr_sc_el->structure;
+
+ if (MISTR_NUM_EL((miStructPtr) pstr->deviceData)) {
+ ddRendererStr rend;
+
+ /* init dummy renderer */
+ rend.rendId = PEXAlreadyFreed;
+ rend.pPC = (ddPCPtr)NULL;
+ /* rend.drawExample = ?? */
+ rend.pDrawable = (DrawablePtr)NULL;
+ rend.drawableId = 0;
+ rend.curPath = puCreateList(DD_ELEMENT_REF);
+ if ( !rend.curPath)
+ return(BadAlloc);
+
+ rend.state = PEXIdle;
+ rend.tablesMask = 0;
+ rend.namesetsMask = 0;
+ rend.attrsMask = 0;
+ rend.tablesChanges = 0;
+ rend.namesetsChanges = 0;
+ rend.attrsChanges = 0;
+
+ rend.lut[PEXMarkerBundleLUT] = 0;
+ rend.lut[PEXTextBundleLUT] = 0;
+ rend.lut[PEXLineBundleLUT] = 0;
+ rend.lut[PEXInteriorBundleLUT] = 0;
+ rend.lut[PEXEdgeBundleLUT] = 0;
+ rend.lut[PEXViewLUT] = 0;
+ rend.lut[PEXColourLUT] = 0;
+ rend.lut[PEXDepthCueLUT] = 0;
+ rend.lut[PEXLightLUT] = 0;
+ rend.lut[PEXColourApproxLUT] = 0;
+ rend.lut[PEXPatternLUT] = 0;
+ rend.lut[PEXTextFontLUT] = 0;
+
+ rend.ns[(unsigned)DD_HIGH_INCL_NS] = 0;
+ rend.ns[(unsigned)DD_HIGH_EXCL_NS] = 0;
+ rend.ns[(unsigned)DD_INVIS_INCL_NS] = 0;
+ rend.ns[(unsigned)DD_INVIS_EXCL_NS] = 0;
+
+ rend.hlhsrMode = PEXHlhsrOff;
+ rend.npcSubvolume.minval.x = 0.0;
+ rend.npcSubvolume.minval.y = 0.0;
+ rend.npcSubvolume.minval.z = 0.0;
+ rend.npcSubvolume.maxval.x = 1.0;
+ rend.npcSubvolume.maxval.y = 1.0;
+ rend.npcSubvolume.maxval.z = 1.0;
+
+ /* can't use drawable, it doesn't exist. Is viewport needed??
+ * what viewport to use? default is to use drawable
+ */
+ rend.viewport.useDrawable = 0;
+ rend.viewport.minval.x = 0;
+ rend.viewport.minval.y = 0;
+ rend.viewport.minval.z = 0.0;
+ rend.viewport.maxval.x = 1;
+ rend.viewport.maxval.y = 1;
+ rend.viewport.maxval.z = 1.0;
+ rend.clipList = puCreateList( DD_DEVICE_RECT );
+ if ( !rend.clipList ) {
+ puDeleteList( rend.curPath );
+ return( BadAlloc );
+ }
+
+ rend.immediateMode = FALSE;
+ /* InitRenderer does some stuff not needed for Searching
+ * and since some of that stuff uses a drawable (and searching
+ * doesn't have one), a work-aroundis put in around the drawable
+ * code. * It may be good to sometime reevaluate this and find
+ * another way to deal with it.
+ */
+ err = InitRenderer( &rend );
+ if ( err != Success ) {
+ puDeleteList( rend.curPath );
+ puDeleteList( rend.clipList );
+ return( err );
+ }
+
+ BeginSearching(&rend, pSC);
+
+ BeginStructure(&rend, pstr->id);
+
+ /* always start at the first element in the structure */
+ err = traverser(&rend, pstr, (ddULONG) 1,
+ MISTR_NUM_EL((miStructPtr) pstr->deviceData),
+ (diPMHandle) NULL, pSC, &trav_state);
+
+ EndStructure(&rend);
+
+ /* turn off searching */
+ EndSearching(&rend);
+
+ if (pSC->status == PEXFound) {
+ pBuffer->dataSize = pSC->startPath->numObj * sizeof(pexElementRef);
+ PU_CHECK_BUFFER_SIZE(pBuffer, pBuffer->dataSize);
+ pb = (pexElementRef *)pBuffer->pBuf;
+ pr = (ddElementRef *)pSC->startPath->pList;
+ for (i=pSC->startPath->numObj; i>0; i--, pb++, pr++) {
+ pb->structure = pr->structure->id;
+ pb->offset = pr->offset;
+ }
+ *pNumRefs = pSC->startPath->numObj;
+ } else
+ /* set start path to "not found" */
+ pSC->startPath->numObj = 0;
+ } else
+ return (PEXERR(PEXPathError));
+
+ return (Success);
+} /* SearchNetwork */
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level4/miStruct.c b/xc/programs/Xserver/PEX5/ddpex/mi/level4/miStruct.c
new file mode 100644
index 000000000..68ebb9415
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level4/miStruct.c
@@ -0,0 +1,2487 @@
+/* $TOG: miStruct.c /main/13 1998/02/10 12:43:51 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level4/miStruct.c,v 3.5 1998/10/04 09:34:41 dawes Exp $ */
+
+#include "mipex.h"
+#include "ddpex4.h"
+#include "miStruct.h"
+#include "PEXErr.h"
+#include "PEXproto.h"
+#include "pexError.h"
+#include "pexUtils.h"
+#include "miStrMacro.h"
+#include "pexos.h"
+
+
+/* Level 4 Workstation Support */
+/* Structure Procedures */
+
+extern cssTableType CreateCSSElementTable[];
+extern cssTableType DestroyCSSElementTable[];
+extern cssTableType CopyCSSElementTable[];
+extern cssTableType ReplaceCSSElementTable[];
+extern cssTableType InquireCSSElementTable[];
+
+extern ddBOOL miGetStructurePriority();
+
+extern ddpex4rtn miDealWithStructDynamics();
+extern ddpex4rtn miDealWithDynamics();
+
+void miPrintPath();
+
+#define SET_STR_HEADER(pStruct, pheader) \
+ register miStructPtr pheader = (miStructPtr) pStruct->deviceData
+
+#define DESTROY_STR_HEADER(pheader) \
+ if (pheader->parents) puDeleteList(pheader->parents); \
+ if (pheader->children) puDeleteList(pheader->children); \
+ if (pheader->wksPostedTo) puDeleteList(pheader->wksPostedTo); \
+ if (pheader->wksAppearOn) puDeleteList(pheader->wksAppearOn); \
+ if (MISTR_ZERO_EL(pheader)) xfree(MISTR_ZERO_EL(pheader)); \
+ if (MISTR_LAST_EL(pheader)) xfree(MISTR_LAST_EL(pheader)); \
+ xfree(pheader)
+
+#define CHECK_DELETE(pHandle, pheader) \
+ if ((pheader)->freeFlag && !(pheader)->refCount) { \
+ DESTROY_STR_HEADER(pheader); \
+ xfree(pHandle); \
+ }
+
+/*++
+ |
+ | Function Name: pos2offset
+ |
+ | Function Description:
+ | a utility function for converting whence, offset values to a valid
+ | structure offset
+ |
+ | Note(s):
+ |
+ --*/
+
+static ddpex4rtn
+pos2offset(pstruct, ppos, poffset)
+/* in */
+ miStructStr *pstruct;/* pointer to the structure involved */
+ ddElementPos *ppos; /* the position information */
+/* out */
+ ddULONG *poffset;/* the valid offset calculated from the
+ * postition */
+{
+ ddUSHORT whence = ppos->whence;
+ ddLONG offset = ppos->offset, temp;
+
+#ifdef DDTEST
+ ErrorF(" POSITION : ");
+#endif
+
+ switch (whence) {
+ case PEXBeginning:
+
+#ifdef DDTEST
+ ErrorF("PEXBeginning, ");
+#endif
+
+ temp = offset;
+ break;
+
+ case PEXCurrent:
+
+#ifdef DDTEST
+ ErrorF("PEXCurrent, ");
+#endif
+
+ temp = MISTR_CURR_EL_OFFSET(pstruct) + offset;
+ break;
+
+ case PEXEnd:
+
+#ifdef DDTEST
+ ErrorF("End, ");
+#endif
+
+ /* numElements is the same as the last elements offset */
+ temp = MISTR_NUM_EL(pstruct) + offset;
+ break;
+
+ default:
+
+#ifdef DDTEST
+ ErrorF("Bad Value\n ");
+#endif
+
+ /* value error */
+ return (BadValue);
+ break;
+ }
+
+#ifdef DDTEST
+ ErrorF("%d", offset);
+#endif
+
+ /* now check that the new offset is in range of the structure */
+ if (temp < 0)
+ *poffset = 0;
+ else if (temp > MISTR_NUM_EL(pstruct))
+ *poffset = MISTR_NUM_EL(pstruct);
+ else
+ *poffset = temp;
+
+#ifdef DDTEST
+ ErrorF(" = %d\n", *poffset);
+#endif
+
+ return (0);
+}
+
+/*++
+ |
+ | Function Name: CreateStructure
+ |
+ | Function Description:
+ | Handles the PEXCreateStructure request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+CreateStructure(pStruct)
+/* in */
+ diStructHandle pStruct;/* structure handle */
+/* out */
+{
+ register miStructStr *pheader;
+ register miGenericElementPtr pelement;
+
+#ifdef DDTEST
+ ErrorF("\nCreateStructure %d\n", pStruct->id);
+#endif
+
+ pStruct->deviceData = NULL;
+
+ if ((pheader = (miStructStr *) xalloc(sizeof(miStructStr))) == NULL)
+ return (BadAlloc);
+
+ MISTR_EDIT_MODE(pheader) = PEXStructureInsert;
+ MISTR_NUM_EL(pheader) = 0;
+ MISTR_LENGTH(pheader) = 0;
+
+ pheader->refCount = 0;
+ pheader->freeFlag = MI_FALSE;
+
+ pheader->parents = pheader->children = pheader->wksPostedTo = pheader->wksAppearOn = NULL;
+
+ pheader->parents = puCreateList(DD_STRUCT);
+ pheader->children = puCreateList(DD_STRUCT);
+ pheader->wksPostedTo = puCreateList(DD_WKS);
+ pheader->wksAppearOn = puCreateList(DD_WKS);
+ if ( !pheader->parents || !pheader->children
+ || !pheader->wksPostedTo || !pheader->wksAppearOn) {
+ DESTROY_STR_HEADER(pheader);
+ return (BadAlloc);
+ }
+ /* create dummy first and last elements */
+ if ((pelement = (miGenericElementPtr)xalloc(sizeof(miGenericElementStr)))
+ == NULL) {
+ DESTROY_STR_HEADER(pheader);
+ return (BadAlloc);
+ }
+ MISTR_PREV_EL(pelement) = NULL;
+ MISTR_EL_TYPE(pelement) = PEXOCNil;
+ MISTR_EL_LENGTH(pelement) = 1;
+ MISTR_ZERO_EL(pheader) = MISTR_CURR_EL_PTR(pheader) = pelement;
+ MISTR_CURR_EL_OFFSET(pheader) = 0;
+
+ if ((pelement = (miGenericElementPtr) xalloc(sizeof(miGenericElementStr)))
+ == NULL) {
+ DESTROY_STR_HEADER(pheader);
+ return (BadAlloc);
+ }
+ MISTR_EL_TYPE(pelement) = PEXOCNil;
+ MISTR_EL_LENGTH(pelement) = 1;
+ MISTR_PREV_EL(pelement) = MISTR_ZERO_EL(pheader);
+ MISTR_NEXT_EL(pelement) = NULL;
+ MISTR_NEXT_EL(MISTR_ZERO_EL(pheader)) = pelement;
+ MISTR_LAST_EL(pheader) = pelement;
+
+ pStruct->deviceData = (ddPointer) pheader;
+ return (Success);
+} /* CreateStructure */
+
+/*++
+ |
+ | Function Name: CopyStructure
+ |
+ | Function Description:
+ | Handles the PEXCopyStructure request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+CopyStructure(pSrcStruct, pDestStruct)
+/* in */
+ diStructHandle pSrcStruct; /* source structure */
+ diStructHandle pDestStruct; /* destination structure */
+{
+ SET_STR_HEADER(pSrcStruct, psource);
+ SET_STR_HEADER(pDestStruct, pdest);
+ ddpex4rtn err = Success;
+ ddElementRange sourceRange;
+ ddElementPos destPos;
+ miGenericElementPtr pel;
+ register ddULONG i;
+
+#ifdef DDTEST
+ ErrorF("\nCopyStructure\n");
+#endif
+
+ /* to do: make this smarter so it can use Replace if possible */
+
+ i = MISTR_NUM_EL(pdest);
+ MISTR_DEL_ELS(pDestStruct, pdest, 1, i); /* can't use NUM_EL macro here
+ * because the num of els
+ * changes as they are deleted */
+
+ MISTR_CURR_EL_OFFSET(pdest) = 0;
+ MISTR_CURR_EL_PTR(pdest) = MISTR_ZERO_EL(pdest);
+
+ sourceRange.position1.whence = PEXBeginning;
+ sourceRange.position1.offset = 0;
+ sourceRange.position2.whence = PEXEnd;
+ sourceRange.position2.offset = 0;
+ destPos.whence = PEXBeginning;
+ destPos.offset = 0;
+
+ /* Copy Elements will redraw picture if nec */
+ if (err = CopyElements(pSrcStruct, &sourceRange, pDestStruct, &destPos)
+ != Success)
+ return (err);
+
+ MISTR_EDIT_MODE(pdest) = MISTR_EDIT_MODE(psource);
+ MISTR_CURR_EL_OFFSET(pdest) = MISTR_CURR_EL_OFFSET(psource);
+
+ MISTR_FIND_EL(pdest, MISTR_CURR_EL_OFFSET(pdest), pel);
+ MISTR_CURR_EL_PTR(pdest) = pel;
+
+ return (Success);
+} /* CopyStructure */
+
+/* find_execute_structure looks for the specified execute structure element
+ * If the specified structure is NULL, then it finds the next one.
+ * If the element is found, its offset from the start is returned in poffset
+ * When calling this repeatedly to look for all occurrences of the element,
+ * be sure to check that you've reached the end of the structure. Otherwise
+ * you would infinitely loop on finding the last element if it is a match.
+ */
+static ddpex4rtn
+find_execute_structure(pStruct, pStartPos, structHandle, poffset)
+diStructHandle pStruct;/* search this structure */
+ddElementPos *pStartPos;
+diStructHandle structHandle; /* for this exec structure element */
+ddULONG *poffset;
+{
+ SET_STR_HEADER(pStruct, pstruct);
+ ddUSHORT foundExecuteElement;
+ ddUSHORT executeStructureElement = PEXOCExecuteStructure;
+ miGenericElementPtr pel;
+ ddpex4rtn err = Success;
+
+ while (err == Success) {
+ /** Get the position of the next execute structure element **/
+ err = ElementSearch( pStruct, pStartPos, (ddULONG) PEXForward,
+ (ddULONG) 1, (ddULONG) 0,
+ &executeStructureElement, (ddUSHORT *) NULL,
+ &foundExecuteElement, poffset);
+
+ if (foundExecuteElement == PEXFound) {
+ MISTR_FIND_EL(pstruct, *poffset, pel);
+
+ if ( (structHandle == (diStructHandle) MISTR_GET_EXSTR_STR(pel))
+ || (structHandle == (diStructHandle) NULL))
+ return (PEXFound);
+
+ /*
+ * continue searching at the next element unless this one
+ * was the last
+ */
+ if (*poffset == MISTR_NUM_EL(pstruct)) return (PEXNotFound);
+
+ pStartPos->whence = PEXBeginning;
+ pStartPos->offset = *poffset + 1;
+ } else
+ return (PEXNotFound);
+
+ }
+ if (err != Success) return (PEXNotFound);
+ return (PEXFound);
+}
+
+/*++
+ |
+ | Function Name: DeleteStructureRefs
+ |
+ | Function Description:
+ | Handles the PEXDeleteStructures request.
+ |
+ | This routine deletes all structure elements in all of the
+ | structures which reference the specified structure. It is called
+ | by DeleteStructure.
+ |
+ | Note(s):
+ | This does not correct the picture because it is called by
+ | DeleteStructure, which does correct it
+ |
+ --*/
+
+ddpex4rtn
+DeleteStructureRefs(pStruct)
+/* in */
+ diStructHandle pStruct;/* structure handle */
+/* out */
+{
+
+ SET_STR_HEADER(pStruct, pstruct);
+ diStructHandle parentHandle;
+ miStructPtr pparentStruct;
+ ddElementPos position;
+ miGenericElementPtr newPointer;
+ miGenericElementPtr pel, pprevel;
+ ddLONG newOffset;
+ ddULONG offsetFromStart, numParents;
+
+#ifdef DDTEST
+ ErrorF("\nDeleteStructureRefs of structure %d\n", pStruct->id);
+#endif /* DDTEST */
+
+ /** Search through each of the structure's parents **/
+
+ /*
+ * The tricky part here is that each time the execute structure
+ * element is deleted from the parent, the structure's parent list
+ * changes (in DeleteElements) so, remember how many parents there
+ * originally are and look at that many. Each time a parent is
+ * deleted from the list, it's always deleted from the front of the
+ * list, so the next parent will be at the front of the list the next
+ * time through
+ */
+ for (numParents = pstruct->parents->numObj; numParents > 0;) {
+ parentHandle = *(diStructHandle *) pstruct->parents->pList;
+
+ /*
+ * look through all of this structure's elements to delete
+ * all references to the structure being deleted
+ */
+ pparentStruct = (miStructPtr) (parentHandle)->deviceData;
+
+ newOffset = 0;
+ newPointer = NULL;
+
+ /*
+ * look for all execute structure (child) elements in the
+ * parent structure and delete them this could do only one
+ * element at a time. any other elements would be gotten
+ * later because the parent is duplicated in the childs list
+ * for each occurrence and the outer loop would find the
+ * parent again.
+ */
+ /* start looking at the beginning of the parent structure */
+ position.whence = PEXBeginning;
+ position.offset = 0;
+
+ /*
+ * dont' forget we're really comparing the structure handles
+ * because the id was replaced with the handle in the exec
+ * str elements
+ */
+ while (find_execute_structure( parentHandle, &position, pStruct,
+ &offsetFromStart)
+ == PEXFound) {
+ if (offsetFromStart == MISTR_CURR_EL_OFFSET(pparentStruct)) {
+ newOffset = MISTR_CURR_EL_OFFSET(pparentStruct) - 1;
+ newPointer = MISTR_PREV_EL(MISTR_CURR_EL_PTR(pparentStruct));
+ } else if (offsetFromStart < MISTR_CURR_EL_OFFSET(pparentStruct)) {
+ newOffset = MISTR_CURR_EL_OFFSET(pparentStruct) - 1;
+ newPointer = MISTR_CURR_EL_PTR(pparentStruct);
+ } else {
+ newOffset = MISTR_CURR_EL_OFFSET(pparentStruct);
+ newPointer = MISTR_CURR_EL_PTR(pparentStruct);
+ }
+
+ MISTR_FIND_EL(pparentStruct, offsetFromStart, pel);
+ pprevel = MISTR_PREV_EL(pel);
+
+ MISTR_DEL_ONE_EL(parentHandle, pprevel, pel);
+
+ MISTR_CURR_EL_PTR(pparentStruct) = newPointer;
+ MISTR_CURR_EL_OFFSET(pparentStruct) = newOffset;
+
+ numParents--;
+
+ /*
+ * continue looking for other execute structures
+ * after the one found but it just got deleted, so
+ * the next one is now the same offset as the old one
+ */
+ position.whence = PEXBeginning;
+ position.offset = offsetFromStart;
+ }
+
+ }
+
+ return (Success);
+} /* DeleteStructureRefs */
+
+/*++
+ |
+ | Function Name: DeleteStructure
+ |
+ | Function Description:
+ | Deletes all storage associated with the structure
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+DeleteStructure(pStruct, Sid)
+/* in */
+ diStructHandle pStruct;/* structure handle */
+ ddResourceId Sid; /* structure resource id */
+/* out */
+{
+ SET_STR_HEADER(pStruct, pheader);
+ register ddULONG i, imax;
+ diWKSHandle pwks;
+ ddpex4rtn err = Success, next_err = Success;
+ listofObj *pwksToLookAt;
+
+#ifdef DDTEST
+ ErrorF("\nDeleteStructure %d\n", pStruct->id);
+#endif
+
+ /*
+ * Errors are ignored to try to delete and update as much info as possible;
+ * however, if an error is found, the last error detected is returned.
+ */
+
+ /*
+ * Save the posted to list before unposting this structure so wks
+ * pictures can be updated if necessary.
+ */
+ /* Do this here before the parent and children lists are changed. */
+
+ /** Build up a list of workstations from the PostedTo and AppearOn
+ ** lists in the structure structure. They are inserted in such a
+ ** manner so that duplicates between the lists are eliminated.
+ **/
+
+ pwksToLookAt = (listofObj *) NULL;
+
+ if (pheader->wksPostedTo->numObj || pheader->wksAppearOn->numObj) {
+ pwksToLookAt = puCreateList(DD_WKS);
+ if (!pwksToLookAt) err = BadAlloc;
+ else
+ err = puMergeLists( pheader->wksPostedTo, pheader->wksAppearOn,
+ pwksToLookAt);
+ }
+
+ /*
+ * This changes the structures posted to list (because unpost removes
+ * the wks from this list) so always get the first wks from the list.
+ */
+ imax = pheader->wksPostedTo->numObj;
+ for (i = 0; i < imax; i++) {
+ pwks = ((diWKSHandle *) pheader->wksPostedTo->pList)[0];
+ next_err = UnpostStructure(pwks, pStruct);
+ }
+
+ /*
+ * Now, delete all of the references to this struct (i.e. remove this
+ * structure from its parents).
+ */
+ next_err = DeleteStructureRefs(pStruct);
+ if (next_err != Success) err = next_err;
+
+ /* loop through to delete all of the elements */
+ i = MISTR_NUM_EL(pheader);
+ MISTR_DEL_ELS(pStruct, pheader, 1, i);
+
+ /* now redraw picture for all workstations (determined above) */
+ if (pwksToLookAt) {
+ next_err = miDealWithDynamics(DELETE_STR_DYNAMIC, pwksToLookAt);
+ if (next_err != Success) err = next_err;
+ puDeleteList(pwksToLookAt);
+ }
+
+ /*
+ * Don't delete the structure until sc and pick resources aren't using it.
+ */
+ pStruct->id = PEXAlreadyFreed;
+ pheader->freeFlag = MI_TRUE;
+ CHECK_DELETE(pStruct, pheader);
+
+ return (err);
+} /* DeleteStructure */
+
+/*++
+ |
+ | Function Name: InquireStructureInfo
+ |
+ | Function Description:
+ | Handles the PEXGetStructureInfo request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+InquireStructureInfo(fpFormat, pStruct, itemMask, pEditMode, pElOffset, pNumElements, pLength, pHasRefs)
+/* in */
+ ddEnumTypeIndex fpFormat;
+ diStructHandle pStruct; /* structure handle */
+ ddBitmask itemMask;
+/* out */
+ ddUSHORT *pEditMode; /* edit mode */
+ ddULONG *pElOffset; /* current element pointer */
+ ddULONG *pNumElements; /* number of elements in structure */
+ ddULONG *pLength; /* total size of structure */
+ ddUSHORT *pHasRefs; /* is structure referenced by others */
+{
+ SET_STR_HEADER(pStruct, pheader);
+
+#ifdef DDTEST
+ ErrorF("\nInquireStructureInfo of %d\n", pStruct->id);
+#endif
+
+ /* Since all info is easily available and this is a fixed-length
+ * request, ignore itemMask (to the dismay of lint).
+ */
+ *pEditMode = MISTR_EDIT_MODE(pheader);
+ *pElOffset = MISTR_CURR_EL_OFFSET(pheader);
+ *pNumElements = MISTR_NUM_EL(pheader);
+
+ /*
+ * test here: if fpFormat is double precision, then recalculate
+ * length
+ */
+ *pLength = MISTR_LENGTH(pheader);
+ *pHasRefs = MISTR_NUM_PARENTS(pheader) != 0;
+ return (Success);
+} /* InquireStructureInfo */
+
+/*++
+ |
+ | Function Name: InquireElementInfo
+ |
+ | Function Description:
+ | Handles the PEXGetElementInfo request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+InquireElementInfo(pStruct, pRange, pNumElements, pBuffer)
+/* in */
+ diStructHandle pStruct;/* structure handle */
+ ddElementRange *pRange; /* element range */
+/* out */
+ ddULONG *pNumElements; /* number of items in list */
+ ddBufferPtr pBuffer;/* list of element information */
+{
+ SET_STR_HEADER(pStruct, pheader);
+ ddULONG offset1, offset2, needbytes, i;
+ int peisize;
+ ddPointer pbuf;
+ miGenericElementPtr pel;
+
+#ifdef DDTEST
+ ErrorF("\nInquireElementInfo %d\n", pStruct->id);
+#endif
+
+ peisize = sizeof(pexElementInfo);
+
+ if (pos2offset(pheader, &(pRange->position1), &offset1))
+ return (BadValue); /* bad whence value */
+
+ if (pos2offset(pheader, &(pRange->position2), &offset2))
+ return (BadValue); /* bad whence value */
+
+ if (offset1 > offset2) {
+ i = offset1;
+ offset1 = offset2;
+ offset2 = i;
+ }
+
+ if (offset1 == 0)
+ if (offset2 == 0)
+ return(Success);
+ else
+ offset1 = 1;
+
+
+ /* make sure buffer is large enough */
+ needbytes = (offset2 - offset1 + 1) * peisize;
+ PU_CHECK_BUFFER_SIZE(pBuffer, needbytes);
+
+ pbuf = pBuffer->pBuf;
+
+ MISTR_FIND_EL(pheader, offset1, pel);
+
+ /*
+ * remember that element data is required to have the type & length
+ * first so this is portable
+ */
+ for (i = offset1; i <= offset2; i++, pbuf += peisize) {
+ mibcopy(&MISTR_EL_DATA(pel), pbuf, peisize);
+ pel = MISTR_NEXT_EL(pel);
+ }
+
+ *pNumElements = offset2 - offset1 + 1;
+ pBuffer->dataSize = *pNumElements * peisize;
+
+ return (Success);
+} /* InquireElementInfo */
+
+static ddpex4rtn
+get_structure_net(pStruct, plist)
+ diStructHandle pStruct;
+ listofObj *plist;
+{
+ SET_STR_HEADER(pStruct, pheader);
+ register int i;
+ register diStructHandle *pchild;
+
+ /* put this structure on the list */
+ if (puAddToList((ddPointer) & pStruct, (ddULONG) 1, plist) ==
+ MI_ALLOCERR)
+ return (BadAlloc);
+
+ /* loop through all of the children of this structure */
+ pchild = (diStructHandle *) pheader->children->pList;
+ for (i = 0; i < pheader->children->numObj; i++, pchild++)
+ if (get_structure_net(*pchild, plist) == BadAlloc)
+ return (BadAlloc);
+
+ return (Success);
+}
+
+/*++
+ |
+ | Function Name: InquireStructureNetwork
+ |
+ | Function Description:
+ | Handles the PEXGetStructuresInNetwork request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+InquireStructureNetwork(pStruct, which, pNumSids, pBuffer)
+/* in */
+ diStructHandle pStruct; /* structure handle */
+ ddUSHORT which; /* which structures to inquire */
+/* out */
+ ddULONG *pNumSids; /* number of ids in list */
+ ddBufferPtr pBuffer; /* list of structure ids */
+{
+ register int i, j, num;
+ ddResourceId *pbuf;
+ ddStructResource **pstruct, **pparent;
+ listofObj *plist1, *plist2;
+ ddBOOL removing;
+
+#ifdef DDTEST
+ ErrorF("\nInquireStructureNetwork\n");
+#endif
+
+ pBuffer->dataSize = 0;
+ *pNumSids = 0;
+
+ plist1 = puCreateList(DD_STRUCT);
+ if (!plist1) return (BadAlloc);
+
+ plist2 = puCreateList(DD_STRUCT);
+ if (!plist2) {
+ puDeleteList(plist1);
+ return (BadAlloc);
+ }
+
+ if (get_structure_net(pStruct, plist1) != Success) {
+ puDeleteList(plist1);
+ puDeleteList(plist2);
+ return (BadAlloc);
+ }
+ /* now, make the list unique */
+ puMergeLists(plist1, plist2, plist2);
+
+ /* adjust for orphans if requested */
+ if (which == PEXOrphans) {
+
+ /*
+ * Look at the parents of each structure in list 3 if any parent is
+ * not in the list, then that structure is not an orphan (i.e., it
+ * is referenced by a structure not in this net), so remove it from
+ * the list.
+ *
+ * This is a pain though, because we aren't guaranteed that all
+ * parents of a structure precede it in the list; e.g., if plist2
+ * for the network below starting at A is A, B, C, D, then when C
+ * is reached, both of its parents (B & D) are in the list, so it
+ * won't be deleted. But when D is reached, (after C) it will have
+ * parent E not in the list, so D will be deleted. Now C should be
+ * deleted also.
+ *
+ * A E / \ / B D \ / C
+ *
+ * My solution to this is to loop through plist2 multiple times until
+ * it is gone through once without any structs being deleted from it.
+ * If you have a better algorithm for this, then tell me about it.
+ * One solution is to guarantee the list has all parents in it before
+ * their children. I can't think of a way to do this, however.
+ */
+ removing = MI_TRUE;
+ while (removing) {
+ removing = MI_FALSE;
+ pstruct = (ddStructResource **) plist2->pList;
+
+ /*
+ * Note, while going through the list, it may be changed, so be
+ * careful of when pstruct gets incremented and be sure num
+ * reflects the original size of the list, not any changes made
+ * to it.
+ */
+ num = plist2->numObj;
+ for (i = 0; i < num; i++, pstruct++) {
+ pparent = (ddStructResource **)((miStructPtr)(*pstruct)->deviceData)->parents->pList;
+ for ( j = 0;
+ j < ((miStructPtr)(*pstruct)->deviceData)->parents->numObj;
+ j++, pparent++) {
+ if (!puInList((ddPointer) pparent, plist2)) {
+
+ /*
+ * This struct is not an orphan.
+ */
+ puRemoveFromList((ddPointer) pstruct, plist2);
+ removing = MI_TRUE;
+
+ /*
+ * Decrement the pointer so when it gets incremented
+ * in the for loop, it points to where the deleted
+ * struct was,
+ */
+ pstruct--;
+ break;
+ }
+ }
+ }
+ }
+ }
+ /* now, return the structure ids */
+ if (PU_BUF_TOO_SMALL(pBuffer, plist2->numObj * sizeof(ddResourceId))) {
+ if (puBuffRealloc(pBuffer, (ddULONG) plist2->numObj) != Success) {
+ pBuffer->dataSize = 0;
+ puDeleteList(plist1);
+ puDeleteList(plist2);
+ return (BadAlloc);
+ }
+ }
+ *pNumSids = plist2->numObj;
+ pbuf = (ddResourceId *) pBuffer->pBuf;
+ pstruct = (ddStructResource **) plist2->pList;
+ for (i = 0; i < plist2->numObj; i++, pbuf++, pstruct++)
+ *pbuf = (*pstruct)->id;
+
+ pBuffer->dataSize = plist2->numObj * sizeof(ddResourceId);
+
+ puDeleteList(plist1);
+ puDeleteList(plist2);
+ return (Success);
+} /* InquireStructureNetwork */
+
+
+/* bufSave is the size of the buffer header when the buffer is
+ * passed into inq ancestors/descendants. the pBuf pointer
+ * is changed as paths are added to the buffers and bufSave
+ * is used to find where pBuf originally started
+ */
+static int bufSave;
+
+#define MI_ANCESTORS 0
+#define MI_DESCENDANTS 1
+
+/* given a path, which is a list of descendants (in top-down order)
+ * or ancestors (in bottom-down order), see if the depth-length
+ * pathPart part of the list matches any of the lists already
+ * put in the buffer. If it doesn't, then it's unique and this
+ * proc returns MI_TRUE, else it returns MI_FALSE
+ */
+static ddBYTE
+path_unique(pathPart, depth, pNumLists, pBuffer, pPath, which)
+ ddUSHORT pathPart;
+ ddULONG depth;
+ ddULONG *pNumLists;
+ ddBufferPtr pBuffer;
+ listofObj *pPath; /* current path */
+ ddSHORT which;
+{
+ register int i, j;
+ ddPointer pb;
+ ddULONG *ll;
+ ddElementRef *pref, *ppath, *pathstart;
+ ddBYTE match;
+
+ if (!depth || pPath->numObj < depth) depth = pPath->numObj;
+
+ pb = pBuffer->pHead + bufSave;
+ pathstart = (ddElementRef *) pPath->pList;
+ if (which == MI_DESCENDANTS)
+ pathstart += (pathPart == PEXTopPart) ? 0 : pPath->numObj - depth;
+ else
+ pathstart += ((pathPart == PEXTopPart) ? pPath->numObj - 1 : depth - 1);
+
+ for (i = 0; i < *pNumLists; i++) {
+ ll = (ddULONG *) pb;
+ pb += 4;
+ pref = (ddElementRef *) pb;
+ ppath = pathstart;
+ match = MI_TRUE;
+ if (*ll == depth) {
+ if (which==MI_DESCENDANTS) {/* descendants: increment through path */
+ for (j = 0; (j < *ll && match); j++, pref++, ppath++) {
+ if ( (ppath->structure != pref->structure)
+ || (ppath->offset != pref->offset))
+ match = MI_FALSE;
+ }
+ } else {/* ancestors: decrement through path */
+ for (j = 0; (j < *ll && match); j++, pref++, ppath--) {
+ if ( (ppath->structure != pref->structure)
+ || (ppath->offset != pref->offset))
+ match = MI_FALSE;
+ }
+ }
+ }
+ pb += *ll * sizeof(ddElementRef);
+ if (match) return (MI_FALSE);
+ }
+
+ return (MI_TRUE);
+}
+
+static ddpex4rtn
+copy_list_to_buf(pathPart, depth, pNumLists, pBuffer, pPath, which)
+ ddUSHORT pathPart;
+ ddULONG depth;
+ ddULONG *pNumLists;
+ ddBufferPtr pBuffer;
+ listofObj *pPath;
+ ddSHORT which;
+{
+ ddUSHORT listsize;
+ ddULONG *pb;
+ ddElementRef *pref, *pbref;
+
+ if (!depth || (pPath->numObj < depth))
+ depth = pPath->numObj;
+ listsize = depth * sizeof(ddElementRef);
+ PU_CHECK_BUFFER_SIZE(pBuffer, listsize + 4);
+
+ pb = (ddULONG *) pBuffer->pBuf;
+ *pb++ = depth;
+ pref = (ddElementRef *) pPath->pList;
+ if (which == MI_DESCENDANTS) {
+ if (pathPart == PEXTopPart)
+ mibcopy(pref, pb, listsize);
+ else {
+ pbref = (ddElementRef *) pb;
+ pref += pPath->numObj - 1;
+ while (depth--)
+ *pbref++ = *pref--;
+ }
+ } else {
+ if (pathPart == PEXBottomPart)
+ mibcopy(pref, pb, listsize);
+ else {
+ pbref = (ddElementRef *) pb;
+ pref += pPath->numObj - 1;
+ while (depth--)
+ *pbref++ = *pref--;
+ }
+ }
+ (*pNumLists)++;
+ pBuffer->pBuf += listsize + 4;
+ pBuffer->dataSize += listsize + 4;
+
+ return (Success);
+}
+
+static ddpex4rtn
+get_ancestors(pStruct, pathPart, depth, pNumLists, pBuffer, pPath)
+ diStructHandle pStruct;
+ ddUSHORT pathPart;
+ ddULONG depth;
+ ddULONG *pNumLists;
+ ddBufferPtr pBuffer;
+ listofObj *pPath; /* current path */
+{
+ SET_STR_HEADER(pStruct, pheader);
+ diStructHandle pParent;
+ miStructPtr pparent;
+ register int num;
+ ddElementRef newref;
+ ddULONG offset;
+ ddElementPos position;
+ ddpex4rtn err;
+ listofObj *singleparents;
+
+ /* start out with the current struct */
+ if (!pPath->numObj) {
+ newref.structure = (diStructHandle) pStruct->id;
+ newref.offset = 0;
+ if (puAddToList((ddPointer) & newref, (ddULONG) 1, pPath) != Success)
+ return (BadAlloc);
+ }
+ /* we're at the root or have gone far enough */
+ num = pheader->parents->numObj;
+ if (!num || ((pathPart==PEXBottomPart) && depth && (pPath->numObj==depth))) {
+ if ( (pathPart == PEXTopPart) && depth && (pPath->numObj > depth)
+ && !path_unique( pathPart, depth, pNumLists, pBuffer, pPath,
+ MI_ANCESTORS))
+
+ /*
+ * if path is top first and has to be truncated to depth, don't
+ * add it to the buffer unless it's unique
+ */
+ err = Success;
+ else
+ err = copy_list_to_buf( pathPart, depth, pNumLists, pBuffer, pPath,
+ MI_ANCESTORS);
+
+/*>>> pPath->numObj--; */
+ return (err);
+ }
+
+ /* take duplicates out of the list of parents */
+ singleparents = puCreateList(DD_STRUCT);
+ if (!singleparents) return (BadAlloc);
+
+ if (puMergeLists(pheader->parents, singleparents, singleparents) != Success)
+ return (BadAlloc);
+
+ num = singleparents->numObj;
+ while (num--) {
+ pParent = ((diStructHandle *) singleparents->pList)[num];
+ pparent = (miStructPtr) pParent->deviceData;
+
+ /*
+ * now, look for each execute structure of this structure in the parent
+ */
+ position.whence = PEXBeginning;
+ position.offset = 0;
+
+ while (find_execute_structure(pParent, &position, pStruct, &offset)
+ == PEXFound) {
+
+ newref.structure = (diStructHandle) pParent->id;
+ newref.offset = offset;
+ if (puAddToList((ddPointer) & newref, (ddULONG) 1, pPath) != Success)
+ return (BadAlloc);
+
+ /*
+ * get the ancestors of this parent struct
+ */
+ if (err = get_ancestors( pParent, pathPart, depth, pNumLists,
+ pBuffer, pPath) != Success)
+ return (err);
+
+ /*
+ * go on to get the next exec struct element in the parent
+ */
+ position.whence = PEXBeginning;
+ position.offset = offset + 1;
+
+ /*
+ * Remove previous parent/ofset from the pathlist so the same
+ * pathlist can be used for the next path.
+ */
+ pPath->numObj--;
+
+ /*
+ * if the last one found was the last element in the
+ * struct, don't continue
+ */
+ if (offset == MISTR_NUM_EL(pparent)) break;
+
+ } /* end while finding execute structure elements in the parent */
+ } /* end while (num--): while this child has parents to look at */
+
+ puDeleteList(singleparents);
+
+ return (Success);
+}
+
+static ddpex4rtn
+get_descendants(pStruct, pathPart, depth, pNumLists, pBuffer, pPath)
+ diStructHandle pStruct;
+ ddUSHORT pathPart;
+ ddULONG depth;
+ ddULONG *pNumLists;
+ ddBufferPtr pBuffer;
+ listofObj *pPath; /* current path */
+{
+ SET_STR_HEADER(pStruct, pheader);
+ register int num;
+ ddElementRef newref;
+ diStructHandle newstruct;
+ ddULONG offset;
+ ddElementPos position;
+ ddpex4rtn err;
+ miGenericElementPtr pel;
+
+ /* if we're at the end of the path put the path in the buffer */
+ num = pheader->children->numObj;
+ if (!num || ((pathPart == PEXTopPart) && depth && (pPath->numObj == depth))){
+ /* add this structure to the path */
+
+ /*
+ * don't need to do this if (pathPart == PEXTopPart) && depth
+ * && (pPath->numObj == depth), but it's ok to do it because
+ * it won't get put into the buffer
+ */
+ newref.structure = (diStructHandle) pStruct->id;
+ newref.offset = 0;
+ if (puAddToList((ddPointer) & newref, (ddULONG) 1, pPath) != Success)
+ return (BadAlloc);
+
+ if ( (pathPart == PEXBottomPart) && depth && (pPath->numObj > depth)
+ && !path_unique( pathPart, depth, pNumLists, pBuffer, pPath,
+ MI_DESCENDANTS))
+
+ /*
+ * If path is bottom first and has to be truncated to depth,
+ * don't add it to the buffer unless it's unique.
+ */
+ err = Success;
+ else
+ err = copy_list_to_buf( pathPart, depth, pNumLists, pBuffer, pPath,
+ MI_DESCENDANTS);
+
+ pPath->numObj--;
+ return (err);
+ }
+
+ /* now, look for each execute structure element in the structure */
+ position.whence = PEXBeginning;
+ position.offset = 0;
+ while (find_execute_structure( pStruct, &position, (diStructHandle) NULL,
+ &offset)
+ == PEXFound) {
+ newref.structure = (diStructHandle) pStruct->id;
+ newref.offset = offset;
+ if (puAddToList((ddPointer) & newref, (ddULONG) 1, pPath) != Success)
+ return (BadAlloc);
+
+ /*
+ * get the descendants of this child struct remember,
+ */
+ MISTR_FIND_EL(pheader, offset, pel);
+
+ newstruct = (diStructHandle) MISTR_GET_EXSTR_STR(pel);
+ if (err = get_descendants( newstruct, pathPart, depth, pNumLists,
+ pBuffer, pPath) != Success)
+ return (err);
+
+ /* go on to get the next child */
+ position.whence = PEXBeginning;
+ position.offset = offset + 1;
+
+ /*
+ * remove previous child from the pathlist so the same
+ * pathlist can be used for the next path
+ */
+ pPath->numObj--;
+
+ /*
+ * if the last one found was the last element in the struct,
+ * don't continue
+ */
+ if (offset == MISTR_NUM_EL(pheader)) break;
+ }
+
+ return (Success);
+}
+
+/*++
+ |
+ | Function Name: InquireAncestors
+ |
+ | Function Description:
+ | Handles the PEXGetAncestors request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+InquireAncestors(pStruct, pathPart, depth, pNumLists, pBuffer)
+/* in */
+ diStructHandle pStruct;/* structure handle */
+ ddUSHORT pathPart; /* which paths to return */
+ ddULONG depth; /* how deep to search */
+/* out */
+ ddULONG *pNumLists; /* number of lists returned */
+ ddBufferPtr pBuffer;/* list of lists of element refs */
+{
+ listofObj *pathlist;
+ ddpex4rtn err;
+
+#ifdef DDTEST
+ ErrorF("\nInquireAncestors\n");
+#endif
+
+ bufSave = PU_BUF_HDR_SIZE(pBuffer);
+ pBuffer->dataSize = 0;
+ *pNumLists = 0;
+
+ pathlist = puCreateList(DD_ELEMENT_REF);
+ if (!pathlist) return (BadAlloc);
+
+ err = get_ancestors(pStruct, pathPart, depth, pNumLists, pBuffer, pathlist);
+
+ pBuffer->pBuf = pBuffer->pHead + bufSave;
+ puDeleteList(pathlist);
+ return (err);
+} /* InquireAncestors */
+
+/*++
+ |
+ | Function Name: InquireDescendants
+ |
+ | Function Description:
+ | Handles the PEXGetDescendants request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+InquireDescendants(pStruct, pathPart, depth, pNumLists, pBuffer)
+/* in */
+ diStructHandle pStruct; /* structure handle */
+ ddUSHORT pathPart; /* which paths to return */
+ ddULONG depth; /* how deep to search */
+/* out */
+ ddULONG *pNumLists; /* number of lists returned */
+ ddBufferPtr pBuffer; /* list of lists of element refs */
+{
+ listofObj *pathlist;
+ ddpex4rtn err;
+
+#ifdef DDTEST
+ ErrorF("\nInquireDescendants\n");
+#endif
+
+ bufSave = PU_BUF_HDR_SIZE(pBuffer);
+ pBuffer->dataSize = 0;
+ *pNumLists = 0;
+
+ pathlist = puCreateList(DD_ELEMENT_REF);
+ if (!pathlist) return (BadAlloc);
+
+ err = get_descendants(pStruct, pathPart, depth, pNumLists, pBuffer,pathlist);
+
+ pBuffer->pBuf = pBuffer->pHead + bufSave;
+ puDeleteList(pathlist);
+ return (err);
+} /* InquireDescendants */
+
+
+/*++
+ |
+ | Function Name: InquireElements
+ |
+ | Function Description:
+ | Handles the PEXFetchElements request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+InquireElements(pStruct, pRange, pNumOCs, pBuffer)
+/* in */
+ diStructHandle pStruct;/* structure handle */
+ ddElementRange *pRange; /* range of elements */
+/* out */
+ ddULONG *pNumOCs;/* number of items in list */
+ ddBufferPtr pBuffer;/* list of element OCs */
+{
+ SET_STR_HEADER(pStruct, pheader);
+ ddULONG offset1, offset2, i;
+ miGenericElementPtr pel;
+ ddpex4rtn err;
+
+#ifdef DDTEST
+ ErrorF("\nInquireElements of %d\n", pStruct->id);
+#endif
+
+ *pNumOCs = 0;
+
+ if (pheader->numElements == 0) return(Success);
+
+ if (pos2offset(pheader, &(pRange->position1), &offset1))
+ return (BadValue); /* bad whence value */
+
+ if (pos2offset(pheader, &(pRange->position2), &offset2))
+ return (BadValue); /* bad whence value */
+
+ if (offset1 > offset2) {
+ i = offset1;
+ offset1 = offset2;
+ offset2 = i;
+ }
+
+ if (offset1 == 0)
+ if (offset2 == 0)
+ return(Success);
+ else
+ offset1 = 1;
+
+ MISTR_FIND_EL(pheader, offset1, pel);
+
+ for (i = offset1; i <= offset2; i++) {
+ /* Propreitary calls (and OCNil) through 0th Table Entry */
+ if (MI_HIGHBIT_ON(MISTR_EL_TYPE(pel)))
+ err = (*InquireCSSElementTable[MI_OC_PROP])
+ (pel, pBuffer, &(pBuffer->pBuf));
+ else {
+ /* not Proprietary see if valid PEX OC */
+ if (MI_IS_PEX_OC(MISTR_EL_TYPE(pel)))
+ err = (*InquireCSSElementTable[MISTR_EL_TYPE(pel)])
+ (pel, pBuffer, &(pBuffer->pBuf));
+ else
+ err = !Success;
+ }
+
+ if (err != Success) {
+ *pNumOCs = i - offset1;
+ return (err);
+ }
+ pBuffer->dataSize += sizeof(CARD32)
+ *(((ddElementInfo *)(pBuffer->pBuf))->length);
+ pBuffer->pBuf += sizeof(CARD32)
+ * (((ddElementInfo *)(pBuffer->pBuf))->length);
+
+ pel = MISTR_NEXT_EL(pel);
+ }
+
+ *pNumOCs = offset2 - offset1 + 1;
+ return (Success);
+
+} /* InquireElements */
+
+/*++
+ |
+ | Function Name: SetEditMode
+ |
+ | Function Description:
+ | Handles the PEXSetEditingMode request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+SetEditMode(pStruct, editMode)
+/* in */
+ diStructHandle pStruct;/* structure handle */
+ ddUSHORT editMode; /* edit mode */
+/* out */
+{
+ SET_STR_HEADER(pStruct, pheader);
+
+#ifdef DDTEST
+ ErrorF("\nSetEditMode of %d\n", pStruct->id);
+#endif
+
+ switch (editMode) {
+ case PEXStructureInsert:
+ case PEXStructureReplace:
+ MISTR_EDIT_MODE(pheader) = editMode;
+ return (Success);
+
+ default:
+ return (BadValue);
+ }
+} /* SetEditMode */
+
+/*++
+ |
+ | Function Name: SetElementPointer
+ |
+ | Function Description:
+ | Handles the PEXSetElementPointer request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+SetElementPointer(pStruct, pPosition)
+/* in */
+ diStructHandle pStruct;/* structure handle */
+ ddElementPos *pPosition; /* position to set pointer at */
+/* out */
+{
+ SET_STR_HEADER(pStruct, pstruct);
+ register miGenericElementPtr pel;
+ ddULONG newoffset;
+
+
+#ifdef DDTEST
+ ErrorF("\nSetElementPointer of %d\n", pStruct->id);
+#endif
+
+ if (pos2offset(pstruct, pPosition, &newoffset)) {
+ /* bad whence value */
+ return (BadValue);
+ }
+ if (newoffset == MISTR_CURR_EL_OFFSET(pstruct))
+ return (Success);
+
+ /* special case */
+ if (newoffset == 0) {
+ MISTR_CURR_EL_OFFSET(pstruct) = 0;
+ MISTR_CURR_EL_PTR(pstruct) = MISTR_ZERO_EL(pstruct);
+ return (Success);
+ }
+ MISTR_FIND_EL(pstruct, newoffset, pel);
+
+ MISTR_CURR_EL_OFFSET(pstruct) = newoffset;
+ MISTR_CURR_EL_PTR(pstruct) = pel;
+ return (Success);
+} /* SetElementPointer */
+
+/* look for the next label */
+static ddpex4rtn
+find_label(pStruct, label, startPos, poffset)
+diStructHandle pStruct;
+ddLONG label;
+ddElementPos startPos;
+ddULONG *poffset;
+{
+ ddUSHORT foundLabelElement;
+ SET_STR_HEADER(pStruct, pstruct);
+ ddUSHORT labelElement = PEXOCLabel;
+ miGenericElementPtr pel;
+ ddpex4rtn err = Success;
+
+ do {
+ err = ElementSearch( pStruct, &startPos, (ddULONG) PEXForward,
+ (ddULONG) 1, (ddULONG) 0, &labelElement,
+ (ddUSHORT *) NULL, &foundLabelElement, poffset);
+
+ if (foundLabelElement == PEXFound) {
+ MISTR_FIND_EL(pstruct, *poffset, pel);
+
+ if (label == MISTR_GET_LABEL(pel)) return (PEXFound);
+
+ if (*poffset == MISTR_NUM_EL(pstruct)) return (PEXNotFound);
+
+ /* continue searching after the new current element */
+ startPos.whence = PEXBeginning;
+ startPos.offset = *poffset + 1;
+
+ } else return (PEXNotFound);
+
+ } while (err == Success);
+
+ if (err != Success) return (PEXNotFound);
+ return (PEXFound);
+}
+
+/*++
+ |
+ | Function Name: SetElementPointerAtLabel
+ |
+ | Function Description:
+ | Handles the PEXSetElementPointerAtLabel request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+SetElementPointerAtLabel(pStruct, label, offset)
+/* in */
+ diStructHandle pStruct;/* structure handle */
+ ddLONG label; /* label id */
+ ddLONG offset; /* offset from label */
+/* out */
+{
+ SET_STR_HEADER(pStruct, pstruct);
+ ddElementPos position;
+ ddULONG offsetFromStart;
+ miGenericElementPtr pel;
+
+#ifdef DDTEST
+ ErrorF("\nSetElementPointerAtLabel\n");
+#endif
+
+ position.whence = PEXCurrent;
+ position.offset = 1;
+
+ if (find_label(pStruct, label, position, &offsetFromStart) == PEXNotFound)
+ return (PEXERR(PEXLabelError));
+
+ offsetFromStart += offset;
+
+ if (offsetFromStart > MISTR_NUM_EL(pstruct))
+ offsetFromStart = MISTR_NUM_EL(pstruct);
+
+ MISTR_FIND_EL(pstruct, offsetFromStart, pel);
+
+ MISTR_CURR_EL_PTR(pstruct) = pel;
+ MISTR_CURR_EL_OFFSET(pstruct) = offsetFromStart;
+
+ return (Success);
+} /* SetElementPointerAtLabel */
+
+static ddBOOL
+InList(val, numInList, list)
+ register ddUSHORT val;
+ ddULONG numInList;
+ register ddUSHORT list[];
+{
+ /** Just do a linear search **/
+ register int i;
+ for (i = 0; i < numInList; i++) {
+ if ((val == list[i]) || PEXOCAll == list[i])
+ return (MI_TRUE);
+ }
+ return (MI_FALSE);
+}
+
+
+/*++
+ |
+ | Function Name: ElementSearch
+ |
+ | Function Description:
+ | Handles the PEXElementSearch request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+ElementSearch(pStruct, pPosition, direction, numIncl, numExcl,
+ pIncls, pExcls, pStatus, pOffset)
+/* in */
+ diStructHandle pStruct;/* structure handle */
+ ddElementPos *pPosition; /* search start position */
+ ddULONG direction; /* search direction (forward/backward) */
+ ddULONG numIncl;/* number of types in incl list */
+ ddULONG numExcl;/* number of types in excl list */
+ ddUSHORT *pIncls; /* list of included element types */
+ ddUSHORT *pExcls; /* list of excluded element types */
+/* out */
+ ddUSHORT *pStatus;/* (found/notfound) */
+ ddULONG *pOffset;/* offset from the start position */
+{
+
+ SET_STR_HEADER(pStruct, str);
+ ddULONG positionOffset;
+ miGenericElementPtr pel;
+
+#ifdef DDTEST
+ ErrorF("\nElementSearch of %d\n", pStruct->id);
+#endif
+
+ /** An element is considered "being searched for" if it is in the
+ ** include list and not in the exclude list. Elements in both
+ ** are excluded. An OCAll element specifies that all elements
+ ** match
+ **/
+
+ if (pos2offset(str, pPosition, &positionOffset)) return (BadValue);
+
+ *pStatus = PEXNotFound;
+ *pOffset = 0;
+
+ MISTR_FIND_EL(str, positionOffset, pel);
+
+ /*
+ * search is either forwards or backwards, check for end of search
+ * for both
+ */
+ while ((positionOffset >= 0) && (positionOffset <= MISTR_NUM_EL(str))) {
+ ddUSHORT elType;
+
+ elType = MISTR_EL_TYPE(pel);
+
+ /** If current element is in include list and not in exclude
+ ** list, then succeed PEXOCAll matches all elements, even PEXOCNil */
+ if ( InList(elType, numIncl, pIncls)
+ && !InList(elType, numExcl, pExcls)) {
+ *pStatus = PEXFound;
+ *pOffset = positionOffset;
+ return (Success);
+ } else {
+ if (direction == PEXForward) {
+ positionOffset++;
+ pel = MISTR_NEXT_EL(pel);
+ } else {
+ positionOffset--;
+ pel = MISTR_PREV_EL(pel);
+ }
+ }
+ }
+
+ return (Success);
+} /* ElementSearch */
+
+/*++
+ |
+ | Function Name: StoreElements
+ |
+ | Function Description:
+ | Handles the PEXStoreElements request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+StoreElements(pStruct, numOCs, pOCs, ppErr)
+/* in */
+ diStructHandle pStruct; /* structure handle */
+ register ddULONG numOCs; /* number of output commands */
+ ddElementInfo *pOCs; /* list of output commands */
+/* out */
+ pexOutputCommandError **ppErr;
+{
+ SET_STR_HEADER(pStruct, pstruct);
+ register ddElementInfo *poc;
+ register miGenericElementPtr pprevel, /* insert new one after this */
+ preplel; /* or replace this one: preplel =
+ * pprevel->next */
+ miGenericElementPtr pnewel; /* new el to insert */
+ int count;
+ ddpex4rtn err = Success;
+
+#ifdef DDTEST
+ ErrorF("\nStoreElements in %d\n", pStruct->id);
+#endif
+
+ switch (MISTR_EDIT_MODE(pstruct)) {
+ case PEXStructureReplace:
+ for ( poc = pOCs, count = 0,
+ preplel = MISTR_CURR_EL_PTR(pstruct),
+ pprevel = MISTR_PREV_EL(preplel);
+ numOCs > 0;
+ numOCs--,
+ pprevel = MISTR_NEXT_EL(pprevel),
+ preplel = MISTR_NEXT_EL(pprevel), poc += poc->length) {
+
+ /*
+ * replace iff
+ * we're not at the end
+ * * and the types match
+ * * and we're not at the beginning
+ * * * and elements are the same size
+ */
+
+ if ((preplel != MISTR_LAST_EL(pstruct))
+ && (poc->elementType == MISTR_EL_TYPE(preplel))
+ && (preplel != MISTR_ZERO_EL(pstruct))
+ && (MISTR_EL_LENGTH(preplel) == poc->length)) {
+
+ /*
+ * * Replace calls Parse functions
+ */
+
+ /* Propreitary OC (and OCNil) through 0th Table Entry */
+ if (MI_HIGHBIT_ON(poc->elementType))
+ err = (*ReplaceCSSElementTable[MI_OC_PROP])
+ (pStruct, preplel, poc );
+ else {
+ /* not Proprietary see if valid PEX OC */
+ if (MI_IS_PEX_OC(poc->elementType))
+ err = (*ReplaceCSSElementTable[poc->elementType])
+ (pStruct, preplel, poc);
+ else {
+ /* Bad Element Type Exit Now */
+ err = !Success;
+ break;
+ }
+ }
+ } else
+ /* Bad Replace */
+ err = !Success;
+
+ if (err != Success) { /* create new el */
+ /* Propreitary OC (and OCNil) through 0th Table Entry */
+ if (MI_HIGHBIT_ON(poc->elementType))
+ err = (*CreateCSSElementTable[MI_OC_PROP])
+ (pStruct, poc, &pnewel);
+ else {
+ /* not Proprietary see if valid PEX OC */
+ if (MI_IS_PEX_OC(poc->elementType))
+ err = (*CreateCSSElementTable[poc->elementType])
+ (pStruct, poc, &pnewel);
+ else
+ /* Bad Element Type */
+ err = !Success;
+ }
+
+ if (err != Success) break;
+
+ count++;
+ if ( (preplel != MISTR_LAST_EL(pstruct))
+ && (preplel != MISTR_ZERO_EL(pstruct))) {
+ /* get rid of old el */
+ MISTR_DEL_ONE_EL(pStruct, pprevel, preplel);
+ }
+ if (preplel == MISTR_ZERO_EL(pstruct))
+ pprevel = preplel;
+
+ MISTR_INSERT_ONE_EL(pprevel, pnewel);
+ }
+ }
+
+ if (err != Success) break;
+ MISTR_CURR_EL_PTR(pstruct) = pprevel;
+ MISTR_FIND_OFFSET(pstruct, pprevel, MISTR_CURR_EL_OFFSET(pstruct));
+
+ break;
+
+
+ case PEXStructureInsert:
+ for ( count = 0, poc = pOCs, pprevel = MISTR_CURR_EL_PTR(pstruct);
+ numOCs > 0;
+ numOCs--, pprevel = pnewel, poc += poc->length) {
+
+ /* Propreitary OC (and OCNil) through 0th Table Entry */
+ if (MI_HIGHBIT_ON(poc->elementType))
+ err = (*CreateCSSElementTable[MI_OC_PROP])
+ (pStruct, poc, &pnewel);
+ else {
+ /* not Proprietary see if valid PEX OC */
+ if (MI_IS_PEX_OC(poc->elementType))
+ err = (*CreateCSSElementTable[poc->elementType])
+ (pStruct, poc, &pnewel);
+ else
+ /* Bad Element Type */
+ err = !Success;
+ }
+
+ if (err != Success) break;
+
+ count++;
+ MISTR_INSERT_ONE_EL(pprevel, pnewel);
+ }
+
+ if (err != Success) break;
+ if (count) {
+ MISTR_CURR_EL_PTR(pstruct) = pprevel;
+ MISTR_FIND_OFFSET( pstruct, pprevel,
+ MISTR_CURR_EL_OFFSET(pstruct));
+ }
+ break;
+
+ default:
+ /* better not get here */
+ ErrorF("tsk, tsk, the edit mode was set wrong\n");
+ return (BadImplementation);
+ break;
+ }
+
+ if (err != Success) {
+ *ppErr = (pexOutputCommandError *)xalloc(sizeof(pexOutputCommandError));
+ (*ppErr)->type = 0;
+ (*ppErr)->errorCode = PEX_ERROR_CODE(PEXOutputCommandError);
+ (*ppErr)->resourceId = pStruct->id;
+ (*ppErr)->opcode = poc->elementType;
+ (*ppErr)->numCommands = count;
+ return (err);
+ }
+
+
+ miDealWithStructDynamics(STR_MODIFY_DYNAMIC, pStruct);
+
+ return (Success);
+} /* StoreElements */
+
+/*++
+ |
+ | Function Name: DeleteElements
+ |
+ | Function Description:
+ | Handles the PEXDeleteElements request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+DeleteElements(pStruct, pRange)
+/* in */
+ diStructHandle pStruct;/* structure handle */
+ ddElementRange *pRange; /* range of elements to delete */
+/* out */
+{
+ ddULONG low, high, temp;
+ SET_STR_HEADER(pStruct, pstruct);
+ ddElementPos newElementPointer;
+ ddpex4rtn err;
+
+#ifdef DDTEST
+ ErrorF("\nDeleteElements in %d\n", pStruct->id);
+#endif
+
+ if (pos2offset(pstruct, &(pRange->position1), &low))
+ return (BadValue); /* bad whence value */
+ if (pos2offset(pstruct, &(pRange->position2), &high))
+ return (BadValue); /* bad whence value */
+
+ /** first pos needn't be lower then second pos, so order them now **/
+ if (low > high) {
+ temp = low;
+ low = high;
+ high = temp;
+ }
+ /** deleting element 0 equivalent to a NO-OP **/
+ if (low == 0) {
+ if (high == 0)
+ return (Success);
+ else
+ low = 1;
+ }
+ MISTR_DEL_ELS(pStruct, pstruct, low, high);
+
+ /*
+ * the current element pointer may now be invalid, so set it back to
+ * the beginning so it can be set correctly
+ */
+ MISTR_CURR_EL_PTR(pstruct) = MISTR_ZERO_EL(pstruct);
+ MISTR_CURR_EL_OFFSET(pstruct) = 0;
+
+ /** Now, according to PEX spec, set element pointer to element
+ ** preceding the range of deletion **/
+ newElementPointer.whence = PEXBeginning;
+ newElementPointer.offset = low - 1;
+ err = SetElementPointer(pStruct, &newElementPointer);
+
+ err = miDealWithStructDynamics(STR_MODIFY_DYNAMIC, pStruct);
+
+ return (err);
+} /* DeleteElements */
+
+/*++
+ |
+ | Function Name: DeleteToLabel
+ |
+ | Function Description:
+ | Handles the PEXDeleteElementsToLabel request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+DeleteToLabel(pStruct, pPosition, label)
+/* in */
+ diStructHandle pStruct;/* structure handle */
+ ddElementPos *pPosition; /* starting position */
+ ddLONG label; /* label id to delete to */
+/* out */
+{
+ SET_STR_HEADER(pStruct, pstruct);
+ ddElementPos position;
+ ddElementRange range;
+ ddULONG labelOffset;
+ ddULONG start;
+
+#ifdef DDTEST
+ ErrorF("\nDeleteToLabel\n");
+#endif
+
+ if (pos2offset(pstruct, pPosition, &start))
+ return (BadValue); /* bad whence value */
+
+ position.whence = PEXBeginning;
+ position.offset = start + 1;
+
+ if (find_label(pStruct, label, position, &labelOffset) == PEXNotFound)
+ return (PEXERR(PEXLabelError));
+
+ /*
+ * Now call DeleteElements to delete the elements, but first adjust
+ * the range since DeleteElements does an inclusive delete and
+ * DeleteToLabel doesn't.
+ */
+ if ((start == labelOffset) || ((start + 1) == labelOffset)) {
+ /* there are no elements between them */
+ /* set the element pointer to point to the offset */
+ return(SetElementPointer(pStruct, pPosition));
+ }
+
+ range.position1.whence = PEXBeginning;
+ range.position1.offset = start + 1;
+ range.position2.whence = PEXBeginning;
+ range.position2.offset = labelOffset - 1;
+
+ /* DeleteElements also updates picture if nec. */
+ return (DeleteElements(pStruct, &range));
+
+} /* DeleteToLabel */
+
+/*++
+ |
+ | Function Name: DeleteBetweenLabels
+ |
+ | Function Description:
+ | Handles the PEXDeleteElementsBetweenLabels request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+DeleteBetweenLabels(pStruct, label1, label2)
+/* in */
+ diStructHandle pStruct;/* structure handle */
+ ddLONG label1; /* first label id */
+ ddLONG label2; /* second label id */
+/* out */
+{
+ ddElementPos position;
+ ddULONG labelOffset;
+
+#ifdef DDTEST
+ ErrorF("\nDeleteBetweenLabels\n");
+#endif
+
+ position.whence = PEXCurrent;
+ position.offset = 1;
+
+ if (find_label(pStruct, label1, position, &labelOffset) == PEXNotFound)
+ return (PEXERR(PEXLabelError));
+
+ position.whence = PEXBeginning;
+ position.offset = labelOffset;
+
+ /* DeleteToLabel also updates picture if nec. */
+ return (DeleteToLabel(pStruct, &position, label2));
+
+} /* DeleteBetweenLabels */
+
+/*++
+ |
+ | Function Name: CopyElements
+ |
+ | Function Description:
+ | Handles the PEXCopyElements request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+CopyElements(pSrcStruct, pSrcRange, pDestStruct, pDestPosition)
+/* in */
+ diStructHandle pSrcStruct; /* source structure handle */
+ ddElementRange *pSrcRange; /* element range to copy */
+ diStructHandle pDestStruct; /* destination structure handle */
+ ddElementPos *pDestPosition; /* destination position to put stuff */
+/* out */
+{
+ SET_STR_HEADER(pSrcStruct, psource);
+ SET_STR_HEADER(pDestStruct, pdest);
+ ddULONG src_low, src_high, dest_offset, i, count;
+ miGenericElementPtr psrcel, pdestel, pdestprev;
+ miGenericElementStr pfirst, plast; /* dummies */
+ ddpex4rtn err4 = Success;
+
+
+#ifdef DDTEST
+ ErrorF("\nCopyElements\n");
+#endif
+ if (pos2offset(psource, &(pSrcRange->position1), &src_low))
+ return (BadValue); /* bad whence value */
+
+ if (pos2offset(psource, &(pSrcRange->position2), &src_high))
+ return (BadValue); /* bad whence value */
+
+ if (pos2offset(pdest, pDestPosition, &dest_offset))
+ return (BadValue); /* bad whence value */
+
+ if (src_low > src_high) {
+ i = src_low;
+ src_low = src_high;
+ src_high = i;
+ }
+ if (src_low == 0) {
+ if (src_high == 0)
+ return (Success);
+ else
+ src_low = 1;
+ }
+ MISTR_FIND_EL(psource, src_low, psrcel);
+
+ /*
+ * copy els to dummy list, then add dummy list to dest NOTE:
+ * CopyCSSElement procedure is passed pDestStruct for the copy even
+ * though the element is not really being inserted into the structure
+ * yet. This should be OK, but beware!!
+ */
+ MISTR_NEXT_EL(&pfirst) = &plast;
+ MISTR_PREV_EL(&plast) = &pfirst;
+ MISTR_PREV_EL(&pfirst) = MISTR_NEXT_EL(&plast) = NULL;
+ pdestprev = &pfirst;
+
+ for (i = src_low, count = 0; i <= src_high; i++) {
+
+ /* Propreitary OC (and OCNil) through 0th Table Entry */
+ if (MI_HIGHBIT_ON(MISTR_EL_TYPE(psrcel)))
+ err4 = (*CopyCSSElementTable[MI_OC_PROP])
+ (psrcel, pDestStruct, &pdestel);
+ else {
+ /* not Proprietary see if valid PEX OC */
+ if (MI_IS_PEX_OC(MISTR_EL_TYPE(psrcel)))
+ err4 = (*CopyCSSElementTable[MISTR_EL_TYPE(psrcel)])
+ (psrcel, pDestStruct, &pdestel);
+ else
+ /* Bad Element Type - Problem if you get here */
+ err4 = !Success;
+ }
+
+ if (err4 != Success)
+ break;
+
+ count++;
+ MISTR_INSERT_ONE_EL(pdestprev, pdestel);
+ pdestprev = pdestel;
+ psrcel = MISTR_NEXT_EL(psrcel);
+ }
+
+ if (count) {
+ MISTR_FIND_EL(pdest, dest_offset, pdestprev);
+
+ MISTR_NEXT_EL(MISTR_PREV_EL(&plast)) = MISTR_NEXT_EL(pdestprev);
+ MISTR_PREV_EL(MISTR_NEXT_EL(pdestprev)) = MISTR_PREV_EL(&plast);
+
+ MISTR_NEXT_EL(pdestprev) = MISTR_NEXT_EL(&pfirst);
+ MISTR_PREV_EL(MISTR_NEXT_EL(&pfirst)) = pdestprev;
+
+ MISTR_CURR_EL_PTR(pdest) = MISTR_PREV_EL(&plast);
+ MISTR_FIND_OFFSET(pdest, MISTR_CURR_EL_PTR(pdest), MISTR_CURR_EL_OFFSET(pdest));
+ }
+ err4 = miDealWithStructDynamics(STR_MODIFY_DYNAMIC, pDestStruct);
+
+ return (err4);
+} /* CopyElements */
+
+/*++
+ |
+ | Function Name: ChangeStructureReferences
+ |
+ | Function Description:
+ | Handles the PEXChangeStructureReferences request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+ChangeStructureReferences(pStruct, pNewStruct)
+/* in */
+ diStructHandle pStruct;/* structure handle */
+ diStructHandle pNewStruct; /* new structure resource */
+/* out */
+{
+
+ SET_STR_HEADER(pStruct, pstruct);
+ SET_STR_HEADER(pNewStruct, pnewstruct);
+ diStructHandle parentHandle;
+ miStructPtr pparentStruct;
+ int loopcount;
+ ddElementPos position;
+ ddpex4rtn foundExecuteElement, err;
+ ddULONG offsetFromStart;
+ diWKSHandle pWks;
+ miGenericElementPtr pel;
+ pexExecuteStructure execStrOC;
+ ddFLOAT prity;
+
+#ifdef DDTEST
+ ErrorF("\nChangeStructureReferences\n");
+#endif /* DDTEST */
+
+ /* set up OC with new structure that will replace old */
+ execStrOC.head.elementType = PEXOCExecuteStructure;
+ execStrOC.head.length = 2;
+ execStrOC.id = (pexStructure) pNewStruct;
+
+ /*
+ * Update all references to this structure by walking through the
+ * structure's parent list. Note that if the structure is referenced
+ * more than once by a parent structure, there will be more than one
+ * occurence of the parent in the parent list.
+ */
+
+ for (loopcount = pstruct->parents->numObj; loopcount > 0; loopcount--) {
+
+ /* The parent list changes in loop, so always get first parent */
+ parentHandle = *(diStructHandle *) pstruct->parents->pList;
+ pparentStruct = (miStructPtr) (parentHandle)->deviceData;
+
+ /* start looking at the beginning of the parent structure */
+ position.whence = PEXBeginning;
+ position.offset = 0;
+ offsetFromStart = 0;
+
+ foundExecuteElement = find_execute_structure (parentHandle, &position,
+ pStruct, &offsetFromStart);
+
+ if (foundExecuteElement == PEXFound) {
+ MISTR_FIND_EL(pparentStruct, offsetFromStart, pel);
+ err = (*ReplaceCSSElementTable[PEXOCExecuteStructure])
+ (parentHandle, pel, &execStrOC);
+ if (err != Success) return (err);
+ } else
+ return (!Success);
+ }
+
+ /*
+ * this changes the old structures posted to list (because unpost removes
+ * the wks from this list) so always get the first wks from the list and
+ * be sure to check the original number of posted wks
+ */
+ for (loopcount = pstruct->wksPostedTo->numObj; loopcount > 0; loopcount--) {
+ pWks = ((diWKSHandle *) pstruct->wksPostedTo->pList)[0];
+ if (puInList((ddPointer) pWks, pnewstruct->wksPostedTo))
+ err = UnpostStructure(pWks, pStruct);
+ else {
+ miGetStructurePriority(pWks, pStruct, &prity);
+ err = PostStructure(pWks, pNewStruct, prity);
+ }
+ if (err) return (err);
+ }
+
+ err = miDealWithStructDynamics(REF_MODIFY_DYNAMIC, pNewStruct);
+
+ return (Success);
+} /* ChangeStructureReferences */
+
+int
+miAddWksToAppearLists(pStruct, pWKS)
+ diStructHandle pStruct;
+ diWKSHandle pWKS;
+{
+ SET_STR_HEADER(pStruct, pheader);
+ register ddULONG i, num;
+ diStructHandle *ps;
+
+ /* loop through the structures list of children */
+ num = pheader->children->numObj;
+ ps = (diStructHandle *) pheader->children->pList;
+ for (i = 0; i < num; i++, ps++) {
+ if (puAddToList( (ddPointer) & pWKS, (ddULONG) 1,
+ ((miStructPtr) (*ps)->deviceData)->wksAppearOn)
+ == MI_ALLOCERR)
+ return (MI_ALLOCERR);
+
+ /* recur to do the children of this child */
+ if (miAddWksToAppearLists(*ps, pWKS) != MI_SUCCESS)
+ return (MI_ALLOCERR);
+ }
+ return (MI_SUCCESS);
+}
+
+void
+miRemoveWksFromAppearLists(pStruct, pWKS)
+ diStructHandle pStruct;
+ diWKSHandle pWKS;
+{
+ SET_STR_HEADER(pStruct, pheader);
+ register ddULONG i, num;
+ diStructHandle *ps;
+
+#ifdef DDTEST
+ ErrorF("\tmiRemoveWksFromAppearLists (of structure %d)\n", pStruct->id);
+#endif
+
+ num = pheader->children->numObj;
+ ps = (diStructHandle *) pheader->children->pList;
+
+ /* look at all children of this structure */
+ for (i = 0; i < num; i++, ps++) {
+ /* remove the wks from the child's list */
+ puRemoveFromList( (ddPointer) & pWKS,
+ ((miStructPtr) (*ps)->deviceData)->wksAppearOn);
+
+ /* recur to do the children of this child */
+ miRemoveWksFromAppearLists(*ps, pWKS);
+ }
+ return;
+}
+
+/*++
+ |
+ | Function Name: UpdateStructRefs
+ |
+ | Function Description:
+ | A utility function to change the cross-reference lists in the structure.
+ | Each structure has a list of every workstation and structure which uses
+ | it.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+UpdateStructRefs(pStruct, pResource, which, action)
+/* in */
+ diStructHandle pStruct;/* structure handle */
+ diResourceHandle pResource; /* wks, struct, sc handle */
+ ddResourceType which; /* wks, struct, pick, sc */
+ ddAction action; /* add or remove */
+/* out */
+{
+ SET_STR_HEADER(pStruct, pheader);
+
+#ifdef DDTEST
+ ErrorF("\nUpdateStructRefs\n");
+#endif
+
+ switch (which) {
+ case WORKSTATION_RESOURCE:
+
+ /*
+ * for each workstation, do it to the specified structures
+ * wksPostedTo list and do it to the wksAppearOn list of all
+ * of the structures children
+ */
+ if (action == ADD) {
+ if (puAddToList( (ddPointer) & pResource, (ddULONG) 1,
+ pheader->wksPostedTo) == MI_ALLOCERR)
+ return (BadAlloc); /* couldn't add to list */
+ if (miAddWksToAppearLists(pStruct, (diWKSHandle) pResource))
+ return (BadAlloc); /* couldn't add to list */
+ } else {
+ puRemoveFromList((ddPointer) & pResource, pheader->wksPostedTo);
+ miRemoveWksFromAppearLists(pStruct, (diWKSHandle) pResource);
+ }
+
+ break;
+
+ case PARENT_STRUCTURE_RESOURCE:
+ if (action == ADD) {
+ if (puAddToList( (ddPointer) & pResource, (ddULONG) 1,
+ pheader->parents) == MI_ALLOCERR)
+ return (BadAlloc); /* couldn't add to list */
+ } else
+ puRemoveFromList((ddPointer) & pResource, pheader->parents);
+
+ break;
+
+ case CHILD_STRUCTURE_RESOURCE:
+ if (action == ADD) {
+ if (puAddToList( (ddPointer) & pResource, (ddULONG) 1,
+ pheader->children) == MI_ALLOCERR)
+ return (BadAlloc); /* couldn't add to list */
+ } else
+ puRemoveFromList((ddPointer) & pResource, pheader->children);
+
+ break;
+
+ case SEARCH_CONTEXT_RESOURCE:
+ case PICK_RESOURCE: /* for both pick device & pick measure */
+ if (action == ADD)
+ pheader->refCount++;
+ else {
+ pheader->refCount--;
+ CHECK_DELETE(pStruct, pheader);
+ }
+ break;
+
+ default: /* better not get here */
+ break;
+ }
+ return (Success);
+}
+
+/* get_wks_postings for InquireWksPostings
+ * implement it here since it uses structure stuff
+ */
+ddpex4rtn
+get_wks_postings(pStruct, pBuffer)
+ diStructHandle pStruct;
+ ddBufferPtr pBuffer;
+{
+ SET_STR_HEADER(pStruct, pheader);
+ listofObj *wkslist;
+ diWKSHandle *pwks;
+ ddResourceId *pbuf;
+ register int i;
+
+ pBuffer->dataSize = 0;
+
+ wkslist = pheader->wksPostedTo;
+
+ if (PU_BUF_TOO_SMALL(pBuffer,(ddULONG)wkslist->numObj *sizeof(ddResourceId)))
+ if (puBuffRealloc( pBuffer,
+ (ddULONG)(wkslist->numObj * sizeof(ddResourceId)))
+ != Success) {
+ puDeleteList(wkslist);
+ return (BadAlloc);
+ }
+ pwks = (diWKSHandle *) wkslist->pList;
+ pbuf = (ddResourceId *) pBuffer->pBuf;
+ for (i = 0; i < wkslist->numObj; i++, pwks++, pbuf++) *pbuf = (*pwks)->id;
+ pBuffer->dataSize = wkslist->numObj * sizeof(ddResourceId);
+
+ return (Success);
+}
+
+/* make a generic puPrintList and put it in dipex/util/pexUtils.c sometime */
+void
+miPrintPath(pPath)
+ listofObj *pPath;
+{
+ register int i;
+ register ddElementRef *pref;
+
+ ErrorF("\nELEMENT REF PATH\n");
+ pref = (ddElementRef *) pPath->pList;
+ for (i = 0; i < pPath->numObj; i++, pref++)
+ ErrorF("\tstructure id: %d\toffset: %d\n",
+ pref->structure, pref->offset);
+ ErrorF("\nEND PATH\n");
+}
+
+/*++
+ |
+ | Function Name: miPrintStructure
+ |
+ | Function Description:
+ | Prints out the contents of a structure for debugging
+ | purposes.
+ |
+ | Input Description:
+ | miStructPtr pStruct;
+ | int strLevel - amount of struct info to display
+ | Output Description:
+ | Switch strLevel :
+ | case 0 :
+ | don't do anything.
+ | case 1 :
+ | print structure header and nothing more
+ | case 2 :
+ | print structure header and affil. structs and wks
+ |
+ --*/
+
+static void printWorkstations(), printStructures();
+
+void
+miPrintStructure(S, strLevel)
+ diStructHandle S;
+ int strLevel;
+{
+ miStructPtr s = (miStructPtr) S->deviceData;
+
+ if (strLevel > 0) {
+
+ ErrorF("\n\n\n**********************************\n");
+ ErrorF("* Printing Structure at 0x%x *\n", s);
+ ErrorF("**********************************\n");
+ ErrorF("ID = %ld\n", S->id);
+ ErrorF("Edit Mode = %s\n", (s->editMode == PEXStructureReplace) ?
+ "REPLACE" : "INSERT");
+ ErrorF("Num Elements = %ld\nTotal Size in 4 byte units = %ld\n",
+ s->numElements, s->totalSize);
+ ErrorF("Curr Offset = %ld\nCurr Elt Ptr = 0x%x\n",
+ s->currElementOffset, s->pCurrElement);
+ ErrorF("Zero El Ptr = 0x%x\nLast El Ptr = 0x%x\n",
+ s->pZeroElement, s->pLastElement);
+
+ if (strLevel == 2) {
+ ErrorF("\nParent Structures :\n");
+ printStructures(s->parents);
+ ErrorF("\nChild Structures :\n");
+ printStructures(s->children);
+ ErrorF("\nWKS posted to:\n");
+ printWorkstations(s->wksPostedTo);
+ ErrorF("\nWKS appearing on:\n");
+ printWorkstations(s->wksAppearOn);
+ }
+ }
+}
+
+static void
+printStructures(list)
+ listofObj *list;
+{
+ int i;
+ diStructHandle *str;
+
+ str = (diStructHandle *) list->pList;
+ for (i = 0; i < list->numObj; i++, str++) {
+ ErrorF("\tStruct Address: 0x%x\t\tId: %ld\n",
+ (*str)->deviceData, (*str)->id);
+ }
+}
+
+static void
+printWorkstations(list)
+ listofObj *list;
+{
+ int i;
+ diWKSHandle *wks;
+
+ wks = (diWKSHandle *) list->pList;
+ for (i = 0; i < list->numObj; i++, wks++) {
+ ErrorF("\tWks Address: 0x%x\t\tId: %ld\n",
+ (*wks)->deviceData, (*wks)->id);
+ }
+}
+
+
+/*++
+ |
+ | Function Name: ValidateStructurePath
+ |
+ | Function Description:
+ Follows the given search or pick path to see if it's valid
+ |
+ --*/
+
+ddpex4rtn
+ValidateStructurePath(pPath)
+ listofObj *pPath;
+{
+ miGenericElementPtr p_element;
+ diStructHandle pStruct, pNextStruct;
+ miStructPtr pstruct;
+ ddULONG offset;
+ int i, j;
+
+ if (pPath->type == DD_ELEMENT_REF) {
+ ddElementRef *pSCPath;
+
+ pSCPath = (ddElementRef *) pPath->pList;
+ pNextStruct = pSCPath->structure;
+
+ for (i = pPath->numObj; i > 0; i--, pSCPath++) {
+ pStruct = pSCPath->structure;
+ if (pNextStruct != pStruct) return (PEXERR(PEXPathError));
+
+ pstruct = (miStructPtr) pStruct->deviceData;
+
+ offset = pSCPath->offset;
+ if (offset > MISTR_NUM_EL(pstruct)) return (PEXERR(PEXPathError));
+
+ /* dont' check what the last element is */
+ if (i == 1) break;
+
+ MISTR_FIND_EL(pstruct, offset, p_element);
+ if (MISTR_EL_TYPE(p_element) != PEXOCExecuteStructure)
+ return (PEXERR(PEXPathError));
+
+ pNextStruct = (diStructHandle) MISTR_GET_EXSTR_STR(p_element);
+ }
+ } else {
+ ddPickPath *pPickPath;
+ ddULONG pickId;
+
+ /*
+ * pick has to step through each element to check pick id also
+ */
+ pPickPath = (ddPickPath *) pPath->pList;
+ pNextStruct = pPickPath->structure;
+ pickId = 0;
+
+ for (i = pPath->numObj; i > 0; i--, pPickPath++) {
+
+ pStruct = pPickPath->structure;
+ if (pNextStruct != pStruct) return (PEXERR(PEXPathError));
+
+ pstruct = (miStructPtr) pStruct->deviceData;
+
+ offset = pPickPath->offset;
+ if (offset > MISTR_NUM_EL(pstruct)) return (PEXERR(PEXPathError));
+
+ /*
+ * start at the first element and look at each
+ * element until the offset is reached
+ */
+ MISTR_FIND_EL(pstruct, 1, p_element);
+
+ for (j = 1; j < offset; j++ ) {
+ if (MISTR_EL_TYPE(p_element) == PEXOCPickId)
+ pickId = MISTR_GET_PICK_ID(p_element);
+ p_element = MISTR_NEXT_EL(p_element);
+ }
+
+ if (pickId != pPickPath->pickid) return (PEXERR(PEXPathError));
+
+ /* dont' check what the last element is */
+ if (i == 1) break;
+
+ if (MISTR_EL_TYPE(p_element) != PEXOCExecuteStructure)
+ return (PEXERR(PEXPathError));
+
+ pNextStruct = (diStructHandle) MISTR_GET_EXSTR_STR(p_element);
+ }
+ }
+ return (Success);
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level4/miTraverse.c b/xc/programs/Xserver/PEX5/ddpex/mi/level4/miTraverse.c
new file mode 100644
index 000000000..3c4f41952
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level4/miTraverse.c
@@ -0,0 +1,596 @@
+/* $TOG: miTraverse.c /main/7 1998/02/10 12:43:58 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level4/miTraverse.c,v 1.8 1999/01/31 12:21:29 dawes Exp $ */
+
+#include "miWks.h"
+#include "PEXproto.h"
+#include "PEXprotost.h"
+#include "miRender.h"
+#include "miPick.h"
+#include "miStruct.h"
+#include "miStrMacro.h"
+#include "pexos.h"
+
+
+extern void InquirePickStatus();
+extern void InquireSearchStatus();
+
+extern ddpex3rtn BeginStructure();
+extern ddpex3rtn EndStructure();
+extern ocTableType ExecuteOCTable[];
+
+ddpex4rtn traverser();
+
+#ifdef DDTEST
+#define ASSURE(test) \
+ if (!(test)) { \
+ ErrorF( "test \n"); \
+ ErrorF( "Failed: Line %d, File %s\n\n", __LINE__, __FILE__); \
+ }
+#else
+#define ASSURE(test)
+#endif /* DDTEST */
+
+static ddBOOL
+pickES (pRend, p_trav_state, p_str, depth, curr_offset)
+ ddRendererPtr pRend;
+ miTraverserState *p_trav_state;
+ diStructHandle p_str; /* current structure */
+ ddSHORT depth; /* how far down in structures */
+ ddULONG curr_offset;
+{
+
+ if ((p_str->id == p_trav_state->p_curr_pick_el->structure->id) &&
+ (curr_offset == p_trav_state->p_curr_pick_el->offset)) {
+
+ if (depth < pRend->pickStartPath->numObj)
+ /* continue following start path */
+ p_trav_state->p_curr_pick_el++;
+ else
+ /* at end of start path; time to start traversal */
+ p_trav_state->exec_str_flag = ES_YES;
+
+ return(MI_TRUE);
+ }
+ return (MI_FALSE);
+}
+
+static ddBOOL
+searchES(pSC, p_trav_state, p_str, depth, curr_offset)
+ ddSCStr *pSC;
+ miTraverserState *p_trav_state;
+ diStructHandle p_str; /* current structure */
+ ddSHORT depth; /* how far down in structures */
+ ddULONG curr_offset;
+{
+ if ((p_str->id == p_trav_state->p_curr_sc_el->structure->id) &&
+ (curr_offset == p_trav_state->p_curr_sc_el->offset)) {
+ /* OK, this element is in the start path. Now if we're
+ * at the ceiling, don't follow the exec-str
+ */
+ if ((pSC->ceiling == 1) || (depth < pSC->ceiling)) {
+ if (depth < pSC->startPath->numObj)
+ /* continue following start path */
+ p_trav_state->p_curr_sc_el++;
+ else
+ /* at end of start path; time to start traversal */
+ p_trav_state->exec_str_flag = ES_YES;
+ return(MI_TRUE);
+ }
+ }
+ return (MI_FALSE);
+}
+
+int
+miTraverse(pWks )
+ diWKSHandle pWks;
+{
+ register ddOrdStruct *pos;
+ miWksPtr pwks = (miWksPtr) pWks->deviceData;
+ ddpex4rtn err = Success;
+ miTraverserState trav_state;
+ DrawablePtr pRealDrawable;
+
+
+ if ( (pwks->pRend->pDrawable == NULL)
+ || (pwks->pRend->drawableId == PEXAlreadyFreed))
+ return (BadDrawable);
+
+ if (!pwks->postedStructs.numStructs || !pwks->pCurDrawable) return (Success);
+
+ /* set exec_str_flag */
+ trav_state.exec_str_flag = ES_YES;
+ trav_state.p_curr_pick_el = (ddPickPath *) NULL;
+ trav_state.p_curr_sc_el = (ddElementRef *) NULL;
+
+ /* save drawable to be restored later */
+ pRealDrawable = pwks->pRend->pDrawable;
+ pwks->pRend->pDrawable = pwks->pCurDrawable;
+
+ /** call into ddPEX level III Begin Rendering **/
+ BeginRendering(pwks->pRend, pwks->pCurDrawable);
+
+ /* traverse all posted structs */
+ pos = pwks->postedStructs.postruct;
+ while ((pos->next) && (err == Success)) {
+ pos = pos->next;
+ /* reset for each structure */
+ trav_state.max_depth = 0;
+ trav_state.pickId = 0;
+ trav_state.ROCoffset = 0;
+
+
+ if (MISTR_NUM_EL((miStructPtr) pos->pstruct->deviceData)) {
+ BeginStructure(pwks->pRend, pos->pstruct->id);
+
+ /*
+ * always start at the first element in the
+ * structure
+ */
+ err = traverser( pwks->pRend, pos->pstruct, (ddULONG) 1,
+ MISTR_NUM_EL((miStructPtr) pos->pstruct->deviceData),
+ (diPMHandle)NULL, (ddSCStr *) NULL, &trav_state);
+
+ EndStructure(pwks->pRend);
+ pwks->displaySurface = PEXNotEmpty;
+ }
+ }
+
+ EndRendering(pwks->pRend);
+
+ pwks->pRend->pDrawable = pRealDrawable;
+
+ if (err != Success) {
+ /* do stuff here to return error */
+ return(err);
+ }
+
+ return (err);
+} /* miTraverse */
+
+/* this traverses server side structures */
+/* startel must be > 0
+ * stopel must be <= num els in structure
+ */
+/*
+ * begin/end structure keep track of the current path,
+ * but calling the level II OCs directly does not
+ * so do this BEFORE calling the OCs
+ */
+#define INCREMENT_OFFSET(pRend) \
+ if (pRend->curPath->numObj) \
+ ((ddElementRef *)pRend->curPath->pList)[pRend->curPath->numObj-1].offset++
+
+ddpex4rtn
+traverser(pRend, pStruct, startel, stopel, pPM, pSC, p_trav_state)
+ddRendererPtr pRend;
+diStructHandle pStruct;
+ddULONG startel;
+ddULONG stopel;
+diPMHandle pPM;
+ddSCStr *pSC;
+miTraverserState *p_trav_state;
+{
+ register ddULONG currOffset;
+ miPickMeasureStr *ppm;
+ miGenericElementPtr p_element;
+ ddPointer ddElement; /* imp. dep. parsed element */
+ diStructHandle p_next_str; /* execute structure structure */
+ ddSHORT depth; /* how far down in structures */
+ ddULONG pickId, ROCoffset;
+ miStructPtr pstruct = (miStructPtr)(pStruct->deviceData);
+ ddUSHORT pickStatus, searchStatus;
+ ddpex2rtn err;
+ ddPickPath *pl;
+ ddElementRef *sl;
+ int zap;
+ miPPLevel myPickLevel, *pp;
+ int i;
+
+
+ if (pPM)
+ ppm = (miPickMeasureStr *) pPM->deviceData;
+ else
+ ppm = (miPickMeasureStr *) NULL;
+
+ /*
+ * set depth=MaxDepth here when called on way in,
+ * so depth is current depth on way out
+ */
+ p_trav_state->max_depth++;
+ depth = p_trav_state->max_depth;
+ /* same for pick id */
+ pickId = p_trav_state->pickId;
+ MISTR_FIND_EL(pstruct, startel, p_element);
+ currOffset = startel;
+
+ /* when calling traverser from ROC ROCoffset may be non-zero
+ to account for prior ROCs, all other times this should
+ be 0 and we set it to 0 here so recursion doesn't mess
+ up the offsets when processing execute structure
+ */
+ ROCoffset = p_trav_state->ROCoffset;
+ p_trav_state->ROCoffset = 0;
+
+ /* do stuff for following search start path */
+ if (pSC) {
+ /* if following start path, and its at the last element_ref
+ * in the start path, and its after the last element in
+ * the element_ref, then its at the end of the start
+ * path and searching should begin
+ */
+ if ( (p_trav_state->exec_str_flag == ES_FOLLOW_SEARCH) &&
+ (depth == pSC->startPath->numObj) &&
+ (currOffset > p_trav_state->p_curr_sc_el->offset) )
+ p_trav_state->exec_str_flag = ES_YES;
+ }
+
+ /* do stuff for following pick start path */
+ if (pPM) {
+ if ( (p_trav_state->exec_str_flag == ES_FOLLOW_PICK) &&
+ (depth == pRend->pickStartPath->numObj) &&
+ (currOffset > p_trav_state->p_curr_pick_el->offset) )
+ p_trav_state->exec_str_flag = ES_YES;
+ }
+
+ while (currOffset <= stopel) {
+ ddElement = (ddPointer) (&(p_element->element));
+
+ switch (MISTR_EL_TYPE(p_element)) {
+ case PEXOCExecuteStructure: {
+
+ /*
+ * While inside this traverser, don't call level II execute
+ * structure OC. It is used in mixed mode traversals to get
+ * from client-side traversing to server-side traverser
+ */
+ ddBOOL go;
+
+ p_next_str = ((diStructHandle) MISTR_GET_EXSTR_STR(p_element));
+ if (p_trav_state->exec_str_flag == ES_FOLLOW_PICK)
+ go = pickES (pRend, p_trav_state, pStruct, depth, currOffset);
+ else if (p_trav_state->exec_str_flag == ES_FOLLOW_SEARCH)
+ go = searchES(pSC, p_trav_state, pStruct, depth, currOffset);
+ else if (p_trav_state->exec_str_flag == ES_YES)
+ go = MI_TRUE;
+ else
+ go = MI_FALSE;
+
+ if (go) {
+
+ BeginStructure(pRend, p_next_str->id);
+
+ /* build the pick path as we descend the hierarchy */
+ if (pPM) {
+ myPickLevel.up = p_trav_state->p_pick_path;
+ myPickLevel.pp.structure = pStruct;
+ myPickLevel.pp.offset = currOffset + ROCoffset;
+ myPickLevel.pp.pickid = pickId;
+ p_trav_state->p_pick_path = &myPickLevel;
+ }
+
+ err = traverser( pRend, p_next_str, (ddULONG) 1,
+ MISTR_NUM_EL((miStructPtr) p_next_str->deviceData),
+ pPM, pSC, p_trav_state);
+ if (err != Success) return (err);
+ EndStructure(pRend);
+ }
+
+ /*
+ * We built the candidate pick path when it was found. We
+ * do nothing on the way out - except restore pointer.
+ */
+ if (pPM) {
+ p_trav_state->p_pick_path = myPickLevel.up;
+ }
+
+
+ /* do the same for searching, replacing the start
+ * path with the found path
+ */
+ if (pSC && (pSC->status == PEXFound)) {
+
+ sl = (ddElementRef *) pSC->startPath->pList;
+
+ zap = depth -1;
+
+ sl[zap].structure = pStruct;
+ sl[zap].offset = currOffset;
+
+ return (Success);
+ } else
+ /* popping out of Not Found */
+ if (pSC && (p_trav_state->exec_str_flag == ES_POP))
+ return (Success);
+
+ /*
+ * still picking or searching, so keep
+ * adjusting max_depth
+ */
+ if (go)
+ p_trav_state->max_depth--;
+ break;
+ }
+
+ case PEXOCPickId:
+
+ /*
+ * For now, set own pick id and call into level II pick OC.
+ * Could do this in a level 4 pick procedure like execute struct
+ */
+ pickId = p_trav_state->pickId = MISTR_GET_LABEL(p_element);
+
+ INCREMENT_OFFSET(pRend);
+
+ pRend->executeOCs[(int) (p_element->element.elementType)]
+ (pRend, ddElement);
+
+ break;
+
+ /* drawing primitives */
+ case PEXOCMarker:
+ case PEXOCMarker2D:
+ case PEXOCText:
+ case PEXOCText2D:
+ case PEXOCAnnotationText:
+ case PEXOCAnnotationText2D:
+ case PEXOCPolyline:
+ case PEXOCPolyline2D:
+ case PEXOCPolylineSet:
+ case PEXOCNurbCurve:
+ case PEXOCFillArea:
+ case PEXOCFillArea2D:
+ case PEXOCExtFillArea:
+ case PEXOCFillAreaSet:
+ case PEXOCFillAreaSet2D:
+ case PEXOCExtFillAreaSet:
+ case PEXOCTriangleStrip:
+ case PEXOCQuadrilateralMesh:
+ case PEXOCSOFAS:
+ case PEXOCNurbSurface:
+ case PEXOCCellArray:
+ case PEXOCCellArray2D:
+ case PEXOCExtCellArray:
+ case PEXOCGdp:
+ case PEXOCGdp2D:
+ INCREMENT_OFFSET(pRend);
+
+ /* if following pick or search path, don't call prims */
+ if ( (p_trav_state->exec_str_flag == ES_FOLLOW_PICK) ||
+ (p_trav_state->exec_str_flag == ES_FOLLOW_SEARCH) )
+ break;
+
+ if (MI_DDC_DO_PRIMS(pRend)) {
+
+ pRend->executeOCs[(int) (p_element->element.elementType)]
+ (pRend, ddElement);
+ if (pSC) {
+ InquireSearchStatus(pRend, &searchStatus);
+ /* searchStatus is PEXFound or PEXNotFound */
+ pSC->status = searchStatus;
+ if (searchStatus == PEXFound) {
+ sl = (ddElementRef *) pSC->startPath->pList;
+
+ pSC->startPath->numObj = p_trav_state->max_depth;
+
+ if (pSC->startPath->maxObj < p_trav_state->max_depth) {
+ pSC->startPath->pList =
+ (ddPointer) xrealloc(
+ pSC->startPath->pList,
+ p_trav_state->max_depth
+ * sizeof(ddElementRef));
+ pSC->startPath->maxObj = p_trav_state->max_depth;
+ }
+ zap = depth -1;
+
+ sl[zap].structure = pStruct;
+ sl[zap].offset = currOffset;
+
+ p_trav_state->exec_str_flag = ES_POP;
+ return (Success);
+ }
+ }
+ if (pPM) {
+ InquirePickStatus(pRend, &pickStatus, p_trav_state);
+ if (pickStatus == PEXOk) {
+ if (pRend->pickstr.state == DD_PICK_ALL) {
+ myPickLevel.up = p_trav_state->p_pick_path;
+ myPickLevel.pp.structure = pStruct;
+ myPickLevel.pp.offset = currOffset + ROCoffset;
+ myPickLevel.pp.pickid = pickId;
+
+ AddPickPathToList( pRend, depth, &myPickLevel);
+ ppm->status = pickStatus;
+
+ } else {
+
+
+ pl = (ddPickPath *) ppm->path->pList;
+
+ /*
+ * then do stuff to update
+ * pick measure path and stop
+ * traversing
+ */
+ ppm->path->numObj = p_trav_state->max_depth;
+
+ if (ppm->path->maxObj < p_trav_state->max_depth) {
+ ppm->path->pList =
+ (ddPointer) xrealloc(ppm->path->pList,
+ p_trav_state->max_depth
+ * sizeof(ddPickPath));
+ ppm->path->maxObj = p_trav_state->max_depth;
+ }
+
+ /*
+ * oh boy, this is where recursion is fun.
+ * In this current iteration of traverser we know
+ * the last element in the path, so stuff this
+ * element into the bottom/top of the pick path list
+ * depending on whether the top/bottom part was
+ * requested
+ */
+ if (ppm->pathOrder == PEXTopFirst)
+ zap = depth - 1;
+ else
+ zap = p_trav_state->max_depth - depth;
+
+ pl[zap].structure = pStruct;
+ pl[zap].offset = currOffset + ROCoffset;
+ pl[zap].pickid = pickId;
+
+ /*
+ * we want to continue on, so we do not want to
+ * pop off to use the recursion.
+ * follow the linked list down
+ */
+ pp = p_trav_state->p_pick_path;
+ for (i = depth-1; i > 0; i-- ) {
+ if (ppm->pathOrder == PEXTopFirst)
+ zap = i - 1;
+ else
+ zap = p_trav_state->max_depth - i;
+
+ pl[zap] = pp->pp; /* structure assignment */
+ pp = pp->up;
+ }
+ ppm->status = pickStatus;
+
+ }
+ }
+ }
+ }
+ break;
+
+ default: /* all others */
+
+ INCREMENT_OFFSET(pRend);
+
+ /* could maybe skip some if doing pick or search */
+ if (MI_IS_PEX_OC(MISTR_EL_TYPE(p_element)))
+ pRend->executeOCs[(int) (p_element->element.elementType)]
+ (pRend, ddElement);
+
+ break; /* default */
+
+ } /* end switch */
+
+
+ /* do stuff for following search start path */
+ if ( pSC ) {
+ /* now, if its at the ceiling, forget it */
+ if ( (depth == pSC->ceiling) && (pSC->ceiling != 1) &&
+ (currOffset >= stopel) ) {
+ pSC->status = PEXNotFound;
+ p_trav_state->exec_str_flag = ES_POP;
+ return (Success);
+ }
+
+ /* do stuff for following search start path */
+ if (pSC) {
+ /* if following start path, and its at the last element_ref
+ * in the start path, and its after the last element in
+ * the element_ref, then its at the end of the start
+ * path and searching should begin
+ */
+ if ( (p_trav_state->exec_str_flag == ES_FOLLOW_SEARCH) &&
+ (depth == pSC->startPath->numObj) &&
+ (currOffset >= p_trav_state->p_curr_sc_el->offset) )
+ p_trav_state->exec_str_flag = ES_YES;
+ }
+
+ }
+
+ /* do stuff for following search start path */
+ if (pPM) {
+ /* if following start path, and its at the last pick_path
+ * in the start path, and its after the last element in
+ * the pick_path, then its at the end of the start
+ * path and searching should begin
+ */
+ if ( (p_trav_state->exec_str_flag == ES_FOLLOW_PICK) &&
+ (depth == pRend->pickStartPath->numObj) &&
+ (currOffset >= p_trav_state->p_curr_pick_el->offset) )
+ p_trav_state->exec_str_flag = ES_YES;
+ }
+
+ /* go on to the next element */
+ currOffset++;
+ p_element = MISTR_NEXT_EL(p_element);
+ } /* while loop (while there are still elements
+ in the structure) */
+
+ return (Success);
+
+} /* traverser */
+
+
+/* for mixed mode traversals, this supports the execute structure OC */
+void
+execute_structure_OC(pRend, pOC)
+ddRendererPtr pRend;
+pexExecuteStructure *pOC;
+{
+ diStructHandle pstruct = *((diStructHandle *)&(pOC->id));
+ miTraverserState trav_state;
+ ddpex4rtn err = Success;
+ if (MISTR_NUM_EL((miStructPtr) pstruct->deviceData)) {
+
+ BeginStructure(pRend, pstruct->id);
+ trav_state.exec_str_flag = ES_YES;
+ trav_state.p_curr_pick_el = NULL;
+ trav_state.p_curr_sc_el = NULL;
+ trav_state.max_depth = 0;
+ trav_state.pickId = 0;
+ trav_state.ROCoffset = 0;
+
+ err = traverser( pRend, pstruct, (ddULONG)0,
+ MISTR_NUM_EL((miStructPtr)pstruct->deviceData),
+ (diPMHandle)NULL, (ddSCStr *)NULL, &trav_state);
+ EndStructure(pRend);
+
+ }
+ return;
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/level4/miWks.c b/xc/programs/Xserver/PEX5/ddpex/mi/level4/miWks.c
new file mode 100644
index 000000000..d8cb83299
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/level4/miWks.c
@@ -0,0 +1,2415 @@
+/* $TOG: miWks.c /main/17 1998/02/10 12:44:02 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/level4/miWks.c,v 1.7 1998/10/04 09:34:43 dawes Exp $ */
+
+
+#include "miWks.h"
+#include "miInfo.h"
+#include "miLUT.h"
+#include "pexUtils.h"
+#include "PEXErr.h"
+#include "PEXprotost.h"
+#include "pexExtract.h"
+#include "Xprotostr.h"
+#include "gcstruct.h"
+#include "resource.h"
+#include "pexos.h"
+
+
+#ifdef MULTIBUFFER
+#define _MULTIBUF_SERVER_
+#include <X11/extensions/multibuf.h>
+#endif
+
+/* Level 4 Workstation Support */
+/* PHIGS Workstation Procedures */
+
+extern ddpex4rtn miDealWithStructDynamics();
+extern ddpex4rtn miDealWithDynamics();
+extern void miMatInverse();
+extern void miTransformPoint();
+extern void path_update_struct_refs();
+extern ddpex3rtn miBldViewport_xform();
+
+ddpex4rtn mi_add_ord_view();
+ddOrdView *mi_find_ord_view();
+
+extern miEnumType miHlhsrModeET[MI_MAXDRAWABLES][SI_HLHSR_NUM];
+extern miEnumType miDisplayUpdateModeET[MI_MAXDRAWABLES][SI_UPDATE_NUM];
+
+static void deletewks();
+
+/* init_pick_flag is initialized in ddpexInit()
+ * there are MIWKS_NUM_PICK_DEVICES pick devices (defined in miWks.h)
+ * pick_devices is the initial state for each of these that
+ * is used to initialize the pick devices in the wks
+ * pick_devices have to be initialized dynamically because
+ * there is a union in them
+ */
+ddBOOL init_pick_flag;
+void initialize_pick_devices();
+miPickDevice pick_devices[MIWKS_NUM_PICK_DEVICES];
+
+static ddNpcSubvolume NPCInit =
+{{0.0, 0.0, 0.0},
+{1.0, 1.0, 1.0}
+};
+
+static ddViewport viewportInit =
+{{0, 0, 0.0},
+{1, 1, 1.0},
+MI_TRUE
+};
+
+/* ugly globals for this module */
+static ddpex4rtn err4;
+static ddpex43rtn err43;
+static ddpex3rtn err3;
+static int err;
+
+#define WKS_WINDOW_MASK 1
+#define WKS_VIEWPORT_MASK 2
+
+/* here are the dynamics that our wks can support */
+
+/* only one so far */
+ddBYTE mi_dynamics[MI_MAXDRAWABLES][MAX_DYNAMIC] = {
+ PEXIRG, PEXIRG, PEXIRG, PEXIRG, PEXIRG, PEXIRG, PEXIRG, PEXIRG, PEXIRG,
+ PEXIRG, PEXIRG, PEXIRG, PEXIRG, PEXIRG, PEXIRG, PEXIRG, PEXIRG, PEXIRG,
+ PEXIRG, PEXIRG, PEXIRG
+};
+
+/* this macro checks to see if a change to the workstation affects
+ * the current display
+ */
+#define WKSIMMEDIATE(pws, attr) \
+ ( (pws->displaySurface == PEXEmpty) || \
+ ((pws)->dynamics[(int)attr] == PEXIMM) )
+
+/* adjust this for the supported dynamics & update modes in your implementation
+ * this should be true if the change to the attribute is visualizable now
+ */
+#define VISUALIZE_NOW( pws, dynamic) \
+ (((pws)->dynamics[(int)(dynamic)] == PEXIMM) || \
+ ((pws)->displayUpdate == PEXVisualizeEach))
+
+SetDoubleDrawable (pwks)
+miWksPtr pwks;
+{
+ /* This routine sets the drawable pointer. It does this with or
+ without the MultiBuffer Extension
+ */
+
+ if (pwks->hasDoubleBuffer)
+ {
+ /* If you have the Double Buffer do whats right for the update mode */
+ switch (pwks->displayUpdate) {
+ case PEXVisualizeEach:
+ case PEXVisualizeWhenever:
+ case PEXVisualizeNone:
+ pwks->pCurDrawable = pwks->doubleDrawables[pwks->curDoubleBuffer];
+ pwks->usingDoubleBuffer = MI_TRUE;
+ break;
+ case PEXSimulateSome:
+ case PEXVisualizeEasy:
+ pwks->pCurDrawable = pwks->pRend->pDrawable;
+ pwks->usingDoubleBuffer = MI_FALSE;
+ break;
+ }
+ }
+ else
+ {
+ /* No Double Buffer so use the renderers drawable */
+ pwks->usingDoubleBuffer = MI_FALSE;
+ pwks->pCurDrawable = pwks->pRend->pDrawable;
+ }
+}
+
+ChangeDoubleBuffers (pwks)
+miWksPtr pwks;
+{
+
+ /* This routine does the actual work to create or delete the
+ Double Buffers. It is a no-op if there is no MultiBuffer
+ Extension, except it still has to SetDoubleBuffers to
+ insure the right drawable gets used
+ */
+
+#ifdef MULTIBUFFER
+
+ if (pwks->curBufferMode == PEXDoubleBuffered && !pwks->hasDoubleBuffer)
+ {
+ /* create the Double Buffers */
+ int i;
+ int client;
+ int result;
+ XID ids[2];
+ extern DrawablePtr GetBufferPointer ();
+
+ client = CLIENT_ID(pwks->pRend->pDrawable->id);
+ for (i = 0; i < 2; i++)
+ ids[i] = FakeClientID (client);
+ result = CreateImageBuffers (pwks->pRend->pDrawable, 2, ids,
+ MultibufferUpdateActionBackground,
+ MultibufferUpdateHintFrequent);
+ if (result != Success)
+ {
+ pwks->pCurDrawable = pwks->pRend->pDrawable;
+ return;
+ }
+ for (i = 0; i < 2; i++)
+ pwks->doubleDrawables[i] = GetBufferPointer (pwks->pRend->pDrawable, i);
+ pwks->curDoubleBuffer = 1;
+ pwks->hasDoubleBuffer = MI_TRUE;
+ }
+ else if (pwks->curBufferMode == PEXSingleBuffered && pwks->hasDoubleBuffer)
+ {
+ /* Destroy the Double Buffers */
+ DestroyImageBuffers (pwks->pRend->pDrawable);
+ pwks->hasDoubleBuffer = MI_FALSE;
+ }
+#endif
+
+ /* With or Without MultiBuffer Call this to set the Drawable Pointer */
+ SetDoubleDrawable (pwks);
+}
+
+SwapDoubleBuffers (pwks)
+miWksPtr pwks;
+{
+ int i;
+
+ /* This one swaps the buffers, a no-op if no MultiBuffer Extension */
+
+#ifdef MULTIBUFFER
+ if (pwks->usingDoubleBuffer)
+ {
+ DisplayImageBuffers (&pwks->pCurDrawable->id, 1);
+ pwks->curDoubleBuffer ^= 1;
+ pwks->pCurDrawable = pwks->doubleDrawables[pwks->curDoubleBuffer];
+ }
+#endif
+}
+
+
+
+/*++
+ |
+ | Function Name: CreatePhigsWks
+ |
+ | Function Description:
+ | Handles the PEXCreatePhigsWKS request.
+ |
+ | Note(s):
+ |
+ --*/
+
+/* set dst = src and if it's not NULL, update the ref list */
+#define MIWKS_SETLUT( SRCLUT, DSTLUT, WKS ) \
+ if ( (DSTLUT) = (SRCLUT) ) { \
+ if(UpdateLUTRefs( (DSTLUT), (diResourceHandle)WKS, \
+ WORKSTATION_RESOURCE, ADD ) ) { \
+ deletewks((miWksPtr)(WKS->deviceData), WKS); \
+ return (BadAlloc); \
+ } }
+
+#define MIWKS_SETNS( SRCNS, DSTNS, WKS ) \
+ if ( (DSTNS) = (SRCNS) ) { \
+ if (UpdateNSRefs( (DSTNS), (diResourceHandle)WKS, \
+ WORKSTATION_RESOURCE, ADD )) { \
+ deletewks((miWksPtr)(WKS->deviceData), WKS); \
+ return (BadAlloc); \
+ } }
+
+ddpex4rtn
+CreatePhigsWks(pInitInfo, pWKS)
+/* in */
+ ddWksInit *pInitInfo; /* workstation info */
+ diWKSHandle pWKS; /* workstation handle */
+/* out */
+{
+ register miWksPtr pwks;
+ register ddRendererPtr prend;
+ ddOrdStruct *pos;
+ diLUTHandle view;
+ register int i;
+ int type;
+
+#ifdef DDTEST
+ ErrorF("\nCreatePhigsWks\n");
+#endif
+ pWKS->deviceData = NULL;
+
+ if (!pInitInfo->pDrawable)
+ return (BadDrawable);
+ MI_WHICHDRAW(pInitInfo->pDrawable, type);
+
+ pwks = (miWksPtr) xalloc(sizeof(miWksStr));
+ if (pwks == NULL)
+ return (BadAlloc);
+ pWKS->deviceData = (ddPointer) pwks;
+
+ pwks->pRend = NULL;
+ pwks->refCount = 0;
+ pwks->freeFlag = 0;
+ pwks->reqViewTable = 0;
+
+ pwks->pwksList = puCreateList(DD_WKS);
+ if (!pwks->pwksList) {
+ xfree(pwks);
+ pWKS->deviceData = NULL;
+ return (BadAlloc);
+ }
+
+ /* see miWks.h for explanation of how view priority list works
+ * there are dummy first and last entries */
+ pwks->views.defined_views = 0;
+ pwks->views.highest = &(pwks->views.entries[0]);
+ pwks->views.lowest = &(pwks->views.entries[1]);
+ pwks->views.entries[0].defined = MI_FALSE;
+ pwks->views.entries[0].first_view = 0;
+ pwks->views.entries[0].last_view = 0;
+ pwks->views.entries[0].higher = NULL;
+ pwks->views.entries[0].lower = &(pwks->views.entries[2]);
+ pwks->views.entries[1].defined = MI_FALSE;
+ pwks->views.entries[1].first_view = 0;
+ pwks->views.entries[1].last_view = 0;
+ pwks->views.entries[1].higher = &(pwks->views.entries[2]);
+ pwks->views.entries[1].lower = NULL;
+ /* set first entry */
+ pwks->views.entries[2].defined = MI_FALSE;
+ pwks->views.entries[2].first_view = 0;
+ pwks->views.entries[2].last_view = 65534;
+ pwks->views.entries[2].higher = &(pwks->views.entries[0]);
+ pwks->views.entries[2].lower = &(pwks->views.entries[1]);
+ /* set free entries */
+ pwks->views.free = &(pwks->views.entries[3]);
+ for (i = 3; i < MIWKS_MAX_ORD_VIEWS - 1; i++) {
+ pwks->views.entries[i].defined = MI_FALSE;
+ pwks->views.entries[i].first_view = 0;
+ pwks->views.entries[i].last_view = 0;
+ pwks->views.entries[i].higher = &(pwks->views.entries[i - 1]);
+ pwks->views.entries[i].lower = &(pwks->views.entries[i + 1]);
+ }
+ /* redefine the higher value for the first free entry */
+ pwks->views.entries[3].higher = NULL;
+ /* now define the last free entry */
+ i = MIWKS_MAX_ORD_VIEWS - 1;
+ pwks->views.entries[i].defined = MI_FALSE;
+ pwks->views.entries[i].first_view = 0;
+ pwks->views.entries[i].last_view = 0;
+ pwks->views.entries[i].higher = &(pwks->views.entries[i - 1]);
+ pwks->views.entries[i].lower = NULL;
+ /* predefined views are set in the priority list later */
+
+ pwks->postedStructs.numStructs = 0;
+ pwks->postedStructs.postruct = NULL;
+
+ prend = (ddRendererPtr) xalloc(sizeof(ddRendererStr));
+ if (prend == NULL) {
+ deletewks(pwks, pWKS);
+ return (BadAlloc);
+ }
+ pwks->pRend = prend;
+
+ /* initialize the renderer */
+ /* initialize the default pipeline context, if necessary,
+ and set this into the renderer */
+ prend->pPC = NULL;
+
+ /* initialize to 0, just in case we hit an alloc error and
+ call deletewks before finishing creation
+ */
+ for (i = MI_FIRSTTABLETYPE; i <= PEXMaxTableType; i++)
+ prend->lut[i] = 0;
+
+ for (i=0; i< (int) DD_MAX_FILTERS; i++)
+ prend->lut[i] = 0;
+
+ for (i=0; i< MIWKS_NUM_PICK_DEVICES; i++)
+ pwks->devices[i].path = 0;
+
+ /* expect a valid drawable */
+ MI_SETDRAWEXAMPLE(pInitInfo->pDrawable, &(prend->drawExample));
+
+ prend->rendId = pWKS->id;
+ prend->pDrawable = pInitInfo->pDrawable;
+ prend->drawableId = pInitInfo->drawableId;
+ prend->curPath = puCreateList(DD_ELEMENT_REF);
+ prend->clipList = 0;
+ if (!prend->curPath) {
+ deletewks(pwks, pWKS);
+ return (BadAlloc);
+ }
+ prend->clipList = puCreateList(DD_DEVICE_RECT);
+ if (!prend->clipList) {
+ deletewks(pwks, pWKS);
+ return (BadAlloc);
+ }
+ prend->state = PEXIdle;
+
+ /* add later: make sure that the drawable is OK for the luts */
+ MIWKS_SETLUT(pInitInfo->pMarkerLUT, prend->lut[PEXMarkerBundleLUT], pWKS);
+ MIWKS_SETLUT(pInitInfo->pTextLUT, prend->lut[PEXTextBundleLUT], pWKS);
+ MIWKS_SETLUT(pInitInfo->pLineLUT, prend->lut[PEXLineBundleLUT], pWKS);
+ MIWKS_SETLUT(pInitInfo->pIntLUT, prend->lut[PEXInteriorBundleLUT], pWKS);
+ MIWKS_SETLUT(pInitInfo->pEdgeLUT, prend->lut[PEXEdgeBundleLUT], pWKS);
+ /* view table done later */
+ MIWKS_SETLUT(pInitInfo->pColourLUT, prend->lut[PEXColourLUT], pWKS);
+ MIWKS_SETLUT(pInitInfo->pDepthCueLUT, prend->lut[PEXDepthCueLUT], pWKS);
+ MIWKS_SETLUT(pInitInfo->pLightLUT, prend->lut[PEXLightLUT], pWKS);
+ MIWKS_SETLUT(pInitInfo->pColourAppLUT, prend->lut[PEXColourApproxLUT], pWKS);
+ MIWKS_SETLUT(pInitInfo->pPatternLUT, prend->lut[PEXPatternLUT], pWKS);
+ MIWKS_SETLUT(pInitInfo->pFontLUT, prend->lut[PEXTextFontLUT], pWKS);
+
+ MIWKS_SETNS(pInitInfo->pHighInclSet, prend->ns[(int) DD_HIGH_INCL_NS], pWKS);
+ MIWKS_SETNS(pInitInfo->pHighExclSet, prend->ns[(int) DD_HIGH_EXCL_NS], pWKS);
+ MIWKS_SETNS(pInitInfo->pInvisInclSet, prend->ns[(int) DD_INVIS_INCL_NS], pWKS);
+ MIWKS_SETNS(pInitInfo->pInvisExclSet, prend->ns[(int) DD_INVIS_EXCL_NS], pWKS);
+ /* These are for Renderer Picking, not used for Wks */
+ MIWKS_SETNS(0, prend->ns[(int) DD_PICK_INCL_NS], pWKS);
+ MIWKS_SETNS(0, prend->ns[(int) DD_PICK_EXCL_NS], pWKS);
+
+
+ prend->hlhsrMode = PEXHlhsrOff;
+ prend->npcSubvolume = NPCInit;
+
+ prend->viewport.useDrawable = MI_TRUE;
+ prend->viewport.minval.x = 0.0;
+ prend->viewport.minval.y = 0.0;
+ prend->viewport.minval.z = 0.0;
+ prend->viewport.maxval.x = prend->pDrawable->width;
+ prend->viewport.maxval.y = prend->pDrawable->height;
+ prend->viewport.maxval.z = 1.0;
+ /* don't really use renderer dynamics */
+ prend->tablesMask = 0;
+ prend->namesetsMask = 0;
+ prend->attrsMask = 0;
+ prend->tablesChanges = 0;
+ prend->namesetsChanges = 0;
+ prend->attrsChanges = 0;
+ prend->immediateMode = FALSE;
+
+ prend->pDDContext = NULL;
+
+ /* new flags added for 5.1 need to be initialized */
+ prend->backgroundColour.colourType = PEXIndexedColour;
+ prend->backgroundColour.colour.indexed.index = 0;
+ prend->clearI = FALSE;
+ prend->clearZ = TRUE;
+ prend->echoMode = PEXNoEcho;
+ prend->echoColour.colourType = PEXIndexedColour;
+ prend->echoColour.colour.indexed.index = 0;
+
+
+ pwks->displayUpdate = PEXVisualizeEach;
+ pwks->visualState = PEXCorrect;
+ pwks->displaySurface = PEXEmpty;
+ pwks->viewUpdate = PEXNotPending;
+ pwks->deltaviewMask = 0;
+ pwks->wksUpdate = PEXNotPending;
+ pwks->wksMask = 0;
+
+ pwks->hlhsrUpdate = PEXNotPending;
+
+ pwks->bufferUpdate = PEXNotPending;
+ pwks->curBufferMode = pwks->reqBufferMode = pInitInfo->bufferMode;
+ pwks->hasDoubleBuffer = MI_FALSE;
+
+ pwks->reqNpcSubvolume = NPCInit;
+
+ pwks->reqviewport.useDrawable = MI_TRUE;
+ pwks->reqviewport.minval.x = 0.0;
+ pwks->reqviewport.minval.y = 0.0;
+ pwks->reqviewport.minval.z = 0.0;
+ pwks->reqviewport.maxval.x = prend->pDrawable->width;
+ pwks->reqviewport.maxval.y = prend->pDrawable->height;
+ pwks->reqviewport.maxval.z = 1.0;
+
+ /*
+ * pos: ordered structure list for posted structures. the first pos
+ * is a dummy
+ */
+ pos = (ddOrdStruct *) xalloc(sizeof(ddOrdStruct));
+ if (pos == NULL) {
+ deletewks(pwks, pWKS);
+ return (BadAlloc);
+ }
+ pos->pstruct = 0;
+ pos->priority = 0;
+ pos->next = NULL;
+ pwks->postedStructs.postruct = pos;
+ pwks->postedStructs.numStructs = 0;
+
+ /*
+ * create the view tables as PEX lookup tables use the wks id as the
+ * lut id. don't put the workstation on the view table's reference
+ * list, we don't want the LUT procedure to generate any picture
+ * redraws this also prevents any nasty side effects when the
+ * resource is deleted
+ */
+
+ /* requested view */
+ /* first create the resource structure that has the table id and type */
+ if (!(view = (diLUTHandle) xalloc(sizeof(ddLUTResource)))) {
+ deletewks(pwks, pWKS);
+ return (BadAlloc);
+ }
+ view->id = pWKS->id;
+ view->lutType = PEXViewLUT;
+
+ if (err43 = CreateLUT(pInitInfo->pDrawable, view)) {
+ deletewks(pwks, pWKS);
+ return (err43);
+ }
+ pwks->reqViewTable = view;
+
+ /* current view */
+ /* first create the resource structure that has the table id and type */
+ if (!(view = (diLUTHandle) xalloc(sizeof(ddLUTResource)))) {
+ deletewks(pwks, pWKS);
+ return (BadAlloc);
+ }
+ view->id = pWKS->id;
+ view->lutType = PEXViewLUT;
+
+ if (err43 = CreateLUT(pInitInfo->pDrawable, view)) {
+ deletewks(pwks, pWKS);
+ return (err43);
+ }
+ prend->lut[PEXViewLUT] = view;
+
+ /*
+ * add an entry for each predefined view note that this assumes that
+ * view 0 is defined to the PEX default values as required for PHIGS
+ * wks
+ */
+ if ((MILUT_HEADER(view))->tableInfo.numPredefined) {
+ for (i = (MILUT_HEADER(view))->tableInfo.predefinedMin;
+ i <= (MILUT_HEADER(view))->tableInfo.predefinedMax; i++) {
+ err3 = mi_add_ord_view(&pwks->views, (ddUSHORT)i);
+ }
+ }
+ /* WksDynamics */
+ for (i = 0; i < (int) MAX_DYNAMIC; i++)
+ pwks->dynamics[i] = mi_dynamics[type][i];
+
+ /* call level III procedure to create dd parts of renderer */
+ if (err3 = InitRenderer(prend)) {
+ deletewks(pwks, pWKS);
+ return (err3);
+ }
+
+ /* Pick device */
+ if (!init_pick_flag) {
+ initialize_pick_devices();
+ init_pick_flag = MI_TRUE;
+ }
+ for (i = 0; i < MIWKS_NUM_PICK_DEVICES; i++) {
+ pwks->devices[i] = pick_devices[i];
+ if (!(pwks->devices[i].path = puCreateList(DD_PICK_PATH))) {
+ deletewks(pwks, pWKS);
+ return (BadAlloc);
+ }
+ }
+
+
+ /* do stuff here to set up hlhsr mode */
+
+ /* do stuff here to set up buffer mode */
+ ChangeDoubleBuffers (pwks);
+
+ return (Success);
+} /* CreatePhigsWks */
+
+static void
+deletewks(pwks, pWKS)
+ miWksPtr pwks;
+ diWKSHandle pWKS;
+{
+ register ddRendererPtr prend;
+ register int i;
+ ddOrdStruct *pos, *posn;
+
+ if (pwks == NULL) return;
+ prend = pwks->pRend;
+ if (prend) {
+ register int i;
+ for (i = MI_FIRSTTABLETYPE; i <= PEXMaxTableType; i++) {
+ if (prend->lut[i]) {
+ if (i != PEXViewLUT)
+ err43 = UpdateLUTRefs(prend->lut[i], (diResourceHandle) pWKS,
+ WORKSTATION_RESOURCE, REMOVE);
+ else
+
+ /*
+ * FreeLUT frees the resource handle structure and the
+ * dd struct if there are no outstanding refs to the LUT
+ */
+ FreeLUT(prend->lut[i], pWKS->id);
+ prend->lut[i] = 0;
+ }
+ }
+ for (i = 0; i < (int) DD_MAX_FILTERS; i++) {
+ if (prend->ns[i])
+ err43 = UpdateNSRefs(prend->ns[i], (diResourceHandle) pWKS,
+ WORKSTATION_RESOURCE, REMOVE);
+ }
+
+ if (prend->curPath) {
+ puDeleteList(prend->curPath);
+ prend->curPath = 0; }
+ if (prend->clipList) {
+ puDeleteList(prend->clipList);
+ prend->clipList = 0; }
+
+ if (prend->pDDContext) {
+ DeleteDDContext(prend->pDDContext);
+ prend->pDDContext = 0; }
+
+ if (prend->pPC) {
+ xfree(prend->pPC); /* allocated in one chunk */
+ prend->pPC = 0;}
+
+ xfree(prend);
+ pwks->pRend = 0;
+ }
+
+ if (pwks->reqViewTable) {
+ FreeLUT(pwks->reqViewTable, pWKS->id);
+ pwks->reqViewTable; }
+ if (pwks->pwksList) {
+ puDeleteList(pwks->pwksList);
+ pwks->reqViewTable; }
+
+ /* unpost all the structures */
+ if (pwks->postedStructs.postruct) {
+ pos = pwks->postedStructs.postruct->next; /* first element is a dummy */
+ while (pos) {
+ /* take the wks out of the structs wks lists */
+ err4 = UpdateStructRefs( pos->pstruct, (diResourceHandle) pWKS,
+ WORKSTATION_RESOURCE, REMOVE);
+ posn = pos;
+ pos = posn->next;
+ xfree(posn);
+ }
+ pwks->postedStructs.numStructs = 0;
+ pwks->postedStructs.postruct->next = 0;
+ xfree(pwks->postedStructs.postruct);
+ pwks->postedStructs.postruct = 0;
+ }
+
+ /* pick devices */
+ for (i = 0; i < MIWKS_NUM_PICK_DEVICES; i++) {
+
+ /*
+ * paths are empty on initialization, but remember that structure
+ * reference count are updated when the path changes
+ */
+ path_update_struct_refs(pwks->devices[i].path, (diResourceHandle) NULL,
+ PICK_RESOURCE, REMOVE);
+
+ if (pwks->devices[i].path) {
+ puDeleteList(pwks->devices[i].path);
+ pwks->devices[i].path = 0; }
+ if (pwks->devices[i].inclusion) {
+ err43 = UpdateNSRefs(pwks->devices[i].inclusion,
+ (diResourceHandle) NULL, PICK_RESOURCE, REMOVE);
+ pwks->devices[i].inclusion = 0; }
+ if (pwks->devices[i].exclusion) {
+ err43 = UpdateNSRefs(pwks->devices[i].exclusion,
+ (diResourceHandle) NULL, PICK_RESOURCE, REMOVE);
+ pwks->devices[i].exclusion = 0; }
+ }
+
+ xfree(pwks);
+ pWKS->deviceData = NULL;
+ return;
+} /* deletewks */
+
+#define CHECK_DELETE( pddwks, handle ) \
+ if ((((pddwks)->freeFlag) == MI_TRUE) && (((pddwks)->refCount) <= 0 )) \
+ { deletewks( pddwks, handle ); \
+ xfree((char *)(handle)); \
+ }
+
+/*++
+ |
+ | Function Name: FreePhigsWks
+ |
+ | Function Description:
+ | Handles the PEXFreePhigsWKS request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+FreePhigsWks(pWKS, WKSid)
+/* in */
+ diWKSHandle pWKS; /* workstation handle */
+ ddResourceId WKSid; /* phigs workstation resource id */
+/* out */
+{
+ register miWksPtr pwks = (miWksPtr) pWKS->deviceData;
+
+#ifdef DDTEST
+ ErrorF("\nFreePhigsWks\n");
+#endif
+
+ pWKS->id = PEXAlreadyFreed;
+ pwks->freeFlag = MI_TRUE;
+ CHECK_DELETE(pwks, pWKS);
+
+ return (Success);
+} /* FreePhigsWks */
+
+/*++
+ |
+ | Function Name: InquireWksInfo
+ |
+ | Function Description:
+ | Handles the PEXGetWKSInfo request.
+ |
+ | Note(s):
+ |
+ --*/
+
+/* depends on 'mask' being defined */
+#define WKS_CHECK_BITMASK( bitIndex ) \
+ if (mask[((bitIndex)/32)] & (((unsigned long)1) << ((bitIndex) % 32)))
+
+/* depends on 'mask' and needbytes being there */
+#define COUNTBYTES( type, bytes ) \
+ WKS_CHECK_BITMASK( type ) \
+ needbytes += (bytes)
+
+static XID ulNULL = 0;
+
+#define PLUTID( plut ) \
+ (plut)==NULL ? &ulNULL : &(plut)->id
+
+#define PNSID( pns ) \
+ (pns)==NULL ? &ulNULL : &(pns)->id
+
+ddpex4rtn
+InquireWksInfo(pWKS, mask, pNumValues, pBuffer)
+/* in */
+ diWKSHandle pWKS; /* workstation handle */
+ ddBitmask mask[2];/* item mask */
+/* out */
+ ddULONG *pNumValues; /* number of items returned */
+ ddBufferPtr pBuffer;/* workstation information */
+{
+ register miWksPtr pwks = (miWksPtr) pWKS->deviceData;
+ ddULONG needbytes;
+ int sshort, sulong, sbyte, sushort, sfloat, spexNpcSubvolume, spexViewport;
+ ddPointer pbyte;
+
+#ifdef DDTEST
+ ErrorF("\nInquireWksInfo\n");
+#endif
+
+ *pNumValues = 0;
+
+ /* calculate the number of bytes needed to return the info */
+ needbytes = 0;
+
+ COUNTBYTES(PEXPWDisplayUpdate, 4);
+ COUNTBYTES(PEXPWVisualState, 4);
+ COUNTBYTES(PEXPWDisplaySurface, 4);
+ COUNTBYTES(PEXPWViewUpdate, 4);
+ COUNTBYTES(PEXPWDefinedViews, (4 + 4 * pwks->views.defined_views));
+ COUNTBYTES(PEXPWWksUpdate, 4);
+ COUNTBYTES(PEXPWReqNpcSubvolume, 24);
+ COUNTBYTES(PEXPWCurNpcSubvolume, 24);
+ COUNTBYTES(PEXPWReqWksViewport, 20);
+ COUNTBYTES(PEXPWCurWksViewport, 20);
+ COUNTBYTES(PEXPWHlhsrUpdate, 4);
+ COUNTBYTES(PEXPWReqHlhsrMode, 4);
+ COUNTBYTES(PEXPWCurHlhsrMode, 4);
+ COUNTBYTES(PEXPWDrawable, 4);
+ COUNTBYTES(PEXPWMarkerBundle, 4);
+ COUNTBYTES(PEXPWTextBundle, 4);
+ COUNTBYTES(PEXPWLineBundle, 4);
+ COUNTBYTES(PEXPWInteriorBundle, 4);
+ COUNTBYTES(PEXPWEdgeBundle, 4);
+ COUNTBYTES(PEXPWColourTable, 4);
+ COUNTBYTES(PEXPWDepthCueTable, 4);
+ COUNTBYTES(PEXPWLightTable, 4);
+ COUNTBYTES(PEXPWColourApproxTable, 4);
+ COUNTBYTES(PEXPWPatternTable, 4);
+ COUNTBYTES(PEXPWTextFontTable, 4);
+ COUNTBYTES(PEXPWHighlightIncl, 4);
+ COUNTBYTES(PEXPWHighlightExcl, 4);
+ COUNTBYTES(PEXPWInvisibilityIncl, 4);
+ COUNTBYTES(PEXPWInvisibilityExcl, 4);
+ COUNTBYTES(PEXPWPostedStructures, (4 + 8 * pwks->postedStructs.numStructs));
+ COUNTBYTES(PEXPWNumPriorities, 4);
+ COUNTBYTES(PEXPWBufferUpdate, 4);
+ COUNTBYTES(PEXPWCurBufferMode, 4);
+ COUNTBYTES(PEXPWReqBufferMode, 4);
+
+ PU_CHECK_BUFFER_SIZE(pBuffer, needbytes);
+
+ /* let's remember a few sizes */
+ sshort = sizeof(ddSHORT);
+ ASSURE(sshort == 2);
+ sbyte = sizeof(ddBYTE);
+ ASSURE(sbyte == 1);
+ sulong = sizeof(ddULONG);
+ ASSURE(sulong == 4);
+ sushort = sizeof(ddUSHORT);
+ ASSURE(sushort == 2);
+ sfloat = sizeof(ddFLOAT);
+ ASSURE(sfloat == 4);
+ spexNpcSubvolume = sizeof(ddNpcSubvolume);
+ ASSURE(spexNpcSubvolume == 24);
+ spexViewport = sizeof(ddViewport);
+ ASSURE(spexViewport == 20);
+
+ pbyte = pBuffer->pBuf;
+
+ /* return the info in the format encoded for the reply */
+
+ /*
+ Took out the micopy usage cause it was a real brain dead way
+ to do this. Note that this stuff NEVER checks the buffer size,
+ maybe I'll add this someday - JSH
+ */
+ WKS_CHECK_BITMASK(PEXPWDisplayUpdate) {
+ PACK_CARD32(pwks->displayUpdate, pbyte);
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWVisualState) {
+ PACK_CARD32(pwks->visualState, pbyte);
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWDisplaySurface) {
+ PACK_CARD32(pwks->displaySurface, pbyte);
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWViewUpdate) {
+ PACK_CARD32(pwks->viewUpdate, pbyte);
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWDefinedViews) {
+ /* returns in order, highest priority view first */
+ ddOrdView *indexer;
+
+ (*pNumValues) += pwks->views.defined_views;
+ PACK_CARD32(pwks->views.defined_views, pbyte);
+ indexer = pwks->views.highest;
+ do {
+ if (indexer->defined) {
+ PACK_CARD32(indexer->first_view, pbyte);
+ }
+ indexer = indexer->lower;
+ } while (indexer != NULL);
+ }
+ WKS_CHECK_BITMASK(PEXPWWksUpdate) {
+ PACK_CARD32(pwks->wksUpdate, pbyte);
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWReqNpcSubvolume) {
+ PACK_STRUCT(ddNpcSubvolume, &(pwks->reqNpcSubvolume), pbyte);
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWCurNpcSubvolume) {
+ PACK_STRUCT(ddNpcSubvolume, &(pwks->pRend->npcSubvolume), pbyte);
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWReqWksViewport) {
+ PACK_STRUCT(ddViewport, &(pwks->reqviewport), pbyte);
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWCurWksViewport) {
+ PACK_STRUCT(ddViewport, &(pwks->pRend->viewport), pbyte);
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWHlhsrUpdate) {
+ PACK_CARD32(pwks->hlhsrUpdate, pbyte);
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWReqHlhsrMode) {
+ PACK_CARD32(pwks->reqhlhsrMode, pbyte);
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWCurHlhsrMode) {
+ PACK_CARD32(pwks->pRend->hlhsrMode, pbyte);
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWDrawable) {
+ PACK_CARD32(pwks->pRend->drawableId, pbyte);
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWMarkerBundle) {
+ PACK_CARD32(*(PLUTID(pwks->pRend->lut[PEXMarkerBundleLUT])), pbyte);
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWTextBundle) {
+ PACK_CARD32(*(PLUTID(pwks->pRend->lut[PEXTextBundleLUT])), pbyte);
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWLineBundle) {
+ PACK_CARD32(*(PLUTID(pwks->pRend->lut[PEXLineBundleLUT])), pbyte);
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWInteriorBundle) {
+ PACK_CARD32(*(PLUTID(pwks->pRend->lut[PEXInteriorBundleLUT])), pbyte);
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWEdgeBundle) {
+ PACK_CARD32(*(PLUTID(pwks->pRend->lut[PEXEdgeBundleLUT])), pbyte);
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWColourTable) {
+ PACK_CARD32(*(PLUTID(pwks->pRend->lut[PEXColourLUT])), pbyte);
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWDepthCueTable) {
+ PACK_CARD32(*(PLUTID(pwks->pRend->lut[PEXDepthCueLUT])), pbyte);
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWLightTable) {
+ PACK_CARD32(*(PLUTID(pwks->pRend->lut[PEXLightLUT])), pbyte);
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWColourApproxTable) {
+ PACK_CARD32(*(PLUTID(pwks->pRend->lut[PEXColourApproxLUT])), pbyte);
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWPatternTable) {
+ PACK_CARD32(*(PLUTID(pwks->pRend->lut[PEXPatternLUT])), pbyte);
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWTextFontTable) {
+ PACK_CARD32(*(PLUTID(pwks->pRend->lut[PEXTextFontLUT])), pbyte);
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWHighlightIncl) {
+ PACK_CARD32(*(PNSID(pwks->pRend->ns[(int) DD_HIGH_INCL_NS])), pbyte);
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWHighlightExcl) {
+ PACK_CARD32(*(PNSID(pwks->pRend->ns[(int) DD_HIGH_EXCL_NS])), pbyte);
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWInvisibilityIncl) {
+ PACK_CARD32(*(PNSID(pwks->pRend->ns[(int) DD_INVIS_INCL_NS])), pbyte);
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWInvisibilityExcl) {
+ PACK_CARD32(*(PNSID(pwks->pRend->ns[(int) DD_INVIS_EXCL_NS])), pbyte);
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWPostedStructures) {
+ register ddOrdStruct *pos;
+
+ PACK_CARD32(pwks->postedStructs.numStructs, pbyte);
+ pos = pwks->postedStructs.postruct;
+ while (pos->next) {
+ PACK_CARD32(pos->next->pstruct->id, pbyte);
+ PACK_FLOAT(pos->next->priority, pbyte);
+ pos = pos->next;
+ }
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWNumPriorities) {
+
+ /*
+ * return 0 for now - should implement num_priorities as part
+ * of the wks
+ */
+ PACK_CARD32( 0, pbyte);
+ (*pNumValues)++;
+ }
+
+ WKS_CHECK_BITMASK( PEXPWBufferUpdate )
+ {
+ PACK_CARD32( pwks->bufferUpdate, pbyte);
+ (*pNumValues)++;
+ }
+
+ WKS_CHECK_BITMASK(PEXPWReqBufferMode) {
+ PACK_CARD32( pwks->reqBufferMode, pbyte);
+ (*pNumValues)++;
+ }
+ WKS_CHECK_BITMASK(PEXPWCurBufferMode) {
+ PACK_CARD32( pwks->curBufferMode, pbyte);
+ (*pNumValues)++;
+ }
+ pBuffer->dataSize = needbytes;
+ ASSURE(needbytes == (pbyte - pBuffer->pBuf));
+
+ return (Success);
+} /* InquireWksInfo */
+
+/*++
+ |
+ | Function Name: InquireWksDynamics
+ |
+ | Function Description:
+ | Handles the PEXGetDynamics request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+InquireWksDynamics(pDrawable, pValues)
+/* in */
+ DrawablePtr pDrawable; /* drawable */
+/* out */
+ ddWksDynamics *pValues;/* dynamics information */
+{
+ ddBYTE *pdtable;
+ int type;
+
+#ifdef DDTEST
+ ErrorF("\nInquireWksDynamics\n");
+#endif
+
+ MI_WHICHDRAW(pDrawable, type);
+
+ pdtable = mi_dynamics[type];
+ pValues->viewRep = pdtable[(int) VIEW_REP_DYNAMIC];
+ pValues->markerBundle = pdtable[(int) MARKER_BUNDLE_DYNAMIC];
+ pValues->textBundle = pdtable[(int) TEXT_BUNDLE_DYNAMIC];
+ pValues->lineBundle = pdtable[(int) LINE_BUNDLE_DYNAMIC];
+ pValues->interiorBundle = pdtable[(int) INTERIOR_BUNDLE_DYNAMIC];
+ pValues->edgeBundle = pdtable[(int) EDGE_BUNDLE_DYNAMIC];
+ pValues->colourTable = pdtable[(int) COLOUR_TABLE_DYNAMIC];
+ pValues->patternTable = pdtable[(int) PATTERN_TABLE_DYNAMIC];
+ pValues->wksTransform = pdtable[(int) WKS_TRANSFORM_DYNAMIC];
+ pValues->highlightFilter = pdtable[(int) HIGH_FILTER_DYNAMIC];
+ pValues->invisFilter = pdtable[(int) INVIS_FILTER_DYNAMIC];
+ pValues->hlhsrMode = pdtable[(int) HLHSR_MODE_DYNAMIC];
+ pValues->strModify = pdtable[(int) STR_MODIFY_DYNAMIC];
+ pValues->postStr = pdtable[(int) POST_STR_DYNAMIC];
+ pValues->unpostStr = pdtable[(int) UNPOST_STR_DYNAMIC];
+ pValues->deleteStr = pdtable[(int) DELETE_STR_DYNAMIC];
+ pValues->refModify = pdtable[(int) REF_MODIFY_DYNAMIC];
+ pValues->bufferModify = pdtable[(int) BUFFER_MODIFY_DYNAMIC];
+ pValues->lightTable = pdtable[(int) BUFFER_MODIFY_DYNAMIC];
+ pValues->depthCueTable = pdtable[(int) BUFFER_MODIFY_DYNAMIC];
+ pValues->colourApproxTable = pdtable[(int) BUFFER_MODIFY_DYNAMIC];
+
+ return (Success);
+} /* InquireWksDynamics */
+
+/*++
+ |
+ | Function Name: InquireViewRep
+ |
+ | Function Description:
+ | Handles the PEXGetViewRep request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+InquireViewRep(pWKS, index, pUpdate, pRequested, pCurrent)
+/* in */
+ diWKSHandle pWKS; /* workstation handle */
+ ddTableIndex index; /* view table index */
+/* out */
+ ddUSHORT *pUpdate;/* (pending/notpending) */
+ ddViewRep *pRequested; /* requested view */
+ ddViewRep *pCurrent; /* current view */
+{
+ register miWksPtr pwks = (miWksPtr) pWKS->deviceData;
+ ddUSHORT status;
+ ddBuffer buffer;
+
+#ifdef DDTEST
+ ErrorF("\nInquireViewRep\n");
+#endif
+
+ *pUpdate = pwks->viewUpdate;
+ buffer.bufSize = 0;
+ buffer.dataSize = 0;
+ buffer.pBuf = NULL;
+ buffer.pHead = NULL;
+ if (err43 = InquireLUTEntry(pwks->reqViewTable, index, PEXSetValue, &status, &buffer))
+ return (err43);
+ pRequested->index = index;
+ mibcopy(buffer.pBuf, &(pRequested->view), sizeof(ddViewEntry));
+ if (err43 = InquireLUTEntry(pwks->pRend->lut[PEXViewLUT], index, PEXSetValue, &status, &buffer))
+ return (err43);
+ pCurrent->index = index;
+ mibcopy(buffer.pBuf, &(pCurrent->view), sizeof(ddViewEntry));
+ xfree(buffer.pHead);
+ return (Success);
+} /* InquireViewRep */
+
+/*++
+ |
+ | Function Name: RedrawStructures
+ |
+ | Function Description:
+ | Handles the PEXRedrawAllStructures request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+RedrawStructures(pWKS)
+/* in */
+ diWKSHandle pWKS; /* workstation handle */
+/* out */
+{
+ register miWksPtr pwks = (miWksPtr) pWKS->deviceData;
+ register DrawablePtr pDraw = pwks->pRend->pDrawable;
+
+
+#ifdef DDTEST
+ ErrorF("\nRedrawStructures\n");
+#endif
+
+ if ( (pDraw == NULL)
+ || (pwks->pRend->drawableId == PEXAlreadyFreed))
+ return (BadDrawable);
+
+ if (pDraw->class == InputOnly) /* from dix dispatch.c */
+ return (BadMatch);
+ else if (!pwks->usingDoubleBuffer) {/* pixmap: fill the rectangle ???? */
+
+ GCPtr pGC;
+ extern GCPtr CreateScratchGC();
+ extern int ChangeGC();
+ extern void ValidateGC();
+ xRectangle xrect;
+ ddUSHORT status;
+ miColourEntry *pLUT;
+ unsigned long gcmask, colourindex;
+
+ /*
+ * get background colour and convert it to an X pixel use
+ * default entry (0) in colourApprox LUT for the conversion
+ */
+ InquireLUTEntryAddress( PEXColourLUT, pwks->pRend->lut[PEXColourLUT], 0,
+ &status, &pLUT);
+ miColourtoIndex(pwks->pRend, 0, &pLUT->entry, &colourindex);
+
+ pGC = CreateScratchGC(pDraw->pScreen, pDraw->depth);
+ gcmask = GCForeground;
+ ChangeGC(pGC, gcmask, &colourindex);
+ ValidateGC(pDraw, pGC);
+ xrect.x = 0;
+ xrect.y = 0;
+ xrect.width = pDraw->width;
+ xrect.height = pDraw->height;
+ (*pGC->ops->PolyFillRect) (pDraw, pGC, 1, &xrect);
+ FreeScratchGC(pGC);
+ pwks->displaySurface = PEXEmpty;
+ }
+
+ /*
+ * If any attributes are set to Pending, make the requested values
+ * current and reset to NotPending - for the following
+ */
+
+ if (pwks->viewUpdate == PEXPending) {
+ register ddUSHORT i, maxviews;
+ ddUSHORT status;
+ ddBuffer buffer;
+
+ buffer.bufSize = sizeof(ddViewEntry);
+ buffer.dataSize = 0;
+ buffer.pHead = buffer.pBuf = (ddPointer) xalloc(sizeof(ddViewEntry));
+
+ if (!buffer.pBuf) return (BadAlloc); /* we're out of memory! */
+
+ /*
+ * loop to check each entry to see if it is pending assume
+ * they are not consecutive entries and set them one at a
+ * time
+ */
+ maxviews = MIWKS_MAX_VIEWS;
+ for (i = 0; i < maxviews; i++) {
+ if (pwks->deltaviewMask & (1L << i)) {
+
+ if (err43 = InquireLUTEntry( pwks->reqViewTable, i,
+ PEXSetValue, &status, &buffer))
+ return (err43); /* we're out of memory! */
+
+ if (err43 = SetLUTEntries( pwks->pRend->lut[PEXViewLUT],
+ i, 1, buffer.pBuf))
+ return (err43); /* we're out of memory! */
+
+ /*
+ * make sure it is in the list of defined
+ * views
+ */
+ err43 = mi_add_ord_view(&pwks->views, i);
+ if (err43) return (err43); /* we're out of memory! */
+ }
+ }
+ pwks->deltaviewMask = 0;
+ xfree(buffer.pBuf);
+ pwks->viewUpdate = PEXNotPending;
+ }
+
+ if (pwks->wksUpdate == PEXPending) {
+ if (pwks->wksMask & WKS_WINDOW_MASK) {
+ pwks->pRend->npcSubvolume = pwks->reqNpcSubvolume;
+ pwks->pRend->attrsChanges |= PEXDynNpcSubvolume;
+ }
+
+ if (pwks->wksMask & WKS_VIEWPORT_MASK) {
+ pwks->pRend->viewport = pwks->reqviewport;
+ pwks->pRend->attrsChanges |= PEXDynViewport;
+ }
+
+ pwks->wksMask = 0;
+ pwks->wksUpdate = PEXNotPending;
+ }
+
+ if (pwks->hlhsrUpdate == PEXPending) {
+ pwks->pRend->hlhsrMode = pwks->reqhlhsrMode;
+ pwks->hlhsrUpdate = PEXNotPending;
+ pwks->pRend->attrsChanges |= PEXDynHlhsrMode;
+ /* do stuff here to effect change in hlhsr mode */
+ }
+
+ if (pwks->bufferUpdate == PEXPending) {
+ pwks->curBufferMode = pwks->reqBufferMode;
+ pwks->bufferUpdate = PEXNotPending;
+ /* do stuff here to effect change in buffer mode */
+ ChangeDoubleBuffers (pwks);
+ }
+ err = miTraverse(pWKS);
+
+ SwapDoubleBuffers (pwks);
+
+ /* Set visual_state to Correct */
+ pwks->visualState = PEXCorrect;
+ /* display Surface is set in miTraverse */
+
+ return (err);
+} /* RedrawStructures */
+
+
+/*++
+ |
+ | Function Name: UpdateWks
+ |
+ | Function Description:
+ | Handles the PEXUpdateWorkstation request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+UpdateWks(pWKS)
+/* in */
+ diWKSHandle pWKS; /* workstation handle */
+/* out */
+{
+ /* If visual_state is Deferred or Simulated, call RedrawAll */
+ if (((miWksPtr) pWKS->deviceData)->visualState != PEXCorrect) {
+ return (RedrawStructures(pWKS));
+ }
+ return (Success);
+} /* UpdateWks */
+
+/*++
+ |
+ | Function Name: RedrawClipRegion
+ |
+ | Function Description:
+ | Handles the PEXRedrawClipRegion request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+RedrawClipRegion(pWKS, numRects, pRects)
+/* in */
+ diWKSHandle pWKS; /* workstation handle */
+ ddULONG numRects; /* number of rectangles in list */
+ ddDeviceRect *pRects; /* list of rectangles */
+/* out */
+{
+ miWksPtr pwks = (miWksPtr) pWKS->deviceData;
+
+#ifdef DDTEST
+ ErrorF("\nRedrawClipRegion\n");
+#endif
+
+ /*
+ * set the clip list in the renderer first, empty the clip list
+ */
+ pwks->pRend->clipList->numObj = 0;
+ if (puAddToList((ddPointer) pRects, numRects, pwks->pRend->clipList)
+ == MI_ALLOCERR)
+ return (BadAlloc);
+
+ pwks->pRend->attrsChanges |= PEXDynClipList;
+
+ /* now redraw picture without updating any state */
+ miTraverse(pWKS); /* ignore errors */
+
+
+ /*
+ * The clip list must be emptied so that subsequent workstation
+ * updates redraw the entire display surface.
+ */
+
+ pwks->pRend->clipList->numObj = 0;
+
+ return (Success);
+} /* RedrawClipRegion */
+
+/*++
+ |
+ | Function Name: ExecuteDeferred
+ |
+ | Function Description:
+ | Handles the PEXExecutedDeferredActions request.
+ |
+ | Note(s):
+ There is no definition in PHIGS or PEX of what this
+ is supposed to do. The PHIGS people we have talked
+ to agree with this. Therefore, we have implemented
+ it as a no-op.
+ |
+ --*/
+
+ddpex4rtn
+ExecuteDeferred(pWKS)
+/* in */
+ diWKSHandle pWKS; /* workstation handle */
+/* out */
+{
+
+#ifdef DDTEST
+ ErrorF("\nExecuteDeferred\n");
+#endif
+
+ return (Success);
+} /* ExecuteDeferred */
+
+/*++
+ |
+ | Function Name: SetViewPriority
+ |
+ | Function Description:
+ | Handles the PEXSetViewPriority request.
+ |
+ | Note(s):
+ move index1 to priority relative to index2
+ |
+ --*/
+
+ddpex4rtn
+SetViewPriority(pWKS, index1, index2, priority)
+/* in */
+ diWKSHandle pWKS; /* workstation handle */
+ ddTableIndex index1; /* view index */
+ ddTableIndex index2; /* view index */
+ ddUSHORT priority; /* (higher/lower) */
+/* out */
+{
+ miWksPtr pwks = (miWksPtr) pWKS->deviceData;
+ ddOrdView *entry1, *entry2;
+
+#ifdef DDTEST
+ ErrorF("\nSetViewPriority\n");
+#endif
+
+ if ((priority != PEXHigher) && (priority != PEXLower))
+ return (BadValue);
+
+ entry1 = mi_find_ord_view(&pwks->views, index1);
+ entry2 = mi_find_ord_view(&pwks->views, index2);
+
+ if ((entry1 == NULL) || (entry2 == NULL))
+ return (BadValue); /* a view is not defined */
+
+ if (index1 == index2)
+ return (Success);
+
+ if (priority == PEXLower) {
+ /* don't do anything if index1 is already next lowest */
+ if (entry2->lower != entry1) {
+ /* take entry1 out of its position */
+ entry1->higher->lower = entry1->lower;
+ entry1->lower->higher = entry1->higher;
+ /* put entry1 before entry2->lower */
+ entry1->lower = entry2->lower;
+ entry2->lower->higher = entry1;
+ /* put entry1 after entry2 */
+ entry2->lower = entry1;
+ entry1->higher = entry2;
+ }
+ } else { /* PEXHigher */
+ /* don't do anything if index1 is already next highest */
+ if (entry2->higher != entry1) {
+ /* take entry1 out of its position */
+ entry1->higher->lower = entry1->lower;
+ entry1->lower->higher = entry1->higher;
+ /* put entry1 after entry2->higher */
+ entry1->higher = entry2->higher;
+ entry2->higher->lower = entry1;
+ /* put entry1 before entry2 */
+ entry2->higher = entry1;
+ entry1->lower = entry2;
+ }
+ }
+
+ return (Success);
+} /* SetViewPriority */
+
+/*++
+ |
+ | Function Name: SetDisplayUpdateMode
+ |
+ | Function Description:
+ | Handles the PEXSetDisplayUpdateMode request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+SetDisplayUpdateMode(pWKS, mode)
+/* in */
+ diWKSHandle pWKS; /* workstation handle */
+ ddSHORT mode; /* display update mode */
+/* out */
+{
+ miWksPtr pwks = (miWksPtr) pWKS->deviceData;
+ register int type, i;
+
+#ifdef DDTEST
+ ErrorF("\nSetDisplayUpdateMode\n");
+#endif
+
+ if ((pwks->pRend->pDrawable == NULL) || (pwks->pRend->drawableId == PEXAlreadyFreed))
+ return (BadDrawable);
+
+ /* todo: put drawtype in wks header */
+
+ MI_WHICHDRAW(pwks->pRend->pDrawable, type);
+
+ /*
+ * make sure this mode is supported by the drawable in this
+ * implementation
+ */
+ for (i = 0; i < SI_UPDATE_NUM; i++) {
+ if (mode == miDisplayUpdateModeET[type][i].index) {
+ pwks->displayUpdate = mode;
+ SetDoubleDrawable (pwks);
+ if (mode == PEXVisualizeEach)
+
+ /*
+ * you may want to do this if mode =
+ * PEXWhenever, too
+ */
+ {
+ /* regen the picture if it isn't correct */
+ if (pwks->visualState != PEXCorrect) {
+ if (err4 = RedrawStructures(pWKS))
+ return (err4);
+ pwks->visualState = PEXCorrect;
+ }
+ }
+ return (Success);
+ }
+ }
+
+ return (BadValue);
+} /* SetDisplayUpdateMode */
+
+/* get_view gets the view transforms from the view table and
+ * it returns the composit transform and the clipping info
+ * it calculates the composite view transform if the vomFlag is true
+ */
+static int
+get_view(view_table, view_index, clipflag, clips, vom, vomFlag)
+ diLUTHandle view_table;
+ ddTableIndex view_index;
+ ddUSHORT *clipflag;
+ ddNpcSubvolume *clips;
+ ddFLOAT vom[4][4];
+ ddBYTE vomFlag;
+{
+ ddBuffer buffer;
+ ddUSHORT status;
+ ddFLOAT orient[4][4];
+ ddFLOAT map[4][4];
+
+ /* get view rep */
+ buffer.pHead = buffer.pBuf = NULL;
+ buffer.dataSize = buffer.bufSize = 0;
+ err = InquireLUTEntry(view_table, view_index, PEXSetValue, &status, &buffer);
+ if (err != Success)
+ return (err);
+
+ mibcopy(&(((ddViewEntry *) buffer.pBuf)->clipLimits),
+ clips, sizeof(ddNpcSubvolume));
+ *clipflag = ((ddViewEntry *) buffer.pBuf)->clipFlags;
+
+ if (vomFlag) {
+ mibcopy((((ddViewEntry *) buffer.pBuf)->orientation),
+ orient, 16 * sizeof(ddFLOAT));
+ mibcopy((((ddViewEntry *) buffer.pBuf)->mapping),
+ map, 16 * sizeof(ddFLOAT));
+ miMatMult(vom, orient, map);
+ }
+ xfree(buffer.pHead);
+ return (Success);
+}
+
+/* no check for z when using drawable */
+#define PT_IN_LIMIT(prend, lim, pt) \
+ ( (pt)->x >= (lim)->minval.x && (pt)->x <= (lim)->maxval.x \
+ && (pt)->y >= (lim)->minval.y && (pt)->y <= (lim)->maxval.y \
+ && (pt)->z >= (lim)->minval.z && (pt)->z <= (lim)->maxval.z )
+
+/*++
+ |
+ | Function Name: MapDcWc
+ |
+ | Function Description:
+ | Handles the PEXMapDCtoWC request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+MapDcWc(pWKS, numPoints, pDCpoints, pRetPoints, pWCpoints, pView)
+/* in */
+ diWKSHandle pWKS; /* workstation handle */
+ ddULONG numPoints; /* number of coords */
+ ddDeviceCoord *pDCpoints; /* list of device coords */
+/* out */
+ ddULONG *pRetPoints; /* number of coords returned */
+ ddCoord3D *pWCpoints; /* list of world coords */
+ ddUSHORT *pView; /* view index */
+{
+ miWksPtr pwks = (miWksPtr) pWKS->deviceData;
+ ddFLOAT npc_dc_xform[4][4];
+ ddFLOAT npc_to_wc_xform[4][4];
+ ddUSHORT clipFlags;
+ ddNpcSubvolume clipLimits;
+ ddDeviceCoord *pDCpoint;
+ ddCoord3D *pWCpoint;
+ ddCoord4D pt4d1, pt4d2;
+ register int i;
+ ddTableIndex view = 0;
+ int ptcount = 0, tmpcount = 0;
+ ddOrdView *poview;
+ ddBOOL last_view;
+
+#ifdef DDTEST
+ ErrorF("\nMapDcWc\n");
+#endif
+
+ *pView = 0;
+ *pRetPoints = 0;
+
+ /*
+ * transforms: wc_to_npc_xform = [view orient][view map]
+ * npc_to_wc_xform = inverse(wc_to_npc_xform)
+ * npc_to_dc_xform = [Sx 0 0 0]
+ * S=Scale [0 Sy 0 0]
+ * T=Translate [0 0 Sz 0]
+ * [Tx Ty Tz 1]
+ * dc_to_npc_xform = inverse(npc_to_dc_xform)
+ * wc_point = [npc_to_wc_xform][npc_point]
+ * npc_point = * [dc_to_npc_xform][dc_point]
+ * (dc_point is a 4d column vector of the
+ * given dc with w=1.0)
+ */
+ miBldViewport_xform(pwks->pRend, pwks->pRend->pDrawable,
+ npc_dc_xform, NULL);
+ miMatInverse(npc_dc_xform);
+
+ /*
+ * go through each defined view and find the one which has the most
+ * points in it and the highest priority
+ */
+ for (last_view = 0, poview = pwks->views.lowest; !last_view; poview = poview->higher) {
+ if (poview->defined) {
+ err = get_view(pwks->pRend->lut[PEXViewLUT], poview->first_view, &clipFlags,
+ &clipLimits, npc_to_wc_xform, MI_FALSE);
+ if (err != Success)
+ return (err);
+
+ for (i = 0, pWCpoint = pWCpoints, pDCpoint = pDCpoints; i < numPoints; i++, pDCpoint++) {
+ pt4d1.x = pDCpoint->x;
+ pt4d1.y = pDCpoint->y;
+ pt4d1.z = pDCpoint->z;
+ pt4d1.w = 1.0;
+ miTransformPoint(&pt4d1, npc_dc_xform, &pt4d2);
+ if (PT_IN_LIMIT(pwks->pRend, &clipLimits, &pt4d2))
+ tmpcount++;
+ }
+
+ /*
+ * use this view if it has more points. if it has
+ * same number then this view has higher priority
+ */
+ if (tmpcount >= ptcount) {
+ view = poview->first_view;
+ ptcount = tmpcount;
+ }
+ }
+ last_view = (poview == pwks->views.highest);
+ }
+
+ err = get_view(pwks->pRend->lut[PEXViewLUT], view, &clipFlags, &clipLimits,
+ npc_to_wc_xform, MI_TRUE);
+ if (err != Success)
+ return (err);
+ miMatInverse(npc_to_wc_xform);
+
+ for (i = 0, pWCpoint = pWCpoints, pDCpoint = pDCpoints; i < numPoints; i++, pDCpoint++) {
+ pt4d1.x = pDCpoint->x;
+ pt4d1.y = pDCpoint->y;
+ pt4d1.z = pDCpoint->z;
+ pt4d1.w = 1.0;
+ miTransformPoint(&pt4d1, npc_dc_xform, &pt4d2);
+ if (PT_IN_LIMIT(pwks->pRend, &clipLimits, &pt4d2)) {
+ miTransformPoint(&pt4d2, npc_to_wc_xform, &pt4d1);
+ pWCpoint->x = pt4d1.x;
+ pWCpoint->y = pt4d1.y;
+ pWCpoint->z = pt4d1.z;
+ pWCpoint++;
+ (*pRetPoints)++;
+ }
+ }
+
+ *pView = view;
+ return (Success);
+} /* MapDcWc */
+
+/*++
+ |
+ | Function Name: MapWcDc
+ |
+ | Function Description:
+ | Handles the PEXMapWCtoDC request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+MapWcDc(pWKS, numPoints, pWCpoints, view, pRetPoints, pDCpoints)
+/* in */
+ diWKSHandle pWKS; /* workstation handle */
+ ddULONG numPoints; /* number of coords */
+ ddCoord3D *pWCpoints; /* list of world coords */
+ ddTableIndex view; /* view index */
+/* out */
+ ddULONG *pRetPoints; /* number of coords returned */
+ ddDeviceCoord *pDCpoints; /* list of device coords */
+{
+ miWksPtr pwks = (miWksPtr) pWKS->deviceData;
+ ddFLOAT wc_to_npc_xform[4][4];
+ ddFLOAT npc_to_dc_xform[4][4];
+ ddUSHORT clipFlags;
+ ddNpcSubvolume clipLimits;
+ ddDeviceCoord *pDCpoint;
+ ddCoord3D *pWCpoint;
+ ddCoord4D pt4d1, pt4d2;
+ register int i;
+
+#ifdef DDTEST
+ ErrorF("\nMapWcDc\n");
+#endif
+
+ *pRetPoints = 0;
+
+ /*
+ * transforms: wc_to_npc_xform = [view orient][view map]
+ * npc_point = [wc_to_npc_xform][wc_point]
+ * (wc_point is a 4d column vector of the
+ * given wc with w=1.0)
+ * npc_to_dc_xform = [Sx 0 0 0]
+ * S=Scale [0 Sy 0 0]
+ * T=Translate [0 0 Sz 0]
+ * [Tx Ty Tz 1]
+ * dc_point = [npc_to_dc_xform][npc_point]
+ */
+ miBldViewport_xform(pwks->pRend, pwks->pRend->pDrawable,
+ npc_to_dc_xform, NULL);
+
+ err = get_view(pwks->pRend->lut[PEXViewLUT], view, &clipFlags, &clipLimits, wc_to_npc_xform, MI_TRUE);
+ if (err != Success)
+ return (err);
+
+ for (i = 0, pWCpoint = pWCpoints, pDCpoint = pDCpoints; i < numPoints; i++, pWCpoint++) {
+ pt4d1.x = pWCpoint->x;
+ pt4d1.y = pWCpoint->y;
+ pt4d1.z = pWCpoint->z;
+ pt4d1.w = 1.0;
+ miTransformPoint(&pt4d1, wc_to_npc_xform, &pt4d2);
+ if (PT_IN_LIMIT(pwks->pRend, &clipLimits, &pt4d2)) {
+ miTransformPoint(&pt4d2, npc_to_dc_xform, &pt4d1);
+ pDCpoint->x = pt4d1.x;
+ pDCpoint->y = pt4d1.y;
+ pDCpoint->z = pt4d1.z;
+ pDCpoint++;
+ (*pRetPoints)++;
+ }
+ }
+
+ return (Success);
+} /* MapWcDc */
+
+/*++
+ |
+ | Function Name: SetViewRep
+ |
+ | Function Description:
+ | Handles the PEXSetViewRep request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+SetViewRep(pWKS, pView)
+/* in */
+ diWKSHandle pWKS; /* workstation handle */
+ ddViewRep *pView; /* view rep */
+/* out */
+{
+ miWksPtr pwks = (miWksPtr) pWKS->deviceData;
+
+#ifdef DDTEST
+ ErrorF("\nSetViewRep\n");
+#endif
+
+ /* set the requested tables */
+ if (err43 = SetLUTEntries(pwks->reqViewTable, pView->index, 1, (ddPointer) & (pView->view)))
+ return (err43);
+
+ if (VISUALIZE_NOW(pwks, VIEW_REP_DYNAMIC)) {
+ /* set the current tables */
+ if (err43 = SetLUTEntries(pwks->pRend->lut[PEXViewLUT], pView->index, 1,
+ (ddPointer) & (pView->view)))
+ return (err43);
+
+ /* set view as defined in view priority list */
+ err43 = mi_add_ord_view(&pwks->views, pView->index);
+ if (err43)
+ return (err43);
+
+ pwks->viewUpdate = PEXNotPending;
+ PU_EMPTY_LIST(pwks->pwksList);
+ puAddToList((ddPointer) & pWKS, (ddULONG) 1, pwks->pwksList);
+
+ miDealWithDynamics(WKS_TRANSFORM_DYNAMIC, pwks->pwksList);
+ } else {
+
+ /*
+ * set mask to show which entry is pending NOTE: mask is only
+ * big enough for tables <= 32 entries our table only has 6
+ * entries right now
+ */
+ pwks->deltaviewMask |= (1L << pView->index);
+
+ pwks->viewUpdate = PEXPending;
+ pwks->visualState = PEXDeferred;
+ }
+
+ return (Success);
+} /* SetViewRep */
+
+/*++
+ |
+ | Function Name: SetWksWindow
+ |
+ | Function Description:
+ | Handles the PEXSetWKSWindow request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+SetWksWindow(pWKS, pNpcSubvolume)
+/* in */
+ diWKSHandle pWKS; /* workstation handle */
+ ddNpcSubvolume *pNpcSubvolume; /* window volume */
+/* out */
+{
+ miWksPtr pwks = (miWksPtr) pWKS->deviceData;
+
+#ifdef DDTEST
+ ErrorF("\nSetWksWindow\n");
+#endif
+
+ pwks->reqNpcSubvolume = *pNpcSubvolume;
+
+ if (VISUALIZE_NOW(pwks, WKS_TRANSFORM_DYNAMIC)) {
+ pwks->pRend->npcSubvolume = *pNpcSubvolume;
+ pwks->pRend->attrsChanges |= PEXDynNpcSubvolume;
+
+ PU_EMPTY_LIST(pwks->pwksList);
+ puAddToList((ddPointer) & pWKS, (ddULONG) 1, pwks->pwksList);
+
+ miDealWithDynamics(WKS_TRANSFORM_DYNAMIC, pwks->pwksList);
+ } else {
+ /* don't update display */
+ pwks->wksUpdate = PEXPending;
+ pwks->visualState = PEXDeferred;
+ pwks->wksMask |= WKS_WINDOW_MASK;
+ }
+ return (Success);
+} /* SetWksWindow */
+
+/*++
+ |
+ | Function Name: SetWksViewport
+ |
+ | Function Description:
+ | Handles the PEXSetWKSViewport request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+SetWksViewport(pWKS, pViewport)
+/* in */
+ diWKSHandle pWKS; /* workstation handle */
+ ddViewport *pViewport; /* viewport */
+/* out */
+{
+ miWksPtr pwks = (miWksPtr) pWKS->deviceData;
+
+#ifdef DDTEST
+ ErrorF("\nSetWksViewport\n");
+#endif
+
+ if ((pwks->pRend->pDrawable == NULL) || (pwks->pRend->drawableId == PEXAlreadyFreed))
+ return (BadDrawable);
+
+ if (pViewport->useDrawable) {
+ pwks->reqviewport.minval.x = 0.0;
+ pwks->reqviewport.minval.y = 0.0;
+ pwks->reqviewport.minval.z = 0.0;
+ pwks->reqviewport.maxval.x = pwks->pRend->pDrawable->width;
+ pwks->reqviewport.maxval.y = pwks->pRend->pDrawable->height;
+ pwks->reqviewport.maxval.z = 1.0;
+ } else
+ pwks->reqviewport = *pViewport;
+
+ if (VISUALIZE_NOW(pwks, WKS_TRANSFORM_DYNAMIC)) {
+ pwks->pRend->viewport = *pViewport;
+ pwks->pRend->attrsChanges |= PEXDynViewport;
+
+ PU_EMPTY_LIST(pwks->pwksList);
+ puAddToList((ddPointer) & pWKS, (ddULONG) 1, pwks->pwksList);
+
+ miDealWithDynamics(WKS_TRANSFORM_DYNAMIC, pwks->pwksList);
+ } else {
+ /* don't update display */
+ pwks->wksUpdate = PEXPending;
+ pwks->visualState = PEXDeferred;
+ pwks->wksMask |= WKS_VIEWPORT_MASK;
+ }
+
+ return (Success);
+} /* SetWksViewport */
+
+/*++
+ |
+ | Function Name: SetHlhsrMode
+ |
+ | Function Description:
+ | Handles the PEXSetHLHSRMode request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+SetHlhsrMode(pWKS, mode)
+/* in */
+ diWKSHandle pWKS; /* workstation handle */
+ ddEnumTypeIndex mode; /* hlhsr mode */
+/* out */
+{
+ miWksPtr pwks = (miWksPtr) pWKS->deviceData;
+ register int i, type;
+
+#ifdef DDTEST
+ ErrorF("\nSetHlhsrMode\n");
+#endif
+
+ if ((pwks->pRend->pDrawable == NULL) || (pwks->pRend->drawableId == PEXAlreadyFreed))
+ return (BadDrawable);
+
+ MI_WHICHDRAW(pwks->pRend->pDrawable, type);
+
+ /*
+ * make sure this mode is supported by the drawable in this
+ * implementation
+ */
+ for (i = 0; i < SI_HLHSR_NUM; i++) {
+ if (mode == miHlhsrModeET[type][i].index) {
+ pwks->reqhlhsrMode = mode;
+ if (WKSIMMEDIATE(pwks, HLHSR_MODE_DYNAMIC))
+ {
+ pwks->pRend->hlhsrMode = mode;
+ pwks->pRend->attrsChanges |= PEXDynHlhsrMode;
+ }
+ /* hlhsrUpdate doesn't change */
+ /* do stuff here to effect change in hlhsr mode */
+ else {
+ /* don't update display */
+ pwks->hlhsrUpdate = PEXPending;
+ pwks->visualState = PEXDeferred;
+ }
+ return (Success);
+ }
+ }
+
+ return (BadValue);
+} /* SetHlhsrMode */
+
+/*++
+ |
+ | Function Name: SetBufferMode
+ |
+ | Function Description:
+ | Handles the PEXSetBufferMode request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+SetBufferMode(pWKS, mode)
+/* in */
+ diWKSHandle pWKS; /* workstation handle */
+ ddUSHORT mode; /* buffer mode */
+/* out */
+{
+ miWksPtr pwks = (miWksPtr) pWKS->deviceData;
+ register int type;
+
+#ifdef DDTEST
+ ErrorF("\nSetBufferMode\n");
+#endif
+
+ if ((pwks->pRend->pDrawable == NULL) || (pwks->pRend->drawableId == PEXAlreadyFreed))
+ return (BadDrawable);
+
+ MI_WHICHDRAW(pwks->pRend->pDrawable, type);
+
+ /*
+ * make sure this mode is supported by the drawable in this
+ * implementation
+ */
+ if ((mode == PEXSingleBuffered) || (mode == PEXDoubleBuffered)) {
+ pwks->reqBufferMode = mode;
+ if (WKSIMMEDIATE(pwks, BUFFER_MODIFY_DYNAMIC))
+ {
+ pwks->curBufferMode = mode;
+ /* bufferUpdate doesn't change */
+ /* do stuff here to effect change in buffer mode */
+ ChangeDoubleBuffers (pwks);
+ }
+ else {
+ /* don't update display */
+ pwks->bufferUpdate = PEXPending;
+ pwks->visualState = PEXDeferred;
+ }
+ return (Success);
+ } else
+ return (BadValue);
+} /* SetBufferMode */
+
+static int
+miAddStructToOrdList(resource, preflist, prity)
+ diStructHandle resource;
+ listofOrdStruct *preflist;
+ ddFLOAT prity;
+{
+ listofOrdStruct *plist = preflist;
+ register ddOrdStruct *postruct, *pbefore, *pnew, *pnext;
+
+#ifdef DDTEST
+ ErrorF("\tmiAddStructToOrdList \n");
+#endif
+ err = MI_SUCCESS;
+
+ /*
+ * check to see if it's in the list already and find out where it
+ * goes in the list if it's in the list, set its priority to the new
+ * priority
+ */
+ pnew = NULL; /* set this to point to the struct already in
+ * the list */
+ pbefore = NULL; /* set this to point to where the struct
+ * belongs inthe list */
+ postruct = preflist->postruct; /* the first element is a dummy */
+
+ /*
+ * loop until the end of the list OR the resource is found in the
+ * list and where it belongs in the list is known
+ */
+ while (postruct->next && (!pnew || !pbefore)) {
+ pnext = postruct->next;
+ if ((prity < pnext->priority) && !pbefore)
+ pbefore = postruct;
+ if (pnext->pstruct == resource) {
+ pnew = pnext; /* remember the old one */
+ postruct->next = pnext->next; /* take it out of the
+ * list */
+ err = MI_EXISTERR;
+ } else
+ postruct = pnext;
+ }
+ if (!pbefore)
+ pbefore = postruct; /* the last element in the list */
+
+ /* now add it to the list */
+ if (!pnew) {
+ if ((pnew = (ddOrdStruct *) xalloc(sizeof(ddOrdStruct))) == NULL)
+ return (MI_ALLOCERR);
+ else
+ plist->numStructs++; /* increment only if it's new
+ * to the list */
+ }
+ pnew->pstruct = resource;
+ pnew->priority = prity;
+
+ pnew->next = pbefore->next;
+ pbefore->next = pnew;
+
+ return (err);
+} /* miAddStructToOrdList */
+
+static void
+miRemoveStructFromOrdList(resource, preflist)
+ diStructHandle resource;
+ listofOrdStruct *preflist;
+{
+ register ddOrdStruct *postruct, *pnew;
+
+#ifdef DDTEST
+ ErrorF("\tmiRemoveStructFromOrdList \n");
+#endif
+
+ pnew = NULL; /* set this to point to the struct already in
+ * the list */
+ postruct = preflist->postruct; /* the first element is a dummy */
+
+ /*
+ * loop until the end of the list OR the resource is found in the
+ * list
+ */
+ while (postruct->next && !pnew) {
+ if (postruct->next->pstruct == resource)
+ pnew = postruct->next;
+ else
+ postruct = postruct->next;
+ }
+ if (pnew) {
+ postruct->next = pnew->next;
+ xfree(pnew);
+ preflist->numStructs--;
+ }
+ return;
+} /* miRemoveStructFromOrdList */
+
+ddBOOL
+miGetStructurePriority(pWKS, pStruct, ppriority)
+ diWKSHandle pWKS; /* workstation handle */
+ diStructHandle pStruct;/* structure handle */
+ ddFLOAT *ppriority; /* structure priority */
+{
+ miWksPtr pwks = (miWksPtr) pWKS->deviceData;
+ listofOrdStruct *plist = &pwks->postedStructs;
+ register ddOrdStruct *postruct, *pnext;
+
+ postruct = plist->postruct; /* the first element is a dummy */
+ *ppriority = 0;
+
+ while (postruct->next) {
+ pnext = postruct->next;
+ if (pnext->pstruct == pStruct) {
+ *ppriority = pnext->priority;
+ return (MI_TRUE);
+ } else
+ postruct = pnext;
+ }
+ return (MI_FALSE);
+}
+
+/*++
+ |
+ | Function Name: PostStructure
+ |
+ | Function Description:
+ | Handles the PEXPostStructure request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+PostStructure(pWKS, pStruct, priority)
+/* in */
+ diWKSHandle pWKS; /* workstation handle */
+ diStructHandle pStruct;/* structure handle */
+ ddFLOAT priority; /* structure priority */
+/* out */
+{
+ miWksPtr pwks = (miWksPtr) pWKS->deviceData;
+
+#ifdef DDTEST
+ ErrorF("\nPostStructure %d\n", pStruct->id);
+#endif
+
+ if ((err = miAddStructToOrdList(pStruct, &(pwks->postedStructs),
+ priority)) == MI_ALLOCERR)
+ return (BadAlloc);
+
+ if (err == MI_SUCCESS) {/* the structure was added */
+ /* add wks to structures list */
+ if (err4 = UpdateStructRefs(pStruct, (diResourceHandle) pWKS,
+ WORKSTATION_RESOURCE, ADD))
+ return (err4);
+ }
+ /* else the structure was already posted it now has a new priority */
+
+ /* do stuff to see if picture needs to be changed */
+ PU_EMPTY_LIST(pwks->pwksList);
+ puAddToList((ddPointer) & pWKS, (ddULONG) 1, pwks->pwksList);
+
+ miDealWithDynamics(POST_STR_DYNAMIC, pwks->pwksList);
+
+ return (Success);
+} /* PostStructure */
+
+/*++
+ |
+ | Function Name: UnpostStructure
+ |
+ | Function Description:
+ | Handles the PEXUnpostStructure request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex4rtn
+UnpostStructure(pWKS, pStruct)
+/* in */
+ diWKSHandle pWKS; /* workstation handle */
+ diStructHandle pStruct;/* structure handle */
+/* out */
+{
+ miWksPtr pwks = (miWksPtr) pWKS->deviceData;
+
+#ifdef DDTEST
+ ErrorF("\nUnpostStructure\n");
+#endif
+
+ /* take the wks out of the structs wks lists */
+ if (err4 = UpdateStructRefs(pStruct, (diResourceHandle) pWKS,
+ WORKSTATION_RESOURCE, REMOVE))
+ return (err4); /* unlikely */
+
+ if (!pwks) return (Success); /* workstation already freed */
+
+ /* now, remove the structure from the wks posted list */
+ miRemoveStructFromOrdList(pStruct, &(pwks->postedStructs));
+
+ /* do stuff to see if picture needs to be changed */
+ PU_EMPTY_LIST(pwks->pwksList);
+ puAddToList((ddPointer) & pWKS, (ddULONG) 1, pwks->pwksList);
+
+ miDealWithDynamics(UNPOST_STR_DYNAMIC, pwks->pwksList);
+
+ return (Success);
+} /* UnpostStructure */
+
+/*++
+ |
+ | Function Name: UnpostAllStructures
+ |
+ | Function Description:
+ | Handles the PEXUnpostAllStructures request.
+ |
+ | Note(s):
+ don't use UnpostStructure because this follows the list of posted structures
+ and removes each one as it goes, instead of having UnpostStructure remove
+ them.
+ |
+ --*/
+
+ddpex4rtn
+UnpostAllStructures(pWKS)
+/* in */
+ diWKSHandle pWKS; /* workstation handle */
+/* out */
+{
+ miWksPtr pwks = (miWksPtr) pWKS->deviceData;
+ ddOrdStruct *pos, *posn;
+
+#ifdef DDTEST
+ ErrorF("\nUnpostAllStructures\n");
+#endif
+
+ if (!pwks) return (Success);
+
+ /* don't forget that the first pos is a dummy */
+ pos = pwks->postedStructs.postruct;
+ posn = pos->next;
+ pos->next = NULL;
+ while (posn) {
+
+ /*
+ * take the wks out of the posted structs and childrens wks
+ * lists
+ */
+ err4 = UpdateStructRefs(posn->pstruct, (diResourceHandle) pWKS,
+ WORKSTATION_RESOURCE, REMOVE);
+
+ pos = posn;
+ posn = pos->next;
+ xfree(pos);
+ }
+ pwks->postedStructs.numStructs = 0;
+
+ /* do stuff to see if picture needs to be changed */
+ PU_EMPTY_LIST(pwks->pwksList);
+ puAddToList((ddPointer) & pWKS, (ddULONG) 1, pwks->pwksList);
+
+ miDealWithDynamics(UNPOST_STR_DYNAMIC, pwks->pwksList);
+ return (Success);
+} /* UnpostAllStructures */
+
+/*++
+ |
+ | Function Name: InquireWksPostings
+ |
+ | Function Description:
+ | Handles the PEXGetWKSPostings request.
+ |
+ | Note(s):
+ |
+ --*/
+
+extern ddpex4rtn get_wks_postings();
+
+ddpex4rtn
+InquireWksPostings(pStruct, pBuffer)
+/* in */
+ diStructHandle pStruct;/* structure handle */
+/* out */
+ ddBufferPtr pBuffer;/* list of workstation ids */
+{
+
+#ifdef DDTEST
+ ErrorF("\nInquireWksPostings\n");
+#endif
+
+ return (get_wks_postings(pStruct, pBuffer));
+} /* InquireWksPostings */
+
+/*++
+ |
+ | Function Name: UpdateWksRefs
+ |
+ | Function Description:
+ | only for pick measure reference count
+ |
+ | Note(s):
+ |
+ --*/
+
+void
+UpdateWksRefs(pWKS, pResource, which, action)
+ diWKSHandle pWKS;
+ diResourceHandle pResource; /* pick measure resource */
+ ddResourceType which;
+ ddAction action;
+{
+ register miWksPtr pwks = (miWksPtr) pWKS->deviceData;
+
+ /* only pick measure counts are used here */
+ if (action == ADD)
+ pwks->refCount++;
+ else if (pwks->refCount > 0)
+ pwks->refCount--;
+
+ CHECK_DELETE(pwks, pWKS);
+
+ return;
+} /* UpdateWksRefs */
+
+ddpex4rtn
+mi_add_ord_view(plist, view)
+ listofOrdView *plist;
+ ddUSHORT view;
+{
+ ddOrdView *free1, *free2, *indexer;
+
+ indexer = plist->highest->lower;
+ do {
+ if ((indexer->first_view == view) &&
+ (indexer->last_view == view)) {
+ /* view is already in the list */
+ if (!indexer->defined) {
+ plist->defined_views++;
+ indexer->defined = MI_TRUE;
+ }
+ return (Success);
+ }
+ if ((indexer->first_view <= view) &&
+ (indexer->last_view >= view)) {
+ MIWKS_NEW_OV_ENTRY(plist, free1);
+ if (free1 == NULL) {
+ /* bad news, no more free entries */
+ return (BadValue);
+ }
+ plist->defined_views++;
+ free1->defined = MI_TRUE;
+ free1->first_view = view;
+ free1->last_view = view;
+ if (indexer->first_view == view) { /* new entry goes in
+ * front */
+ free1->higher = indexer->higher;
+ free1->lower = indexer;
+ indexer->higher = free1;
+ free1->higher->lower = free1;
+ indexer->first_view++;
+ ASSURE(indexer->first_view <= indexer->last_view);
+ } else if (indexer->last_view == view) { /* new entry goes on
+ * back */
+ free1->higher = indexer;
+ free1->lower = indexer->lower;
+ indexer->lower = free1;
+ free1->lower->higher = free1;
+ indexer->last_view--;
+ ASSURE(indexer->first_view <= indexer->last_view);
+ } else {/* new entry goes in middle - need to split
+ * the range. the end of the range goes into
+ * a new entry. ranges are always not defined
+ * views, so all views in that new entry are
+ * still undefined */
+ MIWKS_NEW_OV_ENTRY(plist, free2);
+ free2->defined = MI_FALSE;
+ free2->first_view = view + 1;
+ free2->last_view =
+ indexer->last_view;
+ indexer->last_view = view - 1;
+ free1->higher = indexer;
+ free1->lower = free2;
+ free2->higher = free1;
+ free2->lower = indexer->lower;
+ indexer->lower = free1;
+ free2->lower->higher = free2;
+ }
+ return (Success);
+ }
+ indexer = indexer->lower;
+ } while (indexer != plist->lowest);
+ /* reached end of list: should never get here */
+ return (BadValue);
+
+}
+
+ddOrdView *
+mi_find_ord_view(plist, view)
+ listofOrdView *plist;
+ ddUSHORT view;
+{
+/* finds only defined views */
+ ddOrdView *indexer;
+
+ indexer = plist->highest;
+ do {
+ if (indexer->defined && (indexer->first_view == view))
+ return (indexer);
+
+ indexer = indexer->lower;
+ } while (indexer != NULL);
+ /* view is not defined */
+ return (NULL);
+}
+
+void
+initialize_pick_devices()
+{
+ register int i;
+
+ for (i = 0; i < MIWKS_NUM_PICK_DEVICES; i++) {
+ pick_devices[i].type = i + 1;
+ pick_devices[i].status = PEXNoPick;
+ /* don't put the path in here - create it for the wks devices */
+ pick_devices[i].path = (listofObj *) NULL;
+ pick_devices[i].pathOrder = PEXTopPart;
+ pick_devices[i].inclusion = (diNSHandle) NULL;
+ pick_devices[i].exclusion = (diNSHandle) NULL;
+
+ if (!i)
+ MIWKS_PD_DATA_REC_1(&pick_devices[i]) = 0;
+ else
+ MIWKS_PD_DATA_REC_2(&pick_devices[i]) = 0;
+
+ pick_devices[i].pet = PEXEchoPrimitive;
+ pick_devices[i].echoVolume = viewportInit;
+ pick_devices[i].echoSwitch = PEXNoEcho;
+ }
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/shared/Imakefile b/xc/programs/Xserver/PEX5/ddpex/mi/shared/Imakefile
new file mode 100644
index 000000000..4bb11c1a7
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/shared/Imakefile
@@ -0,0 +1,99 @@
+XCOMM
+XCOMM $XConsortium: Imakefile /main/12 1996/09/28 16:54:42 rws $
+XCOMM $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/shared/Imakefile,v 3.11 1999/07/04 06:38:31 dawes Exp $
+XCOMM
+XCOMM
+XCOMM Copyright 1989, 1990, 1991 by Sun Microsystems, Inc. and the X Consortium
+XCOMM
+XCOMM All Rights Reserved
+XCOMM
+XCOMM Permission to use, copy, modify, and distribute this software and its
+XCOMM documentation for any purpose and without fee is hereby granted,
+XCOMM provided that the above copyright notice appear in all copies and that
+XCOMM both that copyright notice and this permission notice appear in
+XCOMM supporting documentation, and that the names of Sun Microsystems
+XCOMM or the X Consortium not be used in advertising or publicity
+XCOMM pertaining to distribution of the software without specific, written
+XCOMM prior permission.
+XCOMM
+XCOMM SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+XCOMM INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+XCOMM EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+XCOMM CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+XCOMM USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+XCOMM OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+XCOMM PERFORMANCE OF THIS SOFTWARE.
+
+#define IHaveModules
+#include <Server.tmpl>
+
+#ifndef PexDdpexCDebugFlags
+#define PexDdpexCDebugFlags ServerCDebugFlags
+#endif
+
+XCOMM -D defines for ddpex:
+XCOMM DDTEST turns on some fprintf(stderr...)s for debugging
+XCOMM PEX_DEFAULT_FONTPATH defines the default path to PEX fonts
+
+ DEFINES = PexDdpexDefines
+EXT_DEFINES = ExtensionDefines
+CDEBUGFLAGS = PexDdpexCDebugFlags
+
+ PEXSERVINC = ../../../include
+DDPEXINCLUDE = ../include
+
+INCLUDES = -I. \
+ -I$(DDPEXINCLUDE) \
+ -I$(XINCLUDESRC) \
+ -I$(PEXSERVINC) \
+ -I$(SERVERSRC)/include
+
+SRCS = miFont.c \
+ miLUT.c \
+ miLineLUT.c \
+ miMarkLUT.c \
+ miTextLUT.c \
+ miEdgeLUT.c \
+ miIntLUT.c \
+ miPattLUT.c \
+ miFontLUT.c \
+ miViewLUT.c \
+ miColrLUT.c \
+ miClrApLUT.c \
+ miLightLUT.c \
+ miDCueLUT.c \
+ miNS.c \
+ miUtils.c \
+ miMisc.c
+
+OBJS = miFont.o \
+ miLUT.o \
+ miLineLUT.o \
+ miMarkLUT.o \
+ miTextLUT.o \
+ miEdgeLUT.o \
+ miIntLUT.o \
+ miPattLUT.o \
+ miFontLUT.o \
+ miViewLUT.o \
+ miColrLUT.o \
+ miClrApLUT.o \
+ miLightLUT.o \
+ miDCueLUT.o \
+ miNS.o \
+ miUtils.o \
+ miMisc.o
+
+ModuleObjectRule()
+
+SubdirLibraryRule($(OBJS))
+
+NormalLibraryTarget(ddpexs,$(OBJS))
+
+LintLibraryTarget(dps, $(SRCS))
+NormalLintTarget($(SRCS))
+
+SpecialCObjectRule(miMisc,$(ICONFIGFILES),$(EXT_DEFINES))
+
+DependTarget()
+
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/shared/miClrApLUT.c b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miClrApLUT.c
new file mode 100644
index 000000000..51aea512b
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miClrApLUT.c
@@ -0,0 +1,217 @@
+/* $TOG: miClrApLUT.c /main/3 1998/02/10 12:44:09 kaleb $ */
+/*
+
+Copyright 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/shared/miClrApLUT.c,v 1.7 1998/10/04 09:34:45 dawes Exp $ */
+
+#include "miLUT.h"
+#include "miWks.h"
+#include "miInfo.h"
+#include "PEXErr.h"
+#include "PEXprotost.h"
+#include "pexos.h"
+
+
+/* Level 4 Shared Resources */
+/* Lookup Table Procedures */
+
+/* definitions used by miLUTProcs.ci */
+#define LUT_TYPE PEXColourApproxLUT
+
+/* devPriv data structure */
+#define DD_LUT_ENTRY_STR ddColourApproxEntry
+/* table entry data structure */
+#define MI_LUT_ENTRY_STR miColourApproxEntry
+/* pex data */
+#define PEX_LUT_ENTRY_STR pexColourApproxEntry
+
+#define LUT_REND_DYN_BIT PEXDynColourApproxContents
+
+#define LUT_START_INDEX 0
+#define LUT_DEFAULT_INDEX 0
+#define LUT_0_DEFINABLE_ENTRIES 6
+#define LUT_0_NUM_PREDEFINED 0
+#define LUT_0_PREDEFINED_MIN 0
+#define LUT_0_PREDEFINED_MAX 0
+
+#define LUT_TABLE_START(pheader) (pheader)->plut.colourApprox
+
+#define DYNAMIC COLOUR_APPROX_TABLE_DYNAMIC
+
+/* predefined entries table: change this to work with your devPriv data */
+/* there are no predefined entries, but define 1 entry for default */
+static DD_LUT_ENTRY_STR pdeColourApproxEntry[1];
+#define LUT_PDE_ENTRIES pdeColourApproxEntry[0]
+#define LUT_SET_PDE_ENTRY(pentry, pdeentry) \
+ (pentry)->entry = *(pdeentry)
+
+/* predefined entry 0 is set to the default values
+ * change the XXX_DEFAULT_YYY macros below to use something else
+ * if you don't want the default values defined in the pde table
+ */
+#define PDE_DEFAULT_ENTRY_NUM 0
+#define LUT_DEFAULT_VALUES pdeColourApproxEntry[PDE_DEFAULT_ENTRY_NUM]
+#define LUT_SET_DEFAULT_VALUES(pentry) \
+ (pentry)->entry = LUT_DEFAULT_VALUES
+
+/* which procedure definitions in miLUTProcs.h to use and their names
+ * take out USE flags if you're defining those procs in here
+ * but leave the name definitions
+ */
+
+#define LUT_USE_FREE
+#define LUT_USE_INQ_PREDEF
+#define LUT_USE_INQ_ENTRIES
+#define LUT_USE_COPY
+#define LUT_USE_INQ_INFO
+#define LUT_USE_INQ_IND
+#define LUT_USE_INQ_ENTRY
+#define LUT_USE_SET_ENTRIES
+#define LUT_USE_DEL_ENTRIES
+#define LUT_USE_INQ_ENTRY_ADDRESS
+#define LUT_USE_CREATE
+#define LUT_USE_MOD_CALL_BACK
+
+/* these three are redefined in miLUTProcs.h
+#define LUT_FREE ColourApproxLUT_free
+#define LUT_INQ_PREDEF ColourApproxLUT_inq_predef
+#define LUT_INQ_ENTRIES ColourApproxLUT_inq_entries
+*/
+#define LUT_COPY ColourApproxLUT_copy
+#define LUT_INQ_INFO ColourApproxLUT_inq_info
+#define LUT_INQ_IND ColourApproxLUT_inq_ind
+#define LUT_INQ_ENTRY ColourApproxLUT_inq_entry
+#define LUT_SET_ENTRIES ColourApproxLUT_set_entries
+#define LUT_DEL_ENTRIES ColourApproxLUT_del_entries
+#define LUT_INQ_ENTRY_ADDRESS ColourApproxLUT_inq_entry_address
+#define LUT_CREATE ColourApproxLUT_create
+#define LUT_ENTRY_CHECK ColourApproxLUT_entry_check
+#define LUT_COPY_PEX_MI ColourApproxLUT_copy_pex_to_mi
+#define LUT_COPY_MI_PEX ColourApproxLUT_copy_mi_to_pex
+#define LUT_MOD_CALL_BACK ColourApproxLUT_mod_call_back
+
+/* copy from an mi entry to a pex entry and increment ppbuf */
+ddpex43rtn
+LUT_COPY_MI_PEX( pheader, valueType, pentry, ppbuf )
+ miLUTHeader *pheader;
+ ddUSHORT valueType;
+ MI_LUT_ENTRY_STR *pentry;
+ ddPointer *ppbuf;
+{
+ if (pentry == NULL)
+ mibcopy(&(LUT_DEFAULT_VALUES), *ppbuf, sizeof(PEX_LUT_ENTRY_STR));
+ else if (pentry->entry_info.status == MILUT_UNDEFINED)
+ mibcopy(&(LUT_DEFAULT_VALUES), *ppbuf, sizeof(PEX_LUT_ENTRY_STR));
+ else
+ mibcopy(&pentry->entry, *ppbuf, sizeof(PEX_LUT_ENTRY_STR));
+
+ *ppbuf += sizeof(PEX_LUT_ENTRY_STR);
+
+ return(Success);
+}
+
+/* copy from a pex entry to an mi entry and increment ppsrc */
+ddpex43rtn
+LUT_COPY_PEX_MI( pheader, ppsrc, pentry )
+ miLUTHeader *pheader;
+ ddPointer *ppsrc;
+ MI_LUT_ENTRY_STR *pentry;
+{
+ mibcopy(*ppsrc, &(pentry->entry), sizeof(PEX_LUT_ENTRY_STR));
+ *ppsrc += sizeof(PEX_LUT_ENTRY_STR);
+
+ return(Success);
+}
+
+/* check for bad values and increment ppPexEntry */
+
+ddpex43rtn
+LUT_ENTRY_CHECK (pheader, ppPexEntry)
+ miLUTHeader *pheader;
+ PEX_LUT_ENTRY_STR **ppPexEntry;
+{
+ extern miEnumType miColourApproxTypeET[][SI_CLR_APPROX_TYPE_NUM];
+ extern miEnumType miColourApproxModelET[][SI_CLR_APPROX_MODEL_NUM];
+
+ if (((*ppPexEntry)->approxType < miColourApproxTypeET[pheader->drawType][0].index) ||
+ ((*ppPexEntry)->approxType > miColourApproxTypeET[pheader->drawType][SI_CLR_APPROX_TYPE_NUM - 1].index))
+ return(BadValue);
+ if (((*ppPexEntry)->approxModel < miColourApproxModelET[pheader->drawType][0].index) ||
+ ((*ppPexEntry)->approxModel > miColourApproxModelET[pheader->drawType][SI_CLR_APPROX_MODEL_NUM - 1].index))
+ return(BadValue);
+ if (((*ppPexEntry)->dither != PEXOff) && ((*ppPexEntry)->dither != PEXOn))
+ return(BadValue);
+
+ (*ppPexEntry)++;
+ return(Success);
+}
+
+void
+ColourApproxLUT_init_pde()
+{
+ /* Having default values for this makes absolutely no sense.
+ * There is no way for this to know what colors are defined in
+ * the coloramp, and therefor no way to know how to map to them.
+ * This is provided only because something has to be done, but
+ * the likelyhood of this turning out correct colors is small.
+ * The client side MUST set at least one entry in this table
+ * for correct functionality.
+ * These are the sample values in the protocol spec.
+ * They assume a 6x6x6 color cube beginning at location 16.
+ */
+ pdeColourApproxEntry [0].approxType = PEXColourSpace;
+ pdeColourApproxEntry [0].approxModel = PEXColourApproxRGB;
+ pdeColourApproxEntry [0].max1 = 5;
+ pdeColourApproxEntry [0].max2 = 5;
+ pdeColourApproxEntry [0].max3 = 5;
+ pdeColourApproxEntry [0].dither = PEXOff;
+ pdeColourApproxEntry [0].mult1 = 1;
+ pdeColourApproxEntry [0].mult2 = 6;
+ pdeColourApproxEntry [0].mult3 = 36;
+ pdeColourApproxEntry [0].weight1 = 1.0;
+ pdeColourApproxEntry [0].weight2 = 1.0;
+ pdeColourApproxEntry [0].weight3 = 1.0;
+ pdeColourApproxEntry [0].basePixel = 16;
+}
+
+#include "miLUTProcs.ci"
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/shared/miColrLUT.c b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miColrLUT.c
new file mode 100644
index 000000000..fb8a06ee1
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miColrLUT.c
@@ -0,0 +1,295 @@
+/* $TOG: miColrLUT.c /main/3 1998/02/10 12:44:13 kaleb $ */
+/*
+
+Copyright 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/shared/miColrLUT.c,v 1.7 1998/10/04 09:34:46 dawes Exp $ */
+
+#include "miLUT.h"
+#include "miWks.h"
+#include "miInfo.h"
+#include "PEXErr.h"
+#include "PEXprotost.h"
+#include "pexos.h"
+
+
+/* Level 4 Shared Resources */
+/* Lookup Table Procedures */
+
+extern unsigned colour_type_sizes[]; /* in miLUT.c */
+
+/* definitions used by miLUTProcs.ci */
+#define LUT_TYPE PEXColourLUT
+
+/* devPriv data structure */
+#define DD_LUT_ENTRY_STR ddColourSpecifier
+/* table entry data structure */
+#define MI_LUT_ENTRY_STR miColourEntry
+/* pex data */
+#define PEX_LUT_ENTRY_STR pexColourSpecifier
+
+#define LUT_REND_DYN_BIT PEXDynColourTableContents
+
+#define LUT_START_INDEX 0
+#define LUT_DEFAULT_INDEX 1
+#define LUT_0_DEFINABLE_ENTRIES 256
+#define LUT_0_NUM_PREDEFINED 8
+#define LUT_0_PREDEFINED_MIN 0
+#define LUT_0_PREDEFINED_MAX 7
+
+#define LUT_TABLE_START(pheader) (pheader)->plut.colour
+
+#define DYNAMIC COLOUR_TABLE_DYNAMIC
+
+/* predefined entries table: change this to work with your devPriv data */
+static DD_LUT_ENTRY_STR pdeColourEntry[LUT_0_NUM_PREDEFINED];
+#define LUT_PDE_ENTRIES pdeColourEntry[0]
+#define LUT_SET_PDE_ENTRY(pentry, pdeentry) \
+ (pentry)->entry = *(pdeentry);
+
+/* predefined entry 1 is set to the default values
+ * change the XXX_DEFAULT_YYY macros below to use something else
+ * if you don't want the default values defined in the pde table
+ */
+#define PDE_DEFAULT_ENTRY_NUM 1
+#define LUT_DEFAULT_VALUES pdeColourEntry[PDE_DEFAULT_ENTRY_NUM]
+#define LUT_SET_DEFAULT_VALUES(pentry) \
+ (pentry)->entry = LUT_DEFAULT_VALUES
+
+/* which procedure definitions in miLUTProcs.h to use and their names
+ * take out USE flags if you're defining those procs in here
+ * but leave the name definitions
+ */
+
+#define LUT_USE_FREE
+#define LUT_USE_INQ_PREDEF
+#define LUT_USE_INQ_ENTRIES
+#define LUT_USE_COPY
+#define LUT_USE_INQ_INFO
+#define LUT_USE_INQ_IND
+#define LUT_USE_INQ_ENTRY
+#define LUT_USE_SET_ENTRIES
+#define LUT_USE_DEL_ENTRIES
+#define LUT_USE_INQ_ENTRY_ADDRESS
+#define LUT_USE_CREATE
+#define LUT_USE_MOD_CALL_BACK
+
+/* these three are redefined in miLUTProcs.h
+#define LUT_FREE ColourLUT_free
+#define LUT_INQ_PREDEF ColourLUT_inq_predef
+#define LUT_INQ_ENTRIES ColourLUT_inq_entries
+*/
+#define LUT_COPY ColourLUT_copy
+#define LUT_INQ_INFO ColourLUT_inq_info
+#define LUT_INQ_IND ColourLUT_inq_ind
+#define LUT_INQ_ENTRY ColourLUT_inq_entry
+#define LUT_SET_ENTRIES ColourLUT_set_entries
+#define LUT_DEL_ENTRIES ColourLUT_del_entries
+#define LUT_INQ_ENTRY_ADDRESS ColourLUT_inq_entry_address
+#define LUT_CREATE ColourLUT_create
+#define LUT_ENTRY_CHECK ColourLUT_entry_check
+#define LUT_COPY_PEX_MI ColourLUT_copy_pex_to_mi
+#define LUT_COPY_MI_PEX ColourLUT_copy_mi_to_pex
+#define LUT_MOD_CALL_BACK ColourLUT_mod_call_back
+
+/* copy from an mi entry to a pex entry and increment ppbuf */
+ddpex43rtn
+LUT_COPY_MI_PEX ( pheader, valueType, pentry, ppbuf )
+ miLUTHeader *pheader;
+ ddUSHORT valueType;
+ MI_LUT_ENTRY_STR *pentry;
+ ddPointer *ppbuf;
+{
+ ddPointer pb = *ppbuf;
+ DD_LUT_ENTRY_STR *pdev_entry;
+
+ if (pentry == NULL)
+ pdev_entry = &(LUT_DEFAULT_VALUES);
+ else if (pentry->entry_info.status == MILUT_UNDEFINED)
+ pdev_entry = &(LUT_DEFAULT_VALUES);
+ else
+ pdev_entry = &pentry->entry;
+
+ mibcopy(pdev_entry, pb, sizeof(PEX_LUT_ENTRY_STR));
+
+ pb+= sizeof(PEX_LUT_ENTRY_STR);
+
+ MILUT_COPY_COLOUR(&pdev_entry->colour, pb, pdev_entry->colourType);
+
+ pb += colour_type_sizes[(int)pdev_entry->colourType];
+ *ppbuf = pb;
+ return(Success);
+}
+
+/* copy from a pex entry to an mi entry and increment ppsrc */
+ddpex43rtn
+LUT_COPY_PEX_MI ( pheader, ppsrc, pentry )
+ miLUTHeader *pheader;
+ ddPointer *ppsrc;
+ MI_LUT_ENTRY_STR *pentry;
+{
+ ddPointer ps = *ppsrc;
+
+ pentry->entry.colourType = ((PEX_LUT_ENTRY_STR *)ps)->colourType;
+ ps+= sizeof(PEX_LUT_ENTRY_STR);
+
+ MILUT_COPY_COLOUR(ps, &(pentry->entry.colour), pentry->entry.colourType);
+
+ ps += colour_type_sizes[(int)pentry->entry.colourType];
+ *ppsrc = ps;
+ return(Success);
+}
+
+/* check for bad values and increment ppPexEntry */
+
+ddpex43rtn
+LUT_ENTRY_CHECK (pheader, ppPexEntry)
+ miLUTHeader *pheader;
+ PEX_LUT_ENTRY_STR **ppPexEntry;
+{
+ ddPointer pe = (ddPointer)*ppPexEntry;
+
+ /* colours: only accept supported colour types */
+ if (MI_BADCOLOURTYPE((*ppPexEntry)->colourType))
+ return(PEXERR(PEXColourTypeError));
+
+ pe += sizeof(PEX_LUT_ENTRY_STR) +
+ colour_type_sizes[(int)(*ppPexEntry)->colourType];
+ *ppPexEntry = (PEX_LUT_ENTRY_STR *)pe;
+ return(Success);
+}
+
+
+void
+ColourLUT_init_pde()
+{
+ /* black */
+ pdeColourEntry[0].colourType = PEXRgbFloatColour;
+ pdeColourEntry[0].colour.rgbFloat.red = 0.0;
+ pdeColourEntry[0].colour.rgbFloat.green = 0.0;
+ pdeColourEntry[0].colour.rgbFloat.blue = 0.0;
+ /* white */
+ pdeColourEntry[1].colourType = PEXRgbFloatColour;
+ pdeColourEntry[1].colour.rgbFloat.red = 1.0;
+ pdeColourEntry[1].colour.rgbFloat.green = 1.0;
+ pdeColourEntry[1].colour.rgbFloat.blue = 1.0;
+ /* red */
+ pdeColourEntry[2].colourType = PEXRgbFloatColour;
+ pdeColourEntry[2].colour.rgbFloat.red = 1.0;
+ pdeColourEntry[2].colour.rgbFloat.green = 0.0;
+ pdeColourEntry[2].colour.rgbFloat.blue = 0.0;
+ /* green */
+ pdeColourEntry[3].colourType = PEXRgbFloatColour;
+ pdeColourEntry[3].colour.rgbFloat.red = 0.0;
+ pdeColourEntry[3].colour.rgbFloat.green = 1.0;
+ pdeColourEntry[3].colour.rgbFloat.blue = 0.0;
+ /* blue */
+ pdeColourEntry[4].colourType = PEXRgbFloatColour;
+ pdeColourEntry[4].colour.rgbFloat.red = 0.0;
+ pdeColourEntry[4].colour.rgbFloat.green = 0.0;
+ pdeColourEntry[4].colour.rgbFloat.blue = 1.0;
+ /* yellow */
+ pdeColourEntry[5].colourType = PEXRgbFloatColour;
+ pdeColourEntry[5].colour.rgbFloat.red = 1.0;
+ pdeColourEntry[5].colour.rgbFloat.green = 1.0;
+ pdeColourEntry[5].colour.rgbFloat.blue = 0.0;
+ /* cyan */
+ pdeColourEntry[6].colourType = PEXRgbFloatColour;
+ pdeColourEntry[6].colour.rgbFloat.red = 0.0;
+ pdeColourEntry[6].colour.rgbFloat.green = 1.0;
+ pdeColourEntry[6].colour.rgbFloat.blue = 1.0;
+ /* magenta */
+ pdeColourEntry[7].colourType = PEXRgbFloatColour;
+ pdeColourEntry[7].colour.rgbFloat.red = 1.0;
+ pdeColourEntry[7].colour.rgbFloat.green = 0.0;
+ pdeColourEntry[7].colour.rgbFloat.blue = 1.0;
+}
+
+#include "miLUTProcs.ci"
+
+/* utility proc used to get highlight colour
+ * the highlight colour is the last entry in
+ * the table, i.e. the one with the highest index
+ */
+void
+inq_last_colour_entry( pLUT, pColour )
+ diLUTHandle pLUT;
+ ddColourSpecifier *pColour;
+{
+ miLUTHeader *pheader;
+ ddTableIndex high_index = 0;
+ ddColourSpecifier *high_entry = (ddColourSpecifier *)NULL;
+ miColourEntry *pEntry;
+ register int i;
+
+ if (pLUT)
+ {
+ pheader = MILUT_HEADER(pLUT);
+ /* since this supports sparse tables,
+ * we don't know which entry is the last one.
+ * so, we have to do a search. a linear search
+ * is done. this should be optimized if the table
+ * is very large.
+ */
+ for (i = 0, pEntry = pheader->plut.colour;
+ i < MILUT_ALLOC_ENTS(pheader); i++, pEntry++)
+ {
+ if (pEntry->entry_info.status != MILUT_UNDEFINED)
+ if (pEntry->entry_info.index > high_index)
+ {
+ high_index = pEntry->entry_info.index;
+ high_entry = &pEntry->entry;
+ }
+ }
+ }
+ if (high_entry)
+ *pColour = *high_entry;
+ else
+ {
+ /* hot pink */
+ pColour->colourType = PEXRgbFloatColour;
+ pColour->colour.rgbFloat.red = 1.0;
+ pColour->colour.rgbFloat.green = 0.41;
+ pColour->colour.rgbFloat.blue = 0.71;
+ }
+ return;
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/shared/miDCueLUT.c b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miDCueLUT.c
new file mode 100644
index 000000000..4f9a00e81
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miDCueLUT.c
@@ -0,0 +1,232 @@
+/* $TOG: miDCueLUT.c /main/3 1998/02/10 12:44:18 kaleb $ */
+/*
+
+Copyright 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/shared/miDCueLUT.c,v 1.7 1998/10/04 09:34:46 dawes Exp $ */
+
+#include "miLUT.h"
+#include "miWks.h"
+#include "miInfo.h"
+#include "PEXErr.h"
+#include "PEXprotost.h"
+#include "pexos.h"
+
+
+/* Level 4 Shared Resources */
+/* Lookup Table Procedures */
+
+extern unsigned colour_type_sizes[]; /* in miLUT.c */
+
+/* definitions used by miLUTProcs.ci */
+#define LUT_TYPE PEXDepthCueLUT
+
+/* devPriv data structure */
+#define DD_LUT_ENTRY_STR ddDepthCueEntry
+/* table entry data structure */
+#define MI_LUT_ENTRY_STR miDepthCueEntry
+/* pex data */
+#define PEX_LUT_ENTRY_STR pexDepthCueEntry
+
+#define LUT_REND_DYN_BIT PEXDynDepthCueTableContents
+
+#define LUT_START_INDEX 0
+#define LUT_DEFAULT_INDEX 0
+#define LUT_0_DEFINABLE_ENTRIES 6
+#define LUT_0_NUM_PREDEFINED 1
+#define LUT_0_PREDEFINED_MIN 0
+#define LUT_0_PREDEFINED_MAX 0
+
+#define LUT_TABLE_START(pheader) (pheader)->plut.depthCue
+
+#define DYNAMIC DEPTH_CUE_DYNAMIC
+
+/* predefined entries table: change this to work with your devPriv data */
+static DD_LUT_ENTRY_STR pdeDepthCueEntry[LUT_0_NUM_PREDEFINED];
+#define LUT_PDE_ENTRIES pdeDepthCueEntry[0]
+#define LUT_SET_PDE_ENTRY(pentry, pdeentry) \
+ (pentry)->entry = *(pdeentry)
+
+/* predefined entry 0 is set to the default values
+ * change the XXX_DEFAULT_YYY macros below to use something else
+ * if you don't want the default values defined in the pde table
+ */
+#define PDE_DEFAULT_ENTRY_NUM 0
+#define LUT_DEFAULT_VALUES pdeDepthCueEntry[PDE_DEFAULT_ENTRY_NUM]
+#define LUT_SET_DEFAULT_VALUES(pentry) \
+ (pentry)->entry = LUT_DEFAULT_VALUES
+
+/* which procedure definitions in miLUTProcs.h to use and their names
+ * take out USE flags if you're defining those procs in here
+ * but leave the name definitions
+ */
+
+#define LUT_USE_FREE
+#define LUT_USE_INQ_PREDEF
+#define LUT_USE_INQ_ENTRIES
+#define LUT_USE_COPY
+#define LUT_USE_INQ_INFO
+#define LUT_USE_INQ_IND
+#define LUT_USE_INQ_ENTRY
+#define LUT_USE_SET_ENTRIES
+#define LUT_USE_DEL_ENTRIES
+#define LUT_USE_INQ_ENTRY_ADDRESS
+#define LUT_USE_CREATE
+#define LUT_USE_MOD_CALL_BACK
+
+/* these three are redefined in miLUTProcs.h
+#define LUT_FREE DepthCueLUT_free
+#define LUT_INQ_PREDEF DepthCueLUT_inq_predef
+#define LUT_INQ_ENTRIES DepthCueLUT_inq_entries
+*/
+#define LUT_COPY DepthCueLUT_copy
+#define LUT_INQ_INFO DepthCueLUT_inq_info
+#define LUT_INQ_IND DepthCueLUT_inq_ind
+#define LUT_INQ_ENTRY DepthCueLUT_inq_entry
+#define LUT_SET_ENTRIES DepthCueLUT_set_entries
+#define LUT_DEL_ENTRIES DepthCueLUT_del_entries
+#define LUT_INQ_ENTRY_ADDRESS DepthCueLUT_inq_entry_address
+#define LUT_CREATE DepthCueLUT_create
+#define LUT_ENTRY_CHECK DepthCueLUT_entry_check
+#define LUT_COPY_PEX_MI DepthCueLUT_copy_pex_to_mi
+#define LUT_COPY_MI_PEX DepthCueLUT_copy_mi_to_pex
+#define LUT_MOD_CALL_BACK DepthCueLUT_mod_call_back
+
+/* copy from an mi entry to a pex entry and increment ppbuf */
+ddpex43rtn
+LUT_COPY_MI_PEX ( pheader, valueType, pentry, ppbuf )
+ miLUTHeader *pheader;
+ ddUSHORT valueType;
+ MI_LUT_ENTRY_STR *pentry;
+ ddPointer *ppbuf;
+{
+ DD_LUT_ENTRY_STR *pdev_entry;
+ ddPointer pb = *ppbuf;
+
+ if (pentry == NULL)
+ pdev_entry = &(LUT_DEFAULT_VALUES);
+ else if (pentry->entry_info.status == MILUT_UNDEFINED)
+ pdev_entry = &(LUT_DEFAULT_VALUES);
+ else
+ pdev_entry = &pentry->entry;
+
+ mibcopy(pdev_entry, pb, sizeof(PEX_LUT_ENTRY_STR));
+
+ pb+= sizeof(PEX_LUT_ENTRY_STR);
+
+ MILUT_COPY_COLOUR(&pdev_entry->depthCueColour.colour,
+ pb, pdev_entry->depthCueColour.colourType);
+
+ pb += colour_type_sizes[(int)pdev_entry->depthCueColour.colourType];
+ *ppbuf = pb;
+ return(Success);
+}
+
+/* copy from a pex entry to an mi entry and increment ppsrc */
+ddpex43rtn
+LUT_COPY_PEX_MI ( pheader, ppsrc, pentry )
+ miLUTHeader *pheader;
+ ddPointer *ppsrc;
+ MI_LUT_ENTRY_STR *pentry;
+{
+ ddPointer ps = *ppsrc;
+
+ mibcopy(ps, &(pentry->entry), sizeof(PEX_LUT_ENTRY_STR));
+
+ ps+= sizeof(PEX_LUT_ENTRY_STR);
+
+ MILUT_COPY_COLOUR(ps, &(pentry->entry.depthCueColour.colour),
+ pentry->entry.depthCueColour.colourType);
+
+ ps += colour_type_sizes[(int)pentry->entry.depthCueColour.colourType];
+ *ppsrc = ps;
+ return(Success);
+}
+
+/* check for bad values and increment ppPexEntry */
+
+ddpex43rtn
+LUT_ENTRY_CHECK (pheader, ppPexEntry)
+ miLUTHeader *pheader;
+ PEX_LUT_ENTRY_STR **ppPexEntry;
+{
+ ddPointer pe = (ddPointer)*ppPexEntry;
+
+ /* mode: Off or On */
+ if (((*ppPexEntry)->mode != PEXOff) && ((*ppPexEntry)->mode != PEXOn))
+ return(BadValue);
+ /* frontPlane: must be in NPC */
+ if (((*ppPexEntry)->frontPlane < 0.0) || ((*ppPexEntry)->frontPlane > 1.0))
+ return(BadValue);
+ /* backPlane: must be in NPC */
+ if (((*ppPexEntry)->backPlane < 0.0) || ((*ppPexEntry)->backPlane > 1.0))
+ return(BadValue);
+ /* frontScaling: must be in NPC */
+ if (((*ppPexEntry)->frontScaling < 0.0) || ((*ppPexEntry)->frontScaling > 1.0))
+ return(BadValue);
+ /* backScaling: must be in NPC */
+ if (((*ppPexEntry)->backScaling < 0.0) || ((*ppPexEntry)->backScaling > 1.0))
+ return(BadValue);
+ /* colours: only accept supported colour types */
+ if (MI_BADCOLOURTYPE((*ppPexEntry)->depthCueColour.colourType))
+ return(PEXERR(PEXColourTypeError));
+
+ pe += sizeof(PEX_LUT_ENTRY_STR) +
+ colour_type_sizes[(int)(*ppPexEntry)->depthCueColour.colourType];
+
+ *ppPexEntry = (PEX_LUT_ENTRY_STR *)pe;
+ return(Success);
+}
+
+
+void
+DepthCueLUT_init_pde()
+{
+ pdeDepthCueEntry[0].mode = PEXOff;
+ pdeDepthCueEntry[0].frontPlane = 1.0;
+ pdeDepthCueEntry[0].backPlane = 0.0;
+ pdeDepthCueEntry[0].frontScaling = 1.0;
+ pdeDepthCueEntry[0].backScaling = 0.5;
+ MILUT_INIT_COLOUR(pdeDepthCueEntry[0].depthCueColour);
+}
+
+#include "miLUTProcs.ci"
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/shared/miEdgeLUT.c b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miEdgeLUT.c
new file mode 100644
index 000000000..d3163a41c
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miEdgeLUT.c
@@ -0,0 +1,263 @@
+/* $TOG: miEdgeLUT.c /main/3 1998/02/10 12:44:22 kaleb $ */
+/*
+
+Copyright 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/shared/miEdgeLUT.c,v 1.7 1998/10/04 09:34:47 dawes Exp $ */
+
+#include "miLUT.h"
+#include "miWks.h"
+#include "miInfo.h"
+#include "PEXErr.h"
+#include "PEXprotost.h"
+#include "pexos.h"
+
+
+/* Level 4 Shared Resources */
+/* Lookup Table Procedures */
+
+extern unsigned colour_type_sizes[]; /* in miLUT.c */
+
+/* definitions used by miLUTProcs.ci */
+#define LUT_TYPE PEXEdgeBundleLUT
+
+/* devPriv data structure */
+#define DD_LUT_ENTRY_STR ddEdgeBundleEntry
+/* table entry data structure */
+#define MI_LUT_ENTRY_STR miEdgeBundleEntry
+/* pex data */
+#define PEX_LUT_ENTRY_STR pexEdgeBundleEntry
+
+#define LUT_REND_DYN_BIT PEXDynEdgeBundleContents
+
+#define LUT_START_INDEX 1
+#define LUT_DEFAULT_INDEX 1
+#define LUT_0_DEFINABLE_ENTRIES 20
+#define LUT_0_NUM_PREDEFINED 1
+#define LUT_0_PREDEFINED_MIN 1
+#define LUT_0_PREDEFINED_MAX 1
+
+#define LUT_TABLE_START(pheader) (pheader)->plut.edge
+
+#define DYNAMIC EDGE_BUNDLE_DYNAMIC
+
+/* predefined entries table: change this to work with your devPriv data
+ * change the XXX_DEFAULT_YYY macros below to use something else
+ * if you don't want the default values defined in the pde table
+ */
+static DD_LUT_ENTRY_STR pdeEdgeBundleEntry[LUT_0_NUM_PREDEFINED];
+#define LUT_PDE_ENTRIES pdeEdgeBundleEntry[0]
+#define LUT_SET_PDE_ENTRY(pentry, pdeentry) \
+ (pentry)->entry = *(pdeentry); \
+ (pentry)->real_entry = *(pdeentry)
+
+
+/* predefined entry 0 is set to the default values */
+#define PDE_DEFAULT_ENTRY_NUM 0
+#define LUT_DEFAULT_VALUES pdeEdgeBundleEntry[PDE_DEFAULT_ENTRY_NUM]
+#define LUT_SET_DEFAULT_VALUES(pentry) \
+ (pentry)->entry = LUT_DEFAULT_VALUES; \
+ (pentry)->real_entry = LUT_DEFAULT_VALUES
+
+/* which procedure definitions in miLUTProcs.h to use and their names
+ * take out USE flags if you're defining those procs in here
+ * but leave the name definitions
+ */
+
+#define LUT_USE_FREE
+#define LUT_USE_INQ_PREDEF
+#define LUT_USE_INQ_ENTRIES
+#define LUT_USE_COPY
+#define LUT_USE_INQ_INFO
+#define LUT_USE_INQ_IND
+#define LUT_USE_INQ_ENTRY
+#define LUT_USE_SET_ENTRIES
+#define LUT_USE_DEL_ENTRIES
+#define LUT_USE_INQ_ENTRY_ADDRESS
+#define LUT_USE_CREATE
+#define LUT_USE_MOD_CALL_BACK
+
+/* these three are redefined in miLUTProcs.h
+#define LUT_FREE EdgeBundleLUT_free
+#define LUT_INQ_PREDEF EdgeBundleLUT_inq_predef
+#define LUT_INQ_ENTRIES EdgeBundleLUT_inq_entries
+*/
+#define LUT_COPY EdgeBundleLUT_copy
+#define LUT_INQ_INFO EdgeBundleLUT_inq_info
+#define LUT_INQ_IND EdgeBundleLUT_inq_ind
+#define LUT_INQ_ENTRY EdgeBundleLUT_inq_entry
+#define LUT_SET_ENTRIES EdgeBundleLUT_set_entries
+#define LUT_DEL_ENTRIES EdgeBundleLUT_del_entries
+#define LUT_INQ_ENTRY_ADDRESS EdgeBundleLUT_inq_entry_address
+#define LUT_CREATE EdgeBundleLUT_create
+#define LUT_ENTRY_CHECK EdgeBundleLUT_entry_check
+#define LUT_COPY_PEX_MI EdgeBundleLUT_copy_pex_to_mi
+#define LUT_COPY_MI_PEX EdgeBundleLUT_copy_mi_to_pex
+#define LUT_MOD_CALL_BACK EdgeBundleLUT_mod_call_back
+#define LUT_REALIZE_ENTRY EdgeBundleLUT_realize_entry
+
+/* copy from an mi entry to a pex entry and increment ppbuf */
+ddpex43rtn
+LUT_COPY_MI_PEX ( pheader, valueType, pentry, ppbuf )
+ miLUTHeader *pheader;
+ ddUSHORT valueType;
+ MI_LUT_ENTRY_STR *pentry;
+ ddPointer *ppbuf;
+{
+ ddPointer pb = *ppbuf;
+ DD_LUT_ENTRY_STR *pdev_entry;
+
+ if (pentry == NULL)
+ pdev_entry = &(LUT_DEFAULT_VALUES);
+ else if (pentry->entry_info.status == MILUT_UNDEFINED)
+ pdev_entry = &(LUT_DEFAULT_VALUES);
+ else
+ if (valueType == PEXRealizedValue)
+ pdev_entry = &pentry->real_entry;
+ else
+ pdev_entry = &pentry->entry;
+
+ mibcopy(pdev_entry, pb, sizeof(PEX_LUT_ENTRY_STR));
+
+ pb+= sizeof(PEX_LUT_ENTRY_STR);
+
+ MILUT_COPY_COLOUR(&pdev_entry->edgeColour.colour,
+ pb, pdev_entry->edgeColour.colourType);
+
+ pb += colour_type_sizes[(int)pdev_entry->edgeColour.colourType];
+ *ppbuf = pb;
+ return(Success);
+}
+
+/* copy from a pex entry to an mi entry and increment ppsrc */
+ddpex43rtn
+LUT_COPY_PEX_MI ( pheader, ppsrc, pentry )
+ miLUTHeader *pheader;
+ ddPointer *ppsrc;
+ MI_LUT_ENTRY_STR *pentry;
+{
+ ddPointer ps = *ppsrc;
+
+ mibcopy(ps, &(pentry->entry), sizeof(PEX_LUT_ENTRY_STR));
+
+ ps+= sizeof(PEX_LUT_ENTRY_STR);
+
+ MILUT_COPY_COLOUR(ps, &(pentry->entry.edgeColour.colour),
+ pentry->entry.edgeColour.colourType);
+
+ LUT_REALIZE_ENTRY( pheader, pentry );
+
+ ps += colour_type_sizes[(int)pentry->entry.edgeColour.colourType];
+ *ppsrc = ps;
+ return(Success);
+}
+
+/* check for bad values and increment ppPexEntry */
+
+ddpex43rtn
+LUT_ENTRY_CHECK (pheader, ppPexEntry)
+ miLUTHeader *pheader;
+ PEX_LUT_ENTRY_STR **ppPexEntry;
+{
+ ddPointer pe = (ddPointer)*ppPexEntry;
+
+ /* edges: PEXOff or PEXOn */
+ if (((*ppPexEntry)->edges != PEXOff) && ((*ppPexEntry)->edges != PEXOn))
+ return(BadValue);
+
+ /* edgeType: any value OK. use edge type 1 if it's not supported */
+ /* edgeWidth: any value is OK, it is used as a scale */
+
+ /* colours only accept supported colour types */
+ if (MI_BADCOLOURTYPE((*ppPexEntry)->edgeColour.colourType))
+ return(PEXERR(PEXColourTypeError));
+
+ pe += sizeof(PEX_LUT_ENTRY_STR) +
+ colour_type_sizes[(int)(*ppPexEntry)->edgeColour.colourType];
+ *ppPexEntry = (PEX_LUT_ENTRY_STR *)pe;
+ return(Success);
+}
+
+/* realize entry */
+ddpex43rtn
+LUT_REALIZE_ENTRY( pheader, pEntry )
+ miLUTHeader *pheader;
+ MI_LUT_ENTRY_STR *pEntry;
+{
+ extern miEnumType miSurfaceEdgeTypeET[][SI_EDGE_NUM];
+
+ /* edges: PEXOff or PEXOn */
+ pEntry->real_entry.edges = pEntry->entry.edges;
+
+ /* edgeType: any value OK. use edge type 1 if it's not supported */
+ if ( (pEntry->entry.edgeType <
+ miSurfaceEdgeTypeET[pheader->drawType][0].index) ||
+ (pEntry->entry.edgeType >
+ miSurfaceEdgeTypeET[pheader->drawType][SI_EDGE_NUM - 1].index) )
+ pEntry->real_entry.edgeType = 1;
+ else
+ pEntry->real_entry.edgeType = pEntry->entry.edgeType;
+
+ /* edgeWidth: any value is OK, it is multiplied by the nomimal
+ * edge width and the nearest supported size is used
+ * The realized value is the scale for inquiry, not the size
+ */
+ pEntry->real_entry.edgeWidth = pEntry->entry.edgeWidth;
+
+ /* colourType: its an error if an unsupported colour type was
+ * specified. For supported colour types, should mapped colour
+ * be returned??
+ */
+ pEntry->real_entry.edgeColour = pEntry->entry.edgeColour;
+
+}
+
+void
+EdgeBundleLUT_init_pde()
+{
+ pdeEdgeBundleEntry[0].edges = PEXOff;
+ pdeEdgeBundleEntry[0].edgeType = PEXSurfaceEdgeSolid;
+ pdeEdgeBundleEntry[0].edgeWidth = 1.0;
+ MILUT_INIT_COLOUR(pdeEdgeBundleEntry[0].edgeColour);
+}
+
+#include "miLUTProcs.ci"
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/shared/miFont.c b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miFont.c
new file mode 100644
index 000000000..b24eab108
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miFont.c
@@ -0,0 +1,888 @@
+/* $TOG: miFont.c /main/8 1998/02/10 12:44:26 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/shared/miFont.c,v 3.5 1998/10/04 09:34:47 dawes Exp $ */
+
+#include "miFont.h"
+#include "miLUT.h"
+#include "miWks.h"
+#include "PEX.h"
+#include "PEXErr.h"
+#include "pexExtract.h"
+#include "pexUtils.h"
+#include "pexos.h"
+
+
+extern void CopyISOLatin1Lowered();
+extern ErrorCode LoadPEXFontFile();
+extern int pex_get_matching_names();
+
+extern diFontHandle defaultPEXFont;
+
+/* Level 4/3 Shared Resources */
+/* PEX Font Procedures */
+
+/* get_lowered_truncated_entry takes a directory entry, strips off the .phont
+ * suffix, and puts in all in lower case ISO Latin 1. If the entry doesn't
+ * have a .phont suffix, 0 is returned.
+ */
+int
+get_lowered_truncated_entry(before, after)
+char *before; /* in */
+char *after; /* out */
+{
+ char *suffix_ptr;
+
+ suffix_ptr = before + strlen(before) - strlen(".phont");
+ if (strncmp(suffix_ptr, ".phont", strlen(".phont")) != 0)
+ return 0;
+
+ CopyISOLatin1Lowered((unsigned char *)after, (unsigned char *)before,
+ strlen(before) - strlen(".phont"));
+
+ return 1;
+}
+
+/*++
+ |
+ | Function Name: OpenPEXFont
+ |
+ | Function Description:
+ | Handles the PEXOpenFont request.
+ |
+ --*/
+ddpex43rtn
+OpenPEXFont(strLen, pName, pFont)
+/* in */
+ ddULONG strLen; /* length of name */
+ ddUCHAR *pName; /* font name */
+ diFontHandle pFont; /* font handle - we fill in device_data */
+/* out */
+{
+ miFontHeader *font;
+ register int i;
+ Ch_stroke_data **ch_data;
+ ddpex43rtn err = Success;
+
+ font = (miFontHeader *)xalloc((unsigned long)(sizeof(miFontHeader)));
+ if (font == NULL) return (BadAlloc);
+ pFont->deviceData = (ddPointer)font;
+ font->lutRefCount = 0;
+ font->freeFlag = MI_FALSE;
+ font->properties = 0;
+ font->font_info.numProps = 0;
+ font->ch_data = 0;
+ font->num_ch = 0;
+ font->top = 0.0;
+ font->bottom = 0.0;
+ font->max_width = 0.0;
+
+ err = LoadPEXFontFile(strLen, pName, pFont);
+ if (err != Success) {
+ xfree(font);
+ return (err); }
+
+ /*
+ * Now, make a pass from the first glyph to the last glyph, seeing if
+ * all are defined.
+ */
+ font->font_info.allExist = 1;
+ ch_data = font->ch_data + font->font_info.firstGlyph;
+ for ( i = font->font_info.firstGlyph;
+ i < font->num_ch && font->font_info.allExist;
+ i++, ch_data++ )
+ if (*ch_data == NULL || (*ch_data)->strokes.numLists <= 0) {
+ font->font_info.allExist = 0;
+ break; }
+
+
+ /* For now, let the default glyph be an asterisk */
+ font->font_info.defaultGlyph = (CARD16)'*';
+
+ /* It's a stroke font */
+ font->font_info.strokeFont = 1;
+
+ return (Success);
+
+} /* OpenPEXFont */
+
+/*++
+ |
+ | Function Name: FreePEXFont
+ |
+ | Function Description:
+ | Deletes all storage used by the font.
+ |
+ --*/
+static void
+really_free_font(pFont)
+ diFontHandle pFont; /* font handle */
+{
+ miFontHeader *font = (miFontHeader *) pFont->deviceData;
+ register Ch_stroke_data **ch_data, *firstChar = 0;
+ int j;
+
+ if (font->properties)
+ xfree((char *) font->properties);
+
+ if (font->ch_data) {
+ for (j = 0, ch_data = font->ch_data; j < font->num_ch; j++, ch_data++) {
+ if (*ch_data != NULL) {
+ MI_FREELISTHEADER(&((*ch_data)->strokes));
+ if (!firstChar) firstChar = *ch_data; } }
+
+ xfree((char *) (firstChar));
+ xfree((char *) (font->ch_data));
+ }
+
+ xfree((char *) font);
+ xfree((char *) pFont);
+
+}
+
+
+ddpex43rtn
+FreePEXFont(pFont, Fid)
+/* in */
+ diFontHandle pFont; /* font handle */
+ ddResourceId Fid; /* font resource id */
+/* out */
+{
+ miFontHeader *font = (miFontHeader *) pFont->deviceData;
+
+ if (pFont == defaultPEXFont) return (Success);
+
+ font->freeFlag = MI_TRUE;
+ pFont->id = PEXAlreadyFreed;
+
+ if (font->lutRefCount == 0)
+ really_free_font(pFont);
+
+ return (Success);
+}
+
+/*++
+ |
+ | Function Name: QueryPEXFont
+ |
+ | Function Description:
+ | Handles the PEXQueryFont request.
+ |
+ | Input Description:
+ | diFontHandle pFont; font handle
+ |
+ | Output Description:
+ | ddBufferPtr pBuffer; buffer with fontinfo
+ |
+ --*/
+ddpex43rtn
+QueryPEXFont(pFont, pBuffer)
+ diFontHandle pFont; /* font handle */
+ ddBufferPtr pBuffer; /* font info */
+{
+ miFontHeader *font = (miFontHeader *)pFont->deviceData;
+ ddPointer pbuf;
+ ddULONG data_size;
+
+ data_size = sizeof(pexFontInfo) +
+ font->font_info.numProps * sizeof(pexFontProp);
+
+ PU_CHECK_BUFFER_SIZE(pBuffer, data_size);
+ pbuf = pBuffer->pBuf;
+
+ /* copy actual font info into buffer */
+ memcpy( (char *)pbuf, (char *)&(font->font_info), sizeof(pexFontInfo));
+ pbuf += sizeof(pexFontInfo);
+
+ /* copy property info into buffer */
+ if (font->font_info.numProps > 0)
+ PACK_LISTOF_STRUCT( font->font_info.numProps, pexFontProp,
+ font->properties, pbuf);
+
+ pBuffer->dataSize = data_size;
+
+ return (Success);
+
+} /* QueryPEXFont */
+
+/*++
+ |
+ | Function Name: ListPEXFonts
+ |
+ | Function Description:
+ | Handles the PEXListFonts request.
+ |
+ --*/
+ddpex43rtn
+ListPEXFonts(patLen, pPattern, maxNames, pNumNames, pBuffer)
+/* in */
+ ddUSHORT patLen; /* number of chars in pattern */
+ ddUCHAR *pPattern; /* pattern */
+ ddUSHORT maxNames; /* maximum number of names to return */
+/* out */
+ ddULONG *pNumNames;/* number of names in reply */
+ ddBufferPtr pBuffer; /* list of names */
+{
+
+ ddPointer pbuf;
+ ddULONG total_space, n;
+ char **names; /* a list of strings */
+ CARD16 *valCARD16;
+ int i;
+
+ if (!pex_get_matching_names(patLen, pPattern, maxNames, &n, &names))
+ return (BadAlloc);
+
+ /* figure out how much space is needed by these strings */
+ total_space = 0;
+ for (i = 0; i < n; i++) {
+ total_space += 2 + strlen(names[i]) + PADDING(2 + strlen(names[i]));
+ }
+
+ PU_CHECK_BUFFER_SIZE(pBuffer, total_space);
+
+ pbuf = pBuffer->pBuf;
+ for (i = 0; i < n; i++) {
+ valCARD16 = (CARD16 *)pbuf;
+ *valCARD16 = strlen(names[i]);
+ pbuf += sizeof(CARD16);
+ memcpy( (char *)pbuf, names[i], (int)(strlen(names[i])));
+ pbuf += strlen(names[i]) + PADDING(2 + strlen(names[i]));
+ xfree(names[i]);
+ }
+ xfree(names);
+
+ *pNumNames = n;
+ pBuffer->dataSize = total_space;
+ return (Success);
+}
+
+/*++
+ |
+ | Function Name: ListPEXFontsPlus
+ |
+ | Function Description:
+ | Handles the PEXListFontsWithInfo request.
+ |
+ --*/
+
+/* we don't ever expect to have more than this number of properties per font
+ but let's not create any bugs we don't have to, so this is just a
+ guestimate, not an enforced maximum
+*/
+#define EST_MAX_FONT_PROPS 10
+
+ddpex43rtn
+ListPEXFontsPlus(patLen, pPattern, maxNames, pNumNames, pBuffer)
+/* in */
+ ddUSHORT patLen; /* number of chars in pattern */
+ ddUCHAR *pPattern; /* pattern */
+ ddUSHORT maxNames; /* maximum number of names to return */
+/* out */
+ ddULONG *pNumNames;/* number of names in reply */
+ ddBufferPtr pBuffer; /* font names and info */
+{
+
+ ddPointer pBuf;
+ ddULONG guess_size = 0, n;
+ char **names; /* a list of strings */
+ int i, j, len;
+ ddpex43rtn err = Success;
+ ddFontResource ddFont;
+ miFontHeader fontData;
+ Ch_stroke_data **ch_data;
+
+ /* lookup names */
+ if (!pex_get_matching_names(patLen, pPattern, maxNames, &n, &names))
+ return (BadAlloc);
+
+ /* guess at a large number of bytes for the reply, and make sure
+ we have this many (can always realloc later) */
+ for (i=0; i<n; i++)
+ guess_size += (strlen(names[i]) + 4);
+ guess_size += (sizeof(CARD32) + (n * sizeof(pexFontInfo)));
+ guess_size += (n * EST_MAX_FONT_PROPS * sizeof(pexFontProp));
+ if (PU_BUF_TOO_SMALL(pBuffer, guess_size))
+ if (puBuffRealloc(pBuffer, guess_size) != Success) goto free_names;
+
+ /* write names into reply buffer */
+ pBuf = pBuffer->pBuf;
+ pBuffer->dataSize = 0;
+ for (i = 0; i < n; i++) {
+ len = strlen(names[i]);
+ PACK_CARD16(len, pBuf);
+ PACK_LISTOF_STRUCT(len, CARD8, names[i], pBuf);
+ SKIP_PADDING(pBuf, PADDING(sizeof(CARD16) + len));
+ pBuffer->dataSize += sizeof(CARD16) + len +
+ PADDING(sizeof(CARD16) + len);
+ }
+
+
+ /* read in the font info, write it into the reply buffer */
+ ddFont.deviceData = (ddPointer)&(fontData);
+ fontData.properties = 0;
+ PACK_CARD32(n, pBuf);
+ pBuffer->dataSize += sizeof(CARD32);
+ for (i = 0; i < n; i++) {
+
+ err = LoadPEXFontFile( (ddULONG)(strlen(names[i])),
+ (ddUCHAR *)(names[i]),
+ (diFontHandle)&ddFont);
+ if (err) goto free_names;
+
+ pBuffer->dataSize += sizeof(pexFontInfo)
+ + sizeof(pexFontProp) * fontData.font_info.numProps;
+ if (PU_BUF_TOO_SMALL(pBuffer, pBuffer->dataSize))
+ if (puBuffRealloc(pBuffer, pBuffer->dataSize) != Success)
+ goto free_names;
+
+ /*
+ * Now, make a pass from the first glyph to the last glyph, seeing if
+ * all are defined.
+ */
+ fontData.font_info.allExist = 1;
+ ch_data = fontData.ch_data + fontData.font_info.firstGlyph;
+ for (j = fontData.font_info.firstGlyph;
+ j < fontData.num_ch && fontData.font_info.allExist;
+ j++, ch_data++ )
+ if (*ch_data == NULL || (*ch_data)->strokes.numLists <= 0) {
+ fontData.font_info.allExist = 0;
+ break; }
+
+ /* For now, let the default glyph be an asterisk */
+ fontData.font_info.defaultGlyph = (CARD16)'*';
+
+ /* It's a stroke font */
+ fontData.font_info.strokeFont = 1;
+
+ PACK_STRUCT(pexFontInfo, &(fontData.font_info), pBuf);
+ if (fontData.font_info.numProps > 0) {
+ PACK_LISTOF_STRUCT( fontData.font_info.numProps, pexFontProp,
+ fontData.properties, pBuf);
+ xfree(fontData.properties);
+ fontData.properties = 0; }
+
+ if (fontData.ch_data) {
+ for ( j=0, ch_data = fontData.ch_data;
+ j< fontData.num_ch;
+ j++, ch_data++) {
+ if (*ch_data) {
+ MI_FREELISTHEADER(& ((*ch_data)->strokes));
+ xfree((char *)(*ch_data)); } }
+ xfree((char *) (fontData.ch_data)); }
+
+ xfree(names[i]);
+ }
+
+ xfree(names);
+
+ *pNumNames = n;
+ pBuffer->pBuf = pBuf;
+ return (Success);
+
+free_names:
+ for (i = 0; i < n; i++) xfree(names[i]);
+ xfree(names);
+ pBuffer->dataSize = 0;
+ if (err) return(err);
+ return(BadAlloc);
+} /* ListPEXFontsPlus */
+
+/*
+ * Given the extremes of all of the character sets used in composing
+ * an ISTRING, and given the extremes of the ISTRING itself, along
+ * with path, expansion and alignment, calculate the correct
+ * concatenation point and alignment point. The updated extreme values
+ * are returned.
+ */
+void
+micalc_cpt_and_align(meta_font, extent_xmin, extent_xmax,
+ extent_ymin, extent_ymax, path, exp, pAlignment, cpt, align)
+Meta_font *meta_font;
+float *extent_xmin, *extent_xmax;
+float *extent_ymin, *extent_ymax;
+ddUSHORT path;
+ddTextAlignmentData *pAlignment;
+ddFLOAT exp;
+register pexCoord2D *cpt;
+register pexCoord2D *align;
+{
+
+ register float xmin = *extent_xmin,
+ xmax = *extent_xmax,
+ ymin = *extent_ymin,
+ ymax = *extent_ymax;
+ pexCoord2D temp;
+
+ /* some of the necessary info may not be calculated yet */
+ switch (path) {
+ case PEXPathRight:
+ if (xmin < 0) {
+ temp.x = xmax;
+ xmax = xmin;
+ xmin = temp.x;
+ }
+ cpt->x = xmax;
+ ymin = meta_font->bottom;
+ ymax = meta_font->top;
+ break;
+
+ case PEXPathLeft:
+ if (xmax <= 0.0)
+ cpt->x = xmin;
+ else
+ cpt->x = xmax;
+ ymin = meta_font->bottom;
+ ymax = meta_font->top;
+ break;
+
+ case PEXPathUp:
+ if (ymin < 0.0) {
+ temp.y = ymax;
+ ymax = ymin + meta_font->bottom;
+ ymin = temp.y + meta_font->bottom;
+ } else {
+ ymin = meta_font->bottom;
+ ymax += meta_font->bottom;
+ }
+ cpt->y = ymax;
+ xmax = meta_font->width * 0.5 * exp;
+ xmin = - xmax;
+ break;
+
+ case PEXPathDown:
+ if (ymax > 0.0) {
+ temp.y = ymax;
+ ymax = ymin;
+ ymin = temp.y;
+ } else {
+ ymin += meta_font->top;
+ ymax = meta_font->top;
+ }
+ cpt->y = ymin;
+ xmax = meta_font->width * 0.5 * exp;
+ xmin = - xmax;
+ break;
+ }
+
+ /* now do the vertical stuff */
+ switch (path) {
+
+ case PEXPathRight :
+ case PEXPathLeft :
+
+ switch (pAlignment->vertical) {
+ case PEXValignNormal :
+ case PEXValignBase :
+ cpt->y = 0.0;
+ align->y = ymin - meta_font->bottom;
+ break;
+ case PEXValignBottom :
+ cpt->y = align->y = ymin;
+ break;
+ case PEXValignTop :
+ cpt->y = align->y = ymax;
+ break;
+ case PEXValignCap :
+ cpt->y = FONT_COORD_CAP;
+ align->y = ymax - (meta_font->top - FONT_COORD_CAP);
+ break;
+ case PEXValignHalf :
+ cpt->y = align->y = FONT_COORD_HALF;
+ break;
+ }
+
+ break;
+
+ case PEXPathUp :
+ case PEXPathDown :
+ switch (pAlignment->vertical) {
+
+ case PEXValignBase :
+ align->y = ymin - meta_font->bottom;
+ break;
+ case PEXValignBottom :
+ align->y = ymin;
+ break;
+ case PEXValignTop :
+ align->y = ymax;
+ break;
+ case PEXValignCap :
+ align->y = ymax - (meta_font->top - FONT_COORD_CAP);
+ break;
+ case PEXValignHalf :
+ align->y = FONT_COORD_HALF + 0.5*(ymin - meta_font->bottom);
+ break;
+
+ case PEXValignNormal :
+ if (path == PEXPathUp) {
+ /* for PathUp, NORMAL == BASE */
+ align->y = ymin - meta_font->bottom;
+ } else { /* path == PEXPathDown */
+ align->y = ymax;
+ }
+ break;
+ }
+
+ break;
+ }
+
+ /* now do the horizontal stuff */
+ switch (path) {
+
+ case PEXPathRight:
+
+ switch (pAlignment->horizontal) {
+ case PEXHalignNormal :
+ case PEXHalignLeft :
+ align->x = xmin;
+ break;
+ case PEXHalignCenter :
+ align->x = 0.5 * (xmin + xmax);
+ break;
+ case PEXHalignRight :
+ align->x = xmax;
+ break;
+ }
+ break;
+
+ case PEXPathLeft:
+
+ switch (pAlignment->horizontal) {
+ case PEXHalignLeft :
+ if (xmax <= 0.0)
+ align->x = xmin;
+ else
+ align->x = xmax + xmin;
+ break;
+
+ case PEXHalignCenter :
+ align->x = 0.5 * (xmin + xmax);
+ break;
+
+ case PEXHalignNormal :
+ case PEXHalignRight :
+ align->x = (xmax > 0.0 ? 0.0 : xmax);
+ break;
+ }
+ break;
+
+ case PEXPathUp:
+ case PEXPathDown:
+
+ switch (pAlignment->horizontal) {
+ case PEXHalignLeft :
+ align->x = cpt->x = xmin;
+ break;
+ case PEXHalignNormal :
+ case PEXHalignCenter :
+ align->x = cpt->x = 0.5 * (xmin + xmax);
+ break;
+ case PEXHalignRight :
+ align->x = cpt->x = xmax;
+ break;
+ }
+ break;
+
+ }
+
+ *extent_xmin = xmin;
+ *extent_xmax = xmax;
+ *extent_ymin = ymin;
+ *extent_ymax = ymax;
+}
+
+
+
+/*++
+ |
+ | Function Name: QueryPEXTextExtents
+ |
+ | Function Description:
+ | Handles the PEXQueryTextExtents request.
+ |
+ | Note(s):
+ |
+ --*/
+ddpex43rtn
+QueryPEXTextExtents(resource, resourceType, fontIndex, path, expansion,
+ spacing, height, pAlignment, numStrings, pStrings, pBuffer)
+/* in */
+ ddPointer resource; /* what it is depends on next arg */
+ ddResourceType resourceType; /* renderer, wks, or lut */
+ ddUSHORT fontIndex; /* index into font table */
+ ddUSHORT path; /* text path */
+ ddFLOAT expansion; /* character expansion */
+ ddFLOAT spacing; /* character spacing */
+ ddFLOAT height; /* character height */
+ ddTextAlignmentData *pAlignment; /* text alignment */
+ ddULONG numStrings; /* num strings */
+ ddPointer pStrings; /* list of ISTRINGS */
+/* out */
+ ddBufferPtr pBuffer; /* extent info */
+{
+ diLUTHandle fontTable;
+ register ddPointer ptr;
+ pexMonoEncoding *mono_enc;
+ int i, fragnum, charnum, some_characters, signum;
+ CARD32 numFragments, charval;
+ diFontHandle font_handle;
+ miFontHeader *font;
+ pexExtentInfo *extent;
+ Ch_stroke_data *char_data;
+ ddFLOAT sp = spacing * FONT_COORD_HEIGHT;
+ Meta_font meta_font;
+ pexCoord2D cur, end, cpt, align;
+ float xmin, xmax, ymin, ymax;
+ float ht_scale = height / FONT_COORD_HEIGHT;
+ extern unsigned long PEXFontType;
+ miTextFontEntry *miFontTable;
+ ddTextFontEntry *fontEntry;
+ ddpex43rtn err;
+ ddUSHORT status;
+
+ switch (resourceType) {
+ case WORKSTATION_RESOURCE : {
+ miWksPtr pwks = (miWksPtr)(((diWKSHandle)resource)->deviceData);
+ fontTable = pwks->pRend->lut[PEXTextFontLUT];
+ break;
+
+ case LOOKUP_TABLE_RESOURCE :
+ fontTable = (diLUTHandle )resource;
+ if (fontTable->lutType != PEXTextFontLUT) return (BadMatch);
+ break;
+
+ case RENDERER_RESOURCE :
+ fontTable = ((ddRendererPtr )resource)->lut[PEXTextFontLUT];
+ break;
+
+ default: return(BadValue);
+ }
+
+ }
+
+
+ /* get ddTextFontEntry member */
+ err = InquireLUTEntryAddress( PEXTextFontLUT, fontTable, fontIndex,
+ &status, (ddPointer *)(&miFontTable));
+ if (err != Success) return(err);
+ fontEntry = &miFontTable->entry;
+
+ PU_CHECK_BUFFER_SIZE(pBuffer, numStrings * sizeof(pexExtentInfo));
+ pBuffer->dataSize = numStrings * sizeof(pexExtentInfo);
+
+
+ /* signum is used later on to encapsulate addition vs. subtraction */
+ if (path == PEXPathRight || path == PEXPathUp)
+ signum = 1;
+ else
+ signum = -1;
+
+ ptr = pStrings;
+ extent = (pexExtentInfo *)pBuffer->pBuf;
+
+ /* for each ISTRING */
+ for (i = 0; i < numStrings; i++, extent++) {
+
+ meta_font.top = -1.0e20;
+ meta_font.bottom = 1.0e20;
+ meta_font.width = 1.0e-20;
+
+ xmin = xmax = ymin = ymax = 0.0;
+ cpt.x = cpt.y = 0.0;
+ cur.x = end.x = cur.y = end.y = 0.0;
+
+ some_characters = 0; /* make TRUE when a valid character is found */
+
+ numFragments = *(CARD32 *)ptr;
+ ptr += sizeof(CARD32);
+
+ /* for each MONO_ENCODING fragment within the ISTRING */
+ for (fragnum = 0; fragnum < numFragments; fragnum++) {
+
+ mono_enc = (pexMonoEncoding *)ptr;
+ ptr += sizeof(pexMonoEncoding);
+
+ if (mono_enc->characterSet < 1 ||
+ mono_enc->characterSet > fontEntry->numFonts)
+ mono_enc->characterSet = 1;
+
+ font_handle = fontEntry->fonts[mono_enc->characterSet - 1];
+
+ /* this is the font that this MONO_ENCODING would be rendered
+ * with, thus we use it to base our extents on */
+ font = (miFontHeader *)(font_handle->deviceData);
+
+ /* bump up ISTRINGS extremes if appropriate */
+ if (font->top > meta_font.top)
+ meta_font.top = font->top;
+ if (font->bottom < meta_font.bottom)
+ meta_font.bottom = font->bottom;
+ if (font->max_width > meta_font.width)
+ meta_font.width = font->max_width;
+
+ /* for each character within the MONO_ENCODING */
+ for (charnum = 0; charnum < mono_enc->numChars; charnum++) {
+
+ switch (mono_enc->characterSetWidth) {
+ case PEXCSByte :
+ charval = (CARD32)(*(CARD8 *)ptr);
+ ptr += sizeof(CARD8);
+ break;
+ case PEXCSShort :
+ charval = (CARD32)(*(CARD16 *)ptr);
+ ptr += sizeof(CARD16);
+ break;
+ case PEXCSLong :
+ charval = *(CARD32 *)ptr;
+ ptr += sizeof(CARD32);
+ break;
+ }
+
+ if ( (charval < font->font_info.firstGlyph)
+ || (charval > font->font_info.lastGlyph)
+ || !(font->ch_data[(int)charval])) /* undefined char */
+ if (font->font_info.defaultGlyph == 0 &&
+ font->font_info.firstGlyph > 0) /* no default */
+ /* no extent info is calculated for undefined indices
+ * in charsets where there is no default glyph */
+ continue;
+ else
+ charval = font->font_info.defaultGlyph;
+
+ some_characters = 1;
+ char_data = font->ch_data[(int)charval];
+
+ switch (path) {
+
+ case PEXPathRight :
+ case PEXPathLeft :
+ end.x = cur.x + signum * char_data->right * expansion;
+ if (cur.x > xmax) xmax = cur.x;
+ if (cur.x < xmin) xmin = cur.x;
+ if (end.x > xmax) xmax = end.x;
+ if (end.x < xmin) xmin = end.x;
+ cur.x = end.x + signum * sp;
+ break;
+
+ case PEXPathUp :
+ case PEXPathDown :
+ end.y = cur.y + signum * (meta_font.top -
+ meta_font.bottom);
+ if (cur.y > ymax) ymax = cur.y;
+ if (cur.y < ymin) ymin = cur.y;
+ if (end.y > ymax) ymax = end.y;
+ if (end.y < ymin) ymin = end.y;
+ cur.y = end.y + signum * sp;
+ break;
+
+ }
+ }
+
+ ptr += PADDING(mono_enc->numChars *
+ ((mono_enc->characterSetWidth == PEXCSByte)
+ ? sizeof(CARD8)
+ : ((mono_enc->characterSetWidth == PEXCSShort)
+ ? sizeof(CARD16)
+ : sizeof(CARD32))));
+
+
+ } /* for each MONO_ENCODING */
+
+ if (some_characters) {
+
+ micalc_cpt_and_align( &meta_font, &xmin, &xmax, &ymin, &ymax,
+ path, expansion, pAlignment, &cpt, &align);
+
+ } else {
+ /* no valid characters */
+ xmin = xmax = ymin = ymax = 0.0;
+ cpt.x = cpt.y = align.x = align.y = 0.0;
+ }
+
+ extent->lowerLeft.x = ht_scale * (xmin - align.x);
+ extent->lowerLeft.y = ht_scale * (ymin - align.y);
+ extent->upperRight.x = ht_scale * (xmax - align.x);
+ extent->upperRight.y = ht_scale * (ymax - align.y);
+ extent->concatpoint.x = ht_scale * (cpt.x - align.x);
+ extent->concatpoint.y = ht_scale * (cpt.y - align.y);
+
+ } /* for each ISTRING */
+
+ return (Success);
+} /* QueryPEXTextExtents */
+
+
+/*++
+ |
+ | Function Name: UpdateFontRefs
+ |
+ | Function Description:
+ | The font resource knows how many LUTs are referencing it. If
+ | that number drops to zero, and FreePEXFont has already been
+ | called, then we really release the storage used by the font.
+ |
+ | Note(s):
+ |
+ --*/
+ddpex43rtn
+UpdateFontRefs(pFont, pResource, action)
+/* in */
+ diFontHandle pFont; /* font handle */
+ diLUTHandle pResource;/* lut handle */
+ ddAction action; /* add or remove */
+/* out */
+{
+
+ miFontHeader *font = (miFontHeader *) pFont->deviceData;
+
+ if (action == ADD) font->lutRefCount++;
+ else font->lutRefCount--;
+
+ if ((font->freeFlag == MI_TRUE) && (font->lutRefCount == 0))
+ really_free_font (pFont);
+
+ return (Success);
+} /* UpdateFontRefs */
+
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/shared/miFontLUT.c b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miFontLUT.c
new file mode 100644
index 000000000..33bb41b93
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miFontLUT.c
@@ -0,0 +1,228 @@
+/* $TOG: miFontLUT.c /main/3 1998/02/10 12:44:32 kaleb $ */
+/*
+
+Copyright 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/shared/miFontLUT.c,v 1.7 1998/10/04 09:34:48 dawes Exp $ */
+
+#include "miLUT.h"
+#include "miWks.h"
+#include "miInfo.h"
+#include "PEXErr.h"
+#include "PEXprotost.h"
+#include "pexos.h"
+
+
+/* Level 4 Shared Resources */
+/* Lookup Table Procedures */
+
+extern diFontHandle defaultPEXFont;
+extern unsigned colour_type_sizes[]; /* in miLUT.c */
+
+/* definitions used by miLUTProcs.ci */
+#define LUT_TYPE PEXTextFontLUT
+
+/* devPriv data structure */
+#define DD_LUT_ENTRY_STR ddTextFontEntry
+/* table entry data structure */
+#define MI_LUT_ENTRY_STR miTextFontEntry
+/* pex data */
+#define PEX_LUT_ENTRY_STR pexTextFontEntry
+
+#define LUT_REND_DYN_BIT PEXDynTextFontTableContents
+
+#define LUT_START_INDEX 1
+#define LUT_DEFAULT_INDEX 1
+#define LUT_0_DEFINABLE_ENTRIES 2
+#define LUT_0_NUM_PREDEFINED 1
+#define LUT_0_PREDEFINED_MIN 1
+#define LUT_0_PREDEFINED_MAX 1
+
+#define LUT_TABLE_START(pheader) (pheader)->plut.font
+
+/* no DYNAMIC */
+
+/* predefined entries table: change this to work with your devPriv data */
+static DD_LUT_ENTRY_STR pdeTextFontEntry[LUT_0_NUM_PREDEFINED];
+#define LUT_PDE_ENTRIES pdeTextFontEntry[0]
+#define LUT_SET_PDE_ENTRY(pentry, pdeentry) \
+ (pentry)->entry = *(pdeentry);
+
+/* predefined entry 0 is set to the default values
+ * change the XXX_DEFAULT_YYY macros below to use something else
+ * if you don't want the default values defined in the pde table
+ */
+#define PDE_DEFAULT_ENTRY_NUM 0
+#define LUT_DEFAULT_VALUES pdeTextFontEntry[PDE_DEFAULT_ENTRY_NUM]
+#define LUT_SET_DEFAULT_VALUES(pentry) \
+ (pentry)->entry = LUT_DEFAULT_VALUES
+
+/* which procedure definitions in miLUTProcs.h to use and their names
+ * take out USE flags if you're defining those procs in here
+ * but leave the name definitions
+ */
+
+#define LUT_USE_FREE
+#define LUT_USE_INQ_PREDEF
+#define LUT_USE_INQ_ENTRIES
+#define LUT_USE_COPY
+#define LUT_USE_INQ_INFO
+#define LUT_USE_INQ_IND
+#define LUT_USE_INQ_ENTRY
+#define LUT_USE_SET_ENTRIES
+#define LUT_USE_DEL_ENTRIES
+#define LUT_USE_INQ_ENTRY_ADDRESS
+#define LUT_USE_CREATE
+#define LUT_USE_MOD_CALL_BACK
+
+/* these three are redefined in miLUTProcs.h
+#define LUT_FREE TextFontLUT_free
+#define LUT_INQ_PREDEF TextFontLUT_inq_predef
+#define LUT_INQ_ENTRIES TextFontLUT_inq_entries
+*/
+#define LUT_COPY TextFontLUT_copy
+#define LUT_INQ_INFO TextFontLUT_inq_info
+#define LUT_INQ_IND TextFontLUT_inq_ind
+#define LUT_INQ_ENTRY TextFontLUT_inq_entry
+#define LUT_SET_ENTRIES TextFontLUT_set_entries
+#define LUT_DEL_ENTRIES TextFontLUT_del_entries
+#define LUT_INQ_ENTRY_ADDRESS TextFontLUT_inq_entry_address
+#define LUT_CREATE TextFontLUT_create
+#define LUT_ENTRY_CHECK TextFontLUT_entry_check
+#define LUT_COPY_PEX_MI TextFontLUT_copy_pex_to_mi
+#define LUT_COPY_MI_PEX TextFontLUT_copy_mi_to_pex
+#define LUT_MOD_CALL_BACK TextFontLUT_mod_call_back
+
+/* copy from an mi entry to a pex entry and increment ppbuf */
+ddpex43rtn
+LUT_COPY_MI_PEX ( pheader, valueType, pentry, ppbuf )
+ miLUTHeader *pheader;
+ ddUSHORT valueType;
+ MI_LUT_ENTRY_STR *pentry;
+ ddPointer *ppbuf;
+{
+ ddPointer pb = *ppbuf;
+ DD_LUT_ENTRY_STR *pdev_entry;
+
+ if (pentry == NULL)
+ pdev_entry = &(LUT_DEFAULT_VALUES);
+ else if (pentry->entry_info.status == MILUT_UNDEFINED)
+ pdev_entry = &(LUT_DEFAULT_VALUES);
+ else
+ pdev_entry = &pentry->entry;
+
+
+ mibcopy(pdev_entry, pb, sizeof(PEX_LUT_ENTRY_STR));
+
+ pb+= sizeof(PEX_LUT_ENTRY_STR);
+
+ mibcopy(pdev_entry->fonts, pb, pdev_entry->numFonts * sizeof(pexFont));
+
+ pb += pdev_entry->numFonts * sizeof(pexFont);
+
+ *ppbuf = pb;
+ return(Success);
+}
+
+/* copy from a pex entry to an mi entry and increment ppsrc */
+ddpex43rtn
+LUT_COPY_PEX_MI ( pheader, ppsrc, pentry )
+ miLUTHeader *pheader;
+ ddPointer *ppsrc;
+ MI_LUT_ENTRY_STR *pentry;
+{
+ ddPointer ps = *ppsrc;
+ diFontHandle *psfonts, *pdfonts;
+ register int j;
+
+ mibcopy(ps, &(pentry->entry), sizeof(PEX_LUT_ENTRY_STR));
+
+ ps+= sizeof(PEX_LUT_ENTRY_STR);
+
+ for (psfonts = (diFontHandle *)ps, pdfonts = pentry->entry.fonts, j = 0;
+ j < pentry->entry.numFonts; j++, psfonts++, pdfonts++)
+ *pdfonts = *psfonts;
+ for (; j < MILUT_MAX_CS_PER_ENTRY; j++, pdfonts++)
+ *pdfonts = defaultPEXFont;
+
+ *ppsrc = (ddPointer)psfonts;
+
+ return(Success);
+}
+
+/* check for bad values and increment ppPexEntry */
+
+ddpex43rtn
+LUT_ENTRY_CHECK (pheader, ppPexEntry)
+ miLUTHeader *pheader;
+ PEX_LUT_ENTRY_STR **ppPexEntry;
+{
+ ddPointer pe = (ddPointer)*ppPexEntry;
+
+ /* numFonts: imp. dep limitation */
+ if ((*ppPexEntry)->numFonts > MILUT_MAX_CS_PER_ENTRY)
+ return(BadValue);
+ /* dipex should have looked up font id's and made them handles
+ * and would have found any bad ids */
+
+ pe += sizeof(PEX_LUT_ENTRY_STR) +
+ (*ppPexEntry)->numFonts * sizeof(pexFont);
+
+ *ppPexEntry = (PEX_LUT_ENTRY_STR *)pe;
+ return(Success);
+}
+
+
+void
+TextFontLUT_init_pde()
+{
+ register int i;
+
+ pdeTextFontEntry[0].numFonts = 1;
+ pdeTextFontEntry[0].fonts[0] = defaultPEXFont;
+ /* fill in the rest of this with this font, since we want 'undefined'
+ * character sets to default to the default font (0) in the font group. */
+ for (i = 1; i < MILUT_MAX_CS_PER_ENTRY; i++)
+ pdeTextFontEntry[0].fonts[i] = defaultPEXFont;
+}
+
+#include "miLUTProcs.ci"
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/shared/miIntLUT.c b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miIntLUT.c
new file mode 100644
index 000000000..37b267166
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miIntLUT.c
@@ -0,0 +1,435 @@
+/* $TOG: miIntLUT.c /main/3 1998/02/10 12:44:40 kaleb $ */
+/*
+
+Copyright 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/shared/miIntLUT.c,v 1.7 1998/10/04 09:34:49 dawes Exp $ */
+
+#include "miLUT.h"
+#include "miWks.h"
+#include "miInfo.h"
+#include "PEXErr.h"
+#include "PEXprotost.h"
+#include "pexos.h"
+
+
+/* useful definition when testing */
+typedef struct {
+ pexEnumTypeIndex interiorStyle;
+ INT16 interiorStyleIndex;
+ pexEnumTypeIndex reflectionModel;
+ pexEnumTypeIndex surfaceInterp;
+ pexEnumTypeIndex bfInteriorStyle;
+ INT16 bfInteriorStyleIndex;
+ pexEnumTypeIndex bfReflectionModel;
+ pexEnumTypeIndex bfSurfaceInterp;
+ pexSurfaceApprox surfaceApprox;
+ pexColourSpecifier surfaceColour;
+ pexIndexedColour index1;
+ pexReflectionAttr reflectionAttr;
+ pexIndexedColour index2;
+ pexColourSpecifier bfSurfaceColour;
+ pexIndexedColour index3;
+ pexReflectionAttr bfReflectionAttr;
+ pexIndexedColour index4;
+} bogus_pexInteriorBundleEntry;
+
+/* Level 4 Shared Resources */
+/* Lookup Table Procedures */
+
+extern unsigned colour_type_sizes[]; /* in miLUT.c */
+
+/* definitions used by miLUTProcs.ci */
+#define LUT_TYPE PEXInteriorBundleLUT
+
+/* devPriv data structure */
+#define DD_LUT_ENTRY_STR ddInteriorBundleEntry
+/* table entry data structure */
+#define MI_LUT_ENTRY_STR miInteriorBundleEntry
+/* pex data */
+#define PEX_LUT_ENTRY_STR pexInteriorBundleEntry
+
+#define LUT_REND_DYN_BIT PEXDynInteriorBundleContents
+
+#define LUT_START_INDEX 1
+#define LUT_DEFAULT_INDEX 1
+#define LUT_0_DEFINABLE_ENTRIES 20
+#define LUT_0_NUM_PREDEFINED 1
+#define LUT_0_PREDEFINED_MIN 1
+#define LUT_0_PREDEFINED_MAX 1
+
+#define LUT_TABLE_START(pheader) (pheader)->plut.interior
+
+#define DYNAMIC INTERIOR_BUNDLE_DYNAMIC
+
+/* predefined entries table: change this to work with your devPriv data */
+static DD_LUT_ENTRY_STR pdeInteriorBundleEntry[LUT_0_NUM_PREDEFINED];
+#define LUT_PDE_ENTRIES pdeInteriorBundleEntry[0]
+#define LUT_SET_PDE_ENTRY(pentry, pdeentry) \
+ (pentry)->entry = *(pdeentry); \
+ (pentry)->real_entry = *(pdeentry)
+
+/* predefined entry 0 is set to the default values
+ * change the XXX_DEFAULT_YYY macros below to use something else
+ * if you don't want the default values defined in the pde table
+ */
+#define PDE_DEFAULT_ENTRY_NUM 0
+#define LUT_DEFAULT_VALUES pdeInteriorBundleEntry[PDE_DEFAULT_ENTRY_NUM]
+#define LUT_SET_DEFAULT_VALUES(pentry) \
+ (pentry)->entry = LUT_DEFAULT_VALUES; \
+ (pentry)->real_entry = LUT_DEFAULT_VALUES
+
+/* which procedure definitions in miLUTProcs.h to use and their names
+ * take out USE flags if you're defining those procs in here
+ * but leave the name definitions
+ */
+
+#define LUT_USE_FREE
+#define LUT_USE_INQ_PREDEF
+#define LUT_USE_INQ_ENTRIES
+#define LUT_USE_COPY
+#define LUT_USE_INQ_INFO
+#define LUT_USE_INQ_IND
+#define LUT_USE_INQ_ENTRY
+#define LUT_USE_SET_ENTRIES
+#define LUT_USE_DEL_ENTRIES
+#define LUT_USE_INQ_ENTRY_ADDRESS
+#define LUT_USE_CREATE
+#define LUT_USE_MOD_CALL_BACK
+
+/* these three are redefined in miLUTProcs.h
+#define LUT_FREE InteriorBundleLUT_free
+#define LUT_INQ_PREDEF InteriorBundleLUT_inq_predef
+#define LUT_INQ_ENTRIES InteriorBundleLUT_inq_entries
+*/
+#define LUT_COPY InteriorBundleLUT_copy
+#define LUT_INQ_INFO InteriorBundleLUT_inq_info
+#define LUT_INQ_IND InteriorBundleLUT_inq_ind
+#define LUT_INQ_ENTRY InteriorBundleLUT_inq_entry
+#define LUT_SET_ENTRIES InteriorBundleLUT_set_entries
+#define LUT_DEL_ENTRIES InteriorBundleLUT_del_entries
+#define LUT_INQ_ENTRY_ADDRESS InteriorBundleLUT_inq_entry_address
+#define LUT_CREATE InteriorBundleLUT_create
+#define LUT_ENTRY_CHECK InteriorBundleLUT_entry_check
+#define LUT_COPY_PEX_MI InteriorBundleLUT_copy_pex_to_mi
+#define LUT_COPY_MI_PEX InteriorBundleLUT_copy_mi_to_pex
+#define LUT_MOD_CALL_BACK InteriorBundleLUT_mod_call_back
+#define LUT_REALIZE_ENTRY InteriorBundleLUT_realize_entry
+
+/* copy from an mi entry to a pex entry and increment ppbuf */
+ddpex43rtn
+LUT_COPY_MI_PEX ( pheader, valueType, pentry, ppbuf )
+ miLUTHeader *pheader;
+ ddUSHORT valueType;
+ MI_LUT_ENTRY_STR *pentry;
+ ddPointer *ppbuf;
+{
+ ddPointer pb = *ppbuf;
+ DD_LUT_ENTRY_STR *pdev_entry;
+
+ if (pentry == NULL)
+ pdev_entry = &(LUT_DEFAULT_VALUES);
+ else if (pentry->entry_info.status == MILUT_UNDEFINED)
+ pdev_entry = &(LUT_DEFAULT_VALUES);
+ else
+ if (valueType == PEXRealizedValue)
+ pdev_entry = &pentry->real_entry;
+ else
+ pdev_entry = &pentry->entry;
+
+
+ mibcopy(pdev_entry, pb, sizeof(PEX_LUT_ENTRY_STR));
+ pb += sizeof(PEX_LUT_ENTRY_STR);
+
+ /* surface colour */
+ mibcopy(&pdev_entry->surfaceColour, pb, sizeof(pexColourSpecifier));
+ pb += sizeof(pexColourSpecifier);
+ MILUT_COPY_COLOUR(&pdev_entry->surfaceColour.colour,
+ pb, pdev_entry->surfaceColour.colourType);
+ pb += colour_type_sizes[(int)pdev_entry->surfaceColour.colourType];
+
+ /* refl attrs */
+ mibcopy(&pdev_entry->reflectionAttr, pb, sizeof(pexReflectionAttr));
+ pb += sizeof(pexReflectionAttr);
+ MILUT_COPY_COLOUR(&pdev_entry->reflectionAttr.specularColour.colour,
+ pb, pdev_entry->reflectionAttr.specularColour.colourType);
+ pb += colour_type_sizes[(int)pdev_entry->reflectionAttr.specularColour.colourType];
+
+ /* bf surface colour */
+ mibcopy(&pdev_entry->bfSurfaceColour, pb, sizeof(pexColourSpecifier));
+ pb += sizeof(pexColourSpecifier);
+ MILUT_COPY_COLOUR(&pdev_entry->bfSurfaceColour.colour,
+ pb, pdev_entry->bfSurfaceColour.colourType);
+ pb += colour_type_sizes[(int)pdev_entry->bfSurfaceColour.colourType];
+
+ /* bf refl attrs */
+ mibcopy(&pdev_entry->bfReflectionAttr, pb, sizeof(pexReflectionAttr));
+ pb += sizeof(pexReflectionAttr);
+ MILUT_COPY_COLOUR(&pdev_entry->bfReflectionAttr.specularColour.colour,
+ pb, pdev_entry->bfReflectionAttr.specularColour.colourType);
+ pb += colour_type_sizes[(int)pdev_entry->bfReflectionAttr.specularColour.colourType];
+
+ *ppbuf = pb;
+ return(Success);
+}
+
+/* copy from a pex entry to an mi entry and increment ppsrc */
+ddpex43rtn
+LUT_COPY_PEX_MI ( pheader, ppsrc, pentry )
+ miLUTHeader *pheader;
+ ddPointer *ppsrc;
+ MI_LUT_ENTRY_STR *pentry;
+{
+ ddSHORT colourType;
+ ddPointer psrc = *ppsrc;
+
+ mibcopy(psrc, &(pentry->entry), sizeof(PEX_LUT_ENTRY_STR));
+ psrc += sizeof(PEX_LUT_ENTRY_STR);
+
+ pentry->entry.surfaceColour.colourType = colourType =
+ ((pexColourSpecifier *)psrc)->colourType;
+ psrc += sizeof(pexColourSpecifier);
+ MILUT_COPY_COLOUR(psrc, &(pentry->entry.surfaceColour.colour), colourType);
+ psrc += colour_type_sizes[(int)colourType];
+
+ mibcopy(psrc, &(pentry->entry.reflectionAttr), sizeof(pexReflectionAttr));
+ psrc += sizeof(pexReflectionAttr);
+
+ colourType = pentry->entry.reflectionAttr.specularColour.colourType;
+ MILUT_COPY_COLOUR(psrc, &(pentry->entry.reflectionAttr.specularColour.colour),
+ colourType);
+ psrc += colour_type_sizes[(int)colourType];
+
+ pentry->entry.bfSurfaceColour.colourType = colourType =
+ ((pexColourSpecifier *)psrc)->colourType;
+ psrc += sizeof(pexColourSpecifier);
+ MILUT_COPY_COLOUR(psrc, &(pentry->entry.bfSurfaceColour.colour), colourType);
+ psrc += colour_type_sizes[(int)colourType];
+
+ mibcopy(psrc, &(pentry->entry.bfReflectionAttr), sizeof(pexReflectionAttr));
+ psrc += sizeof(pexReflectionAttr);
+
+ colourType = pentry->entry.bfReflectionAttr.specularColour.colourType;
+ MILUT_COPY_COLOUR(psrc, &(pentry->entry.bfReflectionAttr.specularColour.colour),
+ colourType);
+ psrc += colour_type_sizes[(int)colourType];
+
+ LUT_REALIZE_ENTRY( pheader, pentry );
+
+ *ppsrc = psrc;
+
+ return(Success);
+}
+
+/* check for bad values and increment ppPexEntry */
+
+ddpex43rtn
+LUT_ENTRY_CHECK (pheader, ppPexEntry)
+ miLUTHeader *pheader;
+ PEX_LUT_ENTRY_STR **ppPexEntry;
+{
+ ddPointer ps;
+ ddSHORT colourType;
+
+ /* interiorStyle: any value OK. use style 1 if it's not supported */
+ /* interiorStyleIndex: any value OK. this is used for patterns
+ * and hatches which aren't supported */
+ /* reflectionModel: any value OK. use method 1 if it's not supported */
+ /* surfaceInterp: any value OK. use method 1 if it's not supported */
+ /* same as above for bf values */
+
+ /* surfaceApprox: any value OK. use method 1 if it's not supported */
+ /* front and back reflection attrs: any values OK */
+
+ /* colours: only accept supported colour types */
+ ps = (ddPointer)(*ppPexEntry + 1);
+ colourType = ((pexColourSpecifier *)ps)->colourType;
+ if (MI_BADCOLOURTYPE(colourType))
+ return(PEXERR(PEXColourTypeError));
+
+ ps += sizeof(pexColourSpecifier) + colour_type_sizes[(int)colourType];
+ colourType = ((pexReflectionAttr *)ps)->specularColour.colourType;
+ if (MI_BADCOLOURTYPE(colourType))
+ return(PEXERR(PEXColourTypeError));
+
+ ps += sizeof(pexReflectionAttr) + colour_type_sizes[(int)colourType];
+ colourType = ((pexColourSpecifier *)ps)->colourType;
+ if (MI_BADCOLOURTYPE(colourType))
+ return(PEXERR(PEXColourTypeError));
+
+ ps += sizeof(pexColourSpecifier) + colour_type_sizes[(int)colourType];
+ colourType = ((pexReflectionAttr *)ps)->specularColour.colourType;
+ if (MI_BADCOLOURTYPE(colourType))
+ return(PEXERR(PEXColourTypeError));
+
+ ps += sizeof(pexReflectionAttr) + colour_type_sizes[(int)colourType];
+ *ppPexEntry = (PEX_LUT_ENTRY_STR *)ps;
+
+ return(Success);
+}
+
+/* realize entry */
+ddpex43rtn
+LUT_REALIZE_ENTRY( pheader, pEntry )
+ miLUTHeader *pheader;
+ MI_LUT_ENTRY_STR *pEntry;
+{
+ extern miEnumType miInteriorStyleET[][SI_INT_NUM];
+ extern miEnumType miReflectionModelET[][SI_REFLECT_NUM];
+ extern miEnumType miSurfaceInterpMethodET[][SI_SURF_INTERP_NUM];
+ extern miEnumType miSurfaceApproxMethodET[][SI_SURF_APPROX_NUM];
+
+ /* interiorStyle: any value OK. use interior style 1 if it's not supported */
+ if ( (pEntry->entry.interiorStyle <
+ miInteriorStyleET[pheader->drawType][0].index) ||
+ (pEntry->entry.interiorStyle >
+ miInteriorStyleET[pheader->drawType][SI_INT_NUM - 1].index) )
+ pEntry->real_entry.interiorStyle = 1;
+ else
+ pEntry->real_entry.interiorStyle = pEntry->entry.interiorStyle;
+
+ /* interiorStyleIndex: any value OK. it's only for patterns & hatches
+ * which are supported */
+ pEntry->real_entry.interiorStyleIndex = pEntry->entry.interiorStyleIndex;
+
+ /* reflectionModel: any value OK. use model 1 if it's not supported */
+ if ( (pEntry->entry.reflectionModel <
+ miReflectionModelET[pheader->drawType][0].index) ||
+ (pEntry->entry.reflectionModel >
+ miReflectionModelET[pheader->drawType][SI_REFLECT_NUM - 1].index) )
+ pEntry->real_entry.reflectionModel = 1;
+ else
+ pEntry->real_entry.reflectionModel = pEntry->entry.reflectionModel;
+
+ /* surfaceInterp: any value OK. use model 1 if it's not supported */
+ if ( (pEntry->entry.surfaceInterp <
+ miSurfaceInterpMethodET[pheader->drawType][0].index) ||
+ (pEntry->entry.surfaceInterp >
+ miSurfaceInterpMethodET[pheader->drawType][SI_SURF_INTERP_NUM - 1].index) )
+ pEntry->real_entry.surfaceInterp = 1;
+ else
+ pEntry->real_entry.surfaceInterp = pEntry->entry.surfaceInterp;
+
+ /* bfinteriorStyle: any value OK. use style 1 if it's not supported */
+ if ( (pEntry->entry.bfInteriorStyle <
+ miInteriorStyleET[pheader->drawType][0].index) ||
+ (pEntry->entry.bfInteriorStyle >
+ miInteriorStyleET[pheader->drawType][SI_INT_NUM - 1].index) )
+ pEntry->real_entry.bfInteriorStyle = 1;
+ else
+ pEntry->real_entry.bfInteriorStyle = pEntry->entry.bfInteriorStyle;
+
+ /* bfInteriorStyleIndex: any value OK. it's only for patterns & hatches
+ * which are supported */
+ pEntry->real_entry.bfInteriorStyleIndex = pEntry->entry.bfInteriorStyleIndex;
+
+ /* bfReflectionModel: any value OK. use model 1 if it's not supported */
+ if ( (pEntry->entry.bfReflectionModel <
+ miReflectionModelET[pheader->drawType][0].index) ||
+ (pEntry->entry.bfReflectionModel >
+ miReflectionModelET[pheader->drawType][SI_REFLECT_NUM - 1].index) )
+ pEntry->real_entry.bfReflectionModel = 1;
+ else
+ pEntry->real_entry.bfReflectionModel = pEntry->entry.bfReflectionModel;
+
+ /* bfSurfaceInterp: any value OK. use model 1 if it's not supported */
+ if ( (pEntry->entry.bfSurfaceInterp <
+ miSurfaceInterpMethodET[pheader->drawType][0].index) ||
+ (pEntry->entry.bfSurfaceInterp >
+ miSurfaceInterpMethodET[pheader->drawType][SI_SURF_INTERP_NUM - 1].index) )
+ pEntry->real_entry.bfSurfaceInterp = 1;
+ else
+ pEntry->real_entry.bfSurfaceInterp = pEntry->entry.bfSurfaceInterp;
+
+ /* surfaceApprox: any value OK. use model 1 if it's not supported */
+ if ( (pEntry->entry.surfaceApprox.approxMethod <
+ miSurfaceApproxMethodET[pheader->drawType][0].index) ||
+ (pEntry->entry.surfaceApprox.approxMethod >
+ miSurfaceApproxMethodET[pheader->drawType][SI_SURF_APPROX_NUM - 1].index) )
+ pEntry->real_entry.surfaceApprox.approxMethod = 1;
+ else
+ pEntry->real_entry.surfaceApprox.approxMethod =
+ pEntry->entry.surfaceApprox.approxMethod;
+
+ pEntry->real_entry.surfaceApprox.uTolerance = pEntry->entry.surfaceApprox.uTolerance;
+ pEntry->real_entry.surfaceApprox.vTolerance = pEntry->entry.surfaceApprox.vTolerance;
+
+ /* front and back reflection attrs: any values OK (includes colours) */
+ pEntry->real_entry.reflectionAttr = pEntry->entry.reflectionAttr;
+ pEntry->real_entry.bfReflectionAttr = pEntry->entry.bfReflectionAttr;
+
+ /* colourType: its an error if an unsupported colour type was
+ * specified. For supported colour types, should mapped colour
+ * be returned??
+ */
+ pEntry->real_entry.surfaceColour = pEntry->entry.surfaceColour;
+ pEntry->real_entry.bfSurfaceColour = pEntry->entry.bfSurfaceColour;
+
+}
+void
+InteriorBundleLUT_init_pde()
+{
+ pdeInteriorBundleEntry[0].interiorStyle = PEXInteriorStyleHollow;
+ pdeInteriorBundleEntry[0].interiorStyleIndex = 1;
+ pdeInteriorBundleEntry[0].reflectionModel = PEXReflectionNoShading;
+ pdeInteriorBundleEntry[0].surfaceInterp = PEXSurfaceInterpNone;
+ pdeInteriorBundleEntry[0].bfInteriorStyle = PEXInteriorStyleHollow;
+ pdeInteriorBundleEntry[0].bfInteriorStyleIndex = 1;
+ pdeInteriorBundleEntry[0].bfReflectionModel = PEXReflectionNoShading;
+ pdeInteriorBundleEntry[0].bfSurfaceInterp = PEXSurfaceInterpNone;
+ pdeInteriorBundleEntry[0].surfaceApprox.approxMethod = 1;
+ pdeInteriorBundleEntry[0].surfaceApprox.uTolerance = 1.0;
+ pdeInteriorBundleEntry[0].surfaceApprox.vTolerance = 1.0;
+ MILUT_INIT_COLOUR(pdeInteriorBundleEntry[0].surfaceColour);
+ pdeInteriorBundleEntry[0].bfSurfaceColour =
+ pdeInteriorBundleEntry[0].surfaceColour;
+ pdeInteriorBundleEntry[0].reflectionAttr.ambient = 1.0;
+ pdeInteriorBundleEntry[0].reflectionAttr.diffuse = 1.0;
+ pdeInteriorBundleEntry[0].reflectionAttr.specular = 1.0;
+ pdeInteriorBundleEntry[0].reflectionAttr.specularConc = 0.0;
+ pdeInteriorBundleEntry[0].reflectionAttr.transmission = 0.0;
+ MILUT_INIT_COLOUR(pdeInteriorBundleEntry[0].reflectionAttr.specularColour);
+ pdeInteriorBundleEntry[0].bfReflectionAttr =
+ pdeInteriorBundleEntry[0].reflectionAttr;
+}
+
+#include "miLUTProcs.ci"
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/shared/miLUT.c b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miLUT.c
new file mode 100644
index 000000000..e6d17d0ca
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miLUT.c
@@ -0,0 +1,835 @@
+/* $TOG: miLUT.c /main/3 1998/02/10 12:44:46 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/shared/miLUT.c,v 1.9 1999/07/18 08:34:27 dawes Exp $ */
+
+#include "miLUT.h"
+#include "pexUtils.h"
+#include "PEX.h"
+#include "PEXErr.h"
+#include "PEXprotost.h"
+#include "pexos.h"
+
+
+/* Level 4 Shared Resources */
+/* General Lookup Table Procedures */
+
+/* A flag to know if predefined entries are initialized.
+ * Most of them can't be automatically initialized because
+ * they contain unions, so they are set dynamically
+ * The flag is initialized in ddpexInit()
+ */
+int predef_initialized;
+
+/* used by other LUT modules */
+unsigned colour_type_sizes[] = {
+ sizeof(ddIndexedColour),
+ sizeof(ddRgbFloatColour),
+ sizeof(ddCieColour),
+ sizeof(ddHsvColour),
+ sizeof(ddHlsColour),
+ sizeof(ddRgb8Colour),
+ sizeof(ddRgb16Colour)
+};
+
+static void InitializePDEs();
+
+static unsigned entry_size[] = {
+ 0, /* dummy so table type indexes into table */
+ sizeof(miLineBundleEntry), /* line bundle */
+ sizeof(miMarkerBundleEntry), /* marker bundle */
+ sizeof(miTextBundleEntry), /* text bundle */
+ sizeof(miInteriorBundleEntry),/* interior bundle */
+ sizeof(miEdgeBundleEntry), /* edge bundle */
+ sizeof(miPatternEntry), /* pattern table */
+ sizeof(miTextFontEntry), /* font table */
+ sizeof(miColourEntry), /* colour table */
+ sizeof(miViewEntry), /* view table */
+ sizeof(miLightEntry), /* light table */
+ sizeof(miDepthCueEntry), /* depth cue table */
+ sizeof(miColourApproxEntry), /* colour approx table */
+};
+
+/*++
+ |
+ | Function Name: CreateLUT
+ |
+ | Function Description:
+ | Handles the PEXCreateLookupTable request.
+ |
+ | Note(s):
+ dipex checks for bad id, drawable, table type
+ |
+ --*/
+
+/* create procs are called through this table instead of through
+ * ops table in lut header.
+ */
+extern ddpex43rtn LineBundleLUT_create(),
+ MarkerBundleLUT_create(),
+ TextBundleLUT_create(),
+ InteriorBundleLUT_create(),
+ EdgeBundleLUT_create(),
+ PatternLUT_create(),
+ TextFontLUT_create(),
+ ColourLUT_create(),
+ ViewLUT_create(),
+ LightLUT_create(),
+ DepthCueLUT_create(),
+ ColourApproxLUT_create();
+
+miOpsTableType createLUTtable[] = {
+ LineBundleLUT_create,
+ MarkerBundleLUT_create,
+ TextBundleLUT_create,
+ InteriorBundleLUT_create,
+ EdgeBundleLUT_create,
+ PatternLUT_create,
+ TextFontLUT_create,
+ ColourLUT_create,
+ ViewLUT_create,
+ LightLUT_create,
+ DepthCueLUT_create,
+ ColourApproxLUT_create,
+};
+
+ddpex43rtn
+CreateLUT(pDrawable, pLUT)
+/* in */
+ DrawablePtr pDrawable;/* pointer to example drawable */
+ diLUTHandle pLUT; /* lut handle */
+/* out */
+{
+ register miLUTHeader *pheader;
+ ddUSHORT LUTtype = pLUT->lutType;
+ ddpex43rtn err;
+
+#ifdef DDTEST
+ ErrorF( "\nCreateLUT %d type %d\n", pLUT->id, pLUT->lutType);
+#endif
+
+ pLUT->deviceData = NULL;
+
+ if ((pheader = (miLUTHeader *) xalloc(sizeof(miLUTHeader))) == NULL)
+ return (BadAlloc);
+
+ /* the id and table type are already in the di resource structure */
+ pheader->freeFlag = MI_FALSE;
+
+ /* set drawable example and type which supports this drawable */
+ MI_SETDRAWEXAMPLE(pDrawable, &(pheader->drawExample));
+ MI_WHICHDRAW(pDrawable, pheader->drawType);
+
+ if (!(pheader->wksRefList = puCreateList(DD_WKS)))
+ {
+ xfree( pheader);
+ return (BadAlloc);
+ }
+
+ if (!(pheader->rendRefList = puCreateList(DD_RENDERER)))
+ {
+ puDeleteList(pheader->wksRefList);
+ xfree(pheader);
+ return (BadAlloc);
+ }
+
+ /*
+ * now create the predefined entries. for now,
+ * predefined entries don't depend on the drawable type. If they every
+ * do, make the pde vars a 2-d array - the first dimension based on
+ * drawable type and the second one the entries for that drawable type.
+ * (see InquireEnumTypeInfo for an example of this)
+ */
+ if (!predef_initialized)
+ {
+ InitializePDEs();
+ predef_initialized = 1;
+ }
+
+ err = Success;
+ err = createLUTtable[LUTtype-1](pLUT, pheader);
+ if (err != Success)
+ {
+ MILUT_DESTROY_HEADER(pheader);
+ }
+
+ return(err);
+
+} /* CreateLUT */
+
+
+/*++
+ |
+ | Function Name: FreeLUT
+ |
+ | Function Description:
+ | Frees all of the storage for the lookup table if no resource is using
+ | it, otherwise it sets the free flag in the structure. This is
+ | registered with the resource id and handle by diPEX with AddResource.
+ |
+ | Note(s):
+ dipex checks for bad id
+ |
+ --*/
+
+ddpex43rtn
+FreeLUT(pLUT, LUTid)
+/* in */
+ diLUTHandle pLUT; /* lut handle */
+ ddResourceId LUTid; /* lookup table resource id */
+/* out */
+{
+ MILUT_DEFINE_HEADER(pLUT, pheader);
+
+#ifdef DDTEST
+ ErrorF( "\nFreeLUT %d type %d\n", pLUT->id, pLUT->lutType);
+#endif
+
+ pheader->freeFlag = MI_TRUE;
+ pLUT->id = PEXAlreadyFreed;
+ MILUT_CHECK_DESTROY(pLUT, pheader);
+
+ return (Success);
+} /* FreeLUT */
+
+/*++
+ |
+ | Function Name: CopyLUT
+ |
+ | Function Description:
+ | Handles the PEXCopyLookupTable request.
+ |
+ | Note(s):
+ dipex checks for bad ids
+ |
+ --*/
+
+#define COMPARE_DRAWABLE_EXAMPLES(Ex1, Ex2, Op) \
+ ((Ex1).type Op (Ex2).type) \
+&& ((Ex1).depth Op (Ex2).depth) \
+&& ((Ex1).rootDepth Op (Ex2).rootDepth)
+
+ddpex43rtn
+CopyLUT(pSrcLUT, pDestLUT)
+/* in */
+ diLUTHandle pSrcLUT; /* source lookup table */
+ diLUTHandle pDestLUT; /* destination lookup table */
+/* out */
+{
+ MILUT_DEFINE_HEADER(pSrcLUT, srcHeader);
+ MILUT_DEFINE_HEADER(pDestLUT, destHeader);
+
+#ifdef DDTEST
+ ErrorF( "\nCopyLUT src %d type %d\n", pSrcLUT->id, pSrcLUT->lutType);
+ ErrorF( "\nCopyLUT dest %d type %d\n", pDestLUT->id, pDestLUT->lutType);
+#endif
+
+ if (pSrcLUT->lutType != pDestLUT->lutType)
+ return (BadMatch);
+
+ /* compare the drawable examples. */
+/*
+ * Here's one way
+ *
+ * if (! (COMPARE_DRAWABLE_EXAMPLES(srcHeader->drawExample,
+ * destHeader->drawExample,==))
+ *
+ * (see the macro definition above; it compares most of the struct members)
+ * but the one below is more restrictive, I think (it probably means both
+ * drawables are on the same framebuffer) and is likely safe for now.
+ */
+ if (srcHeader->drawExample.rootVisual != destHeader->drawExample.rootVisual)
+ return (BadMatch);
+
+ return(srcHeader->ops[MILUT_REQUEST_OP(PEX_CopyLookupTable)]
+ (pSrcLUT, pDestLUT));
+} /* CopyLUT */
+
+/*++
+ |
+ | Function Name: InquireLUTInfo
+ |
+ | Function Description:
+ | Handles the PEXGetTableInfo request.
+ |
+ | Note(s):
+ dipex checks for bad drawable id and type
+ |
+ --*/
+extern ddpex43rtn LineBundleLUT_inq_info(),
+ MarkerBundleLUT_inq_info(),
+ TextBundleLUT_inq_info(),
+ InteriorBundleLUT_inq_info(),
+ EdgeBundleLUT_inq_info(),
+ PatternLUT_inq_info(),
+ TextFontLUT_inq_info(),
+ ColourLUT_inq_info(),
+ ViewLUT_inq_info(),
+ LightLUT_inq_info(),
+ DepthCueLUT_inq_info(),
+ ColourApproxLUT_inq_info();
+
+miOpsTableType inq_info_LUTtable[] = {
+ LineBundleLUT_inq_info,
+ MarkerBundleLUT_inq_info,
+ TextBundleLUT_inq_info,
+ InteriorBundleLUT_inq_info,
+ EdgeBundleLUT_inq_info,
+ PatternLUT_inq_info,
+ TextFontLUT_inq_info,
+ ColourLUT_inq_info,
+ ViewLUT_inq_info,
+ LightLUT_inq_info,
+ DepthCueLUT_inq_info,
+ ColourApproxLUT_inq_info,
+};
+
+
+ddpex43rtn
+InquireLUTInfo(pDrawable, LUTtype, pLUTinfo)
+/* in */
+ DrawablePtr pDrawable;/* pointer to example drawable */
+ ddUSHORT LUTtype; /* lookup table type */
+/* out */
+ ddTableInfo *pLUTinfo; /* table information */
+{
+
+#ifdef DDTEST
+ ErrorF( "\nInquireLUTInfo type %d\n", LUTtype);
+#endif
+
+ return (inq_info_LUTtable[LUTtype-1](pDrawable, pLUTinfo));
+} /* InquireLUTInfo */
+
+
+/*++
+ |
+ | Function Name: InquireLUTPredEntries
+ |
+ | Function Description:
+ | Handles the PEXGetPredefinedEntries request.
+ |
+ | Note(s):
+ dipex checks for bad drawable and type
+ |
+ --*/
+
+ddpex43rtn
+InquireLUTPredEntries(pDrawable, LUTtype, start, count, pNumEntries, pBuffer)
+/* in */
+ DrawablePtr pDrawable; /* pointer to example drawable */
+ ddUSHORT LUTtype; /* table type */
+ ddTableIndex start; /* start index */
+ ddUSHORT count; /* number of entries to return */ /* out */
+ ddULONG *pNumEntries; /* number of entries */
+ ddBufferPtr pBuffer; /* table entries */
+{
+ ddLUTResource lut;
+ ddpex43rtn err43;
+ unsigned long hdrSiz = pBuffer->pBuf - pBuffer->pHead;
+ unsigned long dataSiz = 0;
+ int reply_size = entry_size[LUTtype] * count;
+ int i;
+ ddUSHORT status;
+
+#ifdef DDTEST
+ ErrorF( "\nInquireLUTPredEntries type %d\n", LUTtype);
+#endif
+
+ *pNumEntries = 0;
+ pBuffer->dataSize = 0;
+
+ /*
+ * reply_size is an upper-bound on the size of the stuff that
+ * will actually be returned, so once we do this, InquireLUTEntry
+ * shouldn't have to reallocate the buffer
+ */
+ PU_CHECK_BUFFER_SIZE(pBuffer, reply_size);
+
+ /*
+ * CreateLUT and InquireLUTEntries have a lot of smarts about
+ * predefined entries and default entries, so use them.
+ */
+ lut.id = 0;
+ lut.lutType = LUTtype;
+ if ((err43 = CreateLUT(pDrawable, &lut)) != Success)
+ return (err43);
+
+ /* see if start and count are in range of predefined entries
+ * or if entry 0 is requested for table which doesn't use 0
+ */
+#if 0
+ if (( start < MILUT_PREMIN(MILUT_HEADER(&lut)) ) ||
+ ( (start + count - 1) > MILUT_PREMAX(MILUT_HEADER(&lut)) ) ||
+ ( !start && MILUT_START_INDEX(MILUT_HEADER(&lut)) ))
+ {
+ MILUT_DESTROY_HEADER((miLUTHeader *) lut.deviceData);
+ return(BadValue);
+ }
+#endif
+
+ for (i = 0; i < count; i++)
+ {
+ /* call get entry op instead of calling InquireLUTEntry */
+ err43 = MILUT_HEADER(&lut)->ops[MILUT_REQUEST_OP(PEX_GetTableEntry)]
+ (&lut, i + start, PEXSetValue, &status, pBuffer);
+
+ if (err43 != Success)
+ {
+ /* reset data buffer pointer */
+ pBuffer->pBuf = pBuffer->pHead + hdrSiz;
+ pBuffer->dataSize = 0;
+ return (err43);
+ }
+
+ /*
+ * move data buffer pointer to put next entry after the one just
+ * gotten
+ */
+ dataSiz += pBuffer->dataSize;
+ pBuffer->pBuf = pBuffer->pHead + hdrSiz + dataSiz;
+ }
+
+ /* reset data buffer pointer */
+ pBuffer->pBuf = pBuffer->pHead + hdrSiz;
+ pBuffer->dataSize = dataSiz;
+ *pNumEntries = count;
+
+ MILUT_DESTROY_HEADER((miLUTHeader *) lut.deviceData);
+
+ return (Success);
+} /* InquireLUTPredEntries */
+
+
+/*++
+ |
+ | Function Name: InquireLUTIndices
+ |
+ | Function Description:
+ | Handles the PEXGetDefinedIndices request.
+ |
+ | Note(s):
+ dipex checks for bad lut
+ |
+ --*/
+
+ddpex43rtn
+InquireLUTIndices(pLUT, pNumIndices, pBuffer)
+/* in */
+ diLUTHandle pLUT; /* lut handle */
+/* out */
+ ddULONG *pNumIndices; /* number of indices in list */
+ ddBufferPtr pBuffer; /* list of table indices */
+{
+#ifdef DDTEST
+ ErrorF( "\nInquireLUTIndices %d type %d\n", pLUT->id, pLUT->lutType);
+#endif
+
+ *pNumIndices = 0;
+ return(MILUT_HEADER(pLUT)->ops[MILUT_REQUEST_OP(PEX_GetDefinedIndices)]
+ (pLUT, pNumIndices, pBuffer));
+} /* InquireLUTIndices */
+
+
+
+/*++
+ |
+ | Function Name: InquireLUTEntry
+ |
+ | Function Description:
+ | Handles the PEXGetTableEntry request.
+ |
+ | Note(s):
+ dipex checks for bad lut
+ |
+ --*/
+
+ddpex43rtn
+InquireLUTEntry(pLUT, index, valueType, pStatus, pBuffer)
+/* in */
+ diLUTHandle pLUT; /* lut handle */
+ ddTableIndex index; /* index of entry to get */
+ ddUSHORT valueType; /* SET or REALIZED */
+/* out */
+ ddUSHORT *pStatus; /* entry status */
+ ddBufferPtr pBuffer; /* table entry */
+{
+#ifdef DDTEST
+ ErrorF( "\nInquireLUTEntry %d type %d\n", pLUT->id, pLUT->lutType);
+#endif
+
+ *pStatus = PEXDefaultEntry;
+ pBuffer->dataSize = 0;
+
+ /* see if entry 0 is requested for table which doesn't use 0 */
+ if (!index && MILUT_START_INDEX(MILUT_HEADER(pLUT)))
+ return(BadValue);
+
+ if ((valueType != PEXRealizedValue) && (valueType != PEXSetValue))
+ return(BadValue);
+
+ return(MILUT_HEADER(pLUT)->ops[MILUT_REQUEST_OP(PEX_GetTableEntry)]
+ (pLUT, index, valueType, pStatus, pBuffer));
+} /* InquireLUTEntry */
+
+
+/*++
+ |
+ | Function Name: InquireLUTEntries
+ |
+ | Function Description:
+ | Handles the PEXGetTableEntries request.
+ |
+ | Note(s):
+ dipex checks for bad lut
+ |
+ --*/
+
+ddpex43rtn
+InquireLUTEntries(pLUT, start, count, valueType, pNumEntries, pBuffer)
+/* in */
+ diLUTHandle pLUT; /* lut handle */
+ ddTableIndex start; /* index of first entry to get */
+ ddUSHORT count; /* number of entries requested */
+ ddUSHORT valueType; /* SET or REALIZED */
+/* out */
+ ddULONG *pNumEntries; /* number of entries in list */
+ ddBufferPtr pBuffer; /* list of table entries */
+{
+ unsigned long hdrSiz = pBuffer->pBuf - pBuffer->pHead;
+ unsigned long dataSiz = 0;
+ int reply_size = entry_size[MILUT_TYPE(pLUT)] * count;
+ int i;
+ ddUSHORT status;
+ ddpex43rtn err;
+
+ /*
+ * reply_size is an upper-bound on the size of the stuff that
+ * will actually be returned, so once we do this, InquireLUTEntry
+ * shouldn't have to reallocate the buffer
+ */
+
+ *pNumEntries = 0;
+ PU_CHECK_BUFFER_SIZE(pBuffer, reply_size);
+
+ /* see if entry 0 is requested for table which doesn't use 0
+ * or if start + count is greater than 65535
+ */
+ if ((!start && MILUT_START_INDEX(MILUT_HEADER(pLUT))) ||
+ ((ddULONG)(start + count) > MILUT_MAX_INDEX))
+ return(BadValue);
+
+ if ((valueType != PEXRealizedValue) && (valueType != PEXSetValue))
+ return(BadValue);
+
+ for (i = 0; i < count; i++)
+ {
+ /* call get entry op instead of calling InquireLUTEntry */
+ err = MILUT_HEADER(pLUT)->ops[MILUT_REQUEST_OP(PEX_GetTableEntry)]
+ (pLUT, i + start, valueType, &status, pBuffer);
+
+ if (err != Success)
+ {
+ /* reset data buffer pointer */
+ pBuffer->pBuf = pBuffer->pHead + hdrSiz;
+ pBuffer->dataSize = 0;
+ return (err);
+ }
+
+ /*
+ * move data buffer pointer to put next entry after the one just
+ * gotten
+ */
+ dataSiz += pBuffer->dataSize;
+ pBuffer->pBuf = pBuffer->pHead + hdrSiz + dataSiz;
+ }
+
+ /* reset data buffer pointer */
+ pBuffer->pBuf = pBuffer->pHead + hdrSiz;
+ pBuffer->dataSize = dataSiz;
+ *pNumEntries = count;
+
+ return (Success);
+} /* InquireLUTEntries */
+
+
+/*++
+ |
+ | Function Name: SetLUTEntries
+ |
+ | Function Description:
+ | Handles the PEXSetTableEntries request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex43rtn
+SetLUTEntries(pLUT, start, numEntries, pEntries)
+/* in */
+ diLUTHandle pLUT; /* lut handle */
+ ddTableIndex start; /* index of first entry to set */
+ ddUSHORT numEntries; /* number of entries to set */
+ ddPointer pEntries; /* list of entries */
+{
+
+#ifdef DDTEST
+ ErrorF( "\nSetLUTEntries %d type %d\n", pLUT->id, pLUT->lutType);
+#endif
+
+ /* see if entry 0 is requested for table which doesn't use 0
+ * or if start + count is greater than 65535
+ */
+ if ((!start && MILUT_START_INDEX(MILUT_HEADER(pLUT))) ||
+ ((ddULONG)(start + numEntries) > MILUT_MAX_INDEX))
+ return(BadValue);
+
+ return(MILUT_HEADER(pLUT)->ops[MILUT_REQUEST_OP(PEX_SetTableEntries)]
+ (pLUT, start, numEntries, pEntries));
+} /* SetLUTEntries */
+
+
+/*++
+ |
+ | Function Name: DeleteLUTEntries
+ |
+ | Function Description:
+ | Handles the PEXDeleteTableEntries request.
+ |
+ | Note(s):
+ |
+ --*/
+
+#define SETSTATUS( ptr, value ) \
+ for ( i=start; i<end; i++, (ptr)++ ) \
+ (ptr)->entry_info.status = (value)
+
+ddpex43rtn
+DeleteLUTEntries(pLUT, start, numEntries)
+/* in */
+ diLUTHandle pLUT; /* lut handle */
+ ddUSHORT start; /* index of first entry to delete */
+ ddUSHORT numEntries; /* number of entries in range */
+/* out */
+{
+
+#ifdef DDTEST
+ ErrorF( "\nDeleteLUTEntries %d type %d\n", pLUT->id, pLUT->lutType);
+#endif
+
+ /* see if start + count is greater than 65535
+ * or if entry 0 is requested for table which doesn't use 0
+ */
+ if (( (ddULONG)(numEntries + start) > MILUT_MAX_INDEX ) ||
+ ( !start && MILUT_START_INDEX(MILUT_HEADER(pLUT)) ))
+ return(BadValue);
+
+ return(MILUT_HEADER(pLUT)->ops[MILUT_REQUEST_OP(PEX_DeleteTableEntries)]
+ (pLUT, start, numEntries));
+} /* DeleteLUTEntries */
+
+
+/*++
+ |
+ | Function Name: UpdateLUTRefs
+ |
+ | Function Description:
+ | A utility procedure for updating the cross-reference lists in the
+ | lookup table. The lookup table has two lists, one for renderers and
+ | one for workstations. These lists tell which resources are using the
+ | table. Deletes the resource if it's been freed and is not referenced.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex43rtn
+UpdateLUTRefs(pLUT, pResource, which, action)
+/* in */
+ diLUTHandle pLUT; /* lut handle */
+ diResourceHandle pResource;/* workstation or renderer handle */
+ ddResourceType which; /* workstation or renderer */
+ ddAction action; /* add or remove */
+/* out */
+{
+ register miLUTHeader *pheader = (miLUTHeader *) pLUT->deviceData;
+
+#ifdef DDTEST
+ ErrorF( "\nUpdateLUTRefs %d type %d\n", pLUT->id, pLUT->lutType);
+#endif
+
+ switch (which)
+ {
+ case WORKSTATION_RESOURCE:
+ if (action == ADD)
+ {
+ if (puAddToList((ddPointer) &pResource, (ddULONG) 1, pheader->wksRefList) == MI_ALLOCERR)
+ return (BadAlloc);
+ } else
+ puRemoveFromList((ddPointer) &pResource, pheader->wksRefList);
+ break;
+
+ case RENDERER_RESOURCE:
+ if (action == ADD)
+ {
+ if (puAddToList((ddPointer) &pResource, (ddULONG) 1, pheader->rendRefList) == MI_ALLOCERR)
+ return (BadAlloc);
+ } else
+ puRemoveFromList((ddPointer) &pResource, pheader->rendRefList);
+ break;
+
+ default: /* better not get here */
+ return (BadValue);
+ break;
+ }
+
+ MILUT_CHECK_DESTROY(pLUT, pheader);
+ return (Success);
+} /* UpdateLUTRefs */
+
+/*++
+ |
+ | Function Name: MatchLUTDrawable
+ |
+ | Function Description:
+ | A utility procedure for comparing a drawable with the
+ drawable example of an LUT. Returns BadMatch if they
+ are not compatible.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex43rtn
+MatchLUTDrawable(pLUT, pDrawable)
+ diLUTHandle pLUT;
+ DrawablePtr pDrawable;
+{
+ register miLUTHeader *pheader = (miLUTHeader *) pLUT->deviceData;
+
+ if ( (pheader->drawExample.type == pDrawable->type) &&
+ (pheader->drawExample.depth == pDrawable->depth) &&
+ (pheader->drawExample.rootDepth == pDrawable->pScreen->rootDepth) &&
+ (pheader->drawExample.rootVisual == pDrawable->pScreen->rootVisual) )
+ return(Success);
+ else
+ return(BadMatch);
+}
+
+static void
+InitializePDEs()
+{
+extern void LineBundleLUT_init_pde();
+extern void MarkerBundleLUT_init_pde();
+extern void TextBundleLUT_init_pde();
+extern void InteriorBundleLUT_init_pde();
+extern void EdgeBundleLUT_init_pde();
+extern void PatternLUT_init_pde();
+extern void TextFontLUT_init_pde();
+extern void ColourLUT_init_pde();
+extern void ViewLUT_init_pde();
+extern void LightLUT_init_pde();
+extern void DepthCueLUT_init_pde();
+extern void ColourApproxLUT_init_pde();
+
+ LineBundleLUT_init_pde();
+ MarkerBundleLUT_init_pde();
+ TextBundleLUT_init_pde();
+ InteriorBundleLUT_init_pde();
+ EdgeBundleLUT_init_pde();
+ PatternLUT_init_pde();
+ TextFontLUT_init_pde();
+ ColourLUT_init_pde();
+ ViewLUT_init_pde();
+ LightLUT_init_pde();
+ DepthCueLUT_init_pde();
+ ColourApproxLUT_init_pde();
+}
+
+extern ddpex43rtn LineBundleLUT_inq_entry_address(),
+ MarkerBundleLUT_inq_entry_address(),
+ TextBundleLUT_inq_entry_address(),
+ InteriorBundleLUT_inq_entry_address(),
+ EdgeBundleLUT_inq_entry_address(),
+ PatternLUT_inq_entry_address(),
+ TextFontLUT_inq_entry_address(),
+ ColourLUT_inq_entry_address(),
+ ViewLUT_inq_entry_address(),
+ LightLUT_inq_entry_address(),
+ DepthCueLUT_inq_entry_address(),
+ ColourApproxLUT_inq_entry_address();
+
+miOpsTableType inq_entry_address_LUTtable[] = {
+ LineBundleLUT_inq_entry_address,
+ MarkerBundleLUT_inq_entry_address,
+ TextBundleLUT_inq_entry_address,
+ InteriorBundleLUT_inq_entry_address,
+ EdgeBundleLUT_inq_entry_address,
+ PatternLUT_inq_entry_address,
+ TextFontLUT_inq_entry_address,
+ ColourLUT_inq_entry_address,
+ ViewLUT_inq_entry_address,
+ LightLUT_inq_entry_address,
+ DepthCueLUT_inq_entry_address,
+ ColourApproxLUT_inq_entry_address,
+};
+
+ddpex43rtn
+InquireLUTEntryAddress(LUTtype, pLUT, index, pStatus, ppEntry)
+/* in */
+ ddUSHORT LUTtype; /* lookup table type */
+ diLUTHandle pLUT; /* lut handle */
+ ddTableIndex index; /* index of entry to get */
+/* out */
+ ddUSHORT *pStatus; /* entry status */
+ ddPointer *ppEntry; /* table entry */
+{
+#ifdef DDTEST
+ ErrorF( "\nInquireLUTEntryAddress %d type \n", LUTtype);
+#endif
+
+ return(inq_entry_address_LUTtable[LUTtype-1]
+ (LUTtype, pLUT, index, pStatus, ppEntry));
+} /* InquireLUTEntryAddress */
+
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/shared/miLUTProcs.ci b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miLUTProcs.ci
new file mode 100644
index 000000000..10672b6ac
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miLUTProcs.ci
@@ -0,0 +1,658 @@
+/* $TOG: miLUTProcs.ci /main/6 1998/02/10 13:59:50 kaleb $ */
+/*
+
+Copyright 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+ of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS 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 MILUT_PROCS_CI
+#define MILUT_PROCS_CI
+
+#include "pexUtils.h"
+
+/* this file is a template for defining the lut procedures */
+/* it uses a bunch of macros (blah) but allows easier porting */
+/* the following macros must be defined in the file which includes
+ * this one before this file is included:
+ * LUT_TYPE the table type
+ * LUT_TABLE_START pointer to the first entry in the table
+ * LUT_PDE_ENTRIES the beginning of the predefined entries table
+ * LUT_SET_PDE_ENTRY macro which sets an entry to a predefined
+ * value
+ * LUT_SET_DEFAULT_VALUES macro which sets an entry to the default
+ * values
+ * data structure names:
+ * DD_LUT_ENTRY_STR devPriv data structure def
+ * MI_LUT_ENTRY_STR table entry data structure def
+ * PEX_LUT_ENTRY_STR pex data structure def
+ * renderer dynamics changes bit:
+ * LUT_REND_DYN_BIT
+ * table info:
+ * LUT_START_INDEX
+ * LUT_DEFAULT_INDEX
+ * table info dependent on drawable type (SI only supports one type):
+ * LUT_0_DEFINABLE_ENTRIES
+ * LUT_0_NUM_PREDEFINED
+ * LUT_0_PREDEFINED_MIN
+ * LUT_0_PREDEFINED_MAX
+ *
+ * procedure definition flags:
+ * define the ones whose definitions you want to use from this file
+ * procedure definition names:
+ * define the names of the procedures to use for the lut
+ */
+
+extern ddpex4rtn miDealWithDynamics(); /* in level4/miDynamics.c */
+
+/* get pointer to first legal entry in the table */
+#define FIRST_ENTRY( pheader ) \
+ LUT_TABLE_START(pheader)
+
+#define SET_TABLE_INFO( drawType, pInfo ) \
+ switch(drawType) { \
+ case MI_DRAWABLE0: \
+ (pInfo)->definableEntries = \
+ LUT_0_DEFINABLE_ENTRIES; \
+ (pInfo)->numPredefined = \
+ LUT_0_NUM_PREDEFINED; \
+ (pInfo)->predefinedMin = \
+ LUT_0_PREDEFINED_MIN; \
+ (pInfo)->predefinedMax = \
+ LUT_0_PREDEFINED_MAX; \
+ break; }
+
+/* the following procedure definitions are useful for all SI lut types */
+/* replace them in the mi*LUT.c files if these are not appropriate */
+
+/* don't use special procs for these - use the general ones called
+ * directly by diPEX */
+
+#ifdef LUT_USE_FREE
+extern ddpex43rtn FreeLUT();
+#define LUT_FREE FreeLUT
+#endif /* LUT_USE_FREE */
+
+#ifdef LUT_USE_INQ_PREDEF
+extern ddpex43rtn InquireLUTPredEntries();
+#define LUT_INQ_PREDEF InquireLUTPredEntries
+#endif /* LUT_USE_INQ_PREDEF */
+
+#ifdef LUT_USE_INQ_ENTRIES
+extern ddpex43rtn InquireLUTEntries();
+#define LUT_INQ_ENTRIES InquireLUTEntries
+#endif /* LUT_USE_INQ_ENTRIES */
+
+/*
+ The default entry: uninitialized, non-static, this scratch
+ structure is kept around so that we can fill it with default
+ data and return its address from routines like those made
+ from LUT_INQ_ENTRY_ADDRESS
+ */
+static MI_LUT_ENTRY_STR def_entry;
+
+
+
+#ifdef LUT_USE_COPY
+ddpex43rtn
+LUT_COPY (pSrcLUT, pDestLUT)
+/* in */
+ diLUTHandle pSrcLUT; /* source lookup table */
+ diLUTHandle pDestLUT; /* destination lookup table */
+/* out */
+{
+ MILUT_DEFINE_HEADER(pSrcLUT, srcHeader);
+ MILUT_DEFINE_HEADER(pDestLUT, destHeader);
+ MI_LUT_ENTRY_STR *pentry;
+ ddpex43rtn err;
+ register int i;
+
+#ifdef DDTEST
+ ErrorF( "\ncopy src lut %d type %d\n", pSrcLUT->id, pSrcLUT->lutType);
+ ErrorF( "\ncopy dest lut %d type %d\n", pDestLUT->id, pDestLUT->lutType);
+#endif
+
+ /* set all entries to undefined */
+ pentry = LUT_TABLE_START(destHeader);
+ MILUT_SET_STATUS(pentry, MILUT_ALLOC_ENTS(destHeader), MILUT_UNDEFINED, MI_FALSE);
+
+ /* copy entries */
+ mibcopy(LUT_TABLE_START(srcHeader), LUT_TABLE_START(destHeader),
+ sizeof(MI_LUT_ENTRY_STR) * MILUT_ALLOC_ENTS(srcHeader));
+
+ MILUT_NUM_ENTS(destHeader) = MILUT_NUM_ENTS(srcHeader);
+
+ err = destHeader->ops[MILUT_REQUEST_OP(milut_mod_call_back)](pDestLUT,
+ MILUT_START_INDEX(destHeader), MILUT_DEF_ENTS(destHeader), MILUT_COPY_MOD);
+ /* check err here if your call back proc can return an error */
+
+ return (err);
+}
+#endif /* LUT_USE_COPY */
+
+#ifdef LUT_USE_INQ_INFO
+ddpex43rtn
+LUT_INQ_INFO (pDrawable, pLUTinfo)
+/* in */
+ DrawablePtr pDrawable;/* pointer to example drawable */
+/* out */
+ ddTableInfo *pLUTinfo; /* table information */
+{
+ ddSHORT drawtype;
+
+#ifdef DDTEST
+ ErrorF( "\ninquire info, table type %d \n", LUT_TYPE );
+#endif
+
+ MI_WHICHDRAW(pDrawable, drawtype);
+ SET_TABLE_INFO( drawtype, pLUTinfo );
+
+ return (Success);
+}
+#endif /* LUT_USE_INQ_INFO */
+
+#ifdef LUT_USE_INQ_IND
+ddpex43rtn
+LUT_INQ_IND (pLUT, pNumIndices, pBuffer)
+/* in */
+ diLUTHandle pLUT; /* lut handle */
+/* out */
+ ddULONG *pNumIndices; /* number of indices in list */
+ ddBufferPtr pBuffer; /* list of table indices */
+{
+ MILUT_DEFINE_HEADER(pLUT, pheader);
+ register ddUSHORT macks; /* number of definable entries */
+ register ddTableIndex *pb;
+ MI_LUT_ENTRY_STR *pentry;
+
+#ifdef DDTEST
+ ErrorF( "\n inquire indices lut %d type %d\n", pLUT->id, pLUT->lutType);
+#endif
+
+ PU_CHECK_BUFFER_SIZE(pBuffer,MILUT_NUM_ENTS(pheader) * sizeof(ddTableIndex));
+ *pNumIndices = MILUT_NUM_ENTS(pheader);
+ pBuffer->dataSize = *pNumIndices * sizeof(ddTableIndex);
+ pb = (ddTableIndex *)(pBuffer->pBuf);
+
+ pentry = FIRST_ENTRY(pheader);
+
+ for ( macks = MILUT_DEF_ENTS(pheader);
+ macks > 0; macks--, pentry++ )
+ if (pentry->entry_info.status != MILUT_UNDEFINED)
+ *pb++ = pentry->entry_info.index;
+
+ return (Success);
+}
+#endif /* LUT_USE_INQ_IND */
+
+#ifdef LUT_USE_INQ_ENTRY
+ddpex43rtn
+LUT_INQ_ENTRY (pLUT, index, valueType, pStatus, pBuffer)
+/* in */
+ diLUTHandle pLUT; /* lut handle */
+ ddTableIndex index; /* index of entry to get */
+ ddUSHORT valueType; /* SET or REALIZED */
+/* out */
+ ddUSHORT *pStatus; /* entry status */
+ ddBufferPtr pBuffer; /* table entry */
+{
+ MILUT_DEFINE_HEADER(pLUT, pheader);
+ MI_LUT_ENTRY_STR *pentry, *plast;
+ ddPointer pb;
+
+#ifdef DDTEST
+ ErrorF( "\ninquire entry lut %d type %d\n", pLUT->id, pLUT->lutType);
+#endif
+
+ PU_CHECK_BUFFER_SIZE(pBuffer, sizeof(PEX_LUT_ENTRY_STR));
+
+ pentry = FIRST_ENTRY(pheader);
+ plast = pentry + MILUT_DEF_ENTS(pheader);
+
+ MILUT_GET_ENTRY(index, pentry, plast);
+
+ if ((pentry == NULL) || (pentry->entry_info.status == MILUT_UNDEFINED))
+ {
+ *pStatus = PEXDefaultEntry;
+ pentry = FIRST_ENTRY(pheader);
+ MILUT_GET_ENTRY(MILUT_DEFAULT_INDEX(pheader), pentry, plast);
+ if (pentry == NULL)
+ {
+ /* default entry doesn't exist - get the default values */
+ LUT_SET_DEFAULT_VALUES(&def_entry);
+ pentry = &def_entry;
+ }
+ else if (pentry->entry_info.status == MILUT_UNDEFINED)
+ {
+ /* default entry is undefined - get default values */
+ LUT_SET_DEFAULT_VALUES(&def_entry);
+ pentry = &def_entry;
+ }
+ } else
+ *pStatus = PEXDefinedEntry;
+
+ pb = pBuffer->pBuf;
+
+ pheader->ops[MILUT_REQUEST_OP(milut_copy_mi_to_pex)](pheader, valueType, pentry, &pb);
+
+ pBuffer->dataSize = pb - pBuffer->pBuf;
+
+ return (Success);
+}
+#endif /* LUT_USE_INQ_ENTRY */
+
+#ifdef LUT_USE_SET_ENTRIES
+ddpex43rtn
+LUT_SET_ENTRIES (pLUT, start, numEntries, pEntries)
+/* in */
+ diLUTHandle pLUT; /* lut handle */
+ ddTableIndex start; /* index of first entry to set */
+ ddUSHORT numEntries; /* number of entries to set */
+ ddPointer pEntries; /* list of entries */
+{
+ MILUT_DEFINE_HEADER(pLUT, pheader);
+ MI_LUT_ENTRY_STR *pentry, *plast, *psave;
+ PEX_LUT_ENTRY_STR *psrc;
+ register int i;
+ int freecount1 = 0, freecount2;
+ ddpex43rtn err;
+ ddPointer ps;
+
+#ifdef DDTEST
+ ErrorF( "\nset entries lut %d type %d\n", pLUT->id, pLUT->lutType);
+#endif
+
+ psrc = (PEX_LUT_ENTRY_STR *) pEntries;
+ pentry = FIRST_ENTRY(pheader);
+ plast = pentry + MILUT_DEF_ENTS(pheader);
+
+ /* check for a place to put the entries and check them for errors */
+ /* this is set up to work for tables with contiguous index
+ * values most efficiently. it will work for sparse tables, too
+ */
+ for (i = start; i < (start + numEntries); i++)
+ {
+ /* starting at current pentry, see if entry 'i' is after it */
+ psave = pentry;
+ MILUT_GET_ENTRY(i, pentry, plast);
+
+ if (!pentry)
+ {
+ /* make sure the entry wasn't before pentry
+ * by starting at the beginning and looking until where
+ * pentry was (psave)
+ */
+ pentry = FIRST_ENTRY(pheader);
+ MILUT_GET_ENTRY(i, pentry, psave);
+ if (!pentry)
+ {
+ /* no entry defined with this index
+ * put one in by looking for the first
+ * undefined entry. this has no intelligence
+ * about it
+ */
+ pentry = FIRST_ENTRY(pheader);
+ plast = pentry + MILUT_DEF_ENTS(pheader);
+ freecount2 = freecount1;
+ while ((pentry < plast) &&
+ ((pentry->entry_info.status != MILUT_UNDEFINED) || freecount2))
+ {
+ if (pentry->entry_info.status == MILUT_UNDEFINED)
+ freecount2--;
+ pentry++;
+ }
+ if (pentry == plast)
+ /* couldn't find a place for it */
+ return(BadAlloc);
+ else
+ /* keep count of free places found so far */
+ freecount1++;
+ }
+ }
+ /* check the entry and increment the source pointer */
+ if ((err = pheader->ops[MILUT_REQUEST_OP(milut_entry_check)](pheader, &psrc)) != Success)
+ return(err);
+ }
+
+ psrc = (PEX_LUT_ENTRY_STR *) pEntries;
+ for (i = start; i < (start + numEntries); i++)
+ {
+ /* starting at current pentry, see if entry 'i' is after it */
+ psave = pentry;
+ MILUT_GET_ENTRY(i, pentry, plast);
+
+ if (!pentry)
+ {
+ /* make sure the entry wasn't before pentry
+ * by starting at the beginning and looking until where
+ * pentry was (psave)
+ */
+ pentry = FIRST_ENTRY(pheader);
+ MILUT_GET_ENTRY(i, pentry, psave);
+ if (!pentry)
+ {
+ /* no entry defined with this index
+ * put one in by looking for the first
+ * undefined entry. this has no intelligence
+ * about it
+ */
+ pentry = FIRST_ENTRY(pheader);
+ plast = pentry + MILUT_DEF_ENTS(pheader);
+ while ((pentry < plast) &&
+ (pentry->entry_info.status != MILUT_UNDEFINED))
+ pentry++;
+ if (pentry == plast)
+ /* this shouldn't happen since it was
+ * checked above, but just in case..
+ * this is where one of those ASSURE
+ * tests can be useful
+ */
+ return(BadAlloc);
+ }
+ }
+
+ if (pentry->entry_info.status == MILUT_UNDEFINED)
+ MILUT_NUM_ENTS(pheader)++;
+ pentry->entry_info.status = MILUT_DEFINED;
+ pentry->entry_info.index = i;
+
+ ps = (ddPointer)psrc;
+ pheader->ops[MILUT_REQUEST_OP(milut_copy_pex_to_mi)](pheader, &ps, pentry);
+
+ psrc = (PEX_LUT_ENTRY_STR *)ps;
+ }
+
+ err = pheader->ops[MILUT_REQUEST_OP(milut_mod_call_back)](pLUT,
+ start, numEntries, MILUT_SET_MOD);
+
+ /* check err here if your call back proc can return an error */
+
+ return (err);
+}
+#endif /* LUT_USE_SET_ENTRIES */
+
+#ifdef LUT_USE_DEL_ENTRIES
+ddpex43rtn
+LUT_DEL_ENTRIES (pLUT, start, numEntries)
+/* in */
+ diLUTHandle pLUT; /* lut handle */
+ ddUSHORT start; /* index of first entry to delete */
+ ddUSHORT numEntries; /* number of entries in range */
+/* out */
+{
+ MILUT_DEFINE_HEADER(pLUT, pheader);
+ MI_LUT_ENTRY_STR *pentry, *plast, *psave;
+ ddpex43rtn err;
+
+#ifdef DDTEST
+ ErrorF( "\ndelete entries lut %d type %d\n", pLUT->id, pLUT->lutType);
+#endif
+
+ pentry = FIRST_ENTRY(pheader);
+ plast = pentry + MILUT_DEF_ENTS(pheader);
+
+ /* invoke the call back before deleting the entries and changing
+ start and numEntries
+ */
+ err = pheader->ops[MILUT_REQUEST_OP(milut_mod_call_back)](pLUT,
+ start, numEntries, MILUT_DEL_MOD);
+
+ /* loop through and set each entry to undefined
+ * this works most efficiently if the entries are stored
+ * in the lut contiguously since MILUT_GET_ENTRY starts
+ * where pentry points then searches forward colour_approxarly
+ */
+ for (; numEntries > 0; start++, numEntries--)
+ {
+ psave = pentry;
+ MILUT_GET_ENTRY(start, pentry, plast);
+
+ if (!pentry)
+ {
+ /* make sure the entry wasn't before pentry */
+ pentry = FIRST_ENTRY(pheader);
+ MILUT_GET_ENTRY(start, pentry, psave);
+ }
+
+ if (pentry)
+ {
+ if (pentry->entry_info.status != MILUT_UNDEFINED)
+ {
+ MILUT_NUM_ENTS(pheader)--;
+ pentry->entry_info.status = MILUT_UNDEFINED;
+ }
+ }
+ else
+ pentry = psave;
+ }
+
+ /* check err here if your call back proc can return an error */
+
+ return (err);
+}
+#endif /* LUT_USE_DEL_ENTRIES */
+
+#ifdef LUT_USE_INQ_ENTRY_ADDRESS
+ddpex43rtn
+LUT_INQ_ENTRY_ADDRESS (LUTtype, pLUT, index, pStatus, ppEntry)
+/* in */
+ ddUSHORT LUTtype; /* lookup table type use this if pLUT is NULL */
+ diLUTHandle pLUT; /* lut handle */
+ ddTableIndex index; /* index of entry to get */
+/* out */
+ ddUSHORT *pStatus; /* entry status */
+ ddPointer *ppEntry; /* table entry */
+{
+ miLUTHeader *pheader;
+ MI_LUT_ENTRY_STR *pentry, *plast;
+
+#ifdef DDTEST
+ ErrorF( "\ninquire entry address lut type %d\n", LUTtype);
+#endif
+
+ pentry = NULL;
+
+ if (!pLUT)
+ {
+ /* get the default values */
+ LUT_SET_DEFAULT_VALUES(&def_entry);
+ *ppEntry = (ddPointer)&def_entry;
+ return (Success);
+ }
+
+ pheader = MILUT_HEADER(pLUT);
+ pentry = FIRST_ENTRY(pheader);
+ plast = pentry + MILUT_DEF_ENTS(pheader);
+
+ MILUT_GET_ENTRY(index, pentry, plast);
+ if ((pentry == NULL) || (pentry->entry_info.status == MILUT_UNDEFINED))
+ {
+ /* get the default entry */
+ *pStatus = PEXDefaultEntry;
+ pentry = FIRST_ENTRY(pheader);
+ MILUT_GET_ENTRY(MILUT_DEFAULT_INDEX(pheader), pentry, plast);
+ if (pentry == NULL)
+ {
+ /* default entry doesn't exist - get the default values */
+ LUT_SET_DEFAULT_VALUES(&def_entry);
+ *ppEntry = (ddPointer)&def_entry;
+ }
+ else if (pentry->entry_info.status == MILUT_UNDEFINED)
+ {
+ /* default entry is undefined - get default values */
+ LUT_SET_DEFAULT_VALUES(&def_entry);
+ *ppEntry = (ddPointer)&def_entry;
+ }
+ else /* the default entry is good */
+ *ppEntry = (ddPointer)pentry;
+ } else /* the entry was found and is defined */
+ {
+ *pStatus = PEXDefinedEntry;
+ *ppEntry = (ddPointer)pentry;
+ }
+
+ return (Success);
+}
+#endif /* LUT_USE_INQ_ENTRY_ADDRESS */
+
+#ifdef LUT_USE_MOD_CALL_BACK
+ddpex43rtn
+LUT_MOD_CALL_BACK(pLUT, start, numEntries, mod)
+ diLUTHandle pLUT;
+ ddTableIndex start; /* index of first entry to set */
+ ddUSHORT numEntries; /* number of entries to set */
+ ddUSHORT mod; /* modification: copy, set, delete */
+{
+ MILUT_DEFINE_HEADER(pLUT, pheader);
+ register int i;
+ ddRendererPtr *pprend;
+ diWKSHandle *phandle;
+ miWksPtr pwks;
+ ddpex43rtn err;
+
+ /* set change flags in renderer so ValidateRenderer will
+ * know to update the ddContext with changes
+ * add to here and calls to hardware, etc. to realize
+ * modifications
+ */
+ pprend = (ddRendererPtr *)pheader->rendRefList->pList;
+ for (i=0; i<pheader->rendRefList->numObj; i++, pprend++)
+ (*pprend)->tablesChanges |= LUT_REND_DYN_BIT;
+
+ /* for view luts: this wks list only identifies the wks for
+ * which this is the current view. The wks is not included
+ * in the list of the requested view lut
+ */
+ if (pheader->wksRefList->numObj)
+ {
+ phandle = (diWKSHandle *)pheader->wksRefList->pList;
+ for (i=0; i<pheader->wksRefList->numObj; i++, phandle++)
+ {
+ pwks = (miWksPtr)((*phandle)->deviceData);
+ pwks->pRend->tablesChanges |= LUT_REND_DYN_BIT;
+ }
+ }
+
+ err = Success;
+
+#ifdef DYNAMIC
+ if (pheader->wksRefList->numObj)
+ err = miDealWithDynamics( DYNAMIC, pheader->wksRefList );
+#endif /* DYNAMIC */
+
+ return( err );
+}
+#endif /* LUT_USE_MOD_CALL_BACK */
+
+
+#ifdef LUT_USE_CREATE
+ddpex43rtn
+LUT_CREATE (pLUT, pheader)
+/* in */
+ diLUTHandle pLUT; /* lut handle */
+ miLUTHeader *pheader; /* lut header */
+/* out */
+{
+ register int i;
+ MI_LUT_ENTRY_STR *pentry;
+ DD_LUT_ENTRY_STR *pdeentry;
+
+#ifdef DDTEST
+ ErrorF( "\ncreate lut %d type %d\n", pLUT->id, pLUT->lutType);
+#endif
+
+ MILUT_START_INDEX(pheader) = LUT_START_INDEX;
+ MILUT_DEFAULT_INDEX(pheader) = LUT_DEFAULT_INDEX;
+ MILUT_NUM_ENTS(pheader) = 0;
+ SET_TABLE_INFO( pheader->drawType, &(pheader->tableInfo) );
+
+ if (MILUT_ALLOC_ENTS(pheader) == 0)
+ {
+ LUT_TABLE_START(pheader) = NULL;
+ }
+ else if ( (LUT_TABLE_START(pheader) = (MI_LUT_ENTRY_STR *)
+ xalloc(MILUT_ALLOC_ENTS(pheader) * sizeof(MI_LUT_ENTRY_STR)) )
+ == NULL)
+ {
+ MILUT_DESTROY_HEADER(pheader);
+ return(BadAlloc);
+ }
+
+ pentry = LUT_TABLE_START(pheader);
+ MILUT_SET_STATUS(pentry, MILUT_ALLOC_ENTS(pheader), MILUT_UNDEFINED, MI_TRUE);
+
+ /* if there are predefined entries, put them in */
+ if (MILUT_PRENUM(pheader))
+ {
+ pentry = LUT_TABLE_START(pheader) + MILUT_PREMIN(pheader);
+ pdeentry = &(LUT_PDE_ENTRIES);
+
+ for (i=MILUT_PREMIN(pheader);
+ i<=MILUT_PREMAX(pheader); i++, pentry++, pdeentry++)
+ {
+ pentry->entry_info.status = MILUT_PREDEFINED;
+ pentry->entry_info.index = i;
+ LUT_SET_PDE_ENTRY(pentry, pdeentry);
+ pheader->numDefined++;
+ }
+ }
+
+ pheader->ops[MILUT_REQUEST_OP(PEX_CreateLookupTable)] = LUT_CREATE;
+ pheader->ops[MILUT_REQUEST_OP(PEX_CopyLookupTable)] = LUT_COPY;
+ pheader->ops[MILUT_REQUEST_OP(PEX_FreeLookupTable)] = LUT_FREE;
+ pheader->ops[MILUT_REQUEST_OP(PEX_GetTableInfo)] = LUT_INQ_INFO;
+ pheader->ops[MILUT_REQUEST_OP(PEX_GetPredefinedEntries)] = LUT_INQ_PREDEF;
+ pheader->ops[MILUT_REQUEST_OP(PEX_GetDefinedIndices)] = LUT_INQ_IND;
+ pheader->ops[MILUT_REQUEST_OP(PEX_GetTableEntry)] = LUT_INQ_ENTRY;
+ pheader->ops[MILUT_REQUEST_OP(PEX_GetTableEntries)] = LUT_INQ_ENTRIES;
+ pheader->ops[MILUT_REQUEST_OP(PEX_SetTableEntries)] = LUT_SET_ENTRIES;
+ pheader->ops[MILUT_REQUEST_OP(PEX_DeleteTableEntries)] = LUT_DEL_ENTRIES;
+ pheader->ops[MILUT_REQUEST_OP(milut_InquireEntryAddress)] = LUT_INQ_ENTRY_ADDRESS;
+ pheader->ops[MILUT_REQUEST_OP(milut_entry_check)] = LUT_ENTRY_CHECK;
+ pheader->ops[MILUT_REQUEST_OP(milut_copy_pex_to_mi)] = LUT_COPY_PEX_MI;
+ pheader->ops[MILUT_REQUEST_OP(milut_copy_mi_to_pex)] = LUT_COPY_MI_PEX;
+ pheader->ops[MILUT_REQUEST_OP(milut_mod_call_back)] = LUT_MOD_CALL_BACK;
+
+ pLUT->deviceData = (ddPointer) pheader;
+ return (Success);
+}
+#endif /* LUT_USE_CREATE */
+
+#endif /* MILUT_PROCS_CI */
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/shared/miLightLUT.c b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miLightLUT.c
new file mode 100644
index 000000000..aefec9e48
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miLightLUT.c
@@ -0,0 +1,249 @@
+/* $TOG: miLightLUT.c /main/4 1998/02/10 12:44:53 kaleb $ */
+/*
+
+Copyright 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/shared/miLightLUT.c,v 1.7 1998/10/04 09:34:50 dawes Exp $ */
+
+#include "miLUT.h"
+#include "miWks.h"
+#include "miInfo.h"
+#include "PEXErr.h"
+#include "PEXprotost.h"
+#include "pexos.h"
+
+
+/* Level 4 Shared Resources */
+/* Lookup Table Procedures */
+
+extern unsigned colour_type_sizes[]; /* in miLUT.c */
+
+/* definitions used by miLUTProcs.ci */
+#define LUT_TYPE PEXLightLUT
+
+/* devPriv data structure */
+#define DD_LUT_ENTRY_STR ddLightEntry
+/* table entry data structure */
+#define MI_LUT_ENTRY_STR miLightEntry
+/* pex data */
+#define PEX_LUT_ENTRY_STR pexLightEntry
+
+#define LUT_REND_DYN_BIT PEXDynLightTableContents
+
+#define LUT_START_INDEX 1
+#define LUT_DEFAULT_INDEX 1
+#define LUT_0_DEFINABLE_ENTRIES 16
+#define LUT_0_NUM_PREDEFINED 1
+#define LUT_0_PREDEFINED_MIN 1
+#define LUT_0_PREDEFINED_MAX 1
+
+#define LUT_TABLE_START(pheader) (pheader)->plut.light
+
+#define DYNAMIC LIGHT_TABLE_DYNAMIC
+
+/* predefined entries table: change this to work with your devPriv data */
+static DD_LUT_ENTRY_STR pdeLightEntry[LUT_0_NUM_PREDEFINED];
+#define LUT_PDE_ENTRIES pdeLightEntry[0]
+#define LUT_SET_PDE_ENTRY(pentry, pdeentry) \
+ (pentry)->entry = *(pdeentry); \
+ if ((pentry)->entry.lightType == PEXLightWcsSpot) \
+ (pentry)->cosSpreadAngle = \
+ cos((double)(pentry)->entry.spreadAngle); \
+ else (pentry)->cosSpreadAngle = 0.0
+
+/* predefined entry 0 is set to the default values
+ * change the XXX_DEFAULT_YYY macros below to use something else
+ * if you don't want the default values defined in the pde table
+ */
+#define PDE_DEFAULT_ENTRY_NUM 0
+#define LUT_DEFAULT_VALUES pdeLightEntry[PDE_DEFAULT_ENTRY_NUM]
+#define LUT_SET_DEFAULT_VALUES(pentry) \
+ (pentry)->entry = LUT_DEFAULT_VALUES
+
+
+/* which procedure definitions in miLUTProcs.h to use and their names
+ * take out USE flags if you're defining those procs in here
+ * but leave the name definitions
+ */
+
+#define LUT_USE_FREE
+#define LUT_USE_INQ_PREDEF
+#define LUT_USE_INQ_ENTRIES
+#define LUT_USE_COPY
+#define LUT_USE_INQ_INFO
+#define LUT_USE_INQ_IND
+#define LUT_USE_INQ_ENTRY
+#define LUT_USE_SET_ENTRIES
+#define LUT_USE_DEL_ENTRIES
+#define LUT_USE_INQ_ENTRY_ADDRESS
+#define LUT_USE_CREATE
+#define LUT_USE_MOD_CALL_BACK
+
+/* these three are redefined in miLUTProcs.h
+#define LUT_FREE LightLUT_free
+#define LUT_INQ_PREDEF LightLUT_inq_predef
+#define LUT_INQ_ENTRIES LightLUT_inq_entries
+*/
+#define LUT_COPY LightLUT_copy
+#define LUT_INQ_INFO LightLUT_inq_info
+#define LUT_INQ_IND LightLUT_inq_ind
+#define LUT_INQ_ENTRY LightLUT_inq_entry
+#define LUT_SET_ENTRIES LightLUT_set_entries
+#define LUT_DEL_ENTRIES LightLUT_del_entries
+#define LUT_INQ_ENTRY_ADDRESS LightLUT_inq_entry_address
+#define LUT_CREATE LightLUT_create
+#define LUT_ENTRY_CHECK LightLUT_entry_check
+#define LUT_COPY_PEX_MI LightLUT_copy_pex_to_mi
+#define LUT_COPY_MI_PEX LightLUT_copy_mi_to_pex
+#define LUT_MOD_CALL_BACK LightLUT_mod_call_back
+
+/* copy from an mi entry to a pex entry and increment ppbuf */
+ddpex43rtn
+LUT_COPY_MI_PEX ( pheader, valueType, pentry, ppbuf )
+ miLUTHeader *pheader;
+ ddUSHORT valueType;
+ MI_LUT_ENTRY_STR *pentry;
+ ddPointer *ppbuf;
+{
+ ddPointer pb = *ppbuf;
+ DD_LUT_ENTRY_STR *pdev_entry;
+
+ if (pentry == NULL)
+ pdev_entry = &(LUT_DEFAULT_VALUES);
+ else if (pentry->entry_info.status == MILUT_UNDEFINED)
+ pdev_entry = &(LUT_DEFAULT_VALUES);
+ else
+ pdev_entry = &pentry->entry;
+
+ mibcopy(pdev_entry, pb, sizeof(PEX_LUT_ENTRY_STR));
+
+ pb+= sizeof(PEX_LUT_ENTRY_STR);
+
+ MILUT_COPY_COLOUR(&pdev_entry->lightColour.colour,
+ pb, pdev_entry->lightColour.colourType);
+
+ pb += colour_type_sizes[(int)pdev_entry->lightColour.colourType];
+ *ppbuf = pb;
+ return(Success);
+}
+
+/* copy from a pex entry to an mi entry and increment ppsrc */
+ddpex43rtn
+LUT_COPY_PEX_MI ( pheader, ppsrc, pentry )
+ miLUTHeader *pheader;
+ ddPointer *ppsrc;
+ MI_LUT_ENTRY_STR *pentry;
+{
+ ddPointer ps = *ppsrc;
+
+ mibcopy(ps, &(pentry->entry), sizeof(PEX_LUT_ENTRY_STR));
+
+ ps+= sizeof(PEX_LUT_ENTRY_STR);
+
+ MILUT_COPY_COLOUR(ps, &(pentry->entry.lightColour.colour),
+ pentry->entry.lightColour.colourType);
+
+ ps += colour_type_sizes[(int)pentry->entry.lightColour.colourType];
+ if (pentry->entry.lightType == PEXLightWcsSpot)
+ pentry->cosSpreadAngle = cos((double)pentry->entry.spreadAngle);
+ else pentry->cosSpreadAngle = 0.0;
+
+ *ppsrc = ps;
+ return(Success);
+}
+
+/* check for bad values and increment ppPexEntry */
+
+ddpex43rtn
+LUT_ENTRY_CHECK (pheader, ppPexEntry)
+ miLUTHeader *pheader;
+ PEX_LUT_ENTRY_STR **ppPexEntry;
+{
+ extern miEnumType miLightTypeET[][SI_LIGHT_NUM];
+ ddPointer pe = (ddPointer)*ppPexEntry;
+
+ /* lightType: only use supported lights */
+ if (((*ppPexEntry)->lightType < miLightTypeET[pheader->drawType][0].index) ||
+ ((*ppPexEntry)->lightType > miLightTypeET[pheader->drawType][SI_LIGHT_NUM - 1].index))
+ return(BadValue);
+ /* direction: any value OK. */
+ /* point: any value OK. */
+ /* concentration: any value OK. */
+ /* spreadAngle: must be in range [0,pi] */
+ if ((*ppPexEntry)->lightType == PEXLightWcsSpot)
+ if (((*ppPexEntry)->spreadAngle < 0.0) ||
+ ((*ppPexEntry)->spreadAngle > MI_PI))
+ return(BadValue);
+ /* attenuaton1: any value OK. */
+ /* attenuaton2: any value OK. */
+ /* colours: only accept supported colour types */
+ if (MI_BADCOLOURTYPE((*ppPexEntry)->lightColour.colourType))
+ return(PEXERR(PEXColourTypeError));
+
+ pe += sizeof(PEX_LUT_ENTRY_STR) + colour_type_sizes[(int)(*ppPexEntry)->lightColour.colourType];
+
+ *ppPexEntry = (PEX_LUT_ENTRY_STR *)pe;
+ return(Success);
+}
+
+void
+LightLUT_init_pde()
+{
+ pdeLightEntry[0].lightType = PEXLightAmbient;
+ pdeLightEntry[0].direction.x = 0.0;
+ pdeLightEntry[0].direction.y = 0.0;
+ pdeLightEntry[0].direction.z = 0.0;
+ pdeLightEntry[0].point.x = 0.0;
+ pdeLightEntry[0].point.y = 0.0;
+ pdeLightEntry[0].point.z = 0.0;
+ pdeLightEntry[0].concentration = 0.0;
+ pdeLightEntry[0].spreadAngle = 0.0;
+ pdeLightEntry[0].attenuation1 = 0.0;
+ pdeLightEntry[0].attenuation2 = 0.0;
+ pdeLightEntry[0].lightColour.colourType = PEXRgbFloatColour;
+ pdeLightEntry[0].lightColour.colour.rgbFloat.red = 1.0;
+ pdeLightEntry[0].lightColour.colour.rgbFloat.green = 1.0;
+ pdeLightEntry[0].lightColour.colour.rgbFloat.blue = 1.0;
+}
+
+#include "miLUTProcs.ci"
+
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/shared/miLineLUT.c b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miLineLUT.c
new file mode 100644
index 000000000..149c91e53
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miLineLUT.c
@@ -0,0 +1,280 @@
+/* $TOG: miLineLUT.c /main/3 1998/02/10 12:45:00 kaleb $ */
+/*
+
+Copyright 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/shared/miLineLUT.c,v 1.7 1998/10/04 09:34:50 dawes Exp $ */
+
+#include "miLUT.h"
+#include "miWks.h"
+#include "miInfo.h"
+#include "PEXErr.h"
+#include "PEXprotost.h"
+#include "pexos.h"
+
+
+/* Level 4 Shared Resources */
+/* Lookup Table Procedures */
+
+extern unsigned colour_type_sizes[]; /* in miLUT.c */
+
+/* definitions used by miLUTProcs.ci */
+#define LUT_TYPE PEXLineBundleLUT
+
+/* devPriv data structure */
+#define DD_LUT_ENTRY_STR ddLineBundleEntry
+/* table entry data structure */
+#define MI_LUT_ENTRY_STR miLineBundleEntry
+/* pex data */
+#define PEX_LUT_ENTRY_STR pexLineBundleEntry
+
+#define LUT_REND_DYN_BIT PEXDynLineBundleContents
+
+#define LUT_START_INDEX 1
+#define LUT_DEFAULT_INDEX 1
+#define LUT_0_DEFINABLE_ENTRIES 20
+#define LUT_0_NUM_PREDEFINED 1
+#define LUT_0_PREDEFINED_MIN 1
+#define LUT_0_PREDEFINED_MAX 1
+
+#define LUT_TABLE_START(pheader) (pheader)->plut.line
+
+#define DYNAMIC LINE_BUNDLE_DYNAMIC
+
+/* predefined entries table: change this to work with your devPriv data */
+static DD_LUT_ENTRY_STR pdeLineBundleEntry[LUT_0_NUM_PREDEFINED];
+#define LUT_PDE_ENTRIES pdeLineBundleEntry[0]
+#define LUT_SET_PDE_ENTRY(pentry, pdeentry) \
+ (pentry)->entry = *(pdeentry); \
+ (pentry)->real_entry = *(pdeentry)
+
+/* predefined entry 0 is set to the default values
+ * change the XXX_DEFAULT_YYY macros below to use something else
+ * if you don't want the default values defined in the pde table
+ */
+#define PDE_DEFAULT_ENTRY_NUM 0
+#define LUT_DEFAULT_VALUES pdeLineBundleEntry[PDE_DEFAULT_ENTRY_NUM]
+#define LUT_SET_DEFAULT_VALUES(pentry) \
+ (pentry)->entry = LUT_DEFAULT_VALUES; \
+ (pentry)->real_entry = LUT_DEFAULT_VALUES
+
+/* which procedure definitions in miLUTProcs.h to use and their names
+ * take out USE flags if you're defining those procs in here
+ * but leave the name definitions
+ */
+
+#define LUT_USE_FREE
+#define LUT_USE_INQ_PREDEF
+#define LUT_USE_INQ_ENTRIES
+#define LUT_USE_COPY
+#define LUT_USE_INQ_INFO
+#define LUT_USE_INQ_IND
+#define LUT_USE_INQ_ENTRY
+#define LUT_USE_SET_ENTRIES
+#define LUT_USE_DEL_ENTRIES
+#define LUT_USE_INQ_ENTRY_ADDRESS
+#define LUT_USE_CREATE
+#define LUT_USE_MOD_CALL_BACK
+
+/* these three are redefined in miLUTProcs.h
+#define LUT_FREE LineBundleLUT_free
+#define LUT_INQ_PREDEF LineBundleLUT_inq_predef
+#define LUT_INQ_ENTRIES LineBundleLUT_inq_entries
+*/
+#define LUT_COPY LineBundleLUT_copy
+#define LUT_INQ_INFO LineBundleLUT_inq_info
+#define LUT_INQ_IND LineBundleLUT_inq_ind
+#define LUT_INQ_ENTRY LineBundleLUT_inq_entry
+#define LUT_SET_ENTRIES LineBundleLUT_set_entries
+#define LUT_DEL_ENTRIES LineBundleLUT_del_entries
+#define LUT_INQ_ENTRY_ADDRESS LineBundleLUT_inq_entry_address
+#define LUT_CREATE LineBundleLUT_create
+#define LUT_ENTRY_CHECK LineBundleLUT_entry_check
+#define LUT_COPY_PEX_MI LineBundleLUT_copy_pex_to_mi
+#define LUT_COPY_MI_PEX LineBundleLUT_copy_mi_to_pex
+#define LUT_MOD_CALL_BACK LineBundleLUT_mod_call_back
+#define LUT_REALIZE_ENTRY LineBundleLUT_realize_entry
+
+/* copy from an mi entry to a pex entry and increment ppbuf */
+ddpex43rtn
+LUT_COPY_MI_PEX ( pheader, valueType, pentry, ppbuf )
+ miLUTHeader *pheader;
+ ddUSHORT valueType;
+ MI_LUT_ENTRY_STR *pentry;
+ ddPointer *ppbuf;
+{
+ ddPointer pb = *ppbuf;
+ DD_LUT_ENTRY_STR *pdev_entry;
+
+ if (pentry == NULL)
+ pdev_entry = &(LUT_DEFAULT_VALUES);
+ else if (pentry->entry_info.status == MILUT_UNDEFINED)
+ pdev_entry = &(LUT_DEFAULT_VALUES);
+ else
+ if (valueType == PEXRealizedValue)
+ pdev_entry = &pentry->real_entry;
+ else
+ pdev_entry = &pentry->entry;
+
+
+ mibcopy(pdev_entry, pb, sizeof(PEX_LUT_ENTRY_STR));
+
+ pb+= sizeof(PEX_LUT_ENTRY_STR);
+
+ MILUT_COPY_COLOUR(&pdev_entry->lineColour.colour,
+ pb, pdev_entry->lineColour.colourType);
+
+ pb += colour_type_sizes[(int)pdev_entry->lineColour.colourType];
+ *ppbuf = pb;
+ return(Success);
+}
+
+/* copy from a pex entry to an mi entry and increment ppsrc */
+ddpex43rtn
+LUT_COPY_PEX_MI ( pheader, ppsrc, pentry )
+ miLUTHeader *pheader;
+ ddPointer *ppsrc;
+ MI_LUT_ENTRY_STR *pentry;
+{
+ ddPointer ps = *ppsrc;
+
+ mibcopy(ps, &(pentry->entry), sizeof(PEX_LUT_ENTRY_STR));
+
+ ps+= sizeof(PEX_LUT_ENTRY_STR);
+
+ MILUT_COPY_COLOUR(ps, &(pentry->entry.lineColour.colour),
+ pentry->entry.lineColour.colourType);
+
+ LUT_REALIZE_ENTRY( pheader, pentry );
+
+ ps += colour_type_sizes[(int)pentry->entry.lineColour.colourType];
+ *ppsrc = ps;
+ return(Success);
+}
+
+/* check for bad values and increment ppPexEntry */
+
+ddpex43rtn
+LUT_ENTRY_CHECK (pheader, ppPexEntry)
+ miLUTHeader *pheader;
+ PEX_LUT_ENTRY_STR **ppPexEntry;
+{
+ ddPointer pe = (ddPointer)*ppPexEntry;
+ /* lineType: any value OK. use line type 1 if it's not supported */
+ /* polylineInterp: any value OK. use method 1 if it's not supported */
+ /* curveApprox: any value OK. use method 1 if it's not supported */
+ /* lineWidth: any value is OK, the nearest supported value is used */
+ /* colours: only accept supported colour types */
+ if (MI_BADCOLOURTYPE((*ppPexEntry)->lineColour.colourType))
+ return(PEXERR(PEXColourTypeError));
+
+ pe += sizeof(PEX_LUT_ENTRY_STR) +
+ colour_type_sizes[(int)(*ppPexEntry)->lineColour.colourType];
+ *ppPexEntry = (PEX_LUT_ENTRY_STR *)pe;
+ return(Success);
+}
+
+/* realize entry */
+ddpex43rtn
+LUT_REALIZE_ENTRY( pheader, pEntry )
+ miLUTHeader *pheader;
+ MI_LUT_ENTRY_STR *pEntry;
+{
+ extern miEnumType miLineTypeET[][SI_LINE_NUM];
+ extern miEnumType miPolylineInterpMethodET[][SI_LINE_INTERP_NUM];
+ extern miEnumType miCurveApproxMethodET[][SI_CURVE_APPROX_NUM];
+
+ /* lineType: any value OK. use line type 1 if it's not supported */
+ if ( (pEntry->entry.lineType <
+ miLineTypeET[pheader->drawType][0].index) ||
+ (pEntry->entry.lineType >
+ miLineTypeET[pheader->drawType][SI_LINE_NUM - 1].index) )
+ pEntry->real_entry.lineType = 1;
+ else
+ pEntry->real_entry.lineType = pEntry->entry.lineType;
+
+ /* polylineInterp: any value OK. use method 1 if it's not supported */
+ if ( (pEntry->entry.polylineInterp <
+ miPolylineInterpMethodET[pheader->drawType][0].index) ||
+ (pEntry->entry.polylineInterp >
+ miPolylineInterpMethodET[pheader->drawType][SI_LINE_INTERP_NUM - 1].index) )
+ pEntry->real_entry.polylineInterp = 1;
+ else
+ pEntry->real_entry.polylineInterp = pEntry->entry.polylineInterp;
+
+ /* curveApprox: any value OK. use method 1 if it's not supported */
+ if ( (pEntry->entry.curveApprox.approxMethod <
+ miCurveApproxMethodET[pheader->drawType][0].index) ||
+ (pEntry->entry.curveApprox.approxMethod >
+ miCurveApproxMethodET[pheader->drawType][SI_CURVE_APPROX_NUM - 1].index) )
+ pEntry->real_entry.curveApprox.approxMethod = 1;
+ else
+ pEntry->real_entry.curveApprox.approxMethod = pEntry->entry.curveApprox.approxMethod;
+ pEntry->real_entry.curveApprox.tolerance =
+ pEntry->entry.curveApprox.tolerance;
+
+ /* lineWidth: any value is OK, it is multiplied by the nomimal
+ * line width and the nearest supported size is used
+ * The realized value is the scale for inquiry, not the size.
+ */
+ pEntry->real_entry.lineWidth = pEntry->entry.lineWidth;
+
+ /* colourType: its an error if an unsupported colour type was
+ * specified. For supported colour types, should mapped colour
+ * be returned??
+ */
+ pEntry->real_entry.lineColour = pEntry->entry.lineColour;
+ return(Success);
+}
+
+void
+LineBundleLUT_init_pde()
+{
+ pdeLineBundleEntry[0].lineType = PEXLineTypeSolid;
+ pdeLineBundleEntry[0].polylineInterp = PEXPolylineInterpNone;
+ pdeLineBundleEntry[0].curveApprox.approxMethod = 1;
+ pdeLineBundleEntry[0].curveApprox.tolerance = 1.0;
+ pdeLineBundleEntry[0].lineWidth = 1.0;
+ MILUT_INIT_COLOUR(pdeLineBundleEntry[0].lineColour);
+}
+
+#include "miLUTProcs.ci"
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/shared/miMarkLUT.c b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miMarkLUT.c
new file mode 100644
index 000000000..d9ee160a0
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miMarkLUT.c
@@ -0,0 +1,258 @@
+/* $TOG: miMarkLUT.c /main/3 1998/02/10 12:45:06 kaleb $ */
+/*
+
+Copyright 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/shared/miMarkLUT.c,v 1.7 1998/10/04 09:34:51 dawes Exp $ */
+
+#include "miLUT.h"
+#include "miWks.h"
+#include "miInfo.h"
+#include "PEXErr.h"
+#include "PEXprotost.h"
+#include "pexos.h"
+
+
+/* Level 4 Shared Resources */
+/* Lookup Table Procedures */
+
+extern unsigned colour_type_sizes[]; /* in miLUT.c */
+
+/* definitions used by miLUTProcs.ci */
+#define LUT_TYPE PEXMarkerBundleLUT
+
+/* devPriv data structure */
+#define DD_LUT_ENTRY_STR ddMarkerBundleEntry
+/* table entry data structure */
+#define MI_LUT_ENTRY_STR miMarkerBundleEntry
+/* pex data */
+#define PEX_LUT_ENTRY_STR pexMarkerBundleEntry
+
+#define LUT_REND_DYN_BIT PEXDynMarkerBundleContents
+
+#define LUT_START_INDEX 1
+#define LUT_DEFAULT_INDEX 1
+#define LUT_0_DEFINABLE_ENTRIES 20
+#define LUT_0_NUM_PREDEFINED 1
+#define LUT_0_PREDEFINED_MIN 1
+#define LUT_0_PREDEFINED_MAX 1
+
+#define LUT_TABLE_START(pheader) (pheader)->plut.marker
+
+#define DYNAMIC MARKER_BUNDLE_DYNAMIC
+
+/* predefined entries table: change this to work with your devPriv data */
+static DD_LUT_ENTRY_STR pdeMarkerBundleEntry[LUT_0_NUM_PREDEFINED];
+#define LUT_PDE_ENTRIES pdeMarkerBundleEntry[0]
+#define LUT_SET_PDE_ENTRY(pentry, pdeentry) \
+ (pentry)->entry = *(pdeentry); \
+ (pentry)->real_entry = *(pdeentry)
+
+/* predefined entry 0 is set to the default values
+ * change the XXX_DEFAULT_YYY macros below to use something else
+ * if you don't want the default values defined in the pde table
+ */
+#define PDE_DEFAULT_ENTRY_NUM 0
+#define LUT_DEFAULT_VALUES pdeMarkerBundleEntry[PDE_DEFAULT_ENTRY_NUM]
+#define LUT_SET_DEFAULT_VALUES(pentry) \
+ (pentry)->entry = LUT_DEFAULT_VALUES; \
+ (pentry)->real_entry = LUT_DEFAULT_VALUES
+
+/* which procedure definitions in miLUTProcs.h to use and their names
+ * take out USE flags if you're defining those procs in here
+ * but leave the name definitions
+ */
+
+#define LUT_USE_FREE
+#define LUT_USE_INQ_PREDEF
+#define LUT_USE_INQ_ENTRIES
+#define LUT_USE_COPY
+#define LUT_USE_INQ_INFO
+#define LUT_USE_INQ_IND
+#define LUT_USE_INQ_ENTRY
+#define LUT_USE_SET_ENTRIES
+#define LUT_USE_DEL_ENTRIES
+#define LUT_USE_INQ_ENTRY_ADDRESS
+#define LUT_USE_CREATE
+#define LUT_USE_MOD_CALL_BACK
+
+/* these three are redefined in miLUTProcs.h
+#define LUT_FREE MarkerBundleLUT_free
+#define LUT_INQ_PREDEF MarkerBundleLUT_inq_predef
+#define LUT_INQ_ENTRIES MarkerBundleLUT_inq_entries
+*/
+#define LUT_COPY MarkerBundleLUT_copy
+#define LUT_INQ_INFO MarkerBundleLUT_inq_info
+#define LUT_INQ_IND MarkerBundleLUT_inq_ind
+#define LUT_INQ_ENTRY MarkerBundleLUT_inq_entry
+#define LUT_SET_ENTRIES MarkerBundleLUT_set_entries
+#define LUT_DEL_ENTRIES MarkerBundleLUT_del_entries
+#define LUT_INQ_ENTRY_ADDRESS MarkerBundleLUT_inq_entry_address
+#define LUT_CREATE MarkerBundleLUT_create
+#define LUT_ENTRY_CHECK MarkerBundleLUT_entry_check
+#define LUT_COPY_PEX_MI MarkerBundleLUT_copy_pex_to_mi
+#define LUT_COPY_MI_PEX MarkerBundleLUT_copy_mi_to_pex
+#define LUT_MOD_CALL_BACK MarkerBundleLUT_mod_call_back
+#define LUT_REALIZE_ENTRY MarkerBundleLUT_realize_entry
+
+/* copy from an mi entry to a pex entry and increment ppbuf */
+ddpex43rtn
+LUT_COPY_MI_PEX ( pheader, valueType, pentry, ppbuf )
+ miLUTHeader *pheader;
+ ddUSHORT valueType;
+ MI_LUT_ENTRY_STR *pentry;
+ ddPointer *ppbuf;
+{
+ ddPointer pb = *ppbuf;
+ DD_LUT_ENTRY_STR *pdev_entry;
+
+ if (pentry == NULL)
+ pdev_entry = &(LUT_DEFAULT_VALUES);
+ else if (pentry->entry_info.status == MILUT_UNDEFINED)
+ pdev_entry = &(LUT_DEFAULT_VALUES);
+ else
+ if (valueType == PEXRealizedValue)
+ pdev_entry = &pentry->real_entry;
+ else
+ pdev_entry = &pentry->entry;
+
+
+ mibcopy(pdev_entry, pb, sizeof(PEX_LUT_ENTRY_STR));
+
+ pb+= sizeof(PEX_LUT_ENTRY_STR);
+
+ MILUT_COPY_COLOUR(&pdev_entry->markerColour.colour,
+ pb, pdev_entry->markerColour.colourType);
+
+ pb += colour_type_sizes[(int)pdev_entry->markerColour.colourType];
+ *ppbuf = pb;
+ return(Success);
+}
+
+/* copy from a pex entry to an mi entry and increment ppsrc */
+ddpex43rtn
+LUT_COPY_PEX_MI ( pheader, ppsrc, pentry )
+ miLUTHeader *pheader;
+ ddPointer *ppsrc;
+ MI_LUT_ENTRY_STR *pentry;
+{
+ ddPointer ps = *ppsrc;
+
+ mibcopy(ps, &(pentry->entry), sizeof(PEX_LUT_ENTRY_STR));
+
+ ps+= sizeof(PEX_LUT_ENTRY_STR);
+
+ MILUT_COPY_COLOUR(ps, &(pentry->entry.markerColour.colour),
+ pentry->entry.markerColour.colourType);
+
+ LUT_REALIZE_ENTRY( pheader, pentry );
+
+ ps += colour_type_sizes[(int)pentry->entry.markerColour.colourType];
+ *ppsrc = ps;
+ return(Success);
+}
+
+/* check for bad values and increment ppPexEntry */
+
+ddpex43rtn
+LUT_ENTRY_CHECK (pheader, ppPexEntry)
+ miLUTHeader *pheader;
+ PEX_LUT_ENTRY_STR **ppPexEntry;
+{
+ ddPointer pe = (ddPointer)*ppPexEntry;
+ /* markerType: any value OK. use marker type 3 if it's not supported */
+ /* markerScale: any value is OK, it is multiplied by the nominal
+ * marker size (see imp dep constants) and the supported size
+ * nearest to that is used
+ */
+
+ /* colours: only accept supported colour types */
+ if (MI_BADCOLOURTYPE((*ppPexEntry)->markerColour.colourType))
+ return(PEXERR(PEXColourTypeError));
+
+ pe += sizeof(PEX_LUT_ENTRY_STR) +
+ colour_type_sizes[(int)(*ppPexEntry)->markerColour.colourType];
+ *ppPexEntry = (PEX_LUT_ENTRY_STR *)pe;
+ return(Success);
+}
+
+/* realize entry */
+ddpex43rtn
+LUT_REALIZE_ENTRY( pheader, pEntry )
+ miLUTHeader *pheader;
+ MI_LUT_ENTRY_STR *pEntry;
+{
+ extern miEnumType miMarkerTypeET[][SI_MARKER_NUM];
+
+ /* markerType: any value OK. use marker type 3 if it's not supported */
+ if ( (pEntry->entry.markerType <
+ miMarkerTypeET[pheader->drawType][0].index) ||
+ (pEntry->entry.markerType >
+ miMarkerTypeET[pheader->drawType][SI_MARKER_NUM - 1].index) )
+ pEntry->real_entry.markerType = 3;
+ else
+ pEntry->real_entry.markerType = pEntry->entry.markerType;
+
+ /* markerScale: any value is OK, it is multiplied by the nomimal
+ * marker size and the nearest supported size is used
+ * The realized value is the scale for inquiry, not the size
+ */
+ pEntry->real_entry.markerScale = pEntry->entry.markerScale;
+
+ /* colourType: its an error if an unsupported colour type was
+ * specified. For supported colour types, should mapped colour
+ * be returned?? - but don't know which colour approx
+ * values to use. could use default.
+ */
+ pEntry->real_entry.markerColour = pEntry->entry.markerColour;
+ return(Success);
+}
+
+void
+MarkerBundleLUT_init_pde()
+{
+ pdeMarkerBundleEntry[0].markerType = PEXMarkerAsterisk;
+ pdeMarkerBundleEntry[0].markerScale = 1.0;
+ MILUT_INIT_COLOUR(pdeMarkerBundleEntry[0].markerColour);
+}
+
+#include "miLUTProcs.ci"
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/shared/miMisc.c b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miMisc.c
new file mode 100644
index 000000000..40cb827c4
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miMisc.c
@@ -0,0 +1,870 @@
+/* $TOG: miMisc.c /main/10 1998/02/10 12:45:11 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/shared/miMisc.c,v 1.7 1998/10/04 09:34:51 dawes Exp $ */
+
+#include "mipex.h"
+#include "miInfo.h"
+#include "pexUtils.h"
+#include "PEXprotost.h"
+#include "pexos.h"
+
+
+/* pex device dependent initialization */
+ddpex43rtn
+ddpexInit()
+{
+ extern int predef_initialized; /* in miLUT.c */
+ extern ddBOOL pcflag; /* in miRender.c */
+ extern ddBOOL init_pick_flag; /* in miWks.c */
+
+ predef_initialized = 0;
+ pcflag = MI_FALSE;
+ init_pick_flag = MI_FALSE;
+
+ return (Success);
+}
+
+/* pex device dependent reset */
+/*
+ This function is called during server reset.
+ It should free any buffers and initialize any device-specific
+ data that must be done during server reset.
+
+ The PEX-ME allocates no buffers and so this function does
+ not much. It is provided as an aid to porting. It is
+ called from the dipex routine PEXResetProc
+*/
+void
+ddpexReset()
+{
+ /* YOUR CODE HERE */
+}
+
+/* define the imp dep info and enum type info */
+
+/* Theoretically, all of this info could depend on the drawable of the
+ * workstation, so put everything into arrays based on the drawable.
+ * There is an imp dep drawable type value defined in mi.h which is
+ * determined by the implementation based on the workstations drawable.
+ * The MI_MAXDRAWABLES is the number of imp dep defined drawable types
+ * used for PEX. In the SI, its value is 1.
+ */
+
+/* also, these values are all hard coded for the SI (using #defines
+ * in miInfo.h). You may want to
+ * inquire into a library that you are porting to for these values.
+ * To do this, replace the code in the procedures below to retrieve
+ * the value from your library instead of from the table.
+ */
+
+/* imp dep constants */
+
+/* These values are in two arrays that can be accessed by
+ * the PEXID constant value. One array has the values which are
+ * type CARD32. The other is for FLOAT values.
+ * SI_NUM_INT_IMPS and SI_NUM_FLOAT_IMPS specify how many values
+ * there are of each
+ */
+
+/* add one to number of ints because imps start at 1 */
+static ddULONG intImpDeps[MI_MAXDRAWABLES][SI_NUM_INT_IMPS + 1] = {
+ 0, /* dummy */
+ SI_DITHERING_SUPPORTED,
+ SI_MAX_EDGE_WIDTH,
+ SI_MAX_LINE_WIDTH,
+ SI_MAX_MARKER_SIZE,
+ SI_MAX_MODEL_CLIP_PLANES,
+ SI_MAX_NAME_SET_NAMES,
+ SI_MAX_NON_AMBIENT_LIGHTS,
+ SI_MAX_NURB_ORDER,
+ SI_MAX_TRIM_CURVE_ORDER,
+ SI_MIN_EDGE_WIDTH,
+ SI_MIN_LINE_WIDTH,
+ SI_MIN_MARKER_SIZE,
+ SI_NOM_EDGE_WIDTH,
+ SI_NOM_LINE_WIDTH,
+ SI_NOM_MARKER_SIZE,
+ SI_SUPP_EDGE_WIDTHS,
+ SI_SUPP_LINE_WIDTHS,
+ SI_SUPP_MARKER_SIZES,
+ SI_BEST_COLOUR_APPROX_VALUES,
+ SI_TRANSPARENCY_SUPPORTED,
+ SI_DOUBLE_BUFFERING_SUPPORTED,
+ SI_MAX_HITS_EVENT_SUPPORTED
+};
+
+#define FLOAT_INDEX(n) (n) - (SI_NUM_INT_IMPS + 1)
+
+static ddFLOAT floatImpDeps[MI_MAXDRAWABLES][SI_NUM_FLOAT_IMPS] = {
+ SI_CHROM_RED_U,
+ SI_CHROM_RED_V,
+ SI_LUM_RED,
+ SI_CHROM_GREEN_U,
+ SI_CHROM_GREEN_V,
+ SI_LUM_GREEN,
+ SI_CHROM_BLUE_U,
+ SI_CHROM_BLUE_V,
+ SI_LUM_BLUE,
+ SI_CHROM_WHITE_U,
+ SI_CHROM_WHITE_V,
+ SI_LUM_WHITE
+};
+
+/*++
+ |
+ | Function Name: InquireImpDepConstants
+ |
+ | Function Description:
+ | Handles the PEXGetImpDepConstants request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex43rtn
+InquireImpDepConstants(pDrawable, numNames, pNames, pBuffer)
+/* in */
+ DrawablePtr pDrawable;/* drawable */
+ ddULONG numNames; /* number of names */
+ ddUSHORT *pNames; /* list of names */
+/* out */
+ ddBufferPtr pBuffer; /* list of constants */
+
+{
+
+ register short i;
+ register ddULONG dsize;
+
+ register union
+ {
+ ddULONG *C32;
+ ddFLOAT *F32;
+ } pbuf;
+
+ register ddUSHORT *pname;
+ register int drawType;
+
+ pBuffer->dataSize = 0;
+
+ dsize = numNames * sizeof(ddULONG);
+ PU_CHECK_BUFFER_SIZE(pBuffer, dsize);
+
+ pBuffer->dataSize = dsize;
+ MI_WHICHDRAW(pDrawable, drawType);
+
+ /* process each inquiry request in the list */
+
+ for (i = 0, pname = pNames, pbuf.C32 = (ddULONG *) (pBuffer->pBuf);
+ i < numNames; i++, pname++, pbuf.C32++)
+ {
+
+ /*
+ * use a switch here for each constant type if you don't hard code
+ * the values (e.g. you want to call into a library to get the
+ * values)
+ */
+ if ((int) *pname < SI_NUM_INT_IMPS)
+ *pbuf.C32 = intImpDeps[drawType][(int) *pname];
+ else
+ *pbuf.F32 = floatImpDeps[drawType][(int)FLOAT_INDEX(*pname)];
+
+ } /* for (i=0, pname = pNames... */
+
+ return (Success);
+
+} /* InquireImpDepConstants */
+
+/* now enumerated type info */
+
+/* again, these can theoretically vary depending on the drawable type
+ * and arrays bases on the imp dep drawable type are used again
+ */
+
+/* some of these are accessed in other code to make sure that only valid
+ * enum types are used, so they are not declared static
+ * the defined constants used with these are in miInfo.h
+ * TODO: make proceures to check for valid ets to call instead of
+ * declaring these global
+ */
+
+miEnumType miMarkerTypeET[MI_MAXDRAWABLES][SI_MARKER_NUM] = {
+ {{1, SI_MARKER_1},
+ {2, SI_MARKER_2},
+ {3, SI_MARKER_3},
+ {4, SI_MARKER_4},
+ {5, SI_MARKER_5}}
+};
+
+miEnumType miATextStyleET[MI_MAXDRAWABLES][SI_ATEXT_NUM] = {
+ {{1, SI_ATEXT_1},
+ {2, SI_ATEXT_2}}
+};
+
+miEnumType miInteriorStyleET[MI_MAXDRAWABLES][SI_INT_NUM] = {
+ {{1, SI_INT_1},
+ {2, SI_INT_2},
+ {5, SI_INT_5}}
+};
+
+/* hatches are not supported but put in a dummy */
+miEnumType miHatchStyleET[MI_MAXDRAWABLES][SI_HATCH_NUM + 1] = {
+ {{0, ""}}
+};
+
+miEnumType miLineTypeET[MI_MAXDRAWABLES][SI_LINE_NUM] = {
+ {{1, SI_LINE_1},
+ {2, SI_LINE_2},
+ {3, SI_LINE_3},
+ {4, SI_LINE_4}}
+};
+
+miEnumType miSurfaceEdgeTypeET[MI_MAXDRAWABLES][SI_EDGE_NUM] = {
+ {{1, SI_EDGE_1},
+ {2, SI_EDGE_2},
+ {3, SI_EDGE_3},
+ {4, SI_EDGE_4}}
+};
+
+miEnumType miPickDeviceTypeET[MI_MAXDRAWABLES][SI_PICK_DEVICE_NUM] = {
+ {{1, SI_PICK_DEVICE_1},
+ {2, SI_PICK_DEVICE_2}}
+};
+
+miEnumType miPickOneMethodET[MI_MAXDRAWABLES][SI_PICK_ONE_NUM] = {
+ {{1, SI_PICK_ONE_LAST}}
+};
+
+miEnumType miPickAllMethodET[MI_MAXDRAWABLES][SI_PICK_ALL_NUM] = {
+ {{1, SI_PICK_ALL_ALL}}
+};
+
+miEnumType miPolylineInterpMethodET[MI_MAXDRAWABLES][SI_LINE_INTERP_NUM] = {
+ {{1, SI_LINE_INTERP_1}}
+};
+
+miEnumType miCurveApproxMethodET[MI_MAXDRAWABLES][SI_CURVE_APPROX_NUM] = {
+ {{1, SI_CURVE_APPROX_1},
+ {2, SI_CURVE_APPROX_2},
+ {3, SI_CURVE_APPROX_3},
+ {4, SI_CURVE_APPROX_4},
+ {6, SI_CURVE_APPROX_6},
+ {7, SI_CURVE_APPROX_7}}
+};
+
+miEnumType miReflectionModelET[MI_MAXDRAWABLES][SI_REFLECT_NUM] = {
+ {{1, SI_REFLECT_1},
+ {2, SI_REFLECT_2},
+ {3, SI_REFLECT_3},
+ {4, SI_REFLECT_4}}
+};
+
+miEnumType miSurfaceInterpMethodET[MI_MAXDRAWABLES][SI_SURF_INTERP_NUM] = {
+ {{1, SI_SURF_INTERP_1}}
+};
+
+miEnumType miSurfaceApproxMethodET[MI_MAXDRAWABLES][SI_SURF_APPROX_NUM] = {
+ {{1, SI_SURF_APPROX_1},
+ {2, SI_SURF_APPROX_2},
+ {3, SI_SURF_APPROX_3},
+ {4, SI_SURF_APPROX_4},
+ {6, SI_SURF_APPROX_6},
+ {7, SI_SURF_APPROX_7}}
+};
+
+miEnumType miTrimCurveApproxMethodET[MI_MAXDRAWABLES][SI_TRIM_CURVE_NUM] = {
+ {{1, SI_TRIM_CURVE_1},
+ {2, SI_TRIM_CURVE_2}}
+};
+
+miEnumType miModelClipOperatorET[MI_MAXDRAWABLES][SI_MODEL_CLIP_NUM] = {
+ {{1, SI_MODEL_CLIP_1},
+ {2, SI_MODEL_CLIP_2}}
+};
+
+miEnumType miLightTypeET[MI_MAXDRAWABLES][SI_LIGHT_NUM] = {
+ {{1, SI_LIGHT_1},
+ {2, SI_LIGHT_2},
+ {3, SI_LIGHT_3},
+ {4, SI_LIGHT_4}}
+};
+
+miEnumType miColourTypeET[MI_MAXDRAWABLES][SI_COLOUR_NUM] = {
+ {{0, SI_COLOUR_0},
+ {1, SI_COLOUR_1}}
+};
+
+miEnumType miFloatFormatET[MI_MAXDRAWABLES][SI_FLOAT_NUM] = {
+ {{1, SI_FLOAT_1},
+ {2, SI_FLOAT_2}}
+};
+
+miEnumType miHlhsrModeET[MI_MAXDRAWABLES][SI_HLHSR_NUM] = {
+ {{1, SI_HLHSR_1}}
+};
+
+miEnumType miPromptEchoTypeET[MI_MAXDRAWABLES][SI_PET_NUM] = {
+ {{1, SI_PET_1}}
+};
+
+miEnumType miDisplayUpdateModeET[MI_MAXDRAWABLES][SI_UPDATE_NUM] = {
+ {{1, SI_UPDATE_1},
+ {2, SI_UPDATE_2},
+ {3, SI_UPDATE_3},
+ {4, SI_UPDATE_4},
+ {5, SI_UPDATE_5}}
+};
+
+miEnumType miColourApproxTypeET[MI_MAXDRAWABLES][SI_CLR_APPROX_TYPE_NUM] = {
+ {{1, SI_CLR_APPROX_TYPE_1},
+ {2, SI_CLR_APPROX_TYPE_2}}
+};
+
+miEnumType miColourApproxModelET[MI_MAXDRAWABLES][SI_CLR_APPROX_MODEL_NUM] = {
+ {{1, SI_CLR_APPROX_MODEL_1}}
+};
+
+/* put in a dummy */
+miEnumType miGDPET[MI_MAXDRAWABLES][SI_GDP_NUM + 1] = {
+ {{0, ""}}
+};
+
+/* put in a dummy */
+miEnumType miGDP3ET[MI_MAXDRAWABLES][SI_GDP3_NUM + 1] = {
+ {{0, ""}}
+};
+
+/* put in a dummy */
+miEnumType miGSEET[MI_MAXDRAWABLES][SI_GSE_NUM + 1] = {
+ {{0, ""}}
+};
+
+miEnumType miEscapeET[MI_MAXDRAWABLES][SI_ESCAPE_NUM] = {
+ {{1, SI_ESCAPE_1}}
+};
+
+miEnumType miRenderingColourModelET[MI_MAXDRAWABLES][SI_REND_COLOUR_NUM] = {
+ {{1, SI_REND_COLOUR_1}}
+};
+
+miEnumType miParametricSurfaceCharsET[MI_MAXDRAWABLES][SI_P_SURF_CHAR_NUM] = {
+ {{1, SI_P_SURF_CHAR_1},
+ {2, SI_P_SURF_CHAR_2},
+ {3, SI_P_SURF_CHAR_3}}
+};
+
+/* useful macros for putting et info into buffer */
+#define PUT_BUF32(buf, value) \
+ *(buf).C32++ = (value);
+
+#define PUT_BUF16(buf, value) \
+ *(buf).C16++ = (value);
+
+#define PUT_BUF8(buf, value) \
+ *(buf).C8++ = (value);
+
+#define PADDING(n) ( (n)&3 ? (4 - ((n)&3)) : 0)
+
+/* be sure k is defined before using this */
+/* size is the size of the string
+ * extra is 2 if the case is PEXETBoth, it's 0 for PEXETMnemonic
+ * this macro is not used for PEXETIndex
+ */
+#define PUT_STR(buf, string, size, extra) \
+ { \
+ PUT_BUF16(buf, size); \
+ for (k=0; k < size; k++) \
+ PUT_BUF8(buf, string[k]); \
+ k = PADDING( size + 2 + extra ); \
+ while (k) { \
+ PUT_BUF8( buf, 0 ); \
+ k--; \
+ } }
+
+/* macro to count space needed for et info */
+#define COUNT_ET( num, pet ) \
+ count+=4; /* space for returned num value */ \
+ switch (itemMask) \
+ { \
+ case PEXETIndex: /* return index values only */ \
+ count += (num << 1); \
+ /* add pad if necessary */ \
+ if (num & 1) \
+ count+=2; \
+ break; \
+ \
+ case PEXETMnemonic: /* return mnemonics only */ \
+ for (j=0; j<num; j++, pet++) \
+ { \
+ /* add length of string */ \
+ count += 2; \
+ /* then number of chars in string */ \
+ count += strlen((pet)->name); \
+ /* then pads for string (and its length) */\
+ count += PADDING(strlen((pet)->name) + 2);\
+ } \
+ break; \
+ \
+ case PEXETBoth: /* return index and mnemonic */ \
+ for (j=0; j<num; j++, pet++) \
+ { \
+ /* add index */ \
+ count += 2; \
+ /* add length of string */ \
+ count += 2; \
+ /* then number of chars in string */ \
+ count += strlen((pet)->name); \
+ /* then pads for string */ \
+ count += PADDING( strlen((pet)->name) );\
+ } \
+ break; \
+ \
+ } /* switch (itemMask) */
+
+/* macro to put hard coded et info into buffer */
+#define GET_ET( num, pet ) \
+ /* always increment the list count and return the number of types */\
+ (*pNumLists)++; \
+ PUT_BUF32(pbuf, (num)); \
+ /* now put in the index and/or mnemonic */ \
+ switch (itemMask) \
+ { \
+ case PEXETIndex: /* return index values only */ \
+ for (j=0; j<(num); j++, pet++) \
+ PUT_BUF16(pbuf, (pet)->index); \
+ /* add pad if necessary */ \
+ if ((num) & 1) \
+ PUT_BUF16(pbuf, 0); \
+ break; \
+ \
+ case PEXETMnemonic: /* return mnemonics only */ \
+ for (j=0; j<(num); j++, pet++) \
+ { \
+ size = strlen( (pet)->name ); \
+ /* PUT_STR pads end of string */ \
+ PUT_STR(pbuf, (pet)->name, size, 0); \
+ } \
+ break; \
+ \
+ case PEXETBoth: /* return index and mnemonic */ \
+ for (j=0; j<(num); j++, pet++) \
+ { \
+ size = strlen( (pet)->name ); \
+ PUT_BUF16(pbuf, (pet)->index); \
+ /* PUT_STR pads end of string */ \
+ PUT_STR(pbuf, (pet)->name, size, 2); \
+ } \
+ break; \
+ \
+ } /* switch (itemMask) */
+
+#define DO_ET(num, pet) \
+ if ( counting ) \
+ { \
+ COUNT_ET( num, pet ); \
+ } \
+ else \
+ { \
+ GET_ET( num, pet ) \
+ }
+
+/*++
+ |
+ | Function Name: InquireEnumTypeInfo
+ |
+ | Function Description:
+ | Handles the PEXGetEnumTypeInfo request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex43rtn
+InquireEnumTypeInfo(pDrawable, itemMask, numEnumTypes, pEnumTypeList, pNumLists, pBuffer)
+/* in */
+ DrawablePtr pDrawable;
+ ddBitmask itemMask;
+ ddULONG numEnumTypes;
+ ddUSHORT *pEnumTypeList;
+/* out */
+ ddULONG *pNumLists;
+ ddBufferPtr pBuffer;
+{
+ register union
+ {
+ ddULONG *C32;
+ ddUSHORT *C16;
+ ddBYTE *C8;
+ } pbuf;
+
+ register int drawType;
+ register ddUSHORT *ptype;
+ register unsigned i,
+ j,
+ k;
+ ddUSHORT size;
+ short counting;
+ int count;
+ ddULONG num;
+ miEnumType *pet;
+
+ MI_WHICHDRAW(pDrawable, drawType);
+
+ *pNumLists = 0;
+ count = 0;
+ pBuffer->dataSize = 0;
+
+ /*
+ * loop twice. the first time, count buffer size needed second time,
+ * fill the buffer
+ */
+ for (counting = 1; counting >= 0; counting--)
+ {
+
+ /*
+ * be sure to put this here in case the buffer is realloc'd after the
+ * first time throught
+ */
+ pbuf.C32 = (ddULONG *) pBuffer->pBuf;
+ for (i = numEnumTypes, ptype = pEnumTypeList; i > 0; i--, ptype++)
+ {
+ /* process each enum request */
+
+ /*
+ * this is all hard coded (in miInfo.h) for the SI replace as
+ * needed if you don't want it hard coded
+ */
+ switch (*ptype)
+ {
+ case PEXETMarkerType:
+ num = SI_MARKER_NUM;
+ pet = &miMarkerTypeET[drawType][0];
+ DO_ET(num, pet);
+ break;
+
+ case PEXETATextStyle:
+ num = SI_ATEXT_NUM;
+ pet = miATextStyleET[drawType];
+ DO_ET(num, pet);
+ break;
+
+ case PEXETInteriorStyle:
+ num = SI_INT_NUM;
+ pet = miInteriorStyleET[drawType];
+ DO_ET(num, pet);
+ break;
+
+ case PEXETHatchStyle:
+ num = SI_HATCH_NUM;
+ pet = miHatchStyleET[drawType];
+ DO_ET(num, pet);
+ break;
+
+ case PEXETLineType:
+ num = SI_LINE_NUM;
+ pet = miLineTypeET[drawType];
+ DO_ET(num, pet);
+ break;
+
+ case PEXETSurfaceEdgeType:
+ num = SI_EDGE_NUM;
+ pet = miSurfaceEdgeTypeET[drawType];
+ DO_ET(num, pet);
+ break;
+
+ case PEXETPickDeviceType:
+ num = SI_PICK_DEVICE_NUM;
+ pet = miPickDeviceTypeET[drawType];
+ DO_ET(num, pet);
+ break;
+
+ case PEXETPolylineInterpMethod:
+ num = SI_LINE_INTERP_NUM;
+ pet = miPolylineInterpMethodET[drawType];
+ DO_ET(num, pet);
+ break;
+
+ case PEXETCurveApproxMethod:
+ num = SI_CURVE_APPROX_NUM;
+ pet = miCurveApproxMethodET[drawType];
+ DO_ET(num, pet);
+ break;
+
+ case PEXETReflectionModel:
+ num = SI_REFLECT_NUM;
+ pet = miReflectionModelET[drawType];
+ DO_ET(num, pet);
+ break;
+
+ case PEXETSurfaceInterpMethod:
+ num = SI_SURF_INTERP_NUM;
+ pet = miSurfaceInterpMethodET[drawType];
+ DO_ET(num, pet);
+ break;
+
+ case PEXETSurfaceApproxMethod:
+ num = SI_SURF_APPROX_NUM;
+ pet = miSurfaceApproxMethodET[drawType];
+ DO_ET(num, pet);
+ break;
+
+ case PEXETModelClipOperator:
+ num = SI_MODEL_CLIP_NUM;
+ pet = miModelClipOperatorET[drawType];
+ DO_ET(num, pet);
+ break;
+
+ case PEXETLightType:
+ num = SI_LIGHT_NUM;
+ pet = miLightTypeET[drawType];
+ DO_ET(num, pet);
+ break;
+
+ case PEXETColourType:
+ num = SI_COLOUR_NUM;
+ pet = miColourTypeET[drawType];
+ DO_ET(num, pet);
+ break;
+
+ case PEXETFloatFormat:
+ num = SI_FLOAT_NUM;
+ pet = miFloatFormatET[drawType];
+ DO_ET(num, pet);
+ break;
+
+ case PEXETHlhsrMode:
+ num = SI_HLHSR_NUM;
+ pet = miHlhsrModeET[drawType];
+ DO_ET(num, pet);
+ break;
+
+ case PEXETPromptEchoType:
+ num = SI_PET_NUM;
+ pet = miPromptEchoTypeET[drawType];
+ DO_ET(num, pet);
+ break;
+
+ case PEXETDisplayUpdateMode:
+ num = SI_UPDATE_NUM;
+ pet = miDisplayUpdateModeET[drawType];
+ DO_ET(num, pet);
+ break;
+
+ case PEXETColourApproxType:
+
+ /*
+ * The colour approximation type is based on the depth of the
+ * drawable - > 8 bits implies indexed otherwise colorspace
+ */
+ num = SI_CLR_APPROX_TYPE_NUM;
+ pet = miColourApproxTypeET[drawType];
+ DO_ET(num, pet);
+ break;
+
+ case PEXETColourApproxModel:
+ num = SI_CLR_APPROX_MODEL_NUM;
+ pet = miColourApproxModelET[drawType];
+ DO_ET(num, pet);
+ break;
+
+ case PEXETGDP:
+ num = SI_GDP_NUM;
+ pet = miGDPET[drawType];
+ DO_ET(num, pet);
+ break;
+
+ case PEXETGDP3:
+ num = SI_GDP3_NUM;
+ pet = miGDP3ET[drawType];
+ DO_ET(num, pet);
+ break;
+
+ case PEXETGSE:
+ num = SI_GSE_NUM;
+ pet = miGSEET[drawType];
+ DO_ET(num, pet);
+ break;
+
+ case PEXETTrimCurveApproxMethod:
+ num = SI_TRIM_CURVE_NUM;
+ pet = miTrimCurveApproxMethodET[drawType];
+ DO_ET(num, pet);
+ break;
+
+ case PEXETRenderingColourModel:
+ num = SI_REND_COLOUR_NUM;
+ pet = miRenderingColourModelET[drawType];
+ DO_ET(num, pet);
+ break;
+
+ case PEXETParaSurfCharacteristics:
+ num = SI_P_SURF_CHAR_NUM;
+ pet = miParametricSurfaceCharsET[drawType];
+ DO_ET(num, pet);
+ break;
+
+ case PEXETEscape:
+ num = SI_ESCAPE_NUM;
+ pet = miEscapeET[drawType];
+ DO_ET(num, pet);
+ break;
+
+ case PEXETPickOneMethod:
+ num = SI_PICK_ONE_NUM;
+ pet = miPickOneMethodET[drawType];
+ DO_ET(num, pet);
+ break;
+
+ case PEXETPickAllMethod:
+ num = SI_PICK_ALL_NUM;
+ pet = miPickAllMethodET[drawType];
+ DO_ET(num, pet);
+ break;
+
+ } /* switch (*ptype) */
+
+ } /* for (i=0, ptype = pEnumTypeList) */
+
+ if (counting)
+ {
+ PU_CHECK_BUFFER_SIZE(pBuffer, count);
+ }
+ } /* for (counting >= 0) */
+
+ pBuffer->dataSize = count;
+ return (Success);
+} /* InquireEnumTypeInfo */
+
+/*************************************************************************
+ * macro for MatchRendererTargets.
+ */
+
+/* 30 is arbitrary constant */
+#define ADD_TRIPLET(d,t,v) { int diff; \
+ if ((pexBuffer->dataSize + sizeof(pexRendererTarget)) > \
+ pexBuffer->bufSize){\
+ diff = (unsigned long)p - (unsigned long)pexBuffer->pBuf; \
+ puBuffRealloc(pexBuffer,pexBuffer->bufSize + \
+ 30*sizeof(pexRendererTarget)); \
+ p = (pexRendererTarget *)(((unsigned long)pexBuffer->pBuf) +diff);\
+ } \
+ p->depth = (d); \
+ p->type = (t); \
+ p->visualID = (v); \
+ pexBuffer->dataSize += sizeof(pexRendererTarget); \
+ p++; nTargets++; \
+ if (nTargets >= maxTriplets) return (Success); \
+ }
+/*++
+ |
+ | Function Name: MatchRendererTargets
+ |
+ | Function Description:
+ | Handles Match Renderer Taregets Request.
+ | Given a visualID, depth & drawable type, tell whether PEX will
+ | render into it. Real life: PEX does not do all drawables.
+ |
+ | Note(s):
+ |
+ --*/
+
+
+ddpex43rtn
+MatchRendererTargets(pDraw, depth, drawType, visualID, maxTriplets, pexBuffer)
+ DrawablePtr pDraw;
+ int depth;
+ int drawType;
+ VisualID visualID;
+ int maxTriplets;
+ ddBuffer *pexBuffer;
+{
+ int i;
+ int nTargets = 0;
+
+ register ScreenPtr pScreen;
+ int idepth, ivisual;
+ DepthPtr pDepth;
+
+ pexRendererTarget *p = (pexRendererTarget *)pexBuffer->pBuf;
+
+/*
+ * Code originally lifted from CreateWindow (x11/server/dix/window.c)
+ */
+ pScreen = pDraw->pScreen;
+
+ for(idepth = 0; idepth < pScreen->numDepths; idepth++) {
+
+ pDepth = (DepthPtr) &pScreen->allowedDepths[idepth];
+
+ /*
+ * if depth is wild carded, then we need to walk them all.
+ */
+ if ((depth == pDepth->depth) || (depth == 0)) {
+
+ for (ivisual = 0; ivisual < pDepth->numVids; ivisual++) {
+
+ /* if visual is a match or it's wildcarded then do it */
+ if ((visualID == pDepth->vids[ivisual]) || (visualID == 0)) {
+ /*
+ * Here is the moment of truth, this is just going to say
+ * that everything is available for PEX rendering. It is possible
+ * that vendors will want to create a global table that hangs
+ * around. That way they can be qualified in ddpexInit().
+ * If compiled with -DMULTIBUFFER it assumes that mutli buffers
+ * are fair game.
+ */
+ if ((drawType == PEXWindow) || (drawType == PEXDontCare))
+ ADD_TRIPLET(pDepth->depth, PEXWindow, pDepth->vids[ivisual] );
+ if ((drawType == PEXPixmap) || (drawType == PEXDontCare))
+ ADD_TRIPLET(pDepth->depth, PEXPixmap, pDepth->vids[ivisual] );
+#ifdef MULTIBUFFER
+ if ((drawType == PEXBuffer) || (drawType == PEXDontCare))
+ ADD_TRIPLET(pDepth->depth, PEXBuffer, pDepth->vids[ivisual] );
+#endif
+ }
+ }
+ }
+ }
+ return (Success);
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/shared/miNS.c b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miNS.c
new file mode 100644
index 000000000..fb745162e
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miNS.c
@@ -0,0 +1,446 @@
+/* $TOG: miNS.c /main/4 1998/02/10 12:45:17 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/shared/miNS.c,v 1.8 1999/01/31 12:21:31 dawes Exp $ */
+
+#include "mipex.h"
+#include "miNS.h"
+#include "miWks.h"
+#include "PEXErr.h"
+#include "pexUtils.h"
+#include "pexos.h"
+
+
+/* Level 4 Shared Resources */
+/* Name Set Procedures */
+
+/* DELETE_DD_NS is used to delete just the dd part of a resource */
+
+/* CHECK_DELETE is used to see if the resource has been freed and is
+ * no longer being used. If so, then the entire resource storage is
+ * freed, including the ddNSResource part
+ */
+
+#define DELETE_DD_NS( phead ) \
+ puDeleteList((phead)->wksRefList); \
+ puDeleteList((phead)->rendRefList); \
+ xfree(phead)
+
+#define CHECK_DELETE(pns,phead) \
+ if ( (phead)->freeFlag && !((phead)->refCount) && \
+ !((phead)->wksRefList->numObj) && !((phead)->rendRefList->numObj) ) \
+ { \
+ DELETE_DD_NS( phead ); \
+ xfree(pns); \
+ }
+static ddpex4rtn dynerr;
+extern ddpex4rtn miDealWithNSDynamics();
+
+/*++
+ |
+ | Function Name: CreateNameSet
+ |
+ | Function Description:
+ | Handles the PEXCreateNameSet request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex43rtn
+CreateNameSet(pNS)
+/* in */
+ diNSHandle pNS; /* name set handle */
+/* out */
+{
+ miNSHeader *pheader;
+
+#ifdef DDTEST
+ ErrorF( "\nCreateNameSet \n");
+#endif
+
+ pNS->deviceData = NULL;
+
+ if ((pheader = (miNSHeader *) xalloc(sizeof(miNSHeader))) == NULL)
+ {
+ pNS->deviceData = NULL;
+ return (BadAlloc);
+ }
+ if (!(pheader->wksRefList = puCreateList(DD_WKS)))
+ {
+ xfree(pheader);
+ return (BadAlloc);
+ }
+
+ if (!(pheader->rendRefList = puCreateList(DD_RENDERER)))
+ {
+ puDeleteList(pheader->wksRefList);
+ xfree(pheader);
+ return (BadAlloc);
+ }
+
+ pheader->nameCount = 0;
+ pheader->refCount = 0;
+ pheader->freeFlag = MI_FALSE;
+ MINS_EMPTY_NAMESET(pheader->names);
+
+ pNS->deviceData = (ddPointer) pheader;
+ return (Success);
+} /* CreateNameSet */
+
+
+static void
+mins_rend_changes(pNS, pheader)
+ diNSHandle pNS;
+ miNSHeader *pheader;
+{
+ register int i;
+ ddRendererPtr *pprend;
+
+ pprend = (ddRendererPtr *)pheader->rendRefList->pList;
+ for (i=0; i<pheader->rendRefList->numObj; i++, pprend++)
+ {
+ if ((pNS == (*pprend)->ns[DD_HIGH_INCL_NS]) ||
+ (pNS == (*pprend)->ns[DD_HIGH_EXCL_NS]))
+ (*pprend)->namesetsChanges |= PEXDynHighlightNamesetContents;
+ else
+ if ((pNS == (*pprend)->ns[DD_INVIS_INCL_NS]) ||
+ (pNS == (*pprend)->ns[DD_INVIS_EXCL_NS]))
+ (*pprend)->namesetsChanges |= PEXDynInvisibilityNamesetContents;
+ }
+}
+
+static void
+mins_wks_changes(pNS, pheader)
+ diNSHandle pNS;
+ miNSHeader *pheader;
+{
+ register int i;
+ diWKSHandle *phandle;
+ miWksPtr pwks;
+
+ if (pheader->wksRefList->numObj)
+ {
+ phandle = (diWKSHandle *)pheader->wksRefList->pList;
+ for (i=0; i<pheader->wksRefList->numObj; i++, phandle++)
+ {
+ pwks = (miWksPtr)((*phandle)->deviceData);
+ if ((pNS == pwks->pRend->ns[DD_HIGH_INCL_NS]) ||
+ (pNS == pwks->pRend->ns[DD_HIGH_EXCL_NS]))
+ pwks->pRend->namesetsChanges |= PEXDynHighlightNamesetContents;
+ else if ((pNS == pwks->pRend->ns[DD_INVIS_INCL_NS]) ||
+ (pNS == pwks->pRend->ns[DD_INVIS_EXCL_NS]))
+ pwks->pRend->namesetsChanges |= PEXDynInvisibilityNamesetContents;
+ }
+ }
+}
+
+/*++
+ |
+ | Function Name: CopyNameSet
+ |
+ | Function Description:
+ | Handles the PEXCopyNameSet request.
+ |
+ | Note(s):
+ both name set handles assumed to be valid
+ |
+ --*/
+
+ddpex43rtn
+CopyNameSet(pSrcNS, pDestNS)
+/* in */
+ diNSHandle pSrcNS; /* pointer to source name set */
+ diNSHandle pDestNS; /* pointer to destination name set */
+/* out */
+{
+ miNSHeader *psource = (miNSHeader *) pSrcNS->deviceData;
+ miNSHeader *pdest = (miNSHeader *) pDestNS->deviceData;
+
+#ifdef DDTEST
+ ErrorF( "\nCopyNameSet \n");
+#endif
+
+ MINS_COPY_NAMESET(psource->names, pdest->names);
+ pdest->nameCount = psource->nameCount;
+
+ mins_wks_changes(pDestNS, pdest);
+ mins_rend_changes(pDestNS, pdest);
+
+ dynerr = miDealWithNSDynamics(pDestNS);
+ return (Success);
+} /* CopyNameSet */
+
+/*++
+ |
+ | Function Name: FreeNameSet
+ |
+ | Function Description:
+ | Deletes all of the storage used by the name set if there are no resources
+ | using it, otherwise it sets the free flag in the name set. This function
+ | is registered with the resource id and handle by diPEX with AddResource.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex43rtn
+FreeNameSet(pNS, NSid)
+/* in */
+ diNSHandle pNS; /* name set handle */
+ ddResourceId NSid; /* name set resource id */
+/* out */
+{
+ miNSHeader *pheader = (miNSHeader *) pNS->deviceData;
+
+#ifdef DDTEST
+ ErrorF( "\nFreeNameSet \n");
+#endif
+
+ pheader->freeFlag = MI_TRUE;
+ pNS->id = PEXAlreadyFreed;
+ CHECK_DELETE(pNS, pheader);
+
+ return (Success);
+} /* FreeNameSet */
+
+/*++
+ |
+ | Function Name: InquireNameSet
+ |
+ | Function Description:
+ | Handles the PEXGetNameSet request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex43rtn
+InquireNameSet(pNS, pNumNames, pBuffer)
+/* in */
+ diNSHandle pNS; /* name set handle */
+/* out */
+ ddULONG *pNumNames;/* number of names in list */
+ ddBufferPtr pBuffer; /* list of names */
+{
+ register short i;
+ register ddULONG *pbuf;
+ miNSHeader *pheader = (miNSHeader *) pNS->deviceData;
+ ddULONG dsize;
+
+#ifdef DDTEST
+ ErrorF( "\nInquireNameSet \n");
+#endif
+
+ *pNumNames = 0;
+ dsize = pheader->nameCount * sizeof(ddULONG);
+
+ PU_CHECK_BUFFER_SIZE(pBuffer, dsize);
+
+ *pNumNames = pheader->nameCount;
+ pBuffer->dataSize = dsize;
+
+ if (!pheader->nameCount)
+ return(Success);
+
+ pbuf = (ddULONG *)pBuffer->pBuf;
+ for (i = MINS_MIN_NAME; i <= MINS_MAX_NAME; i++)
+ if ( MINS_IS_NAME_IN_SET(i, pheader->names) )
+ *pbuf++ = i;
+
+ return (Success);
+} /* InquireNameSet */
+
+/*++
+ |
+ | Function Name: ChangeNameSet
+ |
+ | Function Description:
+ | Handles the PEXChangeNameSet request.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex43rtn
+ChangeNameSet(pNS, action, numNames, pNames)
+/* in */
+ diNSHandle pNS; /* name set handle */
+ ddUSHORT action; /* (add/remove/replace) */
+ ddUSHORT numNames; /* number of names in list */
+ ddULONG *pNames; /* list of names */
+/* out */
+{
+ miNSHeader *pheader = (miNSHeader *) pNS->deviceData;
+ ddULONG *pn;
+
+#ifdef DDTEST
+ ErrorF( "\nChangeNameSet \n");
+#endif
+
+ switch (action)
+ {
+ case PEXNSReplace:
+
+#ifdef DDTEST
+ ErrorF( "\tREPLACE\n");
+#endif
+ pheader->nameCount = 0;
+ MINS_EMPTY_NAMESET(pheader->names);
+ /* continue to add */
+
+ case PEXNSAdd:
+
+#ifdef DDTEST
+ ErrorF( "\tADD\n");
+#endif
+
+ /* ignores any values that are out of range */
+ for (pn = pNames; numNames > 0; numNames--, pn++)
+ if ( MINS_VALID_NAME(*pn) &&
+ !MINS_IS_NAME_IN_SET(*pn, pheader->names) )
+ {
+ pheader->nameCount++;
+ MINS_ADD_TO_NAMESET(*pn, pheader->names);
+ }
+ break;
+
+ case PEXNSRemove:
+
+#ifdef DDTEST
+ ErrorF( "\tREMOVE\n");
+#endif
+
+ for (pn = pNames; numNames > 0; numNames--, pn++)
+ if ( MINS_VALID_NAME(*pn) &&
+ MINS_IS_NAME_IN_SET(*pn, pheader->names) )
+ {
+ pheader->nameCount--;
+ MINS_REMOVE_FROM_NAMESET(*pn, pheader->names);
+ }
+ break;
+
+ default:
+ /* better not get here */
+ return (BadValue);
+ break;
+ }
+
+ mins_wks_changes(pNS, pheader);
+ mins_rend_changes(pNS, pheader);
+
+ /* update the picture if necessary */
+ dynerr = miDealWithNSDynamics(pNS);
+ return (Success);
+} /* ChangeNameSet */
+
+/*++
+ |
+ | Function Name: UpdateNSRefs
+ |
+ | Function Description:
+ | Utility function to update a cross-reference list in the name set. Each
+ | name set has two lists, one for workstations and one for renderers. The
+ | lists are of handles of the resources which are using the name set.
+ |
+ | Note(s):
+ |
+ --*/
+
+ddpex43rtn
+UpdateNSRefs(pNS, pResource, which, action)
+/* in */
+ diNSHandle pNS; /* name set handle */
+ diResourceHandle pResource;/* workstation or renderer handle */
+ ddResourceType which; /* wks renderer or pick device */
+ ddAction action; /* add or remove */
+/* out */
+{
+ miNSHeader *pheader = (miNSHeader *) pNS->deviceData;
+
+#ifdef DDTEST
+ ErrorF( "\nUpdateNSRefs \n");
+#endif
+
+ switch (which)
+ {
+ case WORKSTATION_RESOURCE:
+ if (action == ADD)
+ {
+ if (puAddToList((ddPointer) & pResource, (ddULONG) 1,
+ pheader->wksRefList) == MI_ALLOCERR)
+ return (BadAlloc);
+ } else
+ puRemoveFromList((ddPointer) & pResource, pheader->wksRefList);
+ break;
+
+ case SEARCH_CONTEXT_RESOURCE:
+ case PICK_RESOURCE:
+ if (action == ADD)
+ pheader->refCount++;
+ else
+ if (pheader->refCount)
+ pheader->refCount--;
+ break;
+
+ case RENDERER_RESOURCE:
+
+ if (action == ADD)
+ {
+ if (puAddToList((ddPointer) & pResource, (ddULONG) 1,
+ pheader->rendRefList))
+ return (BadAlloc);
+ } else
+ puRemoveFromList((ddPointer) & pResource, pheader->rendRefList);
+
+ break;
+
+ default: /* better not get here */
+ return (BadValue);
+ break;
+ }
+ CHECK_DELETE(pNS, pheader);
+ return (Success);
+} /* UpdateNSRefs */
+
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/shared/miPattLUT.c b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miPattLUT.c
new file mode 100644
index 000000000..ccf236de3
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miPattLUT.c
@@ -0,0 +1,433 @@
+/* $TOG: miPattLUT.c /main/5 1998/02/10 12:45:24 kaleb $ */
+/*
+
+Copyright 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/shared/miPattLUT.c,v 1.7 1998/10/04 09:34:52 dawes Exp $ */
+
+#include "miLUT.h"
+#include "miWks.h"
+#include "miInfo.h"
+#include "PEXErr.h"
+#include "PEXprotost.h"
+#include "pexos.h"
+
+
+/* Level 4 Shared Resources */
+/* Lookup Table Procedures */
+
+/* pattern tables don't have to be implemented. define PEX_PATTERN_LUT
+ * here if they are
+ */
+/* PEX-SI officially doesn't implement pattern tables, but the
+ * API doesn't handle it correctly yet if they aren't implemented,
+ * so pretend that they are
+ */
+#define PEX_PATTERN_LUT
+
+extern unsigned colour_type_sizes[]; /* in miLUT.c */
+
+/* definitions used by miLUTProcs.ci */
+#define LUT_TYPE PEXPatternLUT
+
+/* devPriv data structure */
+#define DD_LUT_ENTRY_STR ddPatternEntry
+/* table entry data structure */
+#define MI_LUT_ENTRY_STR miPatternEntry
+/* pex data */
+#define PEX_LUT_ENTRY_STR pexPatternEntry
+
+#define LUT_REND_DYN_BIT PEXDynPatternTableContents
+
+#define LUT_START_INDEX 1
+#define LUT_DEFAULT_INDEX 1
+#define LUT_0_DEFINABLE_ENTRIES 0
+#define LUT_0_NUM_PREDEFINED 0
+#define LUT_0_PREDEFINED_MIN 0
+#define LUT_0_PREDEFINED_MAX 0
+
+#define LUT_TABLE_START(pheader) (pheader)->plut.pattern
+
+#define DYNAMIC PATTERN_TABLE_DYNAMIC
+
+/* predefined entries table: change this to work with your devPriv data */
+
+#define PDE_NUMX 1
+#define PDE_NUMY 1
+
+#if LUT_0_NUM_PREDEFINED
+static DD_LUT_ENTRY_STR pdePatternEntry[LUT_0_NUM_PREDEFINED];
+static ddIndexedColour pdeColours[PDE_NUMX][PDE_NUMY] = {};
+#else /* use dummies so things compile */
+static DD_LUT_ENTRY_STR pdePatternEntry[1];
+static ddIndexedColour pdeColours[PDE_NUMX][PDE_NUMY] = {1};
+#endif /* LUT_0_NUM_PREDEFINED */
+
+#define LUT_PDE_ENTRIES pdePatternEntry[0]
+#define LUT_SET_PDE_ENTRY(pentry, pdeentry) \
+ (pentry)->entry = *(pdeentry); \
+ (pentry)->entry.colours.indexed = (ddIndexedColour *)xalloc( \
+ (pentry)->entry.numx * (pentry)->entry.numy * sizeof(colour_type_sizes[(int)(pentry)->entry.colourType])); \
+ mibcopy((pdeentry)->colours.indexed, (pentry)->entry.colours.indexed, \
+ (pentry)->entry.numx * (pentry)->entry.numy * sizeof(colour_type_sizes[(int)(pentry)->entry.colourType]))
+
+/* predefined entry 0 is set to the default values
+ * change the XXX_DEFAULT_YYY macros below to use something else
+ * if you don't want the default values defined in the pde table
+ */
+#define PDE_DEFAULT_ENTRY_NUM 0
+#define LUT_DEFAULT_VALUES pdePatternEntry[PDE_DEFAULT_ENTRY_NUM]
+#define LUT_SET_DEFAULT_VALUES(pentry) \
+ (pentry)->entry.numx = 0; \
+ (pentry)->entry.numy = 0
+
+/* which procedure definitions in miLUTProcs.h to use and their names
+ * take out USE flags if you're defining those procs in here
+ * but leave the name definitions
+ */
+
+/* if pattern tables are implemented, use these procedures in
+ * miLUTProcs.h; the other procs are defined below.
+ * if pattern tables aren't implemented, then the create proc
+ * returns an error and so there won't be a pattern table
+ * (dipex will get bad XID for other requests on the table)
+ */
+#define LUT_USE_FREE
+#define LUT_USE_INQ_PREDEF
+#define LUT_USE_INQ_ENTRIES
+/* #define LUT_USE_COPY */
+#define LUT_USE_INQ_INFO
+#define LUT_USE_INQ_IND
+#define LUT_USE_INQ_ENTRY
+#define LUT_USE_SET_ENTRIES
+#define LUT_USE_DEL_ENTRIES
+#define LUT_USE_INQ_ENTRY_ADDRESS
+/* #define LUT_USE_CREATE */
+#define LUT_USE_MOD_CALL_BACK
+
+/* these three are redefined in miLUTProcs.h
+#define LUT_FREE PatternLUT_free
+#define LUT_INQ_PREDEF PatternLUT_inq_predef
+#define LUT_INQ_ENTRIES PatternLUT_inq_entries
+*/
+#define LUT_COPY PatternLUT_copy
+#define LUT_INQ_INFO PatternLUT_inq_info
+#define LUT_INQ_IND PatternLUT_inq_ind
+#define LUT_INQ_ENTRY PatternLUT_inq_entry
+#define LUT_SET_ENTRIES PatternLUT_set_entries
+#define LUT_DEL_ENTRIES PatternLUT_del_entries
+#define LUT_INQ_ENTRY_ADDRESS PatternLUT_inq_entry_address
+#define LUT_CREATE PatternLUT_create
+#define LUT_ENTRY_CHECK PatternLUT_entry_check
+#define LUT_COPY_PEX_MI PatternLUT_copy_pex_to_mi
+#define LUT_COPY_MI_PEX PatternLUT_copy_mi_to_pex
+#define LUT_MOD_CALL_BACK PatternLUT_mod_call_back
+
+/* copy from an mi entry to a pex entry and increment ppbuf */
+ddpex43rtn
+LUT_COPY_MI_PEX ( pheader, valueType, pentry, ppbuf )
+ miLUTHeader *pheader;
+ ddUSHORT valueType;
+ MI_LUT_ENTRY_STR *pentry;
+ ddPointer *ppbuf;
+{
+ ddPointer pb = *ppbuf;
+ DD_LUT_ENTRY_STR *pdev_entry;
+
+ if (pentry == NULL)
+ pdev_entry = &(LUT_DEFAULT_VALUES);
+ else if (pentry->entry_info.status == MILUT_UNDEFINED)
+ pdev_entry = &(LUT_DEFAULT_VALUES);
+ else
+ pdev_entry = &pentry->entry;
+
+ mibcopy(pdev_entry, pb, sizeof(PEX_LUT_ENTRY_STR));
+
+ pb+= sizeof(PEX_LUT_ENTRY_STR);
+
+ mibcopy(pdev_entry->colours.indexed, pb,
+ pdev_entry->numx * pdev_entry->numy * colour_type_sizes[(int)pdev_entry->colourType]);
+
+ pb += pdev_entry->numx * pdev_entry->numy * colour_type_sizes[(int)pdev_entry->colourType];
+ *ppbuf = pb;
+ return(Success);
+}
+
+/* copy from a pex entry to an mi entry and increment ppsrc */
+ddpex43rtn
+LUT_COPY_PEX_MI ( pheader, ppsrc, pentry )
+ miLUTHeader *pheader;
+ ddPointer *ppsrc;
+ MI_LUT_ENTRY_STR *pentry;
+{
+ ddPointer ps = *ppsrc;
+ ddULONG xy1, xy2;
+ ddSHORT colourType;
+
+ xy1 = pentry->entry.numx * pentry->entry.numy;
+ colourType = pentry->entry.colourType;
+
+ mibcopy(ps, &(pentry->entry), sizeof(PEX_LUT_ENTRY_STR));
+
+ xy2 = pentry->entry.numx * pentry->entry.numy;
+
+ ps+= sizeof(PEX_LUT_ENTRY_STR);
+
+ if ((xy1 * colour_type_sizes[(int)colourType]) <
+ (xy2 * colour_type_sizes[(int)pentry->entry.colourType]))
+ {
+ pentry->entry.colours.indexed = (ddIndexedColour *)xrealloc(
+ pentry->entry.colours.indexed,
+ xy2 * colour_type_sizes[(int)pentry->entry.colourType]);
+ if (!pentry->entry.colours.indexed)
+ return(BadAlloc);
+ }
+
+ mibcopy(ps, pentry->entry.colours.indexed,
+ xy2 * colour_type_sizes[(int)pentry->entry.colourType]);
+
+ ps += xy2 * colour_type_sizes[(int)pentry->entry.colourType];
+ *ppsrc = ps;
+ return(Success);
+}
+
+/* check for bad values and increment ppPexEntry */
+
+ddpex43rtn
+LUT_ENTRY_CHECK (pheader, ppPexEntry)
+ miLUTHeader *pheader;
+ PEX_LUT_ENTRY_STR **ppPexEntry;
+{
+ ddPointer pe = (ddPointer)*ppPexEntry;
+ ddULONG xy;
+
+ /* colours: only accept supported colour types */
+ if (MI_BADCOLOURTYPE((*ppPexEntry)->colourType))
+ return(PEXERR(PEXColourTypeError));
+
+ xy = (*ppPexEntry)->numx * (*ppPexEntry)->numy;
+
+ pe += sizeof(PEX_LUT_ENTRY_STR) +
+ xy * colour_type_sizes[(int)(*ppPexEntry)->colourType];
+ *ppPexEntry = (PEX_LUT_ENTRY_STR *)pe;
+
+ return(Success);
+}
+
+void
+PatternLUT_init_pde()
+{
+#ifdef PEX_PATTERN_LUT
+#if LUT_0_NUM_PREDEFINED
+ pdePatternEntry[0].colourType = PEXIndexedColour;
+ pdePatternEntry[0].numx = PDE_NUMX;
+ pdePatternEntry[0].numy = PDE_NUMY;
+ pdePatternEntry[0].colours.indexed = &pdeColours[0][0];
+#endif /* LUT_0_NUM_PREDEFINED */
+#endif /* PEX_PATTERN_LUT */
+}
+
+#include "miLUTProcs.ci"
+
+ddpex43rtn
+LUT_COPY (pSrcLUT, pDestLUT)
+/* in */
+ diLUTHandle pSrcLUT; /* source lookup table */
+ diLUTHandle pDestLUT; /* destination lookup table */
+/* out */
+{
+ MILUT_DEFINE_HEADER(pSrcLUT, srcHeader);
+ MILUT_DEFINE_HEADER(pDestLUT, destHeader);
+ register int i;
+ MI_LUT_ENTRY_STR *pDestEntry;
+ MI_LUT_ENTRY_STR *pSrcEntry;
+ ddpex43rtn err;
+ ddIndexedColour *psaveColours;
+ ddULONG xy;
+ ddSHORT saveType;
+
+#ifdef DDTEST
+ ErrorF( "\ncopy src lut %d type %d\n", pSrcLUT->id, pSrcLUT->lutType);
+ ErrorF( "\ncopy dest lut %d type %d\n", pDestLUT->id, pDestLUT->lutType);
+#endif
+
+ /* set all entries to undefined */
+ pDestEntry = LUT_TABLE_START(destHeader);
+ MILUT_SET_STATUS(pDestEntry, MILUT_ALLOC_ENTS(destHeader), MILUT_UNDEFINED, MI_FALSE);
+
+ /* copy entries */
+ pDestEntry = LUT_TABLE_START(destHeader);
+ pSrcEntry = LUT_TABLE_START(srcHeader);
+
+ for (i = MILUT_START_INDEX(srcHeader); i < MILUT_ALLOC_ENTS(srcHeader); i++)
+ {
+ xy = pDestEntry->entry.numx * pDestEntry->entry.numy;
+ psaveColours = pDestEntry->entry.colours.indexed;
+ saveType = pDestEntry->entry.colourType;
+
+ mibcopy(pSrcEntry, pDestEntry, sizeof(miPatternEntry));
+
+ /* copy colours */
+ pDestEntry->entry.colours.indexed = psaveColours;
+ if ( (xy * colour_type_sizes[(int)saveType]) <
+ (pSrcEntry->entry.numx * pSrcEntry->entry.numy *
+ colour_type_sizes[(int)pSrcEntry->entry.colourType]) )
+ {
+ pDestEntry->entry.colours.indexed =
+ (ddIndexedColour *)xrealloc(pDestEntry->entry.colours.indexed,
+ (pSrcEntry->entry.numx * pSrcEntry->entry.numy *
+ colour_type_sizes[(int)pSrcEntry->entry.colourType]));
+ if (!pDestEntry->entry.colours.indexed)
+ return(BadAlloc);
+ }
+ mibcopy( pSrcEntry->entry.colours.indexed, pDestEntry->entry.colours.indexed,
+ (pSrcEntry->entry.numx * pSrcEntry->entry.numy *
+ colour_type_sizes[(int)pSrcEntry->entry.colourType]) );
+ pSrcEntry++;
+ pDestEntry++;
+ }
+
+ MILUT_NUM_ENTS(destHeader) = MILUT_NUM_ENTS(srcHeader);
+
+ err = Success;
+
+#ifdef DYNAMIC
+ if (destHeader->wksRefList->numObj)
+ err = miDealWithDynamics( DYNAMIC, destHeader->wksRefList );
+#endif /* DYNAMIC */
+
+ err = destHeader->ops[MILUT_REQUEST_OP(milut_mod_call_back)](pDestLUT,
+ MILUT_START_INDEX(destHeader), MILUT_DEF_ENTS(destHeader),
+ MILUT_COPY_MOD);
+ /* check err here if your call back proc can return an error */
+ if (err != Success) return(err);
+
+ return (err);
+}
+
+ddpex43rtn
+LUT_CREATE (pLUT, pheader)
+/* in */
+ diLUTHandle pLUT; /* lut handle */
+ miLUTHeader *pheader; /* lut header */
+/* out */
+{
+ register int i;
+ MI_LUT_ENTRY_STR *pentry;
+ DD_LUT_ENTRY_STR *pdeentry;
+
+#ifdef DDTEST
+ ErrorF( "\ncreate lut %d type %d\n", pLUT->id, pLUT->lutType);
+#endif
+
+#ifndef PEX_PATTERN_LUT
+ return(PEXERR(PEXLookupTableError));
+#else
+
+ MILUT_START_INDEX(pheader) = LUT_START_INDEX;
+ MILUT_DEFAULT_INDEX(pheader) = LUT_DEFAULT_INDEX;
+ MILUT_NUM_ENTS(pheader) = 0;
+ SET_TABLE_INFO( pheader->drawType, &(pheader->tableInfo) );
+
+ if (MILUT_ALLOC_ENTS(pheader) == 0)
+ {
+ LUT_TABLE_START(pheader) = NULL;
+ }
+ else if ((LUT_TABLE_START(pheader) = (MI_LUT_ENTRY_STR *)
+ xalloc(MILUT_ALLOC_ENTS(pheader) * sizeof(MI_LUT_ENTRY_STR)))
+ == NULL)
+ {
+ MILUT_DESTROY_HEADER(pheader);
+ return(BadAlloc);
+ }
+
+ pentry = LUT_TABLE_START(pheader);
+ MILUT_SET_STATUS(pentry, MILUT_ALLOC_ENTS(pheader), MILUT_UNDEFINED, MI_TRUE);
+
+ pentry = LUT_TABLE_START(pheader);
+ for (i=0; i<MILUT_ALLOC_ENTS(pheader); i++, pentry++)
+ {
+ pentry->entry.numx=0; pentry->entry.numy=0;
+ pentry->entry.colourType=0;
+ pentry->entry.colours.indexed = (ddIndexedColour *)NULL;
+ }
+
+ /* if there are predefined entries, put them in */
+ if (MILUT_PRENUM(pheader))
+ {
+ pentry = LUT_TABLE_START(pheader) + MILUT_PREMIN(pheader);
+ pdeentry = &(LUT_PDE_ENTRIES);
+
+ for (i=MILUT_PREMIN(pheader);
+ i<=MILUT_PREMAX(pheader); i++, pentry++, pdeentry++)
+ {
+ pentry->entry_info.status = MILUT_PREDEFINED;
+ pentry->entry_info.index = i;
+ pentry->entry = *pdeentry;
+ pentry->entry.colours.indexed = (ddIndexedColour *)xalloc(
+ pentry->entry.numx * pentry->entry.numy * sizeof(colour_type_sizes[(int)pentry->entry.colourType]));
+ mibcopy(pdeentry->colours.indexed, pentry->entry.colours.indexed,
+ pentry->entry.numx * pentry->entry.numy * sizeof(colour_type_sizes[(int)pentry->entry.colourType]));
+ pheader->numDefined++;
+ }
+ }
+
+ pheader->ops[MILUT_REQUEST_OP(PEX_CreateLookupTable)] = LUT_CREATE;
+ pheader->ops[MILUT_REQUEST_OP(PEX_CopyLookupTable)] = LUT_COPY;
+ pheader->ops[MILUT_REQUEST_OP(PEX_FreeLookupTable)] = LUT_FREE;
+ pheader->ops[MILUT_REQUEST_OP(PEX_GetTableInfo)] = LUT_INQ_INFO;
+ pheader->ops[MILUT_REQUEST_OP(PEX_GetPredefinedEntries)] = LUT_INQ_PREDEF;
+ pheader->ops[MILUT_REQUEST_OP(PEX_GetDefinedIndices)] = LUT_INQ_IND;
+ pheader->ops[MILUT_REQUEST_OP(PEX_GetTableEntry)] = LUT_INQ_ENTRY;
+ pheader->ops[MILUT_REQUEST_OP(PEX_GetTableEntries)] = LUT_INQ_ENTRIES;
+ pheader->ops[MILUT_REQUEST_OP(PEX_SetTableEntries)] = LUT_SET_ENTRIES;
+ pheader->ops[MILUT_REQUEST_OP(PEX_DeleteTableEntries)] = LUT_DEL_ENTRIES;
+ pheader->ops[MILUT_REQUEST_OP(milut_InquireEntryAddress)] = LUT_INQ_ENTRY_ADDRESS;
+ pheader->ops[MILUT_REQUEST_OP(milut_entry_check)] = LUT_ENTRY_CHECK;
+ pheader->ops[MILUT_REQUEST_OP(milut_copy_pex_to_mi)] = LUT_COPY_PEX_MI;
+ pheader->ops[MILUT_REQUEST_OP(milut_copy_mi_to_pex)] = LUT_COPY_MI_PEX;
+
+ pLUT->deviceData = (ddPointer) pheader;
+ return (Success);
+#endif /* PEX_PATTERN_LUT */
+}
+
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/shared/miTextLUT.c b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miTextLUT.c
new file mode 100644
index 000000000..0f0b0af19
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miTextLUT.c
@@ -0,0 +1,257 @@
+/* $TOG: miTextLUT.c /main/3 1998/02/10 12:45:30 kaleb $ */
+
+/*
+
+Copyright 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/shared/miTextLUT.c,v 1.7 1998/10/04 09:34:53 dawes Exp $ */
+
+#include "miLUT.h"
+#include "miWks.h"
+#include "miInfo.h"
+#include "PEXErr.h"
+#include "PEXprotost.h"
+#include "pexos.h"
+
+
+/* Level 4 Shared Resources */
+/* Lookup Table Procedures */
+
+extern unsigned colour_type_sizes[]; /* in miLUT.c */
+
+/* definitions used by miLUTProcs.ci */
+#define LUT_TYPE PEXTextBundleLUT
+
+/* devPriv data structure */
+#define DD_LUT_ENTRY_STR ddTextBundleEntry
+/* table entry data structure */
+#define MI_LUT_ENTRY_STR miTextBundleEntry
+/* pex data */
+#define PEX_LUT_ENTRY_STR pexTextBundleEntry
+
+#define LUT_REND_DYN_BIT PEXDynTextBundleContents
+
+#define LUT_START_INDEX 1
+#define LUT_DEFAULT_INDEX 1
+#define LUT_0_DEFINABLE_ENTRIES 20
+#define LUT_0_NUM_PREDEFINED 1
+#define LUT_0_PREDEFINED_MIN 1
+#define LUT_0_PREDEFINED_MAX 1
+
+#define LUT_TABLE_START(pheader) (pheader)->plut.text
+
+#define DYNAMIC TEXT_BUNDLE_DYNAMIC
+
+/* predefined entries table: change this to work with your devPriv data */
+static DD_LUT_ENTRY_STR pdeTextBundleEntry[LUT_0_NUM_PREDEFINED];
+#define LUT_PDE_ENTRIES pdeTextBundleEntry[0]
+#define LUT_SET_PDE_ENTRY(pentry, pdeentry) \
+ (pentry)->entry = *(pdeentry); \
+ (pentry)->real_entry = *(pdeentry)
+
+/* predefined entry 0 is set to the default values
+ * change the XXX_DEFAULT_YYY macros below to use something else
+ * if you don't want the default values defined in the pde table
+ */
+#define PDE_DEFAULT_ENTRY_NUM 0
+#define LUT_DEFAULT_VALUES pdeTextBundleEntry[PDE_DEFAULT_ENTRY_NUM]
+#define LUT_SET_DEFAULT_VALUES(pentry) \
+ (pentry)->entry = LUT_DEFAULT_VALUES; \
+ (pentry)->real_entry = LUT_DEFAULT_VALUES
+
+/* which procedure definitions in miLUTProcs.h to use and their names
+ * take out USE flags if you're defining those procs in here
+ * but leave the name definitions
+ */
+
+#define LUT_USE_FREE
+#define LUT_USE_INQ_PREDEF
+#define LUT_USE_INQ_ENTRIES
+#define LUT_USE_COPY
+#define LUT_USE_INQ_INFO
+#define LUT_USE_INQ_IND
+#define LUT_USE_INQ_ENTRY
+#define LUT_USE_SET_ENTRIES
+#define LUT_USE_DEL_ENTRIES
+#define LUT_USE_INQ_ENTRY_ADDRESS
+#define LUT_USE_CREATE
+#define LUT_USE_MOD_CALL_BACK
+
+/* these three are redefined in miLUTProcs.h
+#define LUT_FREE TextBundleLUT_free
+#define LUT_INQ_PREDEF TextBundleLUT_inq_predef
+#define LUT_INQ_ENTRIES TextBundleLUT_inq_entries
+*/
+#define LUT_COPY TextBundleLUT_copy
+#define LUT_INQ_INFO TextBundleLUT_inq_info
+#define LUT_INQ_IND TextBundleLUT_inq_ind
+#define LUT_INQ_ENTRY TextBundleLUT_inq_entry
+#define LUT_SET_ENTRIES TextBundleLUT_set_entries
+#define LUT_DEL_ENTRIES TextBundleLUT_del_entries
+#define LUT_INQ_ENTRY_ADDRESS TextBundleLUT_inq_entry_address
+#define LUT_CREATE TextBundleLUT_create
+#define LUT_ENTRY_CHECK TextBundleLUT_entry_check
+#define LUT_COPY_PEX_MI TextBundleLUT_copy_pex_to_mi
+#define LUT_COPY_MI_PEX TextBundleLUT_copy_mi_to_pex
+#define LUT_MOD_CALL_BACK TextBundleLUT_mod_call_back
+#define LUT_REALIZE_ENTRY TextBundleLUT_realize_entry
+
+/* copy from an mi entry to a pex entry and increment ppbuf */
+ddpex43rtn
+LUT_COPY_MI_PEX ( pheader, valueType, pentry, ppbuf )
+ miLUTHeader *pheader;
+ ddUSHORT valueType;
+ MI_LUT_ENTRY_STR *pentry;
+ ddPointer *ppbuf;
+{
+ ddPointer pb = *ppbuf;
+ DD_LUT_ENTRY_STR *pdev_entry;
+
+ if (pentry == NULL)
+ pdev_entry = &(LUT_DEFAULT_VALUES);
+ else if (pentry->entry_info.status == MILUT_UNDEFINED)
+ pdev_entry = &(LUT_DEFAULT_VALUES);
+ else
+ if (valueType == PEXRealizedValue)
+ pdev_entry = &pentry->real_entry;
+ else
+ pdev_entry = &pentry->entry;
+
+ mibcopy(pdev_entry, pb, sizeof(PEX_LUT_ENTRY_STR));
+
+ pb+= sizeof(PEX_LUT_ENTRY_STR);
+
+ MILUT_COPY_COLOUR(&pdev_entry->textColour.colour,
+ pb, pdev_entry->textColour.colourType);
+
+ pb += colour_type_sizes[(int)pdev_entry->textColour.colourType];
+ *ppbuf = pb;
+ return(Success);
+}
+
+/* copy from a pex entry to an mi entry and increment ppsrc */
+ddpex43rtn
+LUT_COPY_PEX_MI ( pheader, ppsrc, pentry )
+ miLUTHeader *pheader;
+ ddPointer *ppsrc;
+ MI_LUT_ENTRY_STR *pentry;
+{
+ ddPointer ps = *ppsrc;
+
+ mibcopy(ps, &(pentry->entry), sizeof(PEX_LUT_ENTRY_STR));
+
+ ps+= sizeof(PEX_LUT_ENTRY_STR);
+
+ MILUT_COPY_COLOUR(ps, &(pentry->entry.textColour.colour),
+ pentry->entry.textColour.colourType);
+
+ LUT_REALIZE_ENTRY( pheader, pentry );
+
+ ps += colour_type_sizes[(int)pentry->entry.textColour.colourType];
+ *ppsrc = ps;
+ return(Success);
+}
+
+/* check for bad values and increment ppPexEntry */
+
+ddpex43rtn
+LUT_ENTRY_CHECK (pheader, ppPexEntry)
+ miLUTHeader *pheader;
+ PEX_LUT_ENTRY_STR **ppPexEntry;
+{
+ ddPointer pe = (ddPointer)*ppPexEntry;
+
+ /* textFont: any value OK. this is an index into the font table */
+
+ /* textPrecision: must be String, Char, or Stroke */
+ if (((*ppPexEntry)->textPrecision != PEXStringPrecision) &&
+ ((*ppPexEntry)->textPrecision != PEXCharPrecision) &&
+ ((*ppPexEntry)->textPrecision != PEXStrokePrecision))
+ return(BadValue);
+
+ /* charExpansion: any value OK. use closest magnitude if it's not supported */
+ /* charSpacing: any value is OK */
+
+ /* colours: only accept supported colour types */
+ if (MI_BADCOLOURTYPE((*ppPexEntry)->textColour.colourType))
+ return(PEXERR(PEXColourTypeError));
+
+ pe += sizeof(PEX_LUT_ENTRY_STR) +
+ colour_type_sizes[(int)(*ppPexEntry)->textColour.colourType];
+ *ppPexEntry = (PEX_LUT_ENTRY_STR *)pe;
+ return(Success);
+}
+
+/* realize entry */
+ddpex43rtn
+LUT_REALIZE_ENTRY( pheader, pEntry )
+ miLUTHeader *pheader;
+ MI_LUT_ENTRY_STR *pEntry;
+{
+ /* textPrecision: realized value can only be determined at
+ * traversal time since it depends on the font used and on
+ * the string being rendered. it looks like it will probably
+ * only differ if a font group has X and PEX fonts in it.
+ * PEX-SI does not support X fonts in a font group, so this
+ * should be correct for PEX-SI.
+ */
+ /* charExpansion: use closest supported magnitude.
+ * will be based on imp dep values, but they aren't in
+ * spec yet, so just put magnitude for now.
+ * todo: define values even though they aren't returned by
+ * inqimpdepconstants yet.
+ */
+ pEntry->real_entry = pEntry->entry;
+ pEntry->real_entry.charExpansion = ABS(pEntry->entry.charExpansion);
+}
+
+void
+TextBundleLUT_init_pde()
+{
+ pdeTextBundleEntry[0].textFontIndex = 1;
+ pdeTextBundleEntry[0].textPrecision = PEXStringPrecision;
+ pdeTextBundleEntry[0].charExpansion = 1.0;
+ pdeTextBundleEntry[0].charSpacing = 0.0;
+ MILUT_INIT_COLOUR(pdeTextBundleEntry[0].textColour);
+}
+
+#include "miLUTProcs.ci"
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/shared/miUtils.c b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miUtils.c
new file mode 100644
index 000000000..ae716fd41
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miUtils.c
@@ -0,0 +1,624 @@
+/* $TOG: miUtils.c /main/6 1998/02/10 12:45:37 kaleb $ */
+/*
+
+Copyright 1989, 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1989, 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/shared/miUtils.c,v 1.7 1998/10/04 09:34:53 dawes Exp $ */
+
+#include "mipex.h"
+#include "PEX.h"
+#include "PEXprotost.h"
+#include "ddpex3.h"
+#include "miRender.h"
+#include "miWks.h"
+#include "pexos.h"
+
+
+/*++
+ |
+ | Function Name: miMatIdent
+ |
+ | Function Description:
+ | initializes 4x4 matrices to identity.
+ |
+ --*/
+
+void
+miMatIdent(m)
+ ddFLOAT m[4][4];
+{
+ int i, j;
+
+ for (i=0; i<4; i++) {
+ for (j=0; j<4; j++) {
+ m[i][j] = ((i==j) ? 1.0 : 0.0);
+ }
+ }
+}
+
+/*++
+ |
+ | Function Name: miMatCopy
+ |
+ | Function Description:
+ | copies 4x4 mat
+ |
+ --*/
+
+void
+miMatCopy(src, dest)
+ ddFLOAT src[4][4];
+ ddFLOAT dest[4][4];
+{
+ int i, j;
+
+ for (i=0; i<4; i++) {
+ for (j=0; j<4; j++) {
+ dest[i][j] = src[i][j];
+ }
+ }
+}
+
+/*++
+ |
+ | Function Name: miMatTranspose
+ |
+ | Function Description:
+ | transposes 4x4 matrices.
+ |
+ --*/
+
+void
+miMatTranspose(m)
+ ddFLOAT m[4][4];
+{
+ int i, j;
+ ddFLOAT t;
+
+ for (i=1; i<4; i++) {
+ for (j=0; j<i; j++) {
+ t = m[i][j];
+ m[i][j] = m[j][i];
+ m[j][i] = t;
+ }
+ }
+}
+
+/*++
+ |
+ | Function Name: miMatMult
+ |
+ | Function Description:
+ | implements m = b x a for 4x4 matrices.
+ |
+ | Note(s):
+ |
+ | NOTE the order of the multiply: BxA *NOT* AxB
+ |
+ --*/
+
+void
+miMatMult(m, a, b)
+ddFLOAT m[4][4];
+ddFLOAT a[4][4];
+ddFLOAT b[4][4];
+{
+ register int i,j,k;
+ register float *col_ptr;
+ register float *row_ptr;
+ register float *result;
+
+ if ((m != a) && (m != b))
+ {
+ result = &(m[0][0]);
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ *result = 0.0;
+ col_ptr = &(b[i][0]);
+ row_ptr = &(a[0][j]);
+ for (k = 0; k < 4; k++) {
+ *result += *row_ptr * *(col_ptr++);
+ row_ptr += 4;
+ }
+ result++;
+ }
+ }
+ } else {
+ float t[4][4];
+
+ result = &(t[0][0]);
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ *result = 0.0;
+ col_ptr = &(b[i][0]);
+ row_ptr = &(a[0][j]);
+ for (k = 0; k < 4; k++) {
+ *result += *row_ptr * *(col_ptr++);
+ row_ptr += 4;
+ }
+ result++;
+ }
+ }
+ memcpy( (char *)m, (char *)t, 16*sizeof(float));
+ }
+}
+
+/*++
+ |
+ | Function Name: miPrintVertList
+ |
+ | Function Description: print a formatted version of the
+ | miListHeader structure and its contents.
+ |
+ --*/
+
+void
+miPrintVertList(vinput)
+/* in */
+miListHeader *vinput;
+{
+ int i, j;
+ listofddPoint *pddlist;
+ int vert_count;
+ char *pt;
+ int point_size;
+
+ /*
+ * Print each list.
+ */
+ ErrorF(" Number of lists: %d, list data type: %d \n",
+ vinput->numLists, vinput->type);
+
+ DD_VertPointSize(vinput->type, point_size);
+
+ pddlist = vinput->ddList;
+ for (i = 0; i < vinput->numLists; i++) {
+
+ vert_count = pddlist->numPoints;
+ ErrorF(" num points, list %d: %d", i, vert_count);
+
+ /*
+ *
+ */
+ pt = (char *)pddlist->pts.p4Dpt;
+
+ for (j = 0; j < vert_count; j++) {
+
+ if (DD_IsVertFloat(vinput->type)) {
+
+ if (DD_IsVert2D(vinput->type))
+ ErrorF(" x %f, y %f \n",
+ ((ddCoord4D *)pt)->x,
+ ((ddCoord4D *)pt)->y );
+
+ else if (DD_IsVert3D(vinput->type))
+ ErrorF(" x %f, y %f, z %f \n",
+ ((ddCoord4D *)pt)->x,
+ ((ddCoord4D *)pt)->y,
+ ((ddCoord4D *)pt)->z );
+
+ else
+ ErrorF(" x %f, y %f, z %f \n",
+ ((ddCoord4D *)pt)->x,
+ ((ddCoord4D *)pt)->y,
+ ((ddCoord4D *)pt)->z,
+ ((ddCoord4D *)pt)->w );
+
+
+ } else {
+
+ if (DD_IsVert2D(vinput->type))
+ ErrorF(" x %d, y %d \n",
+ ((ddCoord3DS *)pt)->x,
+ ((ddCoord3DS *)pt)->y );
+
+ else if (DD_IsVert3D(vinput->type))
+ ErrorF(" x %d, y %d, z %d \n",
+ ((ddCoord3DS *)pt)->x,
+ ((ddCoord3DS *)pt)->y,
+ ((ddCoord3DS *)pt)->z );
+
+ }
+
+ pt += point_size;
+
+ }
+ /* Now, ski to next input list */
+ pddlist++;
+ }
+}
+
+/*++
+ |
+ | Function Name: miTransformVector
+ |
+ | Function Description: Transform a 3D point by the 3x3
+ | portion of a 4x4 matrix
+ | Added 4/8/91 by JSH.
+ |
+ --*/
+void
+miTransformVector (p3, matrix, xp3)
+/* in */
+ddVector3D *p3;
+ddFLOAT matrix[4][4];
+/* out */
+ddVector3D *xp3;
+{
+
+ xp3->x = matrix[0][0]*p3->x;
+ xp3->x += matrix[0][1]*p3->y;
+ xp3->x += matrix[0][2]*p3->z;
+
+ xp3->y = matrix[1][0]*p3->x;
+ xp3->y += matrix[1][1]*p3->y;
+ xp3->y += matrix[1][2]*p3->z;
+
+ xp3->z = matrix[2][0]*p3->x;
+ xp3->z += matrix[2][1]*p3->y;
+ xp3->z += matrix[2][2]*p3->z;
+
+}
+
+/*++
+ |
+ | Function Name: miTransformPoint
+ |
+ | Function Description: Transform a 4D point by a 4x4 matrix
+ |
+ --*/
+void
+miTransformPoint (p4, matrix, xp4)
+/* in */
+ddCoord4D *p4;
+ddFLOAT matrix[4][4];
+/* out */
+ddCoord4D *xp4;
+{
+
+ xp4->x = matrix[0][0]*p4->x;
+ xp4->x += matrix[0][1]*p4->y;
+ xp4->x += matrix[0][2]*p4->z;
+ xp4->x += matrix[0][3]*p4->w;
+
+ xp4->y = matrix[1][0]*p4->x;
+ xp4->y += matrix[1][1]*p4->y;
+ xp4->y += matrix[1][2]*p4->z;
+ xp4->y += matrix[1][3]*p4->w;
+
+ xp4->z = matrix[2][0]*p4->x;
+ xp4->z += matrix[2][1]*p4->y;
+ xp4->z += matrix[2][2]*p4->z;
+ xp4->z += matrix[2][3]*p4->w;
+
+ xp4->w = matrix[3][0]*p4->x;
+ xp4->w += matrix[3][1]*p4->y;
+ xp4->w += matrix[3][2]*p4->z;
+ xp4->w += matrix[3][3]*p4->w;
+}
+
+/*++
+ |
+ | Function Name: miMatInverse
+ |
+ | Function Description:
+ | miMatInverse - a fairly robust matrix inversion routine
+ | inverts a 4x4 matrix.
+ |
+ | TODO: If the matrix is singular, call a more robust routine (SVD)
+ | to find a solution. See Numerical Recipes in C
+ |
+ |
+ --*/
+
+void
+miMatInverse( a )
+ ddFLOAT a[4][4];
+{
+ short index[4][2], ipivot[4];
+ float pivot[4];
+ short row, colum;
+ float themax;
+ short i, j, k, l;
+
+ for (j = 0; j < 4; j++)
+ ipivot[j] = 0;
+
+ for (i = 0; i < 4; i++) { /* do matrix inversion */
+ themax = 0.0;
+ for (j = 0; j < 4; j++) { /* search for pivot element */
+ if (ipivot[j] == 1)
+ continue;
+ for (k = 0; k < 4; k++) {
+ if (ipivot[k] == 1)
+ continue;
+ /* what does this mean? is it another singular case?
+ if (ipivot[k] > 1)
+ TODO:
+ */
+ if (fabs(themax) < fabs(a[j][k])) {
+ row = j;
+ colum = k;
+ themax = a[j][k];
+ }
+ }
+ }
+ if (MI_NEAR_ZERO(themax)) {
+ /* input matrix is singular, return the an identity matrix */
+ MI_MAT_IDENTITY( a, 4 );
+ /* TODO: restore matix 'a' and call SVD routine */
+ return;
+ }
+ ipivot[colum] += 1;
+ if (row != colum) { /* interchange rows to put */
+ for (l = 0; l < 4; l++) {
+ themax = a[row][l];
+ a[row][l] = a[colum][l];
+ a[colum][l] = themax;
+ }
+ }
+ index[i][0] = row;
+ index[i][1] = colum;
+ pivot[i] = a[colum][colum];
+#ifndef NDEBUG
+ if ((pivot[i] < 1.0e-6) && (pivot[i] > -1.0e-6) ) {
+ /* input matrix is singular, return the an identity matrix */
+ MI_MAT_IDENTITY( a, 4 );
+ /* TODO: restore matix 'a' and call SVD routine */
+ }
+#endif
+ /* the following isn't needed if we have SVD routine */
+ if (MI_NEAR_ZERO(pivot[i])) {
+ pivot[i] = MI_ZERO_TOLERANCE;
+ }
+ a[colum][colum] = 1.0; /* divide pivot row by pivot element */
+ for (l = 0; l < 4; l++)
+ a[colum][l] /= pivot[i];
+ for (j = 0; j < 4; j++)
+ if (j != colum) {
+ themax = a[j][colum];
+ a[j][colum] = 0.0;
+ for (l = 0; l < 4; l++)
+ a[j][l] -= a[colum][l] * themax;
+ }
+ }
+
+ for (i = 0; i < 4; i++) { /* interchange columns */
+ l = 4 - 1 - i;
+ if (index[l][0] != index[l][1]) {
+ row = index[l][0];
+ colum = index[l][1];
+ for (k = 0; k < 4; k++) {
+ themax = a[k][row];
+ a[k][row] = a[k][colum];
+ a[k][colum] = themax;
+ }
+ }
+ }
+ /* determinant is
+
+ (row == column)?1:(-1) * pivot[0] * pivot[1] * pivot[2] * pivot[3]
+
+ if needed*/
+}
+
+/*++
+ |
+ | Function Name: miMatInverseTranspose
+ |
+ | Function Description:
+ | miMatInverseTranspose - compute the inverse transpose of a matrix.
+ |
+ --*/
+
+void
+miMatInverseTranspose( m )
+ ddFLOAT m[4][4];
+{
+ miMatInverse( m );
+ miMatTranspose( m );
+}
+
+/*++
+ |
+ | Function Name: LostXResource
+ |
+ | Function Description:
+ | General purpose procedure to inform ddpex when an X
+ | resource is deleted.
+ |
+ | Note(s):
+ |
+ --*/
+
+void
+LostXResource( pPEXResource, PEXtype, Xtype )
+ diResourceHandle pPEXResource;
+ ddResourceType PEXtype;
+ ddXResourceType Xtype;
+{
+ /* the only case known to use this is when a drawable is
+ * deleted and a workstation is using the drawable
+ */
+ if ( (PEXtype == WORKSTATION_RESOURCE) && (Xtype == X_DRAWABLE_RESOURCE) )
+ {
+ register miWksPtr pwks = (miWksPtr)((diWKSHandle)pPEXResource)->deviceData;
+
+ pwks->pRend->pDrawable = NULL;
+ pwks->pRend->drawableId = PEXAlreadyFreed;
+ }
+ /* no else should ever happen */
+ return;
+}
+
+/*++
+ |
+ | Function Name: mi_set_filters
+ |
+ | Function Description:
+ | sets the filter flags in the ddcontext
+ |
+ | Note(s):
+ |
+ --*/
+
+void
+mi_set_filters(pRend, pddc, namesets)
+ ddRendererPtr pRend;
+ miDDContext *pddc;
+ ddBitmask namesets;
+{
+ ddUSHORT isempty;
+ ddUSHORT incl_match, excl_match;
+ ddUSHORT invert_incl_match, invert_excl_match;
+ ddNamePtr pnames;
+
+ /* TODO: look at bitmask to smartly change filter_flags
+ * instead of always reseting everything
+ */
+ pddc->Dynamic->filter_flags = 0;
+ MINS_IS_NAMESET_EMPTY(pddc->Dynamic->currentNames, isempty);
+
+ /* do search first */
+ if (pRend->render_mode == MI_REND_SEARCHING)
+ {
+ /* filters pass if they are empty, regardless of
+ * whether there are names in the current name set
+ */
+ pnames = pddc->Static.search.norm_inclusion;
+ MINS_IS_NAMESET_EMPTY( pnames, incl_match );
+
+ pnames = pddc->Static.search.norm_exclusion;
+ MINS_IS_NAMESET_EMPTY( pnames, excl_match );
+
+ if (incl_match && excl_match) {
+ /* norm list is empty, then all elements pass,
+ * so fake it to pass
+ */
+ incl_match = 1;
+ excl_match = 0;
+ } else {
+ /* norm list is not empty */
+ pnames = pddc->Static.search.norm_inclusion;
+ MINS_MATCH_NAMESETS(pnames, pddc->Dynamic->currentNames, incl_match);
+ pnames = pddc->Static.search.norm_exclusion;
+ MINS_MATCH_NAMESETS(pnames, pddc->Dynamic->currentNames, excl_match);
+ }
+
+ pnames = pddc->Static.search.invert_inclusion;
+ MINS_IS_NAMESET_EMPTY( pnames, invert_incl_match );
+
+ pnames = pddc->Static.search.invert_exclusion;
+ MINS_IS_NAMESET_EMPTY( pnames, invert_excl_match );
+
+ if (invert_incl_match && invert_excl_match) {
+ /* invert list is empty, then all elements rejected,
+ * so fake it to reject
+ */
+ invert_incl_match = 0;
+ invert_excl_match = 1;
+ } else {
+ /* invert list is not empty */
+ pnames = pddc->Static.search.invert_inclusion;
+ MINS_MATCH_NAMESETS(pnames, pddc->Dynamic->currentNames, invert_incl_match);
+ pnames = pddc->Static.search.invert_exclusion;
+ MINS_MATCH_NAMESETS(pnames, pddc->Dynamic->currentNames, invert_excl_match);
+ }
+ if ((incl_match && !excl_match) &&
+ !(invert_incl_match && !invert_excl_match))
+ MI_DDC_SET_DETECTABLE(pddc);
+ }
+
+ /* now, go on to other filters */
+ if (isempty)
+ /* current name set is empty. no filters pass */
+ return;
+
+ /* highlight */
+ if ( pRend->ns[DD_HIGH_INCL_NS] )
+ {
+ pnames = ((miNSHeader *)pRend->ns[DD_HIGH_INCL_NS]->deviceData)->names;
+ MINS_MATCH_NAMESETS(pnames, pddc->Dynamic->currentNames, incl_match);
+ if ( pRend->ns[DD_HIGH_EXCL_NS] )
+ {
+ pnames = ((miNSHeader *)pRend->ns[DD_HIGH_EXCL_NS]->deviceData)->names;
+ MINS_MATCH_NAMESETS(pnames, pddc->Dynamic->currentNames, excl_match);
+ }
+ else
+ excl_match = 0;
+ if (incl_match && !excl_match)
+ MI_DDC_SET_HIGHLIGHT(pddc);
+ }
+ /* else inclusion set is empty; filter does not pass */
+
+ /* invisibility */
+ if ( pRend->ns[DD_INVIS_INCL_NS] )
+ {
+ pnames = ((miNSHeader *)pRend->ns[DD_INVIS_INCL_NS]->deviceData)->names;
+ MINS_MATCH_NAMESETS(pnames, pddc->Dynamic->currentNames, incl_match);
+ if ( pRend->ns[DD_INVIS_EXCL_NS] )
+ {
+ pnames = ((miNSHeader *)pRend->ns[DD_INVIS_EXCL_NS]->deviceData)->names;
+ MINS_MATCH_NAMESETS(pnames, pddc->Dynamic->currentNames, excl_match);
+ }
+ else
+ excl_match = 0;
+ if (incl_match && !excl_match)
+ MI_DDC_SET_INVISIBLE(pddc);
+ }
+ /* else inclusion set is empty; filter does not pass */
+
+ if (pRend->render_mode == MI_REND_PICKING)
+ {
+ pnames = pddc->Static.pick.inclusion;
+ MINS_MATCH_NAMESETS(pnames, pddc->Dynamic->currentNames, incl_match);
+ pnames = pddc->Static.pick.exclusion;
+ MINS_MATCH_NAMESETS(pnames, pddc->Dynamic->currentNames, excl_match);
+ if (incl_match && !excl_match)
+ MI_DDC_SET_DETECTABLE(pddc);
+ }
+
+ if (pRend->render_mode == MI_REND_DRAWING)
+ MI_DDC_SET_DETECTABLE(pddc);
+
+ return;
+}
diff --git a/xc/programs/Xserver/PEX5/ddpex/mi/shared/miViewLUT.c b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miViewLUT.c
new file mode 100644
index 000000000..3f5c13f89
--- /dev/null
+++ b/xc/programs/Xserver/PEX5/ddpex/mi/shared/miViewLUT.c
@@ -0,0 +1,258 @@
+/* $TOG: miViewLUT.c /main/3 1998/02/10 12:45:43 kaleb $ */
+/*
+
+Copyright 1990, 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1990, 1991 by Sun Microsystems, Inc.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Sun Microsystems
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/PEX5/ddpex/mi/shared/miViewLUT.c,v 1.7 1998/10/04 09:34:54 dawes Exp $ */
+
+#include "miLUT.h"
+#include "miWks.h"
+#include "miInfo.h"
+#include "PEXErr.h"
+#include "PEXprotost.h"
+#include "pexos.h"
+
+
+extern void miMatMult();
+
+/* Level 4 Shared Resources */
+/* Lookup Table Procedures */
+
+extern unsigned colour_type_sizes[]; /* in miLUT.c */
+
+/* definitions used by miLUTProcs.ci */
+#define LUT_TYPE PEXViewLUT
+
+/* devPriv data structure */
+#define DD_LUT_ENTRY_STR ddViewEntry
+/* table entry data structure */
+#define MI_LUT_ENTRY_STR miViewEntry
+/* pex data */
+#define PEX_LUT_ENTRY_STR pexViewEntry
+
+#define LUT_REND_DYN_BIT PEXDynViewTableContents
+
+#define LUT_START_INDEX 0
+#define LUT_DEFAULT_INDEX 0
+/* LUT_0_DEFINABLE_ENTRIES value is also defined in miWks.h */
+#define LUT_0_DEFINABLE_ENTRIES 6
+#define LUT_0_NUM_PREDEFINED 1
+#define LUT_0_PREDEFINED_MIN 0
+#define LUT_0_PREDEFINED_MAX 0
+
+#define LUT_TABLE_START(pheader) (pheader)->plut.view
+
+#define DYNAMIC VIEW_REP_DYNAMIC
+
+/* predefined entries table: change this to work with your devPriv data */
+static DD_LUT_ENTRY_STR pdeViewEntry[LUT_0_NUM_PREDEFINED];
+#define LUT_PDE_ENTRIES pdeViewEntry[0]
+#define LUT_SET_PDE_ENTRY(pentry, pdeentry) \
+ (pentry)->entry = *(pdeentry); \
+ miMatMult((pentry)->vom, (pentry)->entry.orientation, (pentry)->entry.mapping); \
+ (pentry)->inv_flag = MI_FALSE
+
+/* predefined entry 0 is set to the default values
+ * change the XXX_DEFAULT_YYY macros below to use something else
+ * if you don't want the default values defined in the pde table
+ */
+#define PDE_DEFAULT_ENTRY_NUM 0
+#define LUT_DEFAULT_VALUES pdeViewEntry[PDE_DEFAULT_ENTRY_NUM]
+#define LUT_SET_DEFAULT_VALUES(pentry) \
+ (pentry)->entry = LUT_DEFAULT_VALUES; \
+ miMatMult((pentry)->vom, (pentry)->entry.orientation, (pentry)->entry.mapping); \
+ (pentry)->inv_flag = MI_FALSE
+
+/* which procedure definitions in miLUTProcs.h to use and their names
+ * take out USE flags if you're defining those procs in here
+ * but leave the name definitions
+ */
+
+#define LUT_USE_FREE
+#define LUT_USE_INQ_PREDEF
+#define LUT_USE_INQ_ENTRIES
+#define LUT_USE_COPY
+#define LUT_USE_INQ_INFO
+#define LUT_USE_INQ_IND
+#define LUT_USE_INQ_ENTRY
+#define LUT_USE_SET_ENTRIES
+#define LUT_USE_DEL_ENTRIES
+#define LUT_USE_INQ_ENTRY_ADDRESS
+#define LUT_USE_CREATE
+#define LUT_USE_MOD_CALL_BACK
+
+/* these three are redefined in miLUTProcs.h
+#define LUT_FREE ViewLUT_free
+#define LUT_INQ_PREDEF ViewLUT_inq_predef
+#define LUT_INQ_ENTRIES ViewLUT_inq_entries
+*/
+#define LUT_COPY ViewLUT_copy
+#define LUT_INQ_INFO ViewLUT_inq_info
+#define LUT_INQ_IND ViewLUT_inq_ind
+#define LUT_INQ_ENTRY ViewLUT_inq_entry
+#define LUT_SET_ENTRIES ViewLUT_set_entries
+#define LUT_DEL_ENTRIES ViewLUT_del_entries
+#define LUT_INQ_ENTRY_ADDRESS ViewLUT_inq_entry_address
+#define LUT_CREATE ViewLUT_create
+#define LUT_ENTRY_CHECK ViewLUT_entry_check
+#define LUT_COPY_PEX_MI ViewLUT_copy_pex_to_mi
+#define LUT_COPY_MI_PEX ViewLUT_copy_mi_to_pex
+#define LUT_MOD_CALL_BACK ViewLUT_mod_call_back
+
+/* copy from an mi entry to a pex entry and increment ppbuf */
+ddpex43rtn
+LUT_COPY_MI_PEX ( pheader, valueType, pentry, ppbuf )
+ miLUTHeader *pheader;
+ ddUSHORT valueType;
+ MI_LUT_ENTRY_STR *pentry;
+ ddPointer *ppbuf;
+{
+ ddPointer pb = *ppbuf;
+ DD_LUT_ENTRY_STR *pdev_entry;
+
+ if (pentry == NULL)
+ pdev_entry = &(LUT_DEFAULT_VALUES);
+ else if (pentry->entry_info.status == MILUT_UNDEFINED)
+ pdev_entry = &(LUT_DEFAULT_VALUES);
+ else
+ pdev_entry = &pentry->entry;
+
+ mibcopy(pdev_entry, pb, sizeof(PEX_LUT_ENTRY_STR));
+
+ pb+= sizeof(PEX_LUT_ENTRY_STR);
+
+ *ppbuf = pb;
+ return(Success);
+}
+
+/* copy from a pex entry to an mi entry and increment ppsrc */
+ddpex43rtn
+LUT_COPY_PEX_MI ( pheader, ppsrc, pentry )
+ miLUTHeader *pheader;
+ ddPointer *ppsrc;
+ MI_LUT_ENTRY_STR *pentry;
+{
+ ddPointer ps = *ppsrc;
+
+ mibcopy(ps, &(pentry->entry), sizeof(PEX_LUT_ENTRY_STR));
+
+ miMatMult(pentry->vom, pentry->entry.orientation, pentry->entry.mapping);
+ pentry->inv_flag = MI_FALSE;
+
+ ps+= sizeof(PEX_LUT_ENTRY_STR);
+ *ppsrc = ps;
+ return(Success);
+}
+
+/* check for bad values and increment ppPexEntry */
+
+ddpex43rtn
+LUT_ENTRY_CHECK (pheader, ppPexEntry)
+ miLUTHeader *pheader;
+ PEX_LUT_ENTRY_STR **ppPexEntry;
+{
+ /* orientation, mapping, clipFlags: no error for these */
+ /* correct clipLimits: XMAX > XMIN, YMAX > YMIN, ZMAX >= ZMIN, plus in NPC */
+ if (((*ppPexEntry)->clipLimits.minval.x >= (*ppPexEntry)->clipLimits.maxval.x) ||
+ ((*ppPexEntry)->clipLimits.minval.y >= (*ppPexEntry)->clipLimits.maxval.y) ||
+ ((*ppPexEntry)->clipLimits.minval.z > (*ppPexEntry)->clipLimits.maxval.z) ||
+ ((*ppPexEntry)->clipLimits.minval.x < 0.0) ||
+ ((*ppPexEntry)->clipLimits.maxval.x > 1.0) ||
+ ((*ppPexEntry)->clipLimits.minval.y < 0.0) ||
+ ((*ppPexEntry)->clipLimits.maxval.y > 1.0) ||
+ ((*ppPexEntry)->clipLimits.minval.z < 0.0) ||
+ ((*ppPexEntry)->clipLimits.maxval.z > 1.0))
+ return(BadValue);
+
+ (*ppPexEntry)++;
+ return(Success);
+}
+
+void
+ViewLUT_init_pde()
+{
+ pdeViewEntry[0].clipFlags = (PEXClipXY | PEXClipBack | PEXClipFront);
+ pdeViewEntry[0].clipLimits.minval.x = 0.0;
+ pdeViewEntry[0].clipLimits.minval.y = 0.0;
+ pdeViewEntry[0].clipLimits.minval.z = 0.0;
+ pdeViewEntry[0].clipLimits.maxval.x = 1.0;
+ pdeViewEntry[0].clipLimits.maxval.y = 1.0;
+ pdeViewEntry[0].clipLimits.maxval.z = 1.0;
+
+ pdeViewEntry[0].orientation[0][0] = 1.0;
+ pdeViewEntry[0].orientation[0][1] = 0.0;
+ pdeViewEntry[0].orientation[0][2] = 0.0;
+ pdeViewEntry[0].orientation[0][3] = 0.0;
+ pdeViewEntry[0].orientation[1][0] = 0.0;
+ pdeViewEntry[0].orientation[1][1] = 1.0;
+ pdeViewEntry[0].orientation[1][2] = 0.0;
+ pdeViewEntry[0].orientation[1][3] = 0.0;
+ pdeViewEntry[0].orientation[2][0] = 0.0;
+ pdeViewEntry[0].orientation[2][1] = 0.0;
+ pdeViewEntry[0].orientation[2][2] = 1.0;
+ pdeViewEntry[0].orientation[2][3] = 0.0;
+ pdeViewEntry[0].orientation[3][0] = 0.0;
+ pdeViewEntry[0].orientation[3][1] = 0.0;
+ pdeViewEntry[0].orientation[3][2] = 0.0;
+ pdeViewEntry[0].orientation[3][3] = 1.0;
+
+ pdeViewEntry[0].mapping[0][0] = 1.0;
+ pdeViewEntry[0].mapping[0][1] = 0.0;
+ pdeViewEntry[0].mapping[0][2] = 0.0;
+ pdeViewEntry[0].mapping[0][3] = 0.0;
+ pdeViewEntry[0].mapping[1][0] = 0.0;
+ pdeViewEntry[0].mapping[1][1] = 1.0;
+ pdeViewEntry[0].mapping[1][2] = 0.0;
+ pdeViewEntry[0].mapping[1][3] = 0.0;
+ pdeViewEntry[0].mapping[2][0] = 0.0;
+ pdeViewEntry[0].mapping[2][1] = 0.0;
+ pdeViewEntry[0].mapping[2][2] = 1.0;
+ pdeViewEntry[0].mapping[2][3] = 0.0;
+ pdeViewEntry[0].mapping[3][0] = 0.0;
+ pdeViewEntry[0].mapping[3][1] = 0.0;
+ pdeViewEntry[0].mapping[3][2] = 0.0;
+ pdeViewEntry[0].mapping[3][3] = 1.0;
+}
+
+#include "miLUTProcs.ci"
+
+