/****
 *
 * Copyright (c) 1988 by Sun Microsystems, Inc.
 * @(#)sh_TRANS.h 22.1 89/08/10 Copyright 1988 Sun Micro
 *
 * TRANS.H - TRANSFORM object information
 *
 ****/
#ifndef	_SH_CLASS_TRANS

/*
 * Transform Data
 */
typedef	float	MTX_FLT[4][4];	/* floating matrix data */
typedef	fract	MTX_BIN[4][4];	/* fract matrix data */

/*
 * Transform attributes
 */
typedef enum
  {
   TRANS_TYPE,
   trans_data,
   trans_mtx_flt,
   trans_mtx_bin
  } TRANS_attr;

#define	TRANS_ATTRS ((int) trans_mtx_bin)

/*
 * Transform type values
 *
 * Note: The generic implementation of Point_Transform and
 * InversePoint_Transform depends on the order of these bits.
 */
typedef	Unsgn8	TRANS_type;

#define	TRANS_2D	0x00
#define	TRANS_3D	0x01
#define	TRANS_FLT	0x02
#define	TRANS_BIN	0x00
#define	TRANS_GENERIC	(TRANS_BIN|TRANS_2D) /* THIS IMPLEMENTATION ONLY */

#define	TRANS_MASK	0x03		/* mask for 2d,3d,bin,flt */
#define	TRANS_SHIFT	2		/* shift count for mask */

#define	TRANS_SCALE	0x04
#define	TRANS_ROTATE	0x08
#define	TRANS_TRANSLATE	0x10
#define	TRANS_IDENTITY	0x20

#define	TRANS_GEN	0x40	/* general matrix, may have perspective */
#define	TRANS_ALL	(TRANS_GEN|TRANS_ROTATE|TRANS_SCALE|TRANS_TRANSLATE)

/*
 * Rotation axis and angle values
 */
#define	TRANS_AXIS_Z	0
#define	TRANS_AXIS_X	1
#define	TRANS_AXIS_Y	2
#define	TRANS_ANGLE_DEGREES	4
#define	TRANS_ANGLE_FRACT	8
typedef char TRANS_axis;

#define	TRANS_OP_Destroy	0
#define	TRANS_OP_Init		1
#define	TRANS_OP_Get		2
#define	TRANS_OP_Set		3
#define	TRANS_OP_Print		4
#define	TRANS_OP_Scale		5
#define	TRANS_OP_Translate	6
#define	TRANS_OP_Rotate		7
#define	TRANS_OP_Identity	8
#define	TRANS_OP_Copy		9
#define	TRANS_OP_Mul		10
#define	TRANS_OP_Point		11
#define	TRANS_OP_Invert		12
#define	TRANS_OP_Transpose	13
#define	TRANS_OP_Read		14
#define	TRANS_OP_Write		15
#define	TRANS_OP_Path		16
#define	TRANS_OP_InversePoint	17
#define	TRANS_OPERS		18

/*
 * TRANSFORM operators.
 *
 * TRANSFORM Create_Transform(r,t)		create TRANSFORM object
 * TRANSFORM Scale_Transform(trans, p)		concatenate scaling
 * TRANSFORM Translate_Transform(trans, p)	concatenate translation
 * TRANSFORM Rotate_Transform(trans, axis, ang)	concatenate rotation
 * TRANSFORM Identity_Transform(trans)		return identity transform
 * TRANSFORM Copy_Transform(ts, td)		copy transform ts into td
 * TRANSFORM Mul_Transform(t1, t2, t3)		multiply t1 by t2,store in t3
 * TRANSFORM Invert_Transform(t1, t2)		invert transform t1 into t2
 * TRANSFORM Transpose_Transform(t1, t2)	transpose transforms
 * TRANSFORM Set_Transform(trans, attr, val)	set transform attribute
 * TRANSFORM Write_Transform(trans, mat, t)	set 4x4 matrix
 * int Read_Transform(trans, mat, t)		get 4x4 matrix
 * Destroy_Transform(trans)			destroy transform object
 * Point_Transform(trans, p)			transform point P by transform
 * InversePoint_Transform(trans, p)		transform P by inverse
 * Get_Transform(trans, attr)			get transform attribute
 *
 * Print_Transform(trans)			print info of transform object
 * Path_Transform(trans, path, ofs)		transform path coordinates
 * Validate_Transform(t) Validates current graphics pipeline
 */
#define	Print_Transform(m)	((void) GetOper_Obj(m,TRANS_OP_Print)(m))
#define	Path_Transform(m,p,o)	((void) GetOper_Obj(m,TRANS_OP_Path)(m,p,o))
#define	Read_Transform(m,d,t)	((int)  GetOper_Obj(m,TRANS_OP_Read)(m,d,t))
#define	Point_Transform(m,p)	((void) GetOper_Obj(m,TRANS_OP_Point)(m,p))
#define	Identity_Transform(m) \
	((TRANSFORM) GetOper_Obj(m,TRANS_OP_Identity)(m))
#define	InversePoint_Transform(m,p) \
	((void) GetOper_Obj(m,TRANS_OP_InversePoint)(m,p))
#define	Write_Transform(m,d,t) \
	((TRANSFORM) GetOper_Obj(m,TRANS_OP_Write)(m,d,t))
#define	Scale_Transform(m,p) \
	((TRANSFORM) GetOper_Obj(m, TRANS_OP_Scale)(m,p))
#define	Translate_Transform(m,p) \
	((TRANSFORM) GetOper_Obj(m,TRANS_OP_Translate)(m,p))
#define	Rotate_Transform(m,axis,angle) \
	((TRANSFORM) GetOper_Obj(m,TRANS_OP_Rotate)(m,axis,angle))
#define	Copy_Transform(s,d)\
	((TRANSFORM) GetOper_Obj(s,TRANS_OP_Copy)(s,d))
#define	Invert_Transform(m1,m2)\
	((TRANSFORM) GetOper_Obj(m1,TRANS_OP_Invert)(m1,m2))
#define	Transpose_Transform(m1,m2)\
	((TRANSFORM) GetOper_Obj(m1,TRANS_OP_Transpose)(m1,m2))
#define	Mul_Transform(m1,m2,m3)\
	((TRANSFORM) GetOper_Obj(m1,TRANS_OP_Mul)(m1,m2,m3))
#define Validate_Transform(c) ((*((TRANSFORM) (c))->trans_val_func)(c))

#define	Create_Transform	sh_Create_Transform
#define	Temp_Transform		sh_Temp_Transform
#define	Destroy_Transform(m)	Destroy_Obj(m)

extern	TRANSFORM	sh_Create_Transform();
extern	TRANSFORM	sh_Temp_Transform();

/*
 * Generic Transform Object Data Structure
 * Overlays private data for all device implementations
 */
struct class_TRANS
  {
#include "sh_TRANS.ah"
  };

/*
 * Get_Transform(trans, attr)
 * Set_Transform(trans, attr, val)
 * Fast way to access transform attributes.
 * This macro depends on the "attr" argument being a compile time constant.
 */

#ifndef	SH_MONITOR

#define	Set_Transform(t,a,v)	CAT(a,set)((TRANSFORM)(t),v)

#else	/* SH_MONITOR */

#define	Set_Transform(t,a,v)	CAT(a,set)((TRANSFORM)sh_Monitor_Set_Transform(t),v)

#endif	/* SH_MONITOR */

#define	TRANS_TYPEset(t,v)	((TRANSFORM) GetOper_Obj(t,TRANS_OP_Set)(t,TRANS_TYPE,v))
#define trans_ctxset(t,v)	((t)->trans_ctx = v)
#define trans_selectset(t,v)	((t)->trans_select = v)
#define trans_modeset(t,v)	((t)->trans_mode = v)

#ifndef	SH_MONITOR

#define	Get_Transform(t,a)	CAT(a,get)((TRANSFORM)(t))

#else	/* SH_MONITOR */

#define	Get_Transform(t,a)	CAT(a,get)((TRANSFORM)sh_Monitor_Get_Transform(t))

#endif	/* SH_MONITOR */

#define TRANS_TYPEget(t)	((t)->TRANS_TYPE)
#define trans_ctxget(t)		((t)->trans_ctx)
#define trans_mtx_binget(t)	((MTX_BIN *) ((t)->trans_data))
#define trans_invget(t)		((t)->trans_inv)

#define trans_dataget(t)	(((t)->trans_flags & TRANS_FLAG_DINV) ?	\
	((MTX_FLT *) (GetOper_Obj(t, TRANS_OP_Get)(t, trans_data))) :	\
	 (MTX_FLT *) (t)->trans_data)

#define trans_mtx_fltget(t)	(((t)->TRANS_TYPE) & TRANS_FLT ?	\
	((MTX_FLT *) (t)->trans_data) :					\
	((MTX_FLT *) (GetOper_Obj(t, TRANS_OP_Get)(t, trans_mtx_flt))))

/*
 * trans_mode indicates whether the transform is part of
 * the rendering pipeline, construction pipeline or neither.
 * It is set by Pipeline_Context.
 */
#define	CTM_CONSTRUCT	1	/* used in path construction */
#define	CTM_RENDER	2	/* used in rendering */
#define	CTM_PIPELINE	4	/* is the pipeline transform */

#define	_SH_CLASS_TRANS
#endif	/* _SH_CLASS_TRANS */
