/*
 * 5799-WZQ (C) COPYRIGHT IBM CORPORATION 1986
 * LICENSED MATERIALS - PROPERTY OF IBM
 * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
 */
/* $Header:creg.c 12.0$ */
/* $ACIS:creg.c 12.0$ */
/* $Source: /ibm/acis/usr/src/ibm/lib/pmp/RCS/creg.c,v $ */

#ifndef lint
static char *rcsid = "$Header:creg.c 12.0$";
#endif

#include <stdio.h>
#include <utils.h>
#include <char.h>
#include <font.h>
#include <creg.h>
#include <vp.h>

/***===================================================================***/

int cr_debug;

#define CR_REGISTER_KNT	15

static	CREG	 cr_regs[CR_REGISTER_KNT];
static	CREG	*cr_freelist= NULL;


#ifdef DEBUG_UTILS
/***============================================================***/

static char *
_cr_xystring(which)
register1 int which;
{
    switch (which) {
	case _CR_X:		return("x");
	case _CR_Y:		return("y");
	case _CR_X|_CR_Y:	return("x&y");
    }
    return("***ILLEGAL***");
}

/***============================================================***/

static char *
_cr_keepstr(keep)
register1 int keep;
{
    if (keep==CR_FREE_REG)	return("free");
    if (keep==CR_KEEP_REG)	return("keep");
    return("***ILLEGAL***");
}

#endif /* DEBUG_UTILS */

/***===================================================================***/

int
cr_init(constraint)
register3 int constraint;
{
static 	int	beenhere= 	FALSE;
register2 CREG	*last;

    D_ENTRY1(cr_debug,"cr_init(%d)\n",constraint);
    if (!beenhere) {
	register1 int knt;

	/* link up circular free list */

	cr_freelist= last= &cr_regs[0];
	for (knt=CR_REGISTER_KNT-1;knt>=0;knt--) {
	    cr_regs[knt].cr_next= last;
	    last= &cr_regs[knt];
	}
	beenhere=TRUE;
    }
    RETURN(TRUE);
}

/***============================================================***/

int
cr_xyremark(reg,x,y)
register1 CREG	*reg;
register2 int	 x;
register3 int	 y;
{
    D_ENTRY3(cr_debug,"cr_xyremark(0x%x,%d,%d)\n",reg,x,y);
    if ((!reg)||(reg->cr_next))
	RETURN(FALSE);
    reg->cr_x= x;
    reg->cr_y= y;
    reg->cr_orient= vp_orient;
    RETURN(TRUE);
}

/***===================================================================***/

CREG *
cr_xymark(x,y)
register2 int	x,y;
{
register1 CREG	*reg;

    D_ENTRY2(cr_debug,"cr_xymark(%d,%d)\n",x,y);
    if (!cr_freelist) 
	RETURN(NULL);
    reg= cr_freelist;
    if (reg->cr_next==reg) { /* last item on freelist? */
	cr_freelist= NULL;
    }
    else {
	cr_freelist= reg->cr_next;
    }
    reg->cr_x= x;
    reg->cr_y= y;
    reg->cr_orient= vp_orient;
    reg->cr_next= NULL;
    RETURN(reg);
}

/***===================================================================***/

int
_cr_return(which,reg,keep)
register2 int	 which;
register1 CREG	*reg;
register3 int	keep;
{
    D_ENTRY3(cr_debug,"_cr_return(%s,0x%x,%s)\n",_cr_xystring(which),reg,
							_cr_keepstr(keep));
    if ((!reg)||(reg->cr_next)) /* no register, or register on free list */
	RETURN(FALSE);
    if (vp_orient!=reg->cr_orient) {
	register3 int direction;

	direction= u_direction(reg->cr_orient,vp_orient);
	u_rotatecoord(direction,vp_pgwidth,vp_pgheight,&reg->cr_x,&reg->cr_y);
	reg->cr_orient= vp_orient;
    }
    if (which&_CR_X) 
	vp_x= reg->cr_x;
    if (which&_CR_Y)
	vp_y= reg->cr_y;
    if (keep!=CR_KEEP_REG) {
	cr_free(reg);
    }
    RETURN(TRUE);
}

/***===================================================================***/

int
cr_free(reg)
register1 CREG *reg;
{
    D_ENTRY1(cr_debug,"cr_free(0x%x)\n",reg);
    if ((!reg)||(reg->cr_next)) /* no register or register on free list */
       RETURN(FALSE);
    if (cr_freelist)	reg->cr_next= cr_freelist;
    else		reg->cr_next= reg;
    cr_freelist= reg;
    RETURN(TRUE);
}

/***===================================================================***/
