/*
 *      XCountdown - X version of the popular Channel 4 quiz show
 *
 * This software comes with NO warranty whatsoever. I therefore take no
 * responsibility for any damages, losses or problems caused through use
 * or misuse of this program.
 *
 * I hereby grant permission for this program to be freely copied and
 * distributed by any means, provided no charge is made for it.
 *
 * Matthew Chapman, csuoq@csv.warwick.ac.uk
 *    June 1995.
 */

/* main program */

#include "xcountdown.h"
#include "globals.h"

#include "carol1.xpm"
#include "carol2.xpm"
#include "carol3.xpm"

#include "slate.xpm"
#include "slate2.xpm"

#include <X11/xpm.h>

void InitGame(void);
void MainLoop(void);
void SetBoard(Widget top,int dpy);
void SetLettRound(Widget top,int dpy);
void SetNumRound(Widget top,int dnum);

static Pixmap carol_xpm[NP][3];

/* fallback resources - black and white, and colour */
static String bw_res[] = {
    "*menuButton.leftBitmap:    dropbar8",
    "*font:						-b&h-lucidatypewriter-medium-r-normal-*-18-*",
    "*title.font:				-*-helvetica-bold-r-*-*-34-*",
    "*rmain*font:				-b&h-lucidatypewriter-medium-r-normal-*-12-*",
    "*menuButton*font:			-b&h-lucidatypewriter-medium-r-normal-*-12-*",
    "*background:				white",
    "*foreground:				black",
    "*board*lett*background:	black",
    "*title.foreground:			white",
    "*tclock.borderColor:		white",
    "*tclock.interiorColor:		black",
    "*tclock.completedColor:	white",
    NULL,
};

static String cols_used[7] = {
    "gray40","deepskyblue3","steelblue","gray70","gray90","red",
    "lightsteelblue",
};

static String col_res[] = {
    "*menuButton.leftBitmap:    dropbar8",
    "*font:						-b&h-lucidatypewriter-medium-r-normal-*-18-*",
    "*title.font:				-*-helvetica-bold-r-*-*-34-*",
    "*rmain*font:				-b&h-lucidatypewriter-medium-r-normal-*-12-*",
    "*menuButton*font:			-b&h-lucidatypewriter-medium-r-normal-*-12-*",
    "*background:				gray40",
    "*foreground:				white",
    "*borderColor:                        black",
    "*title.foreground:			deepskyblue3",
    "*tclock.interiorColor:		steelblue",
    "*tclock.completedColor:	white",
    "*board*background:			gray70",
    "*board*lett*background:	gray40",
    "*board*num*background:		deepskyblue3",
    "*board*num*foreground:		gray90",
    "*board*cnum*background:	gray90",
    "*board*vbutt.background:	steelblue",
    "*board*cbutt.background:	steelblue",
    "*cecil.valueBackground:	black",
    "*cecil.valueForeground:	red",
    "*cecil*borderColor:          lightsteelblue",
    "*carol*borderColor:		lightskyblue",
    "*board.borderColor:		lightskyblue",
    "*richard*borderColor:		lightskyblue",
    "*richard*background:		steelblue",
    "*tclock.borderColor:		lightskyblue",
    "*name1*background:			steelblue",
    "*name2*background:			steelblue",
    "*input1*borderColor:		lightskyblue",
    "*input2*borderColor:		lightskyblue",
    "*score.valueBackground:	black",
    "*score.valueForeground:	red",
    "*score*borderColor:          lightsteelblue",
    "*rtitle*foreground:		lightsteelblue",
    "*rdismiss*background:		red",
    "*hdismiss*background:		red",
    "*ctitle*foreground:		lightsteelblue",
    "*cquit*background:			red",
    "*ccancel*background:		red",
    "*menuButton*background:	steelblue",
    NULL,
};

void FinalQuit()
{
    int i,j;

    for (i=0; i<NP; i++)
	for (j=0; j<3; j++)
	    XFreePixmap(XtDisplay(topLevel),carol_xpm[i][j]);
    XtDestroyWidget(topLevel);
    exit(0);
}

void Quit(Widget w, XtPointer client_data, XtPointer call_data)
{
    int dnum;
	
    for (dnum=0; dpy[dnum]!=XtDisplay(w); dnum++)
	;
    ConfirmQuit(dnum);
}

void InitGame(void)
{
    int i;

    InitRound();
    InitPiles();
    stop_the_clock=False;	
    round=0;
    for (i=0; i<NP; i++)
    {
	app_data.score[i]=0;
	XcLcdUpdateValue(score1[i],&app_data.score[i]);
	XcLcdUpdateValue(score2[i],&app_data.score[i]);
    }
}

/* main controlling loop */
void MainLoop(void)
{
    static char buff[1024];
    Boolean end;
    int win,i;
	
    DoMess("Hello and welcome to Countdown.",5000);
    WaitForMess();
	
    DoMess("Hello and welcome to Countdown.",2000);

    for (i=0; i<NP; i++)
	ToggleAbout(i,False);

    WaitForMess();
    DoMess("Type your names in the boxes below, and press Return...",3000);
    waiting_for_names=True;
    while (got_name[0]==False || got_name[1]==False)
	ProcessEvent();
    waiting_for_names=False;
	
    while (1)
    {
	end=False;
	DoMess("Let's start as usual with a letters game.",3000);
	WaitForMess();
	while(!end)
	{
	    if (round==4)
		ply_go=1-ply_go;				
	    switch(round)
	    {
	    case 0: case 1: case 2: case 4: case 5: case 6: 
		LettRound();
		break;
	    case 3: case 7:
		NumRound();
		break;
	    default:
		Conun();
		/* check for draw */
		if (app_data.score[0]!=app_data.score[1])
		    end=True;
		else
		{
		    DoMess("It's a draw! Another conundrum will have to be played.",
			   3000);
		    InitRound();
		}
		break;
	    }
	}
	win = (app_data.score[0]>app_data.score[1]) ? 0 : 1;
	DoMess("That's it. Let's look at the final scores...",3000);
	sprintf(buff,"%s is the winner with %d points! Congratulations.",
		app_data.name[win],app_data.score[win]);
	DoMess(buff,15000);
	WaitForMess();
	if (!new_game)
	    DoMess("Select \"New Game\" from the Extras menu to play again...",2000);
	while (!new_game)
	    ProcessEvent();
	InitGame();
	for (i=0; i<NP; i++)
	    ClearNewGame(i);
    }
}

/* switch to a private colormap, if required */
void private_cmap(int dnum)
{
    printf("Switching to private colormap for player %i.\n",dnum);
    pseudo_cmap[dnum] = XCopyColormapAndFree(dpy[dnum],pseudo_cmap[dnum]);
    XtVaSetValues(topl[dnum],
		  XtNcolormap,pseudo_cmap[dnum],
		  NULL);
}

/* create main widgets */
void SetBoard(Widget top,int dpy)
{
    static String input_trans = "#override\n\
<Key>Tab:    no-op()\n\
<Key>Return: Bing()\n\
Ctrl<Key>R:  no-op()\n\
Ctrl<Key>S:  no-op()\n\
Ctrl<Key>I:  no-op()\n\
Meta<Key>I:  no-op()";
    static String no_input_trans = "#override\n\
<Key>: no-op()\n\
<Btn1Up>:   no-op()\n\
<Btn1Down>: no-op()\n\
<Btn2Up>:   no-op()\n\
<Btn2Down>: no-op()\n\
<Btn3Up>:   no-op()\n\
<Btn3Down>: no-op()";
    static String other_trans = "#override\n\
<Key>: KeyRedirect()";
    Widget tmain,title,board,ply1,ply2;
    Pixmap bg_xpm2;

    tmaind[dpy] = XtVaCreateManagedWidget("tmain",
					  formWidgetClass,top,
					  XtNtranslations,
					  XtParseTranslationTable(other_trans),
					  XtNmappedWhenManaged,False,
					  NULL);
    tmain=tmaind[dpy];

    title = XtVaCreateManagedWidget("title",
				    labelWidgetClass,tmain,
				    XtNlabel,"XCOUNTDOWN",
				    XtNborderWidth,0,
				    XtNwidth,353,
				    NULL);
    board = XtVaCreateManagedWidget("board",
				    formWidgetClass,tmain,
				    XtNfromVert,title,
				    XtNhorizDistance,10,
				    NULL);
    SetNumRound(board,dpy);
    SetLettRound(board,dpy); 
    SetupMenu(tmain,title,dpy);
	
    carol[dpy] = XtVaCreateManagedWidget("carol",
					 labelWidgetClass,tmain,
					 XtNfromVert,title,
					 XtNfromHoriz,board,
					 XtNlabel,"",
					 NULL);

    /* for the numbers round */
    cecil[dpy] = XtVaCreateManagedWidget("cecil",
					 xcLcdWidgetClass,tmain,
					 XtNvalue,0,
					 XcNvalueLength,3,
					 XtNfromVert,carol[dpy],
					 XtNfromHoriz,board,
					 XtNmappedWhenManaged,False,
					 XtNwidth,108,
					 XtNheight,48,
					 XtNlabel," ",
					 XcNshadeDepth,1,
					 XcNdataType,XcLval,
					 XcNlowerBound,0,
					 XcNupperBound,999,
					 XcNinterval,0,
					 NULL);
    richard[dpy] = XtVaCreateManagedWidget("richard",
					   asciiTextWidgetClass,tmain,
					   XtNfromVert,board,
					   XtNtranslations,
					   XtParseTranslationTable
					   (no_input_trans),
					   XtNwidth,441,
					   XtNheight,50,
					   XtNvertDistance,20,
					   XtNwrap,XawtextWrapWord,
					   XtNeditType,XawtextEdit,
					   NULL);
    XawTextDisplayCaret(richard[dpy],False);
    ply1 = XtVaCreateManagedWidget("ply1",
				   formWidgetClass,tmain,
				   XtNfromVert,richard[dpy],
				   XtNborderWidth,0,
				   XtNvertDistance,20,
				   XtNhorizDistance,15,
				   NULL);
    input1[dpy] = XtVaCreateManagedWidget("input1",
					  asciiTextWidgetClass,ply1,
					  XtNtranslations,
					  XtParseTranslationTable
					  ((dpy==0) ?
					   input_trans : no_input_trans),
					  XtNwidth,130,
					  XtNeditType,XawtextEdit,
					  NULL);
    name1[dpy] = XtVaCreateManagedWidget("name1",
					 labelWidgetClass,ply1,
					 XtNfromVert,input1[dpy],
					 XtNlabel,app_data.name[0],
					 XtNwidth,130,
					 NULL);
    score1[dpy] = XtVaCreateManagedWidget("score",
					  xcLcdWidgetClass,ply1,
					  XtNfromVert,name1[dpy],
					  XcNvalueLength,2,
					  XtNvalue,app_data.score[0],
					  XtNwidth,75,
					  XtNheight,45,
					  XtNlabel," ",
					  XtNhorizDistance,30,
					  XcNdataType,XcLval,
					  XcNlowerBound,0,
					  XcNupperBound,99,
					  XcNinterval,0,
					  XcNshadeDepth,1,
					  NULL);
    tclock[dpy] = XtVaCreateManagedWidget("tclock",
					  xfwfCircularPercentageWidgetClass,
					  tmain,
					  XtNfromVert,richard[dpy],
					  XtNfromHoriz,ply1,
					  XtNvertDistance,20,
					  XtNhorizDistance,15,
					  XtNwidth,113,
					  XtNheight,113,
					  XtNborderWidth,0,
					  NULL);
    ply2 = XtVaCreateManagedWidget("ply2",
				   formWidgetClass,tmain,
				   XtNfromVert,richard[dpy],
				   XtNfromHoriz,tclock[dpy],
				   XtNborderWidth,0,
				   XtNvertDistance,20,
				   XtNhorizDistance,15,
				   NULL);
    input2[dpy] = XtVaCreateManagedWidget("input2",
					  asciiTextWidgetClass,ply2,
					  XtNtranslations,
					  XtParseTranslationTable
					  ((dpy==0) ?
					   no_input_trans : input_trans),
					  XtNwidth,130,
					  XtNeditType,XawtextEdit,
					  NULL);
    name2[dpy] = XtVaCreateManagedWidget("name2",
					 labelWidgetClass,ply2,
					 XtNfromVert,input2[dpy],
					 XtNlabel,app_data.name[1],
					 XtNwidth,130,
					 NULL);
    score2[dpy] = XtVaCreateManagedWidget("score",
					  xcLcdWidgetClass,ply2,
					  XtNfromVert,name2[dpy],
					  XcNvalueLength,2,
					  XtNvalue,app_data.score[1],
					  XtNwidth,75,
					  XtNheight,45,
					  XtNlabel," ",
					  XtNhorizDistance,30,
					  XcNdataType,XcLval,
					  XcNlowerBound,0,
					  XcNupperBound,99,
					  XcNinterval,0,
					  XcNshadeDepth,1,
					  NULL);
    XawTextDisplayCaret((dpy==0) ? input2[dpy] : input1[dpy],False);

    /* load Carol XPMs */
    if (!load_data_pixmap(carol1,&carol_xpm[dpy][0],top,pseudo_cmap[dpy]))
    {
	private_cmap(dpy);
	load_data_pixmap(carol1,&carol_xpm[dpy][0],top,pseudo_cmap[dpy]);
    }
    if (!load_data_pixmap(carol2,&carol_xpm[dpy][1],top,pseudo_cmap[dpy]))
    {
	private_cmap(dpy);
	load_data_pixmap(carol2,&carol_xpm[dpy][1],top,pseudo_cmap[dpy]);
    }
    if (!load_data_pixmap(carol3,&carol_xpm[dpy][2],top,pseudo_cmap[dpy]))
    {
	private_cmap(dpy);
	load_data_pixmap(carol3,&carol_xpm[dpy][2],top,pseudo_cmap[dpy]);
    }
    XtVaSetValues(carol[dpy],
		  XtNwidth,66,
		  XtNheight,112,
		  XtNbackgroundPixmap,(XtArgVal)carol_xpm[dpy][1],
		  XtNhorizDistance,27,
		  NULL);

    if (!LoadAboutXPM(dpy))
    {

	private_cmap(dpy);
	LoadAboutXPM(dpy);
    }
    SetAboutXPM(tmain,dpy);

    if (!load_data_pixmap(slate,&bg_xpm[dpy],top,pseudo_cmap[dpy]))
    {
	private_cmap(dpy);
	load_data_pixmap(slate,&bg_xpm[dpy],top,pseudo_cmap[dpy]);
    }       

    XtVaSetValues(ply1,XtNbackgroundPixmap,(XtArgVal)bg_xpm[dpy],NULL);
    XtVaSetValues(ply2,XtNbackgroundPixmap,(XtArgVal)bg_xpm[dpy],NULL);
    XtVaSetValues(tclock[dpy],XtNbackgroundPixmap,(XtArgVal)bg_xpm[dpy],NULL);
    XtVaSetValues(title,XtNbackgroundPixmap,(XtArgVal)bg_xpm[dpy],NULL);
    if (!load_data_pixmap(slate2,&bg_xpm2,top,pseudo_cmap[dpy]))
    {
	private_cmap(dpy);
	load_data_pixmap(slate2,&bg_xpm2,top,pseudo_cmap[dpy]);
    }
    XtVaSetValues(board,XtNbackgroundPixmap,(XtArgVal)bg_xpm2,NULL);
    /*		XFreePixmap(XtDisplay(top),bg_xpm);
		XFreePixmap(XtDisplay(top),bg_xpm2);
		*/
    XtVaSetValues(top,XtNtitle,app_data.name[dpy],NULL);	

    acceptQuitPre(top);
    XtRealizeWidget(top);
    acceptQuitPost(top);
}

/* create board widgets for letters game */
void SetLettRound(Widget top,int dpy)
{
    int ac,dn;
	
    for (dn=0; dn<2; dn++)
	for (ac=0; ac<NL; ac++)
	{
	    lett[dpy][ac][dn] = XtVaCreateManagedWidget("lett",
							labelWidgetClass,top,
							XtNlabel,"  ",
							XtNvertDistance,26,
							XtNhorizDistance,6,
							NULL);
	    if (ac>0)
		XtVaSetValues(lett[dpy][ac][dn],
			      XtNfromHoriz,lett[dpy][ac-1][dn],
			      XtNhorizDistance,3,
			      NULL);
	    if (dn>0)
		XtVaSetValues(lett[dpy][ac][dn],
			      XtNfromVert,lett[dpy][ac][dn-1],
			      XtNvertDistance,7,
			      NULL);
	}
    vbutt[dpy] = XtVaCreateManagedWidget("vbutt",
					 commandWidgetClass,top,
					 XtNfromVert,lett[dpy][0][1],
					 XtNvertDistance,22,
					 XtNhorizDistance,6,
					 XtNlabel,"Vowel",
					 XtNwidth,151,
					 NULL);
    cbutt[dpy] = XtVaCreateManagedWidget("cbutt",
					 commandWidgetClass,top,
					 XtNfromVert,lett[dpy][0][1],
					 XtNfromHoriz,vbutt[dpy],
					 XtNvertDistance,22,
					 XtNhorizDistance,10,
					 XtNlabel,"Consonant",
					 XtNwidth,151,
					 NULL);
    XtAddCallback(vbutt[dpy],XtNcallback,DoLett,NULL);
    XtAddCallback(cbutt[dpy],XtNcallback,DoLett,NULL);
}

/* create board widgets for numbers game */
void SetNumRound(Widget top,int dnum)
{
    int ac,dn;
    Widget pform;
    static String input_trans = "#override\n\
<Key>Tab:    no-op()\n\
<Key>Return: Enter()\n\
Ctrl<Key>R:  no-op()\n\
Ctrl<Key>S:  no-op()\n\
Ctrl<Key>I:  no-op()\n\
Meta<Key>I:  no-op()";
    const int WD=310,HT=62;
    const int SWD=200,SHT=120;
  
    for (ac=0; ac<6; ac++)
    {
	cnum[dnum][ac] = XtVaCreateManagedWidget("cnum",
						 labelWidgetClass,top,
						 XtNlabel,"   ",
						 XtNmappedWhenManaged,False,
						 XtNhorizDistance,26,
						 NULL);
	if (ac>0)
	    XtVaSetValues(cnum[dnum][ac],
			  XtNfromHoriz,cnum[dnum][ac-1],
			  XtNhorizDistance,2,
			  NULL);
    }
  
    for (dn=0; dn<4; dn++)
	for (ac=0; ac<7; ac++)
	{
	    num[dnum][ac][dn] =
		XtVaCreateManagedWidget("num",
					((dn==0 && (ac<=1 || ac==6)) ||
					 (dn==1 && ac==0)) ?
					labelWidgetClass : 
					toggleWidgetClass,top,
					XtNlabel,"   ",
					XtNmappedWhenManaged,False,
					XtNhighlightThickness,0,
					XtNborderWidth,1,
					NULL);
	    if (ac>0)
		XtVaSetValues(num[dnum][ac][dn],
			      XtNfromHoriz,num[dnum][ac-1][dn],
			      XtNhorizDistance,2,
			      NULL);			
	    if (dn>0)
		XtVaSetValues(num[dnum][ac][dn],
			      XtNfromVert,num[dnum][ac][dn-1],
			      XtNvertDistance,2,
			      NULL);
	    else
		XtVaSetValues(num[dnum][ac][dn],
			      XtNfromVert,cnum[0][0],
			      XtNvertDistance,10,
			      NULL);
	    if (!((dn==0 && (ac<=1 || ac==6)) || (dn==1 && ac==0)))
		XtAddCallback(num[dnum][ac][dn],XtNcallback,Tog,NULL);
	    else
		XtVaSetValues(num[dnum][ac][dn],SETBG(gray70),NULL);
	}
  
    /* create the popups required for entering and displaying method */
    ptop[dnum] = XtVaAppCreateShell("ptop","XCountdown",
				    applicationShellWidgetClass,dpy[dnum],
				    XtNmappedWhenManaged,False,
				    XtNtitle,"XCountdown",
				    XtNiconName,"XCountdown",
				    XtNwidth,WD,
				    XtNminWidth,WD,
				    XtNmaxWidth,WD,
				    XtNheight,HT,
				    XtNminHeight,HT,
				    XtNmaxHeight,HT,
				    XtNcolormap,pseudo_cmap[dnum],
				    NULL);
    pform = XtVaCreateManagedWidget("pform",
				    formWidgetClass,ptop[dnum],
				    NULL);
    ptitle[dnum] = XtVaCreateManagedWidget("ptitle",
					   labelWidgetClass,pform,
					   XtNwidth,300,
					   XtNlabel,"Enter your expression...",
					   NULL);
    pmain[dnum] = XtVaCreateManagedWidget("pmain",
					  asciiTextWidgetClass,pform,
					  XtNfromVert,ptitle[dnum],
					  XtNwidth,300,
					  XtNtranslations,
					  XtParseTranslationTable(input_trans),
					  XtNeditType,XawtextEdit,
					  NULL);
    XtRealizeWidget(ptop[dnum]);
    /* create the popups for smug mode */
    smtop[dnum] = XtVaAppCreateShell("smtop","XCountdown",
				     applicationShellWidgetClass,dpy[dnum],
				     XtNmappedWhenManaged,False,
				     XtNtitle,"XCountdown",
				     XtNiconName,"XCountdown",
				     XtNwidth,SWD,
				     XtNminWidth,SWD,
				     XtNmaxWidth,SWD,
				     XtNheight,SHT,
				     XtNminHeight,SHT,
				     XtNmaxHeight,SHT,
				     XtNcolormap,pseudo_cmap[dnum],
				     NULL);
    smmain[dnum] = XtVaCreateManagedWidget("smmain",
					   labelWidgetClass,smtop[dnum],
					   XtNwidth,200,
					   XtNheight,120,
					   NULL);
    XtRealizeWidget(smtop[dnum]);	
}

void ChangeCarol(int newcarol)
{
    int width,horz,i;
	
    if (newcarol==1)
    {
	width=78;
	horz=20;
    } else if (newcarol==2)
    {
	width=66;
	horz=27;
    }
    else
    {
	width=96;
	horz=10;
    }
    for (i=0; i<NP; i++)
    {
	XtVaSetValues(carol[i],
		      XtNwidth,width,
		      XtNheight,112,
		      XtNbackgroundPixmap,(XtArgVal)carol_xpm[i][newcarol-1],
		      XtNhorizDistance,horz,
		      NULL);
	XtResizeWidget(carol[i],width,112,1);
    }
}


/* main program */
int main(int argc, char **argv)
{
    int i;
    char other_disp[1025];
    Display *tdpy;
    Boolean mono=False;
    static XtActionsRec actions[] = {
	{"KeyRedirect", KeyRedirect },
	{"Bing", Bing },
	{"Enter", Enter },
    };
    const int WD=456,HT=410;

    printf("XCountdown - by Matt Chapman (matt@belgarath.demon.co.uk)\n");

#ifdef DEBUG
    printf("Debugging output is enabled.\n");
#endif
    srand((unsigned int)time((time_t *)NULL));

    tdpy=XOpenDisplay(NULL);
    if (DefaultDepth(tdpy,XDefaultScreen(tdpy))==1)
    {
	printf("Using monochrome mode.\n");
	mono=True;
	strcpy(steelblue,"white");
	strcpy(gray40,"black");
	strcpy(gray90,"white");
	strcpy(gray70,"white");
    }
    XCloseDisplay(tdpy);
	
    topLevel = XtVaAppInitialize(&app_context,"_XCountdown",NULL,0,
				 &argc,argv,(mono) ? bw_res : col_res,XtNtitle,"XCountdown",
				 XtNiconName,"XCountdown",NULL);

    if ((argc != 2) || (argv[1][0]=='-'))
    {
	fprintf(stderr,"  X version of the popular Channel 4 quiz show.\n\n");
	fprintf(stderr,"Usage: %s <second_display>\n",argv[0]);
	fprintf(stderr,"  Where <second_display> is the display which Player 2's window will get\n");
	fprintf(stderr,"  sent to. This is something like \"cookie:0.0\", or simply \"cookie\", as\n");
	fprintf(stderr,"  \":0.0\" is appended if the given display does not contain \":\". You must\n" );
	fprintf(stderr,"  have permission to connect to the server on the given machine.\n\n");
	fprintf(stderr,"  Example: Assuming someone on a machine called figroll wish to play\n");
	fprintf(stderr,"  with someone on wafer, the person on wafer would type \"xhost figroll\"\n");
	fprintf(stderr,"  to give them display permission. Then the person on figroll would type\n");
	fprintf(stderr,"  \"xcountdown wafer\".\n");
	return(1);
    }
    /* get DISPLAY for other player */
    strncpy(other_disp,argv[1],1024);
    if (strchr(other_disp,':')==NULL)
	strcat(other_disp,":0.0");

    XtAppAddActions(app_context,actions,XtNumber(actions));	

    /* open displays */
    for (i=0; i<NP; i++)
    {
	char buff[1024];
	sprintf(app_data.name[i],"Player %d",i+1);

	if (i==0)
	    strncpy(buff,getenv("DISPLAY"),1024);
	else
	    strncpy(buff,other_disp,1024);
	dpy[i] = XtOpenDisplay(app_context,buff,argv[0],
			       "XCountdown",NULL,0,&argc,argv);
	if (dpy[i] == NULL)
	{
	    fprintf(stderr,"Can't open display %s\n",buff);
	    exit(1);
	}
	app_data.score[i]=0;
    }

    loaddict();
    InitPiles();

    /* setup widgets on displays */
    for (i=0; i<NP; i++)
    {
	pseudo_cmap[i] = DefaultColormap(dpy[i],DefaultScreen(dpy[i]));

	topl[i] =  XtVaAppCreateShell("topl","XCountdown",
				      applicationShellWidgetClass,dpy[i],
				      XtNtitle,"XCountdown",
				      XtNiconName,"XCountdown",
				      XtNwidth,WD,
				      XtNminWidth,WD,
				      XtNmaxWidth,WD,
				      XtNheight,HT,
				      XtNminHeight,HT,
				      XtNmaxHeight,HT,
				      XtNcolormap,pseudo_cmap[i],
				      NULL);
	/* alloc required colours - XPMs done separately */
	if (!mono)
	{
	    int cl;
	    XColor junk1,junk2;

	    for (cl=0; cl<7; cl++)
	    {
		if (!(XAllocNamedColor(dpy[i],pseudo_cmap[i],cols_used[cl],
				       &junk1,&junk2)))
		{
		    private_cmap(i);
		    XAllocNamedColor(dpy[i],pseudo_cmap[i],cols_used[cl],
				     &junk1,&junk2);
		}
	    }
	}

	SetBoard(topl[i],i);
    }

    /* call main game loop - instead of XtAppMainLoop. Event processing is
       handled by ProcessEvent()
       */
    MainLoop();
    FinalQuit();
    return(0);
}

