
/* *      ***    *   *   ****  ****  **** *****
   *     *   *   **  *  *      *     *      *     
   *     *****   * * *  *  **  ****  ***    *   
   *     *   *   *  **  *   *     *  *      *   
   ****  *   *   *   *   ***   ****  ****   *   

		SCREEN ROUTINES	*/
#include "equs.c"
#include "data.c"


makeLang ()
{   /* if isfox stop the buck */
	if (ovlLoad ("CUST1.OVL",OVLCH))
		{ (*ovlcall)();
		  if (charsuc) isUseLang = TRUE;
		  mainDisp ();
		}

}  /* end of MAKE LANG */



makeKeyb ()
{   /* if isfox stop the buck */
	if (ovlLoad ("CUST2.OVL",OVLKB))
		{ (*ovlcall)();
		  if (charsuc) isUseKeyB = TRUE;
		  mainDisp ();
		}

}  /* end of MAKE KEYBOARD */



GTLang ()
{   
	readIt = OVSLG;
	if (ovlLoad ("CUST5.OVL",OVLGN))
		{ (*ovlcall)();
		  
		}

}  /* end of MAKE LANG */





GTkeys ()
{   
	readIt = OVSKB;
	if (ovlLoad ("CUST5.OVL",OVLGN))
		(*ovlcall)();

}  /* end of MAKE LANG */







/* ROUTINES FOR READING LOADING USER CHARACTER SET */
/* ROUTINES FOR READING LOADING USER CHARACTER SET */
/* ROUTINES FOR READING LOADING USER CHARACTER SET */


/* if read in KBD and CRT trantables, if failure on CRTT table 
  return false 
	For fox we read in a CRT table, for both fox and 5000
	we must read a KBD table if one is available.  If no
	CRT table is available that is an error, if no
	KBD table thats Okay	*/

char	readCHset()
{	int	tranfd;
	char	i;

	tranfd = -1;  /* set as flag ofr CRT read */
	if (lg.charset == '*') return (TRUE); /* don't change */
	
	/* read CRT trantable */
	if (lg.charset == 'A')  /* ASCII */
		for (i = 0; i < 128; i++)
			lg.crttrantable [i] = i;
	else
		{
		if (isFox) 
			{ tranfd = ropenfile ("LANGUAGE.CST");
			  if (tranfd == -1) 
				{ lg.noCRTtran = TRUE;
				   return (FALSE);
				}
			}  /* fox open */
		else
			{     /* 5000 - try to open but don't bother user */
			tranfd = open ("LANGUAGE.CST",0);
			if (tranfd == -1) tranfd = open ("A:LANGUAGE.CST",0);
			if (tranfd == -1) lg.noCRTtran = TRUE;
			}   /* 5000 */
		if (tranfd != -1)
			{
			if (!rdTranTable (CRT,tranfd)) 
				{
				fabort (tranfd);
			  	if (isFox) 
					{ lg.noCRTtran = TRUE;
					   return (FALSE);
					}
			  	else 	/*  5000 */
					lg.noCRTtran = TRUE;
				}
			else   /* successful read */
				lg.noCRTtran = FALSE;
			}  /* trand != -1 */
		}  /* not ascii set */

	/* now read KBD tran table - if fd = -1 then its a 5000
		and LANGUAGE file isn't open. Look for it on
		logged drive and drive A but don't bother user */
	if (lg.charset == 'A')  /* ASCII */
		for (i = 0; i < 128; i++)
			lg.keytrantable [i] = i;
	else		/* non ASCII */
		{
		if (tranfd == -1)
			{ for (i = 0; i < 128; i++)
				lg.keytrantable [i] = i;
			}
		else rdTrantable (KBD,tranfd);
		} /* not ascii KBD load */

 	rdchreturn:
		fabort (tranfd);
		return (TRUE);
		

}   /* end of readCHset */







/*  move a char definiton from one place to another */
movechar (dp,sp,mode)
	char *dp,*sp,mode; /* pointers to string */
{	int i,j,setbyte,readbyte;
	/* mode is set if character needs to be rotated Vertical to
		Horizontal, Horizontal to vertical, or not at all */
	if (mode == NOROT)
		{
		for (i = 0; i < (charbytes); i++)
			{ *dp = *sp;
			   dp++; sp++;
			}
		}  /* no rotation */

	else if (mode == VtoH)
		{
		for (i = 0; i < HORZBYTES;i++)
			*(dp+i) = 0;
			
		 /* to rotate from vert to horiz, for byte B in the vert
			for each on bit (b) turn on the (7-B) bit of byte 
			number (7-b) the horiz structure. */
		setbyte = 0x80;
		for (i = 0; i < VERTBYTES; i++)
			{
			readbyte = *(sp+i);
			for (j = 0; j < HORZBYTES; j++)
				{ if (readbyte & 0x80)
					*(dp + j) |= setbyte;
				  else *(dp + j) &= ~setbyte;
				  readbyte = (readbyte << 1);
				}  /* j to horiz bytes */
			setbyte = (setbyte >> 1);
			} /* i to vertbytes */ 
		
		}  /* rotate a vertical to horiz */
		

	else	/* must be HtoV */
		{
		 /* to rotate from horiz to vert, for byte B in the horiz
			for each on bit b turn on the (7-B) bit of byte number
			(7-b) in the horiz structure. */
		setbyte = 0x80;
		for (i = 0; i < HORZBYTES; i++)
			{
			readbyte = *(sp + i);
			for (j = 0; j < VERTBYTES; j++)
				{ if (readbyte & 0x80) 
					*(dp + j) |= setbyte;
				  else *(dp + j) &= ~setbyte;
				  readbyte = (readbyte << 1);
				}  /* j to horiz bytes */
			setbyte = (setbyte >> 1);
			} /* i to vertbytes */ 
		
		}  /* rotate horiz to vertical */
	
}  /* end of movechar */

/* down load user defined character set, return TRUE if
    successful (failure is only possible with User file  */
char	loadCHset ()
{
	/* see if user defined, if so download file */

	if (lg.charset == '*') return (TRUE);
	if (lg.charset == 'U')
		{  /* dowloading user file */
		dnldUchset();
		}  /* if result = U */
	else   /* if 5000 send code, fox dnlad table */ 
		{ if (isFox) dnldTranTable (CRT);
		  else
			{ putz (ldlangseq);
			  ptch (lg.charset);
			} /* 5000 */
		} /* load a standard lagnuage */
	dnldTranTable (KBD);
		
	return (TRUE);
}  /* load chset */


/* load character set in */
dnldUCHset()
{	int	i,j,downsize;
	char	dnstr [HORZBYTES+1];

	/* make sure we can load this lagnuage */
	if (isFox | (st.SCdoSize & (cs.Usmall != st.isSmall))) return;

	/* size of language to download is langsize unless its 
		horizontal and small */
	if (cs.Usmall) 
		{ if (isHoriz) downsize = HORZBYTES * NUMCHARS;
		  else downsize = VERTBYTES * NUMCHARS;
		}
	else downsize = BIGBYTES * NUMCHARS;

	putz (ldcharseq);
	ptch (downsize - ((downsize/256)*256));
	ptch (downsize/256);
	if (! (cs.Usmall & isHoriz))
		{ for (i = 0; i < downsize; i++)
			gptch (cs.langbuffer [i]);
		}  /* not small,horizontal */
	else		/* small and horiz */
		{ for (i = 0; i < NUMCHARS; i++)
			{
			movechar (dnstr,&cs.langbuffer[(i * VERTBYTES)],VtoH);
			for (j = 0; j < HORZBYTES; j++)
				gptch (dnstr[j]); 
			}  /* i to numkeys */
		}  /* small and horiz */
	putz (lddescseq);
	for (i = 0; i < DESCENDBYTES; i++)
		ptch (descenders [i]);
	
}




/* read in tran table from file LANGUAGE.CST for CRT or KBD
	return true if successful */
char	rdTranTable (dev,fd)
	int	dev,fd;
{	struct	tranfileDir TFD [TFDSIZE + 10];
	char	i,searchstr[3];

	/* first read in file table and then find offset */
	/* table is made of strings with first char of language
		followed by a C or K for CRT or keyboard trans table,
		then is number of recod offset to table */

	if (seek (fd,0,0) == -1)
		goto nofind;
	if (read (fd,&TFD,1) == -1)
		goto nofind;

	searchstr [0] = lg.charset;
	if (dev == CRT) searchstr [1] = 'C';   
	else searchstr [1] = 'K';
	searchstr [2] = '\0';
	/* search table for string, if not found go to not found */
	for (i = 0; i < TFDSIZE; i++)
		{ if (strmatch (searchstr,TFD[i].entname)) 
			goto entfound;
		}
	goto nofind;  /* search failed */

	entfound:
	if (seek (fd,TFD[i].entoff,0) == -1) goto nofind;
	if (dev == CRT)
		{ if (read (fd,&lg.crttrantable [0],1) == -1) goto nofind;
		}
	else if (read (fd,&lg.keytrantable [0],1) == -1) goto nofind;

	return (TRUE);
   nofind:
	return (FALSE);	
}  /* end of rdCRTtable */
 
/***   ***   ***   ***   ***   ***   ***   ***   ***
    ***   ***   ***   ***   ***   ***   ***   ***   ***
 ***   ***   ***   ***   ***   ***   ***   ***   ***   */

/*  down load tran table */
dnldTrantable (dev)
	int	dev;
{	int	i;
	if (dev == CRT)
		{
		putz (ldCRTseq);
		for (i = 0; i < 128; i++)
			ptch (lg.crttrantable[i]); 
		}	/* crt */
	else if (dev == KBD)
		{
		putz (ldKBDseq);
		
		for (i = 0; i < 128; i++)
			if (lg.Ukeyb) ptch (keybBuffer [i]); 
			else ptch (lg.keytrantable[i]); 
		}  /* kbd */
	else return;

}  /* end of dnld tran table */




/****************/
/****************/
/****************/



/* read a user keyboard or language, return true on success */

char	doUread (isLang)
	char	isLang;
{	char	*fname,fd;

	if (isLang) fname = UfileName;
	else fname = UkeybName;
	if (!(gtSRfileName (TRUE,fname)))
		goto falseret;
	clrPrompt (3);
	fd = open (fname,2);
	if (fd == -1) 
		goto falseret;
	if (readtable (fd) == -1) goto falseret;

	if (isLang)
		{ if (ft.chsloc == 0) goto falseret;
		  if (readuchar (fd) == -1) goto falseret;
		}
	else 
		{ if (ft.kbdloc == 0) goto falseret;
		  if (readkeyb (fd) == -1) goto falseret;
		}
	clrprompt (3);
	return  (TRUE);

	falseret:
		clrPrompt (3);
		ptch (BELL);
		curpos (PROMPTLINE,PROMCOL);
		putz (ms59ptr);
		fname [0] = '\0';
		return (FALSE);

}  /* read in either a keyboard or a user language */




int	readtable (fd)
	int	fd;
{
	if (read (fd,&filebuffer[0],2) == -1)
		goto badtabread;
	if (!(strmatch (&filebuffer[1],"CUSTOMIZ VER")))
		goto badtabread;
	/* move table form buffer into ft structure */
	tabcopy (&ft,&filebuffer [0]);

	/* note which records are in buffer */
	fbstartrec = 0;
	fblastrec  = 1;
	return (0);
badtabread:
	return (-1);
}  /* end of readtable */





int	readuchar (fd)
	int fd;
{  int 	bytenum,i;
   struct CHset *checkptr;

	if (isFox & !dealer) 
		{ keyPrompt (ms54ptr);
		  st.charset = '*';
		  return (-1);
		} 
	bytenum = ft.chsloc;
	if (bytenum == 0) goto badchread;
	if (flreader (bytenum,127,fd) == -1) goto badchread;

	/* check language size */
	checkptr = filebuffer;
	if (checkptr->Usmall) bytenum = NUMCHARS * VERTBYTES;
	else bytenum = NUMCHARS * BIGBYTES;
	bytenum += sizeof (cs.Usmall) + DESCENDBYTES;

	if (seek (fd,(ft.chsloc/128),0) == -1) goto badchread;
	if (read (fd,&filebuffer[0],((bytenum/128) + 1)) == -1)
		goto badchread;
	/* since successful read move from file buffer to langbuffer */
	isUseLang = TRUE;
	movmem (filebuffer,cs,(bytenum-DESCENDBYTES));
	movmem (&filebuffer [bytenum-DESCENDBYTES],descenders,DESCENDBYTES);
	return (0);

	
badchread:
	return (-1);
}  /* end of read uchar */



int	readkeyb (fd)
	int fd;
{  int 	bytenum,i;

	bytenum = ft.kbdloc;
	if (bytenum == 0) goto badkbread;
	if (flreader (bytenum,128,fd) == -1) goto badkbread;

	/* since successful read move from file buffer to keybuffer */
	isUseKeyb = TRUE;
	movmem (filebuffer,keybBuffer,128);
	return (0);
	
badkbread:
	return (-1);
	
}  /* end of read readlg.Ukeyb */







/*	gets a file name for read or save */
char	gtSRfileName (read,name)
	char	read, *name;

{	char	*promptr;
gtSR1:
	while (1)	  /* read query */
		{
		if (strlen (name) == 0)
			{ if (!gtSRname (read,name)) 
				 return (FALSE);
			  /* if reading  don't confirm file name */
			  if (read) break;
			}
		else  /* don't confirm if we already queried for user name */
			{
			if (read) promptr = ms35ptr;  /* confirm using current file */
			else promptr = ms40ptr;
			PA.PAptr [1] = promptr;
			PA.PAptr [0] = ms20ptr;
			doPrompt (2,PA);
			curpos (PROMPTLINE - 1,(strlen (promptr) + PROMCOL));
			putz (name);
			if (conPrompt (ms20ptr)) 
				{ clrPrompt (2);
				  break;
				}
			name [0] = '\0';
			clrPrompt (2);
			}
		} /* read in query */

	return (TRUE);
}  /* gtSRfilename */


char	gtSRname (read,name)
	char	read,*name;  /* flag */

{	char	result;

	clrPrompt (2);
	PA.PAptr [0] = ms38ptr;
	if (read) PA.PAptr [1] = ms37ptr;
	else PA.PAptr [1] = ms39ptr;
	doPrompt (2,PA);
	result = inpPrompt (PROMPTLINE,strlen (ms38ptr));
	if ((result == CR) | (result == ESC)) return (FALSE);
	ungtch (result);
	GTfilename (name);
	clrPrompt (3);
	if (strlen (name) == 0) return (FALSE);
	return (TRUE);

}  /* end of gtUfileName */





/* this routine is used by others for reading from file */

int 	flreader (bytenum,size,fd)
	int	bytenum,size,fd;
{	int	firstrec,lastrec;

	/*see what records are needed in memory, and if they're there */
	firstrec = (bytenum)/128;
	lastrec = (bytenum + size)/128;
	if (!((firstrec >= fbstartrec) & (lastrec <= fblastrec)))
		{ if (seek (fd,firstrec,0) == -1)
			return (-1);
		  if (read (fd,&filebuffer[0],(lastrec-firstrec+1)) == -1)
			return (-1);
		  fbstartrec =firstrec;
		  fblastrec = lastrec;
		} /* recs not in memory, read em */
	return (0);	
}  /* end of flreader */





/* see if size needs to be changed becuase of new user language,
     if so, set flags and return true */
char	SZresetCheck()
{	if (cs.Usmall != st.isSmall) 
		{ st.isSmall = cs.Usmall;
		  if (st.SCdoSize)
			{ if (st.isSmall)
				mens [OscrSize].MENdefChoice [0] = 0;
			  else 
				{ st.SCexLines = FALSE;
				  mens [OscrSize].MENdefChoice [0] = 1;
				}
			}	
		  return (TRUE);
		}		
	else return (FALSE);
}



/* see if language is invalidated by new size setting, if 
	so, return true  */
char	LGresetCheck()
{	if (cs.Usmall != st.isSmall)
		{ isUseLang = FALSE;
		  if (lg.charset == 'U')
			{ loadLang == FALSE;
			  lg.charset = '*';
			  mens [Olang].MENdefChoice [0] = mens [Olang].MENnumChoice -1;
			}
		   return (TRUE);
		}
	else return (FALSE);		

}
