diff options
Diffstat (limited to 'xc/programs/Xserver/PEX5/ddpex/mi')
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, ©_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, ©_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" + + |