public synchronized void mouseReleased (MouseEvent e)
	// handle mouse input
	{
		if ( !MouseDown) return;
		int x = e.getX(), y = e.getY();
		MouseDown = false;
		if (ActiveImage == null) return;
		if ( !Active) return;
		getinformation();
		x -= O + OTU;
		y -= O + OTU;
		int i = x / D, j = y / D; // determine position
		if (x < 0 || y < 0 || i < 0 || j < 0 || i >= S || j >= S) return;
		switch (State)
		{
			case 3: // set a black stone
				if (GF.blocked() && Pos.isLastMain()) return;
				if (e.isShiftDown() && e.isControlDown())
					setmousec(i, j, 1);
				else setmouse(i, j, 1);
				break;
			case 4: // set a white stone
				if (GF.blocked() && Pos.isLastMain()) return;
				if (e.isShiftDown() && e.isControlDown())
					setmousec(i, j, -1);
				else setmouse(i, j, -1);
				break;
			case 5:
				mark(i, j);
				break;
			case 6:
				letter(i, j);
				break;
			case 7: // delete a stone
				if (e.isShiftDown() && e.isControlDown())
					deletemousec(i, j);
				else deletemouse(i, j);
				break;
			case 8: // remove a group
				removemouse(i, j);
				break;
			case 9:
				specialmark(i, j);
				break;
			case 10:
				textmark(i, j);
				break;
			case 1:
			case 2: // normal move mode
				if (e.isShiftDown()) // create variation
				{
					if (e.isControlDown())
					{
						if (GF.blocked() && Pos.isLastMain()) return;
						changemove(i, j);
					}
					else variation(i, j);
				}
				else if (e.isControlDown())
				// goto variation
				{
					if (P.tree(i, j) != null)
					{
						gotovariation(i, j);
					}
				}
				else if (e.isMetaDown()) // right click
				{
					if (P.tree(i, j) != null)
					{
						gotovariation(i, j);
					}
					else variation(i, j);
				}
				else
				// place a W or B stone
				{
					if (GF.blocked() && Pos.isLastMain()) return;
					movemouse(i, j);
				}
				break;
		}
		showinformation();
		copy(); // show position
	}