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

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

#include <stdio.h>
#include <utils.h>
#include <pmp_utils.h>
#include <char.h>
#include <font.h>
#include <rp.h>
#include <pmp_commands.h>

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

#define WHERE_AM_I	"rp.c"

int	rp_debug;

int	rp_state=	RP_UNKNOWN;
FONT	*rp_active=	NULL;
int	rp_x=		0;
int	rp_y=		0;
int	rp_pgwidth= 	RP_DFL_PGWIDTH;
int	rp_pgheight=	RP_DFL_PGHEIGHT;
int	rp_memory=	RP_PRINTER_MEMORY;
int	rp_memused=	0;
int	rp_orient=	RP_PORTRAIT;
int	rp_display=	RP_CLEAR_DISPLAY;
FILE	*rp_file=	NULL;

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

static	_rp_mtab_entry	*_rp_mount_tbl[RP_NUMBEROFFONTS];
static	int   		 _rp_last_mounted=0;
static	int		 _rp_uses=0;
unsigned		*_rp_loadmap;
static	int		*_rp_fntsize;

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

_rp_freespace(amount)
register4 int amount;
{
register1 int knt;
register2 _rp_mtab_entry *tmp;
register3 _rp_mtab_entry *lowmt= NULL;


    D_ENTRY1(rp_debug,"_rp_freespace(%d)\n",amount);
    while (amount>0) {
	for (knt=0;knt<_rp_last_mounted;knt++) {
	    tmp= _rp_mount_tbl[knt];
	    if (tmp&&tmp->rp_mt_size) {
		if ((!lowmt)||(tmp->rp_mt_used<lowmt->rp_mt_used)) {
		    lowmt= tmp;
		}
	    }
	}
	if (lowmt) {
	    _rp_command(PMP_UNLOAD_FONT);
	    _rp_byte(lowmt->rp_mt_index);
	    rp_memused-=	lowmt->rp_mt_size;
	    amount-=	 	lowmt->rp_mt_size;
	    lowmt->rp_mt_size=	0;
	    bzero(lowmt->rp_mt_map,sizeof(lowmt->rp_mt_map));
	}
	else RETURN(FALSE);
    }
    RETURN(TRUE);
}

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

int
rp_init(fil)
register1 FILE	*fil;
{
register2 int knt;

    D_ENTRY1(rp_debug,"rp_init(0x%x)\n",fil);
    rp_file=		fil;
    rp_state=		RP_UNKNOWN;
    rp_pgwidth=		RP_DFL_PGWIDTH;
    rp_pgheight=	RP_DFL_PGHEIGHT;
    rp_memory=		RP_PRINTER_MEMORY;
    rp_clear();

    _rp_command(PMP_UNLOAD_ALL_MACROS);
    _rp_command(PMP_UNLOAD_ALL_FONTS);
    for (knt=0;knt<RP_NUMBEROFFONTS;knt++) {
	if (_rp_mount_tbl[knt]) {
	    u_free(_rp_mount_tbl[knt]);
	    _rp_mount_tbl[knt]= NULL;
	}
    }
    rp_memused=		0;
    _rp_loadmap=	0;
    rp_active=		NULL;

    _rp_command(PMP_CURSOR_HOME);
    rp_x= 0;
    rp_y= 0;

    _rp_command(PMP_SET_DISPLAY);
    _rp_byte(PMPARG_CLEAR_DISPLAY);
    rp_display=		RP_CLEAR_DISPLAY;

    _rp_command(PMP_SET_PAGE_ORIENTATION);
    _rp_byte(PMPARG_PORTRAIT);
    rp_orient=		RP_PORTRAIT;

    RETURN(TRUE);
}

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

int
rp_close()
{
    D_ENTRY(rp_debug,"rp_close()\n");
    if (rp_state==RP_MARKED) 
	rp_clear();
    if (rp_display!=RP_CLEAR_DISPLAY) 
	rp_set_display(PMPARG_CLEAR_DISPLAY);
    _rp_flush();
    rp_file=		NULL;
    rp_state=		RP_CLOSED;
    rp_active= 		NULL;
    _rp_loadmap=	NULL;
    RETURN(TRUE);
}

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

int
rp_clear()
{
    D_ENTRY(rp_debug,"rp_clear()\n");
    if ((rp_state==RP_MARKED)||(rp_state==RP_UNKNOWN)) {
	_rp_command(PMP_SET_PAGE_SIZE);
	_rp_word(rp_pgwidth);
	_rp_word(rp_pgheight);
	rp_state= RP_CLEAR;
    }
    RETURN(TRUE);
}
	
/***============================================================***/

int
rp_activate(fnt)
register1 FONT *fnt;
{
register2 _rp_mtab_entry	*mt;
register3 int			 num;
register4 int			 knt;

    D_ENTRY1(rp_debug,"rp_activate(0x%x)\n",fnt);
    if (!fnt) 
	RETURN(FALSE);
    mt= (_rp_mtab_entry *)fnt_loadinfo(fnt);
    if ((!mt)||(mt->rp_mt_font!=fnt)) {
	num= RP_UNMOUNTED;
	if (_rp_last_mounted<=RP_MAX_FONT) {
	    num= _rp_last_mounted++;
	}
	else {
	    for (knt=0;knt<RP_NUMBEROFFONTS;knt++) {
		if (_rp_mount_tbl[knt]==NULL) {
		    num= knt;
		    break;
		}
	    }
	}
	if (num==RP_UNMOUNTED) 
	    RETURN(FALSE);
	mt= (_rp_mtab_entry *)u_malloc(sizeof(_rp_mtab_entry));
	mt->rp_mt_font= fnt;
	for (knt=0;knt<_RP_LOADMAP_SIZE;knt++) {
	    mt->rp_mt_map[knt]= 0;
	}
	mt->rp_mt_size= 0;
	mt->rp_mt_index= num;
	fnt_setloadinfo(fnt,(char *)mt);
	_rp_mount_tbl[num]= mt;
    }
    else {
	num= mt->rp_mt_index;
    }
    if (mt->rp_mt_size==0) {
	while (rp_memused+_RP_FONT_OVERHEAD>rp_memory) {
	    if (!_rp_freespace(_RP_FONT_OVERHEAD)) {
		WSGO("Can't free any more memory in _rp_activate\n");
		action("resetting rp_memused (good luck)\n");
		rp_memused= 0;
	    }
	}
	mt->rp_mt_size= _RP_FONT_OVERHEAD;
	rp_memused+= _RP_FONT_OVERHEAD;
    }
    rp_active= fnt;
    _rp_loadmap= &mt->rp_mt_map[0];
    _rp_fntsize= &mt->rp_mt_size;
    mt->rp_mt_used= _rp_uses++;
    _rp_command(PMP_ACTIVATE_FONT);
    _rp_byte(num);
    RETURN(TRUE);
}

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

_rp_download(index,ch)
register8 int	 index;
register1 CHAR	*ch;
{
register2 char	*pattern;
register3 int	 knt;
register4 int	 size;
register5 int	 ptrn_sz;
register6 int	 height;
register7 int	 width;

    D_ENTRY2(rp_debug,"_rp_download(%d,0x%x)\n",index,ch);
    ptrn_sz= ch_sizepattern(ch);
    width= ch_width(ch);
    height= ch_height(ch);
    size= _RP_CHAR_OVERHEAD(width,height);
    if (rp_memused+size>rp_memory) {
	if (!_rp_freespace(size)) {
	    WSGO("Can't free any more memory in _rp_activate\n");
	    action("resetting rp_memused (good luck)\n");
	    rp_memused= 0;
	}
    }
    rp_memused+= 	size;
    *_rp_fntsize+=	size;
    _rp_load(index);
    if (ch_encoding(ch)&CH_LARGE_PTRN) {
	_rp_command(PMP_LOAD_LARGE_PATTERN);
	_rp_byte(PMPARG_PORTRAIT);	/* orientation		*/
	_rp_byte(index);		/* position on font	*/
	_rp_word(height);		/* height in pels	*/
	_rp_word(width);		/* width in pels	*/
	_rp_word(ch_LTspace(ch));	/* L/T space in pels	*/
	_rp_word(ch_RBspace(ch));	/* R/B space in pels	*/
	_rp_word(ch_offset(ch));	/* offset from baseline	*/
	_rp_24bits(ptrn_sz);		/* size of pattern 	*/
    }
    else {
	_rp_command(PMP_LOAD_FONT_PATTERN);
	_rp_byte(index);		/* position on font	*/
	_rp_byte(height);
	_rp_byte(width);
	_rp_byte(ch_LTspace(ch));
	_rp_byte(ch_RBspace(ch));
	_rp_byte(ch_offset(ch));
    }
    pattern= ch_pattern(ch);
    if (pattern) {
	_rp_block(pattern,ptrn_sz);
    }
    else {
	for (knt=0;knt<ptrn_sz;knt++) {
	    _rp_byte('\0');
	}
    }
    RETURN(TRUE);
}

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

rp_rotate(new_orient)
register1 int new_orient;
{
register2 int direction;

    D_ENTRY1(rp_debug,"rp_rotate(0x%x)\n",new_orient);
    if (new_orient==rp_orient)
	RETURN(TRUE);
    direction= u_direction(rp_orient,new_orient);
    if (direction==U_ROT_ILLEGAL)
	RETURN(FALSE);
    if (rp_active) 
	rp_deactivate();
    u_rotatecoord(direction,rp_pgwidth,rp_pgheight,&rp_x,&rp_y);
    if ((direction==U_ROT_LEFT)||(direction==U_ROT_RIGHT)) {
	register3 int itmp;

	itmp= 		rp_pgwidth;
	rp_pgwidth= 	rp_pgheight;
	rp_pgheight=	itmp;
    }
    rp_orient= new_orient;
    _rp_command(PMP_SET_PAGE_ORIENTATION);
    _rp_byte(new_orient);
    RETURN(TRUE);
}

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

int
rp_index(fnt)
register1 FONT			*fnt;
{
register2 _rp_mtab_entry	*mt;

    D_ENTRY1(rp_debug,"rp_index(0x%x)\n",fnt);
    if (fnt) {
	mt= (_rp_mtab_entry *)fnt_loadinfo(fnt);
    }
    if (mt) {
	RETURN(mt->rp_mt_index);
    }
    RETURN(RP_UNMOUNTED);
}
