#include "X.h"
#include "Xmd.h"
#include "os.h"
#include "osstruct.h"
#include "misc.h"
#include "font.h"
#define NEED←EVENTS
#include "Xproto.h"
#include "inputstr.h"
#include "opaque.h"

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

extern char *GetHeap();

long MaxClients = 128;
Bool clientsDoomed = FALSE;

mesa void XConnectionMgr←CreateWellKnownSockets();
mesa void XConnectionMgr←CloseDownConnection();
mesa void XConnectionMgr←ReallyMarkConnectionClosed();
mesa void XConnectionMgr←OnlyListenToOneClient();
mesa void XConnectionMgr←ListenToAllClients();
mesa FID XFileIO←FiOpenForRead();
mesa int XFileIO←FiRead();
mesa void XFileIO←FiClose();
mesa void XFileIO←SetDefaultFontPath();
mesa void XFileIO←SetFontPath();
mesa int XFileIO←ExpandFontName();
mesa FontPathPtr XFileIO←ExpandFontNamePattern();
mesa int * XConnectionMgr←ReadRequestFromClient();
mesa int XConnectionMgr←WriteToClient();
mesa void XConnectionMgr←WaitForSomething();
mesa void Runtime←Interrupt();
mesa long XMKDriver←getTimeInMillis();

char *index();

static FontPathRec fontSearchList;
extern char *defaultFontPath;

void
CreateWellKnownSockets()
	{
	XConnectionMgr←CreateWellKnownSockets();
	}

Bool
CloseDownConnection(client)
	ClientPtr client;
	{
	XConnectionMgr←CloseDownConnection(client);
	}

void
ReallyMarkConnectionClosed(client)
	ClientPtr client;
	{
	XConnectionMgr←ReallyMarkConnectionClosed(client);
	}

void
OnlyListenToOneClient(client)
	ClientPtr client;
	{
	XConnectionMgr←OnlyListenToOneClient(client);
	}

void
ListenToAllClients()
	{
	XConnectionMgr←ListenToAllClients();
	}

FID
FiOpenForRead(lenn, name)
	int lenn;
	char *name;
	{
	char *newname;
	FID fid;

	newname = name;
	if (name[lenn-1] != '\0')
		{
		newname = (char *)Xalloc(lenn+1);
		strncpy(newname,name,lenn);
		newname[lenn] = '\0';
		}
	fid = XFileIO←FiOpenForRead(name);
	if(name != newname)
		Xfree(newname);
	return(fid);
	}

int
FiRead(buf, itemsize, nitems, fid)
	char *buf;
	unsigned itemsize;
	unsigned nitems;
	FID fid;
	{
	if ( (long)buf & 0x80000000L )
		return(XFileIO←FiRead((int *)buf, itemsize, nitems, fid));
	else
		return(XFileIO←FiRead(buf, itemsize, nitems, fid));
	}

int
FiClose(fid)
	FID fid;
	{
	XFileIO←FiClose(fid);
	return(0);
	}

void
SetDefaultFontPath(name)
	char *name;
	{
	int		len = strlen( name);
	XFileIO←SetDefaultFontPath(name);

	fontSearchList.npaths = 1;
	fontSearchList.length = (int *)Xalloc(sizeof(int));
	fontSearchList.length[0] = len;
	fontSearchList.paths = (char **)Xalloc(sizeof(char *));
	fontSearchList.paths[0] = (char *)Xalloc(len + 1);
	bcopy(name, fontSearchList.paths[0], len);
	fontSearchList.paths[0][len] = '\0';        
	}

void
FreeFontRecord(pFP)
	FontPathPtr pFP;
	{
	int i;
	for(i=0;i<pFP->npaths;i++)
		Xfree(pFP->paths[i]);
	Xfree(pFP->paths);
	Xfree(pFP->length);
	}


/*
 * pnames is a pointer to counted strings, each string long word
 * aligned
 */
void
SetFontPath( npaths, totalLength, countedStrings)
    int		npaths;
    int		totalLength;
    char *	countedStrings;
{
    int i;
    char * bufPtr = countedStrings;
    char n;

    FreeFontRecord(&fontSearchList);
    if (npaths == 0)
    {
	SetDefaultFontPath(defaultFontPath);
    }
    else
    {
        fontSearchList.length = (int *)Xalloc(npaths * sizeof(int));
        fontSearchList.paths = (char **)Xalloc(npaths * sizeof(char *));
	for (i=0; i<npaths; i++)
        {
	    n = *bufPtr++;
	    fontSearchList.length[i] = n;
	    fontSearchList.paths[i] = (char *) Xalloc(n + 1);
	    bcopy(bufPtr, fontSearchList.paths[i], n);
	    fontSearchList.paths[i][n] = '\0';
	    bufPtr += n;
	}
	fontSearchList.npaths = npaths;
	XFileIO←SetFontPath(&fontSearchList);
    }
}


/*
 * return value is length in bytes 
 */

FontPathPtr
GetFontPath()
{
    return( & fontSearchList);
}

/*
 * used by OpenFont
 *
 *  returns length of ppathname.
 *  may set *ppPathname to fname;
 */

int
ExpandFontName( ppPathname, lenfname, fname)
    char	**ppPathname;
    int		lenfname;
    char	*fname;
{
    int		in;
    char	*fullname = NULL;
    char	*lowername;
    char	*pch;
    int len;

    lowername = (char *) Xalloc(lenfname + 5);
    bzero(lowername, lenfname + 5);
    strncpy(lowername, fname, lenfname);
    /* if the name doesn't end in .snf, append that to the name */
    if((pch = index(lowername, '.')) == (char *)NULL || 
     *(pch + 1) != 's' ||
     *(pch + 2) != 'n' ||
     *(pch + 3) != 'f' ||
     pch + 4 - lowername != lenfname)
    {
	strcat(lowername, ".snf");
	lenfname += 4;
    }
	

    /*
     * reduce to lower case only
     */
    for ( in=0; in<lenfname; in++)
	if ( isupper( lowername[in]))
	    lowername[in] = tolower( lowername[in]);
	else if (lowername[in] == '/')
	    lowername[in] = '>';
    
    if (lowername[0] == '>')
	lowername[0] = '<';
    len = XFileIO←ExpandFontName(lowername, ppPathname, GetHeap());
    Xfree(lowername);
    return(len);
}

/*******************************************************************
 *  ExpandFontPathPattern
 *
 *	Returns a FontPathPtr with at most max-names, of names of fonts matching
 *	the pattern.  The pattern should use the ASCII encoding, and
 *      upper/lower case does not matter.  In the pattern, the '?' character
 *	(octal value 77) will match any single character, and the character '*'
 *	(octal value 52) will match any number of characters.  The return
 *	names are in lower case.
 *
 *      Used only by protocol request ListFonts
 *******************************************************************/


FontPathPtr
ExpandFontNamePattern(lenpat, countedPattern, maxNames)
    int		lenpat;
    char	*countedPattern;
    int		maxNames;
{
    char	*pattern;
    int		i;
    FontPathPtr fpr;


    /*
     * make a pattern which is guaranteed NULL-terminated
     */
    pattern = (char *) ALLOCATE←LOCAL( lenpat+1);
    strncpy( pattern, countedPattern, lenpat);
    pattern[lenpat] = '\0';
    if(pattern[0] == '/')
	pattern[0] = '<';
    for ( i = 0; i<lenpat; i++ )
	if ( pattern[i] == '/' )
	    pattern[i] = '>';
	else if ( pattern[i] == '?' )
	    pattern[i] = '#';
    fpr = XFileIO←ExpandFontNamePattern(pattern, maxNames, GetHeap());

    DEALLOCATE←LOCAL(pattern);
    return(fpr);
}

char *
ReadRequestFromClient(who, status, oldbuf)
	ClientPtr who;
	int *status;
	char *oldbuf;
	{
	if( (long)oldbuf & 0x80000000L )
		return((char *)XConnectionMgr←ReadRequestFromClient((long)who->index, status, (int *)oldbuf));
	else
		return((char *)XConnectionMgr←ReadRequestFromClient((long)who->index, status, oldbuf));
	}

int
WriteToClient(who, remaining, buf)
	ClientPtr who;
	int remaining;
	char *buf;
	{
	if ( (long)buf & 0x80000000L )
		return(XConnectionMgr←WriteToClient((long)who->index, remaining, (int *)buf));
	else
		return(XConnectionMgr←WriteToClient((long)who->index, remaining, buf));
	}

int
WaitForSomething(pClientsReady, nready, pNewClients, nnew)
	ClientPtr pClientsReady;
	int *nready;
	ClientPtr pNewClients;
	int *nnew;
	{
	XConnectionMgr←WaitForSomething(pClientsReady, nready, pNewClients, nnew);
	}

int
OsLookupColor(screen, name, len, pred, pgreen, pblue)
	int screen;
	char *name;
	int len;
	unsigned short *pred, *pgreen, *pblue;
	{
	return(0);
	}

void
OsInit()
	{
	}


HangUp()
	{
	Runtime←Interrupt();
	}


Notice()
	{
	}


ProcessCommandLine(argc, argv)
	int argc;
	char *argv[];
	{
	}

bcopy(src, dst, length)
	char *src, *dst;
	int length;
	{
	register int i;
	
	if(!((long)src & 0x80000000L))
		src = (char *)((((long)src)<<1)|0x80000000L);
	if(!((long)dst & 0x80000000L))
		dst = (char *)((((long)dst)<<1)|0x80000000L);
	for(i=0; i<length; i++)
		{
		*dst = *src;
		dst++;
		src++;
		}
	}
	
bzero(b, length)
	char *b;
	int length;
	{
	int i;
	if(!((long)b & 0x80000000L))
		b = (char *)((((long)b)<<1)|0x80000000L);
	for(i=0; i<length; i++)
		*b++ = (char)0;
	}

char *	
index(s, c)
	char *s, c;
	{
	while( (*s) && (*s != c ) )
	        s++
		;
	return(*s ? s : (char *)NULL );
	}
	
int
ffs(i)
	long i;
	{
	int count = 1;
	do
		{
		if(i&1L)
			return(count);
		i = i>>1;
		}
	while(count++ < 32);
	return(0);
	}
	
long
GetTimeInMillis()
	{
	return(XMKDriver←getTimeInMillis());
	}

long
random()
	{
	return(	GetTimeInMillis());
	}
/*
void	
ErrorF(s1,x1,x2,x3,x4,x5)
	char *s1;
	long x1, x2, x3, x4, x5;
	{
	Runtime←Interrupt();
	printf(s1,x1,x2,x3,x4,x5);
	}
	*/

insque(elem, pred)
	QdEventPtr elem, pred;
	{
	elem->forw = pred->forw;
	elem->back = pred;
	pred->forw = elem;
	if( elem->forw != NULL )
		elem->forw->back = elem;
	}
	
remque(elem)
	QdEventPtr elem;
	{
	if( elem->back != NULL )
		elem->back->forw = elem->forw;
	if( elem->forw != NULL )
		elem->forw->back = elem->back;
	}	
	
ResetHosts()
	{
	return(0);
	}
	
AddHost()
	{
	return(0);
	}
	
RemoveHost()
	{
	return(0);
	}
	
GetHosts()
	{
	return(0);
	}
	
ChangeAccessControl()
	{
	return(0);
	}

pointer
Xrealloc(ptr, amount)
	char *ptr;
	int amount;
	{
	char *ret;
	int *tmp;
	if(ptr == NULL)
		return(malloc(amount));
	else
	    {
	    ret = realloc(ptr, amount);
	    if( (long)ret & 0x80000000L )
	        return(ret);
	    else
	        {
	        tmp = (int *)((long)ret);
	        return((char *)(tmp));
	        }
	    }
	}
	
Xfree(ptr)
	char *ptr;
	{
	if(ptr!=NULL)
		free(ptr);
	}

pointer	
Xalloc(size)
	int size;
	{
	return(malloc(size));
	}