/* Copyright (C) 2000 Damir Zucic */

/*=============================================================================

				control_refresh.c

Purpose:
	Refresh the control window content. This function draws two small
	projections,  showing current positions  of outer slab and fading
	surfaces.

Input:
	(1) Pointer to MolComplexS structure, with macromol. complex.
	(2) Pointer to ConfigS structure, with configuration data.
	(3) Pointer to GUIS structure, with GUI data.
	    
Output:
	(1) Two small projections drawn  to the bottom of control window.
	(2) Return value.

Return value:
	(1) Positive if something useful drawn.
	(2) Zero if there are no atoms.

Notes:
	(1) Default caught complex is  the only complex projected in this
	    function.

	(2) Drawing is done on  a hidden pixmap.  This was not absolutely
	    necessary.

	(3) If nothing is loaded,  or if maximal extent is equal to zero,
	    do nothing!

	(4) Only atoms which are not hidden will be drawn.

========includes:============================================================*/

#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>

#include "defines.h"
#include "typedefs.h"

/*======refresh the control window:==========================================*/

int ControlRefresh_ (MolComplexS *curr_mol_complexSP,
		     ConfigS *configSP, GUIS *guiSP)
{
static double		extra_scale = 0.8;
static int		screen_slab_x0    =  6, screen_slab_y0    = 206;
static int		screen_fading_x0  =  6, screen_fading_y0  = 331;
int			screen_delta_x    = 84, screen_delta_y    =  58,
			screen_center_x   = 42, screen_center_y   =  29;
size_t			atomsN, atomI;
double			max_extent, scale_factor;
AtomS			*curr_atomSP;
double			x0, z0, x, z, front, back;
int			screen_x0, screen_y0, screen_x1;
int			n, half_width;
double			d;
unsigned int		width, height;
size_t			c_alphaI, c_alphaN;
BackboneS		*curr_backboneSP;

/* Prepare and check the number of atoms: */
atomsN = curr_mol_complexSP->atomsN;
if (atomsN == 0)
	{
	XSetForeground (guiSP->displaySP, guiSP->theGCA[0],
			guiSP->black_colorID);
	width  = (unsigned int) screen_delta_x;
	height = (unsigned int) screen_delta_y;
	XFillRectangle (guiSP->displaySP, guiSP->main_hidden_pixmapID,
			guiSP->theGCA[0],
			0, 0, width, height);
	XCopyArea (guiSP->displaySP,
		   guiSP->main_hidden_pixmapID, guiSP->control_winS.ID,
		   guiSP->theGCA[0],
		   1, 1, screen_delta_x - 2, screen_delta_y - 2,
		   screen_slab_x0 + 1, screen_slab_y0 + 1);
	XCopyArea (guiSP->displaySP,
		   guiSP->main_hidden_pixmapID, guiSP->control_winS.ID,
		   guiSP->theGCA[0],
		   1, 1, screen_delta_x - 2, screen_delta_y - 2,
		   screen_fading_x0 + 1, screen_fading_y0 + 1);
	return 0;
	}

/* Prepare and check the maximal extent: */
max_extent = curr_mol_complexSP->max_extent;
if (max_extent == 0.0)
	{
	XSetForeground (guiSP->displaySP, guiSP->theGCA[0],
			guiSP->black_colorID);
	width  = (unsigned int) screen_delta_x;
	height = (unsigned int) screen_delta_y;
	XFillRectangle (guiSP->displaySP, guiSP->main_hidden_pixmapID,
			guiSP->theGCA[0],
			0, 0, width, height);
	XCopyArea (guiSP->displaySP,
		   guiSP->main_hidden_pixmapID, guiSP->control_winS.ID,
		   guiSP->theGCA[0],
		   1, 1, screen_delta_x - 2, screen_delta_y - 2,
		   screen_slab_x0 + 1, screen_slab_y0 + 1);
	XCopyArea (guiSP->displaySP,
		   guiSP->main_hidden_pixmapID, guiSP->control_winS.ID,
		   guiSP->theGCA[0],
		   1, 1, screen_delta_x - 2, screen_delta_y - 2,
		   screen_fading_x0 + 1, screen_fading_y0 + 1);
	return 0;
	}

/* Prepare the scale factor: */
scale_factor = extra_scale * (double) screen_delta_y / max_extent;

/* Atomic coordinates of slab center: */
x0 = curr_mol_complexSP->slab_center_vectorS.x;
z0 = curr_mol_complexSP->slab_center_vectorS.z;

/*------slab:----------------------------------------------------------------*/

/* Refresh part of the main hidden pixmap: */
XSetForeground (guiSP->displaySP, guiSP->theGCA[0], guiSP->black_colorID);
width  = (unsigned int) screen_delta_x;
height = (unsigned int) screen_delta_y;
XFillRectangle (guiSP->displaySP, guiSP->main_hidden_pixmapID,
		guiSP->theGCA[0],
		0, 0, width, height);

/* Prepare two GUI's with different colors: */
XSetForeground (guiSP->displaySP, guiSP->theGCA[0], guiSP->dark_cyan_colorID);
XSetForeground (guiSP->displaySP, guiSP->theGCA[1], guiSP->red_colorID);

/* Draw all atoms which belong to the currently caught macromol. complex: */
for (atomI = 0; atomI < atomsN; atomI ++)
	{
	/* Pointer to the current atom: */
	curr_atomSP = curr_mol_complexSP->atomSP + atomI;

	/* This atom may be hidden: */
	if (curr_atomSP->hiddenF) continue;

	/* Atomic coordinates: */
	x = curr_atomSP->raw_atomS.x[0] - x0;
	z = curr_atomSP->raw_atomS.z[0] - z0;

	/* Screen coordinates (atomic coordinates projected to the screen): */
	screen_x0 = screen_center_x - scale_factor * z;
	screen_y0 = screen_center_y - scale_factor * x;
	
	/* Draw atom: */
	if (curr_atomSP->inside_projected_slabF)	/* red */
		{
		XDrawPoint (guiSP->displaySP,
			    guiSP->main_hidden_pixmapID,
			    guiSP->theGCA[1],
			    screen_x0, screen_y0);

		/* If there fewer than 100 atoms, draw 4 additional pixels: */
		if (atomsN < 100)
			{
			XDrawPoint (guiSP->displaySP,
				    guiSP->main_hidden_pixmapID,
				    guiSP->theGCA[1],
				    screen_x0 - 1, screen_y0);
			XDrawPoint (guiSP->displaySP,
				    guiSP->main_hidden_pixmapID,
				    guiSP->theGCA[1],
				    screen_x0 + 1, screen_y0);
			XDrawPoint (guiSP->displaySP,
				    guiSP->main_hidden_pixmapID,
				    guiSP->theGCA[1],
				    screen_x0, screen_y0 - 1);
			XDrawPoint (guiSP->displaySP,
				    guiSP->main_hidden_pixmapID,
				    guiSP->theGCA[1],
				    screen_x0, screen_y0 + 1);
			}
		}
	else						/* green */
		{
		XDrawPoint (guiSP->displaySP,
			    guiSP->main_hidden_pixmapID,
			    guiSP->theGCA[0],
			    screen_x0, screen_y0);

		/* If there fewer than 100 atoms, draw 4 additional pixels: */
		if (atomsN < 100)
			{
			XDrawPoint (guiSP->displaySP,
				    guiSP->main_hidden_pixmapID,
				    guiSP->theGCA[0],
				    screen_x0 - 1, screen_y0);
			XDrawPoint (guiSP->displaySP,
				    guiSP->main_hidden_pixmapID,
				    guiSP->theGCA[0],
				    screen_x0 + 1, screen_y0);
			XDrawPoint (guiSP->displaySP,
				    guiSP->main_hidden_pixmapID,
				    guiSP->theGCA[0],
				    screen_x0, screen_y0 - 1);
			XDrawPoint (guiSP->displaySP,
				    guiSP->main_hidden_pixmapID,
				    guiSP->theGCA[0],
				    screen_x0, screen_y0 + 1);
			}
		}
	}

/* Draw backbone atoms: */
c_alphaN = curr_mol_complexSP->c_alphaN;
for (c_alphaI = 0; c_alphaI < c_alphaN; c_alphaI++)
	{
	/* Pointer to the current BackboneS structure: */
	curr_backboneSP = curr_mol_complexSP->backboneSP + c_alphaI;
	curr_atomSP = curr_mol_complexSP->atomSP + curr_backboneSP->c_alphaI;

	/* The current backbone element may be hidden: */
	if (curr_backboneSP->hiddenF) continue;

	/* Atomic coordinates: */
	x = curr_atomSP->raw_atomS.x[0] - x0;
	z = curr_atomSP->raw_atomS.z[0] - z0;

	/* Screen coordinates (atomic coordinates projected to the screen): */
	screen_x0 = screen_center_x - scale_factor * z;
	screen_y0 = screen_center_y - scale_factor * x;

	/* Draw atom: */
	if (curr_atomSP->inside_projected_slabF)	/* red */
		{
		XDrawPoint (guiSP->displaySP,
			    guiSP->main_hidden_pixmapID,
			    guiSP->theGCA[1],
			    screen_x0, screen_y0);

		/* If there fewer than 100 atoms, draw 4 additional pixels: */
		if (atomsN < 100)
			{
			XDrawPoint (guiSP->displaySP,
				    guiSP->main_hidden_pixmapID,
				    guiSP->theGCA[1],
				    screen_x0 - 1, screen_y0);
			XDrawPoint (guiSP->displaySP,
				    guiSP->main_hidden_pixmapID,
				    guiSP->theGCA[1],
				    screen_x0 + 1, screen_y0);
			XDrawPoint (guiSP->displaySP,
				    guiSP->main_hidden_pixmapID,
				    guiSP->theGCA[1],
				    screen_x0, screen_y0 - 1);
			XDrawPoint (guiSP->displaySP,
				    guiSP->main_hidden_pixmapID,
				    guiSP->theGCA[1],
				    screen_x0, screen_y0 + 1);
			}
		}
	else						/* green */
		{
		XDrawPoint (guiSP->displaySP,
			    guiSP->main_hidden_pixmapID,
			    guiSP->theGCA[0],
			    screen_x0, screen_y0);

		/* If there fewer than 100 atoms, draw 4 additional pixels: */
		if (atomsN < 100)
			{
			XDrawPoint (guiSP->displaySP,
				    guiSP->main_hidden_pixmapID,
				    guiSP->theGCA[0],
				    screen_x0 - 1, screen_y0);
			XDrawPoint (guiSP->displaySP,
				    guiSP->main_hidden_pixmapID,
				    guiSP->theGCA[0],
				    screen_x0 + 1, screen_y0);
			XDrawPoint (guiSP->displaySP,
				    guiSP->main_hidden_pixmapID,
				    guiSP->theGCA[0],
				    screen_x0, screen_y0 - 1);
			XDrawPoint (guiSP->displaySP,
				    guiSP->main_hidden_pixmapID,
				    guiSP->theGCA[0],
				    screen_x0, screen_y0 + 1);
			}
		}
	}

/* Atomic coordinates of slab surfaces: */
front = curr_mol_complexSP->slab_front_relative_position;
back  = curr_mol_complexSP->slab_back_relative_position;

/* Draw two outermost slab surfaces (but not the area between them): */
XSetForeground (guiSP->displaySP, guiSP->theGCA[2], guiSP->yellow_colorID);
switch (curr_mol_complexSP->slab_modeI)
	{
	/* Fading not used: */
	case 0:
		break;

	/* Planar slab: */
	case 1:
		d = (double) screen_center_x - scale_factor * back;
		screen_x0 = (int) d;
		d = (double) screen_center_x - scale_factor * front;
		screen_x1 = (int) d;
		if (screen_x0 >= screen_x1)
			{
			screen_x0 = screen_x1 - 1;
			}
		if (screen_x0 < 1) screen_x0 = 1;
		if (screen_x1 < 1) screen_x1 = 1;
		n = screen_delta_x - 3;
		if (screen_x1 > n) screen_x1 = n;
		n = screen_x1 - screen_x0 + 1;
		if (n >= 2) width = n;
		else width = 2;
		height = screen_delta_y;
		XDrawRectangle (guiSP->displaySP,
				guiSP->main_hidden_pixmapID,
				guiSP->theGCA[2],
				screen_x0, 0,
				width, height);
		XDrawRectangle (guiSP->displaySP,
				guiSP->main_hidden_pixmapID,
				guiSP->theGCA[2],
				screen_x0 + 1, 0,
				width - 2, height);

		break;

	/* Spherical and cylindrical slab: */
	case 2:
	case 4:
		/* Outer surface (yellow): */
		d = scale_factor * front;
		half_width = (int) d;
		screen_x0 = screen_center_x - half_width;
		if (screen_x0 < 1) screen_x0 = 1;
		screen_x1 = screen_center_x + half_width;
		n = screen_delta_x - 3;
		if (screen_x1 > n)
			{
			half_width = n / 2;
			screen_x0 = screen_center_x - half_width;
			screen_x1 = n;
			}
		screen_y0 = screen_center_y - half_width;
		n = screen_x1 - screen_x0 + 1;
		if (n > 0) width = n;
		else width = 0;
		height = width;
		XDrawArc (guiSP->displaySP,
			  guiSP->main_hidden_pixmapID,
			  guiSP->theGCA[2],
			  screen_x0, screen_y0,
			  width, height,
			  0, 23040);
		XDrawArc (guiSP->displaySP,
			  guiSP->main_hidden_pixmapID,
			  guiSP->theGCA[2],
			  screen_x0 - 1, screen_y0 - 1,
			  width + 2, height + 2,
			  0, 23040);

		/* Inner surface (yellow): */
		d = scale_factor * back;
		half_width = (int) d;
		screen_x0 = screen_center_x - half_width;
		if (screen_x0 < 0) screen_x0 = 0;
		screen_x1 = screen_center_x + half_width;
		n = screen_delta_x - 3;
		if (screen_x1 > n)
			{
			half_width = n / 2;
			screen_x0 = screen_center_x - half_width;
			screen_x1 = n;
			}

		screen_y0 = screen_center_y - half_width;
		n = screen_x1 - screen_x0 + 1;
		if (n > 0) width = n;
		else width = 0;
		height = width;
		XDrawArc (guiSP->displaySP,
			  guiSP->main_hidden_pixmapID,
			  guiSP->theGCA[2],
			  screen_x0, screen_y0,
			  width, height,
			  0, 23040);
		XDrawArc (guiSP->displaySP,
			  guiSP->main_hidden_pixmapID,
			  guiSP->theGCA[2],
			  screen_x0 - 1, screen_y0 - 1,
			  width + 2, height + 2,
			  0, 23040);

		break;

	/* Semi-spherical and semi-cylindrical slab: */
	case 3:
	case 5:
		/* Outer surface (yellow): */
		d = scale_factor * front;
		half_width = (int) d;
		screen_x0 = screen_center_x - half_width;
		if (screen_x0 < 1) screen_x0 = 1;
		screen_x1 = screen_center_x + half_width;
		n = screen_delta_x - 3;
		if (screen_x1 > n)
			{
			half_width = n / 2;
			screen_x0 = screen_center_x - half_width;
			screen_x1 = n;
			}
		screen_y0 = screen_center_y - half_width;
		n = screen_x1 - screen_x0 + 1;
		if (n > 0) width = n;
		else width = 0;
		height = width;
		XDrawArc (guiSP->displaySP,
			  guiSP->main_hidden_pixmapID,
			  guiSP->theGCA[2],
			  screen_x0, screen_y0,
			  width, height,
			  0, 5760);
		XDrawArc (guiSP->displaySP,
			  guiSP->main_hidden_pixmapID,
			  guiSP->theGCA[2],
			  screen_x0 - 1, screen_y0 - 1,
			  width + 2, height + 2,
			  0, 5760);
		XDrawArc (guiSP->displaySP,
			  guiSP->main_hidden_pixmapID,
			  guiSP->theGCA[2],
			  screen_x0, screen_y0,
			  width, height,
			  0, -5760);
		XDrawArc (guiSP->displaySP,
			  guiSP->main_hidden_pixmapID,
			  guiSP->theGCA[2],
			  screen_x0 - 1, screen_y0 - 1,
			  width + 2, height + 2,
			  0, -5760);

		/* Inner surface (yellow): */
		d = scale_factor * back;
		half_width = (int) d;
		screen_x0 = screen_center_x - half_width;
		if (screen_x0 < 1) screen_x0 = 1;
		screen_x1 = screen_center_x + half_width;
		n = screen_delta_x - 3;
		if (screen_x1 > n)
			{
			half_width = n / 2;
			screen_x0 = screen_center_x - half_width;
			screen_x1 = n;
			}

		screen_y0 = screen_center_y - half_width;
		n = screen_x1 - screen_x0 + 1;
		if (n > 0) width = n;
		else width = 0;
		height = width;
		XDrawArc (guiSP->displaySP,
			  guiSP->main_hidden_pixmapID,
			  guiSP->theGCA[2],
			  screen_x0, screen_y0,
			  width, height,
			  0, 5760);
		XDrawArc (guiSP->displaySP,
			  guiSP->main_hidden_pixmapID,
			  guiSP->theGCA[2],
			  screen_x0 - 1, screen_y0 - 1,
			  width + 2, height + 2,
			  0, 5760);
		XDrawArc (guiSP->displaySP,
			  guiSP->main_hidden_pixmapID,
			  guiSP->theGCA[2],
			  screen_x0, screen_y0,
			  width, height,
			  0, -5760);
		XDrawArc (guiSP->displaySP,
			  guiSP->main_hidden_pixmapID,
			  guiSP->theGCA[2],
			  screen_x0 - 1, screen_y0 - 1,
			  width + 2, height + 2,
			  0, -5760);

		/* Two vertical lines (yellow): */
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[2],
			   screen_center_x, 1,
			   screen_center_x, screen_delta_y - 1);
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[2],
			   screen_center_x - 1, 1,
			   screen_center_x - 1, screen_delta_y - 1);

		break;

	/* Unknown slab: */
	default:
		;
	}

/* Copy part of the main hidden pixmap to control window: */
XCopyArea (guiSP->displaySP,
	   guiSP->main_hidden_pixmapID, guiSP->control_winS.ID,
	   guiSP->theGCA[0],
	   1, 1, screen_delta_x - 2, screen_delta_y - 2,
	   screen_slab_x0 + 1, screen_slab_y0 + 1);

/*------fading:--------------------------------------------------------------*/

/* Refresh part of the main hidden pixmap: */
XSetForeground (guiSP->displaySP, guiSP->theGCA[0], guiSP->black_colorID);
width  = screen_delta_x;
height = screen_delta_y;
XFillRectangle (guiSP->displaySP, guiSP->main_hidden_pixmapID,
		guiSP->theGCA[0],
		0, 0, width, height);

/* Prepare GUI: */
XSetForeground (guiSP->displaySP, guiSP->theGCA[1], guiSP->red_colorID);

/* Draw all atoms which belong to the currently caught macromol. complex: */
for (atomI = 0; atomI < atomsN; atomI ++)
	{
	/* Pointer to the current atom: */
	curr_atomSP = curr_mol_complexSP->atomSP + atomI;

	/* This atom may be hidden: */
	if (curr_atomSP->hiddenF) continue;

	/* Atomic coordinates: */
	x = curr_atomSP->raw_atomS.x[0] - x0;
	z = curr_atomSP->raw_atomS.z[0] - z0;

	/* Screen coordinates (atomic coordinates projected to the screen): */
	screen_x0 = screen_center_x - scale_factor * z;
	screen_y0 = screen_center_y - scale_factor * x;
	
	/* Draw atom (a single pixel): */
	XDrawPoint (guiSP->displaySP,
		    guiSP->main_hidden_pixmapID,
		    guiSP->theGCA[1],
		    screen_x0, screen_y0);

	/* If there fewer than 100 atoms, draw 4 additional pixels: */
	if (atomsN < 100)
		{
		XDrawPoint (guiSP->displaySP,
			    guiSP->main_hidden_pixmapID,
			    guiSP->theGCA[1],
			    screen_x0 - 1, screen_y0);
		XDrawPoint (guiSP->displaySP,
			    guiSP->main_hidden_pixmapID,
			    guiSP->theGCA[1],
			    screen_x0 + 1, screen_y0);
		XDrawPoint (guiSP->displaySP,
			    guiSP->main_hidden_pixmapID,
			    guiSP->theGCA[1],
			    screen_x0, screen_y0 - 1);
		XDrawPoint (guiSP->displaySP,
			    guiSP->main_hidden_pixmapID,
			    guiSP->theGCA[1],
			    screen_x0, screen_y0 + 1);
		}
	}

/* Draw backbone atoms: */
c_alphaN = curr_mol_complexSP->c_alphaN;
for (c_alphaI = 0; c_alphaI < c_alphaN; c_alphaI++)
	{
	/* Pointer to the current BackboneS structure: */
	curr_backboneSP = curr_mol_complexSP->backboneSP + c_alphaI;
	curr_atomSP = curr_mol_complexSP->atomSP + curr_backboneSP->c_alphaI;

	/* The current backbone element may be hidden: */
	if (curr_backboneSP->hiddenF) continue;

	/* Atomic coordinates: */
	x = curr_atomSP->raw_atomS.x[0] - x0;
	z = curr_atomSP->raw_atomS.z[0] - z0;

	/* Screen coordinates (atomic coordinates projected to the screen): */
	screen_x0 = screen_center_x - scale_factor * z;
	screen_y0 = screen_center_y - scale_factor * x;

	/* Draw atom (a single pixel): */
	XDrawPoint (guiSP->displaySP,
		    guiSP->main_hidden_pixmapID,
		    guiSP->theGCA[1],
		    screen_x0, screen_y0);

	/* If there fewer than 100 atoms, draw 4 additional pixels: */
	if (atomsN < 100)
		{
		XDrawPoint (guiSP->displaySP,
			    guiSP->main_hidden_pixmapID,
			    guiSP->theGCA[1],
			    screen_x0 - 1, screen_y0);
		XDrawPoint (guiSP->displaySP,
			    guiSP->main_hidden_pixmapID,
			    guiSP->theGCA[1],
			    screen_x0 + 1, screen_y0);
		XDrawPoint (guiSP->displaySP,
			    guiSP->main_hidden_pixmapID,
			    guiSP->theGCA[1],
			    screen_x0, screen_y0 - 1);
		XDrawPoint (guiSP->displaySP,
			    guiSP->main_hidden_pixmapID,
			    guiSP->theGCA[1],
			    screen_x0, screen_y0 + 1);
		}
	}

/* Atomic coordinates of fading surfaces: */
front = curr_mol_complexSP->fading_front_relative_position;
back  = curr_mol_complexSP->fading_back_relative_position;

/* Draw two outermost fading surfaces (but not the area between them): */
XSetForeground (guiSP->displaySP, guiSP->theGCA[2], guiSP->yellow_colorID);
switch (curr_mol_complexSP->fading_modeI)
	{
	/* Fading not used: */
	case 0:
		break;

	/* Planar fading: */
	case 1:
		d = (double) screen_center_x - scale_factor * back;
		screen_x0 = (int) d;
		d = (double) screen_center_x - scale_factor * front;
		screen_x1 = (int) d;
		if (screen_x0 >= screen_x1)
			{
			screen_x0 = screen_x1 - 1;
			}
		if (screen_x0 < 1) screen_x0 = 1;
		if (screen_x1 < 1) screen_x1 = 1;
		n = screen_delta_x - 3;
		if (screen_x1 > n) screen_x1 = n;
		n = screen_x1 - screen_x0 + 1;
		if (n >= 2) width = n;
		else width = 2;
		height = screen_delta_y;
		XDrawRectangle (guiSP->displaySP,
				guiSP->main_hidden_pixmapID,
				guiSP->theGCA[2],
				screen_x0, 0,
				width, height);
		XDrawRectangle (guiSP->displaySP,
				guiSP->main_hidden_pixmapID,
				guiSP->theGCA[2],
				screen_x0 + 1, 0,
				width - 2, height);

		break;

	/* Spherical and cylindrical fading: */
	case 2:
	case 4:
		/* Outer surface (yellow): */
		d = scale_factor * front;
		half_width = (int) d;
		screen_x0 = screen_center_x - half_width;
		if (screen_x0 < 1) screen_x0 = 1;
		screen_x1 = screen_center_x + half_width;
		n = screen_delta_x - 3;
		if (screen_x1 > n)
			{
			half_width = n / 2;
			screen_x0 = screen_center_x - half_width;
			screen_x1 = n;
			}
		screen_y0 = screen_center_y - half_width;
		n = screen_x1 - screen_x0 + 1;
		if (n > 0) width = n;
		else width = 0;
		height = width;
		XDrawArc (guiSP->displaySP,
			  guiSP->main_hidden_pixmapID,
			  guiSP->theGCA[2],
			  screen_x0, screen_y0,
			  width, height,
			  0, 23040);
		XDrawArc (guiSP->displaySP,
			  guiSP->main_hidden_pixmapID,
			  guiSP->theGCA[2],
			  screen_x0 - 1, screen_y0 - 1,
			  width + 2, height + 2,
			  0, 23040);

		/* Inner surface (yellow): */
		d = scale_factor * back;
		half_width = (int) d;
		screen_x0 = screen_center_x - half_width;
		if (screen_x0 < 0) screen_x0 = 0;
		screen_x1 = screen_center_x + half_width;
		n = screen_delta_x - 3;
		if (screen_x1 > n)
			{
			half_width = n / 2;
			screen_x0 = screen_center_x - half_width;
			screen_x1 = n;
			}

		screen_y0 = screen_center_y - half_width;
		n = screen_x1 - screen_x0 + 1;
		if (n > 0) width = n;
		else width = 0;
		height = width;
		XDrawArc (guiSP->displaySP,
			  guiSP->main_hidden_pixmapID,
			  guiSP->theGCA[2],
			  screen_x0, screen_y0,
			  width, height,
			  0, 23040);
		XDrawArc (guiSP->displaySP,
			  guiSP->main_hidden_pixmapID,
			  guiSP->theGCA[2],
			  screen_x0 - 1, screen_y0 - 1,
			  width + 2, height + 2,
			  0, 23040);

		break;

	/* Semi-spherical and semi-cylindrical fading: */
	case 3:
	case 5:
		/* Outer surface (yellow): */
		d = scale_factor * front;
		half_width = (int) d;
		screen_x0 = screen_center_x - half_width;
		if (screen_x0 < 1) screen_x0 = 1;
		screen_x1 = screen_center_x + half_width;
		n = screen_delta_x - 3;
		if (screen_x1 > n)
			{
			half_width = n / 2;
			screen_x0 = screen_center_x - half_width;
			screen_x1 = n;
			}
		screen_y0 = screen_center_y - half_width;
		n = screen_x1 - screen_x0 + 1;
		if (n > 0) width = n;
		else width = 0;
		height = width;
		XDrawArc (guiSP->displaySP,
			  guiSP->main_hidden_pixmapID,
			  guiSP->theGCA[2],
			  screen_x0, screen_y0,
			  width, height,
			  0, 5760);
		XDrawArc (guiSP->displaySP,
			  guiSP->main_hidden_pixmapID,
			  guiSP->theGCA[2],
			  screen_x0 - 1, screen_y0 - 1,
			  width + 2, height + 2,
			  0, 5760);
		XDrawArc (guiSP->displaySP,
			  guiSP->main_hidden_pixmapID,
			  guiSP->theGCA[2],
			  screen_x0, screen_y0,
			  width, height,
			  0, -5760);
		XDrawArc (guiSP->displaySP,
			  guiSP->main_hidden_pixmapID,
			  guiSP->theGCA[2],
			  screen_x0 - 1, screen_y0 - 1,
			  width + 2, height + 2,
			  0, -5760);

		/* Inner surface (yellow): */
		d = scale_factor * back;
		half_width = (int) d;
		screen_x0 = screen_center_x - half_width;
		if (screen_x0 < 1) screen_x0 = 1;
		screen_x1 = screen_center_x + half_width;
		n = screen_delta_x - 3;
		if (screen_x1 > n)
			{
			half_width = n / 2;
			screen_x0 = screen_center_x - half_width;
			screen_x1 = n;
			}

		screen_y0 = screen_center_y - half_width;
		n = screen_x1 - screen_x0 + 1;
		if (n > 0) width = n;
		else width = 0;
		height = width;
		XDrawArc (guiSP->displaySP,
			  guiSP->main_hidden_pixmapID,
			  guiSP->theGCA[2],
			  screen_x0, screen_y0,
			  width, height,
			  0, 5760);
		XDrawArc (guiSP->displaySP,
			  guiSP->main_hidden_pixmapID,
			  guiSP->theGCA[2],
			  screen_x0 - 1, screen_y0 - 1,
			  width + 2, height + 2,
			  0, 5760);
		XDrawArc (guiSP->displaySP,
			  guiSP->main_hidden_pixmapID,
			  guiSP->theGCA[2],
			  screen_x0, screen_y0,
			  width, height,
			  0, -5760);
		XDrawArc (guiSP->displaySP,
			  guiSP->main_hidden_pixmapID,
			  guiSP->theGCA[2],
			  screen_x0 - 1, screen_y0 - 1,
			  width + 2, height + 2,
			  0, -5760);

		/* Two vertical lines (yellow): */
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[2],
			   screen_center_x, 1,
			   screen_center_x, screen_delta_y - 1);
		XDrawLine (guiSP->displaySP,
			   guiSP->main_hidden_pixmapID,
			   guiSP->theGCA[2],
			   screen_center_x - 1, 1,
			   screen_center_x - 1, screen_delta_y - 1);

		break;

	/* Unknown fading: */
	default:
		;
	}

/* Copy part of the main hidden pixmap to control window: */
XCopyArea (guiSP->displaySP,
	   guiSP->main_hidden_pixmapID, guiSP->control_winS.ID,
	   guiSP->theGCA[0],
	   1, 1, screen_delta_x - 2, screen_delta_y - 2,
	   screen_fading_x0 + 1, screen_fading_y0 + 1);

/*---------------------------------------------------------------------------*/

/* Return positive value on success: */
return 1;
}

/*===========================================================================*/


