/*  drawing.c

    Copyright (C) 1994	Lambert Klasen & Detlef Steuer
			klasen@asterix.uni-muenster.de
			steuer@amadeus.statistik.uni-dortmund.de

    This file is free source code; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
    COPYING for more details.
 */


#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Xatom.h>
#include <X11/Shell.h>
#include <stdio.h>
#include <stdlib.h>

#include "xgammon.h"
#include "gammon.h"


XPoint		PinToPosition     (int pin);
void		DrawEmptyBoard    ();
void		DrawBoard         ();
void		DrawDice          ();
void		DeleteDice        ();
void		DrawEmptyDice     ();
void		DrawDiceValues    ();
void		DrawDoubler       ();
void		PutStone          (unsigned int color, unsigned int pin);
void		DrawStone         ();
void		RemoveStone       ();
void		RedrawAllStones   ();
void		FreePixmaps       ();
void		CreatePixmaps     ();
static void	draw_one	  ();
static void	draw_two	  ();
static void	draw_three	  ();
static void	draw_four	  ();
static void	draw_five	  ();
static void	draw_six	  ();

int		rect_width, rect_height;
static int	dice_x = 0, dice_y = 0;

void DrawBoard (void)
{
	Display *dpy 	= Player[0].X11Set.dpy;
	Pixmap	pixmap  = Player[0].X11Set.board.pixmap;
	Window	window  = Player[0].X11Set.board.window;
	GC	gc 	= Player[0].X11Set.board.gc;

	XCopyArea (dpy, pixmap, window, gc, 0, 0, width, height, 0, 0);

	if (gammon_resource.other_display) {
		dpy 	= Player[1].X11Set.dpy;
		pixmap  = Player[1].X11Set.board.pixmap;
		window  = Player[1].X11Set.board.window;
		gc 	= Player[1].X11Set.board.gc;

		XCopyArea (dpy, pixmap, window, gc, 0, 0, width, height, 0, 0);
	}
}

void DrawEmptyBoard (void)
{
	Display *dpy 	 = Player[0].X11Set.dpy;
	Pixmap	pixmap   = Player[0].X11Set.board.pixmap;
	GC	board_gc = Player[0].X11Set.board.gc;
	GC	gc 	 = Player[0].X11Set.gc;

	XPoint c[3];
	int i;
	int s = 0;
	static int here = 0;

	rect_width  = stone_width;
	rect_height = stone_width * 5;

	XSetForeground (dpy, board_gc, gammon_resource.board_Pixel);
	XFillRectangle (dpy, pixmap, board_gc, 0, 0, width, height);

	XSetForeground (dpy, board_gc, gammon_resource.bar_Pixel);
	XFillRectangle (dpy, pixmap, board_gc, 0,		     0, rect_width, height);
	XFillRectangle (dpy, pixmap, board_gc, rect_width * 7,     0, rect_width, height);
	XFillRectangle (dpy, pixmap, board_gc, width - rect_width, 0, rect_width, height);

	for (i=1; i<13; i++) {

		/* first draw a filled triangle */
		c[0].x = i * rect_width;	if (i>6) c[0].x += rect_width;
		c[0].y = 0;
		c[1].x = c[0].x + rect_width;
		c[1].y = 0;
		c[2].x = c[0].x + rect_width/2;
		c[2].y = rect_height;

		if (s) XSetForeground (dpy, board_gc, gammon_resource.light_Pixel);
		else   XSetForeground (dpy, board_gc, gammon_resource.dark_Pixel);
		XFillPolygon (dpy, pixmap, board_gc, c, 3, Convex, CoordModeOrigin);

		/* then a little black border around it */
		/* base */
		XDrawLine (dpy, pixmap, gc, c[0].x, c[0].y, c[0].x, c[1].y);

		/* left side */
		c[1].y =  rect_height;
		c[1].x -= rect_width/2;
		XDrawLine (dpy, pixmap, gc, c[0].x,	      c[0].y, c[1].x, c[1].y);

		/* right side */
		XDrawLine (dpy, pixmap, gc, c[0].x + rect_width, c[0].y, c[1].x, c[1].y);

		if (s==0) s=1; else s=0;
	}

	for(i=1; i<13; i++) {
		/* draw a triangle */
		c[0].x = i * rect_width; if (i > 6) c[0].x += rect_width;
		c[0].y = height - 1;
		c[1].x = c[0].x + rect_width;
		c[1].y = height - 1;
		c[2].x = c[0].x + rect_width/2;
		c[2].y = height - rect_height;

		/* make the opposing colors different, so !s */
		if (!s) XSetForeground (dpy, board_gc, gammon_resource.light_Pixel);
		else    XSetForeground (dpy, board_gc, gammon_resource.dark_Pixel);
		XFillPolygon (dpy, pixmap, board_gc, c, 3, Convex, CoordModeOrigin);

		/* and around it a little black border */
		c[0].x = i  * rect_width; if (i > 6) c[0].x += rect_width;
		c[1].x = c[0].x + rect_width;
		c[0].y = c[1].y = height - 1;
		XDrawLine (dpy, pixmap, gc, c[0].x, c[0].y, c[0].x, c[1].y);
		c[1].y =  height - rect_height;
		c[1].x -= rect_width/2;
		XDrawLine (dpy, pixmap, gc, c[0].x, c[0].y, c[1].x, c[1].y);
		XDrawLine (dpy, pixmap, gc, c[0].x + rect_width, c[0].y, c[1].x, c[1].y);

		if (s==0) s=1; else s=0;
	}

	if (gammon_resource.other_display) {
	dpy 	 = Player[1].X11Set.dpy;
	pixmap   = Player[1].X11Set.board.pixmap;
	board_gc = Player[1].X11Set.board.gc;
	gc 	 = Player[1].X11Set.gc;

	s = 0;

	rect_width  = stone_width;
	rect_height = stone_width * 5;

	XSetForeground (dpy, board_gc, gammon_resource.board_Pixel);
	XFillRectangle (dpy, pixmap, board_gc, 0, 0, width, height);

	XSetForeground (dpy, board_gc, gammon_resource.bar_Pixel);
	XFillRectangle (dpy, pixmap, board_gc, 0,		     0, rect_width, height);
	XFillRectangle (dpy, pixmap, board_gc, rect_width * 7,     0, rect_width, height);
	XFillRectangle (dpy, pixmap, board_gc, width - rect_width, 0, rect_width, height);

	for (i=1; i<13; i++) {

		/* first draw a filled triangle */
		c[0].x = i * rect_width;	if (i>6) c[0].x += rect_width;
		c[0].y = 0;
		c[1].x = c[0].x + rect_width;
		c[1].y = 0;
		c[2].x = c[0].x + rect_width/2;
		c[2].y = rect_height;

		if (s) XSetForeground (dpy, board_gc, gammon_resource.light_Pixel);
		else   XSetForeground (dpy, board_gc, gammon_resource.dark_Pixel);
		XFillPolygon (dpy, pixmap, board_gc, c, 3, Convex, CoordModeOrigin);

		/* then a little black border around it */
		/* base */
		XDrawLine (dpy, pixmap, gc, c[0].x, c[0].y, c[0].x, c[1].y);

		/* left side */
		c[1].y =  rect_height;
		c[1].x -= rect_width/2;
		XDrawLine (dpy, pixmap, gc, c[0].x,	      c[0].y, c[1].x, c[1].y);

		/* right side */
		XDrawLine (dpy, pixmap, gc, c[0].x + rect_width, c[0].y, c[1].x, c[1].y);

		if (s==0) s=1; else s=0;
	}

	for(i=1; i<13; i++) {
		/* draw a triangle */
		c[0].x = i * rect_width; if (i > 6) c[0].x += rect_width;
		c[0].y = height - 1;
		c[1].x = c[0].x + rect_width;
		c[1].y = height - 1;
		c[2].x = c[0].x + rect_width/2;
		c[2].y = height - rect_height;

		/* make the opposing colors different, so !s */
		if (!s) XSetForeground (dpy, board_gc, gammon_resource.light_Pixel);
		else    XSetForeground (dpy, board_gc, gammon_resource.dark_Pixel);
		XFillPolygon (dpy, pixmap, board_gc, c, 3, Convex, CoordModeOrigin);

		/* and around it a little black border */
		c[0].x = i  * rect_width; if (i > 6) c[0].x += rect_width;
		c[1].x = c[0].x + rect_width;
		c[0].y = c[1].y = height - 1;
		XDrawLine (dpy, pixmap, gc, c[0].x, c[0].y, c[0].x, c[1].y);
		c[1].y =  height - rect_height;
		c[1].x -= rect_width/2;
		XDrawLine (dpy, pixmap, gc, c[0].x, c[0].y, c[1].x, c[1].y);
		XDrawLine (dpy, pixmap, gc, c[0].x + rect_width, c[0].y, c[1].x, c[1].y);

		if (s==0) s=1; else s=0;
	}
	} /* other_display */
	/*DrawBoard ();*/

	here = 1;
}

void DrawDice (int color)
{
	DeleteDice     ();
	DrawEmptyDice  (color);
	DrawDiceValues ();
}

void DeleteDice ()
{
	Display *dpy  = Player[0].X11Set.dpy;
	Pixmap pixmap = Player[0].X11Set.board.pixmap;
	Window window = Player[0].X11Set.board.window;
	GC     gc     = Player[0].X11Set.board.gc;

	int x;

	if (!dice_y) return;

	if (turn == BLACK) x = 3 * stone_width + stone_width/2 - 3; /* remove white dice */
	else 		   x = 9 * stone_width + stone_width/2 - 3;

	XSetForeground (dpy, gc,     gammon_resource.board_Pixel);
	XFillRectangle (dpy, window, gc, x, dice_y - 3, stone_width * 2 + stone_width/2 + 6, dice_width + 6);
	XFillRectangle (dpy, window, gc, x, dice_y - 3, stone_width * 2 + stone_width/2 + 6, dice_width + 6);
	XFillRectangle (dpy, pixmap, gc, x, dice_y - 3, stone_width * 2 + stone_width/2 + 6, dice_width + 6);
	XFillRectangle (dpy, pixmap, gc, x, dice_y - 3, stone_width * 2 + stone_width/2 + 6, dice_width + 6);

	if (gammon_resource.other_display) {
	dpy    = Player[1].X11Set.dpy;
	pixmap = Player[1].X11Set.board.pixmap;
	window = Player[1].X11Set.board.window;
	gc     = Player[1].X11Set.board.gc;

	XSetForeground (dpy, gc,     gammon_resource.board_Pixel);
	XFillRectangle (dpy, window, gc, x, dice_y - 3, stone_width * 2 + stone_width/2 + 6, dice_width + 6);
	XFillRectangle (dpy, window, gc, x, dice_y - 3, stone_width * 2 + stone_width/2 + 6, dice_width + 6);
	XFillRectangle (dpy, pixmap, gc, x, dice_y - 3, stone_width * 2 + stone_width/2 + 6, dice_width + 6);
	XFillRectangle (dpy, pixmap, gc, x, dice_y - 3, stone_width * 2 + stone_width/2 + 6, dice_width + 6);
	}
}

void DrawEmptyDice (int color)
{
	Display *dpy  = Player[0].X11Set.dpy;
	Pixmap pixmap = Player[0].X11Set.board.pixmap;
	Window window = Player[0].X11Set.board.window;
	GC     diceGC = Player[0].X11Set.diceGC;

	static int backup_width = 0;
	unsigned long b, w; /* black and white pixel */

	if (!backup_width) backup_width = width;

	dice_y = 6 * stone_width - dice_width/2;

	if (color == BLACK) {
		b = gammon_resource.white_Pixel;
		w = gammon_resource.black_Pixel;
		dice_x = 9 * stone_width + stone_width/2;
	}
	else {
	        w = gammon_resource.white_Pixel;
	        b = gammon_resource.black_Pixel;
		dice_x = 3 * stone_width + stone_width/2;
        }

	
	if (width != backup_width) {
		int line_width;
		backup_width = width;

		line_width = width/100;
		XSetLineAttributes (dpy, diceGC, line_width, LineSolid, CapRound, JoinMiter);
	}

	XSetForeground (dpy, diceGC, w);
	XFillRectangle (dpy, window, diceGC, dice_x, dice_y, dice_width, dice_width);
	XFillRectangle (dpy, window, diceGC, dice_x + dice_width + dice_width/2, dice_y, dice_width, dice_width);
	XFillRectangle (dpy, pixmap, diceGC, dice_x, dice_y, dice_width, dice_width);
	XFillRectangle (dpy, pixmap, diceGC, dice_x + dice_width + dice_width/2, dice_y, dice_width, dice_width);
	XSetForeground (dpy, diceGC, b);
	XDrawRectangle (dpy, window, diceGC, dice_x, dice_y, dice_width, dice_width);
	XDrawRectangle (dpy, window, diceGC, dice_x + dice_width + dice_width/2, dice_y, dice_width, dice_width);
	XDrawRectangle (dpy, pixmap, diceGC, dice_x, dice_y, dice_width, dice_width);
	XDrawRectangle (dpy, pixmap, diceGC, dice_x + dice_width + dice_width/2, dice_y, dice_width, dice_width);

	if (gammon_resource.other_display) {
	dpy    = Player[1].X11Set.dpy;
	pixmap = Player[1].X11Set.board.pixmap;
	window = Player[1].X11Set.board.window;
	diceGC = Player[1].X11Set.diceGC;

	XSetForeground (dpy, diceGC, w);
	XFillRectangle (dpy, window, diceGC, dice_x, dice_y, dice_width, dice_width);
	XFillRectangle (dpy, window, diceGC, dice_x + dice_width + dice_width/2, dice_y, dice_width, dice_width);
	XFillRectangle (dpy, pixmap, diceGC, dice_x, dice_y, dice_width, dice_width);
	XFillRectangle (dpy, pixmap, diceGC, dice_x + dice_width + dice_width/2, dice_y, dice_width, dice_width);
	XSetForeground (dpy, diceGC, b);
	XDrawRectangle (dpy, window, diceGC, dice_x, dice_y, dice_width, dice_width);
	XDrawRectangle (dpy, window, diceGC, dice_x + dice_width + dice_width/2, dice_y, dice_width, dice_width);
	XDrawRectangle (dpy, pixmap, diceGC, dice_x, dice_y, dice_width, dice_width);
	XDrawRectangle (dpy, pixmap, diceGC, dice_x + dice_width + dice_width/2, dice_y, dice_width, dice_width);
	}
}

void DrawDiceValues (void)
{
	switch (abs(roll[0])) {
		case 1: draw_one   (dice_x, dice_y, dice_width); break;
		case 2: draw_two   (dice_x, dice_y, dice_width); break;
		case 3: draw_three (dice_x, dice_y, dice_width); break;
		case 4: draw_four  (dice_x, dice_y, dice_width); break;
		case 5: draw_five  (dice_x, dice_y, dice_width); break;
		case 6: draw_six   (dice_x, dice_y, dice_width); break;
	}

	switch (abs(roll[1])) {
		case 1: draw_one   (dice_x + dice_width + dice_width/2, dice_y, dice_width); break;
		case 2: draw_two   (dice_x + dice_width + dice_width/2, dice_y, dice_width); break;
		case 3: draw_three (dice_x + dice_width + dice_width/2, dice_y, dice_width); break;
		case 4: draw_four  (dice_x + dice_width + dice_width/2, dice_y, dice_width); break;
		case 5: draw_five  (dice_x + dice_width + dice_width/2, dice_y, dice_width); break;
		case 6: draw_six   (dice_x + dice_width + dice_width/2, dice_y, dice_width); break;
	}
}

void DrawDoubler  (int how_double, int who_doubled) /* doubler is as wide as a stone */
{
	Display *dpy  = Player[0].X11Set.dpy;
	Pixmap pixmap = Player[0].X11Set.board.pixmap;
	Window window = Player[0].X11Set.board.window;
	GC     gc     = Player[0].X11Set.board.gc;
	GC     diceGC = Player[0].X11Set.diceGC;

	Display *o_dpy  = Player[1].X11Set.dpy;
	Pixmap o_pixmap = Player[1].X11Set.board.pixmap;
	Window o_window = Player[1].X11Set.board.window;
	GC     o_gc     = Player[1].X11Set.board.gc;
	GC     o_diceGC = Player[1].X11Set.diceGC;

	int x = 0;
	static int y = 0; /* yes */
	int font_height, font_width;

	char t[3];

	/* all the x+1, y-3, x-1 ... or some like that are more or lesss
	   neccessary cause of XDrawLine () Function */

	/* remove old doubler */
	XSetForeground (dpy, gc, gammon_resource.bar_Pixel);
	XFillRectangle (dpy, window, gc, x, y - 3, stone_width, 2*stone_width);
	XFillRectangle (dpy, pixmap, gc, x, y - 3, stone_width, 2*stone_width);

	if (gammon_resource.other_display) {
	XSetForeground (o_dpy, o_gc, gammon_resource.bar_Pixel);
	XFillRectangle (o_dpy, o_window, o_gc, x, y - 3, stone_width, 2*stone_width);
	XFillRectangle (o_dpy, o_pixmap, o_gc, x, y - 3, stone_width, 2*stone_width);
	}
	/* set new position */
	switch (who_doubled) {
	case BLACK: y = 2*stone_width; break;
	case WHITE: y = 9*stone_width; break;
	default:    y = 5*stone_width + stone_width/2; break;
	}

	/* draw new one */
	XSetForeground (dpy, diceGC,      gammon_resource.white_Pixel);
	XFillRectangle (dpy, window, diceGC, x+1, y, stone_width-3, stone_width);
	XFillRectangle (dpy, pixmap, diceGC, x+1, y, stone_width-3, stone_width);
	XSetForeground (dpy, diceGC,      gammon_resource.black_Pixel);
	XDrawRectangle (dpy, window, diceGC, x+1, y, stone_width-3, stone_width);
	XDrawRectangle (dpy, pixmap, diceGC, x+1, y, stone_width-3, stone_width);

	if (gammon_resource.other_display) {
	XSetForeground (o_dpy, o_diceGC,      gammon_resource.white_Pixel);
	XFillRectangle (o_dpy, o_window, o_diceGC, x+1, y, stone_width-3, stone_width);
	XFillRectangle (o_dpy, o_pixmap, o_diceGC, x+1, y, stone_width-3, stone_width);
	XSetForeground (o_dpy, o_diceGC,      gammon_resource.black_Pixel);
	XDrawRectangle (o_dpy, o_window, o_diceGC, x+1, y, stone_width-3, stone_width);
	XDrawRectangle (o_dpy, o_pixmap, o_diceGC, x+1, y, stone_width-3, stone_width);
	}

	sprintf (t, "%d", how_double);		/* see 6 lines below */

	/* decide witch font to use */
	if ((Player[0].X11Set.doubler_font->ascent + Player[0].X11Set.doubler_font->descent + 6) > stone_width) {
		XSetFont (dpy, diceGC, Player[0].X11Set.small_font->fid);
		font_height = Player[0].X11Set.small_font->ascent + Player[0].X11Set.small_font->descent;
		font_width  = Player[0].X11Set.small_font->per_char[t[0] - Player[0].X11Set.small_font->min_char_or_byte2].width;
	} else {
		XSetFont (dpy, diceGC, Player[0].X11Set.doubler_font->fid);
		font_height = Player[0].X11Set.doubler_font->ascent + Player[0].X11Set.doubler_font->descent;
		font_width  = Player[0].X11Set.doubler_font->per_char[t[0] - Player[0].X11Set.doubler_font->min_char_or_byte2].width;
	}

	if (gammon_resource.other_display) {
	if ((Player[1].X11Set.doubler_font->ascent + Player[1].X11Set.doubler_font->descent + 6) > stone_width) {
		XSetFont (o_dpy, o_diceGC, Player[1].X11Set.small_font->fid);
		font_height = Player[1].X11Set.small_font->ascent + Player[1].X11Set.small_font->descent;
		font_width  = Player[1].X11Set.small_font->per_char[t[0] - Player[1].X11Set.small_font->min_char_or_byte2].width;
	} else {
		XSetFont (o_dpy, o_diceGC, Player[1].X11Set.doubler_font->fid);
		font_height = Player[1].X11Set.doubler_font->ascent + Player[1].X11Set.doubler_font->descent;
		font_width  = Player[1].X11Set.doubler_font->per_char[t[0] - Player[1].X11Set.doubler_font->min_char_or_byte2].width;
	}
	}

	font_width *= strlen (t);		/* see 7 lines above */

	/* draw the text */
	x += stone_width/2 - font_width/2;
	y += stone_width - (stone_width - font_height)/2 - 3;
	XDrawImageString (dpy, window, diceGC, x , y, t, strlen (t));
	XDrawImageString (dpy, pixmap, diceGC, x , y, t, strlen (t));
	if (gammon_resource.other_display) {
	XDrawImageString (o_dpy, o_window, o_diceGC, x , y, t, strlen (t));
	XDrawImageString (o_dpy, o_pixmap, o_diceGC, x , y, t, strlen (t));
	}

	/* reset y for remove */
	y -= stone_width - (stone_width - font_height)/2 - 3;
}

void draw_one (int dice_x, int dice_y, int dice_width)
{
	Display *dpy  = Player[0].X11Set.dpy;
	Pixmap pixmap = Player[0].X11Set.board.pixmap;
	Window window = Player[0].X11Set.board.window;
	GC     gc     = Player[0].X11Set.diceGC;

	int x, y, r;

	r = dice_width/4;
	x = dice_x + dice_width/2 - r/2;
	y = dice_y + dice_width/2 - r/2;

	XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
	XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);

	if (gammon_resource.other_display) {
		dpy    = Player[1].X11Set.dpy;
		pixmap = Player[1].X11Set.board.pixmap;
		window = Player[1].X11Set.board.window;
		gc     = Player[1].X11Set.diceGC;

		XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
		XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);
	}
}

void draw_two (int dice_x, int dice_y, int dice_width)
{
	Display *dpy  = Player[0].X11Set.dpy;
	Pixmap pixmap = Player[0].X11Set.board.pixmap;
	Window window = Player[0].X11Set.board.window;
	GC     gc     = Player[0].X11Set.diceGC;

	int x, y, r;

	r = dice_width/4;
	x = dice_x + dice_width/4 - r/4;
	y = dice_y + dice_width/4 - r/4;

	XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
	XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);

	x = dice_x + dice_width - (dice_width - 6)/4 - r;
	y = dice_y + dice_width - (dice_width - 6)/4 - r;

	XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
	XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);

	if (gammon_resource.other_display) {
		dpy    = Player[1].X11Set.dpy;
		pixmap = Player[1].X11Set.board.pixmap;
		window = Player[1].X11Set.board.window;
		gc     = Player[1].X11Set.diceGC;

		x = dice_x + dice_width/4 - r/4;
		y = dice_y + dice_width/4 - r/4;

		XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
		XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);

		x = dice_x + dice_width - (dice_width - 6)/4 - r;
		y = dice_y + dice_width - (dice_width - 6)/4 - r;

		XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
		XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);
	}
}

void draw_three (int dice_x, int dice_y, int dice_width)
{
	Display *dpy  = Player[0].X11Set.dpy;
	Pixmap pixmap = Player[0].X11Set.board.pixmap;
	Window window = Player[0].X11Set.board.window;
	GC     gc     = Player[0].X11Set.diceGC;

	int x, y, r;

	/* center */
	r = dice_width/4;
	x = dice_x + dice_width/2 - r/2;
	y = dice_y + dice_width/2 - r/2;

	XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
	XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);

	/* upper left */
	x = dice_x + dice_width/4 - r/2;
	y = dice_y + dice_width/4 - r/2;

	XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
	XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);

	/* lower right */
	x = dice_x + dice_width - dice_width/4 - r/2;
	y = dice_y + dice_width - dice_width/4 - r/2;

	XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
	XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);

	if (gammon_resource.other_display) {
		dpy    = Player[1].X11Set.dpy;
		pixmap = Player[1].X11Set.board.pixmap;
		window = Player[1].X11Set.board.window;
		gc     = Player[1].X11Set.diceGC;

		/* center */
		x = dice_x + dice_width/2 - r/2;
		y = dice_y + dice_width/2 - r/2;

		XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
		XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);

		/* upper left */
		x = dice_x + dice_width/4 - r/2;
		y = dice_y + dice_width/4 - r/2;

		XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
		XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);

		/* lower right */
		x = dice_x + dice_width - dice_width/4 - r/2;
		y = dice_y + dice_width - dice_width/4 - r/2;

		XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
		XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);
	}
}

void draw_four (int dice_x, int dice_y, int dice_width)
{
	Display *dpy  = Player[0].X11Set.dpy;
	Pixmap pixmap = Player[0].X11Set.board.pixmap;
	Window window = Player[0].X11Set.board.window;
	GC     gc     = Player[0].X11Set.diceGC;

	int x, y, r;

	r = dice_width/4;
	x = dice_x + dice_width/4 - r/4;
	y = dice_y + dice_width/4 - r/4;

	XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
	XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);

	x = dice_x + dice_width/4 - r/4;
	y = dice_y + dice_width - dice_width/4 - r/2;

	XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
	XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);

	x = dice_x + dice_width - dice_width/4 - r/2;
	y = dice_y + dice_width/4 - r/4;

	XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
	XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);

	x = dice_x + dice_width - dice_width/4 - r/2;
	y = dice_y + dice_width - dice_width/4 - r/2;

	XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
	XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);

	if (gammon_resource.other_display) {
		dpy    = Player[1].X11Set.dpy;
		pixmap = Player[1].X11Set.board.pixmap;
		window = Player[1].X11Set.board.window;
		gc     = Player[1].X11Set.diceGC;

		x = dice_x + dice_width/4 - r/4;
		y = dice_y + dice_width/4 - r/4;
               
		XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
		XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);
               
		x = dice_x + dice_width/4 - r/4;
		y = dice_y + dice_width - dice_width/4 - r/2;
               
		XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
		XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);
               
		x = dice_x + dice_width - dice_width/4 - r/2;
		y = dice_y + dice_width/4 - r/4;
               
		XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
		XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);
               
		x = dice_x + dice_width - dice_width/4 - r/2;
		y = dice_y + dice_width - dice_width/4 - r/2;
               
		XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
		XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);
	}
}

void draw_five (int dice_x, int dice_y, int dice_width)
{
	draw_one  (dice_x+2, dice_y+2, dice_width);
	draw_four (dice_x, dice_y, dice_width);
}

void draw_six (int dice_x, int dice_y, int dice_width)
{
	Display *dpy  = Player[0].X11Set.dpy;
	Pixmap pixmap = Player[0].X11Set.board.pixmap;
	Window window = Player[0].X11Set.board.window;
	GC     gc     = Player[0].X11Set.diceGC;

	int r, x, y;

	r = dice_width/4;

	/* left three */
	x = dice_x + dice_width/3 - r/2 - 2;
	y = dice_y + dice_width/4 - r/2;
	XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
	XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);

	y = dice_y + dice_width/2 - r/2;
	XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
	XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);

	y = dice_y  + dice_width - dice_width/4 - r/2;
	XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
	XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);

	/* right three */
	x = dice_x  + dice_width - dice_width/3 - r/2 + 2;
	y = dice_y + dice_width/4 - r/2;
	XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
	XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);

	y = dice_y + dice_width/2 - r/2;
	XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
	XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);

	y = dice_y  + dice_width - dice_width/4 - r/2;
	XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
	XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);

	if (gammon_resource.other_display) {
		dpy    = Player[1].X11Set.dpy;
		pixmap = Player[1].X11Set.board.pixmap;
		window = Player[1].X11Set.board.window;
		gc     = Player[1].X11Set.diceGC;

		r = dice_width/4;
               
		/* left three */
		x = dice_x + dice_width/3 - r/2 - 2;
		y = dice_y + dice_width/4 - r/2;
		XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
		XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);
               
		y = dice_y + dice_width/2 - r/2;
		XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
		XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);
               
		y = dice_y  + dice_width - dice_width/4 - r/2;
		XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
		XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);
               
		/* right three */
		x = dice_x  + dice_width - dice_width/3 - r/2 + 2;
		y = dice_y + dice_width/4 - r/2;
		XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
		XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);
               
		y = dice_y + dice_width/2 - r/2;
		XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
		XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);
               
		y = dice_y  + dice_width - dice_width/4 - r/2;
		XFillArc (dpy, window, gc, x, y, r, r, 0*64, 360*64);
		XFillArc (dpy, pixmap, gc, x, y, r, r, 0*64, 360*64);
	}
}

void PutStone (unsigned int color, unsigned int pin)
{
	Display *dpy  = Player[0].X11Set.dpy;
	Pixmap pixmap = Player[0].X11Set.board.pixmap;
	XPoint p;

	p = PinToPosition  (pin);	/* before adding the stone to the Pin */

	Pin[pin].count++;
	Pin[pin].color = color;

	DrawStone  (p.x, p.y, color);
	/* this is not in DrawStone, DrawStone is for moved stones */
	if (color == BLACK) {
	        XFillArc (dpy, pixmap, Player[0].X11Set.stoneGC[0], p.x, p.y, stone_width,   stone_width,   0, 360*64);
	        XDrawArc (dpy, pixmap, Player[0].X11Set.stoneGC[1], p.x, p.y, stone_width-1, stone_width-1, 0, 360*64);
	        /* DrawArc is somtimes a pixel wider than FillArc, donno why */
        }
	else {
	        XFillArc (dpy, pixmap, Player[0].X11Set.stoneGC[1], p.x, p.y, stone_width,   stone_width,   0, 360*64);
	        XDrawArc (dpy, pixmap, Player[0].X11Set.stoneGC[0], p.x, p.y, stone_width-1, stone_width-1, 0, 360*64);
        }

	if (gammon_resource.other_display) {
	dpy    = Player[1].X11Set.dpy;
	pixmap = Player[1].X11Set.board.pixmap;
	/* this is not in DrawStone, DrawStone is for moved stones */
	if (color == BLACK) {
	        XFillArc (dpy, pixmap, Player[1].X11Set.stoneGC[0], p.x, p.y, stone_width,   stone_width,   0, 360*64);
	        XDrawArc (dpy, pixmap, Player[1].X11Set.stoneGC[1], p.x, p.y, stone_width-1, stone_width-1, 0, 360*64);
	        /* DrawArc is somtimes a pixel wider than FillArc, donno why */
        }
	else {
	        XFillArc (dpy, pixmap, Player[1].X11Set.stoneGC[1], p.x, p.y, stone_width,   stone_width,   0, 360*64);
	        XDrawArc (dpy, pixmap, Player[1].X11Set.stoneGC[0], p.x, p.y, stone_width-1, stone_width-1, 0, 360*64);
        }
	}
}

void DrawStone (int x, int y, int color)
{
	Display *dpy  = Player[0].X11Set.dpy;
	Window window = Player[0].X11Set.board.window;

	if (color == BLACK) {
	        XFillArc (dpy, window, Player[0].X11Set.stoneGC[0], x, y, stone_width,   stone_width,   0, 360*64);
	        XDrawArc (dpy, window, Player[0].X11Set.stoneGC[1], x, y, stone_width-1, stone_width-1, 0, 360*64);
	        /* DrawArc is somtimes a pixel wider than FillArc, donno why */
        } else {
	        XFillArc (dpy, window, Player[0].X11Set.stoneGC[1], x, y, stone_width,   stone_width,   0, 360*64);
	        XDrawArc (dpy, window, Player[0].X11Set.stoneGC[0], x, y, stone_width-1, stone_width-1, 0, 360*64);
        }

	if (gammon_resource.other_display) {
		dpy    = Player[1].X11Set.dpy;
		window = Player[1].X11Set.board.window;
               
		if (color == BLACK) {
		        XFillArc (dpy, window, Player[1].X11Set.stoneGC[0], x, y, stone_width,   stone_width,   0, 360*64);
		        XDrawArc (dpy, window, Player[1].X11Set.stoneGC[1], x, y, stone_width-1, stone_width-1, 0, 360*64);
		        /* DrawArc is somtimes a pixel wider than FillArc, donno why */
                } else {
		        XFillArc (dpy, window, Player[1].X11Set.stoneGC[1], x, y, stone_width,   stone_width,   0, 360*64);
		        XDrawArc (dpy, window, Player[1].X11Set.stoneGC[0], x, y, stone_width-1, stone_width-1, 0, 360*64);
                }
	}
}

void RemoveStone (int pin)
{
	Display *dpy      = Player[0].X11Set.dpy;
	Window window     = Player[0].X11Set.board.window;
	Pixmap pixmap     = Player[0].X11Set.board.pixmap;
	GC     gc         = Player[0].X11Set.board.gc;
	Pixmap pin_pixmap = Player[0].X11Set.board.pin_pixmap[0];

	XPoint p;
	int i, c, copy_start, copy_start_in_pixmap (int pin);
	int pixmap_to_redraw (int pin);


	Pin[pin].count--;
	if (Pin[pin].count == 0) Pin[pin].color = 0;

	if (pin == FINISHED) {				/* for UndoMove() */
		p.x = width - stone_width;
		p.y = (turn == BLACK) ?  height/2 + stone_width : 0;

		XCopyArea (dpy, pin_pixmap, window, gc, 0, 0, stone_width, stone_width*5, p.x, p.y);
		XCopyArea (dpy, pin_pixmap, pixmap, gc, 0, 0, stone_width, stone_width*5, p.x, p.y);

		for (i = Pin[pin].count, Pin[pin].count = 0; i; i--) PutStone (turn, pin);

		return;
	}
		
	p = PinToPosition  (pin);

	c          = pixmap_to_redraw     (pin);
	copy_start = copy_start_in_pixmap (pin);

	pin_pixmap = Player[0].X11Set.board.pin_pixmap[c];

	XCopyArea (dpy, pin_pixmap, window, gc, 0, copy_start, stone_width, stone_width, p.x, p.y);
	XCopyArea (dpy, pin_pixmap, pixmap, gc, 0, copy_start, stone_width, stone_width, p.x, p.y);

	if (gammon_resource.other_display) {
	dpy        = Player[1].X11Set.dpy;
	window     = Player[1].X11Set.board.window;
	pixmap     = Player[1].X11Set.board.pixmap;
	gc         = Player[1].X11Set.board.gc;
	pin_pixmap = Player[1].X11Set.board.pin_pixmap[0];

	if (pin == FINISHED) {				/* for UndoMove() */
		p.x = width - stone_width;
		p.y = (turn == BLACK) ?  height/2 + stone_width : 0;

		XCopyArea (dpy, pin_pixmap, window, gc, 0, 0, stone_width, stone_width*5, p.x, p.y);
		XCopyArea (dpy, pin_pixmap, pixmap, gc, 0, 0, stone_width, stone_width*5, p.x, p.y);

		for (i = Pin[pin].count, Pin[pin].count = 0; i; i--) PutStone (turn, pin);

		return;
	}
		
	p = PinToPosition  (pin);

	copy_start = copy_start_in_pixmap (pin);

	pin_pixmap = Player[1].X11Set.board.pin_pixmap[c];

	XCopyArea (dpy, pin_pixmap, window, gc, 0, copy_start, stone_width, stone_width, p.x, p.y);
	XCopyArea (dpy, pin_pixmap, pixmap, gc, 0, copy_start, stone_width, stone_width, p.x, p.y);
	}
}

int pixmap_to_redraw (int pin)
{
	int layer, turn_color, direct, pin_color;

	if (pin == BAR || pin == OTHER_BAR) {

		if (Pin[pin].count<5) return 32 + 0;

		else if (Pin[pin].count<9)  layer = 1;
		else if (Pin[pin].count<13) layer = 3;
		else			    layer = 5;

		turn_color = (turn == BLACK) ? 0 : 1;

		if (Pin[pin].count>8) direct = (turn == BLACK) ? 0 : 1;
		else		      direct = 0;

		return 32 + layer + turn_color + direct;
	}

	if	(Pin[pin].count<5)  layer = 0;
	else if (Pin[pin].count<9)  layer = 1;
	else if (Pin[pin].count<13) layer = 2;
	else			    layer = 3;

	turn_color = (turn == BLACK) ? 0 : 2;

	pin_color = pin%2;

	direct = (pin <13) ? 0 : 16;

	return direct + pin_color + turn_color + (4 * layer);
}

int copy_start_in_pixmap (int pin)
{
	if (pin<13) {
		if     (Pin[pin].count < 5)  return ( Pin[pin].count       * stone_width);
		else if(Pin[pin].count < 9)  return ((Pin[pin].count - 5)  * stone_width + stone_width/2);
		else if(Pin[pin].count < 13) return ((Pin[pin].count - 9)  * stone_width + stone_width/4);
		else 			     return ((Pin[pin].count - 13) * stone_width + stone_width*3/4);
	}
	else {			/* GRRRHHUUUMMPPFFFNNAAARRGGHHH */
		if     (Pin[pin].count < 5)  return ((4  - Pin[pin].count) * stone_width);
		else if(Pin[pin].count < 9)  return ((8  - Pin[pin].count) * stone_width + stone_width/2);
		else if(Pin[pin].count < 13) return ((13 - Pin[pin].count) * stone_width - stone_width/4);
		else 			     return ((16 - Pin[pin].count) * stone_width - stone_width*3/4);
	}
}

void RedrawAllStones   (void)
{
	int i, c, backup_turn;

	if (turn == BLACK) {
		for (c = Pin[ 0].count, Pin[ 0].count = 0; c; c--)  PutStone  (BLACK, BAR);
		for (c = Pin[25].count, Pin[25].count = 0; c; c--)  PutStone  (WHITE, OTHER_BAR);
	} else { 
		for (c = Pin[ 0].count, Pin[ 0].count = 0; c; c--)  PutStone  (BLACK, OTHER_BAR);
		for (c = Pin[25].count, Pin[25].count = 0; c; c--)  PutStone  (WHITE, BAR);
	}

	for (i=1; i<25; i++) {
		for (c = Pin[i].count, Pin[i].count = 0; c; c--) PutStone  (Pin[i].color, i);
	}
	
	backup_turn = turn;	/* for loading from a file */

	turn = BLACK;		/* for PutStone */
	for (c = Pin[25+BLACK].count, Pin[25+BLACK].count = 0; c; c--) PutStone  (BLACK, 25+BLACK);

	turn = WHITE;
	for (c = Pin[25+WHITE].count, Pin[25+WHITE].count = 0; c; c--) PutStone  (WHITE, 25+WHITE);

	turn = backup_turn;
}

void FreePixmaps()
{
	Display *dpy = Player[0].X11Set.dpy;
	Pixmap  *p = Player[0].X11Set.board.pin_pixmap;
	int i;

	XFreePixmap (dpy, Player[0].X11Set.board.pixmap);
	for (i=0; i<41; i++) XFreePixmap (dpy, Player[0].X11Set.board.pin_pixmap[i]);

	if (gammon_resource.other_display) {
		dpy = Player[1].X11Set.dpy;
		p = Player[1].X11Set.board.pin_pixmap;

		XFreePixmap (dpy, Player[1].X11Set.board.pixmap);
		for (i=0; i<41; i++) XFreePixmap (dpy, p[i]);
	}
}

/* there is a comment in the sources of `xmgt' program:
   "... pixmap hell ..."
   so, here we go 
 */

void CreatePixmaps (int player_index)
{
	Display *dpy           = Player[player_index].X11Set.dpy;
	Window	window         = Player[player_index].X11Set.board.window;
	Pixmap  board_pixmap;
	Pixmap	*pin_pixmap;
	GC	board_gc       = Player[player_index].X11Set.board.gc;

	XPoint  down_p[3], up_p[3];
	int i, j, y;
	unsigned int rect_width, rect_height;
	int screen_depth = DefaultDepth (dpy, DefaultScreen  (dpy));

	Player[player_index].X11Set.board.pixmap  = XCreatePixmap (dpy, window, width, height, screen_depth);
	board_pixmap = Player[player_index].X11Set.board.pixmap;

	rect_width = stone_width;
	rect_height = stone_width * 5;

	down_p[0].x = 1;		/* looks a little more slim */
	down_p[1].x = rect_width - 1;
	down_p[2].x = rect_width/2;
	down_p[0].y = 0;
	down_p[1].y = 0;
	down_p[2].y = rect_height;

	up_p[0].x = rect_width/2;
	up_p[1].x = 1;
	up_p[2].x = rect_width - 1;
	up_p[0].y = 0;
	up_p[1].y = rect_height;
	up_p[2].y = rect_height;



/* for the bar stuff:
   there are layer [0-3] with
      empty = bar_pixmap[0]
      first and second layer are epual for up and down so:
	 p[1],p[2] black,white first layer
	 p[3],p[4] black,white second layer
      for the third layer up and down are different so:
	 p[5],p[6] black,white up layer
	 p[7],p[8] black,white down layer


   for the pins:

   there are UP|DOWN DARK|LIGHT BLACK|WHITE EMPTY|ONE|TWO|THREE layers
	   =   2    *    2     *     2     *       4     = 32 pixmaps
   two of them (empty ones) are equal and so left unused 

   there are 15 stones: 5 in the first layer, 4 in the second and third
   and two in the fourth and last layer, (witch needs no redraw and so
   no pixmap)

   I think this lotta pixmaps are a little a one way street,
   and I should possibly think a little more (but don't)
 */

	for (i=0; i<41; i++) Player[player_index].X11Set.board.pin_pixmap[i] = XCreatePixmap (dpy, window, rect_width, rect_height, screen_depth);
	pin_pixmap = Player[player_index].X11Set.board.pin_pixmap;

	/* now draw the boardcolor inside */
	XSetForeground (dpy, board_gc, gammon_resource.board_Pixel);
	for (i=0; i<32; i++) XFillRectangle (dpy, pin_pixmap[i], board_gc, 0, 0, rect_width, rect_height);

	XSetForeground (dpy, board_gc, gammon_resource.dark_Pixel);
	for (i=0; i<16; i+=2) {				/* UP && DARK */
		XFillPolygon (dpy, pin_pixmap[i], board_gc, down_p, 3, Convex, CoordModeOrigin);
		XDrawLine    (dpy, pin_pixmap[i], Player[player_index].X11Set.gc, down_p[0].x, down_p[0].y, down_p[2].x, down_p[2].y);
		XDrawLine    (dpy, pin_pixmap[i], Player[player_index].X11Set.gc, down_p[1].x, down_p[1].y, down_p[2].x, down_p[2].y);
	}

	for (i=16; i<32; i+=2) {			/* DOWN && DARK */
		XFillPolygon (dpy, pin_pixmap[i], board_gc, up_p, 3, Convex, CoordModeOrigin);
		XDrawLine    (dpy, pin_pixmap[i], Player[player_index].X11Set.gc, up_p[0].x, up_p[0].y, up_p[1].x, up_p[1].y);
		XDrawLine    (dpy, pin_pixmap[i], Player[player_index].X11Set.gc, up_p[0].x, up_p[0].y, up_p[2].x, up_p[2].y);
	}

	XSetForeground (dpy, board_gc, gammon_resource.light_Pixel);
	for (i=1; i<16; i+=2) {				/* UP && LIGHT */
		XFillPolygon (dpy, pin_pixmap[i], board_gc, down_p, 3, Convex, CoordModeOrigin);
		XDrawLine    (dpy, pin_pixmap[i], Player[player_index].X11Set.gc, down_p[0].x, down_p[0].y, down_p[2].x, down_p[2].y);
		XDrawLine    (dpy, pin_pixmap[i], Player[player_index].X11Set.gc, down_p[1].x, down_p[1].y, down_p[2].x, down_p[2].y);
	}

	for (i=17; i<32; i+=2) {			/* DOWN && LIGHT */
		XFillPolygon (dpy, pin_pixmap[i],  board_gc, up_p, 3, Convex, CoordModeOrigin);
		XDrawLine    (dpy, pin_pixmap[i], Player[player_index].X11Set.gc, up_p[0].x, up_p[0].y, up_p[1].x, up_p[1].y);
		XDrawLine    (dpy, pin_pixmap[i], Player[player_index].X11Set.gc, up_p[0].x, up_p[0].y, up_p[2].x, up_p[2].y);
	}

/* now draw the first layer of stones into the pin_pixmaps where necessary */
for (i=4; i<32; i+=4) {
	if (i == 16) i = 20;	/* skip empty ones */
for (j=0; j<5; j++) {
	y = stone_width * j;
	/* black stone on dark pin */
	XFillArc (dpy, pin_pixmap[i], Player[player_index].X11Set.stoneGC[0], 0, y, stone_width,   stone_width,   0, 360*64);
	XDrawArc (dpy, pin_pixmap[i], Player[player_index].X11Set.stoneGC[1], 0, y, stone_width-1, stone_width-1, 0, 360*64);

	/* black stone on light pin */
	XFillArc (dpy, pin_pixmap[i+1], Player[player_index].X11Set.stoneGC[0], 0, y, stone_width,   stone_width,   0, 360*64);
	XDrawArc (dpy, pin_pixmap[i+1], Player[player_index].X11Set.stoneGC[1], 0, y, stone_width-1, stone_width-1, 0, 360*64);

	/* white stone on dark pin */
	XFillArc (dpy, pin_pixmap[i+2], Player[player_index].X11Set.stoneGC[1], 0, y, stone_width,   stone_width,   0, 360*64);
	XDrawArc (dpy, pin_pixmap[i+2], Player[player_index].X11Set.stoneGC[0], 0, y, stone_width-1, stone_width-1, 0, 360*64);

	/* white stone on light pin */
	XFillArc (dpy, pin_pixmap[i+3], Player[player_index].X11Set.stoneGC[1], 0, y, stone_width,   stone_width,   0, 360*64);
	XDrawArc (dpy, pin_pixmap[i+3], Player[player_index].X11Set.stoneGC[0], 0, y, stone_width-1, stone_width-1, 0, 360*64);
	}
	}

/* second layer */
for (i=8; i<32; i+=4) {
	if (i == 16) i = 24;	/* skip empty ones */
	for (j=0; j<4; j++) {
		y = stone_width * j + stone_width/2;
		XFillArc (dpy, pin_pixmap[i], Player[player_index].X11Set.stoneGC[0], 0, y, stone_width,   stone_width,   0, 360*64);
		XDrawArc (dpy, pin_pixmap[i], Player[player_index].X11Set.stoneGC[1], 0, y, stone_width-1, stone_width-1, 0, 360*64);

		XFillArc (dpy, pin_pixmap[i+1], Player[player_index].X11Set.stoneGC[0], 0, y, stone_width,   stone_width,   0, 360*64);
		XDrawArc (dpy, pin_pixmap[i+1], Player[player_index].X11Set.stoneGC[1], 0, y, stone_width-1, stone_width-1, 0, 360*64);

		XFillArc (dpy, pin_pixmap[i+2], Player[player_index].X11Set.stoneGC[1], 0, y, stone_width,   stone_width,   0, 360*64);
		XDrawArc (dpy, pin_pixmap[i+2], Player[player_index].X11Set.stoneGC[0], 0, y, stone_width-1, stone_width-1, 0, 360*64);

		XFillArc (dpy, pin_pixmap[i+3], Player[player_index].X11Set.stoneGC[1], 0, y, stone_width,   stone_width,   0, 360*64);
		XDrawArc (dpy, pin_pixmap[i+3], Player[player_index].X11Set.stoneGC[0], 0, y, stone_width-1, stone_width-1, 0, 360*64);
		}
	}

/* third and last layer */
for (j=0; j<4; j++) {
	y = stone_width * j + stone_width/4;	/* upper half of board */
	XFillArc (dpy, pin_pixmap[12], Player[player_index].X11Set.stoneGC[0], 0, y, stone_width,   stone_width,   0, 360*64);
	XDrawArc (dpy, pin_pixmap[12], Player[player_index].X11Set.stoneGC[1], 0, y, stone_width-1, stone_width-1, 0, 360*64);
	XFillArc (dpy, pin_pixmap[13], Player[player_index].X11Set.stoneGC[0], 0, y, stone_width,   stone_width,   0, 360*64);
	XDrawArc (dpy, pin_pixmap[13], Player[player_index].X11Set.stoneGC[1], 0, y, stone_width-1, stone_width-1, 0, 360*64);
	XFillArc (dpy, pin_pixmap[14], Player[player_index].X11Set.stoneGC[1], 0, y, stone_width,   stone_width,   0, 360*64);
	XDrawArc (dpy, pin_pixmap[14], Player[player_index].X11Set.stoneGC[0], 0, y, stone_width-1, stone_width-1, 0, 360*64);
	XFillArc (dpy, pin_pixmap[15], Player[player_index].X11Set.stoneGC[1], 0, y, stone_width,   stone_width,   0, 360*64);
	XDrawArc (dpy, pin_pixmap[15], Player[player_index].X11Set.stoneGC[0], 0, y, stone_width-1, stone_width-1, 0, 360*64);

	y = stone_width * j + stone_width*3/4;	/* lower half of board */
	XFillArc (dpy, pin_pixmap[28], Player[player_index].X11Set.stoneGC[0], 0, y, stone_width,   stone_width,   0, 360*64);
	XDrawArc (dpy, pin_pixmap[28], Player[player_index].X11Set.stoneGC[1], 0, y, stone_width-1, stone_width-1, 0, 360*64);
	XFillArc (dpy, pin_pixmap[29], Player[player_index].X11Set.stoneGC[0], 0, y, stone_width,   stone_width,   0, 360*64);
	XDrawArc (dpy, pin_pixmap[29], Player[player_index].X11Set.stoneGC[1], 0, y, stone_width-1, stone_width-1, 0, 360*64);
	XFillArc (dpy, pin_pixmap[30], Player[player_index].X11Set.stoneGC[1], 0, y, stone_width,   stone_width,   0, 360*64);
	XDrawArc (dpy, pin_pixmap[30], Player[player_index].X11Set.stoneGC[0], 0, y, stone_width-1, stone_width-1, 0, 360*64);
	XFillArc (dpy, pin_pixmap[31], Player[player_index].X11Set.stoneGC[1], 0, y, stone_width,   stone_width,   0, 360*64);
	XDrawArc (dpy, pin_pixmap[31], Player[player_index].X11Set.stoneGC[0], 0, y, stone_width-1, stone_width-1, 0, 360*64);
}


	/* now the drawing in the bar pin_pixmaps */

	/* the bar background */
	XSetForeground (dpy, board_gc, gammon_resource.bar_Pixel);
	for (i=0; i<9; i++) XFillRectangle(dpy, pin_pixmap[32+i], board_gc, 0, 0, rect_width, rect_height);

	for (i=1; i<9; i+=2) {         /* first layer */
	for (j=0; j<5; j++) {
		y = stone_width * j;
		XFillArc (dpy, pin_pixmap[32+i  ], Player[player_index].X11Set.stoneGC[0], 0, y, stone_width,   stone_width,   0, 360*64);
		XDrawArc (dpy, pin_pixmap[32+i  ], Player[player_index].X11Set.stoneGC[1], 0, y, stone_width-1, stone_width-1, 0, 360*64);

		XFillArc (dpy, pin_pixmap[32+i+1], Player[player_index].X11Set.stoneGC[1], 0, y, stone_width,   stone_width,   0, 360*64);
		XDrawArc (dpy, pin_pixmap[32+i+1], Player[player_index].X11Set.stoneGC[0], 0, y, stone_width-1, stone_width-1, 0, 360*64);
	}}

	for (i=3; i<9; i+=2) {         /* second layer */
	for (j=0; j<4; j++) {
		y = stone_width * j + stone_width/2;
		XFillArc (dpy, pin_pixmap[32+i  ], Player[player_index].X11Set.stoneGC[0], 0, y, stone_width,   stone_width,   0, 360*64);
		XDrawArc (dpy, pin_pixmap[32+i  ], Player[player_index].X11Set.stoneGC[1], 0, y, stone_width-1, stone_width-1, 0, 360*64);

		XFillArc (dpy, pin_pixmap[32+i+1], Player[player_index].X11Set.stoneGC[1], 0, y, stone_width,   stone_width,   0, 360*64);
		XDrawArc (dpy, pin_pixmap[32+i+1], Player[player_index].X11Set.stoneGC[0], 0, y, stone_width-1, stone_width-1, 0, 360*64);
	}}

	for (j=0; j<4; j++) {         /* third layer */
		y = stone_width * j + stone_width/4;
		XFillArc (dpy, pin_pixmap[32+5], Player[player_index].X11Set.stoneGC[0], 0, y, stone_width,   stone_width,   0, 360*64);
		XDrawArc (dpy, pin_pixmap[32+5], Player[player_index].X11Set.stoneGC[1], 0, y, stone_width-1, stone_width-1, 0, 360*64);
		XFillArc (dpy, pin_pixmap[32+6], Player[player_index].X11Set.stoneGC[1], 0, y, stone_width,   stone_width,   0, 360*64);
		XDrawArc (dpy, pin_pixmap[32+7], Player[player_index].X11Set.stoneGC[0], 0, y, stone_width-1, stone_width-1, 0, 360*64);

		y = stone_width * j + stone_width*3/4;
		XFillArc (dpy, pin_pixmap[32+7], Player[player_index].X11Set.stoneGC[0], 0, y, stone_width,   stone_width,   0, 360*64);
		XDrawArc (dpy, pin_pixmap[32+8], Player[player_index].X11Set.stoneGC[1], 0, y, stone_width-1, stone_width-1, 0, 360*64);
		XFillArc (dpy, pin_pixmap[32+8], Player[player_index].X11Set.stoneGC[1], 0, y, stone_width,   stone_width,   0, 360*64);
		XDrawArc (dpy, pin_pixmap[32+8], Player[player_index].X11Set.stoneGC[0], 0, y, stone_width-1, stone_width-1, 0, 360*64);
	}
}
