/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%               DDDD   IIIII  SSSSS  PPPP   L       AAA   Y   Y               %
%               D   D    I    SS     P   P  L      A   A   Y Y                %
%               D   D    I     SSS   PPPP   L      AAAAA    Y                 %
%               D   D    I       SS  P      L      A   A    Y                 %
%               DDDD   IIIII  SSSSS  P      LLLLL  A   A    Y                 %
%                                                                             %
%                                                                             %
%        MagickCore Methods to Interactively Display and Edit an Image        %
%                                                                             %
%                             Software Design                                 %
%                                  Cristy                                     %
%                                July 1992                                    %
%                                                                             %
%                                                                             %
%  Copyright 1999-2021 ImageMagick Studio LLC, a non-profit organization      %
%  dedicated to making software imaging solutions freely available.           %
%                                                                             %
%  You may not use this file except in compliance with the License.  You may  %
%  obtain a copy of the License at                                            %
%                                                                             %
%    https://imagemagick.org/script/license.php                               %
%                                                                             %
%  Unless required by applicable law or agreed to in writing, software        %
%  distributed under the License is distributed on an "AS IS" BASIS,          %
%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
%  See the License for the specific language governing permissions and        %
%  limitations under the License.                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%
*/

/*
  Include declarations.
*/
#include "MagickCore/studio.h"
#include "MagickCore/artifact.h"
#include "MagickCore/attribute.h"
#include "MagickCore/blob.h"
#include "MagickCore/cache.h"
#include "MagickCore/cache-private.h"
#include "MagickCore/channel.h"
#include "MagickCore/client.h"
#include "MagickCore/color.h"
#include "MagickCore/colorspace.h"
#include "MagickCore/composite.h"
#include "MagickCore/constitute.h"
#include "MagickCore/decorate.h"
#include "MagickCore/delegate.h"
#include "MagickCore/display.h"
#include "MagickCore/display-private.h"
#include "MagickCore/distort.h"
#include "MagickCore/draw.h"
#include "MagickCore/effect.h"
#include "MagickCore/enhance.h"
#include "MagickCore/exception.h"
#include "MagickCore/exception-private.h"
#include "MagickCore/fx.h"
#include "MagickCore/geometry.h"
#include "MagickCore/image.h"
#include "MagickCore/image-private.h"
#include "MagickCore/list.h"
#include "MagickCore/log.h"
#include "MagickCore/magick.h"
#include "MagickCore/memory_.h"
#include "MagickCore/monitor.h"
#include "MagickCore/monitor-private.h"
#include "MagickCore/montage.h"
#include "MagickCore/nt-base-private.h"
#include "MagickCore/option.h"
#include "MagickCore/paint.h"
#include "MagickCore/pixel.h"
#include "MagickCore/pixel-accessor.h"
#include "MagickCore/property.h"
#include "MagickCore/quantum.h"
#include "MagickCore/quantum-private.h"
#include "MagickCore/resize.h"
#include "MagickCore/resource_.h"
#include "MagickCore/shear.h"
#include "MagickCore/segment.h"
#include "MagickCore/statistic.h"
#include "MagickCore/string_.h"
#include "MagickCore/string-private.h"
#include "MagickCore/timer-private.h"
#include "MagickCore/transform.h"
#include "MagickCore/transform-private.h"
#include "MagickCore/threshold.h"
#include "MagickCore/utility.h"
#include "MagickCore/utility-private.h"
#include "MagickCore/version.h"
#include "MagickCore/visual-effects.h"
#include "MagickCore/widget.h"
#include "MagickCore/widget-private.h"
#include "MagickCore/xwindow.h"
#include "MagickCore/xwindow-private.h"

#if defined(MAGICKCORE_X11_DELEGATE)
/*
  Define declarations.
*/
#define MaxColors  MagickMin((ssize_t) windows->visual_info->colormap_size,256L)

/*
  Constant declarations.
*/
static const unsigned char
  HighlightBitmap[8] =
  {
    0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55
  },
  OpaqueBitmap[8] =
  {
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
  },
  ShadowBitmap[8] =
  {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  };

/*
  Help widget declarations.
*/
static const char
  ImageAnnotateHelp[] =
  {
    "In annotate mode, the Command widget has these options:\n"
    "\n"
    "    Font Name\n"
    "      fixed\n"
    "      variable\n"
    "      5x8\n"
    "      6x10\n"
    "      7x13bold\n"
    "      8x13bold\n"
    "      9x15bold\n"
    "      10x20\n"
    "      12x24\n"
    "      Browser...\n"
    "    Font Color\n"
    "      black\n"
    "      blue\n"
    "      cyan\n"
    "      green\n"
    "      gray\n"
    "      red\n"
    "      magenta\n"
    "      yellow\n"
    "      white\n"
    "      transparent\n"
    "      Browser...\n"
    "    Font Color\n"
    "      black\n"
    "      blue\n"
    "      cyan\n"
    "      green\n"
    "      gray\n"
    "      red\n"
    "      magenta\n"
    "      yellow\n"
    "      white\n"
    "      transparent\n"
    "      Browser...\n"
    "    Rotate Text\n"
    "      -90\n"
    "      -45\n"
    "      -30\n"
    "      0\n"
    "      30\n"
    "      45\n"
    "      90\n"
    "      180\n"
    "      Dialog...\n"
    "    Help\n"
    "    Dismiss\n"
    "\n"
    "Choose a font name from the Font Name sub-menu.  Additional\n"
    "font names can be specified with the font browser.  You can\n"
    "change the menu names by setting the X resources font1\n"
    "through font9.\n"
    "\n"
    "Choose a font color from the Font Color sub-menu.\n"
    "Additional font colors can be specified with the color\n"
    "browser.  You can change the menu colors by setting the X\n"
    "resources pen1 through pen9.\n"
    "\n"
    "If you select the color browser and press Grab, you can\n"
    "choose the font color by moving the pointer to the desired\n"
    "color on the screen and press any button.\n"
    "\n"
    "If you choose to rotate the text, choose Rotate Text from the\n"
    "menu and select an angle.  Typically you will only want to\n"
    "rotate one line of text at a time.  Depending on the angle you\n"
    "choose, subsequent lines may end up overwriting each other.\n"
    "\n"
    "Choosing a font and its color is optional.  The default font\n"
    "is fixed and the default color is black.  However, you must\n"
    "choose a location to begin entering text and press button 1.\n"
    "An underscore character will appear at the location of the\n"
    "pointer.  The cursor changes to a pencil to indicate you are\n"
    "in text mode.  To exit immediately, press Dismiss.\n"
    "\n"
    "In text mode, any key presses will display the character at\n"
    "the location of the underscore and advance the underscore\n"
    "cursor.  Enter your text and once completed press Apply to\n"
    "finish your image annotation.  To correct errors press BACK\n"
    "SPACE.  To delete an entire line of text, press DELETE.  Any\n"
    "text that exceeds the boundaries of the image window is\n"
    "automagically continued onto the next line.\n"
    "\n"
    "The actual color you request for the font is saved in the\n"
    "image.  However, the color that appears in your image window\n"
    "may be different.  For example, on a monochrome screen the\n"
    "text will appear black or white even if you choose the color\n"
    "red as the font color.  However, the image saved to a file\n"
    "with -write is written with red lettering.  To assure the\n"
    "correct color text in the final image, any PseudoClass image\n"
    "is promoted to DirectClass (see miff(5)).  To force a\n"
    "PseudoClass image to remain PseudoClass, use -colors.\n"
  },
  ImageChopHelp[] =
  {
    "In chop mode, the Command widget has these options:\n"
    "\n"
    "    Direction\n"
    "      horizontal\n"
    "      vertical\n"
    "    Help\n"
    "    Dismiss\n"
    "\n"
    "If the you choose the horizontal direction (this the\n"
    "default), the area of the image between the two horizontal\n"
    "endpoints of the chop line is removed.  Otherwise, the area\n"
    "of the image between the two vertical endpoints of the chop\n"
    "line is removed.\n"
    "\n"
    "Select a location within the image window to begin your chop,\n"
    "press and hold any button.  Next, move the pointer to\n"
    "another location in the image.  As you move a line will\n"
    "connect the initial location and the pointer.  When you\n"
    "release the button, the area within the image to chop is\n"
    "determined by which direction you choose from the Command\n"
    "widget.\n"
    "\n"
    "To cancel the image chopping, move the pointer back to the\n"
    "starting point of the line and release the button.\n"
  },
  ImageColorEditHelp[] =
  {
    "In color edit mode, the Command widget has these options:\n"
    "\n"
    "    Method\n"
    "      point\n"
    "      replace\n"
    "      floodfill\n"
    "      filltoborder\n"
    "      reset\n"
    "    Pixel Color\n"
    "      black\n"
    "      blue\n"
    "      cyan\n"
    "      green\n"
    "      gray\n"
    "      red\n"
    "      magenta\n"
    "      yellow\n"
    "      white\n"
    "      Browser...\n"
    "    Border Color\n"
    "      black\n"
    "      blue\n"
    "      cyan\n"
    "      green\n"
    "      gray\n"
    "      red\n"
    "      magenta\n"
    "      yellow\n"
    "      white\n"
    "      Browser...\n"
    "    Fuzz\n"
    "      0%\n"
    "      2%\n"
    "      5%\n"
    "      10%\n"
    "      15%\n"
    "      Dialog...\n"
    "    Undo\n"
    "    Help\n"
    "    Dismiss\n"
    "\n"
    "Choose a color editing method from the Method sub-menu\n"
    "of the Command widget.  The point method recolors any pixel\n"
    "selected with the pointer until the button is released.  The\n"
    "replace method recolors any pixel that matches the color of\n"
    "the pixel you select with a button press.  Floodfill recolors\n"
    "any pixel that matches the color of the pixel you select with\n"
    "a button press and is a neighbor.  Whereas filltoborder recolors\n"
    "any neighbor pixel that is not the border color.  Finally reset\n"
    "changes the entire image to the designated color.\n"
    "\n"
    "Next, choose a pixel color from the Pixel Color sub-menu.\n"
    "Additional pixel colors can be specified with the color\n"
    "browser.  You can change the menu colors by setting the X\n"
    "resources pen1 through pen9.\n"
    "\n"
    "Now press button 1 to select a pixel within the image window\n"
    "to change its color.  Additional pixels may be recolored as\n"
    "prescribed by the method you choose.\n"
    "\n"
    "If the Magnify widget is mapped, it can be helpful in positioning\n"
    "your pointer within the image (refer to button 2).\n"
    "\n"
    "The actual color you request for the pixels is saved in the\n"
    "image.  However, the color that appears in your image window\n"
    "may be different.  For example, on a monochrome screen the\n"
    "pixel will appear black or white even if you choose the\n"
    "color red as the pixel color.  However, the image saved to a\n"
    "file with -write is written with red pixels.  To assure the\n"
    "correct color text in the final image, any PseudoClass image\n"
    "is promoted to DirectClass (see miff(5)).  To force a\n"
    "PseudoClass image to remain PseudoClass, use -colors.\n"
  },
  ImageCompositeHelp[] =
  {
    "First a widget window is displayed requesting you to enter an\n"
    "image name. Press Composite, Grab or type a file name.\n"
    "Press Cancel if you choose not to create a composite image.\n"
    "When you choose Grab, move the pointer to the desired window\n"
    "and press any button.\n"
    "\n"
    "If the Composite image does not have any matte information,\n"
    "you are informed and the file browser is displayed again.\n"
    "Enter the name of a mask image.  The image is typically\n"
    "grayscale and the same size as the composite image.  If the\n"
    "image is not grayscale, it is converted to grayscale and the\n"
    "resulting intensities are used as matte information.\n"
    "\n"
    "A small window appears showing the location of the cursor in\n"
    "the image window. You are now in composite mode.  To exit\n"
    "immediately, press Dismiss.  In composite mode, the Command\n"
    "widget has these options:\n"
    "\n"
    "    Operators\n"
    "      Over\n"
    "      In\n"
    "      Out\n"
    "      Atop\n"
    "      Xor\n"
    "      Plus\n"
    "      Minus\n"
    "      Add\n"
    "      Subtract\n"
    "      Difference\n"
    "      Multiply\n"
    "      Bumpmap\n"
    "      Copy\n"
    "      CopyRed\n"
    "      CopyGreen\n"
    "      CopyBlue\n"
    "      CopyOpacity\n"
    "      Clear\n"
    "    Dissolve\n"
    "    Displace\n"
    "    Help\n"
    "    Dismiss\n"
    "\n"
    "Choose a composite operation from the Operators sub-menu of\n"
    "the Command widget.  How each operator behaves is described\n"
    "below.  Image window is the image currently displayed on\n"
    "your X server and image is the image obtained with the File\n"
    "Browser widget.\n"
    "\n"
    "Over     The result is the union of the two image shapes,\n"
    "         with image obscuring image window in the region of\n"
    "         overlap.\n"
    "\n"
    "In       The result is simply image cut by the shape of\n"
    "         image window.  None of the image data of image\n"
    "         window is in the result.\n"
    "\n"
    "Out      The resulting image is image with the shape of\n"
    "         image window cut out.\n"
    "\n"
    "Atop     The result is the same shape as image image window,\n"
    "         with image obscuring image window where the image\n"
    "         shapes overlap.  Note this differs from over\n"
    "         because the portion of image outside image window's\n"
    "         shape does not appear in the result.\n"
    "\n"
    "Xor      The result is the image data from both image and\n"
    "         image window that is outside the overlap region.\n"
    "         The overlap region is blank.\n"
    "\n"
    "Plus     The result is just the sum of the image data.\n"
    "         Output values are cropped to QuantumRange (no overflow).\n"
    "\n"
    "Minus    The result of image - image window, with underflow\n"
    "         cropped to zero.\n"
    "\n"
    "Add      The result of image + image window, with overflow\n"
    "         wrapping around (mod 256).\n"
    "\n"
    "Subtract The result of image - image window, with underflow\n"
    "         wrapping around (mod 256).  The add and subtract\n"
    "         operators can be used to perform reversible\n"
    "         transformations.\n"
    "\n"
    "Difference\n"
    "         The result of abs(image - image window).  This\n"
    "         useful for comparing two very similar images.\n"
    "\n"
    "Multiply\n"
    "         The result of image * image window.  This\n"
    "         useful for the creation of drop-shadows.\n"
    "\n"
    "Bumpmap  The result of surface normals from image * image\n"
    "         window.\n"
    "\n"
    "Copy     The resulting image is image window replaced with\n"
    "         image.  Here the matte information is ignored.\n"
    "\n"
    "CopyRed  The red layer of the image window is replace with\n"
    "         the red layer of the image.  The other layers are\n"
    "         untouched.\n"
    "\n"
    "CopyGreen\n"
    "         The green layer of the image window is replace with\n"
    "         the green layer of the image.  The other layers are\n"
    "         untouched.\n"
    "\n"
    "CopyBlue The blue layer of the image window is replace with\n"
    "         the blue layer of the image.  The other layers are\n"
    "         untouched.\n"
    "\n"
    "CopyOpacity\n"
    "         The matte layer of the image window is replace with\n"
    "         the matte layer of the image.  The other layers are\n"
    "         untouched.\n"
    "\n"
    "The image compositor requires a matte, or alpha channel in\n"
    "the image for some operations.  This extra channel usually\n"
    "defines a mask which represents a sort of a cookie-cutter\n"
    "for the image.  This the case when matte is opaque (full\n"
    "coverage) for pixels inside the shape, zero outside, and\n"
    "between 0 and QuantumRange on the boundary.  If image does not\n"
    "have a matte channel, it is initialized with 0 for any pixel\n"
    "matching in color to pixel location (0,0), otherwise QuantumRange.\n"
    "\n"
    "If you choose Dissolve, the composite operator becomes Over.  The\n"
    "image matte channel percent transparency is initialized to factor.\n"
    "The image window is initialized to (100-factor). Where factor is the\n"
    "value you specify in the Dialog widget.\n"
    "\n"
    "Displace shifts the image pixels as defined by a displacement\n"
    "map.  With this option, image is used as a displacement map.\n"
    "Black, within the displacement map, is a maximum positive\n"
    "displacement.  White is a maximum negative displacement and\n"
    "middle gray is neutral.  The displacement is scaled to determine\n"
    "the pixel shift.  By default, the displacement applies in both the\n"
    "horizontal and vertical directions.  However, if you specify a mask,\n"
    "image is the horizontal X displacement and mask the vertical Y\n"
    "displacement.\n"
    "\n"
    "Note that matte information for image window is not retained\n"
    "for colormapped X server visuals (e.g. StaticColor,\n"
    "StaticColor, GrayScale, PseudoColor).  Correct compositing\n"
    "behavior may require a TrueColor or DirectColor visual or a\n"
    "Standard Colormap.\n"
    "\n"
    "Choosing a composite operator is optional.  The default\n"
    "operator is replace.  However, you must choose a location to\n"
    "composite your image and press button 1.  Press and hold the\n"
    "button before releasing and an outline of the image will\n"
    "appear to help you identify your location.\n"
    "\n"
    "The actual colors of the composite image is saved.  However,\n"
    "the color that appears in image window may be different.\n"
    "For example, on a monochrome screen image window will appear\n"
    "black or white even though your composited image may have\n"
    "many colors.  If the image is saved to a file it is written\n"
    "with the correct colors.  To assure the correct colors are\n"
    "saved in the final image, any PseudoClass image is promoted\n"
    "to DirectClass (see miff(5)).  To force a PseudoClass image\n"
    "to remain PseudoClass, use -colors.\n"
  },
  ImageCutHelp[] =
  {
    "In cut mode, the Command widget has these options:\n"
    "\n"
    "    Help\n"
    "    Dismiss\n"
    "\n"
    "To define a cut region, press button 1 and drag.  The\n"
    "cut region is defined by a highlighted rectangle that\n"
    "expands or contracts as it follows the pointer.  Once you\n"
    "are satisfied with the cut region, release the button.\n"
    "You are now in rectify mode.  In rectify mode, the Command\n"
    "widget has these options:\n"
    "\n"
    "    Cut\n"
    "    Help\n"
    "    Dismiss\n"
    "\n"
    "You can make adjustments by moving the pointer to one of the\n"
    "cut rectangle corners, pressing a button, and dragging.\n"
    "Finally, press Cut to commit your copy region.  To\n"
    "exit without cutting the image, press Dismiss.\n"
  },
  ImageCopyHelp[] =
  {
    "In copy mode, the Command widget has these options:\n"
    "\n"
    "    Help\n"
    "    Dismiss\n"
    "\n"
    "To define a copy region, press button 1 and drag.  The\n"
    "copy region is defined by a highlighted rectangle that\n"
    "expands or contracts as it follows the pointer.  Once you\n"
    "are satisfied with the copy region, release the button.\n"
    "You are now in rectify mode.  In rectify mode, the Command\n"
    "widget has these options:\n"
    "\n"
    "    Copy\n"
    "    Help\n"
    "    Dismiss\n"
    "\n"
    "You can make adjustments by moving the pointer to one of the\n"
    "copy rectangle corners, pressing a button, and dragging.\n"
    "Finally, press Copy to commit your copy region.  To\n"
    "exit without copying the image, press Dismiss.\n"
  },
  ImageCropHelp[] =
  {
    "In crop mode, the Command widget has these options:\n"
    "\n"
    "    Help\n"
    "    Dismiss\n"
    "\n"
    "To define a cropping region, press button 1 and drag.  The\n"
    "cropping region is defined by a highlighted rectangle that\n"
    "expands or contracts as it follows the pointer.  Once you\n"
    "are satisfied with the cropping region, release the button.\n"
    "You are now in rectify mode.  In rectify mode, the Command\n"
    "widget has these options:\n"
    "\n"
    "    Crop\n"
    "    Help\n"
    "    Dismiss\n"
    "\n"
    "You can make adjustments by moving the pointer to one of the\n"
    "cropping rectangle corners, pressing a button, and dragging.\n"
    "Finally, press Crop to commit your cropping region.  To\n"
    "exit without cropping the image, press Dismiss.\n"
  },
  ImageDrawHelp[] =
  {
    "The cursor changes to a crosshair to indicate you are in\n"
    "draw mode.  To exit immediately, press Dismiss.  In draw mode,\n"
    "the Command widget has these options:\n"
    "\n"
    "    Element\n"
    "      point\n"
    "      line\n"
    "      rectangle\n"
    "      fill rectangle\n"
    "      circle\n"
    "      fill circle\n"
    "      ellipse\n"
    "      fill ellipse\n"
    "      polygon\n"
    "      fill polygon\n"
    "    Color\n"
    "      black\n"
    "      blue\n"
    "      cyan\n"
    "      green\n"
    "      gray\n"
    "      red\n"
    "      magenta\n"
    "      yellow\n"
    "      white\n"
    "      transparent\n"
    "      Browser...\n"
    "    Stipple\n"
    "      Brick\n"
    "      Diagonal\n"
    "      Scales\n"
    "      Vertical\n"
    "      Wavy\n"
    "      Translucent\n"
    "      Opaque\n"
    "      Open...\n"
    "    Width\n"
    "      1\n"
    "      2\n"
    "      4\n"
    "      8\n"
    "      16\n"
    "      Dialog...\n"
    "    Undo\n"
    "    Help\n"
    "    Dismiss\n"
    "\n"
    "Choose a drawing primitive from the Element sub-menu.\n"
    "\n"
    "Choose a color from the Color sub-menu.  Additional\n"
    "colors can be specified with the color browser.\n"
    "\n"
    "If you choose the color browser and press Grab, you can\n"
    "select the color by moving the pointer to the desired\n"
    "color on the screen and press any button.  The transparent\n"
    "color updates the image matte channel and is useful for\n"
    "image compositing.\n"
    "\n"
    "Choose a stipple, if appropriate, from the Stipple sub-menu.\n"
    "Additional stipples can be specified with the file browser.\n"
    "Stipples obtained from the file browser must be on disk in the\n"
    "X11 bitmap format.\n"
    "\n"
    "Choose a width, if appropriate, from the Width sub-menu.  To\n"
    "choose a specific width select the Dialog widget.\n"
    "\n"
    "Choose a point in the Image window and press button 1 and\n"
    "hold.  Next, move the pointer to another location in the\n"
    "image.  As you move, a line connects the initial location and\n"
    "the pointer.  When you release the button, the image is\n"
    "updated with the primitive you just drew.  For polygons, the\n"
    "image is updated when you press and release the button without\n"
    "moving the pointer.\n"
    "\n"
    "To cancel image drawing, move the pointer back to the\n"
    "starting point of the line and release the button.\n"
  },
  DisplayHelp[] =
  {
    "BUTTONS\n"
    "  The effects of each button press is described below.  Three\n"
    "  buttons are required.  If you have a two button mouse,\n"
    "  button 1 and 3 are returned.  Press ALT and button 3 to\n"
    "  simulate button 2.\n"
    "\n"
    "  1    Press this button to map or unmap the Command widget.\n"
    "\n"
    "  2    Press and drag to define a region of the image to\n"
    "       magnify.\n"
    "\n"
    "  3    Press and drag to choose from a select set of commands.\n"
    "       This button behaves differently if the image being\n"
    "       displayed is a visual image directory.  Here, choose a\n"
    "       particular tile of the directory and press this button and\n"
    "       drag to select a command from a pop-up menu.  Choose from\n"
    "       these menu items:\n"
    "\n"
    "           Open\n"
    "           Next\n"
    "           Former\n"
    "           Delete\n"
    "           Update\n"
    "\n"
    "       If you choose Open, the image represented by the tile is\n"
    "       displayed.  To return to the visual image directory, choose\n"
    "       Next from the Command widget.  Next and Former moves to the\n"
    "       next or former image respectively.  Choose Delete to delete\n"
    "       a particular image tile.  Finally, choose Update to\n"
    "       synchronize all the image tiles with their respective\n"
    "       images.\n"
    "\n"
    "COMMAND WIDGET\n"
    "  The Command widget lists a number of sub-menus and commands.\n"
    "  They are\n"
    "\n"
    "      File\n"
    "        Open...\n"
    "        Next\n"
    "        Former\n"
    "        Select...\n"
    "        Save...\n"
    "        Print...\n"
    "        Delete...\n"
    "        New...\n"
    "        Visual Directory...\n"
    "        Quit\n"
    "      Edit\n"
    "        Undo\n"
    "        Redo\n"
    "        Cut\n"
    "        Copy\n"
    "        Paste\n"
    "      View\n"
    "        Half Size\n"
    "        Original Size\n"
    "        Double Size\n"
    "        Resize...\n"
    "        Apply\n"
    "        Refresh\n"
    "        Restore\n"
    "      Transform\n"
    "        Crop\n"
    "        Chop\n"
    "        Flop\n"
    "        Flip\n"
    "        Rotate Right\n"
    "        Rotate Left\n"
    "        Rotate...\n"
    "        Shear...\n"
    "        Roll...\n"
    "        Trim Edges\n"
    "      Enhance\n"
    "        Brightness...\n"
    "        Saturation...\n"
    "        Hue...\n"
    "        Gamma...\n"
    "        Sharpen...\n"
    "        Dull\n"
    "        Contrast Stretch...\n"
    "        Sigmoidal Contrast...\n"
    "        Normalize\n"
    "        Equalize\n"
    "        Negate\n"
    "        Grayscale\n"
    "        Map...\n"
    "        Quantize...\n"
    "      Effects\n"
    "        Despeckle\n"
    "        Emboss\n"
    "        Reduce Noise\n"
    "        Add Noise\n"
    "        Sharpen...\n"
    "        Blur...\n"
    "        Threshold...\n"
    "        Edge Detect...\n"
    "        Spread...\n"
    "        Shade...\n"
    "        Painting...\n"
    "        Segment...\n"
    "      F/X\n"
    "        Solarize...\n"
    "        Sepia Tone...\n"
    "        Swirl...\n"
    "        Implode...\n"
    "        Vignette...\n"
    "        Wave...\n"
    "        Oil Painting...\n"
    "        Charcoal Drawing...\n"
    "      Image Edit\n"
    "        Annotate...\n"
    "        Draw...\n"
    "        Color...\n"
    "        Matte...\n"
    "        Composite...\n"
    "        Add Border...\n"
    "        Add Frame...\n"
    "        Comment...\n"
    "        Launch...\n"
    "        Region of Interest...\n"
    "      Miscellany\n"
    "        Image Info\n"
    "        Zoom Image\n"
    "        Show Preview...\n"
    "        Show Histogram\n"
    "        Show Matte\n"
    "        Background...\n"
    "        Slide Show\n"
    "        Preferences...\n"
    "      Help\n"
    "        Overview\n"
    "        Browse Documentation\n"
    "        About Display\n"
    "\n"
    "  Menu items with a indented triangle have a sub-menu.  They\n"
    "  are represented above as the indented items.  To access a\n"
    "  sub-menu item, move the pointer to the appropriate menu and\n"
    "  press a button and drag.  When you find the desired sub-menu\n"
    "  item, release the button and the command is executed.  Move\n"
    "  the pointer away from the sub-menu if you decide not to\n"
    "  execute a particular command.\n"
    "\n"
    "KEYBOARD ACCELERATORS\n"
    "  Accelerators are one or two key presses that effect a\n"
    "  particular command.  The keyboard accelerators that\n"
    "  display(1) understands is:\n"
    "\n"
    "  Ctl+O     Press to open an image from a file.\n"
    "\n"
    "  space     Press to display the next image.\n"
    "\n"
    "            If the image is a multi-paged document such as a Postscript\n"
    "            document, you can skip ahead several pages by preceding\n"
    "            this command with a number.  For example to display the\n"
    "            third page beyond the current page, press 3<space>.\n"
    "\n"
    "  backspace Press to display the former image.\n"
    "\n"
    "            If the image is a multi-paged document such as a Postscript\n"
    "            document, you can skip behind several pages by preceding\n"
    "            this command with a number.  For example to display the\n"
    "            third page preceding the current page, press 3<backspace>.\n"
    "\n"
    "  Ctl+S     Press to write the image to a file.\n"
    "\n"
    "  Ctl+P     Press to print the image to a Postscript printer.\n"
    "\n"
    "  Ctl+D     Press to delete an image file.\n"
    "\n"
    "  Ctl+N     Press to create a blank canvas.\n"
    "\n"
    "  Ctl+Q     Press to discard all images and exit program.\n"
    "\n"
    "  Ctl+Z     Press to undo last image transformation.\n"
    "\n"
    "  Ctl+R     Press to redo last image transformation.\n"
    "\n"
    "  Ctl+X     Press to cut a region of the image.\n"
    "\n"
    "  Ctl+C     Press to copy a region of the image.\n"
    "\n"
    "  Ctl+V     Press to paste a region to the image.\n"
    "\n"
    "  <         Press to half the image size.\n"
    "\n"
    "  -         Press to return to the original image size.\n"
    "\n"
    "  >         Press to double the image size.\n"
    "\n"
    "  %         Press to resize the image to a width and height you\n"
    "            specify.\n"
    "\n"
    "Cmd-A       Press to make any image transformations permanent."
    "\n"
    "            By default, any image size transformations are applied\n"
    "            to the original image to create the image displayed on\n"
    "            the X server.  However, the transformations are not\n"
    "            permanent (i.e. the original image does not change\n"
    "            size only the X image does).  For example, if you\n"
    "            press > the X image will appear to double in size,\n"
    "            but the original image will in fact remain the same size.\n"
    "            To force the original image to double in size, press >\n"
    "            followed by Cmd-A.\n"
    "\n"
    "  @         Press to refresh the image window.\n"
    "\n"
    "  C         Press to cut out a rectangular region of the image.\n"
    "\n"
    "  [         Press to chop the image.\n"
    "\n"
    "  H         Press to flop image in the horizontal direction.\n"
    "\n"
    "  V         Press to flip image in the vertical direction.\n"
    "\n"
    "  /         Press to rotate the image 90 degrees clockwise.\n"
    "\n"
    " \\         Press to rotate the image 90 degrees counter-clockwise.\n"
    "\n"
    "  *         Press to rotate the image the number of degrees you\n"
    "            specify.\n"
    "\n"
    "  S         Press to shear the image the number of degrees you\n"
    "            specify.\n"
    "\n"
    "  R         Press to roll the image.\n"
    "\n"
    "  T         Press to trim the image edges.\n"
    "\n"
    "  Shft-H    Press to vary the image hue.\n"
    "\n"
    "  Shft-S    Press to vary the color saturation.\n"
    "\n"
    "  Shft-L    Press to vary the color brightness.\n"
    "\n"
    "  Shft-G    Press to gamma correct the image.\n"
    "\n"
    "  Shft-C    Press to sharpen the image contrast.\n"
    "\n"
    "  Shft-Z    Press to dull the image contrast.\n"
    "\n"
    "  =         Press to perform histogram equalization on the image.\n"
    "\n"
    "  Shft-N    Press to perform histogram normalization on the image.\n"
    "\n"
    "  Shft-~    Press to negate the colors of the image.\n"
    "\n"
    "  .         Press to convert the image colors to gray.\n"
    "\n"
    "  Shft-#    Press to set the maximum number of unique colors in the\n"
    "            image.\n"
    "\n"
    "  F2        Press to reduce the speckles in an image.\n"
    "\n"
    "  F3        Press to eliminate peak noise from an image.\n"
    "\n"
    "  F4        Press to add noise to an image.\n"
    "\n"
    "  F5        Press to sharpen an image.\n"
    "\n"
    "  F6        Press to delete an image file.\n"
    "\n"
    "  F7        Press to threshold the image.\n"
    "\n"
    "  F8        Press to detect edges within an image.\n"
    "\n"
    "  F9        Press to emboss an image.\n"
    "\n"
    "  F10       Press to displace pixels by a random amount.\n"
    "\n"
    "  F11       Press to negate all pixels above the threshold level.\n"
    "\n"
    "  F12       Press to shade the image using a distant light source.\n"
    "\n"
    "  F13       Press to lighten or darken image edges to create a 3-D effect.\n"
    "\n"
    "  F14       Press to segment the image by color.\n"
    "\n"
    "  Meta-S    Press to swirl image pixels about the center.\n"
    "\n"
    "  Meta-I    Press to implode image pixels about the center.\n"
    "\n"
    "  Meta-W    Press to alter an image along a sine wave.\n"
    "\n"
    "  Meta-P    Press to simulate an oil painting.\n"
    "\n"
    "  Meta-C    Press to simulate a charcoal drawing.\n"
    "\n"
    "  Alt-A     Press to annotate the image with text.\n"
    "\n"
    "  Alt-D     Press to draw on an image.\n"
    "\n"
    "  Alt-P     Press to edit an image pixel color.\n"
    "\n"
    "  Alt-M     Press to edit the image matte information.\n"
    "\n"
    "  Alt-V     Press to composite the image with another.\n"
    "\n"
    "  Alt-B     Press to add a border to the image.\n"
    "\n"
    "  Alt-F     Press to add an ornamental border to the image.\n"
    "\n"
    "  Alt-Shft-!\n"
    "            Press to add an image comment.\n"
    "\n"
    "  Ctl-A     Press to apply image processing techniques to a region\n"
    "            of interest.\n"
    "\n"
    "  Shft-?    Press to display information about the image.\n"
    "\n"
    "  Shft-+    Press to map the zoom image window.\n"
    "\n"
    "  Shft-P    Press to preview an image enhancement, effect, or f/x.\n"
    "\n"
    "  F1        Press to display helpful information about display(1).\n"
    "\n"
    "  Find      Press to browse documentation about ImageMagick.\n"
    "\n"
    "  1-9       Press to change the level of magnification.\n"
    "\n"
    "  Use the arrow keys to move the image one pixel up, down,\n"
    "  left, or right within the magnify window.  Be sure to first\n"
    "  map the magnify window by pressing button 2.\n"
    "\n"
    "  Press ALT and one of the arrow keys to trim off one pixel\n"
    "  from any side of the image.\n"
  },
  ImageMatteEditHelp[] =
  {
    "Matte information within an image is useful for some\n"
    "operations such as image compositing (See IMAGE\n"
    "COMPOSITING).  This extra channel usually defines a mask\n"
    "which represents a sort of a cookie-cutter for the image.\n"
    "This the case when matte is opaque (full coverage) for\n"
    "pixels inside the shape, zero outside, and between 0 and\n"
    "QuantumRange on the boundary.\n"
    "\n"
    "A small window appears showing the location of the cursor in\n"
    "the image window. You are now in matte edit mode.  To exit\n"
    "immediately, press Dismiss.  In matte edit mode, the Command\n"
    "widget has these options:\n"
    "\n"
    "    Method\n"
    "      point\n"
    "      replace\n"
    "      floodfill\n"
    "      filltoborder\n"
    "      reset\n"
    "    Border Color\n"
    "      black\n"
    "      blue\n"
    "      cyan\n"
    "      green\n"
    "      gray\n"
    "      red\n"
    "      magenta\n"
    "      yellow\n"
    "      white\n"
    "      Browser...\n"
    "    Fuzz\n"
    "      0%\n"
    "      2%\n"
    "      5%\n"
    "      10%\n"
    "      15%\n"
    "      Dialog...\n"
    "    Matte\n"
    "      Opaque\n"
    "      Transparent\n"
    "      Dialog...\n"
    "    Undo\n"
    "    Help\n"
    "    Dismiss\n"
    "\n"
    "Choose a matte editing method from the Method sub-menu of\n"
    "the Command widget.  The point method changes the matte value\n"
    "of any pixel selected with the pointer until the button is\n"
    "is released.  The replace method changes the matte value of\n"
    "any pixel that matches the color of the pixel you select with\n"
    "a button press.  Floodfill changes the matte value of any pixel\n"
    "that matches the color of the pixel you select with a button\n"
    "press and is a neighbor.  Whereas filltoborder changes the matte\n"
    "value any neighbor pixel that is not the border color.  Finally\n"
    "reset changes the entire image to the designated matte value.\n"
    "\n"
    "Choose Matte Value and pick Opaque or Transarent.  For other values\n"
    "select the Dialog entry.  Here a dialog appears requesting a matte\n"
    "value.  The value you select is assigned as the opacity value of the\n"
    "selected pixel or pixels.\n"
    "\n"
    "Now, press any button to select a pixel within the image\n"
    "window to change its matte value.\n"
    "\n"
    "If the Magnify widget is mapped, it can be helpful in positioning\n"
    "your pointer within the image (refer to button 2).\n"
    "\n"
    "Matte information is only valid in a DirectClass image.\n"
    "Therefore, any PseudoClass image is promoted to DirectClass\n"
    "(see miff(5)).  Note that matte information for PseudoClass\n"
    "is not retained for colormapped X server visuals (e.g.\n"
    "StaticColor, StaticColor, GrayScale, PseudoColor) unless you\n"
    "immediately save your image to a file (refer to Write).\n"
    "Correct matte editing behavior may require a TrueColor or\n"
    "DirectColor visual or a Standard Colormap.\n"
  },
  ImagePanHelp[] =
  {
    "When an image exceeds the width or height of the X server\n"
    "screen, display maps a small panning icon.  The rectangle\n"
    "within the panning icon shows the area that is currently\n"
    "displayed in the image window.  To pan about the image,\n"
    "press any button and drag the pointer within the panning\n"
    "icon.  The pan rectangle moves with the pointer and the\n"
    "image window is updated to reflect the location of the\n"
    "rectangle within the panning icon.  When you have selected\n"
    "the area of the image you wish to view, release the button.\n"
    "\n"
    "Use the arrow keys to pan the image one pixel up, down,\n"
    "left, or right within the image window.\n"
    "\n"
    "The panning icon is withdrawn if the image becomes smaller\n"
    "than the dimensions of the X server screen.\n"
  },
  ImagePasteHelp[] =
  {
    "A small window appears showing the location of the cursor in\n"
    "the image window. You are now in paste mode.  To exit\n"
    "immediately, press Dismiss.  In paste mode, the Command\n"
    "widget has these options:\n"
    "\n"
    "    Operators\n"
    "      over\n"
    "      in\n"
    "      out\n"
    "      atop\n"
    "      xor\n"
    "      plus\n"
    "      minus\n"
    "      add\n"
    "      subtract\n"
    "      difference\n"
    "      replace\n"
    "    Help\n"
    "    Dismiss\n"
    "\n"
    "Choose a composite operation from the Operators sub-menu of\n"
    "the Command widget.  How each operator behaves is described\n"
    "below.  Image window is the image currently displayed on\n"
    "your X server and image is the image obtained with the File\n"
    "Browser widget.\n"
    "\n"
    "Over     The result is the union of the two image shapes,\n"
    "         with image obscuring image window in the region of\n"
    "         overlap.\n"
    "\n"
    "In       The result is simply image cut by the shape of\n"
    "         image window.  None of the image data of image\n"
    "         window is in the result.\n"
    "\n"
    "Out      The resulting image is image with the shape of\n"
    "         image window cut out.\n"
    "\n"
    "Atop     The result is the same shape as image image window,\n"
    "         with image obscuring image window where the image\n"
    "         shapes overlap.  Note this differs from over\n"
    "         because the portion of image outside image window's\n"
    "         shape does not appear in the result.\n"
    "\n"
    "Xor      The result is the image data from both image and\n"
    "         image window that is outside the overlap region.\n"
    "         The overlap region is blank.\n"
    "\n"
    "Plus     The result is just the sum of the image data.\n"
    "         Output values are cropped to QuantumRange (no overflow).\n"
    "         This operation is independent of the matte\n"
    "         channels.\n"
    "\n"
    "Minus    The result of image - image window, with underflow\n"
    "         cropped to zero.\n"
    "\n"
    "Add      The result of image + image window, with overflow\n"
    "         wrapping around (mod 256).\n"
    "\n"
    "Subtract The result of image - image window, with underflow\n"
    "         wrapping around (mod 256).  The add and subtract\n"
    "         operators can be used to perform reversible\n"
    "         transformations.\n"
    "\n"
    "Difference\n"
    "         The result of abs(image - image window).  This\n"
    "         useful for comparing two very similar images.\n"
    "\n"
    "Copy     The resulting image is image window replaced with\n"
    "         image.  Here the matte information is ignored.\n"
    "\n"
    "CopyRed  The red layer of the image window is replace with\n"
    "         the red layer of the image.  The other layers are\n"
    "         untouched.\n"
    "\n"
    "CopyGreen\n"
    "         The green layer of the image window is replace with\n"
    "         the green layer of the image.  The other layers are\n"
    "         untouched.\n"
    "\n"
    "CopyBlue The blue layer of the image window is replace with\n"
    "         the blue layer of the image.  The other layers are\n"
    "         untouched.\n"
    "\n"
    "CopyOpacity\n"
    "         The matte layer of the image window is replace with\n"
    "         the matte layer of the image.  The other layers are\n"
    "         untouched.\n"
    "\n"
    "The image compositor requires a matte, or alpha channel in\n"
    "the image for some operations.  This extra channel usually\n"
    "defines a mask which represents a sort of a cookie-cutter\n"
    "for the image.  This the case when matte is opaque (full\n"
    "coverage) for pixels inside the shape, zero outside, and\n"
    "between 0 and QuantumRange on the boundary.  If image does not\n"
    "have a matte channel, it is initialized with 0 for any pixel\n"
    "matching in color to pixel location (0,0), otherwise QuantumRange.\n"
    "\n"
    "Note that matte information for image window is not retained\n"
    "for colormapped X server visuals (e.g. StaticColor,\n"
    "StaticColor, GrayScale, PseudoColor).  Correct compositing\n"
    "behavior may require a TrueColor or DirectColor visual or a\n"
    "Standard Colormap.\n"
    "\n"
    "Choosing a composite operator is optional.  The default\n"
    "operator is replace.  However, you must choose a location to\n"
    "paste your image and press button 1.  Press and hold the\n"
    "button before releasing and an outline of the image will\n"
    "appear to help you identify your location.\n"
    "\n"
    "The actual colors of the pasted image is saved.  However,\n"
    "the color that appears in image window may be different.\n"
    "For example, on a monochrome screen image window will appear\n"
    "black or white even though your pasted image may have\n"
    "many colors.  If the image is saved to a file it is written\n"
    "with the correct colors.  To assure the correct colors are\n"
    "saved in the final image, any PseudoClass image is promoted\n"
    "to DirectClass (see miff(5)).  To force a PseudoClass image\n"
    "to remain PseudoClass, use -colors.\n"
  },
  ImageROIHelp[] =
  {
    "In region of interest mode, the Command widget has these\n"
    "options:\n"
    "\n"
    "    Help\n"
    "    Dismiss\n"
    "\n"
    "To define a region of interest, press button 1 and drag.\n"
    "The region of interest is defined by a highlighted rectangle\n"
    "that expands or contracts as it follows the pointer.  Once\n"
    "you are satisfied with the region of interest, release the\n"
    "button.  You are now in apply mode.  In apply mode the\n"
    "Command widget has these options:\n"
    "\n"
    "      File\n"
    "        Save...\n"
    "        Print...\n"
    "      Edit\n"
    "        Undo\n"
    "        Redo\n"
    "      Transform\n"
    "        Flop\n"
    "        Flip\n"
    "        Rotate Right\n"
    "        Rotate Left\n"
    "      Enhance\n"
    "        Hue...\n"
    "        Saturation...\n"
    "        Brightness...\n"
    "        Gamma...\n"
    "        Spiff\n"
    "        Dull\n"
    "        Contrast Stretch\n"
    "        Sigmoidal Contrast...\n"
    "        Normalize\n"
    "        Equalize\n"
    "        Negate\n"
    "        Grayscale\n"
    "        Map...\n"
    "        Quantize...\n"
    "      Effects\n"
    "        Despeckle\n"
    "        Emboss\n"
    "        Reduce Noise\n"
    "        Sharpen...\n"
    "        Blur...\n"
    "        Threshold...\n"
    "        Edge Detect...\n"
    "        Spread...\n"
    "        Shade...\n"
    "        Raise...\n"
    "        Segment...\n"
    "      F/X\n"
    "        Solarize...\n"
    "        Sepia Tone...\n"
    "        Swirl...\n"
    "        Implode...\n"
    "        Vignette...\n"
    "        Wave...\n"
    "        Oil Painting...\n"
    "        Charcoal Drawing...\n"
    "      Miscellany\n"
    "        Image Info\n"
    "        Zoom Image\n"
    "        Show Preview...\n"
    "        Show Histogram\n"
    "        Show Matte\n"
    "      Help\n"
    "      Dismiss\n"
    "\n"
    "You can make adjustments to the region of interest by moving\n"
    "the pointer to one of the rectangle corners, pressing a\n"
    "button, and dragging.  Finally, choose an image processing\n"
    "technique from the Command widget.  You can choose more than\n"
    "one image processing technique to apply to an area.\n"
    "Alternatively, you can move the region of interest before\n"
    "applying another image processing technique.  To exit, press\n"
    "Dismiss.\n"
  },
  ImageRotateHelp[] =
  {
    "In rotate mode, the Command widget has these options:\n"
    "\n"
    "    Pixel Color\n"
    "      black\n"
    "      blue\n"
    "      cyan\n"
    "      green\n"
    "      gray\n"
    "      red\n"
    "      magenta\n"
    "      yellow\n"
    "      white\n"
    "      Browser...\n"
    "    Direction\n"
    "      horizontal\n"
    "      vertical\n"
    "    Help\n"
    "    Dismiss\n"
    "\n"
    "Choose a background color from the Pixel Color sub-menu.\n"
    "Additional background colors can be specified with the color\n"
    "browser.  You can change the menu colors by setting the X\n"
    "resources pen1 through pen9.\n"
    "\n"
    "If you choose the color browser and press Grab, you can\n"
    "select the background color by moving the pointer to the\n"
    "desired color on the screen and press any button.\n"
    "\n"
    "Choose a point in the image window and press this button and\n"
    "hold.  Next, move the pointer to another location in the\n"
    "image.  As you move a line connects the initial location and\n"
    "the pointer.  When you release the button, the degree of\n"
    "image rotation is determined by the slope of the line you\n"
    "just drew.  The slope is relative to the direction you\n"
    "choose from the Direction sub-menu of the Command widget.\n"
    "\n"
    "To cancel the image rotation, move the pointer back to the\n"
    "starting point of the line and release the button.\n"
  };

/*
  Enumeration declarations.
*/
typedef enum
{
  CopyMode,
  CropMode,
  CutMode
} ClipboardMode;

typedef enum
{
  OpenCommand,
  NextCommand,
  FormerCommand,
  SelectCommand,
  SaveCommand,
  PrintCommand,
  DeleteCommand,
  NewCommand,
  VisualDirectoryCommand,
  QuitCommand,
  UndoCommand,
  RedoCommand,
  CutCommand,
  CopyCommand,
  PasteCommand,
  HalfSizeCommand,
  OriginalSizeCommand,
  DoubleSizeCommand,
  ResizeCommand,
  ApplyCommand,
  RefreshCommand,
  RestoreCommand,
  CropCommand,
  ChopCommand,
  FlopCommand,
  FlipCommand,
  RotateRightCommand,
  RotateLeftCommand,
  RotateCommand,
  ShearCommand,
  RollCommand,
  TrimCommand,
  HueCommand,
  SaturationCommand,
  BrightnessCommand,
  GammaCommand,
  SpiffCommand,
  DullCommand,
  ContrastStretchCommand,
  SigmoidalContrastCommand,
  NormalizeCommand,
  EqualizeCommand,
  NegateCommand,
  GrayscaleCommand,
  MapCommand,
  QuantizeCommand,
  DespeckleCommand,
  EmbossCommand,
  ReduceNoiseCommand,
  AddNoiseCommand,
  SharpenCommand,
  BlurCommand,
  ThresholdCommand,
  EdgeDetectCommand,
  SpreadCommand,
  ShadeCommand,
  RaiseCommand,
  SegmentCommand,
  SolarizeCommand,
  SepiaToneCommand,
  SwirlCommand,
  ImplodeCommand,
  VignetteCommand,
  WaveCommand,
  OilPaintCommand,
  CharcoalDrawCommand,
  AnnotateCommand,
  DrawCommand,
  ColorCommand,
  MatteCommand,
  CompositeCommand,
  AddBorderCommand,
  AddFrameCommand,
  CommentCommand,
  LaunchCommand,
  RegionofInterestCommand,
  ROIHelpCommand,
  ROIDismissCommand,
  InfoCommand,
  ZoomCommand,
  ShowPreviewCommand,
  ShowHistogramCommand,
  ShowMatteCommand,
  BackgroundCommand,
  SlideShowCommand,
  PreferencesCommand,
  HelpCommand,
  BrowseDocumentationCommand,
  VersionCommand,
  SaveToUndoBufferCommand,
  FreeBuffersCommand,
  NullCommand
} CommandType;

typedef enum
{
  AnnotateNameCommand,
  AnnotateFontColorCommand,
  AnnotateBackgroundColorCommand,
  AnnotateRotateCommand,
  AnnotateHelpCommand,
  AnnotateDismissCommand,
  TextHelpCommand,
  TextApplyCommand,
  ChopDirectionCommand,
  ChopHelpCommand,
  ChopDismissCommand,
  HorizontalChopCommand,
  VerticalChopCommand,
  ColorEditMethodCommand,
  ColorEditColorCommand,
  ColorEditBorderCommand,
  ColorEditFuzzCommand,
  ColorEditUndoCommand,
  ColorEditHelpCommand,
  ColorEditDismissCommand,
  CompositeOperatorsCommand,
  CompositeDissolveCommand,
  CompositeDisplaceCommand,
  CompositeHelpCommand,
  CompositeDismissCommand,
  CropHelpCommand,
  CropDismissCommand,
  RectifyCopyCommand,
  RectifyHelpCommand,
  RectifyDismissCommand,
  DrawElementCommand,
  DrawColorCommand,
  DrawStippleCommand,
  DrawWidthCommand,
  DrawUndoCommand,
  DrawHelpCommand,
  DrawDismissCommand,
  MatteEditMethod,
  MatteEditBorderCommand,
  MatteEditFuzzCommand,
  MatteEditValueCommand,
  MatteEditUndoCommand,
  MatteEditHelpCommand,
  MatteEditDismissCommand,
  PasteOperatorsCommand,
  PasteHelpCommand,
  PasteDismissCommand,
  RotateColorCommand,
  RotateDirectionCommand,
  RotateCropCommand,
  RotateSharpenCommand,
  RotateHelpCommand,
  RotateDismissCommand,
  HorizontalRotateCommand,
  VerticalRotateCommand,
  TileLoadCommand,
  TileNextCommand,
  TileFormerCommand,
  TileDeleteCommand,
  TileUpdateCommand
} ModeType;

/*
  Stipples.
*/
#define BricksWidth  20
#define BricksHeight  20
#define DiagonalWidth  16
#define DiagonalHeight  16
#define HighlightWidth  8
#define HighlightHeight  8
#define OpaqueWidth  8
#define OpaqueHeight  8
#define ScalesWidth  16
#define ScalesHeight  16
#define ShadowWidth  8
#define ShadowHeight  8
#define VerticalWidth  16
#define VerticalHeight  16
#define WavyWidth  16
#define WavyHeight  16

/*
  Constant declaration.
*/
static const int
  RoiDelta = 8;

static const unsigned char
  BricksBitmap[] =
  {
    0xff, 0xff, 0x0f, 0x03, 0x0c, 0x00, 0x03, 0x0c, 0x00, 0x03, 0x0c, 0x00,
    0x03, 0x0c, 0x00, 0xff, 0xff, 0x0f, 0x60, 0x80, 0x01, 0x60, 0x80, 0x01,
    0x60, 0x80, 0x01, 0x60, 0x80, 0x01, 0xff, 0xff, 0x0f, 0x03, 0x0c, 0x00,
    0x03, 0x0c, 0x00, 0x03, 0x0c, 0x00, 0x03, 0x0c, 0x00, 0xff, 0xff, 0x0f,
    0x60, 0x80, 0x01, 0x60, 0x80, 0x01, 0x60, 0x80, 0x01, 0x60, 0x80, 0x01
  },
  DiagonalBitmap[] =
  {
    0x44, 0x44, 0x88, 0x88, 0x11, 0x11, 0x22, 0x22, 0x44, 0x44, 0x88, 0x88,
    0x11, 0x11, 0x22, 0x22, 0x44, 0x44, 0x88, 0x88, 0x11, 0x11, 0x22, 0x22,
    0x44, 0x44, 0x88, 0x88, 0x11, 0x11, 0x22, 0x22
  },
  ScalesBitmap[] =
  {
    0x08, 0x08, 0x08, 0x08, 0x14, 0x14, 0xe3, 0xe3, 0x80, 0x80, 0x80, 0x80,
    0x41, 0x41, 0x3e, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x14, 0x14, 0xe3, 0xe3,
    0x80, 0x80, 0x80, 0x80, 0x41, 0x41, 0x3e, 0x3e
  },
  VerticalBitmap[] =
  {
    0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
    0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
    0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11
  },
  WavyBitmap[] =
  {
    0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfb, 0xff,
    0xe7, 0xff, 0x1f, 0xff, 0xff, 0xf8, 0xff, 0xe7, 0xff, 0xdf, 0xff, 0xbf,
    0xff, 0xbf, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f
  };

/*
  Function prototypes.
*/
static CommandType
  XImageWindowCommand(Display *,XResourceInfo *,XWindows *,
    const MagickStatusType,KeySym,Image **,ExceptionInfo *);

static Image
  *XMagickCommand(Display *,XResourceInfo *,XWindows *,const CommandType,
    Image **,ExceptionInfo *),
  *XOpenImage(Display *,XResourceInfo *,XWindows *,const MagickBooleanType),
  *XTileImage(Display *,XResourceInfo *,XWindows *,Image *,XEvent *,
    ExceptionInfo *),
  *XVisualDirectoryImage(Display *,XResourceInfo *,XWindows *,
    ExceptionInfo *);

static MagickBooleanType
  XAnnotateEditImage(Display *,XResourceInfo *,XWindows *,Image *,
    ExceptionInfo *),
  XBackgroundImage(Display *,XResourceInfo *,XWindows *,Image **,
    ExceptionInfo *),
  XChopImage(Display *,XResourceInfo *,XWindows *,Image **,
    ExceptionInfo *),
  XCropImage(Display *,XResourceInfo *,XWindows *,Image *,const ClipboardMode,
    ExceptionInfo *),
  XColorEditImage(Display *,XResourceInfo *,XWindows *,Image **,
    ExceptionInfo *),
  XCompositeImage(Display *,XResourceInfo *,XWindows *,Image *,
    ExceptionInfo *),
  XConfigureImage(Display *,XResourceInfo *,XWindows *,Image *,ExceptionInfo *),
  XDrawEditImage(Display *,XResourceInfo *,XWindows *,Image **,
    ExceptionInfo *),
  XMatteEditImage(Display *,XResourceInfo *,XWindows *,Image **,
    ExceptionInfo *),
  XPasteImage(Display *,XResourceInfo *,XWindows *,Image *,ExceptionInfo *),
  XPrintImage(Display *,XResourceInfo *,XWindows *,Image *,ExceptionInfo *),
  XRotateImage(Display *,XResourceInfo *,XWindows *,double,Image **,
    ExceptionInfo *),
  XROIImage(Display *,XResourceInfo *,XWindows *,Image **,ExceptionInfo *),
  XSaveImage(Display *,XResourceInfo *,XWindows *,Image *,ExceptionInfo *),
  XTrimImage(Display *,XResourceInfo *,XWindows *,Image *,ExceptionInfo *);

static void
  XDrawPanRectangle(Display *,XWindows *),
  XImageCache(Display *,XResourceInfo *,XWindows *,const CommandType,Image **,
    ExceptionInfo *),
  XMagnifyImage(Display *,XWindows *,XEvent *,ExceptionInfo *),
  XMakePanImage(Display *,XResourceInfo *,XWindows *,Image *,ExceptionInfo *),
  XPanImage(Display *,XWindows *,XEvent *,ExceptionInfo *),
  XMagnifyWindowCommand(Display *,XWindows *,const MagickStatusType,
    const KeySym,ExceptionInfo *),
  XSetCropGeometry(Display *,XWindows *,RectangleInfo *,Image *),
  XScreenEvent(Display *,XWindows *,XEvent *,ExceptionInfo *),
  XTranslateImage(Display *,XWindows *,Image *,const KeySym);

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   D i s p l a y I m a g e s                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  DisplayImages() displays an image sequence to any X window screen.  It
%  returns a value other than 0 if successful.  Check the exception member
%  of image to determine the reason for any failure.
%
%  The format of the DisplayImages method is:
%
%      MagickBooleanType DisplayImages(const ImageInfo *image_info,
%        Image *images,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image_info: the image info.
%
%    o image: the image.
%
%    o exception: return any errors or warnings in this structure.
%
*/
MagickExport MagickBooleanType DisplayImages(const ImageInfo *image_info,
  Image *images,ExceptionInfo *exception)
{
  char
    *argv[1];

  Display
    *display;

  Image
    *image;

  ssize_t
    i;

  size_t
    state;

  XrmDatabase
    resource_database;

  XResourceInfo
    resource_info;

  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickCoreSignature);
  assert(images != (Image *) NULL);
  assert(images->signature == MagickCoreSignature);
  if (images->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
  display=XOpenDisplay(image_info->server_name);
  if (display == (Display *) NULL)
    {
      (void) ThrowMagickException(exception,GetMagickModule(),XServerError,
        "UnableToOpenXServer","`%s'",XDisplayName(image_info->server_name));
      return(MagickFalse);
    }
  if (exception->severity != UndefinedException)
    CatchException(exception);
  (void) XSetErrorHandler(XError);
  resource_database=XGetResourceDatabase(display,GetClientName());
  (void) memset(&resource_info,0,sizeof(resource_info));
  XGetResourceInfo(image_info,resource_database,GetClientName(),&resource_info);
  if (image_info->page != (char *) NULL)
    resource_info.image_geometry=AcquireString(image_info->page);
  resource_info.immutable=MagickTrue;
  argv[0]=AcquireString(GetClientName());
  state=DefaultState;
  for (i=0; (state & ExitState) == 0; i++)
  {
    if ((images->iterations != 0) && (i >= (ssize_t) images->iterations))
      break;
    image=GetImageFromList(images,i % GetImageListLength(images));
    (void) XDisplayImage(display,&resource_info,argv,1,&image,&state,exception);
  }
  (void) SetErrorHandler((ErrorHandler) NULL);
  (void) SetWarningHandler((WarningHandler) NULL);
  argv[0]=DestroyString(argv[0]);
  (void) XCloseDisplay(display);
  XDestroyResourceInfo(&resource_info);
  if (exception->severity != UndefinedException)
    return(MagickFalse);
  return(MagickTrue);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e m o t e D i s p l a y C o m m a n d                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  RemoteDisplayCommand() encourages a remote display program to display the
%  specified image filename.
%
%  The format of the RemoteDisplayCommand method is:
%
%      MagickBooleanType RemoteDisplayCommand(const ImageInfo *image_info,
%        const char *window,const char *filename,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image_info: the image info.
%
%    o window: Specifies the name or id of an X window.
%
%    o filename: the name of the image filename to display.
%
%    o exception: return any errors or warnings in this structure.
%
*/
MagickExport MagickBooleanType RemoteDisplayCommand(const ImageInfo *image_info,
  const char *window,const char *filename,ExceptionInfo *exception)
{
  Display
    *display;

  MagickStatusType
    status;

  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickCoreSignature);
  assert(filename != (char *) NULL);
  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
  display=XOpenDisplay(image_info->server_name);
  if (display == (Display *) NULL)
    {
      (void) ThrowMagickException(exception,GetMagickModule(),XServerError,
        "UnableToOpenXServer","`%s'",XDisplayName(image_info->server_name));
      return(MagickFalse);
    }
  (void) XSetErrorHandler(XError);
  status=XRemoteCommand(display,window,filename);
  (void) XCloseDisplay(display);
  return(status != 0 ? MagickTrue : MagickFalse);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X A n n o t a t e E d i t I m a g e                                       %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XAnnotateEditImage() annotates the image with text.
%
%  The format of the XAnnotateEditImage method is:
%
%      MagickBooleanType XAnnotateEditImage(Display *display,
%        XResourceInfo *resource_info,XWindows *windows,Image *image,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o display: Specifies a connection to an X server;  returned from
%      XOpenDisplay.
%
%    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
%
%    o windows: Specifies a pointer to a XWindows structure.
%
%    o image: the image; returned from ReadImage.
%
*/

static MagickBooleanType XAnnotateEditImage(Display *display,
  XResourceInfo *resource_info,XWindows *windows,Image *image,
  ExceptionInfo *exception)
{
  const char
    *const AnnotateMenu[] =
    {
      "Font Name",
      "Font Color",
      "Box Color",
      "Rotate Text",
      "Help",
      "Dismiss",
      (char *) NULL
    },
    *const TextMenu[] =
    {
      "Help",
      "Apply",
      (char *) NULL
    };

  static const ModeType
    AnnotateCommands[] =
    {
      AnnotateNameCommand,
      AnnotateFontColorCommand,
      AnnotateBackgroundColorCommand,
      AnnotateRotateCommand,
      AnnotateHelpCommand,
      AnnotateDismissCommand
    },
    TextCommands[] =
    {
      TextHelpCommand,
      TextApplyCommand
    };

  static MagickBooleanType
    transparent_box = MagickTrue,
    transparent_pen = MagickFalse;

  static double
    degrees = 0.0;

  static unsigned int
    box_id = MaxNumberPens-2,
    font_id = 0,
    pen_id = 0;

  char
    command[MagickPathExtent],
    text[MagickPathExtent];

  const char
    *ColorMenu[MaxNumberPens+1];

  Cursor
    cursor;

  GC
    annotate_context;

  int
    id,
    pen_number,
    status,
    x,
    y;

  KeySym
    key_symbol;

  char
    *p;

  ssize_t
    i;

  unsigned int
    height,
    width;

  size_t
    state;

  XAnnotateInfo
    *annotate_info,
    *previous_info;

  XColor
    color;

  XFontStruct
    *font_info;

  XEvent
    event,
    text_event;

  /*
    Map Command widget.
  */
  (void) CloneString(&windows->command.name,"Annotate");
  windows->command.data=4;
  (void) XCommandWidget(display,windows,AnnotateMenu,(XEvent *) NULL);
  (void) XMapRaised(display,windows->command.id);
  XClientMessage(display,windows->image.id,windows->im_protocols,
    windows->im_update_widget,CurrentTime);
  /*
    Track pointer until button 1 is pressed.
  */
  XQueryPosition(display,windows->image.id,&x,&y);
  (void) XSelectInput(display,windows->image.id,
    windows->image.attributes.event_mask | PointerMotionMask);
  cursor=XCreateFontCursor(display,XC_left_side);
  (void) XCheckDefineCursor(display,windows->image.id,cursor);
  state=DefaultState;
  do
  {
    if (windows->info.mapped != MagickFalse)
      {
        /*
          Display pointer position.
        */
        (void) FormatLocaleString(text,MagickPathExtent," %+d%+d ",
          x+windows->image.x,y+windows->image.y);
        XInfoWidget(display,windows,text);
      }
    /*
      Wait for next event.
    */
    XScreenEvent(display,windows,&event,exception);
    if (event.xany.window == windows->command.id)
      {
        /*
          Select a command from the Command widget.
        */
        id=XCommandWidget(display,windows,AnnotateMenu,&event);
        (void) XCheckDefineCursor(display,windows->image.id,cursor);
        if (id < 0)
          continue;
        switch (AnnotateCommands[id])
        {
          case AnnotateNameCommand:
          {
            const char
              *FontMenu[MaxNumberFonts];

            int
              font_number;

            /*
              Initialize menu selections.
            */
            for (i=0; i < MaxNumberFonts; i++)
              FontMenu[i]=resource_info->font_name[i];
            FontMenu[MaxNumberFonts-2]="Browser...";
            FontMenu[MaxNumberFonts-1]=(const char *) NULL;
            /*
              Select a font name from the pop-up menu.
            */
            font_number=XMenuWidget(display,windows,AnnotateMenu[id],
              (const char **) FontMenu,command);
            if (font_number < 0)
              break;
            if (font_number == (MaxNumberFonts-2))
              {
                static char
                  font_name[MagickPathExtent] = "fixed";

                /*
                  Select a font name from a browser.
                */
                resource_info->font_name[font_number]=font_name;
                XFontBrowserWidget(display,windows,"Select",font_name);
                if (*font_name == '\0')
                  break;
              }
            /*
              Initialize font info.
            */
            font_info=XLoadQueryFont(display,resource_info->font_name[
              font_number]);
            if (font_info == (XFontStruct *) NULL)
              {
                XNoticeWidget(display,windows,"Unable to load font:",
                  resource_info->font_name[font_number]);
                break;
              }
            font_id=(unsigned int) font_number;
            (void) XFreeFont(display,font_info);
            break;
          }
          case AnnotateFontColorCommand:
          {
            /*
              Initialize menu selections.
            */
            for (i=0; i < (int) (MaxNumberPens-2); i++)
              ColorMenu[i]=resource_info->pen_colors[i];
            ColorMenu[MaxNumberPens-2]="transparent";
            ColorMenu[MaxNumberPens-1]="Browser...";
            ColorMenu[MaxNumberPens]=(const char *) NULL;
            /*
              Select a pen color from the pop-up menu.
            */
            pen_number=XMenuWidget(display,windows,AnnotateMenu[id],
              (const char **) ColorMenu,command);
            if (pen_number < 0)
              break;
            transparent_pen=pen_number == (MaxNumberPens-2) ? MagickTrue :
              MagickFalse;
            if (transparent_pen != MagickFalse)
              break;
            if (pen_number == (MaxNumberPens-1))
              {
                static char
                  color_name[MagickPathExtent] = "gray";

                /*
                  Select a pen color from a dialog.
                */
                resource_info->pen_colors[pen_number]=color_name;
                XColorBrowserWidget(display,windows,"Select",color_name);
                if (*color_name == '\0')
                  break;
              }
            /*
              Set pen color.
            */
            (void) XParseColor(display,windows->map_info->colormap,
              resource_info->pen_colors[pen_number],&color);
            XBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
              (unsigned int) MaxColors,&color);
            windows->pixel_info->pen_colors[pen_number]=color;
            pen_id=(unsigned int) pen_number;
            break;
          }
          case AnnotateBackgroundColorCommand:
          {
            /*
              Initialize menu selections.
            */
            for (i=0; i < (int) (MaxNumberPens-2); i++)
              ColorMenu[i]=resource_info->pen_colors[i];
            ColorMenu[MaxNumberPens-2]="transparent";
            ColorMenu[MaxNumberPens-1]="Browser...";
            ColorMenu[MaxNumberPens]=(const char *) NULL;
            /*
              Select a pen color from the pop-up menu.
            */
            pen_number=XMenuWidget(display,windows,AnnotateMenu[id],
              (const char **) ColorMenu,command);
            if (pen_number < 0)
              break;
            transparent_box=pen_number == (MaxNumberPens-2) ? MagickTrue :
              MagickFalse;
            if (transparent_box != MagickFalse)
              break;
            if (pen_number == (MaxNumberPens-1))
              {
                static char
                  color_name[MagickPathExtent] = "gray";

                /*
                  Select a pen color from a dialog.
                */
                resource_info->pen_colors[pen_number]=color_name;
                XColorBrowserWidget(display,windows,"Select",color_name);
                if (*color_name == '\0')
                  break;
              }
            /*
              Set pen color.
            */
            (void) XParseColor(display,windows->map_info->colormap,
              resource_info->pen_colors[pen_number],&color);
            XBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
              (unsigned int) MaxColors,&color);
            windows->pixel_info->pen_colors[pen_number]=color;
            box_id=(unsigned int) pen_number;
            break;
          }
          case AnnotateRotateCommand:
          {
            int
              entry;

            const char
              *const RotateMenu[] =
              {
                "-90",
                "-45",
                "-30",
                "0",
                "30",
                "45",
                "90",
                "180",
                "Dialog...",
                (char *) NULL,
              };

            static char
              angle[MagickPathExtent] = "30.0";

            /*
              Select a command from the pop-up menu.
            */
            entry=XMenuWidget(display,windows,AnnotateMenu[id],RotateMenu,
              command);
            if (entry < 0)
              break;
            if (entry != 8)
              {
                degrees=StringToDouble(RotateMenu[entry],(char **) NULL);
                break;
              }
            (void) XDialogWidget(display,windows,"OK","Enter rotation angle:",
              angle);
            if (*angle == '\0')
              break;
            degrees=StringToDouble(angle,(char **) NULL);
            break;
          }
          case AnnotateHelpCommand:
          {
            XTextViewHelp(display,resource_info,windows,MagickFalse,
              "Help Viewer - Image Annotation",ImageAnnotateHelp);
            break;
          }
          case AnnotateDismissCommand:
          {
            /*
              Prematurely exit.
            */
            state|=EscapeState;
            state|=ExitState;
            break;
          }
          default:
            break;
        }
        continue;
      }
    switch (event.type)
    {
      case ButtonPress:
      {
        if (event.xbutton.button != Button1)
          break;
        if (event.xbutton.window != windows->image.id)
          break;
        /*
          Change to text entering mode.
        */
        x=event.xbutton.x;
        y=event.xbutton.y;
        state|=ExitState;
        break;
      }
      case ButtonRelease:
        break;
      case Expose:
        break;
      case KeyPress:
      {
        if (event.xkey.window != windows->image.id)
          break;
        /*
          Respond to a user key press.
        */
        (void) XLookupString((XKeyEvent *) &event.xkey,command,(int)
          sizeof(command),&key_symbol,(XComposeStatus *) NULL);
        switch ((int) key_symbol)
        {
          case XK_Escape:
          case XK_F20:
          {
            /*
              Prematurely exit.
            */
            state|=EscapeState;
            state|=ExitState;
            break;
          }
          case XK_F1:
          case XK_Help:
          {
            XTextViewHelp(display,resource_info,windows,MagickFalse,
              "Help Viewer - Image Annotation",ImageAnnotateHelp);
            break;
          }
          default:
          {
            (void) XBell(display,0);
            break;
          }
        }
        break;
      }
      case MotionNotify:
      {
        /*
          Map and unmap Info widget as cursor crosses its boundaries.
        */
        x=event.xmotion.x;
        y=event.xmotion.y;
        if (windows->info.mapped != MagickFalse)
          {
            if ((x < (int) (windows->info.x+windows->info.width)) &&
                (y < (int) (windows->info.y+windows->info.height)))
              (void) XWithdrawWindow(display,windows->info.id,
                windows->info.screen);
          }
        else
          if ((x > (int) (windows->info.x+windows->info.width)) ||
              (y > (int) (windows->info.y+windows->info.height)))
            (void) XMapWindow(display,windows->info.id);
        break;
      }
      default:
        break;
    }
  } while ((state & ExitState) == 0);
  (void) XSelectInput(display,windows->image.id,
    windows->image.attributes.event_mask);
  (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
  if ((state & EscapeState) != 0)
    return(MagickTrue);
  /*
    Set font info and check boundary conditions.
  */
  font_info=XLoadQueryFont(display,resource_info->font_name[font_id]);
  if (font_info == (XFontStruct *) NULL)
    {
      XNoticeWidget(display,windows,"Unable to load font:",
        resource_info->font_name[font_id]);
      font_info=windows->font_info;
    }
  if ((x+font_info->max_bounds.width) >= (int) windows->image.width)
    x=(int) windows->image.width-font_info->max_bounds.width;
  if (y < (int) (font_info->ascent+font_info->descent))
    y=(int) font_info->ascent+font_info->descent;
  if (((int) font_info->max_bounds.width > (int) windows->image.width) ||
      ((font_info->ascent+font_info->descent) >= (int) windows->image.height))
    return(MagickFalse);
  /*
    Initialize annotate structure.
  */
  annotate_info=(XAnnotateInfo *) AcquireMagickMemory(sizeof(*annotate_info));
  if (annotate_info == (XAnnotateInfo *) NULL)
    return(MagickFalse);
  XGetAnnotateInfo(annotate_info);
  annotate_info->x=x;
  annotate_info->y=y;
  if ((transparent_box == MagickFalse) && (transparent_pen == MagickFalse))
    annotate_info->stencil=OpaqueStencil;
  else
    if (transparent_box == MagickFalse)
      annotate_info->stencil=BackgroundStencil;
    else
      annotate_info->stencil=ForegroundStencil;
  annotate_info->height=(unsigned int) font_info->ascent+font_info->descent;
  annotate_info->degrees=degrees;
  annotate_info->font_info=font_info;
  annotate_info->text=(char *) AcquireQuantumMemory((size_t)
    windows->image.width/MagickMax((ssize_t) font_info->min_bounds.width,1)+2UL,
    sizeof(*annotate_info->text));
  if (annotate_info->text == (char *) NULL)
    return(MagickFalse);
  /*
    Create cursor and set graphic context.
  */
  cursor=XCreateFontCursor(display,XC_pencil);
  (void) XCheckDefineCursor(display,windows->image.id,cursor);
  annotate_context=windows->image.annotate_context;
  (void) XSetFont(display,annotate_context,font_info->fid);
  (void) XSetBackground(display,annotate_context,
    windows->pixel_info->pen_colors[box_id].pixel);
  (void) XSetForeground(display,annotate_context,
    windows->pixel_info->pen_colors[pen_id].pixel);
  /*
    Begin annotating the image with text.
  */
  (void) CloneString(&windows->command.name,"Text");
  windows->command.data=0;
  (void) XCommandWidget(display,windows,TextMenu,(XEvent *) NULL);
  state=DefaultState;
  (void) XDrawString(display,windows->image.id,annotate_context,x,y,"_",1);
  text_event.xexpose.width=(int) font_info->max_bounds.width;
  text_event.xexpose.height=font_info->max_bounds.ascent+
    font_info->max_bounds.descent;
  p=annotate_info->text;
  do
  {
    /*
      Display text cursor.
    */
    *p='\0';
    (void) XDrawString(display,windows->image.id,annotate_context,x,y,"_",1);
    /*
      Wait for next event.
    */
    XScreenEvent(display,windows,&event,exception);
    if (event.xany.window == windows->command.id)
      {
        /*
          Select a command from the Command widget.
        */
        (void) XSetBackground(display,annotate_context,
          windows->pixel_info->background_color.pixel);
        (void) XSetForeground(display,annotate_context,
          windows->pixel_info->foreground_color.pixel);
        id=XCommandWidget(display,windows,AnnotateMenu,&event);
        (void) XSetBackground(display,annotate_context,
          windows->pixel_info->pen_colors[box_id].pixel);
        (void) XSetForeground(display,annotate_context,
          windows->pixel_info->pen_colors[pen_id].pixel);
        if (id < 0)
          continue;
        switch (TextCommands[id])
        {
          case TextHelpCommand:
          {
            XTextViewHelp(display,resource_info,windows,MagickFalse,
              "Help Viewer - Image Annotation",ImageAnnotateHelp);
            (void) XCheckDefineCursor(display,windows->image.id,cursor);
            break;
          }
          case TextApplyCommand:
          {
            /*
              Finished annotating.
            */
            annotate_info->width=(unsigned int) XTextWidth(font_info,
              annotate_info->text,(int) strlen(annotate_info->text));
            XRefreshWindow(display,&windows->image,&text_event);
            state|=ExitState;
            break;
          }
          default:
            break;
        }
        continue;
      }
    /*
      Erase text cursor.
    */
    text_event.xexpose.x=x;
    text_event.xexpose.y=y-font_info->max_bounds.ascent;
    (void) XClearArea(display,windows->image.id,x,text_event.xexpose.y,
      (unsigned int) text_event.xexpose.width,(unsigned int)
      text_event.xexpose.height,MagickFalse);
    XRefreshWindow(display,&windows->image,&text_event);
    switch (event.type)
    {
      case ButtonPress:
      {
        if (event.xbutton.window != windows->image.id)
          break;
        if (event.xbutton.button == Button2)
          {
            /*
              Request primary selection.
            */
            (void) XConvertSelection(display,XA_PRIMARY,XA_STRING,XA_STRING,
              windows->image.id,CurrentTime);
            break;
          }
        break;
      }
      case Expose:
      {
        if (event.xexpose.count == 0)
          {
            XAnnotateInfo
              *text_info;

            /*
              Refresh Image window.
            */
            XRefreshWindow(display,&windows->image,(XEvent *) NULL);
            text_info=annotate_info;
            while (text_info != (XAnnotateInfo *) NULL)
            {
              if (annotate_info->stencil == ForegroundStencil)
                (void) XDrawString(display,windows->image.id,annotate_context,
                  text_info->x,text_info->y,text_info->text,
                  (int) strlen(text_info->text));
              else
                (void) XDrawImageString(display,windows->image.id,
                  annotate_context,text_info->x,text_info->y,text_info->text,
                  (int) strlen(text_info->text));
              text_info=text_info->previous;
            }
            (void) XDrawString(display,windows->image.id,annotate_context,
              x,y,"_",1);
          }
        break;
      }
      case KeyPress:
      {
        int
          length;

        if (event.xkey.window != windows->image.id)
          break;
        /*
          Respond to a user key press.
        */
        length=XLookupString((XKeyEvent *) &event.xkey,command,(int)
          sizeof(command),&key_symbol,(XComposeStatus *) NULL);
        *(command+length)='\0';
        if (((event.xkey.state & ControlMask) != 0) ||
            ((event.xkey.state & Mod1Mask) != 0))
          state|=ModifierState;
        if ((state & ModifierState) != 0)
          switch ((int) key_symbol)
          {
            case XK_u:
            case XK_U:
            {
              key_symbol=DeleteCommand;
              break;
            }
            default:
              break;
          }
        switch ((int) key_symbol)
        {
          case XK_BackSpace:
          {
            /*
              Erase one character.
            */
            if (p == annotate_info->text)
              {
                if (annotate_info->previous == (XAnnotateInfo *) NULL)
                  break;
                else
                  {
                    /*
                      Go to end of the previous line of text.
                    */
                    annotate_info=annotate_info->previous;
                    p=annotate_info->text;
                    x=annotate_info->x+annotate_info->width;
                    y=annotate_info->y;
                    if (annotate_info->width != 0)
                      p+=strlen(annotate_info->text);
                    break;
                  }
              }
            p--;
            x-=XTextWidth(font_info,p,1);
            text_event.xexpose.x=x;
            text_event.xexpose.y=y-font_info->max_bounds.ascent;
            XRefreshWindow(display,&windows->image,&text_event);
            break;
          }
          case XK_bracketleft:
          {
            key_symbol=XK_Escape;
            break;
          }
          case DeleteCommand:
          {
            /*
              Erase the entire line of text.
            */
            while (p != annotate_info->text)
            {
              p--;
              x-=XTextWidth(font_info,p,1);
              text_event.xexpose.x=x;
              XRefreshWindow(display,&windows->image,&text_event);
            }
            break;
          }
          case XK_Escape:
          case XK_F20:
          {
            /*
              Finished annotating.
            */
            annotate_info->width=(unsigned int) XTextWidth(font_info,
              annotate_info->text,(int) strlen(annotate_info->text));
            XRefreshWindow(display,&windows->image,&text_event);
            state|=ExitState;
            break;
          }
          default:
          {
            /*
              Draw a single character on the Image window.
            */
            if ((state & ModifierState) != 0)
              break;
            if (*command == '\0')
              break;
            *p=(*command);
            if (annotate_info->stencil == ForegroundStencil)
              (void) XDrawString(display,windows->image.id,annotate_context,
                x,y,p,1);
            else
              (void) XDrawImageString(display,windows->image.id,
                annotate_context,x,y,p,1);
            x+=XTextWidth(font_info,p,1);
            p++;
            if ((x+font_info->max_bounds.width) < (int) windows->image.width)
              break;
          }
          case XK_Return:
          case XK_KP_Enter:
          {
            /*
              Advance to the next line of text.
            */
            *p='\0';
            annotate_info->width=(unsigned int) XTextWidth(font_info,
              annotate_info->text,(int) strlen(annotate_info->text));
            if (annotate_info->next != (XAnnotateInfo *) NULL)
              {
                /*
                  Line of text already exists.
                */
                annotate_info=annotate_info->next;
                x=annotate_info->x;
                y=annotate_info->y;
                p=annotate_info->text;
                break;
              }
            annotate_info->next=(XAnnotateInfo *) AcquireQuantumMemory(1,
              sizeof(*annotate_info->next));
            if (annotate_info->next == (XAnnotateInfo *) NULL)
              return(MagickFalse);
            *annotate_info->next=(*annotate_info);
            annotate_info->next->previous=annotate_info;
            annotate_info=annotate_info->next;
            annotate_info->text=(char *) AcquireQuantumMemory((size_t)
              windows->image.width/MagickMax((ssize_t)
              font_info->min_bounds.width,1)+2UL,sizeof(*annotate_info->text));
            if (annotate_info->text == (char *) NULL)
              return(MagickFalse);
            annotate_info->y+=annotate_info->height;
            if (annotate_info->y > (int) windows->image.height)
              annotate_info->y=(int) annotate_info->height;
            annotate_info->next=(XAnnotateInfo *) NULL;
            x=annotate_info->x;
            y=annotate_info->y;
            p=annotate_info->text;
            break;
          }
        }
        break;
      }
      case KeyRelease:
      {
        /*
          Respond to a user key release.
        */
        (void) XLookupString((XKeyEvent *) &event.xkey,command,(int)
          sizeof(command),&key_symbol,(XComposeStatus *) NULL);
        state&=(~ModifierState);
        break;
      }
      case SelectionNotify:
      {
        Atom
          type;

        int
          format;

        unsigned char
          *data;

        unsigned long
          after,
          length;

        /*
          Obtain response from primary selection.
        */
        if (event.xselection.property == (Atom) None)
          break;
        status=XGetWindowProperty(display,event.xselection.requestor,
          event.xselection.property,0L,(long) MagickPathExtent,True,XA_STRING,
          &type,&format,&length,&after,&data);
        if ((status != Success) || (type != XA_STRING) || (format == 32) ||
            (length == 0))
          break;
        /*
          Annotate Image window with primary selection.
        */
        for (i=0; i < (ssize_t) length; i++)
        {
          if ((char) data[i] != '\n')
            {
              /*
                Draw a single character on the Image window.
              */
              *p=(char) data[i];
              (void) XDrawString(display,windows->image.id,annotate_context,
                x,y,p,1);
              x+=XTextWidth(font_info,p,1);
              p++;
              if ((x+font_info->max_bounds.width) < (int) windows->image.width)
                continue;
            }
          /*
            Advance to the next line of text.
          */
          *p='\0';
          annotate_info->width=(unsigned int) XTextWidth(font_info,
            annotate_info->text,(int) strlen(annotate_info->text));
          if (annotate_info->next != (XAnnotateInfo *) NULL)
            {
              /*
                Line of text already exists.
              */
              annotate_info=annotate_info->next;
              x=annotate_info->x;
              y=annotate_info->y;
              p=annotate_info->text;
              continue;
            }
          annotate_info->next=(XAnnotateInfo *) AcquireQuantumMemory(1,
            sizeof(*annotate_info->next));
          if (annotate_info->next == (XAnnotateInfo *) NULL)
            return(MagickFalse);
          *annotate_info->next=(*annotate_info);
          annotate_info->next->previous=annotate_info;
          annotate_info=annotate_info->next;
          annotate_info->text=(char *) AcquireQuantumMemory((size_t)
            windows->image.width/MagickMax((ssize_t)
            font_info->min_bounds.width,1)+2UL,sizeof(*annotate_info->text));
          if (annotate_info->text == (char *) NULL)
            return(MagickFalse);
          annotate_info->y+=annotate_info->height;
          if (annotate_info->y > (int) windows->image.height)
            annotate_info->y=(int) annotate_info->height;
          annotate_info->next=(XAnnotateInfo *) NULL;
          x=annotate_info->x;
          y=annotate_info->y;
          p=annotate_info->text;
        }
        (void) XFree((void *) data);
        break;
      }
      default:
        break;
    }
  } while ((state & ExitState) == 0);
  (void) XFreeCursor(display,cursor);
  /*
    Annotation is relative to image configuration.
  */
  width=(unsigned int) image->columns;
  height=(unsigned int) image->rows;
  x=0;
  y=0;
  if (windows->image.crop_geometry != (char *) NULL)
    (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
  /*
    Initialize annotated image.
  */
  XSetCursorState(display,windows,MagickTrue);
  XCheckRefreshWindows(display,windows);
  while (annotate_info != (XAnnotateInfo *) NULL)
  {
    if (annotate_info->width == 0)
      {
        /*
          No text on this line--  go to the next line of text.
        */
        previous_info=annotate_info->previous;
        annotate_info->text=(char *)
          RelinquishMagickMemory(annotate_info->text);
        annotate_info=(XAnnotateInfo *) RelinquishMagickMemory(annotate_info);
        annotate_info=previous_info;
        continue;
      }
    /*
      Determine pixel index for box and pen color.
    */
    windows->pixel_info->box_color=windows->pixel_info->pen_colors[box_id];
    if (windows->pixel_info->colors != 0)
      for (i=0; i < (ssize_t) windows->pixel_info->colors; i++)
        if (windows->pixel_info->pixels[i] ==
            windows->pixel_info->pen_colors[box_id].pixel)
          {
            windows->pixel_info->box_index=(unsigned short) i;
            break;
          }
    windows->pixel_info->pen_color=windows->pixel_info->pen_colors[pen_id];
    if (windows->pixel_info->colors != 0)
      for (i=0; i < (ssize_t) windows->pixel_info->colors; i++)
        if (windows->pixel_info->pixels[i] ==
            windows->pixel_info->pen_colors[pen_id].pixel)
          {
            windows->pixel_info->pen_index=(unsigned short) i;
            break;
          }
    /*
      Define the annotate geometry string.
    */
    annotate_info->x=(int)
      width*(annotate_info->x+windows->image.x)/windows->image.ximage->width;
    annotate_info->y=(int) height*(annotate_info->y-font_info->ascent+
      windows->image.y)/windows->image.ximage->height;
    (void) FormatLocaleString(annotate_info->geometry,MagickPathExtent,
      "%ux%u%+d%+d",width*annotate_info->width/windows->image.ximage->width,
      height*annotate_info->height/windows->image.ximage->height,
      annotate_info->x+x,annotate_info->y+y);
    /*
      Annotate image with text.
    */
    status=XAnnotateImage(display,windows->pixel_info,annotate_info,image,
      exception);
    if (status == 0)
      return(MagickFalse);
    /*
      Free up memory.
    */
    previous_info=annotate_info->previous;
    annotate_info->text=DestroyString(annotate_info->text);
    annotate_info=(XAnnotateInfo *) RelinquishMagickMemory(annotate_info);
    annotate_info=previous_info;
  }
  (void) XSetForeground(display,annotate_context,
    windows->pixel_info->foreground_color.pixel);
  (void) XSetBackground(display,annotate_context,
    windows->pixel_info->background_color.pixel);
  (void) XSetFont(display,annotate_context,windows->font_info->fid);
  XSetCursorState(display,windows,MagickFalse);
  (void) XFreeFont(display,font_info);
  /*
    Update image configuration.
  */
  XConfigureImageColormap(display,resource_info,windows,image,exception);
  (void) XConfigureImage(display,resource_info,windows,image,exception);
  return(MagickTrue);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X B a c k g r o u n d I m a g e                                           %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XBackgroundImage() displays the image in the background of a window.
%
%  The format of the XBackgroundImage method is:
%
%      MagickBooleanType XBackgroundImage(Display *display,
%        XResourceInfo *resource_info,XWindows *windows,Image **image,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o display: Specifies a connection to an X server; returned from
%      XOpenDisplay.
%
%    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
%
%    o windows: Specifies a pointer to a XWindows structure.
%
%    o image: the image.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static MagickBooleanType XBackgroundImage(Display *display,
  XResourceInfo *resource_info,XWindows *windows,Image **image,
  ExceptionInfo *exception)
{
#define BackgroundImageTag  "Background/Image"

  int
    status;

  static char
    window_id[MagickPathExtent] = "root";

  XResourceInfo
    background_resources;

  /*
    Put image in background.
  */
  status=XDialogWidget(display,windows,"Background",
    "Enter window id (id 0x00 selects window with pointer):",window_id);
  if (*window_id == '\0')
    return(MagickFalse);
  (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
    exception);
  XInfoWidget(display,windows,BackgroundImageTag);
  XSetCursorState(display,windows,MagickTrue);
  XCheckRefreshWindows(display,windows);
  background_resources=(*resource_info);
  background_resources.window_id=window_id;
  background_resources.backdrop=status != 0 ? MagickTrue : MagickFalse;
  status=XDisplayBackgroundImage(display,&background_resources,*image,
    exception);
  if (status != MagickFalse)
    XClientMessage(display,windows->image.id,windows->im_protocols,
      windows->im_retain_colors,CurrentTime);
  XSetCursorState(display,windows,MagickFalse);
  (void) XMagickCommand(display,resource_info,windows,UndoCommand,image,
    exception);
  return(MagickTrue);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X C h o p I m a g e                                                       %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XChopImage() chops the X image.
%
%  The format of the XChopImage method is:
%
%    MagickBooleanType XChopImage(Display *display,XResourceInfo *resource_info,
%      XWindows *windows,Image **image,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o display: Specifies a connection to an X server; returned from
%      XOpenDisplay.
%
%    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
%
%    o windows: Specifies a pointer to a XWindows structure.
%
%    o image: the image.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static MagickBooleanType XChopImage(Display *display,
  XResourceInfo *resource_info,XWindows *windows,Image **image,
  ExceptionInfo *exception)
{
  const char
    *const ChopMenu[] =
    {
      "Direction",
      "Help",
      "Dismiss",
      (char *) NULL
    };

  static ModeType
    direction = HorizontalChopCommand;

  static const ModeType
    ChopCommands[] =
    {
      ChopDirectionCommand,
      ChopHelpCommand,
      ChopDismissCommand
    },
    DirectionCommands[] =
    {
      HorizontalChopCommand,
      VerticalChopCommand
    };

  char
    text[MagickPathExtent];

  Image
    *chop_image;

  int
    id,
    x,
    y;

  double
    scale_factor;

  RectangleInfo
    chop_info;

  unsigned int
    distance,
    height,
    width;

  size_t
    state;

  XEvent
    event;

  XSegment
    segment_info;

  /*
    Map Command widget.
  */
  (void) CloneString(&windows->command.name,"Chop");
  windows->command.data=1;
  (void) XCommandWidget(display,windows,ChopMenu,(XEvent *) NULL);
  (void) XMapRaised(display,windows->command.id);
  XClientMessage(display,windows->image.id,windows->im_protocols,
    windows->im_update_widget,CurrentTime);
  /*
    Track pointer until button 1 is pressed.
  */
  XQueryPosition(display,windows->image.id,&x,&y);
  (void) XSelectInput(display,windows->image.id,
    windows->image.attributes.event_mask | PointerMotionMask);
  state=DefaultState;
  (void) memset(&segment_info,0,sizeof(segment_info));
  do
  {
    if (windows->info.mapped != MagickFalse)
      {
        /*
          Display pointer position.
        */
        (void) FormatLocaleString(text,MagickPathExtent," %+d%+d ",
          x+windows->image.x,y+windows->image.y);
        XInfoWidget(display,windows,text);
      }
    /*
      Wait for next event.
    */
    XScreenEvent(display,windows,&event,exception);
    if (event.xany.window == windows->command.id)
      {
        /*
          Select a command from the Command widget.
        */
        id=XCommandWidget(display,windows,ChopMenu,&event);
        if (id < 0)
          continue;
        switch (ChopCommands[id])
        {
          case ChopDirectionCommand:
          {
            char
              command[MagickPathExtent];

            const char
              *const Directions[] =
              {
                "horizontal",
                "vertical",
                (char *) NULL,
              };

            /*
              Select a command from the pop-up menu.
            */
            id=XMenuWidget(display,windows,ChopMenu[id],Directions,command);
            if (id >= 0)
              direction=DirectionCommands[id];
            break;
          }
          case ChopHelpCommand:
          {
            XTextViewHelp(display,resource_info,windows,MagickFalse,
              "Help Viewer - Image Chop",ImageChopHelp);
            break;
          }
          case ChopDismissCommand:
          {
            /*
              Prematurely exit.
            */
            state|=EscapeState;
            state|=ExitState;
            break;
          }
          default:
            break;
        }
        continue;
      }
    switch (event.type)
    {
      case ButtonPress:
      {
        if (event.xbutton.button != Button1)
          break;
        if (event.xbutton.window != windows->image.id)
          break;
        /*
          User has committed to start point of chopping line.
        */
        segment_info.x1=(short int) event.xbutton.x;
        segment_info.x2=(short int) event.xbutton.x;
        segment_info.y1=(short int) event.xbutton.y;
        segment_info.y2=(short int) event.xbutton.y;
        state|=ExitState;
        break;
      }
      case ButtonRelease:
        break;
      case Expose:
        break;
      case KeyPress:
      {
        char
          command[MagickPathExtent];

        KeySym
          key_symbol;

        if (event.xkey.window != windows->image.id)
          break;
        /*
          Respond to a user key press.
        */
        (void) XLookupString((XKeyEvent *) &event.xkey,command,(int)
          sizeof(command),&key_symbol,(XComposeStatus *) NULL);
        switch ((int) key_symbol)
        {
          case XK_Escape:
          case XK_F20:
          {
            /*
              Prematurely exit.
            */
            state|=EscapeState;
            state|=ExitState;
            break;
          }
          case XK_F1:
          case XK_Help:
          {
            (void) XSetFunction(display,windows->image.highlight_context,
              GXcopy);
            XTextViewHelp(display,resource_info,windows,MagickFalse,
              "Help Viewer - Image Chop",ImageChopHelp);
            (void) XSetFunction(display,windows->image.highlight_context,
              GXinvert);
            break;
          }
          default:
          {
            (void) XBell(display,0);
            break;
          }
        }
        break;
      }
      case MotionNotify:
      {
        /*
          Map and unmap Info widget as text cursor crosses its boundaries.
        */
        x=event.xmotion.x;
        y=event.xmotion.y;
        if (windows->info.mapped != MagickFalse)
          {
            if ((x < (int) (windows->info.x+windows->info.width)) &&
                (y < (int) (windows->info.y+windows->info.height)))
              (void) XWithdrawWindow(display,windows->info.id,
                windows->info.screen);
          }
        else
          if ((x > (int) (windows->info.x+windows->info.width)) ||
              (y > (int) (windows->info.y+windows->info.height)))
            (void) XMapWindow(display,windows->info.id);
      }
    }
  } while ((state & ExitState) == 0);
  (void) XSelectInput(display,windows->image.id,
    windows->image.attributes.event_mask);
  (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
  if ((state & EscapeState) != 0)
    return(MagickTrue);
  /*
    Draw line as pointer moves until the mouse button is released.
  */
  chop_info.width=0;
  chop_info.height=0;
  chop_info.x=0;
  chop_info.y=0;
  distance=0;
  (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
  state=DefaultState;
  do
  {
    if (distance > 9)
      {
        /*
          Display info and draw chopping line.
        */
        if (windows->info.mapped == MagickFalse)
          (void) XMapWindow(display,windows->info.id);
        (void) FormatLocaleString(text,MagickPathExtent,
          " %.20gx%.20g%+.20g%+.20g",(double) chop_info.width,(double)
          chop_info.height,(double) chop_info.x,(double) chop_info.y);
        XInfoWidget(display,windows,text);
        XHighlightLine(display,windows->image.id,
          windows->image.highlight_context,&segment_info);
      }
    else
      if (windows->info.mapped != MagickFalse)
        (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
    /*
      Wait for next event.
    */
    XScreenEvent(display,windows,&event,exception);
    if (distance > 9)
      XHighlightLine(display,windows->image.id,
        windows->image.highlight_context,&segment_info);
    switch (event.type)
    {
      case ButtonPress:
      {
        segment_info.x2=(short int) event.xmotion.x;
        segment_info.y2=(short int) event.xmotion.y;
        break;
      }
      case ButtonRelease:
      {
        /*
          User has committed to chopping line.
        */
        segment_info.x2=(short int) event.xbutton.x;
        segment_info.y2=(short int) event.xbutton.y;
        state|=ExitState;
        break;
      }
      case Expose:
        break;
      case MotionNotify:
      {
        segment_info.x2=(short int) event.xmotion.x;
        segment_info.y2=(short int) event.xmotion.y;
      }
      default:
        break;
    }
    /*
      Check boundary conditions.
    */
    if (segment_info.x2 < 0)
      segment_info.x2=0;
    else
      if (segment_info.x2 > windows->image.ximage->width)
        segment_info.x2=windows->image.ximage->width;
    if (segment_info.y2 < 0)
      segment_info.y2=0;
    else
      if (segment_info.y2 > windows->image.ximage->height)
        segment_info.y2=windows->image.ximage->height;
    distance=(unsigned int)
      (((segment_info.x2-segment_info.x1)*(segment_info.x2-segment_info.x1))+
       ((segment_info.y2-segment_info.y1)*(segment_info.y2-segment_info.y1)));
    /*
      Compute chopping geometry.
    */
    if (direction == HorizontalChopCommand)
      {
        chop_info.width=(size_t) (segment_info.x2-segment_info.x1+1);
        chop_info.x=(ssize_t) windows->image.x+segment_info.x1;
        chop_info.height=0;
        chop_info.y=0;
        if (segment_info.x1 > (int) segment_info.x2)
          {
            chop_info.width=(size_t) (segment_info.x1-segment_info.x2+1);
            chop_info.x=(ssize_t) windows->image.x+segment_info.x2;
          }
      }
    else
      {
        chop_info.width=0;
        chop_info.height=(size_t) (segment_info.y2-segment_info.y1+1);
        chop_info.x=0;
        chop_info.y=(ssize_t) windows->image.y+segment_info.y1;
        if (segment_info.y1 > segment_info.y2)
          {
            chop_info.height=(size_t) (segment_info.y1-segment_info.y2+1);
            chop_info.y=(ssize_t) windows->image.y+segment_info.y2;
          }
      }
  } while ((state & ExitState) == 0);
  (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
  (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
  if (distance <= 9)
    return(MagickTrue);
  /*
    Image chopping is relative to image configuration.
  */
  (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
    exception);
  XSetCursorState(display,windows,MagickTrue);
  XCheckRefreshWindows(display,windows);
  windows->image.window_changes.width=windows->image.ximage->width-
    (unsigned int) chop_info.width;
  windows->image.window_changes.height=windows->image.ximage->height-
    (unsigned int) chop_info.height;
  width=(unsigned int) (*image)->columns;
  height=(unsigned int) (*image)->rows;
  x=0;
  y=0;
  if (windows->image.crop_geometry != (char *) NULL)
    (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
  scale_factor=(double) width/windows->image.ximage->width;
  chop_info.x+=x;
  chop_info.x=(ssize_t) (scale_factor*chop_info.x+0.5);
  chop_info.width=(unsigned int) (scale_factor*chop_info.width+0.5);
  scale_factor=(double) height/windows->image.ximage->height;
  chop_info.y+=y;
  chop_info.y=(ssize_t) (scale_factor*chop_info.y+0.5);
  chop_info.height=(unsigned int) (scale_factor*chop_info.height+0.5);
  /*
    Chop image.
  */
  chop_image=ChopImage(*image,&chop_info,exception);
  XSetCursorState(display,windows,MagickFalse);
  if (chop_image == (Image *) NULL)
    return(MagickFalse);
  *image=DestroyImage(*image);
  *image=chop_image;
  /*
    Update image configuration.
  */
  XConfigureImageColormap(display,resource_info,windows,*image,exception);
  (void) XConfigureImage(display,resource_info,windows,*image,exception);
  return(MagickTrue);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X C o l o r E d i t I m a g e                                             %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XColorEditImage() allows the user to interactively change the color of one
%  pixel for a DirectColor image or one colormap entry for a PseudoClass image.
%
%  The format of the XColorEditImage method is:
%
%      MagickBooleanType XColorEditImage(Display *display,
%        XResourceInfo *resource_info,XWindows *windows,Image **image,
%          ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o display: Specifies a connection to an X server;  returned from
%      XOpenDisplay.
%
%    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
%
%    o windows: Specifies a pointer to a XWindows structure.
%
%    o image: the image; returned from ReadImage.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static MagickBooleanType XColorEditImage(Display *display,
  XResourceInfo *resource_info,XWindows *windows,Image **image,
  ExceptionInfo *exception)
{
  const char
    *const ColorEditMenu[] =
    {
      "Method",
      "Pixel Color",
      "Border Color",
      "Fuzz",
      "Undo",
      "Help",
      "Dismiss",
      (char *) NULL
    };

  static const ModeType
    ColorEditCommands[] =
    {
      ColorEditMethodCommand,
      ColorEditColorCommand,
      ColorEditBorderCommand,
      ColorEditFuzzCommand,
      ColorEditUndoCommand,
      ColorEditHelpCommand,
      ColorEditDismissCommand
    };

  static PaintMethod
    method = PointMethod;

  static unsigned int
    pen_id = 0;

  static XColor
    border_color = { 0, 0, 0, 0, 0, 0 };

  char
    command[MagickPathExtent],
    text[MagickPathExtent];

  Cursor
    cursor;

  int
    entry,
    id,
    x,
    x_offset,
    y,
    y_offset;

  Quantum
    *q;

  ssize_t
    i;

  unsigned int
    height,
    width;

  size_t
    state;

  XColor
    color;

  XEvent
    event;

  /*
    Map Command widget.
  */
  (void) CloneString(&windows->command.name,"Color Edit");
  windows->command.data=4;
  (void) XCommandWidget(display,windows,ColorEditMenu,(XEvent *) NULL);
  (void) XMapRaised(display,windows->command.id);
  XClientMessage(display,windows->image.id,windows->im_protocols,
    windows->im_update_widget,CurrentTime);
  /*
    Make cursor.
  */
  cursor=XMakeCursor(display,windows->image.id,windows->map_info->colormap,
    resource_info->background_color,resource_info->foreground_color);
  (void) XCheckDefineCursor(display,windows->image.id,cursor);
  /*
    Track pointer until button 1 is pressed.
  */
  XQueryPosition(display,windows->image.id,&x,&y);
  (void) XSelectInput(display,windows->image.id,
    windows->image.attributes.event_mask | PointerMotionMask);
  state=DefaultState;
  do
  {
    if (windows->info.mapped != MagickFalse)
      {
        /*
          Display pointer position.
        */
        (void) FormatLocaleString(text,MagickPathExtent," %+d%+d ",
          x+windows->image.x,y+windows->image.y);
        XInfoWidget(display,windows,text);
      }
    /*
      Wait for next event.
    */
    XScreenEvent(display,windows,&event,exception);
    if (event.xany.window == windows->command.id)
      {
        /*
          Select a command from the Command widget.
        */
        id=XCommandWidget(display,windows,ColorEditMenu,&event);
        if (id < 0)
          {
            (void) XCheckDefineCursor(display,windows->image.id,cursor);
            continue;
          }
        switch (ColorEditCommands[id])
        {
          case ColorEditMethodCommand:
          {
            char
              **methods;

            /*
              Select a method from the pop-up menu.
            */
            methods=(char **) GetCommandOptions(MagickMethodOptions);
            if (methods == (char **) NULL)
              break;
            entry=XMenuWidget(display,windows,ColorEditMenu[id],
              (const char **) methods,command);
            if (entry >= 0)
              method=(PaintMethod) ParseCommandOption(MagickMethodOptions,
                MagickFalse,methods[entry]);
            methods=DestroyStringList(methods);
            break;
          }
          case ColorEditColorCommand:
          {
            const char
              *ColorMenu[MaxNumberPens];

            int
              pen_number;

            /*
              Initialize menu selections.
            */
            for (i=0; i < (int) (MaxNumberPens-2); i++)
              ColorMenu[i]=resource_info->pen_colors[i];
            ColorMenu[MaxNumberPens-2]="Browser...";
            ColorMenu[MaxNumberPens-1]=(const char *) NULL;
            /*
              Select a pen color from the pop-up menu.
            */
            pen_number=XMenuWidget(display,windows,ColorEditMenu[id],
              (const char **) ColorMenu,command);
            if (pen_number < 0)
              break;
            if (pen_number == (MaxNumberPens-2))
              {
                static char
                  color_name[MagickPathExtent] = "gray";

                /*
                  Select a pen color from a dialog.
                */
                resource_info->pen_colors[pen_number]=color_name;
                XColorBrowserWidget(display,windows,"Select",color_name);
                if (*color_name == '\0')
                  break;
              }
            /*
              Set pen color.
            */
            (void) XParseColor(display,windows->map_info->colormap,
              resource_info->pen_colors[pen_number],&color);
            XBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
              (unsigned int) MaxColors,&color);
            windows->pixel_info->pen_colors[pen_number]=color;
            pen_id=(unsigned int) pen_number;
            break;
          }
          case ColorEditBorderCommand:
          {
            const char
              *ColorMenu[MaxNumberPens];

            int
              pen_number;

            /*
              Initialize menu selections.
            */
            for (i=0; i < (int) (MaxNumberPens-2); i++)
              ColorMenu[i]=resource_info->pen_colors[i];
            ColorMenu[MaxNumberPens-2]="Browser...";
            ColorMenu[MaxNumberPens-1]=(const char *) NULL;
            /*
              Select a pen color from the pop-up menu.
            */
            pen_number=XMenuWidget(display,windows,ColorEditMenu[id],
              (const char **) ColorMenu,command);
            if (pen_number < 0)
              break;
            if (pen_number == (MaxNumberPens-2))
              {
                static char
                  color_name[MagickPathExtent] = "gray";

                /*
                  Select a pen color from a dialog.
                */
                resource_info->pen_colors[pen_number]=color_name;
                XColorBrowserWidget(display,windows,"Select",color_name);
                if (*color_name == '\0')
                  break;
              }
            /*
              Set border color.
            */
            (void) XParseColor(display,windows->map_info->colormap,
              resource_info->pen_colors[pen_number],&border_color);
            break;
          }
          case ColorEditFuzzCommand:
          {
            const char
              *const FuzzMenu[] =
              {
                "0%",
                "2%",
                "5%",
                "10%",
                "15%",
                "Dialog...",
                (char *) NULL,
              };

            static char
              fuzz[MagickPathExtent];

            /*
              Select a command from the pop-up menu.
            */
            entry=XMenuWidget(display,windows,ColorEditMenu[id],FuzzMenu,
              command);
            if (entry < 0)
              break;
            if (entry != 5)
              {
                (*image)->fuzz=StringToDoubleInterval(FuzzMenu[entry],(double)
                  QuantumRange+1.0);
                break;
              }
            (void) (void) CopyMagickString(fuzz,"20%",MagickPathExtent);
            (void) XDialogWidget(display,windows,"Ok",
              "Enter fuzz factor (0.0 - 99.9%):",fuzz);
            if (*fuzz == '\0')
              break;
            (void) ConcatenateMagickString(fuzz,"%",MagickPathExtent);
            (*image)->fuzz=StringToDoubleInterval(fuzz,(double) QuantumRange+
              1.0);
            break;
          }
          case ColorEditUndoCommand:
          {
            (void) XMagickCommand(display,resource_info,windows,UndoCommand,
              image,exception);
            break;
          }
          case ColorEditHelpCommand:
          default:
          {
            XTextViewHelp(display,resource_info,windows,MagickFalse,
              "Help Viewer - Image Annotation",ImageColorEditHelp);
            break;
          }
          case ColorEditDismissCommand:
          {
            /*
              Prematurely exit.
            */
            state|=EscapeState;
            state|=ExitState;
            break;
          }
        }
        (void) XCheckDefineCursor(display,windows->image.id,cursor);
        continue;
      }
    switch (event.type)
    {
      case ButtonPress:
      {
        if (event.xbutton.button != Button1)
          break;
        if ((event.xbutton.window != windows->image.id) &&
            (event.xbutton.window != windows->magnify.id))
          break;
        /*
          exit loop.
        */
        x=event.xbutton.x;
        y=event.xbutton.y;
        (void) XMagickCommand(display,resource_info,windows,
          SaveToUndoBufferCommand,image,exception);
        state|=UpdateConfigurationState;
        break;
      }
      case ButtonRelease:
      {
        if (event.xbutton.button != Button1)
          break;
        if ((event.xbutton.window != windows->image.id) &&
            (event.xbutton.window != windows->magnify.id))
          break;
        /*
          Update colormap information.
        */
        x=event.xbutton.x;
        y=event.xbutton.y;
        XConfigureImageColormap(display,resource_info,windows,*image,exception);
        (void) XConfigureImage(display,resource_info,windows,*image,exception);
        XInfoWidget(display,windows,text);
        (void) XCheckDefineCursor(display,windows->image.id,cursor);
        state&=(~UpdateConfigurationState);
        break;
      }
      case Expose:
        break;
      case KeyPress:
      {
        KeySym
          key_symbol;

        if (event.xkey.window == windows->magnify.id)
          {
            Window
              window;

            window=windows->magnify.id;
            while (XCheckWindowEvent(display,window,KeyPressMask,&event)) ;
          }
        if (event.xkey.window != windows->image.id)
          break;
        /*
          Respond to a user key press.
        */
        (void) XLookupString((XKeyEvent *) &event.xkey,command,(int)
          sizeof(command),&key_symbol,(XComposeStatus *) NULL);
        switch ((int) key_symbol)
        {
          case XK_Escape:
          case XK_F20:
          {
            /*
              Prematurely exit.
            */
            state|=ExitState;
            break;
          }
          case XK_F1:
          case XK_Help:
          {
            XTextViewHelp(display,resource_info,windows,MagickFalse,
              "Help Viewer - Image Annotation",ImageColorEditHelp);
            break;
          }
          default:
          {
            (void) XBell(display,0);
            break;
          }
        }
        break;
      }
      case MotionNotify:
      {
        /*
          Map and unmap Info widget as cursor crosses its boundaries.
        */
        x=event.xmotion.x;
        y=event.xmotion.y;
        if (windows->info.mapped != MagickFalse)
          {
            if ((x < (int) (windows->info.x+windows->info.width)) &&
                (y < (int) (windows->info.y+windows->info.height)))
              (void) XWithdrawWindow(display,windows->info.id,
                windows->info.screen);
          }
        else
          if ((x > (int) (windows->info.x+windows->info.width)) ||
              (y > (int) (windows->info.y+windows->info.height)))
            (void) XMapWindow(display,windows->info.id);
        break;
      }
      default:
        break;
    }
    if (event.xany.window == windows->magnify.id)
      {
        x=windows->magnify.x-windows->image.x;
        y=windows->magnify.y-windows->image.y;
      }
    x_offset=x;
    y_offset=y;
    if ((state & UpdateConfigurationState) != 0)
      {
        CacheView
          *image_view;

        int
          x,
          y;

        /*
          Pixel edit is relative to image configuration.
        */
        (void) XClearArea(display,windows->image.id,x_offset,y_offset,1,1,
          MagickTrue);
        color=windows->pixel_info->pen_colors[pen_id];
        XPutPixel(windows->image.ximage,x_offset,y_offset,color.pixel);
        width=(unsigned int) (*image)->columns;
        height=(unsigned int) (*image)->rows;
        x=0;
        y=0;
        if (windows->image.crop_geometry != (char *) NULL)
          (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
            &width,&height);
        x_offset=(int)
          (width*(windows->image.x+x_offset)/windows->image.ximage->width+x);
        y_offset=(int)
          (height*(windows->image.y+y_offset)/windows->image.ximage->height+y);
        if ((x_offset < 0) || (y_offset < 0))
          continue;
        if ((x_offset >= (int) (*image)->columns) ||
            (y_offset >= (int) (*image)->rows))
          continue;
        image_view=AcquireAuthenticCacheView(*image,exception);
        switch (method)
        {
          case PointMethod:
          default:
          {
            /*
              Update color information using point algorithm.
            */
            if (SetImageStorageClass(*image,DirectClass,exception) == MagickFalse)
              return(MagickFalse);
            q=GetCacheViewAuthenticPixels(image_view,(ssize_t)x_offset,
              (ssize_t) y_offset,1,1,exception);
            if (q == (Quantum *) NULL)
              break;
            SetPixelRed(*image,ScaleShortToQuantum(color.red),q);
            SetPixelGreen(*image,ScaleShortToQuantum(color.green),q);
            SetPixelBlue(*image,ScaleShortToQuantum(color.blue),q);
            (void) SyncCacheViewAuthenticPixels(image_view,exception);
            break;
          }
          case ReplaceMethod:
          {
            PixelInfo
              pixel,
              target;

            /*
              Update color information using replace algorithm.
            */
            (void) GetOneCacheViewVirtualPixelInfo(image_view,(ssize_t)
              x_offset,(ssize_t) y_offset,&target,exception);
            if ((*image)->storage_class == DirectClass)
              {
                for (y=0; y < (int) (*image)->rows; y++)
                {
                  q=GetCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
                    (*image)->columns,1,exception);
                  if (q == (Quantum *) NULL)
                    break;
                  for (x=0; x < (int) (*image)->columns; x++)
                  {
                    GetPixelInfoPixel(*image,q,&pixel);
                    if (IsFuzzyEquivalencePixelInfo(&pixel,&target))
                      {
                        SetPixelRed(*image,ScaleShortToQuantum(
                          color.red),q);
                        SetPixelGreen(*image,ScaleShortToQuantum(
                          color.green),q);
                        SetPixelBlue(*image,ScaleShortToQuantum(
                          color.blue),q);
                      }
                    q+=GetPixelChannels(*image);
                  }
                  if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
                    break;
                }
              }
            else
              {
                for (i=0; i < (ssize_t) (*image)->colors; i++)
                  if (IsFuzzyEquivalencePixelInfo((*image)->colormap+i,&target))
                    {
                      (*image)->colormap[i].red=(double) ScaleShortToQuantum(
                        color.red);
                      (*image)->colormap[i].green=(double) ScaleShortToQuantum(
                        color.green);
                      (*image)->colormap[i].blue=(double) ScaleShortToQuantum(
                        color.blue);
                    }
                (void) SyncImage(*image,exception);
              }
            break;
          }
          case FloodfillMethod:
          case FillToBorderMethod:
          {
            DrawInfo
              *draw_info;

            PixelInfo
              target;

            /*
              Update color information using floodfill algorithm.
            */
            (void) GetOneVirtualPixelInfo(*image,
              GetPixelCacheVirtualMethod(*image),(ssize_t) x_offset,(ssize_t)
              y_offset,&target,exception);
            if (method == FillToBorderMethod)
              {
                target.red=(double)
                  ScaleShortToQuantum(border_color.red);
                target.green=(double)
                  ScaleShortToQuantum(border_color.green);
                target.blue=(double)
                  ScaleShortToQuantum(border_color.blue);
              }
            draw_info=CloneDrawInfo(resource_info->image_info,
              (DrawInfo *) NULL);
            (void) QueryColorCompliance(resource_info->pen_colors[pen_id],
              AllCompliance,&draw_info->fill,exception);
            (void) FloodfillPaintImage(*image,draw_info,&target,
              (ssize_t)x_offset,(ssize_t)y_offset,
              method != FloodfillMethod ? MagickTrue : MagickFalse,exception);
            draw_info=DestroyDrawInfo(draw_info);
            break;
          }
          case ResetMethod:
          {
            /*
              Update color information using reset algorithm.
            */
            if (SetImageStorageClass(*image,DirectClass,exception) == MagickFalse)
              return(MagickFalse);
            for (y=0; y < (int) (*image)->rows; y++)
            {
              q=QueueCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
                (*image)->columns,1,exception);
              if (q == (Quantum *) NULL)
                break;
              for (x=0; x < (int) (*image)->columns; x++)
              {
                SetPixelRed(*image,ScaleShortToQuantum(color.red),q);
                SetPixelGreen(*image,ScaleShortToQuantum(color.green),q);
                SetPixelBlue(*image,ScaleShortToQuantum(color.blue),q);
                q+=GetPixelChannels(*image);
              }
              if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
                break;
            }
            break;
          }
        }
        image_view=DestroyCacheView(image_view);
        state&=(~UpdateConfigurationState);
      }
  } while ((state & ExitState) == 0);
  (void) XSelectInput(display,windows->image.id,
    windows->image.attributes.event_mask);
  XSetCursorState(display,windows,MagickFalse);
  (void) XFreeCursor(display,cursor);
  return(MagickTrue);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X C o m p o s i t e I m a g e                                             %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XCompositeImage() requests an image name from the user, reads the image and
%  composites it with the X window image at a location the user chooses with
%  the pointer.
%
%  The format of the XCompositeImage method is:
%
%      MagickBooleanType XCompositeImage(Display *display,
%        XResourceInfo *resource_info,XWindows *windows,Image *image,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o display: Specifies a connection to an X server;  returned from
%      XOpenDisplay.
%
%    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
%
%    o windows: Specifies a pointer to a XWindows structure.
%
%    o image: the image; returned from ReadImage.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static MagickBooleanType XCompositeImage(Display *display,
  XResourceInfo *resource_info,XWindows *windows,Image *image,
  ExceptionInfo *exception)
{
  const char
    *const CompositeMenu[] =
    {
      "Operators",
      "Dissolve",
      "Displace",
      "Help",
      "Dismiss",
      (char *) NULL
    };

  static char
    displacement_geometry[MagickPathExtent] = "30x30",
    filename[MagickPathExtent] = "\0";

  static CompositeOperator
    compose = CopyCompositeOp;

  static const ModeType
    CompositeCommands[] =
    {
      CompositeOperatorsCommand,
      CompositeDissolveCommand,
      CompositeDisplaceCommand,
      CompositeHelpCommand,
      CompositeDismissCommand
    };

  char
    text[MagickPathExtent];

  Cursor
    cursor;

  Image
    *composite_image;

  int
    entry,
    id,
    x,
    y;

  double
    blend,
    scale_factor;

  RectangleInfo
    highlight_info,
    composite_info;

  unsigned int
    height,
    width;

  size_t
    state;

  XEvent
    event;

  /*
    Request image file name from user.
  */
  XFileBrowserWidget(display,windows,"Composite",filename);
  if (*filename == '\0')
    return(MagickTrue);
  /*
    Read image.
  */
  XSetCursorState(display,windows,MagickTrue);
  XCheckRefreshWindows(display,windows);
  (void) CopyMagickString(resource_info->image_info->filename,filename,
    MagickPathExtent);
  composite_image=ReadImage(resource_info->image_info,exception);
  CatchException(exception);
  XSetCursorState(display,windows,MagickFalse);
  if (composite_image == (Image *) NULL)
    return(MagickFalse);
  /*
    Map Command widget.
  */
  (void) CloneString(&windows->command.name,"Composite");
  windows->command.data=1;
  (void) XCommandWidget(display,windows,CompositeMenu,(XEvent *) NULL);
  (void) XMapRaised(display,windows->command.id);
  XClientMessage(display,windows->image.id,windows->im_protocols,
    windows->im_update_widget,CurrentTime);
  /*
    Track pointer until button 1 is pressed.
  */
  XQueryPosition(display,windows->image.id,&x,&y);
  (void) XSelectInput(display,windows->image.id,
    windows->image.attributes.event_mask | PointerMotionMask);
  composite_info.x=(ssize_t) windows->image.x+x;
  composite_info.y=(ssize_t) windows->image.y+y;
  composite_info.width=0;
  composite_info.height=0;
  cursor=XCreateFontCursor(display,XC_ul_angle);
  (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
  blend=0.0;
  state=DefaultState;
  do
  {
    if (windows->info.mapped != MagickFalse)
      {
        /*
          Display pointer position.
        */
        (void) FormatLocaleString(text,MagickPathExtent," %+ld%+ld ",
          (long) composite_info.x,(long) composite_info.y);
        XInfoWidget(display,windows,text);
      }
    highlight_info=composite_info;
    highlight_info.x=composite_info.x-windows->image.x;
    highlight_info.y=composite_info.y-windows->image.y;
    XHighlightRectangle(display,windows->image.id,
      windows->image.highlight_context,&highlight_info);
    /*
      Wait for next event.
    */
    XScreenEvent(display,windows,&event,exception);
    XHighlightRectangle(display,windows->image.id,
      windows->image.highlight_context,&highlight_info);
    if (event.xany.window == windows->command.id)
      {
        /*
          Select a command from the Command widget.
        */
        id=XCommandWidget(display,windows,CompositeMenu,&event);
        if (id < 0)
          continue;
        switch (CompositeCommands[id])
        {
          case CompositeOperatorsCommand:
          {
            char
              command[MagickPathExtent],
              **operators;

            /*
              Select a command from the pop-up menu.
            */
            operators=GetCommandOptions(MagickComposeOptions);
            if (operators == (char **) NULL)
              break;
            entry=XMenuWidget(display,windows,CompositeMenu[id],
              (const char **) operators,command);
            if (entry >= 0)
              compose=(CompositeOperator) ParseCommandOption(
                MagickComposeOptions,MagickFalse,operators[entry]);
            operators=DestroyStringList(operators);
            break;
          }
          case CompositeDissolveCommand:
          {
            static char
              factor[MagickPathExtent] = "20.0";

            /*
              Dissolve the two images a given percent.
            */
            (void) XSetFunction(display,windows->image.highlight_context,
              GXcopy);
            (void) XDialogWidget(display,windows,"Dissolve",
              "Enter the blend factor (0.0 - 99.9%):",factor);
            (void) XSetFunction(display,windows->image.highlight_context,
              GXinvert);
            if (*factor == '\0')
              break;
            blend=StringToDouble(factor,(char **) NULL);
            compose=DissolveCompositeOp;
            break;
          }
          case CompositeDisplaceCommand:
          {
            /*
              Get horizontal and vertical scale displacement geometry.
            */
            (void) XSetFunction(display,windows->image.highlight_context,
              GXcopy);
            (void) XDialogWidget(display,windows,"Displace",
              "Enter the horizontal and vertical scale:",displacement_geometry);
            (void) XSetFunction(display,windows->image.highlight_context,
              GXinvert);
            if (*displacement_geometry == '\0')
              break;
            compose=DisplaceCompositeOp;
            break;
          }
          case CompositeHelpCommand:
          {
            (void) XSetFunction(display,windows->image.highlight_context,
              GXcopy);
            XTextViewHelp(display,resource_info,windows,MagickFalse,
              "Help Viewer - Image Composite",ImageCompositeHelp);
            (void) XSetFunction(display,windows->image.highlight_context,
              GXinvert);
            break;
          }
          case CompositeDismissCommand:
          {
            /*
              Prematurely exit.
            */
            state|=EscapeState;
            state|=ExitState;
            break;
          }
          default:
            break;
        }
        continue;
      }
    switch (event.type)
    {
      case ButtonPress:
      {
        if (image->debug != MagickFalse)
          (void) LogMagickEvent(X11Event,GetMagickModule(),
            "Button Press: 0x%lx %u +%d+%d",event.xbutton.window,
            event.xbutton.button,event.xbutton.x,event.xbutton.y);
        if (event.xbutton.button != Button1)
          break;
        if (event.xbutton.window != windows->image.id)
          break;
        /*
          Change cursor.
        */
        composite_info.width=composite_image->columns;
        composite_info.height=composite_image->rows;
        (void) XCheckDefineCursor(display,windows->image.id,cursor);
        composite_info.x=(ssize_t) windows->image.x+event.xbutton.x;
        composite_info.y=(ssize_t) windows->image.y+event.xbutton.y;
        break;
      }
      case ButtonRelease:
      {
        if (image->debug != MagickFalse)
          (void) LogMagickEvent(X11Event,GetMagickModule(),
            "Button Release: 0x%lx %u +%d+%d",event.xbutton.window,
            event.xbutton.button,event.xbutton.x,event.xbutton.y);
        if (event.xbutton.button != Button1)
          break;
        if (event.xbutton.window != windows->image.id)
          break;
        if ((composite_info.width != 0) && (composite_info.height != 0))
          {
            /*
              User has selected the location of the composite image.
            */
            composite_info.x=(ssize_t) windows->image.x+event.xbutton.x;
            composite_info.y=(ssize_t) windows->image.y+event.xbutton.y;
            state|=ExitState;
          }
        break;
      }
      case Expose:
        break;
      case KeyPress:
      {
        char
          command[MagickPathExtent];

        KeySym
          key_symbol;

        int
          length;

        if (event.xkey.window != windows->image.id)
          break;
        /*
          Respond to a user key press.
        */
        length=XLookupString((XKeyEvent *) &event.xkey,command,(int)
          sizeof(command),&key_symbol,(XComposeStatus *) NULL);
        *(command+length)='\0';
        if (image->debug != MagickFalse)
          (void) LogMagickEvent(X11Event,GetMagickModule(),
            "Key press: 0x%lx (%s)",(unsigned long) key_symbol,command);
        switch ((int) key_symbol)
        {
          case XK_Escape:
          case XK_F20:
          {
            /*
              Prematurely exit.
            */
            composite_image=DestroyImage(composite_image);
            state|=EscapeState;
            state|=ExitState;
            break;
          }
          case XK_F1:
          case XK_Help:
          {
            (void) XSetFunction(display,windows->image.highlight_context,
              GXcopy);
            XTextViewHelp(display,resource_info,windows,MagickFalse,
              "Help Viewer - Image Composite",ImageCompositeHelp);
            (void) XSetFunction(display,windows->image.highlight_context,
              GXinvert);
            break;
          }
          default:
          {
            (void) XBell(display,0);
            break;
          }
        }
        break;
      }
      case MotionNotify:
      {
        /*
          Map and unmap Info widget as text cursor crosses its boundaries.
        */
        x=event.xmotion.x;
        y=event.xmotion.y;
        if (windows->info.mapped != MagickFalse)
          {
            if ((x < (int) (windows->info.x+windows->info.width)) &&
                (y < (int) (windows->info.y+windows->info.height)))
              (void) XWithdrawWindow(display,windows->info.id,
                windows->info.screen);
          }
        else
          if ((x > (int) (windows->info.x+windows->info.width)) ||
              (y > (int) (windows->info.y+windows->info.height)))
            (void) XMapWindow(display,windows->info.id);
        composite_info.x=(ssize_t) windows->image.x+x;
        composite_info.y=(ssize_t) windows->image.y+y;
        break;
      }
      default:
      {
        if (image->debug != MagickFalse)
          (void) LogMagickEvent(X11Event,GetMagickModule(),"Event type: %d",
            event.type);
        break;
      }
    }
  } while ((state & ExitState) == 0);
  (void) XSelectInput(display,windows->image.id,
    windows->image.attributes.event_mask);
  (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
  XSetCursorState(display,windows,MagickFalse);
  (void) XFreeCursor(display,cursor);
  if ((state & EscapeState) != 0)
    return(MagickTrue);
  /*
    Image compositing is relative to image configuration.
  */
  XSetCursorState(display,windows,MagickTrue);
  XCheckRefreshWindows(display,windows);
  width=(unsigned int) image->columns;
  height=(unsigned int) image->rows;
  x=0;
  y=0;
  if (windows->image.crop_geometry != (char *) NULL)
    (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
  scale_factor=(double) width/windows->image.ximage->width;
  composite_info.x+=x;
  composite_info.x=(ssize_t) (scale_factor*composite_info.x+0.5);
  composite_info.width=(unsigned int) (scale_factor*composite_info.width+0.5);
  scale_factor=(double) height/windows->image.ximage->height;
  composite_info.y+=y;
  composite_info.y=(ssize_t) (scale_factor*composite_info.y+0.5);
  composite_info.height=(unsigned int) (scale_factor*composite_info.height+0.5);
  if ((composite_info.width != composite_image->columns) ||
      (composite_info.height != composite_image->rows))
    {
      Image
        *resize_image;

      /*
        Scale composite image.
      */
      resize_image=ResizeImage(composite_image,composite_info.width,
        composite_info.height,composite_image->filter,exception);
      composite_image=DestroyImage(composite_image);
      if (resize_image == (Image *) NULL)
        {
          XSetCursorState(display,windows,MagickFalse);
          return(MagickFalse);
        }
      composite_image=resize_image;
    }
  if (compose == DisplaceCompositeOp)
    (void) SetImageArtifact(composite_image,"compose:args",
      displacement_geometry);
  if (blend != 0.0)
    {
      CacheView
        *image_view;

      int
        y;

      Quantum
        opacity;

      int
        x;

      Quantum
        *q;

      /*
        Create mattes for blending.
      */
      (void) SetImageAlphaChannel(composite_image,OpaqueAlphaChannel,exception);
      opacity=(Quantum) (ScaleQuantumToChar(QuantumRange)-
        ((ssize_t) ScaleQuantumToChar(QuantumRange)*blend)/100);
      if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
        return(MagickFalse);
      image->alpha_trait=BlendPixelTrait;
      image_view=AcquireAuthenticCacheView(image,exception);
      for (y=0; y < (int) image->rows; y++)
      {
        q=GetCacheViewAuthenticPixels(image_view,0,(ssize_t) y,image->columns,1,
          exception);
        if (q == (Quantum *) NULL)
          break;
        for (x=0; x < (int) image->columns; x++)
        {
          SetPixelAlpha(image,opacity,q);
          q+=GetPixelChannels(image);
        }
        if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
          break;
      }
      image_view=DestroyCacheView(image_view);
    }
  /*
    Composite image with X Image window.
  */
  (void) CompositeImage(image,composite_image,compose,MagickTrue,
    composite_info.x,composite_info.y,exception);
  composite_image=DestroyImage(composite_image);
  XSetCursorState(display,windows,MagickFalse);
  /*
    Update image configuration.
  */
  XConfigureImageColormap(display,resource_info,windows,image,exception);
  (void) XConfigureImage(display,resource_info,windows,image,exception);
  return(MagickTrue);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X C o n f i g u r e I m a g e                                             %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XConfigureImage() creates a new X image.  It also notifies the window
%  manager of the new image size and configures the transient widows.
%
%  The format of the XConfigureImage method is:
%
%      MagickBooleanType XConfigureImage(Display *display,
%        XResourceInfo *resource_info,XWindows *windows,Image *image,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o display: Specifies a connection to an X server; returned from
%      XOpenDisplay.
%
%    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
%
%    o windows: Specifies a pointer to a XWindows structure.
%
%    o image: the image.
%
%    o exception: return any errors or warnings in this structure.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static MagickBooleanType XConfigureImage(Display *display,
  XResourceInfo *resource_info,XWindows *windows,Image *image,
  ExceptionInfo *exception)
{
  char
    geometry[MagickPathExtent];

  MagickStatusType
    status;

  size_t
    mask,
    height,
    width;

  ssize_t
    x,
    y;

  XSizeHints
    *size_hints;

  XWindowChanges
    window_changes;

  /*
    Dismiss if window dimensions are zero.
  */
  width=(unsigned int) windows->image.window_changes.width;
  height=(unsigned int) windows->image.window_changes.height;
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(X11Event,GetMagickModule(),
      "Configure Image: %dx%d=>%.20gx%.20g",windows->image.ximage->width,
      windows->image.ximage->height,(double) width,(double) height);
  if ((width*height) == 0)
    return(MagickTrue);
  x=0;
  y=0;
  /*
    Resize image to fit Image window dimensions.
  */
  XSetCursorState(display,windows,MagickTrue);
  (void) XFlush(display);
  if (((int) width != windows->image.ximage->width) ||
      ((int) height != windows->image.ximage->height))
    image->taint=MagickTrue;
  windows->magnify.x=(int)
    width*windows->magnify.x/windows->image.ximage->width;
  windows->magnify.y=(int)
    height*windows->magnify.y/windows->image.ximage->height;
  windows->image.x=(int) (width*windows->image.x/windows->image.ximage->width);
  windows->image.y=(int)
    (height*windows->image.y/windows->image.ximage->height);
  status=XMakeImage(display,resource_info,&windows->image,image,
    (unsigned int) width,(unsigned int) height,exception);
  if (status == MagickFalse)
    XNoticeWidget(display,windows,"Unable to configure X image:",
      windows->image.name);
  /*
    Notify window manager of the new configuration.
  */
  if (resource_info->image_geometry != (char *) NULL)
    (void) FormatLocaleString(geometry,MagickPathExtent,"%s>!",
      resource_info->image_geometry);
  else
    (void) FormatLocaleString(geometry,MagickPathExtent,"%ux%u+0+0>!",
      XDisplayWidth(display,windows->image.screen),
      XDisplayHeight(display,windows->image.screen));
  (void) ParseMetaGeometry(geometry,&x,&y,&width,&height);
  window_changes.width=(int) width;
  if (window_changes.width > XDisplayWidth(display,windows->image.screen))
    window_changes.width=XDisplayWidth(display,windows->image.screen);
  window_changes.height=(int) height;
  if (window_changes.height > XDisplayHeight(display,windows->image.screen))
    window_changes.height=XDisplayHeight(display,windows->image.screen);
  mask=(size_t) (CWWidth | CWHeight);
  if (resource_info->backdrop)
    {
      mask|=CWX | CWY;
      window_changes.x=(int)
        ((XDisplayWidth(display,windows->image.screen)/2)-(width/2));
      window_changes.y=(int)
        ((XDisplayHeight(display,windows->image.screen)/2)-(height/2));
    }
  (void) XReconfigureWMWindow(display,windows->image.id,windows->image.screen,
    (unsigned int) mask,&window_changes);
  (void) XClearWindow(display,windows->image.id);
  XRefreshWindow(display,&windows->image,(XEvent *) NULL);
  /*
    Update Magnify window configuration.
  */
  if (windows->magnify.mapped != MagickFalse)
    XMakeMagnifyImage(display,windows,exception);
  windows->pan.crop_geometry=windows->image.crop_geometry;
  XBestIconSize(display,&windows->pan,image);
  while (((windows->pan.width << 1) < MaxIconSize) &&
         ((windows->pan.height << 1) < MaxIconSize))
  {
    windows->pan.width<<=1;
    windows->pan.height<<=1;
  }
  if (windows->pan.geometry != (char *) NULL)
    (void) XParseGeometry(windows->pan.geometry,&windows->pan.x,&windows->pan.y,
      &windows->pan.width,&windows->pan.height);
  window_changes.width=(int) windows->pan.width;
  window_changes.height=(int) windows->pan.height;
  size_hints=XAllocSizeHints();
  if (size_hints != (XSizeHints *) NULL)
    {
      /*
        Set new size hints.
      */
      size_hints->flags=PSize | PMinSize | PMaxSize;
      size_hints->width=window_changes.width;
      size_hints->height=window_changes.height;
      size_hints->min_width=size_hints->width;
      size_hints->min_height=size_hints->height;
      size_hints->max_width=size_hints->width;
      size_hints->max_height=size_hints->height;
      (void) XSetNormalHints(display,windows->pan.id,size_hints);
      (void) XFree((void *) size_hints);
    }
  (void) XReconfigureWMWindow(display,windows->pan.id,windows->pan.screen,
    (unsigned int) (CWWidth | CWHeight),&window_changes);
  /*
    Update icon window configuration.
  */
  windows->icon.crop_geometry=windows->image.crop_geometry;
  XBestIconSize(display,&windows->icon,image);
  window_changes.width=(int) windows->icon.width;
  window_changes.height=(int) windows->icon.height;
  (void) XReconfigureWMWindow(display,windows->icon.id,windows->icon.screen,
    (unsigned int) (CWWidth | CWHeight),&window_changes);
  XSetCursorState(display,windows,MagickFalse);
  return(status != 0 ? MagickTrue : MagickFalse);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X C r o p I m a g e                                                       %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XCropImage() allows the user to select a region of the image and crop, copy,
%  or cut it.  For copy or cut, the image can subsequently be composited onto
%  the image with XPasteImage.
%
%  The format of the XCropImage method is:
%
%      MagickBooleanType XCropImage(Display *display,
%        XResourceInfo *resource_info,XWindows *windows,Image *image,
%        const ClipboardMode mode,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o display: Specifies a connection to an X server; returned from
%      XOpenDisplay.
%
%    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
%
%    o windows: Specifies a pointer to a XWindows structure.
%
%    o image: the image; returned from ReadImage.
%
%    o mode: This unsigned value specified whether the image should be
%      cropped, copied, or cut.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static MagickBooleanType XCropImage(Display *display,
  XResourceInfo *resource_info,XWindows *windows,Image *image,
  const ClipboardMode mode,ExceptionInfo *exception)
{
  const char
    *const CropModeMenu[] =
    {
      "Help",
      "Dismiss",
      (char *) NULL
    },
    *RectifyModeMenu[] =
    {
      "Crop",
      "Help",
      "Dismiss",
      (char *) NULL
    };

  static const ModeType
    CropCommands[] =
    {
      CropHelpCommand,
      CropDismissCommand
    },
    RectifyCommands[] =
    {
      RectifyCopyCommand,
      RectifyHelpCommand,
      RectifyDismissCommand
    };

  CacheView
    *image_view;

  char
    command[MagickPathExtent],
    text[MagickPathExtent];

  Cursor
    cursor;

  int
    id,
    x,
    y;

  KeySym
    key_symbol;

  Image
    *crop_image;

  double
    scale_factor;

  RectangleInfo
    crop_info,
    highlight_info;

  Quantum
    *q;

  unsigned int
    height,
    width;

  size_t
    state;

  XEvent
    event;

  /*
    Map Command widget.
  */
  switch (mode)
  {
    case CopyMode:
    {
      (void) CloneString(&windows->command.name,"Copy");
      break;
    }
    case CropMode:
    {
      (void) CloneString(&windows->command.name,"Crop");
      break;
    }
    case CutMode:
    {
      (void) CloneString(&windows->command.name,"Cut");
      break;
    }
  }
  RectifyModeMenu[0]=windows->command.name;
  windows->command.data=0;
  (void) XCommandWidget(display,windows,CropModeMenu,(XEvent *) NULL);
  (void) XMapRaised(display,windows->command.id);
  XClientMessage(display,windows->image.id,windows->im_protocols,
    windows->im_update_widget,CurrentTime);
  /*
    Track pointer until button 1 is pressed.
  */
  XQueryPosition(display,windows->image.id,&x,&y);
  (void) XSelectInput(display,windows->image.id,
    windows->image.attributes.event_mask | PointerMotionMask);
  crop_info.x=(ssize_t) windows->image.x+x;
  crop_info.y=(ssize_t) windows->image.y+y;
  crop_info.width=0;
  crop_info.height=0;
  cursor=XCreateFontCursor(display,XC_fleur);
  state=DefaultState;
  do
  {
    if (windows->info.mapped != MagickFalse)
      {
        /*
          Display pointer position.
        */
        (void) FormatLocaleString(text,MagickPathExtent," %+ld%+ld ",
          (long) crop_info.x,(long) crop_info.y);
        XInfoWidget(display,windows,text);
      }
    /*
      Wait for next event.
    */
    XScreenEvent(display,windows,&event,exception);
    if (event.xany.window == windows->command.id)
      {
        /*
          Select a command from the Command widget.
        */
        id=XCommandWidget(display,windows,CropModeMenu,&event);
        if (id < 0)
          continue;
        switch (CropCommands[id])
        {
          case CropHelpCommand:
          {
            switch (mode)
            {
              case CopyMode:
              {
                XTextViewHelp(display,resource_info,windows,MagickFalse,
                  "Help Viewer - Image Copy",ImageCopyHelp);
                break;
              }
              case CropMode:
              {
                XTextViewHelp(display,resource_info,windows,MagickFalse,
                  "Help Viewer - Image Crop",ImageCropHelp);
                break;
              }
              case CutMode:
              {
                XTextViewHelp(display,resource_info,windows,MagickFalse,
                  "Help Viewer - Image Cut",ImageCutHelp);
                break;
              }
            }
            break;
          }
          case CropDismissCommand:
          {
            /*
              Prematurely exit.
            */
            state|=EscapeState;
            state|=ExitState;
            break;
          }
          default:
            break;
        }
        continue;
      }
    switch (event.type)
    {
      case ButtonPress:
      {
        if (event.xbutton.button != Button1)
          break;
        if (event.xbutton.window != windows->image.id)
          break;
        /*
          Note first corner of cropping rectangle-- exit loop.
        */
        (void) XCheckDefineCursor(display,windows->image.id,cursor);
        crop_info.x=(ssize_t) windows->image.x+event.xbutton.x;
        crop_info.y=(ssize_t) windows->image.y+event.xbutton.y;
        state|=ExitState;
        break;
      }
      case ButtonRelease:
        break;
      case Expose:
        break;
      case KeyPress:
      {
        if (event.xkey.window != windows->image.id)
          break;
        /*
          Respond to a user key press.
        */
        (void) XLookupString((XKeyEvent *) &event.xkey,command,(int)
          sizeof(command),&key_symbol,(XComposeStatus *) NULL);
        switch ((int) key_symbol)
        {
          case XK_Escape:
          case XK_F20:
          {
            /*
              Prematurely exit.
            */
            state|=EscapeState;
            state|=ExitState;
            break;
          }
          case XK_F1:
          case XK_Help:
          {
            switch (mode)
            {
              case CopyMode:
              {
                XTextViewHelp(display,resource_info,windows,MagickFalse,
                  "Help Viewer - Image Copy",ImageCopyHelp);
                break;
              }
              case CropMode:
              {
                XTextViewHelp(display,resource_info,windows,MagickFalse,
                  "Help Viewer - Image Crop",ImageCropHelp);
                break;
              }
              case CutMode:
              {
                XTextViewHelp(display,resource_info,windows,MagickFalse,
                  "Help Viewer - Image Cut",ImageCutHelp);
                break;
              }
            }
            break;
          }
          default:
          {
            (void) XBell(display,0);
            break;
          }
        }
        break;
      }
      case MotionNotify:
      {
        if (event.xmotion.window != windows->image.id)
          break;
        /*
          Map and unmap Info widget as text cursor crosses its boundaries.
        */
        x=event.xmotion.x;
        y=event.xmotion.y;
        if (windows->info.mapped != MagickFalse)
          {
            if ((x < (int) (windows->info.x+windows->info.width)) &&
                (y < (int) (windows->info.y+windows->info.height)))
              (void) XWithdrawWindow(display,windows->info.id,
                windows->info.screen);
          }
        else
          if ((x > (int) (windows->info.x+windows->info.width)) ||
              (y > (int) (windows->info.y+windows->info.height)))
            (void) XMapWindow(display,windows->info.id);
        crop_info.x=(ssize_t) windows->image.x+x;
        crop_info.y=(ssize_t) windows->image.y+y;
        break;
      }
      default:
        break;
    }
  } while ((state & ExitState) == 0);
  (void) XSelectInput(display,windows->image.id,
    windows->image.attributes.event_mask);
  if ((state & EscapeState) != 0)
    {
      /*
        User want to exit without cropping.
      */
      (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
      (void) XFreeCursor(display,cursor);
      return(MagickTrue);
    }
  (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
  do
  {
    /*
      Size rectangle as pointer moves until the mouse button is released.
    */
    x=(int) crop_info.x;
    y=(int) crop_info.y;
    crop_info.width=0;
    crop_info.height=0;
    state=DefaultState;
    do
    {
      highlight_info=crop_info;
      highlight_info.x=crop_info.x-windows->image.x;
      highlight_info.y=crop_info.y-windows->image.y;
      if ((highlight_info.width > 3) && (highlight_info.height > 3))
        {
          /*
            Display info and draw cropping rectangle.
          */
          if (windows->info.mapped == MagickFalse)
            (void) XMapWindow(display,windows->info.id);
          (void) FormatLocaleString(text,MagickPathExtent,
            " %.20gx%.20g%+.20g%+.20g",(double) crop_info.width,(double)
            crop_info.height,(double) crop_info.x,(double) crop_info.y);
          XInfoWidget(display,windows,text);
          XHighlightRectangle(display,windows->image.id,
            windows->image.highlight_context,&highlight_info);
        }
      else
        if (windows->info.mapped != MagickFalse)
          (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
      /*
        Wait for next event.
      */
      XScreenEvent(display,windows,&event,exception);
      if ((highlight_info.width > 3) && (highlight_info.height > 3))
        XHighlightRectangle(display,windows->image.id,
          windows->image.highlight_context,&highlight_info);
      switch (event.type)
      {
        case ButtonPress:
        {
          crop_info.x=(ssize_t) windows->image.x+event.xbutton.x;
          crop_info.y=(ssize_t) windows->image.y+event.xbutton.y;
          break;
        }
        case ButtonRelease:
        {
          /*
            User has committed to cropping rectangle.
          */
          crop_info.x=(ssize_t) windows->image.x+event.xbutton.x;
          crop_info.y=(ssize_t) windows->image.y+event.xbutton.y;
          XSetCursorState(display,windows,MagickFalse);
          state|=ExitState;
          windows->command.data=0;
          (void) XCommandWidget(display,windows,RectifyModeMenu,
            (XEvent *) NULL);
          break;
        }
        case Expose:
          break;
        case MotionNotify:
        {
          crop_info.x=(ssize_t) windows->image.x+event.xmotion.x;
          crop_info.y=(ssize_t) windows->image.y+event.xmotion.y;
        }
        default:
          break;
      }
      if ((((int) crop_info.x != x) && ((int) crop_info.y != y)) ||
          ((state & ExitState) != 0))
        {
          /*
            Check boundary conditions.
          */
          if (crop_info.x < 0)
            crop_info.x=0;
          else
            if (crop_info.x > (ssize_t) windows->image.ximage->width)
              crop_info.x=(ssize_t) windows->image.ximage->width;
          if ((int) crop_info.x < x)
            crop_info.width=(unsigned int) (x-crop_info.x);
          else
            {
              crop_info.width=(unsigned int) (crop_info.x-x);
              crop_info.x=(ssize_t) x;
            }
          if (crop_info.y < 0)
            crop_info.y=0;
          else
            if (crop_info.y > (ssize_t) windows->image.ximage->height)
              crop_info.y=(ssize_t) windows->image.ximage->height;
          if ((int) crop_info.y < y)
            crop_info.height=(unsigned int) (y-crop_info.y);
          else
            {
              crop_info.height=(unsigned int) (crop_info.y-y);
              crop_info.y=(ssize_t) y;
            }
        }
    } while ((state & ExitState) == 0);
    /*
      Wait for user to grab a corner of the rectangle or press return.
    */
    state=DefaultState;
    (void) XMapWindow(display,windows->info.id);
    do
    {
      if (windows->info.mapped != MagickFalse)
        {
          /*
            Display pointer position.
          */
          (void) FormatLocaleString(text,MagickPathExtent,
            " %.20gx%.20g%+.20g%+.20g",(double) crop_info.width,(double)
            crop_info.height,(double) crop_info.x,(double) crop_info.y);
          XInfoWidget(display,windows,text);
        }
      highlight_info=crop_info;
      highlight_info.x=crop_info.x-windows->image.x;
      highlight_info.y=crop_info.y-windows->image.y;
      if ((highlight_info.width <= 3) || (highlight_info.height <= 3))
        {
          state|=EscapeState;
          state|=ExitState;
          break;
        }
      XHighlightRectangle(display,windows->image.id,
        windows->image.highlight_context,&highlight_info);
      XScreenEvent(display,windows,&event,exception);
      if (event.xany.window == windows->command.id)
        {
          /*
            Select a command from the Command widget.
          */
          (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
          id=XCommandWidget(display,windows,RectifyModeMenu,&event);
          (void) XSetFunction(display,windows->image.highlight_context,
            GXinvert);
          XHighlightRectangle(display,windows->image.id,
            windows->image.highlight_context,&highlight_info);
          if (id >= 0)
            switch (RectifyCommands[id])
            {
              case RectifyCopyCommand:
              {
                state|=ExitState;
                break;
              }
              case RectifyHelpCommand:
              {
                (void) XSetFunction(display,windows->image.highlight_context,
                  GXcopy);
                switch (mode)
                {
                  case CopyMode:
                  {
                    XTextViewHelp(display,resource_info,windows,MagickFalse,
                      "Help Viewer - Image Copy",ImageCopyHelp);
                    break;
                  }
                  case CropMode:
                  {
                    XTextViewHelp(display,resource_info,windows,MagickFalse,
                      "Help Viewer - Image Crop",ImageCropHelp);
                    break;
                  }
                  case CutMode:
                  {
                    XTextViewHelp(display,resource_info,windows,MagickFalse,
                      "Help Viewer - Image Cut",ImageCutHelp);
                    break;
                  }
                }
                (void) XSetFunction(display,windows->image.highlight_context,
                  GXinvert);
                break;
              }
              case RectifyDismissCommand:
              {
                /*
                  Prematurely exit.
                */
                state|=EscapeState;
                state|=ExitState;
                break;
              }
              default:
                break;
            }
          continue;
        }
      XHighlightRectangle(display,windows->image.id,
        windows->image.highlight_context,&highlight_info);
      switch (event.type)
      {
        case ButtonPress:
        {
          if (event.xbutton.button != Button1)
            break;
          if (event.xbutton.window != windows->image.id)
            break;
          x=windows->image.x+event.xbutton.x;
          y=windows->image.y+event.xbutton.y;
          if ((x < (int) (crop_info.x+RoiDelta)) &&
              (x > (int) (crop_info.x-RoiDelta)) &&
              (y < (int) (crop_info.y+RoiDelta)) &&
              (y > (int) (crop_info.y-RoiDelta)))
            {
              crop_info.x=(ssize_t) (crop_info.x+crop_info.width);
              crop_info.y=(ssize_t) (crop_info.y+crop_info.height);
              state|=UpdateConfigurationState;
              break;
            }
          if ((x < (int) (crop_info.x+RoiDelta)) &&
              (x > (int) (crop_info.x-RoiDelta)) &&
              (y < (int) (crop_info.y+crop_info.height+RoiDelta)) &&
              (y > (int) (crop_info.y+crop_info.height-RoiDelta)))
            {
              crop_info.x=(ssize_t) (crop_info.x+crop_info.width);
              state|=UpdateConfigurationState;
              break;
            }
          if ((x < (int) (crop_info.x+crop_info.width+RoiDelta)) &&
              (x > (int) (crop_info.x+crop_info.width-RoiDelta)) &&
              (y < (int) (crop_info.y+RoiDelta)) &&
              (y > (int) (crop_info.y-RoiDelta)))
            {
              crop_info.y=(ssize_t) (crop_info.y+crop_info.height);
              state|=UpdateConfigurationState;
              break;
            }
          if ((x < (int) (crop_info.x+crop_info.width+RoiDelta)) &&
              (x > (int) (crop_info.x+crop_info.width-RoiDelta)) &&
              (y < (int) (crop_info.y+crop_info.height+RoiDelta)) &&
              (y > (int) (crop_info.y+crop_info.height-RoiDelta)))
            {
              state|=UpdateConfigurationState;
              break;
            }
        }
        case ButtonRelease:
        {
          if (event.xbutton.window == windows->pan.id)
            if ((highlight_info.x != crop_info.x-windows->image.x) ||
                (highlight_info.y != crop_info.y-windows->image.y))
              XHighlightRectangle(display,windows->image.id,
                windows->image.highlight_context,&highlight_info);
          (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id,
            event.xbutton.time);
          break;
        }
        case Expose:
        {
          if (event.xexpose.window == windows->image.id)
            if (event.xexpose.count == 0)
              {
                event.xexpose.x=(int) highlight_info.x;
                event.xexpose.y=(int) highlight_info.y;
                event.xexpose.width=(int) highlight_info.width;
                event.xexpose.height=(int) highlight_info.height;
                XRefreshWindow(display,&windows->image,&event);
              }
          if (event.xexpose.window == windows->info.id)
            if (event.xexpose.count == 0)
              XInfoWidget(display,windows,text);
          break;
        }
        case KeyPress:
        {
          if (event.xkey.window != windows->image.id)
            break;
          /*
            Respond to a user key press.
          */
          (void) XLookupString((XKeyEvent *) &event.xkey,command,(int)
            sizeof(command),&key_symbol,(XComposeStatus *) NULL);
          switch ((int) key_symbol)
          {
            case XK_Escape:
            case XK_F20:
              state|=EscapeState;
            case XK_Return:
            {
              state|=ExitState;
              break;
            }
            case XK_Home:
            case XK_KP_Home:
            {
              crop_info.x=(ssize_t) (windows->image.width/2L-crop_info.width/
                2L);
              crop_info.y=(ssize_t) (windows->image.height/2L-crop_info.height/
                2L);
              break;
            }
            case XK_Left:
            case XK_KP_Left:
            {
              crop_info.x--;
              break;
            }
            case XK_Up:
            case XK_KP_Up:
            case XK_Next:
            {
              crop_info.y--;
              break;
            }
            case XK_Right:
            case XK_KP_Right:
            {
              crop_info.x++;
              break;
            }
            case XK_Prior:
            case XK_Down:
            case XK_KP_Down:
            {
              crop_info.y++;
              break;
            }
            case XK_F1:
            case XK_Help:
            {
              (void) XSetFunction(display,windows->image.highlight_context,
                GXcopy);
              switch (mode)
              {
                case CopyMode:
                {
                  XTextViewHelp(display,resource_info,windows,MagickFalse,
                    "Help Viewer - Image Copy",ImageCopyHelp);
                  break;
                }
                case CropMode:
                {
                  XTextViewHelp(display,resource_info,windows,MagickFalse,
                    "Help Viewer - Image Cropg",ImageCropHelp);
                  break;
                }
                case CutMode:
                {
                  XTextViewHelp(display,resource_info,windows,MagickFalse,
                    "Help Viewer - Image Cutg",ImageCutHelp);
                  break;
                }
              }
              (void) XSetFunction(display,windows->image.highlight_context,
                GXinvert);
              break;
            }
            default:
            {
              (void) XBell(display,0);
              break;
            }
          }
          (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id,
            event.xkey.time);
          break;
        }
        case KeyRelease:
          break;
        case MotionNotify:
        {
          if (event.xmotion.window != windows->image.id)
            break;
          /*
            Map and unmap Info widget as text cursor crosses its boundaries.
          */
          x=event.xmotion.x;
          y=event.xmotion.y;
          if (windows->info.mapped != MagickFalse)
            {
              if ((x < (int) (windows->info.x+windows->info.width)) &&
                  (y < (int) (windows->info.y+windows->info.height)))
                (void) XWithdrawWindow(display,windows->info.id,
                  windows->info.screen);
            }
          else
            if ((x > (int) (windows->info.x+windows->info.width)) ||
                (y > (int) (windows->info.y+windows->info.height)))
              (void) XMapWindow(display,windows->info.id);
          crop_info.x=(ssize_t) windows->image.x+event.xmotion.x;
          crop_info.y=(ssize_t) windows->image.y+event.xmotion.y;
          break;
        }
        case SelectionRequest:
        {
          XSelectionEvent
            notify;

          XSelectionRequestEvent
            *request;

          /*
            Set primary selection.
          */
          (void) FormatLocaleString(text,MagickPathExtent,
            "%.20gx%.20g%+.20g%+.20g",(double) crop_info.width,(double)
            crop_info.height,(double) crop_info.x,(double) crop_info.y);
          request=(&(event.xselectionrequest));
          (void) XChangeProperty(request->display,request->requestor,
            request->property,request->target,8,PropModeReplace,
            (unsigned char *) text,(int) strlen(text));
          notify.type=SelectionNotify;
          notify.display=request->display;
          notify.requestor=request->requestor;
          notify.selection=request->selection;
          notify.target=request->target;
          notify.time=request->time;
          if (request->property == None)
            notify.property=request->target;
          else
            notify.property=request->property;
          (void) XSendEvent(request->display,request->requestor,False,0,
            (XEvent *) &notify);
        }
        default:
          break;
      }
      if ((state & UpdateConfigurationState) != 0)
        {
          (void) XPutBackEvent(display,&event);
          (void) XCheckDefineCursor(display,windows->image.id,cursor);
          break;
        }
    } while ((state & ExitState) == 0);
  } while ((state & ExitState) == 0);
  (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
  XSetCursorState(display,windows,MagickFalse);
  if ((state & EscapeState) != 0)
    return(MagickTrue);
  if (mode == CropMode)
    if (((int) crop_info.width != windows->image.ximage->width) ||
        ((int) crop_info.height != windows->image.ximage->height))
      {
        /*
          Reconfigure Image window as defined by cropping rectangle.
        */
        XSetCropGeometry(display,windows,&crop_info,image);
        windows->image.window_changes.width=(int) crop_info.width;
        windows->image.window_changes.height=(int) crop_info.height;
        (void) XConfigureImage(display,resource_info,windows,image,exception);
        return(MagickTrue);
      }
  /*
    Copy image before applying image transforms.
  */
  XSetCursorState(display,windows,MagickTrue);
  XCheckRefreshWindows(display,windows);
  width=(unsigned int) image->columns;
  height=(unsigned int) image->rows;
  x=0;
  y=0;
  if (windows->image.crop_geometry != (char *) NULL)
    (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
  scale_factor=(double) width/windows->image.ximage->width;
  crop_info.x+=x;
  crop_info.x=(ssize_t) (scale_factor*crop_info.x+0.5);
  crop_info.width=(unsigned int) (scale_factor*crop_info.width+0.5);
  scale_factor=(double) height/windows->image.ximage->height;
  crop_info.y+=y;
  crop_info.y=(ssize_t) (scale_factor*crop_info.y+0.5);
  crop_info.height=(unsigned int) (scale_factor*crop_info.height+0.5);
  crop_info.x+=image->page.x;
  crop_info.y+=image->page.y;
  crop_image=CropImage(image,&crop_info,exception);
  XSetCursorState(display,windows,MagickFalse);
  if (crop_image == (Image *) NULL)
    return(MagickFalse);
  if (resource_info->copy_image != (Image *) NULL)
    resource_info->copy_image=DestroyImage(resource_info->copy_image);
  resource_info->copy_image=crop_image;
  if (mode == CopyMode)
    {
      (void) XConfigureImage(display,resource_info,windows,image,exception);
      return(MagickTrue);
    }
  /*
    Cut image.
  */
  if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
    return(MagickFalse);
  image->alpha_trait=BlendPixelTrait;
  image_view=AcquireAuthenticCacheView(image,exception);
  for (y=0; y < (int) crop_info.height; y++)
  {
    q=GetCacheViewAuthenticPixels(image_view,crop_info.x,y+crop_info.y,
      crop_info.width,1,exception);
    if (q == (Quantum *) NULL)
      break;
    for (x=0; x < (int) crop_info.width; x++)
    {
      SetPixelAlpha(image,TransparentAlpha,q);
      q+=GetPixelChannels(image);
    }
    if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
      break;
  }
  image_view=DestroyCacheView(image_view);
  /*
    Update image configuration.
  */
  XConfigureImageColormap(display,resource_info,windows,image,exception);
  (void) XConfigureImage(display,resource_info,windows,image,exception);
  return(MagickTrue);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X D r a w I m a g e                                                       %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XDrawEditImage() draws a graphic element (point, line, rectangle, etc.) on
%  the image.
%
%  The format of the XDrawEditImage method is:
%
%      MagickBooleanType XDrawEditImage(Display *display,
%        XResourceInfo *resource_info,XWindows *windows,Image **image,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o display: Specifies a connection to an X server; returned from
%      XOpenDisplay.
%
%    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
%
%    o windows: Specifies a pointer to a XWindows structure.
%
%    o image: the image.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static MagickBooleanType XDrawEditImage(Display *display,
  XResourceInfo *resource_info,XWindows *windows,Image **image,
  ExceptionInfo *exception)
{
  const char
    *const DrawMenu[] =
    {
      "Element",
      "Color",
      "Stipple",
      "Width",
      "Undo",
      "Help",
      "Dismiss",
      (char *) NULL
    };

  static ElementType
    element = PointElement;

  static const ModeType
    DrawCommands[] =
    {
      DrawElementCommand,
      DrawColorCommand,
      DrawStippleCommand,
      DrawWidthCommand,
      DrawUndoCommand,
      DrawHelpCommand,
      DrawDismissCommand
    };

  static Pixmap
    stipple = (Pixmap) NULL;

  static unsigned int
    pen_id = 0,
    line_width = 1;

  char
    command[MagickPathExtent],
    text[MagickPathExtent];

  Cursor
    cursor;

  int
    entry,
    id,
    number_coordinates,
    x,
    y;

  double
    degrees;

  MagickStatusType
    status;

  RectangleInfo
    rectangle_info;

  int
    i;

  unsigned int
    distance,
    height,
    max_coordinates,
    width;

  size_t
    state;

  Window
    root_window;

  XDrawInfo
    draw_info;

  XEvent
    event;

  XPoint
    *coordinate_info;

  XSegment
    line_info;

  /*
    Allocate polygon info.
  */
  max_coordinates=2048;
  coordinate_info=(XPoint *) AcquireQuantumMemory((size_t) max_coordinates,
    sizeof(*coordinate_info));
  if (coordinate_info == (XPoint *) NULL)
    {
      (void) ThrowMagickException(exception,GetMagickModule(),
        ResourceLimitError,"MemoryAllocationFailed","`%s'","...");
      return(MagickFalse);
    }
  /*
    Map Command widget.
  */
  (void) CloneString(&windows->command.name,"Draw");
  windows->command.data=4;
  (void) XCommandWidget(display,windows,DrawMenu,(XEvent *) NULL);
  (void) XMapRaised(display,windows->command.id);
  XClientMessage(display,windows->image.id,windows->im_protocols,
    windows->im_update_widget,CurrentTime);
  /*
    Wait for first button press.
  */
  root_window=XRootWindow(display,XDefaultScreen(display));
  draw_info.stencil=OpaqueStencil;
  status=MagickTrue;
  cursor=XCreateFontCursor(display,XC_tcross);
  for ( ; ; )
  {
    XQueryPosition(display,windows->image.id,&x,&y);
    (void) XSelectInput(display,windows->image.id,
      windows->image.attributes.event_mask | PointerMotionMask);
    (void) XCheckDefineCursor(display,windows->image.id,cursor);
    state=DefaultState;
    do
    {
      if (windows->info.mapped != MagickFalse)
        {
          /*
            Display pointer position.
          */
          (void) FormatLocaleString(text,MagickPathExtent," %+d%+d ",
            x+windows->image.x,y+windows->image.y);
          XInfoWidget(display,windows,text);
        }
      /*
        Wait for next event.
      */
      XScreenEvent(display,windows,&event,exception);
      if (event.xany.window == windows->command.id)
        {
          /*
            Select a command from the Command widget.
          */
          id=XCommandWidget(display,windows,DrawMenu,&event);
          if (id < 0)
            continue;
          switch (DrawCommands[id])
          {
            case DrawElementCommand:
            {
              const char
                *const Elements[] =
                {
                  "point",
                  "line",
                  "rectangle",
                  "fill rectangle",
                  "circle",
                  "fill circle",
                  "ellipse",
                  "fill ellipse",
                  "polygon",
                  "fill polygon",
                  (char *) NULL,
                };

              /*
                Select a command from the pop-up menu.
              */
              element=(ElementType) (XMenuWidget(display,windows,
                DrawMenu[id],Elements,command)+1);
              break;
            }
            case DrawColorCommand:
            {
              const char
                *ColorMenu[MaxNumberPens+1];

              int
                pen_number;

              MagickBooleanType
                transparent;

              XColor
                color;

              /*
                Initialize menu selections.
              */
              for (i=0; i < (int) (MaxNumberPens-2); i++)
                ColorMenu[i]=resource_info->pen_colors[i];
              ColorMenu[MaxNumberPens-2]="transparent";
              ColorMenu[MaxNumberPens-1]="Browser...";
              ColorMenu[MaxNumberPens]=(char *) NULL;
              /*
                Select a pen color from the pop-up menu.
              */
              pen_number=XMenuWidget(display,windows,DrawMenu[id],
                (const char **) ColorMenu,command);
              if (pen_number < 0)
                break;
              transparent=pen_number == (MaxNumberPens-2) ? MagickTrue :
                MagickFalse;
              if (transparent != MagickFalse)
                {
                  draw_info.stencil=TransparentStencil;
                  break;
                }
              if (pen_number == (MaxNumberPens-1))
                {
                  static char
                    color_name[MagickPathExtent] = "gray";

                  /*
                    Select a pen color from a dialog.
                  */
                  resource_info->pen_colors[pen_number]=color_name;
                  XColorBrowserWidget(display,windows,"Select",color_name);
                  if (*color_name == '\0')
                    break;
                }
              /*
                Set pen color.
              */
              (void) XParseColor(display,windows->map_info->colormap,
                resource_info->pen_colors[pen_number],&color);
              XBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
                (unsigned int) MaxColors,&color);
              windows->pixel_info->pen_colors[pen_number]=color;
              pen_id=(unsigned int) pen_number;
              draw_info.stencil=OpaqueStencil;
              break;
            }
            case DrawStippleCommand:
            {
              const char
                *StipplesMenu[] =
                {
                  "Brick",
                  "Diagonal",
                  "Scales",
                  "Vertical",
                  "Wavy",
                  "Translucent",
                  "Opaque",
                  (char *) NULL,
                  (char *) NULL,
                };

              Image
                *stipple_image;

              ImageInfo
                *image_info;

              int
                status;

              static char
                filename[MagickPathExtent] = "\0";

              /*
                Select a command from the pop-up menu.
              */
              StipplesMenu[7]="Open...";
              entry=XMenuWidget(display,windows,DrawMenu[id],StipplesMenu,
                command);
              if (entry < 0)
                break;
              if (stipple != (Pixmap) NULL)
                (void) XFreePixmap(display,stipple);
              stipple=(Pixmap) NULL;
              if (entry != 7)
                {
                  switch (entry)
                  {
                    case 0:
                    {
                      stipple=XCreateBitmapFromData(display,root_window,
                        (char *) BricksBitmap,BricksWidth,BricksHeight);
                      break;
                    }
                    case 1:
                    {
                      stipple=XCreateBitmapFromData(display,root_window,
                        (char *) DiagonalBitmap,DiagonalWidth,DiagonalHeight);
                      break;
                    }
                    case 2:
                    {
                      stipple=XCreateBitmapFromData(display,root_window,
                        (char *) ScalesBitmap,ScalesWidth,ScalesHeight);
                      break;
                    }
                    case 3:
                    {
                      stipple=XCreateBitmapFromData(display,root_window,
                        (char *) VerticalBitmap,VerticalWidth,VerticalHeight);
                      break;
                    }
                    case 4:
                    {
                      stipple=XCreateBitmapFromData(display,root_window,
                        (char *) WavyBitmap,WavyWidth,WavyHeight);
                      break;
                    }
                    case 5:
                    {
                      stipple=XCreateBitmapFromData(display,root_window,
                        (char *) HighlightBitmap,HighlightWidth,
                        HighlightHeight);
                      break;
                    }
                    case 6:
                    default:
                    {
                      stipple=XCreateBitmapFromData(display,root_window,
                        (char *) OpaqueBitmap,OpaqueWidth,OpaqueHeight);
                      break;
                    }
                  }
                  break;
                }
              XFileBrowserWidget(display,windows,"Stipple",filename);
              if (*filename == '\0')
                break;
              /*
                Read image.
              */
              XSetCursorState(display,windows,MagickTrue);
              XCheckRefreshWindows(display,windows);
              image_info=AcquireImageInfo();
              (void) CopyMagickString(image_info->filename,filename,
                MagickPathExtent);
              stipple_image=ReadImage(image_info,exception);
              CatchException(exception);
              XSetCursorState(display,windows,MagickFalse);
              if (stipple_image == (Image *) NULL)
                break;
              (void) AcquireUniqueFileResource(filename);
              (void) FormatLocaleString(stipple_image->filename,
                MagickPathExtent,"xbm:%s",filename);
              (void) WriteImage(image_info,stipple_image,exception);
              stipple_image=DestroyImage(stipple_image);
              image_info=DestroyImageInfo(image_info);
              status=XReadBitmapFile(display,root_window,filename,&width,
                &height,&stipple,&x,&y);
              (void) RelinquishUniqueFileResource(filename);
              if ((status != BitmapSuccess) != 0)
                XNoticeWidget(display,windows,"Unable to read X bitmap image:",
                  filename);
              break;
            }
            case DrawWidthCommand:
            {
              const char
                *const WidthsMenu[] =
                {
                  "1",
                  "2",
                  "4",
                  "8",
                  "16",
                  "Dialog...",
                  (char *) NULL,
                };

              static char
                width[MagickPathExtent] = "0";

              /*
                Select a command from the pop-up menu.
              */
              entry=XMenuWidget(display,windows,DrawMenu[id],WidthsMenu,
                command);
              if (entry < 0)
                break;
              if (entry != 5)
                {
                  line_width=(unsigned int) StringToUnsignedLong(
                    WidthsMenu[entry]);
                  break;
                }
              (void) XDialogWidget(display,windows,"Ok","Enter line width:",
                width);
              if (*width == '\0')
                break;
              line_width=(unsigned int) StringToUnsignedLong(width);
              break;
            }
            case DrawUndoCommand:
            {
              (void) XMagickCommand(display,resource_info,windows,UndoCommand,
                image,exception);
              break;
            }
            case DrawHelpCommand:
            {
              XTextViewHelp(display,resource_info,windows,MagickFalse,
                "Help Viewer - Image Rotation",ImageDrawHelp);
              (void) XCheckDefineCursor(display,windows->image.id,cursor);
              break;
            }
            case DrawDismissCommand:
            {
              /*
                Prematurely exit.
              */
              state|=EscapeState;
              state|=ExitState;
              break;
            }
            default:
              break;
          }
          (void) XCheckDefineCursor(display,windows->image.id,cursor);
          continue;
        }
      switch (event.type)
      {
        case ButtonPress:
        {
          if (event.xbutton.button != Button1)
            break;
          if (event.xbutton.window != windows->image.id)
            break;
          /*
            exit loop.
          */
          x=event.xbutton.x;
          y=event.xbutton.y;
          state|=ExitState;
          break;
        }
        case ButtonRelease:
          break;
        case Expose:
          break;
        case KeyPress:
        {
          KeySym
            key_symbol;

          if (event.xkey.window != windows->image.id)
            break;
          /*
            Respond to a user key press.
          */
          (void) XLookupString((XKeyEvent *) &event.xkey,command,(int)
            sizeof(command),&key_symbol,(XComposeStatus *) NULL);
          switch ((int) key_symbol)
          {
            case XK_Escape:
            case XK_F20:
            {
              /*
                Prematurely exit.
              */
              state|=EscapeState;
              state|=ExitState;
              break;
            }
            case XK_F1:
            case XK_Help:
            {
              XTextViewHelp(display,resource_info,windows,MagickFalse,
                "Help Viewer - Image Rotation",ImageDrawHelp);
              break;
            }
            default:
            {
              (void) XBell(display,0);
              break;
            }
          }
          break;
        }
        case MotionNotify:
        {
          /*
            Map and unmap Info widget as text cursor crosses its boundaries.
          */
          x=event.xmotion.x;
          y=event.xmotion.y;
          if (windows->info.mapped != MagickFalse)
            {
              if ((x < (int) (windows->info.x+windows->info.width)) &&
                  (y < (int) (windows->info.y+windows->info.height)))
                (void) XWithdrawWindow(display,windows->info.id,
                  windows->info.screen);
            }
          else
            if ((x > (int) (windows->info.x+windows->info.width)) ||
                (y > (int) (windows->info.y+windows->info.height)))
              (void) XMapWindow(display,windows->info.id);
          break;
        }
      }
    } while ((state & ExitState) == 0);
    (void) XSelectInput(display,windows->image.id,
      windows->image.attributes.event_mask);
    (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
    if ((state & EscapeState) != 0)
      break;
    /*
      Draw element as pointer moves until the button is released.
    */
    distance=0;
    degrees=0.0;
    line_info.x1=x;
    line_info.y1=y;
    line_info.x2=x;
    line_info.y2=y;
    rectangle_info.x=(ssize_t) x;
    rectangle_info.y=(ssize_t) y;
    rectangle_info.width=0;
    rectangle_info.height=0;
    number_coordinates=1;
    coordinate_info->x=x;
    coordinate_info->y=y;
    (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
    state=DefaultState;
    do
    {
      switch (element)
      {
        case PointElement:
        default:
        {
          if (number_coordinates > 1)
            {
              (void) XDrawLines(display,windows->image.id,
                windows->image.highlight_context,coordinate_info,
                number_coordinates,CoordModeOrigin);
              (void) FormatLocaleString(text,MagickPathExtent," %+d%+d",
                coordinate_info[number_coordinates-1].x,
                coordinate_info[number_coordinates-1].y);
              XInfoWidget(display,windows,text);
            }
          break;
        }
        case LineElement:
        {
          if (distance > 9)
            {
              /*
                Display angle of the line.
              */
              degrees=RadiansToDegrees(-atan2((double) (line_info.y2-
                line_info.y1),(double) (line_info.x2-line_info.x1)));
              (void) FormatLocaleString(text,MagickPathExtent," %g",
                (double) degrees);
              XInfoWidget(display,windows,text);
              XHighlightLine(display,windows->image.id,
                windows->image.highlight_context,&line_info);
            }
          else
            if (windows->info.mapped != MagickFalse)
              (void) XWithdrawWindow(display,windows->info.id,
                windows->info.screen);
          break;
        }
        case RectangleElement:
        case FillRectangleElement:
        {
          if ((rectangle_info.width > 3) && (rectangle_info.height > 3))
            {
              /*
                Display info and draw drawing rectangle.
              */
              (void) FormatLocaleString(text,MagickPathExtent,
                " %.20gx%.20g%+.20g%+.20g",(double) rectangle_info.width,
                (double) rectangle_info.height,(double) rectangle_info.x,
                (double) rectangle_info.y);
              XInfoWidget(display,windows,text);
              XHighlightRectangle(display,windows->image.id,
                windows->image.highlight_context,&rectangle_info);
            }
          else
            if (windows->info.mapped != MagickFalse)
              (void) XWithdrawWindow(display,windows->info.id,
                windows->info.screen);
          break;
        }
        case CircleElement:
        case FillCircleElement:
        case EllipseElement:
        case FillEllipseElement:
        {
          if ((rectangle_info.width > 3) && (rectangle_info.height > 3))
            {
              /*
                Display info and draw drawing rectangle.
              */
              (void) FormatLocaleString(text,MagickPathExtent,
                " %.20gx%.20g%+.20g%+.20g",(double) rectangle_info.width,
                (double) rectangle_info.height,(double) rectangle_info.x,
                (double) rectangle_info.y);
              XInfoWidget(display,windows,text);
              XHighlightEllipse(display,windows->image.id,
                windows->image.highlight_context,&rectangle_info);
            }
          else
            if (windows->info.mapped != MagickFalse)
              (void) XWithdrawWindow(display,windows->info.id,
                windows->info.screen);
          break;
        }
        case PolygonElement:
        case FillPolygonElement:
        {
          if (number_coordinates > 1)
            (void) XDrawLines(display,windows->image.id,
              windows->image.highlight_context,coordinate_info,
              number_coordinates,CoordModeOrigin);
          if (distance > 9)
            {
              /*
                Display angle of the line.
              */
              degrees=RadiansToDegrees(-atan2((double) (line_info.y2-
                line_info.y1),(double) (line_info.x2-line_info.x1)));
              (void) FormatLocaleString(text,MagickPathExtent," %g",
                (double) degrees);
              XInfoWidget(display,windows,text);
              XHighlightLine(display,windows->image.id,
                windows->image.highlight_context,&line_info);
            }
          else
            if (windows->info.mapped != MagickFalse)
              (void) XWithdrawWindow(display,windows->info.id,
                windows->info.screen);
          break;
        }
      }
      /*
        Wait for next event.
      */
      XScreenEvent(display,windows,&event,exception);
      switch (element)
      {
        case PointElement:
        default:
        {
          if (number_coordinates > 1)
            (void) XDrawLines(display,windows->image.id,
              windows->image.highlight_context,coordinate_info,
              number_coordinates,CoordModeOrigin);
          break;
        }
        case LineElement:
        {
          if (distance > 9)
            XHighlightLine(display,windows->image.id,
              windows->image.highlight_context,&line_info);
          break;
        }
        case RectangleElement:
        case FillRectangleElement:
        {
          if ((rectangle_info.width > 3) && (rectangle_info.height > 3))
            XHighlightRectangle(display,windows->image.id,
              windows->image.highlight_context,&rectangle_info);
          break;
        }
        case CircleElement:
        case FillCircleElement:
        case EllipseElement:
        case FillEllipseElement:
        {
          if ((rectangle_info.width > 3) && (rectangle_info.height > 3))
            XHighlightEllipse(display,windows->image.id,
              windows->image.highlight_context,&rectangle_info);
          break;
        }
        case PolygonElement:
        case FillPolygonElement:
        {
          if (number_coordinates > 1)
            (void) XDrawLines(display,windows->image.id,
              windows->image.highlight_context,coordinate_info,
              number_coordinates,CoordModeOrigin);
          if (distance > 9)
            XHighlightLine(display,windows->image.id,
              windows->image.highlight_context,&line_info);
          break;
        }
      }
      switch (event.type)
      {
        case ButtonPress:
          break;
        case ButtonRelease:
        {
          /*
            User has committed to element.
          */
          line_info.x2=event.xbutton.x;
          line_info.y2=event.xbutton.y;
          rectangle_info.x=(ssize_t) event.xbutton.x;
          rectangle_info.y=(ssize_t) event.xbutton.y;
          coordinate_info[number_coordinates].x=event.xbutton.x;
          coordinate_info[number_coordinates].y=event.xbutton.y;
          if (((element != PolygonElement) &&
               (element != FillPolygonElement)) || (distance <= 9))
            {
              state|=ExitState;
              break;
            }
          number_coordinates++;
          if (number_coordinates < (int) max_coordinates)
            {
              line_info.x1=event.xbutton.x;
              line_info.y1=event.xbutton.y;
              break;
            }
          max_coordinates<<=1;
          coordinate_info=(XPoint *) ResizeQuantumMemory(coordinate_info,
            max_coordinates,sizeof(*coordinate_info));
          if (coordinate_info == (XPoint *) NULL)
            (void) ThrowMagickException(exception,GetMagickModule(),
              ResourceLimitError,"MemoryAllocationFailed","`%s'","...");
          break;
        }
        case Expose:
          break;
        case MotionNotify:
        {
          if (event.xmotion.window != windows->image.id)
            break;
          if (element != PointElement)
            {
              line_info.x2=event.xmotion.x;
              line_info.y2=event.xmotion.y;
              rectangle_info.x=(ssize_t) event.xmotion.x;
              rectangle_info.y=(ssize_t) event.xmotion.y;
              break;
            }
          coordinate_info[number_coordinates].x=event.xbutton.x;
          coordinate_info[number_coordinates].y=event.xbutton.y;
          number_coordinates++;
          if (number_coordinates < (int) max_coordinates)
            break;
          max_coordinates<<=1;
          coordinate_info=(XPoint *) ResizeQuantumMemory(coordinate_info,
            max_coordinates,sizeof(*coordinate_info));
          if (coordinate_info == (XPoint *) NULL)
            (void) ThrowMagickException(exception,GetMagickModule(),
              ResourceLimitError,"MemoryAllocationFailed","`%s'","...");
          break;
        }
        default:
          break;
      }
      /*
        Check boundary conditions.
      */
      if (line_info.x2 < 0)
        line_info.x2=0;
      else
        if (line_info.x2 > (int) windows->image.width)
          line_info.x2=(short) windows->image.width;
      if (line_info.y2 < 0)
        line_info.y2=0;
      else
        if (line_info.y2 > (int) windows->image.height)
          line_info.y2=(short) windows->image.height;
      distance=(unsigned int)
        (((line_info.x2-line_info.x1+1)*(line_info.x2-line_info.x1+1))+
         ((line_info.y2-line_info.y1+1)*(line_info.y2-line_info.y1+1)));
      if ((((int) rectangle_info.x != x) && ((int) rectangle_info.y != y)) ||
          ((state & ExitState) != 0))
        {
          if (rectangle_info.x < 0)
            rectangle_info.x=0;
          else
            if (rectangle_info.x > (ssize_t) windows->image.width)
              rectangle_info.x=(ssize_t) windows->image.width;
          if ((int) rectangle_info.x < x)
            rectangle_info.width=(unsigned int) (x-rectangle_info.x);
          else
            {
              rectangle_info.width=(unsigned int) (rectangle_info.x-x);
              rectangle_info.x=(ssize_t) x;
            }
          if (rectangle_info.y < 0)
            rectangle_info.y=0;
          else
            if (rectangle_info.y > (ssize_t) windows->image.height)
              rectangle_info.y=(ssize_t) windows->image.height;
          if ((int) rectangle_info.y < y)
            rectangle_info.height=(unsigned int) (y-rectangle_info.y);
          else
            {
              rectangle_info.height=(unsigned int) (rectangle_info.y-y);
              rectangle_info.y=(ssize_t) y;
            }
        }
    } while ((state & ExitState) == 0);
    (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
    if ((element == PointElement) || (element == PolygonElement) ||
        (element == FillPolygonElement))
      {
        /*
          Determine polygon bounding box.
        */
        rectangle_info.x=(ssize_t) coordinate_info->x;
        rectangle_info.y=(ssize_t) coordinate_info->y;
        x=coordinate_info->x;
        y=coordinate_info->y;
        for (i=1; i < number_coordinates; i++)
        {
          if (coordinate_info[i].x > x)
            x=coordinate_info[i].x;
          if (coordinate_info[i].y > y)
            y=coordinate_info[i].y;
          if ((ssize_t) coordinate_info[i].x < rectangle_info.x)
            rectangle_info.x=MagickMax((ssize_t) coordinate_info[i].x,0);
          if ((ssize_t) coordinate_info[i].y < rectangle_info.y)
            rectangle_info.y=MagickMax((ssize_t) coordinate_info[i].y,0);
        }
        rectangle_info.width=(size_t) (x-rectangle_info.x);
        rectangle_info.height=(size_t) (y-rectangle_info.y);
        for (i=0; i < number_coordinates; i++)
        {
          coordinate_info[i].x-=rectangle_info.x;
          coordinate_info[i].y-=rectangle_info.y;
        }
      }
    else
      if (distance <= 9)
        continue;
      else
        if ((element == RectangleElement) ||
            (element == CircleElement) || (element == EllipseElement))
          {
            rectangle_info.width--;
            rectangle_info.height--;
          }
    /*
      Drawing is relative to image configuration.
    */
    draw_info.x=(int) rectangle_info.x;
    draw_info.y=(int) rectangle_info.y;
    (void) XMagickCommand(display,resource_info,windows,SaveToUndoBufferCommand,
      image,exception);
    width=(unsigned int) (*image)->columns;
    height=(unsigned int) (*image)->rows;
    x=0;
    y=0;
    if (windows->image.crop_geometry != (char *) NULL)
      (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
    draw_info.x+=windows->image.x-(line_width/2);
    if (draw_info.x < 0)
      draw_info.x=0;
    draw_info.x=(int) (width*draw_info.x/windows->image.ximage->width);
    draw_info.y+=windows->image.y-(line_width/2);
    if (draw_info.y < 0)
      draw_info.y=0;
    draw_info.y=(int) height*draw_info.y/windows->image.ximage->height;
    draw_info.width=(unsigned int) rectangle_info.width+(line_width << 1);
    if (draw_info.width > (unsigned int) (*image)->columns)
      draw_info.width=(unsigned int) (*image)->columns;
    draw_info.height=(unsigned int) rectangle_info.height+(line_width << 1);
    if (draw_info.height > (unsigned int) (*image)->rows)
      draw_info.height=(unsigned int) (*image)->rows;
    (void) FormatLocaleString(draw_info.geometry,MagickPathExtent,"%ux%u%+d%+d",
      width*draw_info.width/windows->image.ximage->width,
      height*draw_info.height/windows->image.ximage->height,
      draw_info.x+x,draw_info.y+y);
    /*
      Initialize drawing attributes.
    */
    draw_info.degrees=0.0;
    draw_info.element=element;
    draw_info.stipple=stipple;
    draw_info.line_width=line_width;
    draw_info.line_info=line_info;
    if (line_info.x1 > (int) (line_width/2))
      draw_info.line_info.x1=(short) line_width/2;
    if (line_info.y1 > (int) (line_width/2))
      draw_info.line_info.y1=(short) line_width/2;
    draw_info.line_info.x2=(short) (line_info.x2-line_info.x1+(line_width/2));
    draw_info.line_info.y2=(short) (line_info.y2-line_info.y1+(line_width/2));
    if ((draw_info.line_info.x2 < 0) && (draw_info.line_info.y2 < 0))
      {
        draw_info.line_info.x2=(-draw_info.line_info.x2);
        draw_info.line_info.y2=(-draw_info.line_info.y2);
      }
    if (draw_info.line_info.x2 < 0)
      {
        draw_info.line_info.x2=(-draw_info.line_info.x2);
        Swap(draw_info.line_info.x1,draw_info.line_info.x2);
      }
    if (draw_info.line_info.y2 < 0)
      {
        draw_info.line_info.y2=(-draw_info.line_info.y2);
        Swap(draw_info.line_info.y1,draw_info.line_info.y2);
      }
    draw_info.rectangle_info=rectangle_info;
    if (draw_info.rectangle_info.x > (ssize_t) (line_width/2))
      draw_info.rectangle_info.x=(ssize_t) line_width/2;
    if (draw_info.rectangle_info.y > (ssize_t) (line_width/2))
      draw_info.rectangle_info.y=(ssize_t) line_width/2;
    draw_info.number_coordinates=(unsigned int) number_coordinates;
    draw_info.coordinate_info=coordinate_info;
    windows->pixel_info->pen_color=windows->pixel_info->pen_colors[pen_id];
    /*
      Draw element on image.
    */
    XSetCursorState(display,windows,MagickTrue);
    XCheckRefreshWindows(display,windows);
    status=XDrawImage(display,windows->pixel_info,&draw_info,*image,exception);
    XSetCursorState(display,windows,MagickFalse);
    /*
      Update image colormap and return to image drawing.
    */
    XConfigureImageColormap(display,resource_info,windows,*image,exception);
    (void) XConfigureImage(display,resource_info,windows,*image,exception);
  }
  XSetCursorState(display,windows,MagickFalse);
  coordinate_info=(XPoint *) RelinquishMagickMemory(coordinate_info);
  return(status != 0 ? MagickTrue : MagickFalse);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X D r a w P a n R e c t a n g l e                                         %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XDrawPanRectangle() draws a rectangle in the pan window.  The pan window
%  displays a zoom image and the rectangle shows which portion of the image is
%  displayed in the Image window.
%
%  The format of the XDrawPanRectangle method is:
%
%      XDrawPanRectangle(Display *display,XWindows *windows)
%
%  A description of each parameter follows:
%
%    o display: Specifies a connection to an X server;  returned from
%      XOpenDisplay.
%
%    o windows: Specifies a pointer to a XWindows structure.
%
*/
static void XDrawPanRectangle(Display *display,XWindows *windows)
{
  double
    scale_factor;

  RectangleInfo
    highlight_info;

  /*
    Determine dimensions of the panning rectangle.
  */
  scale_factor=(double) windows->pan.width/windows->image.ximage->width;
  highlight_info.x=(ssize_t) (scale_factor*windows->image.x+0.5);
  highlight_info.width=(unsigned int) (scale_factor*windows->image.width+0.5);
  scale_factor=(double)
    windows->pan.height/windows->image.ximage->height;
  highlight_info.y=(ssize_t) (scale_factor*windows->image.y+0.5);
  highlight_info.height=(unsigned int) (scale_factor*windows->image.height+0.5);
  /*
    Display the panning rectangle.
  */
  (void) XClearWindow(display,windows->pan.id);
  XHighlightRectangle(display,windows->pan.id,windows->pan.annotate_context,
    &highlight_info);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X I m a g e C a c h e                                                     %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XImageCache() handles the creation, manipulation, and destruction of the
%  image cache (undo and redo buffers).
%
%  The format of the XImageCache method is:
%
%      void XImageCache(Display *display,XResourceInfo *resource_info,
%        XWindows *windows,const CommandType command,Image **image,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o display: Specifies a connection to an X server; returned from
%      XOpenDisplay.
%
%    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
%
%    o windows: Specifies a pointer to a XWindows structure.
%
%    o command: Specifies a command to perform.
%
%    o image: the image;  XImageCache may transform the image and return a new
%      image pointer.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static void XImageCache(Display *display,XResourceInfo *resource_info,
  XWindows *windows,const CommandType command,Image **image,
  ExceptionInfo *exception)
{
  Image
    *cache_image;

  static Image
    *redo_image = (Image *) NULL,
    *undo_image = (Image *) NULL;

  switch (command)
  {
    case FreeBuffersCommand:
    {
      /*
        Free memory from the undo and redo cache.
      */
      while (undo_image != (Image *) NULL)
      {
        cache_image=undo_image;
        undo_image=GetPreviousImageInList(undo_image);
        cache_image->list=DestroyImage(cache_image->list);
        cache_image=DestroyImage(cache_image);
      }
      undo_image=NewImageList();
      if (redo_image != (Image *) NULL)
        redo_image=DestroyImage(redo_image);
      redo_image=NewImageList();
      return;
    }
    case UndoCommand:
    {
      char
        image_geometry[MagickPathExtent];

      /*
        Undo the last image transformation.
      */
      if (undo_image == (Image *) NULL)
        {
          (void) XBell(display,0);
          return;
        }
      cache_image=undo_image;
      undo_image=GetPreviousImageInList(undo_image);
      windows->image.window_changes.width=(int) cache_image->columns;
      windows->image.window_changes.height=(int) cache_image->rows;
      (void) FormatLocaleString(image_geometry,MagickPathExtent,"%dx%d!",
        windows->image.ximage->width,windows->image.ximage->height);
      (void) TransformImage(image,windows->image.crop_geometry,image_geometry,
        exception);
      if (windows->image.crop_geometry != (char *) NULL)
        windows->image.crop_geometry=(char *) RelinquishMagickMemory(
          windows->image.crop_geometry);
      windows->image.crop_geometry=cache_image->geometry;
      if (redo_image != (Image *) NULL)
        redo_image=DestroyImage(redo_image);
      redo_image=(*image);
      *image=cache_image->list;
      cache_image=DestroyImage(cache_image);
      if (windows->image.orphan != MagickFalse)
        return;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      return;
    }
    case CutCommand:
    case PasteCommand:
    case ApplyCommand:
    case HalfSizeCommand:
    case OriginalSizeCommand:
    case DoubleSizeCommand:
    case ResizeCommand:
    case TrimCommand:
    case CropCommand:
    case ChopCommand:
    case FlipCommand:
    case FlopCommand:
    case RotateRightCommand:
    case RotateLeftCommand:
    case RotateCommand:
    case ShearCommand:
    case RollCommand:
    case NegateCommand:
    case ContrastStretchCommand:
    case SigmoidalContrastCommand:
    case NormalizeCommand:
    case EqualizeCommand:
    case HueCommand:
    case SaturationCommand:
    case BrightnessCommand:
    case GammaCommand:
    case SpiffCommand:
    case DullCommand:
    case GrayscaleCommand:
    case MapCommand:
    case QuantizeCommand:
    case DespeckleCommand:
    case EmbossCommand:
    case ReduceNoiseCommand:
    case AddNoiseCommand:
    case SharpenCommand:
    case BlurCommand:
    case ThresholdCommand:
    case EdgeDetectCommand:
    case SpreadCommand:
    case ShadeCommand:
    case RaiseCommand:
    case SegmentCommand:
    case SolarizeCommand:
    case SepiaToneCommand:
    case SwirlCommand:
    case ImplodeCommand:
    case VignetteCommand:
    case WaveCommand:
    case OilPaintCommand:
    case CharcoalDrawCommand:
    case AnnotateCommand:
    case AddBorderCommand:
    case AddFrameCommand:
    case CompositeCommand:
    case CommentCommand:
    case LaunchCommand:
    case RegionofInterestCommand:
    case SaveToUndoBufferCommand:
    case RedoCommand:
    {
      Image
        *previous_image;

      ssize_t
        bytes;

      bytes=(ssize_t) ((*image)->columns*(*image)->rows*sizeof(PixelInfo));
      if (undo_image != (Image *) NULL)
        {
          /*
            Ensure the undo cache has enough memory available.
          */
          previous_image=undo_image;
          while (previous_image != (Image *) NULL)
          {
            bytes+=previous_image->list->columns*previous_image->list->rows*
              sizeof(PixelInfo);
            if (bytes <= (ssize_t) (resource_info->undo_cache << 20))
              {
                previous_image=GetPreviousImageInList(previous_image);
                continue;
              }
            bytes-=previous_image->list->columns*previous_image->list->rows*
              sizeof(PixelInfo);
            if (previous_image == undo_image)
              undo_image=NewImageList();
            else
              previous_image->next->previous=NewImageList();
            break;
          }
          while (previous_image != (Image *) NULL)
          {
            /*
              Delete any excess memory from undo cache.
            */
            cache_image=previous_image;
            previous_image=GetPreviousImageInList(previous_image);
            cache_image->list=DestroyImage(cache_image->list);
            cache_image=DestroyImage(cache_image);
          }
        }
      if (bytes > (ssize_t) (resource_info->undo_cache << 20))
        break;
      /*
        Save image before transformations are applied.
      */
      cache_image=AcquireImage((ImageInfo *) NULL,exception);
      if (cache_image == (Image *) NULL)
        break;
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      cache_image->list=CloneImage(*image,0,0,MagickTrue,exception);
      XSetCursorState(display,windows,MagickFalse);
      if (cache_image->list == (Image *) NULL)
        {
          cache_image=DestroyImage(cache_image);
          break;
        }
      cache_image->columns=(size_t) windows->image.ximage->width;
      cache_image->rows=(size_t) windows->image.ximage->height;
      cache_image->geometry=windows->image.crop_geometry;
      if (windows->image.crop_geometry != (char *) NULL)
        {
          cache_image->geometry=AcquireString((char *) NULL);
          (void) CopyMagickString(cache_image->geometry,
            windows->image.crop_geometry,MagickPathExtent);
        }
      if (undo_image == (Image *) NULL)
        {
          undo_image=cache_image;
          break;
        }
      undo_image->next=cache_image;
      undo_image->next->previous=undo_image;
      undo_image=undo_image->next;
      break;
    }
    default:
      break;
  }
  if (command == RedoCommand)
    {
      /*
        Redo the last image transformation.
      */
      if (redo_image == (Image *) NULL)
        {
          (void) XBell(display,0);
          return;
        }
      windows->image.window_changes.width=(int) redo_image->columns;
      windows->image.window_changes.height=(int) redo_image->rows;
      if (windows->image.crop_geometry != (char *) NULL)
        windows->image.crop_geometry=(char *)
          RelinquishMagickMemory(windows->image.crop_geometry);
      windows->image.crop_geometry=redo_image->geometry;
      *image=DestroyImage(*image);
      *image=redo_image;
      redo_image=NewImageList();
      if (windows->image.orphan != MagickFalse)
        return;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      return;
    }
  if (command != InfoCommand)
    return;
  /*
    Display image info.
  */
  XSetCursorState(display,windows,MagickTrue);
  XCheckRefreshWindows(display,windows);
  XDisplayImageInfo(display,resource_info,windows,undo_image,*image,exception);
  XSetCursorState(display,windows,MagickFalse);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X I m a g e W i n d o w C o m m a n d                                     %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XImageWindowCommand() makes a transform to the image or Image window as
%  specified by a user menu button or keyboard command.
%
%  The format of the XImageWindowCommand method is:
%
%      CommandType XImageWindowCommand(Display *display,
%        XResourceInfo *resource_info,XWindows *windows,
%        const MagickStatusType state,KeySym key_symbol,Image **image,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o nexus:  Method XImageWindowCommand returns an image when the
%      user chooses 'Open Image' from the command menu.  Otherwise a null
%      image is returned.
%
%    o display: Specifies a connection to an X server; returned from
%      XOpenDisplay.
%
%    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
%
%    o windows: Specifies a pointer to a XWindows structure.
%
%    o state: key mask.
%
%    o key_symbol: Specifies a command to perform.
%
%    o image: the image;  XImageWIndowCommand may transform the image and
%      return a new image pointer.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static CommandType XImageWindowCommand(Display *display,
  XResourceInfo *resource_info,XWindows *windows,const MagickStatusType state,
  KeySym key_symbol,Image **image,ExceptionInfo *exception)
{
  static char
    delta[MagickPathExtent] = "";

  static const char
    Digits[] = "01234567890";

  static KeySym
    last_symbol = XK_0;

  if ((key_symbol >= XK_0) && (key_symbol <= XK_9))
    {
      if (((last_symbol < XK_0) || (last_symbol > XK_9)))
        {
          *delta='\0';
          resource_info->quantum=1;
        }
      last_symbol=key_symbol;
      delta[strlen(delta)+1]='\0';
      delta[strlen(delta)]=Digits[key_symbol-XK_0];
      resource_info->quantum=StringToLong(delta);
      return(NullCommand);
    }
  last_symbol=key_symbol;
  if (resource_info->immutable)
    {
      /*
        Virtual image window has a restricted command set.
      */
      switch (key_symbol)
      {
        case XK_question:
          return(InfoCommand);
        case XK_p:
        case XK_Print:
          return(PrintCommand);
        case XK_space:
          return(NextCommand);
        case XK_q:
        case XK_Escape:
          return(QuitCommand);
        default:
          break;
      }
      return(NullCommand);
    }
  switch ((int) key_symbol)
  {
    case XK_o:
    {
      if ((state & ControlMask) == 0)
        break;
      return(OpenCommand);
    }
    case XK_space:
      return(NextCommand);
    case XK_BackSpace:
      return(FormerCommand);
    case XK_s:
    {
      if ((state & Mod1Mask) != 0)
        return(SwirlCommand);
      if ((state & ControlMask) == 0)
        return(ShearCommand);
      return(SaveCommand);
    }
    case XK_p:
    case XK_Print:
    {
      if ((state & Mod1Mask) != 0)
        return(OilPaintCommand);
      if ((state & Mod4Mask) != 0)
        return(ColorCommand);
      if ((state & ControlMask) == 0)
        return(NullCommand);
      return(PrintCommand);
    }
    case XK_d:
    {
      if ((state & Mod4Mask) != 0)
        return(DrawCommand);
      if ((state & ControlMask) == 0)
        return(NullCommand);
      return(DeleteCommand);
    }
    case XK_Select:
    {
      if ((state & ControlMask) == 0)
        return(NullCommand);
      return(SelectCommand);
    }
    case XK_n:
    {
      if ((state & ControlMask) == 0)
        return(NullCommand);
      return(NewCommand);
    }
    case XK_q:
    case XK_Escape:
      return(QuitCommand);
    case XK_z:
    case XK_Undo:
    {
      if ((state & ControlMask) == 0)
        return(NullCommand);
      return(UndoCommand);
    }
    case XK_r:
    case XK_Redo:
    {
      if ((state & ControlMask) == 0)
        return(RollCommand);
      return(RedoCommand);
    }
    case XK_x:
    {
      if ((state & ControlMask) == 0)
        return(NullCommand);
      return(CutCommand);
    }
    case XK_c:
    {
      if ((state & Mod1Mask) != 0)
        return(CharcoalDrawCommand);
      if ((state & ControlMask) == 0)
        return(CropCommand);
      return(CopyCommand);
    }
    case XK_v:
    case XK_Insert:
    {
      if ((state & Mod4Mask) != 0)
        return(CompositeCommand);
      if ((state & ControlMask) == 0)
        return(FlipCommand);
      return(PasteCommand);
    }
    case XK_less:
      return(HalfSizeCommand);
    case XK_minus:
      return(OriginalSizeCommand);
    case XK_greater:
      return(DoubleSizeCommand);
    case XK_percent:
      return(ResizeCommand);
    case XK_at:
      return(RefreshCommand);
    case XK_bracketleft:
      return(ChopCommand);
    case XK_h:
      return(FlopCommand);
    case XK_slash:
      return(RotateRightCommand);
    case XK_backslash:
      return(RotateLeftCommand);
    case XK_asterisk:
      return(RotateCommand);
    case XK_t:
      return(TrimCommand);
    case XK_H:
      return(HueCommand);
    case XK_S:
      return(SaturationCommand);
    case XK_L:
      return(BrightnessCommand);
    case XK_G:
      return(GammaCommand);
    case XK_C:
      return(SpiffCommand);
    case XK_Z:
      return(DullCommand);
    case XK_N:
      return(NormalizeCommand);
    case XK_equal:
      return(EqualizeCommand);
    case XK_asciitilde:
      return(NegateCommand);
    case XK_period:
      return(GrayscaleCommand);
    case XK_numbersign:
      return(QuantizeCommand);
    case XK_F2:
      return(DespeckleCommand);
    case XK_F3:
      return(EmbossCommand);
    case XK_F4:
      return(ReduceNoiseCommand);
    case XK_F5:
      return(AddNoiseCommand);
    case XK_F6:
      return(SharpenCommand);
    case XK_F7:
      return(BlurCommand);
    case XK_F8:
      return(ThresholdCommand);
    case XK_F9:
      return(EdgeDetectCommand);
    case XK_F10:
      return(SpreadCommand);
    case XK_F11:
      return(ShadeCommand);
    case XK_F12:
      return(RaiseCommand);
    case XK_F13:
      return(SegmentCommand);
    case XK_i:
    {
      if ((state & Mod1Mask) == 0)
        return(NullCommand);
      return(ImplodeCommand);
    }
    case XK_w:
    {
      if ((state & Mod1Mask) == 0)
        return(NullCommand);
      return(WaveCommand);
    }
    case XK_m:
    {
      if ((state & Mod4Mask) == 0)
        return(NullCommand);
      return(MatteCommand);
    }
    case XK_b:
    {
      if ((state & Mod4Mask) == 0)
        return(NullCommand);
      return(AddBorderCommand);
    }
    case XK_f:
    {
      if ((state & Mod4Mask) == 0)
        return(NullCommand);
      return(AddFrameCommand);
    }
    case XK_exclam:
    {
      if ((state & Mod4Mask) == 0)
        return(NullCommand);
      return(CommentCommand);
    }
    case XK_a:
    {
      if ((state & Mod1Mask) != 0)
        return(ApplyCommand);
      if ((state & Mod4Mask) != 0)
        return(AnnotateCommand);
      if ((state & ControlMask) == 0)
        return(NullCommand);
      return(RegionofInterestCommand);
    }
    case XK_question:
      return(InfoCommand);
    case XK_plus:
      return(ZoomCommand);
    case XK_P:
    {
      if ((state & ShiftMask) == 0)
        return(NullCommand);
      return(ShowPreviewCommand);
    }
    case XK_Execute:
      return(LaunchCommand);
    case XK_F1:
      return(HelpCommand);
    case XK_Find:
      return(BrowseDocumentationCommand);
    case XK_Menu:
    {
      (void) XMapRaised(display,windows->command.id);
      return(NullCommand);
    }
    case XK_Next:
    case XK_Prior:
    case XK_Home:
    case XK_KP_Home:
    {
      XTranslateImage(display,windows,*image,key_symbol);
      return(NullCommand);
    }
    case XK_Up:
    case XK_KP_Up:
    case XK_Down:
    case XK_KP_Down:
    case XK_Left:
    case XK_KP_Left:
    case XK_Right:
    case XK_KP_Right:
    {
      if ((state & Mod1Mask) != 0)
        {
          RectangleInfo
            crop_info;

          /*
            Trim one pixel from edge of image.
          */
          crop_info.x=0;
          crop_info.y=0;
          crop_info.width=(size_t) windows->image.ximage->width;
          crop_info.height=(size_t) windows->image.ximage->height;
          if ((key_symbol == XK_Up) || (key_symbol == XK_KP_Up))
            {
              if (resource_info->quantum >= (int) crop_info.height)
                resource_info->quantum=(int) crop_info.height-1;
              crop_info.height-=resource_info->quantum;
            }
          if ((key_symbol == XK_Down) || (key_symbol == XK_KP_Down))
            {
              if (resource_info->quantum >= (int) (crop_info.height-crop_info.y))
                resource_info->quantum=(int) (crop_info.height-crop_info.y-1);
              crop_info.y+=resource_info->quantum;
              crop_info.height-=resource_info->quantum;
            }
          if ((key_symbol == XK_Left) || (key_symbol == XK_KP_Left))
            {
              if (resource_info->quantum >= (int) crop_info.width)
                resource_info->quantum=(int) crop_info.width-1;
              crop_info.width-=resource_info->quantum;
            }
          if ((key_symbol == XK_Right) || (key_symbol == XK_KP_Right))
            {
              if (resource_info->quantum >= (int) (crop_info.width-crop_info.x))
                resource_info->quantum=(int) (crop_info.width-crop_info.x-1);
              crop_info.x+=resource_info->quantum;
              crop_info.width-=resource_info->quantum;
            }
          if ((int) (windows->image.x+windows->image.width) >
              (int) crop_info.width)
            windows->image.x=(int) (crop_info.width-windows->image.width);
          if ((int) (windows->image.y+windows->image.height) >
              (int) crop_info.height)
            windows->image.y=(int) (crop_info.height-windows->image.height);
          XSetCropGeometry(display,windows,&crop_info,*image);
          windows->image.window_changes.width=(int) crop_info.width;
          windows->image.window_changes.height=(int) crop_info.height;
          (void) XSetWindowBackgroundPixmap(display,windows->image.id,None);
          (void) XConfigureImage(display,resource_info,windows,*image,
            exception);
          return(NullCommand);
        }
      XTranslateImage(display,windows,*image,key_symbol);
      return(NullCommand);
    }
    default:
      return(NullCommand);
  }
  return(NullCommand);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X M a g i c k C o m m a n d                                               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XMagickCommand() makes a transform to the image or Image window as
%  specified by a user menu button or keyboard command.
%
%  The format of the XMagickCommand method is:
%
%      Image *XMagickCommand(Display *display,XResourceInfo *resource_info,
%        XWindows *windows,const CommandType command,Image **image,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o display: Specifies a connection to an X server; returned from
%      XOpenDisplay.
%
%    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
%
%    o windows: Specifies a pointer to a XWindows structure.
%
%    o command: Specifies a command to perform.
%
%    o image: the image;  XMagickCommand may transform the image and return a
%      new image pointer.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static Image *XMagickCommand(Display *display,XResourceInfo *resource_info,
  XWindows *windows,const CommandType command,Image **image,
  ExceptionInfo *exception)
{
  char
    filename[MagickPathExtent],
    geometry[MagickPathExtent],
    modulate_factors[MagickPathExtent];

  GeometryInfo
    geometry_info;

  Image
    *nexus;

  ImageInfo
    *image_info;

  int
    x,
    y;

  MagickStatusType
    flags,
    status;

  QuantizeInfo
    quantize_info;

  RectangleInfo
    page_geometry;

  int
    i;

  static char
    color[MagickPathExtent] = "gray";

  unsigned int
    height,
    width;

  /*
    Process user command.
  */
  XCheckRefreshWindows(display,windows);
  XImageCache(display,resource_info,windows,command,image,exception);
  nexus=NewImageList();
  windows->image.window_changes.width=windows->image.ximage->width;
  windows->image.window_changes.height=windows->image.ximage->height;
  image_info=CloneImageInfo(resource_info->image_info);
  SetGeometryInfo(&geometry_info);
  GetQuantizeInfo(&quantize_info);
  switch (command)
  {
    case OpenCommand:
    {
      /*
        Load image.
      */
      nexus=XOpenImage(display,resource_info,windows,MagickFalse);
      break;
    }
    case NextCommand:
    {
      /*
        Display next image.
      */
      for (i=0; i < resource_info->quantum; i++)
        XClientMessage(display,windows->image.id,windows->im_protocols,
          windows->im_next_image,CurrentTime);
      break;
    }
    case FormerCommand:
    {
      /*
        Display former image.
      */
      for (i=0; i < resource_info->quantum; i++)
        XClientMessage(display,windows->image.id,windows->im_protocols,
          windows->im_former_image,CurrentTime);
      break;
    }
    case SelectCommand:
    {
      int
        status;

      /*
        Select image.
      */
      if (*resource_info->home_directory == '\0')
        (void) CopyMagickString(resource_info->home_directory,".",
          MagickPathExtent);
      status=chdir(resource_info->home_directory);
      if (status == -1)
        (void) ThrowMagickException(exception,GetMagickModule(),FileOpenError,
          "UnableToOpenFile","%s",resource_info->home_directory);
      nexus=XOpenImage(display,resource_info,windows,MagickTrue);
      break;
    }
    case SaveCommand:
    {
      /*
        Save image.
      */
      status=XSaveImage(display,resource_info,windows,*image,exception);
      if (status == MagickFalse)
        {
          char
            message[MagickPathExtent];

          (void) FormatLocaleString(message,MagickPathExtent,"%s:%s",
            exception->reason != (char *) NULL ? exception->reason : "",
            exception->description != (char *) NULL ? exception->description :
            "");
          XNoticeWidget(display,windows,"Unable to save file:",message);
          break;
        }
      break;
    }
    case PrintCommand:
    {
      /*
        Print image.
      */
      status=XPrintImage(display,resource_info,windows,*image,exception);
      if (status == MagickFalse)
        {
          char
            message[MagickPathExtent];

          (void) FormatLocaleString(message,MagickPathExtent,"%s:%s",
            exception->reason != (char *) NULL ? exception->reason : "",
            exception->description != (char *) NULL ? exception->description :
            "");
          XNoticeWidget(display,windows,"Unable to print file:",message);
          break;
        }
      break;
    }
    case DeleteCommand:
    {
      static char
        filename[MagickPathExtent] = "\0";

      /*
        Delete image file.
      */
      XFileBrowserWidget(display,windows,"Delete",filename);
      if (*filename == '\0')
        break;
      status=ShredFile(filename);
      if (status != MagickFalse)
        XNoticeWidget(display,windows,"Unable to delete image file:",filename);
      break;
    }
    case NewCommand:
    {
      int
        status;

      static char
        color[MagickPathExtent] = "gray",
        geometry[MagickPathExtent] = "640x480";

      static const char
        *format = "gradient";

      /*
        Query user for canvas geometry.
      */
      status=XDialogWidget(display,windows,"New","Enter image geometry:",
        geometry);
      if (*geometry == '\0')
        break;
      if (status == 0)
        format="xc";
      XColorBrowserWidget(display,windows,"Select",color);
      if (*color == '\0')
        break;
      /*
        Create canvas.
      */
      (void) FormatLocaleString(image_info->filename,MagickPathExtent,
        "%s:%s",format,color);
      (void) CloneString(&image_info->size,geometry);
      nexus=ReadImage(image_info,exception);
      CatchException(exception);
      XClientMessage(display,windows->image.id,windows->im_protocols,
        windows->im_next_image,CurrentTime);
      break;
    }
    case VisualDirectoryCommand:
    {
      /*
        Visual Image directory.
      */
      nexus=XVisualDirectoryImage(display,resource_info,windows,exception);
      break;
    }
    case QuitCommand:
    {
      /*
        exit program.
      */
      if (resource_info->confirm_exit == MagickFalse)
        XClientMessage(display,windows->image.id,windows->im_protocols,
          windows->im_exit,CurrentTime);
      else
        {
          int
            status;

          /*
            Confirm program exit.
          */
          status=XConfirmWidget(display,windows,"Do you really want to exit",
            resource_info->client_name);
          if (status > 0)
            XClientMessage(display,windows->image.id,windows->im_protocols,
              windows->im_exit,CurrentTime);
        }
      break;
    }
    case CutCommand:
    {
      /*
        Cut image.
      */
      (void) XCropImage(display,resource_info,windows,*image,CutMode,exception);
      break;
    }
    case CopyCommand:
    {
      /*
        Copy image.
      */
      (void) XCropImage(display,resource_info,windows,*image,CopyMode,
        exception);
      break;
    }
    case PasteCommand:
    {
      /*
        Paste image.
      */
      status=XPasteImage(display,resource_info,windows,*image,exception);
      if (status == MagickFalse)
        {
          XNoticeWidget(display,windows,"Unable to paste X image",
            (*image)->filename);
          break;
        }
      break;
    }
    case HalfSizeCommand:
    {
      /*
        Half image size.
      */
      windows->image.window_changes.width=windows->image.ximage->width/2;
      windows->image.window_changes.height=windows->image.ximage->height/2;
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case OriginalSizeCommand:
    {
      /*
        Original image size.
      */
      windows->image.window_changes.width=(int) (*image)->columns;
      windows->image.window_changes.height=(int) (*image)->rows;
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case DoubleSizeCommand:
    {
      /*
        Double the image size.
      */
      windows->image.window_changes.width=windows->image.ximage->width << 1;
      windows->image.window_changes.height=windows->image.ximage->height << 1;
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case ResizeCommand:
    {
      int
        status;

      size_t
        height,
        width;

      ssize_t
        x,
        y;

      /*
        Resize image.
      */
      width=(size_t) windows->image.ximage->width;
      height=(size_t) windows->image.ximage->height;
      x=0;
      y=0;
      (void) FormatLocaleString(geometry,MagickPathExtent,"%.20gx%.20g+0+0",
        (double) width,(double) height);
      status=XDialogWidget(display,windows,"Resize",
        "Enter resize geometry (e.g. 640x480, 200%):",geometry);
      if (*geometry == '\0')
        break;
      if (status == 0)
        (void) ConcatenateMagickString(geometry,"!",MagickPathExtent);
      (void) ParseMetaGeometry(geometry,&x,&y,&width,&height);
      windows->image.window_changes.width=(int) width;
      windows->image.window_changes.height=(int) height;
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case ApplyCommand:
    {
      char
        image_geometry[MagickPathExtent];

      if ((windows->image.crop_geometry == (char *) NULL) &&
          ((int) (*image)->columns == windows->image.ximage->width) &&
          ((int) (*image)->rows == windows->image.ximage->height))
        break;
      /*
        Apply size transforms to image.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      /*
        Crop and/or scale displayed image.
      */
      (void) FormatLocaleString(image_geometry,MagickPathExtent,"%dx%d!",
        windows->image.ximage->width,windows->image.ximage->height);
      (void) TransformImage(image,windows->image.crop_geometry,image_geometry,
        exception);
      if (windows->image.crop_geometry != (char *) NULL)
        windows->image.crop_geometry=(char *) RelinquishMagickMemory(
          windows->image.crop_geometry);
      windows->image.x=0;
      windows->image.y=0;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case RefreshCommand:
    {
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case RestoreCommand:
    {
      /*
        Restore Image window to its original size.
      */
      if ((windows->image.width == (unsigned int) (*image)->columns) &&
          (windows->image.height == (unsigned int) (*image)->rows) &&
          (windows->image.crop_geometry == (char *) NULL))
        {
          (void) XBell(display,0);
          break;
        }
      windows->image.window_changes.width=(int) (*image)->columns;
      windows->image.window_changes.height=(int) (*image)->rows;
      if (windows->image.crop_geometry != (char *) NULL)
        {
          windows->image.crop_geometry=(char *)
            RelinquishMagickMemory(windows->image.crop_geometry);
          windows->image.crop_geometry=(char *) NULL;
          windows->image.x=0;
          windows->image.y=0;
        }
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case CropCommand:
    {
      /*
        Crop image.
      */
      (void) XCropImage(display,resource_info,windows,*image,CropMode,
        exception);
      break;
    }
    case ChopCommand:
    {
      /*
        Chop image.
      */
      status=XChopImage(display,resource_info,windows,image,exception);
      if (status == MagickFalse)
        {
          XNoticeWidget(display,windows,"Unable to cut X image",
            (*image)->filename);
          break;
        }
      break;
    }
    case FlopCommand:
    {
      Image
        *flop_image;

      /*
        Flop image scanlines.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      flop_image=FlopImage(*image,exception);
      if (flop_image != (Image *) NULL)
        {
          *image=DestroyImage(*image);
          *image=flop_image;
        }
      CatchException(exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.crop_geometry != (char *) NULL)
        {
          /*
            Flop crop geometry.
          */
          width=(unsigned int) (*image)->columns;
          height=(unsigned int) (*image)->rows;
          (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
            &width,&height);
          (void) FormatLocaleString(windows->image.crop_geometry,
            MagickPathExtent,"%ux%u%+d%+d",width,height,(int) (*image)->columns-
            (int) width-x,y);
        }
      if (windows->image.orphan != MagickFalse)
        break;
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case FlipCommand:
    {
      Image
        *flip_image;

      /*
        Flip image scanlines.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      flip_image=FlipImage(*image,exception);
      if (flip_image != (Image *) NULL)
        {
          *image=DestroyImage(*image);
          *image=flip_image;
        }
      CatchException(exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.crop_geometry != (char *) NULL)
        {
          /*
            Flip crop geometry.
          */
          width=(unsigned int) (*image)->columns;
          height=(unsigned int) (*image)->rows;
          (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
            &width,&height);
          (void) FormatLocaleString(windows->image.crop_geometry,
            MagickPathExtent,"%ux%u%+d%+d",width,height,x,(int) (*image)->rows-
            (int) height-y);
        }
      if (windows->image.orphan != MagickFalse)
        break;
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case RotateRightCommand:
    {
      /*
        Rotate image 90 degrees clockwise.
      */
      status=XRotateImage(display,resource_info,windows,90.0,image,exception);
      if (status == MagickFalse)
        {
          XNoticeWidget(display,windows,"Unable to rotate X image",
            (*image)->filename);
          break;
        }
      break;
    }
    case RotateLeftCommand:
    {
      /*
        Rotate image 90 degrees counter-clockwise.
      */
      status=XRotateImage(display,resource_info,windows,-90.0,image,exception);
      if (status == MagickFalse)
        {
          XNoticeWidget(display,windows,"Unable to rotate X image",
            (*image)->filename);
          break;
        }
      break;
    }
    case RotateCommand:
    {
      /*
        Rotate image.
      */
      status=XRotateImage(display,resource_info,windows,0.0,image,exception);
      if (status == MagickFalse)
        {
          XNoticeWidget(display,windows,"Unable to rotate X image",
            (*image)->filename);
          break;
        }
      break;
    }
    case ShearCommand:
    {
      Image
        *shear_image;

      static char
        geometry[MagickPathExtent] = "45.0x45.0";

      /*
        Query user for shear color and geometry.
      */
      XColorBrowserWidget(display,windows,"Select",color);
      if (*color == '\0')
        break;
      (void) XDialogWidget(display,windows,"Shear","Enter shear geometry:",
        geometry);
      if (*geometry == '\0')
        break;
      /*
        Shear image.
      */
      (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
        exception);
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      (void) QueryColorCompliance(color,AllCompliance,
        &(*image)->background_color,exception);
      flags=ParseGeometry(geometry,&geometry_info);
      if ((flags & SigmaValue) == 0)
        geometry_info.sigma=geometry_info.rho;
      shear_image=ShearImage(*image,geometry_info.rho,geometry_info.sigma,
        exception);
      if (shear_image != (Image *) NULL)
        {
          *image=DestroyImage(*image);
          *image=shear_image;
        }
      CatchException(exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      windows->image.window_changes.width=(int) (*image)->columns;
      windows->image.window_changes.height=(int) (*image)->rows;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case RollCommand:
    {
      Image
        *roll_image;

      static char
        geometry[MagickPathExtent] = "+2+2";

      /*
        Query user for the roll geometry.
      */
      (void) XDialogWidget(display,windows,"Roll","Enter roll geometry:",
        geometry);
      if (*geometry == '\0')
        break;
      /*
        Roll image.
      */
      (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
        exception);
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      (void) ParsePageGeometry(*image,geometry,&page_geometry,
        exception);
      roll_image=RollImage(*image,page_geometry.x,page_geometry.y,
        exception);
      if (roll_image != (Image *) NULL)
        {
          *image=DestroyImage(*image);
          *image=roll_image;
        }
      CatchException(exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      windows->image.window_changes.width=(int) (*image)->columns;
      windows->image.window_changes.height=(int) (*image)->rows;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case TrimCommand:
    {
      static char
        fuzz[MagickPathExtent];

      /*
        Query user for the fuzz factor.
      */
      (void) FormatLocaleString(fuzz,MagickPathExtent,"%g%%",100.0*
        (*image)->fuzz/(QuantumRange+1.0));
      (void) XDialogWidget(display,windows,"Trim","Enter fuzz factor:",fuzz);
      if (*fuzz == '\0')
        break;
      (*image)->fuzz=StringToDoubleInterval(fuzz,(double) QuantumRange+1.0);
      /*
        Trim image.
      */
      status=XTrimImage(display,resource_info,windows,*image,exception);
      if (status == MagickFalse)
        {
          XNoticeWidget(display,windows,"Unable to trim X image",
            (*image)->filename);
          break;
        }
      break;
    }
    case HueCommand:
    {
      static char
        hue_percent[MagickPathExtent] = "110";

      /*
        Query user for percent hue change.
      */
      (void) XDialogWidget(display,windows,"Apply",
        "Enter percent change in image hue (0-200):",hue_percent);
      if (*hue_percent == '\0')
        break;
      /*
        Vary the image hue.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      (void) CopyMagickString(modulate_factors,"100.0/100.0/",MagickPathExtent);
      (void) ConcatenateMagickString(modulate_factors,hue_percent,
        MagickPathExtent);
      (void) ModulateImage(*image,modulate_factors,exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case SaturationCommand:
    {
      static char
        saturation_percent[MagickPathExtent] = "110";

      /*
        Query user for percent saturation change.
      */
      (void) XDialogWidget(display,windows,"Apply",
        "Enter percent change in color saturation (0-200):",saturation_percent);
      if (*saturation_percent == '\0')
        break;
      /*
        Vary color saturation.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      (void) CopyMagickString(modulate_factors,"100.0/",MagickPathExtent);
      (void) ConcatenateMagickString(modulate_factors,saturation_percent,
        MagickPathExtent);
      (void) ModulateImage(*image,modulate_factors,exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case BrightnessCommand:
    {
      static char
        brightness_percent[MagickPathExtent] = "110";

      /*
        Query user for percent brightness change.
      */
      (void) XDialogWidget(display,windows,"Apply",
        "Enter percent change in color brightness (0-200):",brightness_percent);
      if (*brightness_percent == '\0')
        break;
      /*
        Vary the color brightness.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      (void) CopyMagickString(modulate_factors,brightness_percent,
        MagickPathExtent);
      (void) ModulateImage(*image,modulate_factors,exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case GammaCommand:
    {
      static char
        factor[MagickPathExtent] = "1.6";

      /*
        Query user for gamma value.
      */
      (void) XDialogWidget(display,windows,"Gamma",
        "Enter gamma value (e.g. 1.2):",factor);
      if (*factor == '\0')
        break;
      /*
        Gamma correct image.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      (void) GammaImage(*image,strtod(factor,(char **) NULL),exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case SpiffCommand:
    {
      /*
        Sharpen the image contrast.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      (void) ContrastImage(*image,MagickTrue,exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case DullCommand:
    {
      /*
        Dull the image contrast.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      (void) ContrastImage(*image,MagickFalse,exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case ContrastStretchCommand:
    {
      double
        black_point,
        white_point;

      static char
        levels[MagickPathExtent] = "1%";

      /*
        Query user for gamma value.
      */
      (void) XDialogWidget(display,windows,"Contrast Stretch",
        "Enter black and white points:",levels);
      if (*levels == '\0')
        break;
      /*
        Contrast stretch image.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      flags=ParseGeometry(levels,&geometry_info);
      black_point=geometry_info.rho;
      white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma : black_point;
      if ((flags & PercentValue) != 0)
        {
          black_point*=(double) (*image)->columns*(*image)->rows/100.0;
          white_point*=(double) (*image)->columns*(*image)->rows/100.0;
        }
      white_point=(double) (*image)->columns*(*image)->rows-white_point;
      (void) ContrastStretchImage(*image,black_point,white_point,
        exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case SigmoidalContrastCommand:
    {
      GeometryInfo
        geometry_info;

      MagickStatusType
        flags;

      static char
        levels[MagickPathExtent] = "3x50%";

      /*
        Query user for gamma value.
      */
      (void) XDialogWidget(display,windows,"Sigmoidal Contrast",
        "Enter contrast and midpoint:",levels);
      if (*levels == '\0')
        break;
      /*
        Contrast stretch image.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      flags=ParseGeometry(levels,&geometry_info);
      if ((flags & SigmaValue) == 0)
        geometry_info.sigma=1.0*QuantumRange/2.0;
      if ((flags & PercentValue) != 0)
        geometry_info.sigma=1.0*QuantumRange*geometry_info.sigma/100.0;
      (void) SigmoidalContrastImage(*image,MagickTrue,geometry_info.rho,
        geometry_info.sigma,exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case NormalizeCommand:
    {
      /*
        Perform histogram normalization on the image.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      (void) NormalizeImage(*image,exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case EqualizeCommand:
    {
      /*
        Perform histogram equalization on the image.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      (void) EqualizeImage(*image,exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case NegateCommand:
    {
      /*
        Negate colors in image.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      (void) NegateImage(*image,MagickFalse,exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case GrayscaleCommand:
    {
      /*
        Convert image to grayscale.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      (void) SetImageType(*image,(*image)->alpha_trait == UndefinedPixelTrait ?
        GrayscaleType : GrayscaleAlphaType,exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case MapCommand:
    {
      Image
        *affinity_image;

      static char
        filename[MagickPathExtent] = "\0";

      /*
        Request image file name from user.
      */
      XFileBrowserWidget(display,windows,"Map",filename);
      if (*filename == '\0')
        break;
      /*
        Map image.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      (void) CopyMagickString(image_info->filename,filename,MagickPathExtent);
      affinity_image=ReadImage(image_info,exception);
      if (affinity_image != (Image *) NULL)
        {
          (void) RemapImage(&quantize_info,*image,affinity_image,exception);
          affinity_image=DestroyImage(affinity_image);
        }
      CatchException(exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case QuantizeCommand:
    {
      int
        status;

      static char
        colors[MagickPathExtent] = "256";

      /*
        Query user for maximum number of colors.
      */
      status=XDialogWidget(display,windows,"Quantize",
        "Maximum number of colors:",colors);
      if (*colors == '\0')
        break;
      /*
        Color reduce the image.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      quantize_info.number_colors=StringToUnsignedLong(colors);
      quantize_info.dither_method=status != 0 ? RiemersmaDitherMethod :
        NoDitherMethod;
      (void) QuantizeImage(&quantize_info,*image,exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case DespeckleCommand:
    {
      Image
        *despeckle_image;

      /*
        Despeckle image.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      despeckle_image=DespeckleImage(*image,exception);
      if (despeckle_image != (Image *) NULL)
        {
          *image=DestroyImage(*image);
          *image=despeckle_image;
        }
      CatchException(exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case EmbossCommand:
    {
      Image
        *emboss_image;

      static char
        radius[MagickPathExtent] = "0.0x1.0";

      /*
        Query user for emboss radius.
      */
      (void) XDialogWidget(display,windows,"Emboss",
        "Enter the emboss radius and standard deviation:",radius);
      if (*radius == '\0')
        break;
      /*
        Reduce noise in the image.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      flags=ParseGeometry(radius,&geometry_info);
      if ((flags & SigmaValue) == 0)
        geometry_info.sigma=1.0;
      emboss_image=EmbossImage(*image,geometry_info.rho,geometry_info.sigma,
        exception);
      if (emboss_image != (Image *) NULL)
        {
          *image=DestroyImage(*image);
          *image=emboss_image;
        }
      CatchException(exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case ReduceNoiseCommand:
    {
      Image
        *noise_image;

      static char
        radius[MagickPathExtent] = "0";

      /*
        Query user for noise radius.
      */
      (void) XDialogWidget(display,windows,"Reduce Noise",
        "Enter the noise radius:",radius);
      if (*radius == '\0')
        break;
      /*
        Reduce noise in the image.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      flags=ParseGeometry(radius,&geometry_info);
      noise_image=StatisticImage(*image,NonpeakStatistic,(size_t)
        geometry_info.rho,(size_t) geometry_info.rho,exception);
      if (noise_image != (Image *) NULL)
        {
          *image=DestroyImage(*image);
          *image=noise_image;
        }
      CatchException(exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case AddNoiseCommand:
    {
      char
        **noises;

      Image
        *noise_image;

      static char
        noise_type[MagickPathExtent] = "Gaussian";

      /*
        Add noise to the image.
      */
      noises=GetCommandOptions(MagickNoiseOptions);
      if (noises == (char **) NULL)
        break;
      XListBrowserWidget(display,windows,&windows->widget,
        (const char **) noises,"Add Noise",
        "Select a type of noise to add to your image:",noise_type);
      noises=DestroyStringList(noises);
      if (*noise_type == '\0')
        break;
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      noise_image=AddNoiseImage(*image,(NoiseType) ParseCommandOption(
        MagickNoiseOptions,MagickFalse,noise_type),1.0,exception);
      if (noise_image != (Image *) NULL)
        {
          *image=DestroyImage(*image);
          *image=noise_image;
        }
      CatchException(exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case SharpenCommand:
    {
      Image
        *sharp_image;

      static char
        radius[MagickPathExtent] = "0.0x1.0";

      /*
        Query user for sharpen radius.
      */
      (void) XDialogWidget(display,windows,"Sharpen",
        "Enter the sharpen radius and standard deviation:",radius);
      if (*radius == '\0')
        break;
      /*
        Sharpen image scanlines.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      flags=ParseGeometry(radius,&geometry_info);
      sharp_image=SharpenImage(*image,geometry_info.rho,geometry_info.sigma,
        exception);
      if (sharp_image != (Image *) NULL)
        {
          *image=DestroyImage(*image);
          *image=sharp_image;
        }
      CatchException(exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case BlurCommand:
    {
      Image
        *blur_image;

      static char
        radius[MagickPathExtent] = "0.0x1.0";

      /*
        Query user for blur radius.
      */
      (void) XDialogWidget(display,windows,"Blur",
        "Enter the blur radius and standard deviation:",radius);
      if (*radius == '\0')
        break;
      /*
        Blur an image.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      flags=ParseGeometry(radius,&geometry_info);
      blur_image=BlurImage(*image,geometry_info.rho,geometry_info.sigma,
        exception);
      if (blur_image != (Image *) NULL)
        {
          *image=DestroyImage(*image);
          *image=blur_image;
        }
      CatchException(exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case ThresholdCommand:
    {
      double
        threshold;

      static char
        factor[MagickPathExtent] = "128";

      /*
        Query user for threshold value.
      */
      (void) XDialogWidget(display,windows,"Threshold",
        "Enter threshold value:",factor);
      if (*factor == '\0')
        break;
      /*
        Gamma correct image.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      threshold=StringToDoubleInterval(factor,(double) QuantumRange+1.0);
      (void) BilevelImage(*image,threshold,exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case EdgeDetectCommand:
    {
      Image
        *edge_image;

      static char
        radius[MagickPathExtent] = "0";

      /*
        Query user for edge factor.
      */
      (void) XDialogWidget(display,windows,"Detect Edges",
        "Enter the edge detect radius:",radius);
      if (*radius == '\0')
        break;
      /*
        Detect edge in image.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      flags=ParseGeometry(radius,&geometry_info);
      edge_image=EdgeImage(*image,geometry_info.rho,exception);
      if (edge_image != (Image *) NULL)
        {
          *image=DestroyImage(*image);
          *image=edge_image;
        }
      CatchException(exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case SpreadCommand:
    {
      Image
        *spread_image;

      static char
        amount[MagickPathExtent] = "2";

      /*
        Query user for spread amount.
      */
      (void) XDialogWidget(display,windows,"Spread",
        "Enter the displacement amount:",amount);
      if (*amount == '\0')
        break;
      /*
        Displace image pixels by a random amount.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      flags=ParseGeometry(amount,&geometry_info);
      spread_image=EdgeImage(*image,geometry_info.rho,exception);
      if (spread_image != (Image *) NULL)
        {
          *image=DestroyImage(*image);
          *image=spread_image;
        }
      CatchException(exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case ShadeCommand:
    {
      Image
        *shade_image;

      int
        status;

      static char
        geometry[MagickPathExtent] = "30x30";

      /*
        Query user for the shade geometry.
      */
      status=XDialogWidget(display,windows,"Shade",
        "Enter the azimuth and elevation of the light source:",geometry);
      if (*geometry == '\0')
        break;
      /*
        Shade image pixels.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      flags=ParseGeometry(geometry,&geometry_info);
      if ((flags & SigmaValue) == 0)
        geometry_info.sigma=1.0;
      shade_image=ShadeImage(*image,status != 0 ? MagickTrue : MagickFalse,
        geometry_info.rho,geometry_info.sigma,exception);
      if (shade_image != (Image *) NULL)
        {
          *image=DestroyImage(*image);
          *image=shade_image;
        }
      CatchException(exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case RaiseCommand:
    {
      static char
        bevel_width[MagickPathExtent] = "10";

      /*
        Query user for bevel width.
      */
      (void) XDialogWidget(display,windows,"Raise","Bevel width:",bevel_width);
      if (*bevel_width == '\0')
        break;
      /*
        Raise an image.
      */
      (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
        exception);
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      (void) ParsePageGeometry(*image,bevel_width,&page_geometry,
        exception);
      (void) RaiseImage(*image,&page_geometry,MagickTrue,exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case SegmentCommand:
    {
      static char
        threshold[MagickPathExtent] = "1.0x1.5";

      /*
        Query user for smoothing threshold.
      */
      (void) XDialogWidget(display,windows,"Segment","Smooth threshold:",
        threshold);
      if (*threshold == '\0')
        break;
      /*
        Segment an image.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      flags=ParseGeometry(threshold,&geometry_info);
      if ((flags & SigmaValue) == 0)
        geometry_info.sigma=1.0;
      (void) SegmentImage(*image,sRGBColorspace,MagickFalse,geometry_info.rho,
        geometry_info.sigma,exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case SepiaToneCommand:
    {
      double
        threshold;

      Image
        *sepia_image;

      static char
        factor[MagickPathExtent] = "80%";

      /*
        Query user for sepia-tone factor.
      */
      (void) XDialogWidget(display,windows,"Sepia Tone",
        "Enter the sepia tone factor (0 - 99.9%):",factor);
      if (*factor == '\0')
        break;
      /*
        Sepia tone image pixels.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      threshold=StringToDoubleInterval(factor,(double) QuantumRange+1.0);
      sepia_image=SepiaToneImage(*image,threshold,exception);
      if (sepia_image != (Image *) NULL)
        {
          *image=DestroyImage(*image);
          *image=sepia_image;
        }
      CatchException(exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case SolarizeCommand:
    {
      double
        threshold;

      static char
        factor[MagickPathExtent] = "60%";

      /*
        Query user for solarize factor.
      */
      (void) XDialogWidget(display,windows,"Solarize",
        "Enter the solarize factor (0 - 99.9%):",factor);
      if (*factor == '\0')
        break;
      /*
        Solarize image pixels.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      threshold=StringToDoubleInterval(factor,(double) QuantumRange+1.0);
      (void) SolarizeImage(*image,threshold,exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case SwirlCommand:
    {
      Image
        *swirl_image;

      static char
        degrees[MagickPathExtent] = "60";

      /*
        Query user for swirl angle.
      */
      (void) XDialogWidget(display,windows,"Swirl","Enter the swirl angle:",
        degrees);
      if (*degrees == '\0')
        break;
      /*
        Swirl image pixels about the center.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      flags=ParseGeometry(degrees,&geometry_info);
      swirl_image=SwirlImage(*image,geometry_info.rho,(*image)->interpolate,
        exception);
      if (swirl_image != (Image *) NULL)
        {
          *image=DestroyImage(*image);
          *image=swirl_image;
        }
      CatchException(exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case ImplodeCommand:
    {
      Image
        *implode_image;

      static char
        factor[MagickPathExtent] = "0.3";

      /*
        Query user for implode factor.
      */
      (void) XDialogWidget(display,windows,"Implode",
        "Enter the implosion/explosion factor (-1.0 - 1.0):",factor);
      if (*factor == '\0')
        break;
      /*
        Implode image pixels about the center.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      flags=ParseGeometry(factor,&geometry_info);
      implode_image=ImplodeImage(*image,geometry_info.rho,(*image)->interpolate,
        exception);
      if (implode_image != (Image *) NULL)
        {
          *image=DestroyImage(*image);
          *image=implode_image;
        }
      CatchException(exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case VignetteCommand:
    {
      Image
        *vignette_image;

      static char
        geometry[MagickPathExtent] = "0x20";

      /*
        Query user for the vignette geometry.
      */
      (void) XDialogWidget(display,windows,"Vignette",
        "Enter the radius, sigma, and x and y offsets:",geometry);
      if (*geometry == '\0')
        break;
      /*
        Soften the edges of the image in vignette style
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      flags=ParseGeometry(geometry,&geometry_info);
      if ((flags & SigmaValue) == 0)
        geometry_info.sigma=1.0;
      if ((flags & XiValue) == 0)
        geometry_info.xi=0.1*(*image)->columns;
      if ((flags & PsiValue) == 0)
        geometry_info.psi=0.1*(*image)->rows;
      vignette_image=VignetteImage(*image,geometry_info.rho,0.0,(ssize_t)
        ceil(geometry_info.xi-0.5),(ssize_t) ceil(geometry_info.psi-0.5),
        exception);
      if (vignette_image != (Image *) NULL)
        {
          *image=DestroyImage(*image);
          *image=vignette_image;
        }
      CatchException(exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case WaveCommand:
    {
      Image
        *wave_image;

      static char
        geometry[MagickPathExtent] = "25x150";

      /*
        Query user for the wave geometry.
      */
      (void) XDialogWidget(display,windows,"Wave",
        "Enter the amplitude and length of the wave:",geometry);
      if (*geometry == '\0')
        break;
      /*
        Alter an image along a sine wave.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      flags=ParseGeometry(geometry,&geometry_info);
      if ((flags & SigmaValue) == 0)
        geometry_info.sigma=1.0;
      wave_image=WaveImage(*image,geometry_info.rho,geometry_info.sigma,
        (*image)->interpolate,exception);
      if (wave_image != (Image *) NULL)
        {
          *image=DestroyImage(*image);
          *image=wave_image;
        }
      CatchException(exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case OilPaintCommand:
    {
      Image
        *paint_image;

      static char
        radius[MagickPathExtent] = "0";

      /*
        Query user for circular neighborhood radius.
      */
      (void) XDialogWidget(display,windows,"Oil Paint",
        "Enter the mask radius:",radius);
      if (*radius == '\0')
        break;
      /*
        OilPaint image scanlines.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      flags=ParseGeometry(radius,&geometry_info);
      paint_image=OilPaintImage(*image,geometry_info.rho,geometry_info.sigma,
        exception);
      if (paint_image != (Image *) NULL)
        {
          *image=DestroyImage(*image);
          *image=paint_image;
        }
      CatchException(exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case CharcoalDrawCommand:
    {
      Image
        *charcoal_image;

      static char
        radius[MagickPathExtent] = "0x1";

      /*
        Query user for charcoal radius.
      */
      (void) XDialogWidget(display,windows,"Charcoal Draw",
        "Enter the charcoal radius and sigma:",radius);
      if (*radius == '\0')
        break;
      /*
        Charcoal the image.
      */
      (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
        exception);
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      flags=ParseGeometry(radius,&geometry_info);
      if ((flags & SigmaValue) == 0)
        geometry_info.sigma=geometry_info.rho;
      charcoal_image=CharcoalImage(*image,geometry_info.rho,geometry_info.sigma,
        exception);
      if (charcoal_image != (Image *) NULL)
        {
          *image=DestroyImage(*image);
          *image=charcoal_image;
        }
      CatchException(exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case AnnotateCommand:
    {
      /*
        Annotate the image with text.
      */
      status=XAnnotateEditImage(display,resource_info,windows,*image,exception);
      if (status == MagickFalse)
        {
          XNoticeWidget(display,windows,"Unable to annotate X image",
            (*image)->filename);
          break;
        }
      break;
    }
    case DrawCommand:
    {
      /*
        Draw image.
      */
      status=XDrawEditImage(display,resource_info,windows,image,exception);
      if (status == MagickFalse)
        {
          XNoticeWidget(display,windows,"Unable to draw on the X image",
            (*image)->filename);
          break;
        }
      break;
    }
    case ColorCommand:
    {
      /*
        Color edit.
      */
      status=XColorEditImage(display,resource_info,windows,image,exception);
      if (status == MagickFalse)
        {
          XNoticeWidget(display,windows,"Unable to pixel edit X image",
            (*image)->filename);
          break;
        }
      break;
    }
    case MatteCommand:
    {
      /*
        Matte edit.
      */
      status=XMatteEditImage(display,resource_info,windows,image,exception);
      if (status == MagickFalse)
        {
          XNoticeWidget(display,windows,"Unable to matte edit X image",
            (*image)->filename);
          break;
        }
      break;
    }
    case CompositeCommand:
    {
      /*
        Composite image.
      */
      status=XCompositeImage(display,resource_info,windows,*image,
        exception);
      if (status == MagickFalse)
        {
          XNoticeWidget(display,windows,"Unable to composite X image",
            (*image)->filename);
          break;
        }
      break;
    }
    case AddBorderCommand:
    {
      Image
        *border_image;

      static char
        geometry[MagickPathExtent] = "6x6";

      /*
        Query user for border color and geometry.
      */
      XColorBrowserWidget(display,windows,"Select",color);
      if (*color == '\0')
        break;
      (void) XDialogWidget(display,windows,"Add Border",
        "Enter border geometry:",geometry);
      if (*geometry == '\0')
        break;
      /*
        Add a border to the image.
      */
      (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
        exception);
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      (void) QueryColorCompliance(color,AllCompliance,&(*image)->border_color,
        exception);
      (void) ParsePageGeometry(*image,geometry,&page_geometry,
        exception);
      border_image=BorderImage(*image,&page_geometry,(*image)->compose,
        exception);
      if (border_image != (Image *) NULL)
        {
          *image=DestroyImage(*image);
          *image=border_image;
        }
      CatchException(exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      windows->image.window_changes.width=(int) (*image)->columns;
      windows->image.window_changes.height=(int) (*image)->rows;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case AddFrameCommand:
    {
      FrameInfo
        frame_info;

      Image
        *frame_image;

      static char
        geometry[MagickPathExtent] = "6x6";

      /*
        Query user for frame color and geometry.
      */
      XColorBrowserWidget(display,windows,"Select",color);
      if (*color == '\0')
        break;
      (void) XDialogWidget(display,windows,"Add Frame","Enter frame geometry:",
        geometry);
      if (*geometry == '\0')
        break;
      /*
        Surround image with an ornamental border.
      */
      (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
        exception);
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      (void) QueryColorCompliance(color,AllCompliance,&(*image)->matte_color,
        exception);
      (void) ParsePageGeometry(*image,geometry,&page_geometry,
        exception);
      frame_info.width=page_geometry.width;
      frame_info.height=page_geometry.height;
      frame_info.outer_bevel=page_geometry.x;
      frame_info.inner_bevel=page_geometry.y;
      frame_info.x=(ssize_t) frame_info.width;
      frame_info.y=(ssize_t) frame_info.height;
      frame_info.width=(*image)->columns+2*frame_info.width;
      frame_info.height=(*image)->rows+2*frame_info.height;
      frame_image=FrameImage(*image,&frame_info,(*image)->compose,exception);
      if (frame_image != (Image *) NULL)
        {
          *image=DestroyImage(*image);
          *image=frame_image;
        }
      CatchException(exception);
      XSetCursorState(display,windows,MagickFalse);
      if (windows->image.orphan != MagickFalse)
        break;
      windows->image.window_changes.width=(int) (*image)->columns;
      windows->image.window_changes.height=(int) (*image)->rows;
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
      (void) XConfigureImage(display,resource_info,windows,*image,exception);
      break;
    }
    case CommentCommand:
    {
      const char
        *value;

      FILE
        *file;

      int
        unique_file;

      /*
        Edit image comment.
      */
      unique_file=AcquireUniqueFileResource(image_info->filename);
      if (unique_file == -1)
        XNoticeWidget(display,windows,"Unable to edit image comment",
          image_info->filename);
      value=GetImageProperty(*image,"comment",exception);
      if (value == (char *) NULL)
        unique_file=close(unique_file)-1;
      else
        {
          const char
            *p;

          file=fdopen(unique_file,"w");
          if (file == (FILE *) NULL)
            {
              XNoticeWidget(display,windows,"Unable to edit image comment",
                image_info->filename);
              break;
            }
          for (p=value; *p != '\0'; p++)
            (void) fputc((int) *p,file);
          (void) fputc('\n',file);
          (void) fclose(file);
        }
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      status=InvokeDelegate(image_info,*image,"edit",(char *) NULL,
        exception);
      if (status == MagickFalse)
        XNoticeWidget(display,windows,"Unable to edit image comment",
          (char *) NULL);
      else
        {
          char
            *comment;

          comment=FileToString(image_info->filename,~0UL,exception);
          if (comment != (char *) NULL)
            {
              (void) SetImageProperty(*image,"comment",comment,exception);
              (*image)->taint=MagickTrue;
            }
        }
      (void) RelinquishUniqueFileResource(image_info->filename);
      XSetCursorState(display,windows,MagickFalse);
      break;
    }
    case LaunchCommand:
    {
      /*
        Launch program.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      (void) AcquireUniqueFilename(filename);
      (void) FormatLocaleString((*image)->filename,MagickPathExtent,"launch:%s",
        filename);
      status=WriteImage(image_info,*image,exception);
      if (status == MagickFalse)
        XNoticeWidget(display,windows,"Unable to launch image editor",
          (char *) NULL);
      else
        {
          nexus=ReadImage(resource_info->image_info,exception);
          CatchException(exception);
          XClientMessage(display,windows->image.id,windows->im_protocols,
            windows->im_next_image,CurrentTime);
        }
      (void) RelinquishUniqueFileResource(filename);
      XSetCursorState(display,windows,MagickFalse);
      break;
    }
    case RegionofInterestCommand:
    {
      /*
        Apply an image processing technique to a region of interest.
      */
      (void) XROIImage(display,resource_info,windows,image,exception);
      break;
    }
    case InfoCommand:
      break;
    case ZoomCommand:
    {
      /*
        Zoom image.
      */
      if (windows->magnify.mapped != MagickFalse)
        (void) XRaiseWindow(display,windows->magnify.id);
      else
        {
          /*
            Make magnify image.
          */
          XSetCursorState(display,windows,MagickTrue);
          (void) XMapRaised(display,windows->magnify.id);
          XSetCursorState(display,windows,MagickFalse);
        }
      break;
    }
    case ShowPreviewCommand:
    {
      char
        **previews;

      Image
        *preview_image;

      PreviewType
        preview;

      static char
        preview_type[MagickPathExtent] = "Gamma";

      /*
        Select preview type from menu.
      */
      previews=GetCommandOptions(MagickPreviewOptions);
      if (previews == (char **) NULL)
        break;
      XListBrowserWidget(display,windows,&windows->widget,
        (const char **) previews,"Preview",
        "Select an enhancement, effect, or F/X:",preview_type);
      previews=DestroyStringList(previews);
      if (*preview_type == '\0')
        break;
      /*
        Show image preview.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      preview=(PreviewType) ParseCommandOption(MagickPreviewOptions,
        MagickFalse,preview_type);
      (void) FormatImageProperty(*image,"group","%.20g",(double)
        windows->image.id);
      (void) DeleteImageProperty(*image,"label");
      (void) SetImageProperty(*image,"label","Preview",exception);
      preview_image=PreviewImage(*image,preview,exception);
      if (preview_image == (Image *) NULL)
        break;
      (void) AcquireUniqueFilename(filename);
      (void) FormatLocaleString(preview_image->filename,MagickPathExtent,
        "show:%s",filename);
      status=WriteImage(image_info,preview_image,exception);
      (void) RelinquishUniqueFileResource(filename);
      preview_image=DestroyImage(preview_image);
      if (status == MagickFalse)
        XNoticeWidget(display,windows,"Unable to show image preview",
          (*image)->filename);
      XDelay(display,1500);
      XSetCursorState(display,windows,MagickFalse);
      break;
    }
    case ShowHistogramCommand:
    {
      Image
        *histogram_image;

      /*
        Show image histogram.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      (void) DeleteImageProperty(*image,"label");
      (void) FormatImageProperty(*image,"group","%.20g",(double)
        windows->image.id);
      (void) SetImageProperty(*image,"label","Histogram",exception);
      (void) AcquireUniqueFilename(filename);
      (void) FormatLocaleString((*image)->filename,MagickPathExtent,
        "histogram:%s",filename);
      status=WriteImage(image_info,*image,exception);
      (void) CopyMagickString(image_info->filename,filename,MagickPathExtent);
      histogram_image=ReadImage(image_info,exception);
      (void) RelinquishUniqueFileResource(filename);
      if (histogram_image == (Image *) NULL)
        break;
      (void) FormatLocaleString(histogram_image->filename,MagickPathExtent,
        "show:%s",filename);
      status=WriteImage(image_info,histogram_image,exception);
      histogram_image=DestroyImage(histogram_image);
      if (status == MagickFalse)
        XNoticeWidget(display,windows,"Unable to show histogram",
          (*image)->filename);
      XDelay(display,1500);
      XSetCursorState(display,windows,MagickFalse);
      break;
    }
    case ShowMatteCommand:
    {
      Image
        *matte_image;

      if ((*image)->alpha_trait == UndefinedPixelTrait)
        {
          XNoticeWidget(display,windows,
            "Image does not have any matte information",(*image)->filename);
          break;
        }
      /*
        Show image matte.
      */
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      (void) FormatImageProperty(*image,"group","%.20g",(double)
        windows->image.id);
      (void) DeleteImageProperty(*image,"label");
      (void) SetImageProperty(*image,"label","Matte",exception);
      (void) AcquireUniqueFilename(filename);
      (void) FormatLocaleString((*image)->filename,MagickPathExtent,"matte:%s",
        filename);
      status=WriteImage(image_info,*image,exception);
      (void) CopyMagickString(image_info->filename,filename,MagickPathExtent);
      matte_image=ReadImage(image_info,exception);
      (void) RelinquishUniqueFileResource(filename);
      if (matte_image == (Image *) NULL)
        break;
      (void) FormatLocaleString(matte_image->filename,MagickPathExtent,
        "show:%s",filename);
      status=WriteImage(image_info,matte_image,exception);
      matte_image=DestroyImage(matte_image);
      if (status == MagickFalse)
        XNoticeWidget(display,windows,"Unable to show matte",
          (*image)->filename);
      XDelay(display,1500);
      XSetCursorState(display,windows,MagickFalse);
      break;
    }
    case BackgroundCommand:
    {
      /*
        Background image.
      */
      status=XBackgroundImage(display,resource_info,windows,image,exception);
      if (status == MagickFalse)
        break;
      nexus=CloneImage(*image,0,0,MagickTrue,exception);
      if (nexus != (Image *) NULL)
        XClientMessage(display,windows->image.id,windows->im_protocols,
          windows->im_next_image,CurrentTime);
      break;
    }
    case SlideShowCommand:
    {
      static char
        delay[MagickPathExtent] = "5";

      /*
        Display next image after pausing.
      */
      (void) XDialogWidget(display,windows,"Slide Show",
        "Pause how many 1/100ths of a second between images:",delay);
      if (*delay == '\0')
        break;
      resource_info->delay=StringToUnsignedLong(delay);
      XClientMessage(display,windows->image.id,windows->im_protocols,
        windows->im_next_image,CurrentTime);
      break;
    }
    case PreferencesCommand:
    {
      /*
        Set user preferences.
      */
      status=XPreferencesWidget(display,resource_info,windows);
      if (status == MagickFalse)
        break;
      nexus=CloneImage(*image,0,0,MagickTrue,exception);
      if (nexus != (Image *) NULL)
        XClientMessage(display,windows->image.id,windows->im_protocols,
          windows->im_next_image,CurrentTime);
      break;
    }
    case HelpCommand:
    {
      /*
        User requested help.
      */
      XTextViewHelp(display,resource_info,windows,MagickFalse,
        "Help Viewer - Display",DisplayHelp);
      break;
    }
    case BrowseDocumentationCommand:
    {
      Atom
        mozilla_atom;

      Window
        mozilla_window,
        root_window;

      /*
        Browse the ImageMagick documentation.
      */
      root_window=XRootWindow(display,XDefaultScreen(display));
      mozilla_atom=XInternAtom(display,"_MOZILLA_VERSION",MagickFalse);
      mozilla_window=XWindowByProperty(display,root_window,mozilla_atom);
      if (mozilla_window != (Window) NULL)
        {
          char
            command[MagickPathExtent];

          /*
            Display documentation using Netscape remote control.
          */
          (void) FormatLocaleString(command,MagickPathExtent,
            "openurl(%s,new-tab)",MagickAuthoritativeURL);
          mozilla_atom=XInternAtom(display,"_MOZILLA_COMMAND",MagickFalse);
          (void) XChangeProperty(display,mozilla_window,mozilla_atom,XA_STRING,
            8,PropModeReplace,(unsigned char *) command,(int) strlen(command));
          XSetCursorState(display,windows,MagickFalse);
          break;
        }
      XSetCursorState(display,windows,MagickTrue);
      XCheckRefreshWindows(display,windows);
      status=InvokeDelegate(image_info,*image,"browse",(char *) NULL,
        exception);
      if (status == MagickFalse)
        XNoticeWidget(display,windows,"Unable to browse documentation",
          (char *) NULL);
      XDelay(display,1500);
      XSetCursorState(display,windows,MagickFalse);
      break;
    }
    case VersionCommand:
    {
      XNoticeWidget(display,windows,GetMagickVersion((size_t *) NULL),
        GetMagickCopyright());
      break;
    }
    case SaveToUndoBufferCommand:
      break;
    default:
    {
      (void) XBell(display,0);
      break;
    }
  }
  image_info=DestroyImageInfo(image_info);
  return(nexus);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X M a g n i f y I m a g e                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XMagnifyImage() magnifies portions of the image as indicated by the pointer.
%  The magnified portion is displayed in a separate window.
%
%  The format of the XMagnifyImage method is:
%
%      void XMagnifyImage(Display *display,XWindows *windows,XEvent *event,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o display: Specifies a connection to an X server;  returned from
%      XOpenDisplay.
%
%    o windows: Specifies a pointer to a XWindows structure.
%
%    o event: Specifies a pointer to a XEvent structure.  If it is NULL,
%      the entire image is refreshed.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static void XMagnifyImage(Display *display,XWindows *windows,XEvent *event,
  ExceptionInfo *exception)
{
  char
    text[MagickPathExtent];

  int
    x,
    y;

  size_t
    state;

  /*
    Update magnified image until the mouse button is released.
  */
  (void) XCheckDefineCursor(display,windows->image.id,windows->magnify.cursor);
  state=DefaultState;
  x=event->xbutton.x;
  y=event->xbutton.y;
  windows->magnify.x=(int) windows->image.x+x;
  windows->magnify.y=(int) windows->image.y+y;
  do
  {
    /*
      Map and unmap Info widget as text cursor crosses its boundaries.
    */
    if (windows->info.mapped != MagickFalse)
      {
        if ((x < (int) (windows->info.x+windows->info.width)) &&
            (y < (int) (windows->info.y+windows->info.height)))
          (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
      }
    else
      if ((x > (int) (windows->info.x+windows->info.width)) ||
          (y > (int) (windows->info.y+windows->info.height)))
        (void) XMapWindow(display,windows->info.id);
    if (windows->info.mapped != MagickFalse)
      {
        /*
          Display pointer position.
        */
        (void) FormatLocaleString(text,MagickPathExtent," %+d%+d ",
          windows->magnify.x,windows->magnify.y);
        XInfoWidget(display,windows,text);
      }
    /*
      Wait for next event.
    */
    XScreenEvent(display,windows,event,exception);
    switch (event->type)
    {
      case ButtonPress:
        break;
      case ButtonRelease:
      {
        /*
          User has finished magnifying image.
        */
        x=event->xbutton.x;
        y=event->xbutton.y;
        state|=ExitState;
        break;
      }
      case Expose:
        break;
      case MotionNotify:
      {
        x=event->xmotion.x;
        y=event->xmotion.y;
        break;
      }
      default:
        break;
    }
    /*
      Check boundary conditions.
    */
    if (x < 0)
      x=0;
    else
      if (x >= (int) windows->image.width)
        x=(int) windows->image.width-1;
    if (y < 0)
      y=0;
    else
     if (y >= (int) windows->image.height)
       y=(int) windows->image.height-1;
  } while ((state & ExitState) == 0);
  /*
    Display magnified image.
  */
  XSetCursorState(display,windows,MagickFalse);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X M a g n i f y W i n d o w C o m m a n d                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XMagnifyWindowCommand() moves the image within an Magnify window by one
%  pixel as specified by the key symbol.
%
%  The format of the XMagnifyWindowCommand method is:
%
%      void XMagnifyWindowCommand(Display *display,XWindows *windows,
%        const MagickStatusType state,const KeySym key_symbol,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o display: Specifies a connection to an X server; returned from
%      XOpenDisplay.
%
%    o windows: Specifies a pointer to a XWindows structure.
%
%    o state: key mask.
%
%    o key_symbol: Specifies a KeySym which indicates which side of the image
%      to trim.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static void XMagnifyWindowCommand(Display *display,XWindows *windows,
  const MagickStatusType state,const KeySym key_symbol,ExceptionInfo *exception)
{
  unsigned int
    quantum;

  /*
    User specified a magnify factor or position.
  */
  quantum=1;
  if ((state & Mod1Mask) != 0)
    quantum=10;
  switch ((int) key_symbol)
  {
    case QuitCommand:
    {
      (void) XWithdrawWindow(display,windows->magnify.id,
        windows->magnify.screen);
      break;
    }
    case XK_Home:
    case XK_KP_Home:
    {
      windows->magnify.x=(int) windows->image.width/2;
      windows->magnify.y=(int) windows->image.height/2;
      break;
    }
    case XK_Left:
    case XK_KP_Left:
    {
      if (windows->magnify.x > 0)
        windows->magnify.x-=quantum;
      break;
    }
    case XK_Up:
    case XK_KP_Up:
    {
      if (windows->magnify.y > 0)
        windows->magnify.y-=quantum;
      break;
    }
    case XK_Right:
    case XK_KP_Right:
    {
      if (windows->magnify.x < (int) (windows->image.ximage->width-1))
        windows->magnify.x+=quantum;
      break;
    }
    case XK_Down:
    case XK_KP_Down:
    {
      if (windows->magnify.y < (int) (windows->image.ximage->height-1))
        windows->magnify.y+=quantum;
      break;
    }
    case XK_0:
    case XK_1:
    case XK_2:
    case XK_3:
    case XK_4:
    case XK_5:
    case XK_6:
    case XK_7:
    case XK_8:
    case XK_9:
    {
      windows->magnify.data=(key_symbol-XK_0);
      break;
    }
    case XK_KP_0:
    case XK_KP_1:
    case XK_KP_2:
    case XK_KP_3:
    case XK_KP_4:
    case XK_KP_5:
    case XK_KP_6:
    case XK_KP_7:
    case XK_KP_8:
    case XK_KP_9:
    {
      windows->magnify.data=(key_symbol-XK_KP_0);
      break;
    }
    default:
      break;
  }
  XMakeMagnifyImage(display,windows,exception);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X M a k e P a n I m a g e                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XMakePanImage() creates a thumbnail of the image and displays it in the Pan
%  icon window.
%
%  The format of the XMakePanImage method is:
%
%        void XMakePanImage(Display *display,XResourceInfo *resource_info,
%          XWindows *windows,Image *image,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o display: Specifies a connection to an X server;  returned from
%      XOpenDisplay.
%
%    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
%
%    o windows: Specifies a pointer to a XWindows structure.
%
%    o image: the image.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static void XMakePanImage(Display *display,XResourceInfo *resource_info,
  XWindows *windows,Image *image,ExceptionInfo *exception)
{
  MagickStatusType
    status;

  /*
    Create and display image for panning icon.
  */
  XSetCursorState(display,windows,MagickTrue);
  XCheckRefreshWindows(display,windows);
  windows->pan.x=(int) windows->image.x;
  windows->pan.y=(int) windows->image.y;
  status=XMakeImage(display,resource_info,&windows->pan,image,
    windows->pan.width,windows->pan.height,exception);
  if (status == MagickFalse)
    ThrowXWindowException(ResourceLimitError,
     "MemoryAllocationFailed",image->filename);
  (void) XSetWindowBackgroundPixmap(display,windows->pan.id,
    windows->pan.pixmap);
  (void) XClearWindow(display,windows->pan.id);
  XDrawPanRectangle(display,windows);
  XSetCursorState(display,windows,MagickFalse);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X M a t t a E d i t I m a g e                                             %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XMatteEditImage() allows the user to interactively change the Matte channel
%  of an image.  If the image is PseudoClass it is promoted to DirectClass
%  before the matte information is stored.
%
%  The format of the XMatteEditImage method is:
%
%      MagickBooleanType XMatteEditImage(Display *display,
%        XResourceInfo *resource_info,XWindows *windows,Image **image,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o display: Specifies a connection to an X server;  returned from
%      XOpenDisplay.
%
%    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
%
%    o windows: Specifies a pointer to a XWindows structure.
%
%    o image: the image; returned from ReadImage.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static MagickBooleanType XMatteEditImage(Display *display,
  XResourceInfo *resource_info,XWindows *windows,Image **image,
  ExceptionInfo *exception)
{
  const char
    *const MatteEditMenu[] =
    {
      "Method",
      "Border Color",
      "Fuzz",
      "Matte Value",
      "Undo",
      "Help",
      "Dismiss",
      (char *) NULL
    };

  static char
    matte[MagickPathExtent] = "0";

  static const ModeType
    MatteEditCommands[] =
    {
      MatteEditMethod,
      MatteEditBorderCommand,
      MatteEditFuzzCommand,
      MatteEditValueCommand,
      MatteEditUndoCommand,
      MatteEditHelpCommand,
      MatteEditDismissCommand
    };

  static PaintMethod
    method = PointMethod;

  static XColor
    border_color = { 0, 0, 0, 0, 0, 0 };

  char
    command[MagickPathExtent],
    text[MagickPathExtent];

  Cursor
    cursor;

  int
    entry,
    id,
    x,
    x_offset,
    y,
    y_offset;

  int
    i;

  Quantum
    *q;

  unsigned int
    height,
    width;

  size_t
    state;

  XEvent
    event;

  /*
    Map Command widget.
  */
  (void) CloneString(&windows->command.name,"Matte Edit");
  windows->command.data=4;
  (void) XCommandWidget(display,windows,MatteEditMenu,(XEvent *) NULL);
  (void) XMapRaised(display,windows->command.id);
  XClientMessage(display,windows->image.id,windows->im_protocols,
    windows->im_update_widget,CurrentTime);
  /*
    Make cursor.
  */
  cursor=XMakeCursor(display,windows->image.id,windows->map_info->colormap,
    resource_info->background_color,resource_info->foreground_color);
  (void) XCheckDefineCursor(display,windows->image.id,cursor);
  /*
    Track pointer until button 1 is pressed.
  */
  XQueryPosition(display,windows->image.id,&x,&y);
  (void) XSelectInput(display,windows->image.id,
    windows->image.attributes.event_mask | PointerMotionMask);
  state=DefaultState;
  do
  {
    if (windows->info.mapped != MagickFalse)
      {
        /*
          Display pointer position.
        */
        (void) FormatLocaleString(text,MagickPathExtent," %+d%+d ",
          x+windows->image.x,y+windows->image.y);
        XInfoWidget(display,windows,text);
      }
    /*
      Wait for next event.
    */
    XScreenEvent(display,windows,&event,exception);
    if (event.xany.window == windows->command.id)
      {
        /*
          Select a command from the Command widget.
        */
        id=XCommandWidget(display,windows,MatteEditMenu,&event);
        if (id < 0)
          {
            (void) XCheckDefineCursor(display,windows->image.id,cursor);
            continue;
          }
        switch (MatteEditCommands[id])
        {
          case MatteEditMethod:
          {
            char
              **methods;

            /*
              Select a method from the pop-up menu.
            */
            methods=GetCommandOptions(MagickMethodOptions);
            if (methods == (char **) NULL)
              break;
            entry=XMenuWidget(display,windows,MatteEditMenu[id],
              (const char **) methods,command);
            if (entry >= 0)
              method=(PaintMethod) ParseCommandOption(MagickMethodOptions,
                MagickFalse,methods[entry]);
            methods=DestroyStringList(methods);
            break;
          }
          case MatteEditBorderCommand:
          {
            const char
              *ColorMenu[MaxNumberPens];

            int
              pen_number;

            /*
              Initialize menu selections.
            */
            for (i=0; i < (int) (MaxNumberPens-2); i++)
              ColorMenu[i]=resource_info->pen_colors[i];
            ColorMenu[MaxNumberPens-2]="Browser...";
            ColorMenu[MaxNumberPens-1]=(const char *) NULL;
            /*
              Select a pen color from the pop-up menu.
            */
            pen_number=XMenuWidget(display,windows,MatteEditMenu[id],
              (const char **) ColorMenu,command);
            if (pen_number < 0)
              break;
            if (pen_number == (MaxNumberPens-2))
              {
                static char
                  color_name[MagickPathExtent] = "gray";

                /*
                  Select a pen color from a dialog.
                */
                resource_info->pen_colors[pen_number]=color_name;
                XColorBrowserWidget(display,windows,"Select",color_name);
                if (*color_name == '\0')
                  break;
              }
            /*
              Set border color.
            */
            (void) XParseColor(display,windows->map_info->colormap,
              resource_info->pen_colors[pen_number],&border_color);
            break;
          }
          case MatteEditFuzzCommand:
          {
            const char
              *const FuzzMenu[] =
              {
                "0%",
                "2%",
                "5%",
                "10%",
                "15%",
                "Dialog...",
                (char *) NULL,
              };

            static char
              fuzz[MagickPathExtent];

            /*
              Select a command from the pop-up menu.
            */
            entry=XMenuWidget(display,windows,MatteEditMenu[id],FuzzMenu,
              command);
            if (entry < 0)
              break;
            if (entry != 5)
              {
                (*image)->fuzz=StringToDoubleInterval(FuzzMenu[entry],(double)
                  QuantumRange+1.0);
                break;
              }
            (void) CopyMagickString(fuzz,"20%",MagickPathExtent);
            (void) XDialogWidget(display,windows,"Ok",
              "Enter fuzz factor (0.0 - 99.9%):",fuzz);
            if (*fuzz == '\0')
              break;
            (void) ConcatenateMagickString(fuzz,"%",MagickPathExtent);
            (*image)->fuzz=StringToDoubleInterval(fuzz,(double) QuantumRange+
              1.0);
            break;
          }
          case MatteEditValueCommand:
          {
            const char
              *const MatteMenu[] =
              {
                "Opaque",
                "Transparent",
                "Dialog...",
                (char *) NULL,
              };

            static char
              message[MagickPathExtent];

            /*
              Select a command from the pop-up menu.
            */
            entry=XMenuWidget(display,windows,MatteEditMenu[id],MatteMenu,
              command);
            if (entry < 0)
              break;
            if (entry != 2)
              {
                (void) FormatLocaleString(matte,MagickPathExtent,QuantumFormat,
                  OpaqueAlpha);
                if (LocaleCompare(MatteMenu[entry],"Transparent") == 0)
                  (void) FormatLocaleString(matte,MagickPathExtent,
                    QuantumFormat,(Quantum) TransparentAlpha);
                break;
              }
            (void) FormatLocaleString(message,MagickPathExtent,
              "Enter matte value (0 - " QuantumFormat "):",(Quantum)
              QuantumRange);
            (void) XDialogWidget(display,windows,"Matte",message,matte);
            if (*matte == '\0')
              break;
            break;
          }
          case MatteEditUndoCommand:
          {
            (void) XMagickCommand(display,resource_info,windows,UndoCommand,
              image,exception);
            break;
          }
          case MatteEditHelpCommand:
          {
            XTextViewHelp(display,resource_info,windows,MagickFalse,
              "Help Viewer - Matte Edit",ImageMatteEditHelp);
            break;
          }
          case MatteEditDismissCommand:
          {
            /*
              Prematurely exit.
            */
            state|=EscapeState;
            state|=ExitState;
            break;
          }
          default:
            break;
        }
        (void) XCheckDefineCursor(display,windows->image.id,cursor);
        continue;
      }
    switch (event.type)
    {
      case ButtonPress:
      {
        if (event.xbutton.button != Button1)
          break;
        if ((event.xbutton.window != windows->image.id) &&
            (event.xbutton.window != windows->magnify.id))
          break;
        /*
          Update matte data.
        */
        x=event.xbutton.x;
        y=event.xbutton.y;
        (void) XMagickCommand(display,resource_info,windows,
          SaveToUndoBufferCommand,image,exception);
        state|=UpdateConfigurationState;
        break;
      }
      case ButtonRelease:
      {
        if (event.xbutton.button != Button1)
          break;
        if ((event.xbutton.window != windows->image.id) &&
            (event.xbutton.window != windows->magnify.id))
          break;
        /*
          Update colormap information.
        */
        x=event.xbutton.x;
        y=event.xbutton.y;
        XConfigureImageColormap(display,resource_info,windows,*image,exception);
        (void) XConfigureImage(display,resource_info,windows,*image,exception);
        XInfoWidget(display,windows,text);
        (void) XCheckDefineCursor(display,windows->image.id,cursor);
        state&=(~UpdateConfigurationState);
        break;
      }
      case Expose:
        break;
      case KeyPress:
      {
        char
          command[MagickPathExtent];

        KeySym
          key_symbol;

        if (event.xkey.window == windows->magnify.id)
          {
            Window
              window;

            window=windows->magnify.id;
            while (XCheckWindowEvent(display,window,KeyPressMask,&event)) ;
          }
        if (event.xkey.window != windows->image.id)
          break;
        /*
          Respond to a user key press.
        */
        (void) XLookupString((XKeyEvent *) &event.xkey,command,(int)
          sizeof(command),&key_symbol,(XComposeStatus *) NULL);
        switch ((int) key_symbol)
        {
          case XK_Escape:
          case XK_F20:
          {
            /*
              Prematurely exit.
            */
            state|=ExitState;
            break;
          }
          case XK_F1:
          case XK_Help:
          {
            XTextViewHelp(display,resource_info,windows,MagickFalse,
              "Help Viewer - Matte Edit",ImageMatteEditHelp);
            break;
          }
          default:
          {
            (void) XBell(display,0);
            break;
          }
        }
        break;
      }
      case MotionNotify:
      {
        /*
          Map and unmap Info widget as cursor crosses its boundaries.
        */
        x=event.xmotion.x;
        y=event.xmotion.y;
        if (windows->info.mapped != MagickFalse)
          {
            if ((x < (int) (windows->info.x+windows->info.width)) &&
                (y < (int) (windows->info.y+windows->info.height)))
              (void) XWithdrawWindow(display,windows->info.id,
                windows->info.screen);
          }
        else
          if ((x > (int) (windows->info.x+windows->info.width)) ||
              (y > (int) (windows->info.y+windows->info.height)))
            (void) XMapWindow(display,windows->info.id);
        break;
      }
      default:
        break;
    }
    if (event.xany.window == windows->magnify.id)
      {
        x=windows->magnify.x-windows->image.x;
        y=windows->magnify.y-windows->image.y;
      }
    x_offset=x;
    y_offset=y;
    if ((state & UpdateConfigurationState) != 0)
      {
        CacheView
          *image_view;

        int
          x,
          y;

        /*
          Matte edit is relative to image configuration.
        */
        (void) XClearArea(display,windows->image.id,x_offset,y_offset,1,1,
          MagickTrue);
        XPutPixel(windows->image.ximage,x_offset,y_offset,
          windows->pixel_info->background_color.pixel);
        width=(unsigned int) (*image)->columns;
        height=(unsigned int) (*image)->rows;
        x=0;
        y=0;
        if (windows->image.crop_geometry != (char *) NULL)
          (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,
            &height);
        x_offset=(int) (width*(windows->image.x+x_offset)/
          windows->image.ximage->width+x);
        y_offset=(int) (height*(windows->image.y+y_offset)/
          windows->image.ximage->height+y);
        if ((x_offset < 0) || (y_offset < 0))
          continue;
        if ((x_offset >= (int) (*image)->columns) ||
            (y_offset >= (int) (*image)->rows))
          continue;
        if (SetImageStorageClass(*image,DirectClass,exception) == MagickFalse)
          return(MagickFalse);
        if ((*image)->alpha_trait == UndefinedPixelTrait)
          (void) SetImageAlphaChannel(*image,OpaqueAlphaChannel,exception);
        image_view=AcquireAuthenticCacheView(*image,exception);
        switch (method)
        {
          case PointMethod:
          default:
          {
            /*
              Update matte information using point algorithm.
            */
            q=GetCacheViewAuthenticPixels(image_view,(ssize_t) x_offset,
              (ssize_t) y_offset,1,1,exception);
            if (q == (Quantum *) NULL)
              break;
            SetPixelAlpha(*image,(Quantum) StringToLong(matte),q);
            (void) SyncCacheViewAuthenticPixels(image_view,exception);
            break;
          }
          case ReplaceMethod:
          {
            PixelInfo
              pixel,
              target;

            /*
              Update matte information using replace algorithm.
            */
            (void) GetOneCacheViewVirtualPixelInfo(image_view,(ssize_t)
              x_offset,(ssize_t) y_offset,&target,exception);
            for (y=0; y < (int) (*image)->rows; y++)
            {
              q=GetCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
                (*image)->columns,1,exception);
              if (q == (Quantum *) NULL)
                break;
              for (x=0; x < (int) (*image)->columns; x++)
              {
                GetPixelInfoPixel(*image,q,&pixel);
                if (IsFuzzyEquivalencePixelInfo(&pixel,&target))
                  SetPixelAlpha(*image,(Quantum) StringToLong(matte),q);
                q+=GetPixelChannels(*image);
              }
              if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
                break;
            }
            break;
          }
          case FloodfillMethod:
          case FillToBorderMethod:
          {
            ChannelType
              channel_mask;

            DrawInfo
              *draw_info;

            PixelInfo
              target;

            /*
              Update matte information using floodfill algorithm.
            */
            (void) GetOneVirtualPixelInfo(*image,
              GetPixelCacheVirtualMethod(*image),(ssize_t) x_offset,(ssize_t)
              y_offset,&target,exception);
            if (method == FillToBorderMethod)
              {
                target.red=(double) ScaleShortToQuantum(
                  border_color.red);
                target.green=(double) ScaleShortToQuantum(
                  border_color.green);
                target.blue=(double) ScaleShortToQuantum(
                  border_color.blue);
              }
            draw_info=CloneDrawInfo(resource_info->image_info,
              (DrawInfo *) NULL);
            draw_info->fill.alpha=(double) ClampToQuantum(
              StringToDouble(matte,(char **) NULL));
            channel_mask=SetImageChannelMask(*image,AlphaChannel);
            (void) FloodfillPaintImage(*image,draw_info,&target,(ssize_t)
              x_offset,(ssize_t) y_offset,
              method != FloodfillMethod ? MagickTrue : MagickFalse,exception);
            (void) SetPixelChannelMask(*image,channel_mask);
            draw_info=DestroyDrawInfo(draw_info);
            break;
          }
          case ResetMethod:
          {
            /*
              Update matte information using reset algorithm.
            */
            if (SetImageStorageClass(*image,DirectClass,exception) == MagickFalse)
              return(MagickFalse);
            for (y=0; y < (int) (*image)->rows; y++)
            {
              q=QueueCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
                (*image)->columns,1,exception);
              if (q == (Quantum *) NULL)
                break;
              for (x=0; x < (int) (*image)->columns; x++)
              {
                SetPixelAlpha(*image,(Quantum) StringToLong(matte),q);
                q+=GetPixelChannels(*image);
              }
              if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
                break;
            }
            if (StringToLong(matte) == (long) OpaqueAlpha)
              (*image)->alpha_trait=UndefinedPixelTrait;
            break;
          }
        }
        image_view=DestroyCacheView(image_view);
        state&=(~UpdateConfigurationState);
      }
  } while ((state & ExitState) == 0);
  (void) XSelectInput(display,windows->image.id,
    windows->image.attributes.event_mask);
  XSetCursorState(display,windows,MagickFalse);
  (void) XFreeCursor(display,cursor);
  return(MagickTrue);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X O p e n I m a g e                                                       %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XOpenImage() loads an image from a file.
%
%  The format of the XOpenImage method is:
%
%     Image *XOpenImage(Display *display,XResourceInfo *resource_info,
%       XWindows *windows,const unsigned int command)
%
%  A description of each parameter follows:
%
%    o display: Specifies a connection to an X server; returned from
%      XOpenDisplay.
%
%    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
%
%    o windows: Specifies a pointer to a XWindows structure.
%
%    o command: A value other than zero indicates that the file is selected
%      from the command line argument list.
%
*/
static Image *XOpenImage(Display *display,XResourceInfo *resource_info,
  XWindows *windows,const MagickBooleanType command)
{
  const MagickInfo
    *magick_info;

  ExceptionInfo
    *exception;

  Image
    *nexus;

  ImageInfo
    *image_info;

  static char
    filename[MagickPathExtent] = "\0";

  /*
    Request file name from user.
  */
  if (command == MagickFalse)
    XFileBrowserWidget(display,windows,"Open",filename);
  else
    {
      char
        **filelist,
        **files;

      int
        count,
        status;

      int
        i,
        j;

      /*
        Select next image from the command line.
      */
      status=XGetCommand(display,windows->image.id,&files,&count);
      if (status == 0)
        {
          ThrowXWindowException(XServerError,"UnableToGetProperty","...");
          return((Image *) NULL);
        }
      filelist=(char **) AcquireQuantumMemory((size_t) count,sizeof(*filelist));
      if (filelist == (char **) NULL)
        {
          ThrowXWindowException(ResourceLimitError,
            "MemoryAllocationFailed","...");
          (void) XFreeStringList(files);
          return((Image *) NULL);
        }
      j=0;
      for (i=1; i < count; i++)
        if (*files[i] != '-')
          filelist[j++]=files[i];
      filelist[j]=(char *) NULL;
      XListBrowserWidget(display,windows,&windows->widget,
        (const char **) filelist,"Load","Select Image to Load:",filename);
      filelist=(char **) RelinquishMagickMemory(filelist);
      (void) XFreeStringList(files);
    }
  if (*filename == '\0')
    return((Image *) NULL);
  image_info=CloneImageInfo(resource_info->image_info);
  (void) SetImageInfoProgressMonitor(image_info,(MagickProgressMonitor) NULL,
    (void *) NULL);
  (void) CopyMagickString(image_info->filename,filename,MagickPathExtent);
  exception=AcquireExceptionInfo();
  (void) SetImageInfo(image_info,0,exception);
  if (LocaleCompare(image_info->magick,"X") == 0)
    {
      char
        seconds[MagickPathExtent];

      /*
        User may want to delay the X server screen grab.
      */
      (void) CopyMagickString(seconds,"0",MagickPathExtent);
      (void) XDialogWidget(display,windows,"Grab","Enter any delay in seconds:",
        seconds);
      if (*seconds == '\0')
        return((Image *) NULL);
      XDelay(display,(size_t) (1000*StringToLong(seconds)));
    }
  magick_info=GetMagickInfo(image_info->magick,exception);
  if ((magick_info != (const MagickInfo *) NULL) &&
      GetMagickRawSupport(magick_info) == MagickTrue)
    {
      char
        geometry[MagickPathExtent];

      /*
        Request image size from the user.
      */
      (void) CopyMagickString(geometry,"512x512",MagickPathExtent);
      if (image_info->size != (char *) NULL)
        (void) CopyMagickString(geometry,image_info->size,MagickPathExtent);
      (void) XDialogWidget(display,windows,"Load","Enter the image geometry:",
        geometry);
      (void) CloneString(&image_info->size,geometry);
    }
  /*
    Load the image.
  */
  XSetCursorState(display,windows,MagickTrue);
  XCheckRefreshWindows(display,windows);
  (void) CopyMagickString(image_info->filename,filename,MagickPathExtent);
  nexus=ReadImage(image_info,exception);
  CatchException(exception);
  XSetCursorState(display,windows,MagickFalse);
  if (nexus != (Image *) NULL)
    XClientMessage(display,windows->image.id,windows->im_protocols,
      windows->im_next_image,CurrentTime);
  else
    {
      char
        *text,
        **textlist;

      /*
        Unknown image format.
      */
      text=FileToString(filename,~0UL,exception);
      if (text == (char *) NULL)
        return((Image *) NULL);
      textlist=StringToList(text);
      if (textlist != (char **) NULL)
        {
          char
            title[MagickPathExtent];

          int
            i;

          (void) FormatLocaleString(title,MagickPathExtent,
            "Unknown format: %s",filename);
          XTextViewWidget(display,resource_info,windows,MagickTrue,title,
            (const char **) textlist);
          for (i=0; textlist[i] != (char *) NULL; i++)
            textlist[i]=DestroyString(textlist[i]);
          textlist=(char **) RelinquishMagickMemory(textlist);
        }
      text=DestroyString(text);
    }
  exception=DestroyExceptionInfo(exception);
  image_info=DestroyImageInfo(image_info);
  return(nexus);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X P a n I m a g e                                                         %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XPanImage() pans the image until the mouse button is released.
%
%  The format of the XPanImage method is:
%
%      void XPanImage(Display *display,XWindows *windows,XEvent *event,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o display: Specifies a connection to an X server;  returned from
%      XOpenDisplay.
%
%    o windows: Specifies a pointer to a XWindows structure.
%
%    o event: Specifies a pointer to a XEvent structure.  If it is NULL,
%      the entire image is refreshed.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static void XPanImage(Display *display,XWindows *windows,XEvent *event,
  ExceptionInfo *exception)
{
  char
    text[MagickPathExtent];

  Cursor
    cursor;

  double
    x_factor,
    y_factor;

  RectangleInfo
    pan_info;

  size_t
    state;

  /*
    Define cursor.
  */
  if ((windows->image.ximage->width > (int) windows->image.width) &&
      (windows->image.ximage->height > (int) windows->image.height))
    cursor=XCreateFontCursor(display,XC_fleur);
  else
    if (windows->image.ximage->width > (int) windows->image.width)
      cursor=XCreateFontCursor(display,XC_sb_h_double_arrow);
    else
      if (windows->image.ximage->height > (int) windows->image.height)
        cursor=XCreateFontCursor(display,XC_sb_v_double_arrow);
      else
        cursor=XCreateFontCursor(display,XC_arrow);
  (void) XCheckDefineCursor(display,windows->pan.id,cursor);
  /*
    Pan image as pointer moves until the mouse button is released.
  */
  x_factor=(double) windows->image.ximage->width/windows->pan.width;
  y_factor=(double) windows->image.ximage->height/windows->pan.height;
  pan_info.width=windows->pan.width*windows->image.width/
    windows->image.ximage->width;
  pan_info.height=windows->pan.height*windows->image.height/
    windows->image.ximage->height;
  pan_info.x=0;
  pan_info.y=0;
  state=UpdateConfigurationState;
  do
  {
    switch (event->type)
    {
      case ButtonPress:
      {
        /*
          User choose an initial pan location.
        */
        pan_info.x=(ssize_t) event->xbutton.x;
        pan_info.y=(ssize_t) event->xbutton.y;
        state|=UpdateConfigurationState;
        break;
      }
      case ButtonRelease:
      {
        /*
          User has finished panning the image.
        */
        pan_info.x=(ssize_t) event->xbutton.x;
        pan_info.y=(ssize_t) event->xbutton.y;
        state|=UpdateConfigurationState | ExitState;
        break;
      }
      case MotionNotify:
      {
        pan_info.x=(ssize_t) event->xmotion.x;
        pan_info.y=(ssize_t) event->xmotion.y;
        state|=UpdateConfigurationState;
      }
      default:
        break;
    }
    if ((state & UpdateConfigurationState) != 0)
      {
        /*
          Check boundary conditions.
        */
        if (pan_info.x < (ssize_t) (pan_info.width/2))
          pan_info.x=0;
        else
          pan_info.x=(ssize_t) (x_factor*(pan_info.x-(pan_info.width/2)));
        if (pan_info.x < 0)
          pan_info.x=0;
        else
          if ((int) (pan_info.x+windows->image.width) >
              windows->image.ximage->width)
            pan_info.x=(ssize_t)
              (windows->image.ximage->width-windows->image.width);
        if (pan_info.y < (ssize_t) (pan_info.height/2))
          pan_info.y=0;
        else
          pan_info.y=(ssize_t) (y_factor*(pan_info.y-(pan_info.height/2)));
        if (pan_info.y < 0)
          pan_info.y=0;
        else
          if ((int) (pan_info.y+windows->image.height) >
              windows->image.ximage->height)
            pan_info.y=(ssize_t)
              (windows->image.ximage->height-windows->image.height);
        if ((windows->image.x != (int) pan_info.x) ||
            (windows->image.y != (int) pan_info.y))
          {
            /*
              Display image pan offset.
            */
            windows->image.x=(int) pan_info.x;
            windows->image.y=(int) pan_info.y;
            (void) FormatLocaleString(text,MagickPathExtent," %ux%u%+d%+d ",
              windows->image.width,windows->image.height,windows->image.x,
              windows->image.y);
            XInfoWidget(display,windows,text);
            /*
              Refresh Image window.
            */
            XDrawPanRectangle(display,windows);
            XRefreshWindow(display,&windows->image,(XEvent *) NULL);
          }
        state&=(~UpdateConfigurationState);
      }
    /*
      Wait for next event.
    */
    if ((state & ExitState) == 0)
      XScreenEvent(display,windows,event,exception);
  } while ((state & ExitState) == 0);
  /*
    Restore cursor.
  */
  (void) XCheckDefineCursor(display,windows->pan.id,windows->pan.cursor);
  (void) XFreeCursor(display,cursor);
  (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X P a s t e I m a g e                                                     %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XPasteImage() pastes an image previously saved with XCropImage in the X
%  window image at a location the user chooses with the pointer.
%
%  The format of the XPasteImage method is:
%
%      MagickBooleanType XPasteImage(Display *display,
%        XResourceInfo *resource_info,XWindows *windows,Image *image,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o display: Specifies a connection to an X server;  returned from
%      XOpenDisplay.
%
%    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
%
%    o windows: Specifies a pointer to a XWindows structure.
%
%    o image: the image; returned from ReadImage.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static MagickBooleanType XPasteImage(Display *display,
  XResourceInfo *resource_info,XWindows *windows,Image *image,
  ExceptionInfo *exception)
{
  const char
    *const PasteMenu[] =
    {
      "Operator",
      "Help",
      "Dismiss",
      (char *) NULL
    };

  static const ModeType
    PasteCommands[] =
    {
      PasteOperatorsCommand,
      PasteHelpCommand,
      PasteDismissCommand
    };

  static CompositeOperator
    compose = CopyCompositeOp;

  char
    text[MagickPathExtent];

  Cursor
    cursor;

  Image
    *paste_image;

  int
    entry,
    id,
    x,
    y;

  double
    scale_factor;

  RectangleInfo
    highlight_info,
    paste_info;

  unsigned int
    height,
    width;

  size_t
    state;

  XEvent
    event;

  /*
    Copy image.
  */
  if (resource_info->copy_image == (Image *) NULL)
    return(MagickFalse);
  paste_image=CloneImage(resource_info->copy_image,0,0,MagickTrue,exception);
  if (paste_image == (Image *) NULL)
    return(MagickFalse);
  /*
    Map Command widget.
  */
  (void) CloneString(&windows->command.name,"Paste");
  windows->command.data=1;
  (void) XCommandWidget(display,windows,PasteMenu,(XEvent *) NULL);
  (void) XMapRaised(display,windows->command.id);
  XClientMessage(display,windows->image.id,windows->im_protocols,
    windows->im_update_widget,CurrentTime);
  /*
    Track pointer until button 1 is pressed.
  */
  XSetCursorState(display,windows,MagickFalse);
  XQueryPosition(display,windows->image.id,&x,&y);
  (void) XSelectInput(display,windows->image.id,
    windows->image.attributes.event_mask | PointerMotionMask);
  paste_info.x=(ssize_t) windows->image.x+x;
  paste_info.y=(ssize_t) windows->image.y+y;
  paste_info.width=0;
  paste_info.height=0;
  cursor=XCreateFontCursor(display,XC_ul_angle);
  (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
  state=DefaultState;
  do
  {
    if (windows->info.mapped != MagickFalse)
      {
        /*
          Display pointer position.
        */
        (void) FormatLocaleString(text,MagickPathExtent," %+ld%+ld ",
          (long) paste_info.x,(long) paste_info.y);
        XInfoWidget(display,windows,text);
      }
    highlight_info=paste_info;
    highlight_info.x=paste_info.x-windows->image.x;
    highlight_info.y=paste_info.y-windows->image.y;
    XHighlightRectangle(display,windows->image.id,
      windows->image.highlight_context,&highlight_info);
    /*
      Wait for next event.
    */
    XScreenEvent(display,windows,&event,exception);
    XHighlightRectangle(display,windows->image.id,
      windows->image.highlight_context,&highlight_info);
    if (event.xany.window == windows->command.id)
      {
        /*
          Select a command from the Command widget.
        */
        id=XCommandWidget(display,windows,PasteMenu,&event);
        if (id < 0)
          continue;
        switch (PasteCommands[id])
        {
          case PasteOperatorsCommand:
          {
            char
              command[MagickPathExtent],
              **operators;

            /*
              Select a command from the pop-up menu.
            */
            operators=GetCommandOptions(MagickComposeOptions);
            if (operators == (char **) NULL)
              break;
            entry=XMenuWidget(display,windows,PasteMenu[id],
              (const char **) operators,command);
            if (entry >= 0)
              compose=(CompositeOperator) ParseCommandOption(
                MagickComposeOptions,MagickFalse,operators[entry]);
            operators=DestroyStringList(operators);
            break;
          }
          case PasteHelpCommand:
          {
            XTextViewHelp(display,resource_info,windows,MagickFalse,
              "Help Viewer - Image Composite",ImagePasteHelp);
            break;
          }
          case PasteDismissCommand:
          {
            /*
              Prematurely exit.
            */
            state|=EscapeState;
            state|=ExitState;
            break;
          }
          default:
            break;
        }
        continue;
      }
    switch (event.type)
    {
      case ButtonPress:
      {
        if (image->debug != MagickFalse)
          (void) LogMagickEvent(X11Event,GetMagickModule(),
            "Button Press: 0x%lx %u +%d+%d",event.xbutton.window,
            event.xbutton.button,event.xbutton.x,event.xbutton.y);
        if (event.xbutton.button != Button1)
          break;
        if (event.xbutton.window != windows->image.id)
          break;
        /*
          Paste rectangle is relative to image configuration.
        */
        width=(unsigned int) image->columns;
        height=(unsigned int) image->rows;
        x=0;
        y=0;
        if (windows->image.crop_geometry != (char *) NULL)
          (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
            &width,&height);
        scale_factor=(double) windows->image.ximage->width/width;
        paste_info.width=(unsigned int) (scale_factor*paste_image->columns+0.5);
        scale_factor=(double) windows->image.ximage->height/height;
        paste_info.height=(unsigned int) (scale_factor*paste_image->rows+0.5);
        (void) XCheckDefineCursor(display,windows->image.id,cursor);
        paste_info.x=(ssize_t) windows->image.x+event.xbutton.x;
        paste_info.y=(ssize_t) windows->image.y+event.xbutton.y;
        break;
      }
      case ButtonRelease:
      {
        if (image->debug != MagickFalse)
          (void) LogMagickEvent(X11Event,GetMagickModule(),
            "Button Release: 0x%lx %u +%d+%d",event.xbutton.window,
            event.xbutton.button,event.xbutton.x,event.xbutton.y);
        if (event.xbutton.button != Button1)
          break;
        if (event.xbutton.window != windows->image.id)
          break;
        if ((paste_info.width != 0) && (paste_info.height != 0))
          {
            /*
              User has selected the location of the paste image.
            */
            paste_info.x=(ssize_t) windows->image.x+event.xbutton.x;
            paste_info.y=(ssize_t) windows->image.y+event.xbutton.y;
            state|=ExitState;
          }
        break;
      }
      case Expose:
        break;
      case KeyPress:
      {
        char
          command[MagickPathExtent];

        KeySym
          key_symbol;

        int
          length;

        if (event.xkey.window != windows->image.id)
          break;
        /*
          Respond to a user key press.
        */
        length=XLookupString((XKeyEvent *) &event.xkey,command,(int)
          sizeof(command),&key_symbol,(XComposeStatus *) NULL);
        *(command+length)='\0';
        if (image->debug != MagickFalse)
          (void) LogMagickEvent(X11Event,GetMagickModule(),
            "Key press: 0x%lx (%s)",(long) key_symbol,command);
        switch ((int) key_symbol)
        {
          case XK_Escape:
          case XK_F20:
          {
            /*
              Prematurely exit.
            */
            paste_image=DestroyImage(paste_image);
            state|=EscapeState;
            state|=ExitState;
            break;
          }
          case XK_F1:
          case XK_Help:
          {
            (void) XSetFunction(display,windows->image.highlight_context,
              GXcopy);
            XTextViewHelp(display,resource_info,windows,MagickFalse,
              "Help Viewer - Image Composite",ImagePasteHelp);
            (void) XSetFunction(display,windows->image.highlight_context,
              GXinvert);
            break;
          }
          default:
          {
            (void) XBell(display,0);
            break;
          }
        }
        break;
      }
      case MotionNotify:
      {
        /*
          Map and unmap Info widget as text cursor crosses its boundaries.
        */
        x=event.xmotion.x;
        y=event.xmotion.y;
        if (windows->info.mapped != MagickFalse)
          {
            if ((x < (int) (windows->info.x+windows->info.width)) &&
                (y < (int) (windows->info.y+windows->info.height)))
              (void) XWithdrawWindow(display,windows->info.id,
                windows->info.screen);
          }
        else
          if ((x > (int) (windows->info.x+windows->info.width)) ||
              (y > (int) (windows->info.y+windows->info.height)))
            (void) XMapWindow(display,windows->info.id);
        paste_info.x=(ssize_t) windows->image.x+x;
        paste_info.y=(ssize_t) windows->image.y+y;
        break;
      }
      default:
      {
        if (image->debug != MagickFalse)
          (void) LogMagickEvent(X11Event,GetMagickModule(),"Event type: %d",
            event.type);
        break;
      }
    }
  } while ((state & ExitState) == 0);
  (void) XSelectInput(display,windows->image.id,
    windows->image.attributes.event_mask);
  (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
  XSetCursorState(display,windows,MagickFalse);
  (void) XFreeCursor(display,cursor);
  if ((state & EscapeState) != 0)
    return(MagickTrue);
  /*
    Image pasting is relative to image configuration.
  */
  XSetCursorState(display,windows,MagickTrue);
  XCheckRefreshWindows(display,windows);
  width=(unsigned int) image->columns;
  height=(unsigned int) image->rows;
  x=0;
  y=0;
  if (windows->image.crop_geometry != (char *) NULL)
    (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
  scale_factor=(double) width/windows->image.ximage->width;
  paste_info.x+=x;
  paste_info.x=(ssize_t) (scale_factor*paste_info.x+0.5);
  paste_info.width=(unsigned int) (scale_factor*paste_info.width+0.5);
  scale_factor=(double) height/windows->image.ximage->height;
  paste_info.y+=y;
  paste_info.y=(ssize_t) (scale_factor*paste_info.y*scale_factor+0.5);
  paste_info.height=(unsigned int) (scale_factor*paste_info.height+0.5);
  /*
    Paste image with X Image window.
  */
  (void) CompositeImage(image,paste_image,compose,MagickTrue,paste_info.x,
    paste_info.y,exception);
  paste_image=DestroyImage(paste_image);
  XSetCursorState(display,windows,MagickFalse);
  /*
    Update image colormap.
  */
  XConfigureImageColormap(display,resource_info,windows,image,exception);
  (void) XConfigureImage(display,resource_info,windows,image,exception);
  return(MagickTrue);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X P r i n t I m a g e                                                     %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XPrintImage() prints an image to a Postscript printer.
%
%  The format of the XPrintImage method is:
%
%      MagickBooleanType XPrintImage(Display *display,
%        XResourceInfo *resource_info,XWindows *windows,Image *image,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o display: Specifies a connection to an X server; returned from
%      XOpenDisplay.
%
%    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
%
%    o windows: Specifies a pointer to a XWindows structure.
%
%    o image: the image.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static MagickBooleanType XPrintImage(Display *display,
  XResourceInfo *resource_info,XWindows *windows,Image *image,
  ExceptionInfo *exception)
{
  char
    filename[MagickPathExtent],
    geometry[MagickPathExtent];

  const char
    *const PageSizes[] =
    {
      "Letter",
      "Tabloid",
      "Ledger",
      "Legal",
      "Statement",
      "Executive",
      "A3",
      "A4",
      "A5",
      "B4",
      "B5",
      "Folio",
      "Quarto",
      "10x14",
      (char *) NULL
    };

  Image
    *print_image;

  ImageInfo
    *image_info;

  MagickStatusType
    status;

  /*
    Request Postscript page geometry from user.
  */
  image_info=CloneImageInfo(resource_info->image_info);
  (void) FormatLocaleString(geometry,MagickPathExtent,"Letter");
  if (image_info->page != (char *) NULL)
    (void) CopyMagickString(geometry,image_info->page,MagickPathExtent);
  XListBrowserWidget(display,windows,&windows->widget,PageSizes,"Select",
    "Select Postscript Page Geometry:",geometry);
  if (*geometry == '\0')
    return(MagickTrue);
  image_info->page=GetPageGeometry(geometry);
  /*
    Apply image transforms.
  */
  XSetCursorState(display,windows,MagickTrue);
  XCheckRefreshWindows(display,windows);
  print_image=CloneImage(image,0,0,MagickTrue,exception);
  if (print_image == (Image *) NULL)
    return(MagickFalse);
  (void) FormatLocaleString(geometry,MagickPathExtent,"%dx%d!",
    windows->image.ximage->width,windows->image.ximage->height);
  (void) TransformImage(&print_image,windows->image.crop_geometry,geometry,
    exception);
  /*
    Print image.
  */
  (void) AcquireUniqueFilename(filename);
  (void) FormatLocaleString(print_image->filename,MagickPathExtent,"print:%s",
    filename);
  status=WriteImage(image_info,print_image,exception);
  (void) RelinquishUniqueFileResource(filename);
  print_image=DestroyImage(print_image);
  image_info=DestroyImageInfo(image_info);
  XSetCursorState(display,windows,MagickFalse);
  return(status != 0 ? MagickTrue : MagickFalse);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X R O I I m a g e                                                         %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XROIImage() applies an image processing technique to a region of interest.
%
%  The format of the XROIImage method is:
%
%      MagickBooleanType XROIImage(Display *display,
%        XResourceInfo *resource_info,XWindows *windows,Image **image,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o display: Specifies a connection to an X server; returned from
%      XOpenDisplay.
%
%    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
%
%    o windows: Specifies a pointer to a XWindows structure.
%
%    o image: the image; returned from ReadImage.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static MagickBooleanType XROIImage(Display *display,
  XResourceInfo *resource_info,XWindows *windows,Image **image,
  ExceptionInfo *exception)
{
#define ApplyMenus  7

  const char
    *const ROIMenu[] =
    {
      "Help",
      "Dismiss",
      (char *) NULL
    },
    *const ApplyMenu[] =
    {
      "File",
      "Edit",
      "Transform",
      "Enhance",
      "Effects",
      "F/X",
      "Miscellany",
      "Help",
      "Dismiss",
      (char *) NULL
    },
    *const FileMenu[] =
    {
      "Save...",
      "Print...",
      (char *) NULL
    },
    *const EditMenu[] =
    {
      "Undo",
      "Redo",
      (char *) NULL
    },
    *const TransformMenu[] =
    {
      "Flop",
      "Flip",
      "Rotate Right",
      "Rotate Left",
      (char *) NULL
    },
    *const EnhanceMenu[] =
    {
      "Hue...",
      "Saturation...",
      "Brightness...",
      "Gamma...",
      "Spiff",
      "Dull",
      "Contrast Stretch...",
      "Sigmoidal Contrast...",
      "Normalize",
      "Equalize",
      "Negate",
      "Grayscale",
      "Map...",
      "Quantize...",
      (char *) NULL
    },
    *const EffectsMenu[] =
    {
      "Despeckle",
      "Emboss",
      "Reduce Noise",
      "Add Noise",
      "Sharpen...",
      "Blur...",
      "Threshold...",
      "Edge Detect...",
      "Spread...",
      "Shade...",
      "Raise...",
      "Segment...",
      (char *) NULL
    },
    *const FXMenu[] =
    {
      "Solarize...",
      "Sepia Tone...",
      "Swirl...",
      "Implode...",
      "Vignette...",
      "Wave...",
      "Oil Paint...",
      "Charcoal Draw...",
      (char *) NULL
    },
    *const MiscellanyMenu[] =
    {
      "Image Info",
      "Zoom Image",
      "Show Preview...",
      "Show Histogram",
      "Show Matte",
      (char *) NULL
    };

  const char
    *const *Menus[ApplyMenus] =
    {
      FileMenu,
      EditMenu,
      TransformMenu,
      EnhanceMenu,
      EffectsMenu,
      FXMenu,
      MiscellanyMenu
    };

  static const CommandType
    ApplyCommands[] =
    {
      NullCommand,
      NullCommand,
      NullCommand,
      NullCommand,
      NullCommand,
      NullCommand,
      NullCommand,
      HelpCommand,
      QuitCommand
    },
    FileCommands[] =
    {
      SaveCommand,
      PrintCommand
    },
    EditCommands[] =
    {
      UndoCommand,
      RedoCommand
    },
    TransformCommands[] =
    {
      FlopCommand,
      FlipCommand,
      RotateRightCommand,
      RotateLeftCommand
    },
    EnhanceCommands[] =
    {
      HueCommand,
      SaturationCommand,
      BrightnessCommand,
      GammaCommand,
      SpiffCommand,
      DullCommand,
      ContrastStretchCommand,
      SigmoidalContrastCommand,
      NormalizeCommand,
      EqualizeCommand,
      NegateCommand,
      GrayscaleCommand,
      MapCommand,
      QuantizeCommand
    },
    EffectsCommands[] =
    {
      DespeckleCommand,
      EmbossCommand,
      ReduceNoiseCommand,
      AddNoiseCommand,
      SharpenCommand,
      BlurCommand,
      EdgeDetectCommand,
      SpreadCommand,
      ShadeCommand,
      RaiseCommand,
      SegmentCommand
    },
    FXCommands[] =
    {
      SolarizeCommand,
      SepiaToneCommand,
      SwirlCommand,
      ImplodeCommand,
      VignetteCommand,
      WaveCommand,
      OilPaintCommand,
      CharcoalDrawCommand
    },
    MiscellanyCommands[] =
    {
      InfoCommand,
      ZoomCommand,
      ShowPreviewCommand,
      ShowHistogramCommand,
      ShowMatteCommand
    },
    ROICommands[] =
    {
      ROIHelpCommand,
      ROIDismissCommand
    };

  static const CommandType
    *Commands[ApplyMenus] =
    {
      FileCommands,
      EditCommands,
      TransformCommands,
      EnhanceCommands,
      EffectsCommands,
      FXCommands,
      MiscellanyCommands
    };

  char
    command[MagickPathExtent],
    text[MagickPathExtent];

  CommandType
    command_type;

  Cursor
    cursor;

  Image
    *roi_image;

  int
    entry,
    id,
    x,
    y;

  double
    scale_factor;

  MagickProgressMonitor
    progress_monitor;

  RectangleInfo
    crop_info,
    highlight_info,
    roi_info;

  unsigned int
    height,
    width;

  size_t
    state;

  XEvent
    event;

  /*
    Map Command widget.
  */
  (void) CloneString(&windows->command.name,"ROI");
  windows->command.data=0;
  (void) XCommandWidget(display,windows,ROIMenu,(XEvent *) NULL);
  (void) XMapRaised(display,windows->command.id);
  XClientMessage(display,windows->image.id,windows->im_protocols,
    windows->im_update_widget,CurrentTime);
  /*
    Track pointer until button 1 is pressed.
  */
  XQueryPosition(display,windows->image.id,&x,&y);
  (void) XSelectInput(display,windows->image.id,
    windows->image.attributes.event_mask | PointerMotionMask);
  roi_info.x=(ssize_t) windows->image.x+x;
  roi_info.y=(ssize_t) windows->image.y+y;
  roi_info.width=0;
  roi_info.height=0;
  cursor=XCreateFontCursor(display,XC_fleur);
  state=DefaultState;
  do
  {
    if (windows->info.mapped != MagickFalse)
      {
        /*
          Display pointer position.
        */
        (void) FormatLocaleString(text,MagickPathExtent," %+ld%+ld ",
          (long) roi_info.x,(long) roi_info.y);
        XInfoWidget(display,windows,text);
      }
    /*
      Wait for next event.
    */
    XScreenEvent(display,windows,&event,exception);
    if (event.xany.window == windows->command.id)
      {
        /*
          Select a command from the Command widget.
        */
        id=XCommandWidget(display,windows,ROIMenu,&event);
        if (id < 0)
          continue;
        switch (ROICommands[id])
        {
          case ROIHelpCommand:
          {
            XTextViewHelp(display,resource_info,windows,MagickFalse,
              "Help Viewer - Region of Interest",ImageROIHelp);
            break;
          }
          case ROIDismissCommand:
          {
            /*
              Prematurely exit.
            */
            state|=EscapeState;
            state|=ExitState;
            break;
          }
          default:
            break;
        }
        continue;
      }
    switch (event.type)
    {
      case ButtonPress:
      {
        if (event.xbutton.button != Button1)
          break;
        if (event.xbutton.window != windows->image.id)
          break;
        /*
          Note first corner of region of interest rectangle-- exit loop.
        */
        (void) XCheckDefineCursor(display,windows->image.id,cursor);
        roi_info.x=(ssize_t) windows->image.x+event.xbutton.x;
        roi_info.y=(ssize_t) windows->image.y+event.xbutton.y;
        state|=ExitState;
        break;
      }
      case ButtonRelease:
        break;
      case Expose:
        break;
      case KeyPress:
      {
        KeySym
          key_symbol;

        if (event.xkey.window != windows->image.id)
          break;
        /*
          Respond to a user key press.
        */
        (void) XLookupString((XKeyEvent *) &event.xkey,command,(int)
          sizeof(command),&key_symbol,(XComposeStatus *) NULL);
        switch ((int) key_symbol)
        {
          case XK_Escape:
          case XK_F20:
          {
            /*
              Prematurely exit.
            */
            state|=EscapeState;
            state|=ExitState;
            break;
          }
          case XK_F1:
          case XK_Help:
          {
            XTextViewHelp(display,resource_info,windows,MagickFalse,
              "Help Viewer - Region of Interest",ImageROIHelp);
            break;
          }
          default:
          {
            (void) XBell(display,0);
            break;
          }
        }
        break;
      }
      case MotionNotify:
      {
        /*
          Map and unmap Info widget as text cursor crosses its boundaries.
        */
        x=event.xmotion.x;
        y=event.xmotion.y;
        if (windows->info.mapped != MagickFalse)
          {
            if ((x < (int) (windows->info.x+windows->info.width)) &&
                (y < (int) (windows->info.y+windows->info.height)))
              (void) XWithdrawWindow(display,windows->info.id,
                windows->info.screen);
          }
        else
          if ((x > (int) (windows->info.x+windows->info.width)) ||
              (y > (int) (windows->info.y+windows->info.height)))
            (void) XMapWindow(display,windows->info.id);
        roi_info.x=(ssize_t) windows->image.x+x;
        roi_info.y=(ssize_t) windows->image.y+y;
        break;
      }
      default:
        break;
    }
  } while ((state & ExitState) == 0);
  (void) XSelectInput(display,windows->image.id,
    windows->image.attributes.event_mask);
  if ((state & EscapeState) != 0)
    {
      /*
        User want to exit without region of interest.
      */
      (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
      (void) XFreeCursor(display,cursor);
      return(MagickTrue);
    }
  (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
  do
  {
    /*
      Size rectangle as pointer moves until the mouse button is released.
    */
    x=(int) roi_info.x;
    y=(int) roi_info.y;
    roi_info.width=0;
    roi_info.height=0;
    state=DefaultState;
    do
    {
      highlight_info=roi_info;
      highlight_info.x=roi_info.x-windows->image.x;
      highlight_info.y=roi_info.y-windows->image.y;
      if ((highlight_info.width > 3) && (highlight_info.height > 3))
        {
          /*
            Display info and draw region of interest rectangle.
          */
          if (windows->info.mapped == MagickFalse)
            (void) XMapWindow(display,windows->info.id);
          (void) FormatLocaleString(text,MagickPathExtent,
            " %.20gx%.20g%+.20g%+.20g",(double) roi_info.width,(double)
            roi_info.height,(double) roi_info.x,(double) roi_info.y);
          XInfoWidget(display,windows,text);
          XHighlightRectangle(display,windows->image.id,
            windows->image.highlight_context,&highlight_info);
        }
      else
        if (windows->info.mapped != MagickFalse)
          (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
      /*
        Wait for next event.
      */
      XScreenEvent(display,windows,&event,exception);
      if ((highlight_info.width > 3) && (highlight_info.height > 3))
        XHighlightRectangle(display,windows->image.id,
          windows->image.highlight_context,&highlight_info);
      switch (event.type)
      {
        case ButtonPress:
        {
          roi_info.x=(ssize_t) windows->image.x+event.xbutton.x;
          roi_info.y=(ssize_t) windows->image.y+event.xbutton.y;
          break;
        }
        case ButtonRelease:
        {
          /*
            User has committed to region of interest rectangle.
          */
          roi_info.x=(ssize_t) windows->image.x+event.xbutton.x;
          roi_info.y=(ssize_t) windows->image.y+event.xbutton.y;
          XSetCursorState(display,windows,MagickFalse);
          state|=ExitState;
          if (LocaleCompare(windows->command.name,"Apply") == 0)
            break;
          (void) CloneString(&windows->command.name,"Apply");
          windows->command.data=ApplyMenus;
          (void) XCommandWidget(display,windows,ApplyMenu,(XEvent *) NULL);
          break;
        }
        case Expose:
          break;
        case MotionNotify:
        {
          roi_info.x=(ssize_t) windows->image.x+event.xmotion.x;
          roi_info.y=(ssize_t) windows->image.y+event.xmotion.y;
        }
        default:
          break;
      }
      if ((((int) roi_info.x != x) && ((int) roi_info.y != y)) ||
          ((state & ExitState) != 0))
        {
          /*
            Check boundary conditions.
          */
          if (roi_info.x < 0)
            roi_info.x=0;
          else
            if (roi_info.x > (ssize_t) windows->image.ximage->width)
              roi_info.x=(ssize_t) windows->image.ximage->width;
          if ((int) roi_info.x < x)
            roi_info.width=(unsigned int) (x-roi_info.x);
          else
            {
              roi_info.width=(unsigned int) (roi_info.x-x);
              roi_info.x=(ssize_t) x;
            }
          if (roi_info.y < 0)
            roi_info.y=0;
          else
            if (roi_info.y > (ssize_t) windows->image.ximage->height)
              roi_info.y=(ssize_t) windows->image.ximage->height;
          if ((int) roi_info.y < y)
            roi_info.height=(unsigned int) (y-roi_info.y);
          else
            {
              roi_info.height=(unsigned int) (roi_info.y-y);
              roi_info.y=(ssize_t) y;
            }
        }
    } while ((state & ExitState) == 0);
    /*
      Wait for user to grab a corner of the rectangle or press return.
    */
    state=DefaultState;
    command_type=NullCommand;
    crop_info.x=0;
    crop_info.y=0;
    (void) XMapWindow(display,windows->info.id);
    do
    {
      if (windows->info.mapped != MagickFalse)
        {
          /*
            Display pointer position.
          */
          (void) FormatLocaleString(text,MagickPathExtent,
            " %.20gx%.20g%+.20g%+.20g",(double) roi_info.width,(double)
            roi_info.height,(double) roi_info.x,(double) roi_info.y);
          XInfoWidget(display,windows,text);
        }
      highlight_info=roi_info;
      highlight_info.x=roi_info.x-windows->image.x;
      highlight_info.y=roi_info.y-windows->image.y;
      if ((highlight_info.width <= 3) || (highlight_info.height <= 3))
        {
          state|=EscapeState;
          state|=ExitState;
          break;
        }
      if ((state & UpdateRegionState) != 0)
        {
          (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
          switch (command_type)
          {
            case UndoCommand:
            case RedoCommand:
            {
              (void) XMagickCommand(display,resource_info,windows,command_type,
                image,exception);
              break;
            }
            default:
            {
              /*
                Region of interest is relative to image configuration.
              */
              progress_monitor=SetImageProgressMonitor(*image,
                (MagickProgressMonitor) NULL,(*image)->client_data);
              crop_info=roi_info;
              width=(unsigned int) (*image)->columns;
              height=(unsigned int) (*image)->rows;
              x=0;
              y=0;
              if (windows->image.crop_geometry != (char *) NULL)
                (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
                  &width,&height);
              scale_factor=(double) width/windows->image.ximage->width;
              crop_info.x+=x;
              crop_info.x=(ssize_t) (scale_factor*crop_info.x+0.5);
              crop_info.width=(unsigned int) (scale_factor*crop_info.width+0.5);
              scale_factor=(double)
                height/windows->image.ximage->height;
              crop_info.y+=y;
              crop_info.y=(ssize_t) (scale_factor*crop_info.y+0.5);
              crop_info.height=(unsigned int)
                (scale_factor*crop_info.height+0.5);
              roi_image=CropImage(*image,&crop_info,exception);
              (void) SetImageProgressMonitor(*image,progress_monitor,
                (*image)->client_data);
              if (roi_image == (Image *) NULL)
                continue;
              /*
                Apply image processing technique to the region of interest.
              */
              windows->image.orphan=MagickTrue;
              (void) XMagickCommand(display,resource_info,windows,command_type,
                &roi_image,exception);
              progress_monitor=SetImageProgressMonitor(*image,
                (MagickProgressMonitor) NULL,(*image)->client_data);
              (void) XMagickCommand(display,resource_info,windows,
                SaveToUndoBufferCommand,image,exception);
              windows->image.orphan=MagickFalse;
              (void) CompositeImage(*image,roi_image,CopyCompositeOp,
                MagickTrue,crop_info.x,crop_info.y,exception);
              roi_image=DestroyImage(roi_image);
              (void) SetImageProgressMonitor(*image,progress_monitor,
                (*image)->client_data);
              break;
            }
          }
          if (command_type != InfoCommand)
            {
              XConfigureImageColormap(display,resource_info,windows,*image,
                exception);
              (void) XConfigureImage(display,resource_info,windows,*image,
                exception);
            }
          XCheckRefreshWindows(display,windows);
          XInfoWidget(display,windows,text);
          (void) XSetFunction(display,windows->image.highlight_context,
            GXinvert);
          state&=(~UpdateRegionState);
        }
      XHighlightRectangle(display,windows->image.id,
        windows->image.highlight_context,&highlight_info);
      XScreenEvent(display,windows,&event,exception);
      if (event.xany.window == windows->command.id)
        {
          /*
            Select a command from the Command widget.
          */
          (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
          command_type=NullCommand;
          id=XCommandWidget(display,windows,ApplyMenu,&event);
          if (id >= 0)
            {
              (void) CopyMagickString(command,ApplyMenu[id],MagickPathExtent);
              command_type=ApplyCommands[id];
              if (id < ApplyMenus)
                {
                  /*
                    Select a command from a pop-up menu.
                  */
                  entry=XMenuWidget(display,windows,ApplyMenu[id],
                    (const char **) Menus[id],command);
                  if (entry >= 0)
                    {
                      (void) CopyMagickString(command,Menus[id][entry],
                        MagickPathExtent);
                      command_type=Commands[id][entry];
                    }
                }
            }
          (void) XSetFunction(display,windows->image.highlight_context,
            GXinvert);
          XHighlightRectangle(display,windows->image.id,
            windows->image.highlight_context,&highlight_info);
          if (command_type == HelpCommand)
            {
              (void) XSetFunction(display,windows->image.highlight_context,
                GXcopy);
              XTextViewHelp(display,resource_info,windows,MagickFalse,
                "Help Viewer - Region of Interest",ImageROIHelp);
              (void) XSetFunction(display,windows->image.highlight_context,
                GXinvert);
              continue;
            }
          if (command_type == QuitCommand)
            {
              /*
                exit.
              */
              state|=EscapeState;
              state|=ExitState;
              continue;
            }
          if (command_type != NullCommand)
            state|=UpdateRegionState;
          continue;
        }
      XHighlightRectangle(display,windows->image.id,
        windows->image.highlight_context,&highlight_info);
      switch (event.type)
      {
        case ButtonPress:
        {
          x=windows->image.x;
          y=windows->image.y;
          if (event.xbutton.button != Button1)
            break;
          if (event.xbutton.window != windows->image.id)
            break;
          x=windows->image.x+event.xbutton.x;
          y=windows->image.y+event.xbutton.y;
          if ((x < (int) (roi_info.x+RoiDelta)) &&
              (x > (int) (roi_info.x-RoiDelta)) &&
              (y < (int) (roi_info.y+RoiDelta)) &&
              (y > (int) (roi_info.y-RoiDelta)))
            {
              roi_info.x=(ssize_t) (roi_info.x+roi_info.width);
              roi_info.y=(ssize_t) (roi_info.y+roi_info.height);
              state|=UpdateConfigurationState;
              break;
            }
          if ((x < (int) (roi_info.x+RoiDelta)) &&
              (x > (int) (roi_info.x-RoiDelta)) &&
              (y < (int) (roi_info.y+roi_info.height+RoiDelta)) &&
              (y > (int) (roi_info.y+roi_info.height-RoiDelta)))
            {
              roi_info.x=(ssize_t) (roi_info.x+roi_info.width);
              state|=UpdateConfigurationState;
              break;
            }
          if ((x < (int) (roi_info.x+roi_info.width+RoiDelta)) &&
              (x > (int) (roi_info.x+roi_info.width-RoiDelta)) &&
              (y < (int) (roi_info.y+RoiDelta)) &&
              (y > (int) (roi_info.y-RoiDelta)))
            {
              roi_info.y=(ssize_t) (roi_info.y+roi_info.height);
              state|=UpdateConfigurationState;
              break;
            }
          if ((x < (int) (roi_info.x+roi_info.width+RoiDelta)) &&
              (x > (int) (roi_info.x+roi_info.width-RoiDelta)) &&
              (y < (int) (roi_info.y+roi_info.height+RoiDelta)) &&
              (y > (int) (roi_info.y+roi_info.height-RoiDelta)))
            {
              state|=UpdateConfigurationState;
              break;
            }
        }
        case ButtonRelease:
        {
          if (event.xbutton.window == windows->pan.id)
            if ((highlight_info.x != crop_info.x-windows->image.x) ||
                (highlight_info.y != crop_info.y-windows->image.y))
              XHighlightRectangle(display,windows->image.id,
                windows->image.highlight_context,&highlight_info);
          (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id,
            event.xbutton.time);
          break;
        }
        case Expose:
        {
          if (event.xexpose.window == windows->image.id)
            if (event.xexpose.count == 0)
              {
                event.xexpose.x=(int) highlight_info.x;
                event.xexpose.y=(int) highlight_info.y;
                event.xexpose.width=(int) highlight_info.width;
                event.xexpose.height=(int) highlight_info.height;
                XRefreshWindow(display,&windows->image,&event);
              }
          if (event.xexpose.window == windows->info.id)
            if (event.xexpose.count == 0)
              XInfoWidget(display,windows,text);
          break;
        }
        case KeyPress:
        {
          KeySym
            key_symbol;

          if (event.xkey.window != windows->image.id)
            break;
          /*
            Respond to a user key press.
          */
          (void) XLookupString((XKeyEvent *) &event.xkey,command,(int)
            sizeof(command),&key_symbol,(XComposeStatus *) NULL);
          switch ((int) key_symbol)
          {
            case XK_Shift_L:
            case XK_Shift_R:
              break;
            case XK_Escape:
            case XK_F20:
              state|=EscapeState;
            case XK_Return:
            {
              state|=ExitState;
              break;
            }
            case XK_Home:
            case XK_KP_Home:
            {
              roi_info.x=(ssize_t) (windows->image.width/2L-roi_info.width/2L);
              roi_info.y=(ssize_t) (windows->image.height/2L-
                roi_info.height/2L);
              break;
            }
            case XK_Left:
            case XK_KP_Left:
            {
              roi_info.x--;
              break;
            }
            case XK_Up:
            case XK_KP_Up:
            case XK_Next:
            {
              roi_info.y--;
              break;
            }
            case XK_Right:
            case XK_KP_Right:
            {
              roi_info.x++;
              break;
            }
            case XK_Prior:
            case XK_Down:
            case XK_KP_Down:
            {
              roi_info.y++;
              break;
            }
            case XK_F1:
            case XK_Help:
            {
              (void) XSetFunction(display,windows->image.highlight_context,
                GXcopy);
              XTextViewHelp(display,resource_info,windows,MagickFalse,
                "Help Viewer - Region of Interest",ImageROIHelp);
              (void) XSetFunction(display,windows->image.highlight_context,
                GXinvert);
              break;
            }
            default:
            {
              command_type=XImageWindowCommand(display,resource_info,windows,
                event.xkey.state,key_symbol,image,exception);
              if (command_type != NullCommand)
                state|=UpdateRegionState;
              break;
            }
          }
          (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id,
            event.xkey.time);
          break;
        }
        case KeyRelease:
          break;
        case MotionNotify:
        {
          if (event.xbutton.window != windows->image.id)
            break;
          /*
            Map and unmap Info widget as text cursor crosses its boundaries.
          */
          x=event.xmotion.x;
          y=event.xmotion.y;
          if (windows->info.mapped != MagickFalse)
            {
              if ((x < (int) (windows->info.x+windows->info.width)) &&
                  (y < (int) (windows->info.y+windows->info.height)))
                (void) XWithdrawWindow(display,windows->info.id,
                  windows->info.screen);
            }
          else
            if ((x > (int) (windows->info.x+windows->info.width)) ||
                (y > (int) (windows->info.y+windows->info.height)))
              (void) XMapWindow(display,windows->info.id);
          roi_info.x=(ssize_t) windows->image.x+event.xmotion.x;
          roi_info.y=(ssize_t) windows->image.y+event.xmotion.y;
          break;
        }
        case SelectionRequest:
        {
          XSelectionEvent
            notify;

          XSelectionRequestEvent
            *request;

          /*
            Set primary selection.
          */
          (void) FormatLocaleString(text,MagickPathExtent,
            "%.20gx%.20g%+.20g%+.20g",(double) roi_info.width,(double)
            roi_info.height,(double) roi_info.x,(double) roi_info.y);
          request=(&(event.xselectionrequest));
          (void) XChangeProperty(request->display,request->requestor,
            request->property,request->target,8,PropModeReplace,
            (unsigned char *) text,(int) strlen(text));
          notify.type=SelectionNotify;
          notify.display=request->display;
          notify.requestor=request->requestor;
          notify.selection=request->selection;
          notify.target=request->target;
          notify.time=request->time;
          if (request->property == None)
            notify.property=request->target;
          else
            notify.property=request->property;
          (void) XSendEvent(request->display,request->requestor,False,0,
            (XEvent *) &notify);
        }
        default:
          break;
      }
      if ((state & UpdateConfigurationState) != 0)
        {
          (void) XPutBackEvent(display,&event);
          (void) XCheckDefineCursor(display,windows->image.id,cursor);
          break;
        }
    } while ((state & ExitState) == 0);
  } while ((state & ExitState) == 0);
  (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
  XSetCursorState(display,windows,MagickFalse);
  if ((state & EscapeState) != 0)
    return(MagickTrue);
  return(MagickTrue);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X R o t a t e I m a g e                                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XRotateImage() rotates the X image.  If the degrees parameter if zero, the
%  rotation angle is computed from the slope of a line drawn by the user.
%
%  The format of the XRotateImage method is:
%
%      MagickBooleanType XRotateImage(Display *display,
%        XResourceInfo *resource_info,XWindows *windows,double degrees,
%        Image **image,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o display: Specifies a connection to an X server; returned from
%      XOpenDisplay.
%
%    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
%
%    o windows: Specifies a pointer to a XWindows structure.
%
%    o degrees: Specifies the number of degrees to rotate the image.
%
%    o image: the image.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static MagickBooleanType XRotateImage(Display *display,
  XResourceInfo *resource_info,XWindows *windows,double degrees,Image **image,
  ExceptionInfo *exception)
{
  const char
    *const RotateMenu[] =
    {
      "Pixel Color",
      "Direction",
      "Help",
      "Dismiss",
      (char *) NULL
    };

  static ModeType
    direction = HorizontalRotateCommand;

  static const ModeType
    DirectionCommands[] =
    {
      HorizontalRotateCommand,
      VerticalRotateCommand
    },
    RotateCommands[] =
    {
      RotateColorCommand,
      RotateDirectionCommand,
      RotateHelpCommand,
      RotateDismissCommand
    };

  static unsigned int
    pen_id = 0;

  char
    command[MagickPathExtent],
    text[MagickPathExtent];

  Image
    *rotate_image;

  int
    id,
    x,
    y;

  double
    normalized_degrees;

  int
    i;

  unsigned int
    height,
    rotations,
    width;

  if (degrees == 0.0)
    {
      unsigned int
        distance;

      size_t
        state;

      XEvent
        event;

      XSegment
        rotate_info;

      /*
        Map Command widget.
      */
      (void) CloneString(&windows->command.name,"Rotate");
      windows->command.data=2;
      (void) XCommandWidget(display,windows,RotateMenu,(XEvent *) NULL);
      (void) XMapRaised(display,windows->command.id);
      XClientMessage(display,windows->image.id,windows->im_protocols,
        windows->im_update_widget,CurrentTime);
      /*
        Wait for first button press.
      */
      (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
      XQueryPosition(display,windows->image.id,&x,&y);
      rotate_info.x1=x;
      rotate_info.y1=y;
      rotate_info.x2=x;
      rotate_info.y2=y;
      state=DefaultState;
      do
      {
        XHighlightLine(display,windows->image.id,
          windows->image.highlight_context,&rotate_info);
        /*
          Wait for next event.
        */
        XScreenEvent(display,windows,&event,exception);
        XHighlightLine(display,windows->image.id,
          windows->image.highlight_context,&rotate_info);
        if (event.xany.window == windows->command.id)
          {
            /*
              Select a command from the Command widget.
            */
            id=XCommandWidget(display,windows,RotateMenu,&event);
            if (id < 0)
              continue;
            (void) XSetFunction(display,windows->image.highlight_context,
              GXcopy);
            switch (RotateCommands[id])
            {
              case RotateColorCommand:
              {
                const char
                  *ColorMenu[MaxNumberPens];

                int
                  pen_number;

                XColor
                  color;

                /*
                  Initialize menu selections.
                */
                for (i=0; i < (int) (MaxNumberPens-2); i++)
                  ColorMenu[i]=resource_info->pen_colors[i];
                ColorMenu[MaxNumberPens-2]="Browser...";
                ColorMenu[MaxNumberPens-1]=(const char *) NULL;
                /*
                  Select a pen color from the pop-up menu.
                */
                pen_number=XMenuWidget(display,windows,RotateMenu[id],
                  (const char **) ColorMenu,command);
                if (pen_number < 0)
                  break;
                if (pen_number == (MaxNumberPens-2))
                  {
                    static char
                      color_name[MagickPathExtent] = "gray";

                    /*
                      Select a pen color from a dialog.
                    */
                    resource_info->pen_colors[pen_number]=color_name;
                    XColorBrowserWidget(display,windows,"Select",color_name);
                    if (*color_name == '\0')
                      break;
                  }
                /*
                  Set pen color.
                */
                (void) XParseColor(display,windows->map_info->colormap,
                  resource_info->pen_colors[pen_number],&color);
                XBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
                  (unsigned int) MaxColors,&color);
                windows->pixel_info->pen_colors[pen_number]=color;
                pen_id=(unsigned int) pen_number;
                break;
              }
              case RotateDirectionCommand:
              {
                const char
                  *Directions[] =
                  {
                    "horizontal",
                    "vertical",
                    (char *) NULL,
                  };

                /*
                  Select a command from the pop-up menu.
                */
                id=XMenuWidget(display,windows,RotateMenu[id],
                  Directions,command);
                if (id >= 0)
                  direction=DirectionCommands[id];
                break;
              }
              case RotateHelpCommand:
              {
                XTextViewHelp(display,resource_info,windows,MagickFalse,
                  "Help Viewer - Image Rotation",ImageRotateHelp);
                break;
              }
              case RotateDismissCommand:
              {
                /*
                  Prematurely exit.
                */
                state|=EscapeState;
                state|=ExitState;
                break;
              }
              default:
                break;
            }
            (void) XSetFunction(display,windows->image.highlight_context,
              GXinvert);
            continue;
          }
        switch (event.type)
        {
          case ButtonPress:
          {
            if (event.xbutton.button != Button1)
              break;
            if (event.xbutton.window != windows->image.id)
              break;
            /*
              exit loop.
            */
            (void) XSetFunction(display,windows->image.highlight_context,
              GXcopy);
            rotate_info.x1=event.xbutton.x;
            rotate_info.y1=event.xbutton.y;
            state|=ExitState;
            break;
          }
          case ButtonRelease:
            break;
          case Expose:
            break;
          case KeyPress:
          {
            char
              command[MagickPathExtent];

            KeySym
              key_symbol;

            if (event.xkey.window != windows->image.id)
              break;
            /*
              Respond to a user key press.
            */
            (void) XLookupString((XKeyEvent *) &event.xkey,command,(int)
              sizeof(command),&key_symbol,(XComposeStatus *) NULL);
            switch ((int) key_symbol)
            {
              case XK_Escape:
              case XK_F20:
              {
                /*
                  Prematurely exit.
                */
                state|=EscapeState;
                state|=ExitState;
                break;
              }
              case XK_F1:
              case XK_Help:
              {
                (void) XSetFunction(display,windows->image.highlight_context,
                  GXcopy);
                XTextViewHelp(display,resource_info,windows,MagickFalse,
                  "Help Viewer - Image Rotation",ImageRotateHelp);
                (void) XSetFunction(display,windows->image.highlight_context,
                  GXinvert);
                break;
              }
              default:
              {
                (void) XBell(display,0);
                break;
              }
            }
            break;
          }
          case MotionNotify:
          {
            rotate_info.x1=event.xmotion.x;
            rotate_info.y1=event.xmotion.y;
          }
        }
        rotate_info.x2=rotate_info.x1;
        rotate_info.y2=rotate_info.y1;
        if (direction == HorizontalRotateCommand)
          rotate_info.x2+=32;
        else
          rotate_info.y2-=32;
      } while ((state & ExitState) == 0);
      (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
      (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
      if ((state & EscapeState) != 0)
        return(MagickTrue);
      /*
        Draw line as pointer moves until the mouse button is released.
      */
      distance=0;
      (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
      state=DefaultState;
      do
      {
        if (distance > 9)
          {
            /*
              Display info and draw rotation line.
            */
            if (windows->info.mapped == MagickFalse)
              (void) XMapWindow(display,windows->info.id);
            (void) FormatLocaleString(text,MagickPathExtent," %g",
              direction == VerticalRotateCommand ? degrees-90.0 : degrees);
            XInfoWidget(display,windows,text);
            XHighlightLine(display,windows->image.id,
              windows->image.highlight_context,&rotate_info);
          }
        else
          if (windows->info.mapped != MagickFalse)
            (void) XWithdrawWindow(display,windows->info.id,
              windows->info.screen);
        /*
          Wait for next event.
        */
        XScreenEvent(display,windows,&event,exception);
        if (distance > 9)
          XHighlightLine(display,windows->image.id,
            windows->image.highlight_context,&rotate_info);
        switch (event.type)
        {
          case ButtonPress:
            break;
          case ButtonRelease:
          {
            /*
              User has committed to rotation line.
            */
            rotate_info.x2=event.xbutton.x;
            rotate_info.y2=event.xbutton.y;
            state|=ExitState;
            break;
          }
          case Expose:
            break;
          case MotionNotify:
          {
            rotate_info.x2=event.xmotion.x;
            rotate_info.y2=event.xmotion.y;
          }
          default:
            break;
        }
        /*
          Check boundary conditions.
        */
        if (rotate_info.x2 < 0)
          rotate_info.x2=0;
        else
          if (rotate_info.x2 > (int) windows->image.width)
            rotate_info.x2=(short) windows->image.width;
        if (rotate_info.y2 < 0)
          rotate_info.y2=0;
        else
          if (rotate_info.y2 > (int) windows->image.height)
            rotate_info.y2=(short) windows->image.height;
        /*
          Compute rotation angle from the slope of the line.
        */
        degrees=0.0;
        distance=(unsigned int)
          ((rotate_info.x2-rotate_info.x1+1)*(rotate_info.x2-rotate_info.x1+1))+
          ((rotate_info.y2-rotate_info.y1+1)*(rotate_info.y2-rotate_info.y1+1));
        if (distance > 9)
          degrees=RadiansToDegrees(-atan2((double) (rotate_info.y2-
            rotate_info.y1),(double) (rotate_info.x2-rotate_info.x1)));
      } while ((state & ExitState) == 0);
      (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
      (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
      if (distance <= 9)
        return(MagickTrue);
    }
  if (direction == VerticalRotateCommand)
    degrees-=90.0;
  if (degrees == 0.0)
    return(MagickTrue);
  /*
    Rotate image.
  */
  normalized_degrees=degrees;
  while (normalized_degrees < -45.0)
    normalized_degrees+=360.0;
  for (rotations=0; normalized_degrees > 45.0; rotations++)
    normalized_degrees-=90.0;
  if (normalized_degrees != 0.0)
    (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
      exception);
  XSetCursorState(display,windows,MagickTrue);
  XCheckRefreshWindows(display,windows);
  (*image)->background_color.red=(double) ScaleShortToQuantum(
    windows->pixel_info->pen_colors[pen_id].red);
  (*image)->background_color.green=(double) ScaleShortToQuantum(
    windows->pixel_info->pen_colors[pen_id].green);
  (*image)->background_color.blue=(double) ScaleShortToQuantum(
    windows->pixel_info->pen_colors[pen_id].blue);
  rotate_image=RotateImage(*image,degrees,exception);
  XSetCursorState(display,windows,MagickFalse);
  if (rotate_image == (Image *) NULL)
    return(MagickFalse);
  *image=DestroyImage(*image);
  *image=rotate_image;
  if (windows->image.crop_geometry != (char *) NULL)
    {
      /*
        Rotate crop geometry.
      */
      width=(unsigned int) (*image)->columns;
      height=(unsigned int) (*image)->rows;
      (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
      switch (rotations % 4)
      {
        default:
        case 0:
          break;
        case 1:
        {
          /*
            Rotate 90 degrees.
          */
          (void) FormatLocaleString(windows->image.crop_geometry,
            MagickPathExtent,"%ux%u%+d%+d",height,width,(int) (*image)->columns-
            (int) height-y,x);
          break;
        }
        case 2:
        {
          /*
            Rotate 180 degrees.
          */
          (void) FormatLocaleString(windows->image.crop_geometry,
            MagickPathExtent,"%ux%u%+d%+d",width,height,(int) width-x,(int)
            height-y);
          break;
        }
        case 3:
        {
          /*
            Rotate 270 degrees.
          */
          (void) FormatLocaleString(windows->image.crop_geometry,
            MagickPathExtent,"%ux%u%+d%+d",height,width,y,(int) (*image)->rows-
            (int) width-x);
          break;
        }
      }
    }
  if (windows->image.orphan != MagickFalse)
    return(MagickTrue);
  if (normalized_degrees != 0.0)
    {
      /*
        Update image colormap.
      */
      windows->image.window_changes.width=(int) (*image)->columns;
      windows->image.window_changes.height=(int) (*image)->rows;
      if (windows->image.crop_geometry != (char *) NULL)
        {
          /*
            Obtain dimensions of image from crop geometry.
          */
          (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
            &width,&height);
          windows->image.window_changes.width=(int) width;
          windows->image.window_changes.height=(int) height;
        }
      XConfigureImageColormap(display,resource_info,windows,*image,exception);
    }
  else
    if (((rotations % 4) == 1) || ((rotations % 4) == 3))
      {
        windows->image.window_changes.width=windows->image.ximage->height;
        windows->image.window_changes.height=windows->image.ximage->width;
      }
  /*
    Update image configuration.
  */
  (void) XConfigureImage(display,resource_info,windows,*image,exception);
  return(MagickTrue);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X S a v e I m a g e                                                       %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XSaveImage() saves an image to a file.
%
%  The format of the XSaveImage method is:
%
%      MagickBooleanType XSaveImage(Display *display,
%        XResourceInfo *resource_info,XWindows *windows,Image *image,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o display: Specifies a connection to an X server; returned from
%      XOpenDisplay.
%
%    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
%
%    o windows: Specifies a pointer to a XWindows structure.
%
%    o image: the image.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static MagickBooleanType XSaveImage(Display *display,
  XResourceInfo *resource_info,XWindows *windows,Image *image,
  ExceptionInfo *exception)
{
  char
    filename[MagickPathExtent],
    geometry[MagickPathExtent];

  Image
    *save_image;

  ImageInfo
    *image_info;

  MagickStatusType
    status;

  /*
    Request file name from user.
  */
  if (resource_info->write_filename != (char *) NULL)
    (void) CopyMagickString(filename,resource_info->write_filename,
      MagickPathExtent);
  else
    {
      char
        path[MagickPathExtent];

      int
        status;

      GetPathComponent(image->filename,HeadPath,path);
      GetPathComponent(image->filename,TailPath,filename);
      if (*path != '\0')
        {
          status=chdir(path);
          if (status == -1)
            (void) ThrowMagickException(exception,GetMagickModule(),
              FileOpenError,"UnableToOpenFile","%s",path);
        }
    }
  XFileBrowserWidget(display,windows,"Save",filename);
  if (*filename == '\0')
    return(MagickTrue);
  if (IsPathAccessible(filename) != MagickFalse)
    {
      int
        status;

      /*
        File exists-- seek user's permission before overwriting.
      */
      status=XConfirmWidget(display,windows,"Overwrite",filename);
      if (status <= 0)
        return(MagickTrue);
    }
  image_info=CloneImageInfo(resource_info->image_info);
  (void) CopyMagickString(image_info->filename,filename,MagickPathExtent);
  (void) SetImageInfo(image_info,1,exception);
  if ((LocaleCompare(image_info->magick,"JPEG") == 0) ||
      (LocaleCompare(image_info->magick,"JPG") == 0))
    {
      char
        quality[MagickPathExtent];

      int
        status;

      /*
        Request JPEG quality from user.
      */
      (void) FormatLocaleString(quality,MagickPathExtent,"%.20g",(double)
        image->quality);
      status=XDialogWidget(display,windows,"Save","Enter JPEG quality:",
        quality);
      if (*quality == '\0')
        return(MagickTrue);
      image->quality=StringToUnsignedLong(quality);
      image_info->interlace=status != 0 ? NoInterlace : PlaneInterlace;
    }
  if ((LocaleCompare(image_info->magick,"EPS") == 0) ||
      (LocaleCompare(image_info->magick,"PDF") == 0) ||
      (LocaleCompare(image_info->magick,"PS") == 0) ||
      (LocaleCompare(image_info->magick,"PS2") == 0))
    {
      char
        geometry[MagickPathExtent];

      const char
        *const PageSizes[] =
        {
          "Letter",
          "Tabloid",
          "Ledger",
          "Legal",
          "Statement",
          "Executive",
          "A3",
          "A4",
          "A5",
          "B4",
          "B5",
          "Folio",
          "Quarto",
          "10x14",
          (char *) NULL
        };

      /*
        Request page geometry from user.
      */
      (void) CopyMagickString(geometry,PSPageGeometry,MagickPathExtent);
      if (LocaleCompare(image_info->magick,"PDF") == 0)
        (void) CopyMagickString(geometry,PSPageGeometry,MagickPathExtent);
      if (image_info->page != (char *) NULL)
        (void) CopyMagickString(geometry,image_info->page,MagickPathExtent);
      XListBrowserWidget(display,windows,&windows->widget,PageSizes,"Select",
        "Select page geometry:",geometry);
      if (*geometry != '\0')
        image_info->page=GetPageGeometry(geometry);
    }
  /*
    Apply image transforms.
  */
  XSetCursorState(display,windows,MagickTrue);
  XCheckRefreshWindows(display,windows);
  save_image=CloneImage(image,0,0,MagickTrue,exception);
  if (save_image == (Image *) NULL)
    return(MagickFalse);
  (void) FormatLocaleString(geometry,MagickPathExtent,"%dx%d!",
    windows->image.ximage->width,windows->image.ximage->height);
  (void) TransformImage(&save_image,windows->image.crop_geometry,geometry,
    exception);
  /*
    Write image.
  */
  (void) CopyMagickString(save_image->filename,filename,MagickPathExtent);
  status=WriteImage(image_info,save_image,exception);
  if (status != MagickFalse)
    image->taint=MagickFalse;
  save_image=DestroyImage(save_image);
  image_info=DestroyImageInfo(image_info);
  XSetCursorState(display,windows,MagickFalse);
  return(status != 0 ? MagickTrue : MagickFalse);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X S c r e e n E v e n t                                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XScreenEvent() handles global events associated with the Pan and Magnify
%  windows.
%
%  The format of the XScreenEvent function is:
%
%      void XScreenEvent(Display *display,XWindows *windows,XEvent *event,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o display: Specifies a pointer to the Display structure;  returned from
%      XOpenDisplay.
%
%    o windows: Specifies a pointer to a XWindows structure.
%
%    o event: Specifies a pointer to a X11 XEvent structure.
%
%    o exception: return any errors or warnings in this structure.
%
*/

#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif

static int XPredicate(Display *magick_unused(display),XEvent *event,char *data)
{
  XWindows
    *windows;

  windows=(XWindows *) data;
  if ((event->type == ClientMessage) &&
      (event->xclient.window == windows->image.id))
    return(MagickFalse);
  return(MagickTrue);
}

#if defined(__cplusplus) || defined(c_plusplus)
}
#endif

static void XScreenEvent(Display *display,XWindows *windows,XEvent *event,
  ExceptionInfo *exception)
{
  int
    x,
    y;

  (void) XIfEvent(display,event,XPredicate,(char *) windows);
  if (event->xany.window == windows->command.id)
    return;
  switch (event->type)
  {
    case ButtonPress:
    case ButtonRelease:
    {
      if ((event->xbutton.button == Button3) &&
          (event->xbutton.state & Mod1Mask))
        {
          /*
            Convert Alt-Button3 to Button2.
          */
          event->xbutton.button=Button2;
          event->xbutton.state&=(~Mod1Mask);
        }
      if (event->xbutton.window == windows->backdrop.id)
        {
          (void) XSetInputFocus(display,event->xbutton.window,RevertToParent,
            event->xbutton.time);
          break;
        }
      if (event->xbutton.window == windows->pan.id)
        {
          XPanImage(display,windows,event,exception);
          break;
        }
      if (event->xbutton.window == windows->image.id)
        if (event->xbutton.button == Button2)
          {
            /*
              Update magnified image.
            */
            x=event->xbutton.x;
            y=event->xbutton.y;
            if (x < 0)
              x=0;
            else
              if (x >= (int) windows->image.width)
                x=(int) (windows->image.width-1);
            windows->magnify.x=(int) windows->image.x+x;
            if (y < 0)
              y=0;
            else
             if (y >= (int) windows->image.height)
               y=(int) (windows->image.height-1);
            windows->magnify.y=windows->image.y+y;
            if (windows->magnify.mapped == MagickFalse)
              (void) XMapRaised(display,windows->magnify.id);
            XMakeMagnifyImage(display,windows,exception);
            if (event->type == ButtonRelease)
              (void) XWithdrawWindow(display,windows->info.id,
                windows->info.screen);
            break;
          }
      break;
    }
    case ClientMessage:
    {
      /*
        If client window delete message, exit.
      */
      if (event->xclient.message_type != windows->wm_protocols)
        break;
      if (*event->xclient.data.l != (long) windows->wm_delete_window)
        break;
      if (event->xclient.window == windows->magnify.id)
        {
          (void) XWithdrawWindow(display,windows->magnify.id,
            windows->magnify.screen);
          break;
        }
      break;
    }
    case ConfigureNotify:
    {
      if (event->xconfigure.window == windows->magnify.id)
        {
          unsigned int
            magnify;

          /*
            Magnify window has a new configuration.
          */
          windows->magnify.width=(unsigned int) event->xconfigure.width;
          windows->magnify.height=(unsigned int) event->xconfigure.height;
          if (windows->magnify.mapped == MagickFalse)
            break;
          magnify=1;
          while ((int) magnify <= event->xconfigure.width)
            magnify<<=1;
          while ((int) magnify <= event->xconfigure.height)
            magnify<<=1;
          magnify>>=1;
          if (((int) magnify != event->xconfigure.width) ||
              ((int) magnify != event->xconfigure.height))
            {
              XWindowChanges
                window_changes;

              window_changes.width=(int) magnify;
              window_changes.height=(int) magnify;
              (void) XReconfigureWMWindow(display,windows->magnify.id,
                windows->magnify.screen,(unsigned int) (CWWidth | CWHeight),
                &window_changes);
              break;
            }
          XMakeMagnifyImage(display,windows,exception);
          break;
        }
      break;
    }
    case Expose:
    {
      if (event->xexpose.window == windows->image.id)
        {
          XRefreshWindow(display,&windows->image,event);
          break;
        }
      if (event->xexpose.window == windows->pan.id)
        if (event->xexpose.count == 0)
          {
            XDrawPanRectangle(display,windows);
            break;
          }
      if (event->xexpose.window == windows->magnify.id)
        if (event->xexpose.count == 0)
          {
            XMakeMagnifyImage(display,windows,exception);
            break;
          }
      break;
    }
    case KeyPress:
    {
      char
        command[MagickPathExtent];

      KeySym
        key_symbol;

      if (event->xkey.window != windows->magnify.id)
        break;
      /*
        Respond to a user key press.
      */
      (void) XLookupString((XKeyEvent *) &event->xkey,command,(int)
        sizeof(command),&key_symbol,(XComposeStatus *) NULL);
      XMagnifyWindowCommand(display,windows,event->xkey.state,key_symbol,
        exception);
      break;
    }
    case MapNotify:
    {
      if (event->xmap.window == windows->magnify.id)
        {
          windows->magnify.mapped=MagickTrue;
          (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
          break;
        }
      if (event->xmap.window == windows->info.id)
        {
          windows->info.mapped=MagickTrue;
          break;
        }
      break;
    }
    case MotionNotify:
    {
      while (XCheckMaskEvent(display,ButtonMotionMask,event)) ;
      if (event->xmotion.window == windows->image.id)
        if (windows->magnify.mapped != MagickFalse)
          {
            /*
              Update magnified image.
            */
            x=event->xmotion.x;
            y=event->xmotion.y;
            if (x < 0)
              x=0;
            else
              if (x >= (int) windows->image.width)
                x=(int) (windows->image.width-1);
            windows->magnify.x=(int) windows->image.x+x;
            if (y < 0)
              y=0;
            else
             if (y >= (int) windows->image.height)
               y=(int) (windows->image.height-1);
            windows->magnify.y=windows->image.y+y;
            XMakeMagnifyImage(display,windows,exception);
          }
      break;
    }
    case UnmapNotify:
    {
      if (event->xunmap.window == windows->magnify.id)
        {
          windows->magnify.mapped=MagickFalse;
          break;
        }
      if (event->xunmap.window == windows->info.id)
        {
          windows->info.mapped=MagickFalse;
          break;
        }
      break;
    }
    default:
      break;
  }
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X S e t C r o p G e o m e t r y                                           %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XSetCropGeometry() accepts a cropping geometry relative to the Image window
%  and translates it to a cropping geometry relative to the image.
%
%  The format of the XSetCropGeometry method is:
%
%      void XSetCropGeometry(Display *display,XWindows *windows,
%        RectangleInfo *crop_info,Image *image)
%
%  A description of each parameter follows:
%
%    o display: Specifies a connection to an X server; returned from
%      XOpenDisplay.
%
%    o windows: Specifies a pointer to a XWindows structure.
%
%    o crop_info:  A pointer to a RectangleInfo that defines a region of the
%      Image window to crop.
%
%    o image: the image.
%
*/
static void XSetCropGeometry(Display *display,XWindows *windows,
  RectangleInfo *crop_info,Image *image)
{
  char
    text[MagickPathExtent];

  int
    x,
    y;

  double
    scale_factor;

  unsigned int
    height,
    width;

  if (windows->info.mapped != MagickFalse)
    {
      /*
        Display info on cropping rectangle.
      */
      (void) FormatLocaleString(text,MagickPathExtent," %.20gx%.20g%+.20g%+.20g",
        (double) crop_info->width,(double) crop_info->height,(double)
        crop_info->x,(double) crop_info->y);
      XInfoWidget(display,windows,text);
    }
  /*
    Cropping geometry is relative to any previous crop geometry.
  */
  x=0;
  y=0;
  width=(unsigned int) image->columns;
  height=(unsigned int) image->rows;
  if (windows->image.crop_geometry != (char *) NULL)
    (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
  else
    windows->image.crop_geometry=AcquireString((char *) NULL);
  /*
    Define the crop geometry string from the cropping rectangle.
  */
  scale_factor=(double) width/windows->image.ximage->width;
  if (crop_info->x > 0)
    x+=(int) (scale_factor*crop_info->x+0.5);
  width=(unsigned int) (scale_factor*crop_info->width+0.5);
  if (width == 0)
    width=1;
  scale_factor=(double) height/windows->image.ximage->height;
  if (crop_info->y > 0)
    y+=(int) (scale_factor*crop_info->y+0.5);
  height=(unsigned int) (scale_factor*crop_info->height+0.5);
  if (height == 0)
    height=1;
  (void) FormatLocaleString(windows->image.crop_geometry,MagickPathExtent,
    "%ux%u%+d%+d",width,height,x,y);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X T i l e I m a g e                                                       %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XTileImage() loads or deletes a selected tile from a visual image directory.
%  The load or delete command is chosen from a menu.
%
%  The format of the XTileImage method is:
%
%      Image *XTileImage(Display *display,XResourceInfo *resource_info,
%        XWindows *windows,Image *image,XEvent *event,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o tile_image:  XTileImage reads or deletes the tile image
%      and returns it.  A null image is returned if an error occurs.
%
%    o display: Specifies a connection to an X server;  returned from
%      XOpenDisplay.
%
%    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
%
%    o windows: Specifies a pointer to a XWindows structure.
%
%    o image: the image; returned from ReadImage.
%
%    o event: Specifies a pointer to a XEvent structure.  If it is NULL,
%      the entire image is refreshed.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static Image *XTileImage(Display *display,XResourceInfo *resource_info,
  XWindows *windows,Image *image,XEvent *event,ExceptionInfo *exception)
{
  const char
    *const VerbMenu[] =
    {
      "Load",
      "Next",
      "Former",
      "Delete",
      "Update",
      (char *) NULL,
    };

  static const ModeType
    TileCommands[] =
    {
      TileLoadCommand,
      TileNextCommand,
      TileFormerCommand,
      TileDeleteCommand,
      TileUpdateCommand
    };

  char
    command[MagickPathExtent],
    filename[MagickPathExtent];

  Image
    *tile_image;

  int
    id,
    status,
    tile,
    x,
    y;

  double
    scale_factor;

  char
    *p,
    *q;

  int
    i;

  unsigned int
    height,
    width;

  /*
    Tile image is relative to montage image configuration.
  */
  x=0;
  y=0;
  width=(unsigned int) image->columns;
  height=(unsigned int) image->rows;
  if (windows->image.crop_geometry != (char *) NULL)
    (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
  scale_factor=(double) width/windows->image.ximage->width;
  event->xbutton.x+=windows->image.x;
  event->xbutton.x=(int) (scale_factor*event->xbutton.x+x+0.5);
  scale_factor=(double) height/windows->image.ximage->height;
  event->xbutton.y+=windows->image.y;
  event->xbutton.y=(int) (scale_factor*event->xbutton.y+y+0.5);
  /*
    Determine size and location of each tile in the visual image directory.
  */
  width=(unsigned int) image->columns;
  height=(unsigned int) image->rows;
  x=0;
  y=0;
  (void) XParseGeometry(image->montage,&x,&y,&width,&height);
  tile=((event->xbutton.y-y)/height)*(((int) image->columns-x)/width)+
    (event->xbutton.x-x)/width;
  if (tile < 0)
    {
      /*
        Button press is outside any tile.
      */
      (void) XBell(display,0);
      return((Image *) NULL);
    }
  /*
    Determine file name from the tile directory.
  */
  p=image->directory;
  for (i=tile; (i != 0) && (*p != '\0'); )
  {
    if (*p == '\xff')
      i--;
    p++;
  }
  if (*p == '\0')
    {
      /*
        Button press is outside any tile.
      */
      (void) XBell(display,0);
      return((Image *) NULL);
    }
  /*
    Select a command from the pop-up menu.
  */
  id=XMenuWidget(display,windows,"Tile Verb",VerbMenu,command);
  if (id < 0)
    return((Image *) NULL);
  q=p;
  while ((*q != '\xff') && (*q != '\0'))
    q++;
  (void) CopyMagickString(filename,p,(size_t) (q-p+1));
  /*
    Perform command for the selected tile.
  */
  XSetCursorState(display,windows,MagickTrue);
  XCheckRefreshWindows(display,windows);
  tile_image=NewImageList();
  switch (TileCommands[id])
  {
    case TileLoadCommand:
    {
      /*
        Load tile image.
      */
      XCheckRefreshWindows(display,windows);
      (void) CopyMagickString(resource_info->image_info->magick,"MIFF",
        MagickPathExtent);
      (void) CopyMagickString(resource_info->image_info->filename,filename,
        MagickPathExtent);
      tile_image=ReadImage(resource_info->image_info,exception);
      CatchException(exception);
      (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
      break;
    }
    case TileNextCommand:
    {
      /*
        Display next image.
      */
      XClientMessage(display,windows->image.id,windows->im_protocols,
        windows->im_next_image,CurrentTime);
      break;
    }
    case TileFormerCommand:
    {
      /*
        Display former image.
      */
      XClientMessage(display,windows->image.id,windows->im_protocols,
        windows->im_former_image,CurrentTime);
      break;
    }
    case TileDeleteCommand:
    {
      /*
        Delete tile image.
      */
      if (IsPathAccessible(filename) == MagickFalse)
        {
          XNoticeWidget(display,windows,"Image file does not exist:",filename);
          break;
        }
      status=XConfirmWidget(display,windows,"Really delete tile",filename);
      if (status <= 0)
        break;
      status=ShredFile(filename);
      if (status != MagickFalse)
        {
          XNoticeWidget(display,windows,"Unable to delete image file:",
            filename);
          break;
        }
    }
    case TileUpdateCommand:
    {
      int
        x_offset,
        y_offset;

      PixelInfo
        pixel;

      int
        j;

      Quantum
        *s;

      /*
        Ensure all the images exist.
      */
      tile=0;
      GetPixelInfo(image,&pixel);
      for (p=image->directory; *p != '\0'; p++)
      {
        CacheView
          *image_view;

        q=p;
        while ((*q != '\xff') && (*q != '\0'))
          q++;
        (void) CopyMagickString(filename,p,(size_t) (q-p+1));
        p=q;
        if (IsPathAccessible(filename) != MagickFalse)
          {
            tile++;
            continue;
          }
        /*
          Overwrite tile with background color.
        */
        x_offset=(int) (width*(tile % (((int) image->columns-x)/width))+x);
        y_offset=(int) (height*(tile/(((int) image->columns-x)/width))+y);
        image_view=AcquireAuthenticCacheView(image,exception);
        (void) GetOneCacheViewVirtualPixelInfo(image_view,0,0,&pixel,exception);
        for (i=0; i < (int) height; i++)
        {
          s=GetCacheViewAuthenticPixels(image_view,(ssize_t) x_offset,(ssize_t)
            y_offset+i,width,1,exception);
          if (s == (Quantum *) NULL)
            break;
          for (j=0; j < (int) width; j++)
          {
            SetPixelViaPixelInfo(image,&pixel,s);
            s+=GetPixelChannels(image);
          }
          if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
            break;
        }
        image_view=DestroyCacheView(image_view);
        tile++;
      }
      windows->image.window_changes.width=(int) image->columns;
      windows->image.window_changes.height=(int) image->rows;
      XConfigureImageColormap(display,resource_info,windows,image,exception);
      (void) XConfigureImage(display,resource_info,windows,image,exception);
      break;
    }
    default:
      break;
  }
  XSetCursorState(display,windows,MagickFalse);
  return(tile_image);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X T r a n s l a t e I m a g e                                             %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XTranslateImage() translates the image within an Image window by one pixel
%  as specified by the key symbol.  If the image has a montage string the
%  translation is respect to the width and height contained within the string.
%
%  The format of the XTranslateImage method is:
%
%      void XTranslateImage(Display *display,XWindows *windows,
%        Image *image,const KeySym key_symbol)
%
%  A description of each parameter follows:
%
%    o display: Specifies a connection to an X server; returned from
%      XOpenDisplay.
%
%    o windows: Specifies a pointer to a XWindows structure.
%
%    o image: the image.
%
%    o key_symbol: Specifies a KeySym which indicates which side of the image
%      to trim.
%
*/
static void XTranslateImage(Display *display,XWindows *windows,
  Image *image,const KeySym key_symbol)
{
  char
    text[MagickPathExtent];

  int
    x,
    y;

  unsigned int
    x_offset,
    y_offset;

  /*
    User specified a pan position offset.
  */
  x_offset=windows->image.width;
  y_offset=windows->image.height;
  if (image->montage != (char *) NULL)
    (void) XParseGeometry(image->montage,&x,&y,&x_offset,&y_offset);
  switch ((int) key_symbol)
  {
    case XK_Home:
    case XK_KP_Home:
    {
      windows->image.x=(int) windows->image.width/2;
      windows->image.y=(int) windows->image.height/2;
      break;
    }
    case XK_Left:
    case XK_KP_Left:
    {
      windows->image.x-=x_offset;
      break;
    }
    case XK_Next:
    case XK_Up:
    case XK_KP_Up:
    {
      windows->image.y-=y_offset;
      break;
    }
    case XK_Right:
    case XK_KP_Right:
    {
      windows->image.x+=x_offset;
      break;
    }
    case XK_Prior:
    case XK_Down:
    case XK_KP_Down:
    {
      windows->image.y+=y_offset;
      break;
    }
    default:
      return;
  }
  /*
    Check boundary conditions.
  */
  if (windows->image.x < 0)
    windows->image.x=0;
  else
    if ((int) (windows->image.x+windows->image.width) >
        windows->image.ximage->width)
      windows->image.x=(int) windows->image.ximage->width-windows->image.width;
  if (windows->image.y < 0)
    windows->image.y=0;
  else
    if ((int) (windows->image.y+windows->image.height) >
        windows->image.ximage->height)
      windows->image.y=(int) windows->image.ximage->height-windows->image.height;
  /*
    Refresh Image window.
  */
  (void) FormatLocaleString(text,MagickPathExtent," %ux%u%+d%+d ",
    windows->image.width,windows->image.height,windows->image.x,
    windows->image.y);
  XInfoWidget(display,windows,text);
  XCheckRefreshWindows(display,windows);
  XDrawPanRectangle(display,windows);
  XRefreshWindow(display,&windows->image,(XEvent *) NULL);
  (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X T r i m I m a g e                                                       %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XTrimImage() trims the edges from the Image window.
%
%  The format of the XTrimImage method is:
%
%      MagickBooleanType XTrimImage(Display *display,
%        XResourceInfo *resource_info,XWindows *windows,Image *image,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o display: Specifies a connection to an X server; returned from
%      XOpenDisplay.
%
%    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
%
%    o windows: Specifies a pointer to a XWindows structure.
%
%    o image: the image.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static MagickBooleanType XTrimImage(Display *display,
  XResourceInfo *resource_info,XWindows *windows,Image *image,
  ExceptionInfo *exception)
{
  RectangleInfo
    trim_info;

  int
    x,
    y;

  size_t
    background,
    pixel;

  /*
    Trim edges from image.
  */
  XSetCursorState(display,windows,MagickTrue);
  XCheckRefreshWindows(display,windows);
  /*
    Crop the left edge.
  */
  background=XGetPixel(windows->image.ximage,0,0);
  trim_info.width=(size_t) windows->image.ximage->width;
  for (x=0; x < windows->image.ximage->width; x++)
  {
    for (y=0; y < windows->image.ximage->height; y++)
    {
      pixel=XGetPixel(windows->image.ximage,x,y);
      if (pixel != background)
        break;
    }
    if (y < windows->image.ximage->height)
      break;
  }
  trim_info.x=(ssize_t) x;
  if (trim_info.x == (ssize_t) windows->image.ximage->width)
    {
      XSetCursorState(display,windows,MagickFalse);
      return(MagickFalse);
    }
  /*
    Crop the right edge.
  */
  background=XGetPixel(windows->image.ximage,windows->image.ximage->width-1,0);
  for (x=windows->image.ximage->width-1; x != 0; x--)
  {
    for (y=0; y < windows->image.ximage->height; y++)
    {
      pixel=XGetPixel(windows->image.ximage,x,y);
      if (pixel != background)
        break;
    }
    if (y < windows->image.ximage->height)
      break;
  }
  trim_info.width=(size_t) (x-trim_info.x+1);
  /*
    Crop the top edge.
  */
  background=XGetPixel(windows->image.ximage,0,0);
  trim_info.height=(size_t) windows->image.ximage->height;
  for (y=0; y < windows->image.ximage->height; y++)
  {
    for (x=0; x < windows->image.ximage->width; x++)
    {
      pixel=XGetPixel(windows->image.ximage,x,y);
      if (pixel != background)
        break;
    }
    if (x < windows->image.ximage->width)
      break;
  }
  trim_info.y=(ssize_t) y;
  /*
    Crop the bottom edge.
  */
  background=XGetPixel(windows->image.ximage,0,windows->image.ximage->height-1);
  for (y=windows->image.ximage->height-1; y != 0; y--)
  {
    for (x=0; x < windows->image.ximage->width; x++)
    {
      pixel=XGetPixel(windows->image.ximage,x,y);
      if (pixel != background)
        break;
    }
    if (x < windows->image.ximage->width)
      break;
  }
  trim_info.height=(size_t) y-trim_info.y+1;
  if (((unsigned int) trim_info.width != windows->image.width) ||
      ((unsigned int) trim_info.height != windows->image.height))
    {
      /*
        Reconfigure Image window as defined by the trimming rectangle.
      */
      XSetCropGeometry(display,windows,&trim_info,image);
      windows->image.window_changes.width=(int) trim_info.width;
      windows->image.window_changes.height=(int) trim_info.height;
      (void) XConfigureImage(display,resource_info,windows,image,exception);
    }
  XSetCursorState(display,windows,MagickFalse);
  return(MagickTrue);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X V i s u a l D i r e c t o r y I m a g e                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XVisualDirectoryImage() creates a Visual Image Directory.
%
%  The format of the XVisualDirectoryImage method is:
%
%      Image *XVisualDirectoryImage(Display *display,
%        XResourceInfo *resource_info,XWindows *windows,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o display: Specifies a connection to an X server; returned from
%      XOpenDisplay.
%
%    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
%
%    o windows: Specifies a pointer to a XWindows structure.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static Image *XVisualDirectoryImage(Display *display,
  XResourceInfo *resource_info,XWindows *windows,ExceptionInfo *exception)
{
#define TileImageTag  "Scale/Image"
#define XClientName  "montage"

  char
    **filelist;

  Image
    *images,
    *montage_image,
    *next_image,
    *thumbnail_image;

  ImageInfo
    *read_info;

  int
    number_files;

  MagickBooleanType
    backdrop;

  MagickStatusType
    status;

  MontageInfo
    *montage_info;

  RectangleInfo
    geometry;

  int
    i;

  static char
    filename[MagickPathExtent] = "\0",
    filenames[MagickPathExtent] = "*";

  XResourceInfo
    background_resources;

  /*
    Request file name from user.
  */
  XFileBrowserWidget(display,windows,"Directory",filenames);
  if (*filenames == '\0')
    return((Image *) NULL);
  /*
    Expand the filenames.
  */
  filelist=(char **) AcquireMagickMemory(sizeof(*filelist));
  if (filelist == (char **) NULL)
    {
      ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed",
        filenames);
      return((Image *) NULL);
    }
  number_files=1;
  filelist[0]=filenames;
  status=ExpandFilenames(&number_files,&filelist);
  if ((status == MagickFalse) || (number_files == 0))
    {
      if (number_files == 0)
        ThrowXWindowException(ImageError,"NoImagesWereFound",filenames)
      else
        ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed",
          filenames);
      return((Image *) NULL);
    }
  /*
    Set image background resources.
  */
  background_resources=(*resource_info);
  background_resources.window_id=AcquireString("");
  (void) FormatLocaleString(background_resources.window_id,MagickPathExtent,
    "0x%lx",windows->image.id);
  background_resources.backdrop=MagickTrue;
  /*
    Read each image and convert them to a tile.
  */
  backdrop=((windows->visual_info->klass == TrueColor) ||
    (windows->visual_info->klass == DirectColor)) ? MagickTrue : MagickFalse;
  read_info=CloneImageInfo(resource_info->image_info);
  (void) SetImageOption(read_info,"jpeg:size","120x120");
  (void) CloneString(&read_info->size,DefaultTileGeometry);
  (void) SetImageInfoProgressMonitor(read_info,(MagickProgressMonitor) NULL,
    (void *) NULL);
  images=NewImageList();
  XSetCursorState(display,windows,MagickTrue);
  XCheckRefreshWindows(display,windows);
  for (i=0; i < (int) number_files; i++)
  {
    (void) CopyMagickString(read_info->filename,filelist[i],MagickPathExtent);
    filelist[i]=DestroyString(filelist[i]);
    *read_info->magick='\0';
    next_image=ReadImage(read_info,exception);
    CatchException(exception);
    if (next_image != (Image *) NULL)
      {
        (void) DeleteImageProperty(next_image,"label");
        (void) SetImageProperty(next_image,"label",InterpretImageProperties(
          read_info,next_image,DefaultTileLabel,exception),exception);
        (void) ParseRegionGeometry(next_image,read_info->size,&geometry,
          exception);
        thumbnail_image=ThumbnailImage(next_image,geometry.width,
          geometry.height,exception);
        if (thumbnail_image != (Image *) NULL)
          {
            next_image=DestroyImage(next_image);
            next_image=thumbnail_image;
          }
        if (backdrop)
          {
            (void) XDisplayBackgroundImage(display,&background_resources,
              next_image,exception);
            XSetCursorState(display,windows,MagickTrue);
          }
        AppendImageToList(&images,next_image);
        if (images->progress_monitor != (MagickProgressMonitor) NULL)
          {
            MagickBooleanType
              proceed;

            proceed=SetImageProgress(images,LoadImageTag,(MagickOffsetType) i,
              (MagickSizeType) number_files);
            if (proceed == MagickFalse)
              break;
          }
      }
  }
  filelist=(char **) RelinquishMagickMemory(filelist);
  if (images == (Image *) NULL)
    {
      read_info=DestroyImageInfo(read_info);
      XSetCursorState(display,windows,MagickFalse);
      ThrowXWindowException(ImageError,"NoImagesWereLoaded",filenames);
      return((Image *) NULL);
    }
  /*
    Create the Visual Image Directory.
  */
  montage_info=CloneMontageInfo(read_info,(MontageInfo *) NULL);
  montage_info->pointsize=10;
  if (resource_info->font != (char *) NULL)
    (void) CloneString(&montage_info->font,resource_info->font);
  (void) CopyMagickString(montage_info->filename,filename,MagickPathExtent);
  montage_image=MontageImageList(read_info,montage_info,GetFirstImageInList(
    images),exception);
  images=DestroyImageList(images);
  montage_info=DestroyMontageInfo(montage_info);
  read_info=DestroyImageInfo(read_info);
  XSetCursorState(display,windows,MagickFalse);
  if (montage_image == (Image *) NULL)
    return(montage_image);
  XClientMessage(display,windows->image.id,windows->im_protocols,
    windows->im_next_image,CurrentTime);
  return(montage_image);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   X D i s p l a y B a c k g r o u n d I m a g e                             %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XDisplayBackgroundImage() displays an image in the background of a window.
%
%  The format of the XDisplayBackgroundImage method is:
%
%      MagickBooleanType XDisplayBackgroundImage(Display *display,
%        XResourceInfo *resource_info,Image *image,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o display: Specifies a connection to an X server;  returned from
%      XOpenDisplay.
%
%    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
%
%    o image: the image.
%
%    o exception: return any errors or warnings in this structure.
%
*/
MagickExport MagickBooleanType XDisplayBackgroundImage(Display *display,
  XResourceInfo *resource_info,Image *image,ExceptionInfo *exception)
{
  char
    geometry[MagickPathExtent],
    visual_type[MagickPathExtent];

  int
    height,
    status,
    width;

  RectangleInfo
    geometry_info;

  static XPixelInfo
    pixel;

  static XStandardColormap
    *map_info;

  static XVisualInfo
    *visual_info = (XVisualInfo *) NULL;

  static XWindowInfo
    window_info;

  size_t
    delay;

  Window
    root_window;

  XGCValues
    context_values;

  XResourceInfo
    resources;

  XWindowAttributes
    window_attributes;

  /*
    Determine target window.
  */
  assert(image != (Image *) NULL);
  assert(image->signature == MagickCoreSignature);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  resources=(*resource_info);
  window_info.id=(Window) NULL;
  root_window=XRootWindow(display,XDefaultScreen(display));
  if (LocaleCompare(resources.window_id,"root") == 0)
    window_info.id=root_window;
  else
    {
      if (isdigit((int) ((unsigned char) *resources.window_id)) != 0)
        window_info.id=XWindowByID(display,root_window,
          (Window) strtol((char *) resources.window_id,(char **) NULL,0));
      if (window_info.id == (Window) NULL)
        window_info.id=XWindowByName(display,root_window,resources.window_id);
    }
  if (window_info.id == (Window) NULL)
    {
      ThrowXWindowException(XServerError,"NoWindowWithSpecifiedIDExists",
        resources.window_id);
      return(MagickFalse);
    }
  /*
    Determine window visual id.
  */
  window_attributes.width=XDisplayWidth(display,XDefaultScreen(display));
  window_attributes.height=XDisplayHeight(display,XDefaultScreen(display));
  (void) CopyMagickString(visual_type,"default",MagickPathExtent);
  status=XGetWindowAttributes(display,window_info.id,&window_attributes);
  if (status != 0)
    (void) FormatLocaleString(visual_type,MagickPathExtent,"0x%lx",
      XVisualIDFromVisual(window_attributes.visual));
  if (visual_info == (XVisualInfo *) NULL)
    {
      /*
        Allocate standard colormap.
      */
      map_info=XAllocStandardColormap();
      if (map_info == (XStandardColormap *) NULL)
        ThrowXWindowFatalException(XServerFatalError,"MemoryAllocationFailed",
          image->filename);
      map_info->colormap=(Colormap) NULL;
      pixel.pixels=(unsigned long *) NULL;
      /*
        Initialize visual info.
      */
      resources.map_type=(char *) NULL;
      resources.visual_type=visual_type;
      visual_info=XBestVisualInfo(display,map_info,&resources);
      if (visual_info == (XVisualInfo *) NULL)
        ThrowXWindowFatalException(XServerFatalError,"UnableToGetVisual",
          resources.visual_type);
      /*
        Initialize window info.
      */
      window_info.ximage=(XImage *) NULL;
      window_info.matte_image=(XImage *) NULL;
      window_info.pixmap=(Pixmap) NULL;
      window_info.matte_pixmap=(Pixmap) NULL;
    }
  /*
    Free previous root colors.
  */
  if (window_info.id == root_window)
    (void) XDestroyWindowColors(display,root_window);
  /*
    Initialize Standard Colormap.
  */
  resources.colormap=SharedColormap;
  XMakeStandardColormap(display,visual_info,&resources,image,map_info,&pixel,
    exception);
  /*
    Graphic context superclass.
  */
  context_values.background=pixel.foreground_color.pixel;
  context_values.foreground=pixel.background_color.pixel;
  pixel.annotate_context=XCreateGC(display,window_info.id,
    (size_t) (GCBackground | GCForeground),&context_values);
  if (pixel.annotate_context == (GC) NULL)
    ThrowXWindowFatalException(XServerFatalError,"UnableToCreateGraphicContext",
      image->filename);
  /*
    Initialize Image window attributes.
  */
  window_info.name=AcquireString("\0");
  window_info.icon_name=AcquireString("\0");
  XGetWindowInfo(display,visual_info,map_info,&pixel,(XFontStruct *) NULL,
    &resources,&window_info);
  /*
    Create the X image.
  */
  window_info.width=(unsigned int) image->columns;
  window_info.height=(unsigned int) image->rows;
  if ((image->columns != window_info.width) ||
      (image->rows != window_info.height))
    ThrowXWindowFatalException(XServerFatalError,"UnableToCreateXImage",
      image->filename);
  (void) FormatLocaleString(geometry,MagickPathExtent,"%ux%u+0+0>",
    window_attributes.width,window_attributes.height);
  geometry_info.width=window_info.width;
  geometry_info.height=window_info.height;
  geometry_info.x=(ssize_t) window_info.x;
  geometry_info.y=(ssize_t) window_info.y;
  (void) ParseMetaGeometry(geometry,&geometry_info.x,&geometry_info.y,
    &geometry_info.width,&geometry_info.height);
  window_info.width=(unsigned int) geometry_info.width;
  window_info.height=(unsigned int) geometry_info.height;
  window_info.x=(int) geometry_info.x;
  window_info.y=(int) geometry_info.y;
  status=XMakeImage(display,&resources,&window_info,image,window_info.width,
    window_info.height,exception);
  if (status == MagickFalse)
    ThrowXWindowFatalException(XServerFatalError,"UnableToCreateXImage",
      image->filename);
  window_info.x=0;
  window_info.y=0;
  if (image->debug != MagickFalse)
    {
      (void) LogMagickEvent(X11Event,GetMagickModule(),
        "Image: %s[%.20g] %.20gx%.20g ",image->filename,(double) image->scene,
        (double) image->columns,(double) image->rows);
      if (image->colors != 0)
        (void) LogMagickEvent(X11Event,GetMagickModule(),"%.20gc ",(double)
          image->colors);
      (void) LogMagickEvent(X11Event,GetMagickModule(),"%s",image->magick);
    }
  /*
    Adjust image dimensions as specified by backdrop or geometry options.
  */
  width=(int) window_info.width;
  height=(int) window_info.height;
  if (resources.backdrop != MagickFalse)
    {
      /*
        Center image on window.
      */
      window_info.x=(window_attributes.width/2)-(window_info.ximage->width/2);
      window_info.y=(window_attributes.height/2)-(window_info.ximage->height/2);
      width=window_attributes.width;
      height=window_attributes.height;
    }
  if ((resources.image_geometry != (char *) NULL) &&
      (*resources.image_geometry != '\0'))
    {
      char
        default_geometry[MagickPathExtent];

      int
        flags,
        gravity;

      XSizeHints
        *size_hints;

      /*
        User specified geometry.
      */
      size_hints=XAllocSizeHints();
      if (size_hints == (XSizeHints *) NULL)
        ThrowXWindowFatalException(ResourceLimitFatalError,
          "MemoryAllocationFailed",image->filename);
      size_hints->flags=0L;
      (void) FormatLocaleString(default_geometry,MagickPathExtent,"%dx%d",
        width,height);
      flags=XWMGeometry(display,visual_info->screen,resources.image_geometry,
        default_geometry,window_info.border_width,size_hints,&window_info.x,
        &window_info.y,&width,&height,&gravity);
      if (flags & (XValue | YValue))
        {
          width=window_attributes.width;
          height=window_attributes.height;
        }
      (void) XFree((void *) size_hints);
    }
  /*
    Create the X pixmap.
  */
  window_info.pixmap=XCreatePixmap(display,window_info.id,(unsigned int) width,
    (unsigned int) height,window_info.depth);
  if (window_info.pixmap == (Pixmap) NULL)
    ThrowXWindowFatalException(XServerFatalError,"UnableToCreateXPixmap",
      image->filename);
  /*
    Display pixmap on the window.
  */
  if (((unsigned int) width > window_info.width) ||
      ((unsigned int) height > window_info.height))
    (void) XFillRectangle(display,window_info.pixmap,
      window_info.annotate_context,0,0,(unsigned int) width,
      (unsigned int) height);
  (void) XPutImage(display,window_info.pixmap,window_info.annotate_context,
    window_info.ximage,0,0,window_info.x,window_info.y,(unsigned int)
    window_info.width,(unsigned int) window_info.height);
  (void) XSetWindowBackgroundPixmap(display,window_info.id,window_info.pixmap);
  (void) XClearWindow(display,window_info.id);
  delay=1000*image->delay/MagickMax(image->ticks_per_second,1L);
  XDelay(display,delay == 0UL ? 10UL : delay);
  (void) XSync(display,MagickFalse);
  return(window_info.id == root_window ? MagickTrue : MagickFalse);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   X D i s p l a y I m a g e                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  XDisplayImage() displays an image via X11.  A new image is created and
%  returned if the user interactively transforms the displayed image.
%
%  The format of the XDisplayImage method is:
%
%      Image *XDisplayImage(Display *display,XResourceInfo *resource_info,
%        char **argv,int argc,Image **image,size_t *state,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o nexus:  Method XDisplayImage returns an image when the
%      user chooses 'Open Image' from the command menu or picks a tile
%      from the image directory.  Otherwise a null image is returned.
%
%    o display: Specifies a connection to an X server;  returned from
%      XOpenDisplay.
%
%    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
%
%    o argv: Specifies the application's argument list.
%
%    o argc: Specifies the number of arguments.
%
%    o image: Specifies an address to an address of an Image structure;
%
%    o exception: return any errors or warnings in this structure.
%
*/
MagickExport Image *XDisplayImage(Display *display,XResourceInfo *resource_info,
  char **argv,int argc,Image **image,size_t *state,ExceptionInfo *exception)
{
#define MagnifySize  256  /* must be a power of 2 */
#define MagickMenus  10
#define MagickTitle  "Commands"

  const char
    *const CommandMenu[] =
    {
      "File",
      "Edit",
      "View",
      "Transform",
      "Enhance",
      "Effects",
      "F/X",
      "Image Edit",
      "Miscellany",
      "Help",
      (char *) NULL
    },
    *const FileMenu[] =
    {
      "Open...",
      "Next",
      "Former",
      "Select...",
      "Save...",
      "Print...",
      "Delete...",
      "New...",
      "Visual Directory...",
      "Quit",
      (char *) NULL
    },
    *const EditMenu[] =
    {
      "Undo",
      "Redo",
      "Cut",
      "Copy",
      "Paste",
      (char *) NULL
    },
    *const ViewMenu[] =
    {
      "Half Size",
      "Original Size",
      "Double Size",
      "Resize...",
      "Apply",
      "Refresh",
      "Restore",
      (char *) NULL
    },
    *const TransformMenu[] =
    {
      "Crop",
      "Chop",
      "Flop",
      "Flip",
      "Rotate Right",
      "Rotate Left",
      "Rotate...",
      "Shear...",
      "Roll...",
      "Trim Edges",
      (char *) NULL
    },
    *const EnhanceMenu[] =
    {
      "Hue...",
      "Saturation...",
      "Brightness...",
      "Gamma...",
      "Spiff",
      "Dull",
      "Contrast Stretch...",
      "Sigmoidal Contrast...",
      "Normalize",
      "Equalize",
      "Negate",
      "Grayscale",
      "Map...",
      "Quantize...",
      (char *) NULL
    },
    *const EffectsMenu[] =
    {
      "Despeckle",
      "Emboss",
      "Reduce Noise",
      "Add Noise...",
      "Sharpen...",
      "Blur...",
      "Threshold...",
      "Edge Detect...",
      "Spread...",
      "Shade...",
      "Raise...",
      "Segment...",
      (char *) NULL
    },
    *const FXMenu[] =
    {
      "Solarize...",
      "Sepia Tone...",
      "Swirl...",
      "Implode...",
      "Vignette...",
      "Wave...",
      "Oil Paint...",
      "Charcoal Draw...",
      (char *) NULL
    },
    *const ImageEditMenu[] =
    {
      "Annotate...",
      "Draw...",
      "Color...",
      "Matte...",
      "Composite...",
      "Add Border...",
      "Add Frame...",
      "Comment...",
      "Launch...",
      "Region of Interest...",
      (char *) NULL
    },
    *const MiscellanyMenu[] =
    {
      "Image Info",
      "Zoom Image",
      "Show Preview...",
      "Show Histogram",
      "Show Matte",
      "Background...",
      "Slide Show...",
      "Preferences...",
      (char *) NULL
    },
    *const HelpMenu[] =
    {
      "Overview",
      "Browse Documentation",
      "About Display",
      (char *) NULL
    },
    *const ShortCutsMenu[] =
    {
      "Next",
      "Former",
      "Open...",
      "Save...",
      "Print...",
      "Undo",
      "Restore",
      "Image Info",
      "Quit",
      (char *) NULL
    },
    *const VirtualMenu[] =
    {
      "Image Info",
      "Print",
      "Next",
      "Quit",
      (char *) NULL
    };

  const char
    *const *Menus[MagickMenus] =
    {
      FileMenu,
      EditMenu,
      ViewMenu,
      TransformMenu,
      EnhanceMenu,
      EffectsMenu,
      FXMenu,
      ImageEditMenu,
      MiscellanyMenu,
      HelpMenu
    };

  static CommandType
    CommandMenus[] =
    {
      NullCommand,
      NullCommand,
      NullCommand,
      NullCommand,
      NullCommand,
      NullCommand,
      NullCommand,
      NullCommand,
      NullCommand,
      NullCommand,
    },
    FileCommands[] =
    {
      OpenCommand,
      NextCommand,
      FormerCommand,
      SelectCommand,
      SaveCommand,
      PrintCommand,
      DeleteCommand,
      NewCommand,
      VisualDirectoryCommand,
      QuitCommand
    },
    EditCommands[] =
    {
      UndoCommand,
      RedoCommand,
      CutCommand,
      CopyCommand,
      PasteCommand
    },
    ViewCommands[] =
    {
      HalfSizeCommand,
      OriginalSizeCommand,
      DoubleSizeCommand,
      ResizeCommand,
      ApplyCommand,
      RefreshCommand,
      RestoreCommand
    },
    TransformCommands[] =
    {
      CropCommand,
      ChopCommand,
      FlopCommand,
      FlipCommand,
      RotateRightCommand,
      RotateLeftCommand,
      RotateCommand,
      ShearCommand,
      RollCommand,
      TrimCommand
    },
    EnhanceCommands[] =
    {
      HueCommand,
      SaturationCommand,
      BrightnessCommand,
      GammaCommand,
      SpiffCommand,
      DullCommand,
      ContrastStretchCommand,
      SigmoidalContrastCommand,
      NormalizeCommand,
      EqualizeCommand,
      NegateCommand,
      GrayscaleCommand,
      MapCommand,
      QuantizeCommand
    },
    EffectsCommands[] =
    {
      DespeckleCommand,
      EmbossCommand,
      ReduceNoiseCommand,
      AddNoiseCommand,
      SharpenCommand,
      BlurCommand,
      ThresholdCommand,
      EdgeDetectCommand,
      SpreadCommand,
      ShadeCommand,
      RaiseCommand,
      SegmentCommand
    },
    FXCommands[] =
    {
      SolarizeCommand,
      SepiaToneCommand,
      SwirlCommand,
      ImplodeCommand,
      VignetteCommand,
      WaveCommand,
      OilPaintCommand,
      CharcoalDrawCommand
    },
    ImageEditCommands[] =
    {
      AnnotateCommand,
      DrawCommand,
      ColorCommand,
      MatteCommand,
      CompositeCommand,
      AddBorderCommand,
      AddFrameCommand,
      CommentCommand,
      LaunchCommand,
      RegionofInterestCommand
    },
    MiscellanyCommands[] =
    {
      InfoCommand,
      ZoomCommand,
      ShowPreviewCommand,
      ShowHistogramCommand,
      ShowMatteCommand,
      BackgroundCommand,
      SlideShowCommand,
      PreferencesCommand
    },
    HelpCommands[] =
    {
      HelpCommand,
      BrowseDocumentationCommand,
      VersionCommand
    },
    ShortCutsCommands[] =
    {
      NextCommand,
      FormerCommand,
      OpenCommand,
      SaveCommand,
      PrintCommand,
      UndoCommand,
      RestoreCommand,
      InfoCommand,
      QuitCommand
    },
    VirtualCommands[] =
    {
      InfoCommand,
      PrintCommand,
      NextCommand,
      QuitCommand
    };

  static CommandType
    *Commands[MagickMenus] =
    {
      FileCommands,
      EditCommands,
      ViewCommands,
      TransformCommands,
      EnhanceCommands,
      EffectsCommands,
      FXCommands,
      ImageEditCommands,
      MiscellanyCommands,
      HelpCommands
    };

  char
    command[MagickPathExtent],
    *directory,
    geometry[MagickPathExtent],
    resource_name[MagickPathExtent];

  CommandType
    command_type;

  Image
    *display_image,
    *nexus;

  int
    entry,
    id;

  KeySym
    key_symbol;

  MagickStatusType
    context_mask,
    status;

  RectangleInfo
    geometry_info;

  int
    i;

  static char
    working_directory[MagickPathExtent];

  static XPoint
    vid_info;

  static XWindowInfo
    *magick_windows[MaxXWindows];

  static unsigned int
    number_windows;

  struct stat
    attributes;

  time_t
    timer,
    timestamp,
    update_time;

  unsigned int
    height,
    width;

  size_t
    delay;

  WarningHandler
    warning_handler;

  Window
    root_window;

  XClassHint
    *class_hints;

  XEvent
    event;

  XFontStruct
    *font_info;

  XGCValues
    context_values;

  XPixelInfo
    *icon_pixel,
    *pixel;

  XResourceInfo
    *icon_resources;

  XStandardColormap
    *icon_map,
    *map_info;

  XVisualInfo
    *icon_visual,
    *visual_info;

  XWindowChanges
    window_changes;

  XWindows
    *windows;

  XWMHints
    *manager_hints;

  assert(image != (Image **) NULL);
  assert((*image)->signature == MagickCoreSignature);
  if ((*image)->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename);
  display_image=(*image);
  warning_handler=(WarningHandler) NULL;
  windows=XSetWindows((XWindows *) ~0);
  if (windows != (XWindows *) NULL)
    {
      int
        status;

      if (*working_directory == '\0')
        (void) CopyMagickString(working_directory,".",MagickPathExtent);
      status=chdir(working_directory);
      if (status == -1)
        (void) ThrowMagickException(exception,GetMagickModule(),FileOpenError,
          "UnableToOpenFile","%s",working_directory);
      warning_handler=resource_info->display_warnings ?
        SetErrorHandler(XWarning) : SetErrorHandler((ErrorHandler) NULL);
      warning_handler=resource_info->display_warnings ?
        SetWarningHandler(XWarning) : SetWarningHandler((WarningHandler) NULL);
    }
  else
    {
      /*
        Allocate windows structure.
      */
      resource_info->colors=display_image->colors;
      windows=XSetWindows(XInitializeWindows(display,resource_info));
      if (windows == (XWindows *) NULL)
        ThrowXWindowFatalException(XServerFatalError,"UnableToCreateWindow",
          (*image)->filename);
      /*
        Initialize window id's.
      */
      number_windows=0;
      magick_windows[number_windows++]=(&windows->icon);
      magick_windows[number_windows++]=(&windows->backdrop);
      magick_windows[number_windows++]=(&windows->image);
      magick_windows[number_windows++]=(&windows->info);
      magick_windows[number_windows++]=(&windows->command);
      magick_windows[number_windows++]=(&windows->widget);
      magick_windows[number_windows++]=(&windows->popup);
      magick_windows[number_windows++]=(&windows->magnify);
      magick_windows[number_windows++]=(&windows->pan);
      for (i=0; i < (int) number_windows; i++)
        magick_windows[i]->id=(Window) NULL;
      vid_info.x=0;
      vid_info.y=0;
    }
  /*
    Initialize font info.
  */
  if (windows->font_info != (XFontStruct *) NULL)
    (void) XFreeFont(display,windows->font_info);
  windows->font_info=XBestFont(display,resource_info,MagickFalse);
  if (windows->font_info == (XFontStruct *) NULL)
    ThrowXWindowFatalException(XServerFatalError,"UnableToLoadFont",
      resource_info->font);
  /*
    Initialize Standard Colormap.
  */
  map_info=windows->map_info;
  icon_map=windows->icon_map;
  visual_info=windows->visual_info;
  icon_visual=windows->icon_visual;
  pixel=windows->pixel_info;
  icon_pixel=windows->icon_pixel;
  font_info=windows->font_info;
  icon_resources=windows->icon_resources;
  class_hints=windows->class_hints;
  manager_hints=windows->manager_hints;
  root_window=XRootWindow(display,visual_info->screen);
  nexus=NewImageList();
  if (display_image->debug != MagickFalse)
    {
      (void) LogMagickEvent(X11Event,GetMagickModule(),
        "Image: %s[%.20g] %.20gx%.20g ",display_image->filename,
        (double) display_image->scene,(double) display_image->columns,
        (double) display_image->rows);
      if (display_image->colors != 0)
        (void) LogMagickEvent(X11Event,GetMagickModule(),"%.20gc ",(double)
          display_image->colors);
      (void) LogMagickEvent(X11Event,GetMagickModule(),"%s",
        display_image->magick);
    }
  XMakeStandardColormap(display,visual_info,resource_info,display_image,
    map_info,pixel,exception);
  display_image->taint=MagickFalse;
  /*
    Initialize graphic context.
  */
  windows->context.id=(Window) NULL;
  XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
    resource_info,&windows->context);
  (void) CloneString(&class_hints->res_name,resource_info->client_name);
  (void) CloneString(&class_hints->res_class,resource_info->client_name);
  class_hints->res_class[0]=(char) LocaleUppercase((int)
    class_hints->res_class[0]);
  manager_hints->flags=InputHint | StateHint;
  manager_hints->input=MagickFalse;
  manager_hints->initial_state=WithdrawnState;
  XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
    &windows->context);
  if (display_image->debug != MagickFalse)
    (void) LogMagickEvent(X11Event,GetMagickModule(),
      "Window id: 0x%lx (context)",windows->context.id);
  context_values.background=pixel->background_color.pixel;
  context_values.font=font_info->fid;
  context_values.foreground=pixel->foreground_color.pixel;
  context_values.graphics_exposures=MagickFalse;
  context_mask=(MagickStatusType)
    (GCBackground | GCFont | GCForeground | GCGraphicsExposures);
  if (pixel->annotate_context != (GC) NULL)
    (void) XFreeGC(display,pixel->annotate_context);
  pixel->annotate_context=XCreateGC(display,windows->context.id,
    context_mask,&context_values);
  if (pixel->annotate_context == (GC) NULL)
    ThrowXWindowFatalException(XServerFatalError,"UnableToCreateGraphicContext",
      display_image->filename);
  context_values.background=pixel->depth_color.pixel;
  if (pixel->widget_context != (GC) NULL)
    (void) XFreeGC(display,pixel->widget_context);
  pixel->widget_context=XCreateGC(display,windows->context.id,context_mask,
    &context_values);
  if (pixel->widget_context == (GC) NULL)
    ThrowXWindowFatalException(XServerFatalError,"UnableToCreateGraphicContext",
      display_image->filename);
  context_values.background=pixel->foreground_color.pixel;
  context_values.foreground=pixel->background_color.pixel;
  context_values.plane_mask=context_values.background ^
    context_values.foreground;
  if (pixel->highlight_context != (GC) NULL)
    (void) XFreeGC(display,pixel->highlight_context);
  pixel->highlight_context=XCreateGC(display,windows->context.id,
    (size_t) (context_mask | GCPlaneMask),&context_values);
  if (pixel->highlight_context == (GC) NULL)
    ThrowXWindowFatalException(XServerFatalError,"UnableToCreateGraphicContext",
      display_image->filename);
  (void) XDestroyWindow(display,windows->context.id);
  /*
    Initialize icon window.
  */
  XGetWindowInfo(display,icon_visual,icon_map,icon_pixel,(XFontStruct *) NULL,
    icon_resources,&windows->icon);
  windows->icon.geometry=resource_info->icon_geometry;
  XBestIconSize(display,&windows->icon,display_image);
  windows->icon.attributes.colormap=XDefaultColormap(display,
    icon_visual->screen);
  windows->icon.attributes.event_mask=ExposureMask | StructureNotifyMask;
  manager_hints->flags=InputHint | StateHint;
  manager_hints->input=MagickFalse;
  manager_hints->initial_state=IconicState;
  XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
    &windows->icon);
  if (display_image->debug != MagickFalse)
    (void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (icon)",
      windows->icon.id);
  /*
    Initialize graphic context for icon window.
  */
  if (icon_pixel->annotate_context != (GC) NULL)
    (void) XFreeGC(display,icon_pixel->annotate_context);
  context_values.background=icon_pixel->background_color.pixel;
  context_values.foreground=icon_pixel->foreground_color.pixel;
  icon_pixel->annotate_context=XCreateGC(display,windows->icon.id,
    (size_t) (GCBackground | GCForeground),&context_values);
  if (icon_pixel->annotate_context == (GC) NULL)
    ThrowXWindowFatalException(XServerFatalError,"UnableToCreateGraphicContext",
      display_image->filename);
  windows->icon.annotate_context=icon_pixel->annotate_context;
  /*
    Initialize Image window.
  */
  XGetWindowInfo(display,visual_info,map_info,pixel,font_info,resource_info,
    &windows->image);
  windows->image.shape=MagickTrue;  /* non-rectangular shape hint */
  if (resource_info->use_shared_memory == MagickFalse)
    windows->image.shared_memory=MagickFalse;
  if ((resource_info->title != (char *) NULL) && !(*state & MontageImageState))
    {
      char
        *title;

      title=InterpretImageProperties(resource_info->image_info,display_image,
        resource_info->title,exception);
      (void) CloneString(&windows->image.name,title);
      (void) CloneString(&windows->image.icon_name,title);
      title=DestroyString(title);
    }
  else
    {
      char
        filename[MagickPathExtent],
        window_name[MagickPathExtent];

      /*
        Window name is the base of the filename.
      */
      GetPathComponent(display_image->magick_filename,TailPath,filename);
      if (display_image->scene == 0)
        (void) FormatLocaleString(window_name,MagickPathExtent,"%s: %s",
          MagickPackageName,filename);
      else
        (void) FormatLocaleString(window_name,MagickPathExtent,
          "%s: %s[scene: %.20g frames: %.20g]",MagickPackageName,filename,
          (double) display_image->scene,(double) GetImageListLength(
          display_image));
      (void) CloneString(&windows->image.name,window_name);
      (void) CloneString(&windows->image.icon_name,filename);
    }
  if (resource_info->immutable)
    windows->image.immutable=MagickTrue;
  windows->image.use_pixmap=resource_info->use_pixmap;
  windows->image.geometry=resource_info->image_geometry;
  (void) FormatLocaleString(geometry,MagickPathExtent,"%ux%u+0+0>!",
    XDisplayWidth(display,visual_info->screen),
    XDisplayHeight(display,visual_info->screen));
  geometry_info.width=display_image->columns;
  geometry_info.height=display_image->rows;
  geometry_info.x=0;
  geometry_info.y=0;
  (void) ParseMetaGeometry(geometry,&geometry_info.x,&geometry_info.y,
    &geometry_info.width,&geometry_info.height);
  windows->image.width=(unsigned int) geometry_info.width;
  windows->image.height=(unsigned int) geometry_info.height;
  windows->image.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
    ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
    KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask |
    PropertyChangeMask | StructureNotifyMask | SubstructureNotifyMask;
  XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
    resource_info,&windows->backdrop);
  if ((resource_info->backdrop) || (windows->backdrop.id != (Window) NULL))
    {
      /*
        Initialize backdrop window.
      */
      windows->backdrop.x=0;
      windows->backdrop.y=0;
      (void) CloneString(&windows->backdrop.name,"Backdrop");
      windows->backdrop.flags=(size_t) (USSize | USPosition);
      windows->backdrop.width=(unsigned int)
        XDisplayWidth(display,visual_info->screen);
      windows->backdrop.height=(unsigned int)
        XDisplayHeight(display,visual_info->screen);
      windows->backdrop.border_width=0;
      windows->backdrop.immutable=MagickTrue;
      windows->backdrop.attributes.do_not_propagate_mask=ButtonPressMask |
        ButtonReleaseMask;
      windows->backdrop.attributes.event_mask=ButtonPressMask | KeyPressMask |
        StructureNotifyMask;
      manager_hints->flags=IconWindowHint | InputHint | StateHint;
      manager_hints->icon_window=windows->icon.id;
      manager_hints->input=MagickTrue;
      manager_hints->initial_state=resource_info->iconic ? IconicState :
        NormalState;
      XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
        &windows->backdrop);
      if (display_image->debug != MagickFalse)
        (void) LogMagickEvent(X11Event,GetMagickModule(),
          "Window id: 0x%lx (backdrop)",windows->backdrop.id);
      (void) XMapWindow(display,windows->backdrop.id);
      (void) XClearWindow(display,windows->backdrop.id);
      if (windows->image.id != (Window) NULL)
        {
          (void) XDestroyWindow(display,windows->image.id);
          windows->image.id=(Window) NULL;
        }
      /*
        Position image in the center the backdrop.
      */
      windows->image.flags|=USPosition;
      windows->image.x=(XDisplayWidth(display,visual_info->screen)/2)-
        (windows->image.width/2);
      windows->image.y=(XDisplayHeight(display,visual_info->screen)/2)-
        (windows->image.height/2);
    }
  manager_hints->flags=IconWindowHint | InputHint | StateHint;
  manager_hints->icon_window=windows->icon.id;
  manager_hints->input=MagickTrue;
  manager_hints->initial_state=resource_info->iconic ? IconicState :
    NormalState;
  if (windows->group_leader.id != (Window) NULL)
    {
      /*
        Follow the leader.
      */
      manager_hints->flags|=WindowGroupHint;
      manager_hints->window_group=windows->group_leader.id;
      (void) XSelectInput(display,windows->group_leader.id,StructureNotifyMask);
      if (display_image->debug != MagickFalse)
        (void) LogMagickEvent(X11Event,GetMagickModule(),
          "Window id: 0x%lx (group leader)",windows->group_leader.id);
    }
  XMakeWindow(display,
    (Window) (resource_info->backdrop ? windows->backdrop.id : root_window),
    argv,argc,class_hints,manager_hints,&windows->image);
  (void) XChangeProperty(display,windows->image.id,windows->im_protocols,
    XA_STRING,8,PropModeReplace,(unsigned char *) NULL,0);
  if (windows->group_leader.id != (Window) NULL)
    (void) XSetTransientForHint(display,windows->image.id,
      windows->group_leader.id);
  if (display_image->debug != MagickFalse)
    (void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (image)",
      windows->image.id);
  /*
    Initialize Info widget.
  */
  XGetWindowInfo(display,visual_info,map_info,pixel,font_info,resource_info,
    &windows->info);
  (void) CloneString(&windows->info.name,"Info");
  (void) CloneString(&windows->info.icon_name,"Info");
  windows->info.border_width=1;
  windows->info.x=2;
  windows->info.y=2;
  windows->info.flags|=PPosition;
  windows->info.attributes.win_gravity=UnmapGravity;
  windows->info.attributes.event_mask=ButtonPressMask | ExposureMask |
    StructureNotifyMask;
  manager_hints->flags=InputHint | StateHint | WindowGroupHint;
  manager_hints->input=MagickFalse;
  manager_hints->initial_state=NormalState;
  manager_hints->window_group=windows->image.id;
  XMakeWindow(display,windows->image.id,argv,argc,class_hints,manager_hints,
    &windows->info);
  windows->info.highlight_stipple=XCreateBitmapFromData(display,
    windows->info.id,(char *) HighlightBitmap,HighlightWidth,HighlightHeight);
  windows->info.shadow_stipple=XCreateBitmapFromData(display,
    windows->info.id,(char *) ShadowBitmap,ShadowWidth,ShadowHeight);
  (void) XSetTransientForHint(display,windows->info.id,windows->image.id);
  if (windows->image.mapped != MagickFalse)
    (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
  if (display_image->debug != MagickFalse)
    (void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (info)",
      windows->info.id);
  /*
    Initialize Command widget.
  */
  XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
    resource_info,&windows->command);
  windows->command.data=MagickMenus;
  (void) XCommandWidget(display,windows,CommandMenu,(XEvent *) NULL);
  (void) FormatLocaleString(resource_name,MagickPathExtent,"%s.command",
    resource_info->client_name);
  windows->command.geometry=XGetResourceClass(resource_info->resource_database,
    resource_name,"geometry",(char *) NULL);
  (void) CloneString(&windows->command.name,MagickTitle);
  windows->command.border_width=0;
  windows->command.flags|=PPosition;
  windows->command.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
    ButtonReleaseMask | EnterWindowMask | ExposureMask | LeaveWindowMask |
    OwnerGrabButtonMask | StructureNotifyMask;
  manager_hints->flags=InputHint | StateHint | WindowGroupHint;
  manager_hints->input=MagickTrue;
  manager_hints->initial_state=NormalState;
  manager_hints->window_group=windows->image.id;
  XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
    &windows->command);
  windows->command.highlight_stipple=XCreateBitmapFromData(display,
    windows->command.id,(char *) HighlightBitmap,HighlightWidth,
    HighlightHeight);
  windows->command.shadow_stipple=XCreateBitmapFromData(display,
    windows->command.id,(char *) ShadowBitmap,ShadowWidth,ShadowHeight);
  (void) XSetTransientForHint(display,windows->command.id,windows->image.id);
  if (windows->command.mapped != MagickFalse)
    (void) XMapRaised(display,windows->command.id);
  if (display_image->debug != MagickFalse)
    (void) LogMagickEvent(X11Event,GetMagickModule(),
      "Window id: 0x%lx (command)",windows->command.id);
  /*
    Initialize Widget window.
  */
  XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
    resource_info,&windows->widget);
  (void) FormatLocaleString(resource_name,MagickPathExtent,"%s.widget",
    resource_info->client_name);
  windows->widget.geometry=XGetResourceClass(resource_info->resource_database,
    resource_name,"geometry",(char *) NULL);
  windows->widget.border_width=0;
  windows->widget.flags|=PPosition;
  windows->widget.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
    ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
    KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask |
    StructureNotifyMask;
  manager_hints->flags=InputHint | StateHint | WindowGroupHint;
  manager_hints->input=MagickTrue;
  manager_hints->initial_state=NormalState;
  manager_hints->window_group=windows->image.id;
  XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
    &windows->widget);
  windows->widget.highlight_stipple=XCreateBitmapFromData(display,
    windows->widget.id,(char *) HighlightBitmap,HighlightWidth,HighlightHeight);
  windows->widget.shadow_stipple=XCreateBitmapFromData(display,
    windows->widget.id,(char *) ShadowBitmap,ShadowWidth,ShadowHeight);
  (void) XSetTransientForHint(display,windows->widget.id,windows->image.id);
  if (display_image->debug != MagickFalse)
    (void) LogMagickEvent(X11Event,GetMagickModule(),
      "Window id: 0x%lx (widget)",windows->widget.id);
  /*
    Initialize popup window.
  */
  XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
    resource_info,&windows->popup);
  windows->popup.border_width=0;
  windows->popup.flags|=PPosition;
  windows->popup.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
    ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
    KeyReleaseMask | LeaveWindowMask | StructureNotifyMask;
  manager_hints->flags=InputHint | StateHint | WindowGroupHint;
  manager_hints->input=MagickTrue;
  manager_hints->initial_state=NormalState;
  manager_hints->window_group=windows->image.id;
  XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
    &windows->popup);
  windows->popup.highlight_stipple=XCreateBitmapFromData(display,
    windows->popup.id,(char *) HighlightBitmap,HighlightWidth,HighlightHeight);
  windows->popup.shadow_stipple=XCreateBitmapFromData(display,
    windows->popup.id,(char *) ShadowBitmap,ShadowWidth,ShadowHeight);
  (void) XSetTransientForHint(display,windows->popup.id,windows->image.id);
  if (display_image->debug != MagickFalse)
    (void) LogMagickEvent(X11Event,GetMagickModule(),
      "Window id: 0x%lx (pop up)",windows->popup.id);
  /*
    Initialize Magnify window and cursor.
  */
  XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
    resource_info,&windows->magnify);
  if (resource_info->use_shared_memory == MagickFalse)
    windows->magnify.shared_memory=MagickFalse;
  (void) FormatLocaleString(resource_name,MagickPathExtent,"%s.magnify",
    resource_info->client_name);
  windows->magnify.geometry=XGetResourceClass(resource_info->resource_database,
    resource_name,"geometry",(char *) NULL);
  (void) FormatLocaleString(windows->magnify.name,MagickPathExtent,
    "Magnify %uX",resource_info->magnify);
  if (windows->magnify.cursor != (Cursor) NULL)
    (void) XFreeCursor(display,windows->magnify.cursor);
  windows->magnify.cursor=XMakeCursor(display,windows->image.id,
    map_info->colormap,resource_info->background_color,
    resource_info->foreground_color);
  if (windows->magnify.cursor == (Cursor) NULL)
    ThrowXWindowFatalException(XServerFatalError,"UnableToCreateCursor",
      display_image->filename);
  windows->magnify.width=MagnifySize;
  windows->magnify.height=MagnifySize;
  windows->magnify.flags|=PPosition;
  windows->magnify.min_width=MagnifySize;
  windows->magnify.min_height=MagnifySize;
  windows->magnify.width_inc=MagnifySize;
  windows->magnify.height_inc=MagnifySize;
  windows->magnify.data=resource_info->magnify;
  windows->magnify.attributes.cursor=windows->magnify.cursor;
  windows->magnify.attributes.event_mask=ButtonPressMask | ButtonReleaseMask |
    ExposureMask | KeyPressMask | KeyReleaseMask | OwnerGrabButtonMask |
    StructureNotifyMask;
  manager_hints->flags=InputHint | StateHint | WindowGroupHint;
  manager_hints->input=MagickTrue;
  manager_hints->initial_state=NormalState;
  manager_hints->window_group=windows->image.id;
  XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
    &windows->magnify);
  if (display_image->debug != MagickFalse)
    (void) LogMagickEvent(X11Event,GetMagickModule(),
      "Window id: 0x%lx (magnify)",windows->magnify.id);
  (void) XSetTransientForHint(display,windows->magnify.id,windows->image.id);
  /*
    Initialize panning window.
  */
  XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
    resource_info,&windows->pan);
  (void) CloneString(&windows->pan.name,"Pan Icon");
  windows->pan.width=windows->icon.width;
  windows->pan.height=windows->icon.height;
  (void) FormatLocaleString(resource_name,MagickPathExtent,"%s.pan",
    resource_info->client_name);
  windows->pan.geometry=XGetResourceClass(resource_info->resource_database,
    resource_name,"geometry",(char *) NULL);
  (void) XParseGeometry(windows->pan.geometry,&windows->pan.x,&windows->pan.y,
    &windows->pan.width,&windows->pan.height);
  windows->pan.flags|=PPosition;
  windows->pan.immutable=MagickTrue;
  windows->pan.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
    ButtonReleaseMask | ExposureMask | KeyPressMask | KeyReleaseMask |
    StructureNotifyMask;
  manager_hints->flags=InputHint | StateHint | WindowGroupHint;
  manager_hints->input=MagickFalse;
  manager_hints->initial_state=NormalState;
  manager_hints->window_group=windows->image.id;
  XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
    &windows->pan);
  if (display_image->debug != MagickFalse)
    (void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (pan)",
      windows->pan.id);
  (void) XSetTransientForHint(display,windows->pan.id,windows->image.id);
  if (windows->info.mapped != MagickFalse)
    (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
  if ((windows->image.mapped == MagickFalse) ||
      (windows->backdrop.id != (Window) NULL))
    (void) XMapWindow(display,windows->image.id);
  /*
    Set our progress monitor and warning handlers.
  */
  if (warning_handler == (WarningHandler) NULL)
    {
      warning_handler=resource_info->display_warnings ?
        SetErrorHandler(XWarning) : SetErrorHandler((ErrorHandler) NULL);
      warning_handler=resource_info->display_warnings ?
        SetWarningHandler(XWarning) : SetWarningHandler((WarningHandler) NULL);
    }
  /*
    Initialize Image and Magnify X images.
  */
  windows->image.x=0;
  windows->image.y=0;
  windows->magnify.shape=MagickFalse;
  width=(unsigned int) display_image->columns;
  height=(unsigned int) display_image->rows;
  if ((display_image->columns != width) || (display_image->rows != height))
    ThrowXWindowFatalException(XServerFatalError,"UnableToCreateXImage",
      display_image->filename);
  status=XMakeImage(display,resource_info,&windows->image,display_image,
    width,height,exception);
  if (status == MagickFalse)
    ThrowXWindowFatalException(XServerFatalError,"UnableToCreateXImage",
      display_image->filename);
  status=XMakeImage(display,resource_info,&windows->magnify,(Image *) NULL,
    windows->magnify.width,windows->magnify.height,exception);
  if (status == MagickFalse)
    ThrowXWindowFatalException(XServerFatalError,"UnableToCreateXImage",
      display_image->filename);
  if (windows->magnify.mapped != MagickFalse)
    (void) XMapRaised(display,windows->magnify.id);
  if (windows->pan.mapped != MagickFalse)
    (void) XMapRaised(display,windows->pan.id);
  windows->image.window_changes.width=(int) display_image->columns;
  windows->image.window_changes.height=(int) display_image->rows;
  (void) XConfigureImage(display,resource_info,windows,display_image,exception);
  (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
  (void) XSync(display,MagickFalse);
  /*
    Respond to events.
  */
  delay=display_image->delay/MagickMax(display_image->ticks_per_second,1L);
  timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1;
  update_time=0;
  if (resource_info->update != MagickFalse)
    {
      MagickBooleanType
        status;

      /*
        Determine when file data was last modified.
      */
      status=GetPathAttributes(display_image->filename,&attributes);
      if (status != MagickFalse)
        update_time=attributes.st_mtime;
    }
  *state&=(~FormerImageState);
  *state&=(~MontageImageState);
  *state&=(~NextImageState);
  do
  {
    /*
      Handle a window event.
    */
    if (windows->image.mapped != MagickFalse)
      if ((display_image->delay != 0) || (resource_info->update != 0))
        {
          if (timer < GetMagickTime())
            {
              if (resource_info->update == MagickFalse)
                *state|=NextImageState | ExitState;
              else
                {
                  MagickBooleanType
                    status;

                  /*
                    Determine if image file was modified.
                  */
                  status=GetPathAttributes(display_image->filename,&attributes);
                  if (status != MagickFalse)
                    if (update_time != attributes.st_mtime)
                      {
                        /*
                          Redisplay image.
                        */
                        (void) FormatLocaleString(
                          resource_info->image_info->filename,MagickPathExtent,
                          "%s:%s",display_image->magick,
                          display_image->filename);
                        nexus=ReadImage(resource_info->image_info,exception);
                        if (nexus != (Image *) NULL)
                          *state|=NextImageState | ExitState;
                      }
                  delay=display_image->delay/MagickMax(
                    display_image->ticks_per_second,1L);
                  timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1;
                }
            }
          if (XEventsQueued(display,QueuedAfterFlush) == 0)
            {
              /*
                Do not block if delay > 0.
              */
              XDelay(display,SuspendTime << 2);
              continue;
            }
        }
    timestamp=GetMagickTime();
    (void) XNextEvent(display,&event);
    if ((windows->image.stasis == MagickFalse) ||
        (windows->magnify.stasis == MagickFalse))
      {
        if ((GetMagickTime()-timestamp) > 0)
          {
            windows->image.stasis=MagickTrue;
            windows->magnify.stasis=MagickTrue;
          }
      }
    if (event.xany.window == windows->command.id)
      {
        /*
          Select a command from the Command widget.
        */
        id=XCommandWidget(display,windows,CommandMenu,&event);
        if (id < 0)
          continue;
        (void) CopyMagickString(command,CommandMenu[id],MagickPathExtent);
        command_type=CommandMenus[id];
        if (id < MagickMenus)
          {
            /*
              Select a command from a pop-up menu.
            */
            entry=XMenuWidget(display,windows,CommandMenu[id],Menus[id],
              command);
            if (entry < 0)
              continue;
            (void) CopyMagickString(command,Menus[id][entry],MagickPathExtent);
            command_type=Commands[id][entry];
          }
        if (command_type != NullCommand)
          nexus=XMagickCommand(display,resource_info,windows,command_type,
            &display_image,exception);
        continue;
      }
    switch (event.type)
    {
      case ButtonPress:
      {
        if (display_image->debug != MagickFalse)
          (void) LogMagickEvent(X11Event,GetMagickModule(),
            "Button Press: 0x%lx %u +%d+%d",event.xbutton.window,
            event.xbutton.button,event.xbutton.x,event.xbutton.y);
        if ((event.xbutton.button == Button3) &&
            (event.xbutton.state & Mod1Mask))
          {
            /*
              Convert Alt-Button3 to Button2.
            */
            event.xbutton.button=Button2;
            event.xbutton.state&=(~Mod1Mask);
          }
        if (event.xbutton.window == windows->backdrop.id)
          {
            (void) XSetInputFocus(display,event.xbutton.window,RevertToParent,
              event.xbutton.time);
            break;
          }
        if (event.xbutton.window == windows->image.id)
          {
            switch (event.xbutton.button)
            {
              case Button1:
              {
                if (resource_info->immutable)
                  {
                    /*
                      Select a command from the Virtual menu.
                    */
                    entry=XMenuWidget(display,windows,"Commands",VirtualMenu,
                      command);
                    if (entry >= 0)
                      nexus=XMagickCommand(display,resource_info,windows,
                        VirtualCommands[entry],&display_image,exception);
                    break;
                  }
                /*
                  Map/unmap Command widget.
                */
                if (windows->command.mapped != MagickFalse)
                  (void) XWithdrawWindow(display,windows->command.id,
                    windows->command.screen);
                else
                  {
                    (void) XCommandWidget(display,windows,CommandMenu,
                      (XEvent *) NULL);
                    (void) XMapRaised(display,windows->command.id);
                  }
                break;
              }
              case Button2:
              {
                /*
                  User pressed the image magnify button.
                */
                (void) XMagickCommand(display,resource_info,windows,ZoomCommand,
                  &display_image,exception);
                XMagnifyImage(display,windows,&event,exception);
                break;
              }
              case Button3:
              {
                if (resource_info->immutable)
                  {
                    /*
                      Select a command from the Virtual menu.
                    */
                    entry=XMenuWidget(display,windows,"Commands",VirtualMenu,
                      command);
                    if (entry >= 0)
                      nexus=XMagickCommand(display,resource_info,windows,
                        VirtualCommands[entry],&display_image,exception);
                    break;
                  }
                if (display_image->montage != (char *) NULL)
                  {
                    /*
                      Open or delete a tile from a visual image directory.
                    */
                    nexus=XTileImage(display,resource_info,windows,
                      display_image,&event,exception);
                    if (nexus != (Image *) NULL)
                      *state|=MontageImageState | NextImageState | ExitState;
                    vid_info.x=(short int) windows->image.x;
                    vid_info.y=(short int) windows->image.y;
                    break;
                  }
                /*
                  Select a command from the Short Cuts menu.
                */
                entry=XMenuWidget(display,windows,"Short Cuts",ShortCutsMenu,
                  command);
                if (entry >= 0)
                  nexus=XMagickCommand(display,resource_info,windows,
                    ShortCutsCommands[entry],&display_image,exception);
                break;
              }
              case Button4:
              {
                /*
                  Wheel up.
                */
                XTranslateImage(display,windows,*image,XK_Up);
                break;
              }
              case Button5:
              {
                /*
                  Wheel down.
                */
                XTranslateImage(display,windows,*image,XK_Down);
                break;
              }
              default:
                break;
            }
            break;
          }
        if (event.xbutton.window == windows->magnify.id)
          {
            const char
              *const MagnifyMenu[] =
              {
                "2",
                "4",
                "5",
                "6",
                "7",
                "8",
                "9",
                "3",
                (char *) NULL,
              };

            int
              factor;

            static KeySym
              MagnifyCommands[] =
              {
                XK_2,
                XK_4,
                XK_5,
                XK_6,
                XK_7,
                XK_8,
                XK_9,
                XK_3
              };

            /*
              Select a magnify factor from the pop-up menu.
            */
            factor=XMenuWidget(display,windows,"Magnify",MagnifyMenu,command);
            if (factor >= 0)
              XMagnifyWindowCommand(display,windows,0,MagnifyCommands[factor],
                exception);
            break;
          }
        if (event.xbutton.window == windows->pan.id)
          {
            switch (event.xbutton.button)
            {
              case Button4:
              {
                /*
                  Wheel up.
                */
                XTranslateImage(display,windows,*image,XK_Up);
                break;
              }
              case Button5:
              {
                /*
                  Wheel down.
                */
                XTranslateImage(display,windows,*image,XK_Down);
                break;
              }
              default:
              {
                XPanImage(display,windows,&event,exception);
                break;
              }
            }
            break;
          }
        delay=display_image->delay/MagickMax(display_image->ticks_per_second,
          1L);
        timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1;
        break;
      }
      case ButtonRelease:
      {
        if (display_image->debug != MagickFalse)
          (void) LogMagickEvent(X11Event,GetMagickModule(),
            "Button Release: 0x%lx %u +%d+%d",event.xbutton.window,
            event.xbutton.button,event.xbutton.x,event.xbutton.y);
        break;
      }
      case ClientMessage:
      {
        if (display_image->debug != MagickFalse)
          (void) LogMagickEvent(X11Event,GetMagickModule(),
            "Client Message: 0x%lx 0x%lx %d 0x%lx",event.xclient.window,
            event.xclient.message_type,event.xclient.format,(unsigned long)
            event.xclient.data.l[0]);
        if (event.xclient.message_type == windows->im_protocols)
          {
            if (*event.xclient.data.l == (long) windows->im_update_widget)
              {
                (void) CloneString(&windows->command.name,MagickTitle);
                windows->command.data=MagickMenus;
                (void) XCommandWidget(display,windows,CommandMenu,
                  (XEvent *) NULL);
                break;
              }
            if (*event.xclient.data.l == (long) windows->im_update_colormap)
              {
                /*
                  Update graphic context and window colormap.
                */
                for (i=0; i < (int) number_windows; i++)
                {
                  if (magick_windows[i]->id == windows->icon.id)
                    continue;
                  context_values.background=pixel->background_color.pixel;
                  context_values.foreground=pixel->foreground_color.pixel;
                  (void) XChangeGC(display,magick_windows[i]->annotate_context,
                    context_mask,&context_values);
                  (void) XChangeGC(display,magick_windows[i]->widget_context,
                    context_mask,&context_values);
                  context_values.background=pixel->foreground_color.pixel;
                  context_values.foreground=pixel->background_color.pixel;
                  context_values.plane_mask=context_values.background ^
                    context_values.foreground;
                  (void) XChangeGC(display,magick_windows[i]->highlight_context,
                    (size_t) (context_mask | GCPlaneMask),
                    &context_values);
                  magick_windows[i]->attributes.background_pixel=
                    pixel->background_color.pixel;
                  magick_windows[i]->attributes.border_pixel=
                    pixel->border_color.pixel;
                  magick_windows[i]->attributes.colormap=map_info->colormap;
                  (void) XChangeWindowAttributes(display,magick_windows[i]->id,
                    (unsigned long) magick_windows[i]->mask,
                    &magick_windows[i]->attributes);
                }
                if (windows->pan.mapped != MagickFalse)
                  {
                    (void) XSetWindowBackgroundPixmap(display,windows->pan.id,
                      windows->pan.pixmap);
                    (void) XClearWindow(display,windows->pan.id);
                    XDrawPanRectangle(display,windows);
                  }
                if (windows->backdrop.id != (Window) NULL)
                  (void) XInstallColormap(display,map_info->colormap);
                break;
              }
            if (*event.xclient.data.l == (long) windows->im_former_image)
              {
                *state|=FormerImageState | ExitState;
                break;
              }
            if (*event.xclient.data.l == (long) windows->im_next_image)
              {
                *state|=NextImageState | ExitState;
                break;
              }
            if (*event.xclient.data.l == (long) windows->im_retain_colors)
              {
                *state|=RetainColorsState;
                break;
              }
            if (*event.xclient.data.l == (long) windows->im_exit)
              {
                *state|=ExitState;
                break;
              }
            break;
          }
        if (event.xclient.message_type == windows->dnd_protocols)
          {
            Atom
              selection,
              type;

            int
              format,
              status;

            unsigned char
              *data;

            unsigned long
              after,
              length;

            /*
              Display image named by the Drag-and-Drop selection.
            */
            if ((*event.xclient.data.l != 2) && (*event.xclient.data.l != 128))
              break;
            selection=XInternAtom(display,"DndSelection",MagickFalse);
            status=XGetWindowProperty(display,root_window,selection,0L,(long)
              MagickPathExtent,MagickFalse,(Atom) AnyPropertyType,&type,&format,
              &length,&after,&data);
            if ((status != Success) || (length == 0))
              break;
            if (*event.xclient.data.l == 2)
              {
                /*
                  Offix DND.
                */
                (void) CopyMagickString(resource_info->image_info->filename,
                  (char *) data,MagickPathExtent);
              }
            else
              {
                /*
                  XDND.
                */
                if (strncmp((char *) data, "file:", 5) != 0)
                  {
                    (void) XFree((void *) data);
                    break;
                  }
                (void) CopyMagickString(resource_info->image_info->filename,
                  ((char *) data)+5,MagickPathExtent);
              }
            nexus=ReadImage(resource_info->image_info,exception);
            CatchException(exception);
            if (nexus != (Image *) NULL)
              *state|=NextImageState | ExitState;
            (void) XFree((void *) data);
            break;
          }
        /*
          If client window delete message, exit.
        */
        if (event.xclient.message_type != windows->wm_protocols)
          break;
        if (*event.xclient.data.l != (long) windows->wm_delete_window)
          break;
        (void) XWithdrawWindow(display,event.xclient.window,
          visual_info->screen);
        if (event.xclient.window == windows->image.id)
          {
            *state|=ExitState;
            break;
          }
        if (event.xclient.window == windows->pan.id)
          {
            /*
              Restore original image size when pan window is deleted.
            */
            windows->image.window_changes.width=windows->image.ximage->width;
            windows->image.window_changes.height=windows->image.ximage->height;
            (void) XConfigureImage(display,resource_info,windows,
              display_image,exception);
          }
        break;
      }
      case ConfigureNotify:
      {
        if (display_image->debug != MagickFalse)
          (void) LogMagickEvent(X11Event,GetMagickModule(),
            "Configure Notify: 0x%lx %dx%d+%d+%d %d",event.xconfigure.window,
            event.xconfigure.width,event.xconfigure.height,event.xconfigure.x,
            event.xconfigure.y,event.xconfigure.send_event);
        if (event.xconfigure.window == windows->image.id)
          {
            /*
              Image window has a new configuration.
            */
            if (event.xconfigure.send_event != 0)
              {
                XWindowChanges
                  window_changes;

                /*
                  Position the transient windows relative of the Image window.
                */
                if (windows->command.geometry == (char *) NULL)
                  if (windows->command.mapped == MagickFalse)
                    {
                      windows->command.x=event.xconfigure.x-
                        windows->command.width-25;
                      windows->command.y=event.xconfigure.y;
                      XConstrainWindowPosition(display,&windows->command);
                      window_changes.x=windows->command.x;
                      window_changes.y=windows->command.y;
                      (void) XReconfigureWMWindow(display,windows->command.id,
                        windows->command.screen,(unsigned int) (CWX | CWY),
                        &window_changes);
                    }
                if (windows->widget.geometry == (char *) NULL)
                  if (windows->widget.mapped == MagickFalse)
                    {
                      windows->widget.x=event.xconfigure.x+
                        event.xconfigure.width/10;
                      windows->widget.y=event.xconfigure.y+
                        event.xconfigure.height/10;
                      XConstrainWindowPosition(display,&windows->widget);
                      window_changes.x=windows->widget.x;
                      window_changes.y=windows->widget.y;
                      (void) XReconfigureWMWindow(display,windows->widget.id,
                        windows->widget.screen,(unsigned int) (CWX | CWY),
                        &window_changes);
                    }
                if (windows->magnify.geometry == (char *) NULL)
                  if (windows->magnify.mapped == MagickFalse)
                    {
                      windows->magnify.x=event.xconfigure.x+
                        event.xconfigure.width+25;
                      windows->magnify.y=event.xconfigure.y;
                      XConstrainWindowPosition(display,&windows->magnify);
                      window_changes.x=windows->magnify.x;
                      window_changes.y=windows->magnify.y;
                      (void) XReconfigureWMWindow(display,windows->magnify.id,
                        windows->magnify.screen,(unsigned int) (CWX | CWY),
                        &window_changes);
                    }
                if (windows->pan.geometry == (char *) NULL)
                  if (windows->pan.mapped == MagickFalse)
                    {
                      windows->pan.x=event.xconfigure.x+
                        event.xconfigure.width+25;
                      windows->pan.y=event.xconfigure.y+
                        windows->magnify.height+50;
                      XConstrainWindowPosition(display,&windows->pan);
                      window_changes.x=windows->pan.x;
                      window_changes.y=windows->pan.y;
                      (void) XReconfigureWMWindow(display,windows->pan.id,
                        windows->pan.screen,(unsigned int) (CWX | CWY),
                        &window_changes);
                    }
              }
            if ((event.xconfigure.width == (int) windows->image.width) &&
                (event.xconfigure.height == (int) windows->image.height))
              break;
            windows->image.width=(unsigned int) event.xconfigure.width;
            windows->image.height=(unsigned int) event.xconfigure.height;
            windows->image.x=0;
            windows->image.y=0;
            if (display_image->montage != (char *) NULL)
              {
                windows->image.x=vid_info.x;
                windows->image.y=vid_info.y;
              }
            if (windows->image.mapped != MagickFalse &&
                windows->image.stasis != MagickFalse)
              {
                /*
                  Update image window configuration.
                */
                windows->image.window_changes.width=event.xconfigure.width;
                windows->image.window_changes.height=event.xconfigure.height;
                (void) XConfigureImage(display,resource_info,windows,
                  display_image,exception);
              }
            /*
              Update pan window configuration.
            */
            if ((event.xconfigure.width < windows->image.ximage->width) ||
                (event.xconfigure.height < windows->image.ximage->height))
              {
                (void) XMapRaised(display,windows->pan.id);
                XDrawPanRectangle(display,windows);
              }
            else
              if (windows->pan.mapped != MagickFalse)
                (void) XWithdrawWindow(display,windows->pan.id,
                  windows->pan.screen);
            break;
          }
        if (event.xconfigure.window == windows->magnify.id)
          {
            unsigned int
              magnify;

            /*
              Magnify window has a new configuration.
            */
            windows->magnify.width=(unsigned int) event.xconfigure.width;
            windows->magnify.height=(unsigned int) event.xconfigure.height;
            if (windows->magnify.mapped == MagickFalse)
              break;
            magnify=1;
            while ((int) magnify <= event.xconfigure.width)
              magnify<<=1;
            while ((int) magnify <= event.xconfigure.height)
              magnify<<=1;
            magnify>>=1;
            if (((int) magnify != event.xconfigure.width) ||
                ((int) magnify != event.xconfigure.height))
              {
                window_changes.width=(int) magnify;
                window_changes.height=(int) magnify;
                (void) XReconfigureWMWindow(display,windows->magnify.id,
                  windows->magnify.screen,(unsigned int) (CWWidth | CWHeight),
                  &window_changes);
                break;
              }
            if (windows->magnify.mapped != MagickFalse &&
                windows->magnify.stasis != MagickFalse)
              {
                status=XMakeImage(display,resource_info,&windows->magnify,
                  display_image,windows->magnify.width,windows->magnify.height,
                  exception);
                XMakeMagnifyImage(display,windows,exception);
              }
            break;
          }
        if (windows->magnify.mapped != MagickFalse &&
            (event.xconfigure.window == windows->pan.id))
          {
            /*
              Pan icon window has a new configuration.
            */
            if (event.xconfigure.send_event != 0)
              {
                windows->pan.x=event.xconfigure.x;
                windows->pan.y=event.xconfigure.y;
              }
            windows->pan.width=(unsigned int) event.xconfigure.width;
            windows->pan.height=(unsigned int) event.xconfigure.height;
            break;
          }
        if (event.xconfigure.window == windows->icon.id)
          {
            /*
              Icon window has a new configuration.
            */
            windows->icon.width=(unsigned int) event.xconfigure.width;
            windows->icon.height=(unsigned int) event.xconfigure.height;
            break;
          }
        break;
      }
      case DestroyNotify:
      {
        /*
          Group leader has exited.
        */
        if (display_image->debug != MagickFalse)
          (void) LogMagickEvent(X11Event,GetMagickModule(),
            "Destroy Notify: 0x%lx",event.xdestroywindow.window);
        if (event.xdestroywindow.window == windows->group_leader.id)
          {
            *state|=ExitState;
            break;
          }
        break;
      }
      case EnterNotify:
      {
        /*
          Selectively install colormap.
        */
        if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
          if (event.xcrossing.mode != NotifyUngrab)
            XInstallColormap(display,map_info->colormap);
        break;
      }
      case Expose:
      {
        if (display_image->debug != MagickFalse)
          (void) LogMagickEvent(X11Event,GetMagickModule(),
            "Expose: 0x%lx %dx%d+%d+%d",event.xexpose.window,
            event.xexpose.width,event.xexpose.height,event.xexpose.x,
            event.xexpose.y);
        /*
          Refresh windows that are now exposed.
        */
        if ((event.xexpose.window == windows->image.id) &&
            windows->image.mapped != MagickFalse)
          {
            XRefreshWindow(display,&windows->image,&event);
            delay=display_image->delay/MagickMax(
              display_image->ticks_per_second,1L);
            timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1;
            break;
          }
        if ((event.xexpose.window == windows->magnify.id) &&
            windows->magnify.mapped != MagickFalse)
          {
            XMakeMagnifyImage(display,windows,exception);
            break;
          }
        if (event.xexpose.window == windows->pan.id)
          {
            XDrawPanRectangle(display,windows);
            break;
          }
        if (event.xexpose.window == windows->icon.id)
          {
            XRefreshWindow(display,&windows->icon,&event);
            break;
          }
        break;
      }
      case KeyPress:
      {
        int
          length;

        /*
          Respond to a user key press.
        */
        length=XLookupString((XKeyEvent *) &event.xkey,command,(int)
          sizeof(command),&key_symbol,(XComposeStatus *) NULL);
        *(command+length)='\0';
        if (display_image->debug != MagickFalse)
          (void) LogMagickEvent(X11Event,GetMagickModule(),
            "Key press: %d 0x%lx (%s)",event.xkey.state,(unsigned long)
            key_symbol,command);
        if (event.xkey.window == windows->image.id)
          {
            command_type=XImageWindowCommand(display,resource_info,windows,
              event.xkey.state,key_symbol,&display_image,exception);
            if (command_type != NullCommand)
              nexus=XMagickCommand(display,resource_info,windows,command_type,
                &display_image,exception);
          }
        if (event.xkey.window == windows->magnify.id)
          XMagnifyWindowCommand(display,windows,event.xkey.state,key_symbol,
            exception);
        if (event.xkey.window == windows->pan.id)
          {
            if ((key_symbol == XK_q) || (key_symbol == XK_Escape))
              (void) XWithdrawWindow(display,windows->pan.id,
                windows->pan.screen);
            else
              if ((key_symbol == XK_F1) || (key_symbol == XK_Help))
                XTextViewHelp(display,resource_info,windows,MagickFalse,
                  "Help Viewer - Image Pan",ImagePanHelp);
              else
                XTranslateImage(display,windows,*image,key_symbol);
          }
        delay=display_image->delay/MagickMax(
          display_image->ticks_per_second,1L);
        timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1;
        break;
      }
      case KeyRelease:
      {
        /*
          Respond to a user key release.
        */
        (void) XLookupString((XKeyEvent *) &event.xkey,command,(int)
          sizeof(command),&key_symbol,(XComposeStatus *) NULL);
        if (display_image->debug != MagickFalse)
          (void) LogMagickEvent(X11Event,GetMagickModule(),
            "Key release: 0x%lx (%c)",(unsigned long) key_symbol,*command);
        break;
      }
      case LeaveNotify:
      {
        /*
          Selectively uninstall colormap.
        */
        if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
          if (event.xcrossing.mode != NotifyUngrab)
            XUninstallColormap(display,map_info->colormap);
        break;
      }
      case MapNotify:
      {
        if (display_image->debug != MagickFalse)
          (void) LogMagickEvent(X11Event,GetMagickModule(),"Map Notify: 0x%lx",
            event.xmap.window);
        if (event.xmap.window == windows->backdrop.id)
          {
            (void) XSetInputFocus(display,event.xmap.window,RevertToParent,
              CurrentTime);
            windows->backdrop.mapped=MagickTrue;
            break;
          }
        if (event.xmap.window == windows->image.id)
          {
            if (windows->backdrop.id != (Window) NULL)
              (void) XInstallColormap(display,map_info->colormap);
            if (LocaleCompare(display_image->magick,"LOGO") == 0)
              {
                if (LocaleCompare(display_image->filename,"LOGO") == 0)
                  nexus=XOpenImage(display,resource_info,windows,MagickFalse);
              }
            if (((int) windows->image.width < windows->image.ximage->width) ||
                ((int) windows->image.height < windows->image.ximage->height))
              (void) XMapRaised(display,windows->pan.id);
            windows->image.mapped=MagickTrue;
            break;
          }
        if (event.xmap.window == windows->magnify.id)
          {
            XMakeMagnifyImage(display,windows,exception);
            windows->magnify.mapped=MagickTrue;
            (void) XWithdrawWindow(display,windows->info.id,
              windows->info.screen);
            break;
          }
        if (event.xmap.window == windows->pan.id)
          {
            XMakePanImage(display,resource_info,windows,display_image,
              exception);
            windows->pan.mapped=MagickTrue;
            break;
          }
        if (event.xmap.window == windows->info.id)
          {
            windows->info.mapped=MagickTrue;
            break;
          }
        if (event.xmap.window == windows->icon.id)
          {
            MagickBooleanType
              taint;

            /*
              Create an icon image.
            */
            taint=display_image->taint;
            XMakeStandardColormap(display,icon_visual,icon_resources,
              display_image,icon_map,icon_pixel,exception);
            (void) XMakeImage(display,icon_resources,&windows->icon,
              display_image,windows->icon.width,windows->icon.height,
              exception);
            display_image->taint=taint;
            (void) XSetWindowBackgroundPixmap(display,windows->icon.id,
              windows->icon.pixmap);
            (void) XClearWindow(display,windows->icon.id);
            (void) XWithdrawWindow(display,windows->info.id,
              windows->info.screen);
            windows->icon.mapped=MagickTrue;
            break;
          }
        if (event.xmap.window == windows->command.id)
          {
            windows->command.mapped=MagickTrue;
            break;
          }
        if (event.xmap.window == windows->popup.id)
          {
            windows->popup.mapped=MagickTrue;
            break;
          }
        if (event.xmap.window == windows->widget.id)
          {
            windows->widget.mapped=MagickTrue;
            break;
          }
        break;
      }
      case MappingNotify:
      {
        (void) XRefreshKeyboardMapping(&event.xmapping);
        break;
      }
      case NoExpose:
        break;
      case PropertyNotify:
      {
        Atom
          type;

        int
          format,
          status;

        unsigned char
          *data;

        unsigned long
          after,
          length;

        if (display_image->debug != MagickFalse)
          (void) LogMagickEvent(X11Event,GetMagickModule(),
            "Property Notify: 0x%lx 0x%lx %d",event.xproperty.window,
            event.xproperty.atom,event.xproperty.state);
        if (event.xproperty.atom != windows->im_remote_command)
          break;
        /*
          Display image named by the remote command protocol.
        */
        status=XGetWindowProperty(display,event.xproperty.window,
          event.xproperty.atom,0L,(long) MagickPathExtent,MagickFalse,(Atom)
          AnyPropertyType,&type,&format,&length,&after,&data);
        if ((status != Success) || (length == 0))
          break;
        if (LocaleCompare((char *) data,"-quit") == 0)
          {
            XClientMessage(display,windows->image.id,windows->im_protocols,
              windows->im_exit,CurrentTime);
            (void) XFree((void *) data);
            break;
          }
        (void) CopyMagickString(resource_info->image_info->filename,
          (char *) data,MagickPathExtent);
        (void) XFree((void *) data);
        nexus=ReadImage(resource_info->image_info,exception);
        CatchException(exception);
        if (nexus != (Image *) NULL)
          *state|=NextImageState | ExitState;
        break;
      }
      case ReparentNotify:
      {
        if (display_image->debug != MagickFalse)
          (void) LogMagickEvent(X11Event,GetMagickModule(),
            "Reparent Notify: 0x%lx=>0x%lx",event.xreparent.parent,
            event.xreparent.window);
        break;
      }
      case UnmapNotify:
      {
        if (display_image->debug != MagickFalse)
          (void) LogMagickEvent(X11Event,GetMagickModule(),
            "Unmap Notify: 0x%lx",event.xunmap.window);
        if (event.xunmap.window == windows->backdrop.id)
          {
            windows->backdrop.mapped=MagickFalse;
            break;
          }
        if (event.xunmap.window == windows->image.id)
          {
            windows->image.mapped=MagickFalse;
            break;
          }
        if (event.xunmap.window == windows->magnify.id)
          {
            windows->magnify.mapped=MagickFalse;
            break;
          }
        if (event.xunmap.window == windows->pan.id)
          {
            windows->pan.mapped=MagickFalse;
            break;
          }
        if (event.xunmap.window == windows->info.id)
          {
            windows->info.mapped=MagickFalse;
            break;
          }
        if (event.xunmap.window == windows->icon.id)
          {
            if (map_info->colormap == icon_map->colormap)
              XConfigureImageColormap(display,resource_info,windows,
                display_image,exception);
            (void) XFreeStandardColormap(display,icon_visual,icon_map,
              icon_pixel);
            windows->icon.mapped=MagickFalse;
            break;
          }
        if (event.xunmap.window == windows->command.id)
          {
            windows->command.mapped=MagickFalse;
            break;
          }
        if (event.xunmap.window == windows->popup.id)
          {
            if (windows->backdrop.id != (Window) NULL)
              (void) XSetInputFocus(display,windows->image.id,RevertToParent,
                CurrentTime);
            windows->popup.mapped=MagickFalse;
            break;
          }
        if (event.xunmap.window == windows->widget.id)
          {
            if (windows->backdrop.id != (Window) NULL)
              (void) XSetInputFocus(display,windows->image.id,RevertToParent,
                CurrentTime);
            windows->widget.mapped=MagickFalse;
            break;
          }
        break;
      }
      default:
      {
        if (display_image->debug != MagickFalse)
          (void) LogMagickEvent(X11Event,GetMagickModule(),"Event type: %d",
            event.type);
        break;
      }
    }
  } while (!(*state & ExitState));
  if ((*state & ExitState) == 0)
    (void) XMagickCommand(display,resource_info,windows,FreeBuffersCommand,
      &display_image,exception);
  else
    if (resource_info->confirm_edit != MagickFalse)
      {
        /*
          Query user if image has changed.
        */
        if ((resource_info->immutable == MagickFalse) &&
            display_image->taint != MagickFalse)
          {
            int
              status;

            status=XConfirmWidget(display,windows,"Your image changed.",
              "Do you want to save it");
            if (status == 0)
              *state&=(~ExitState);
            else
              if (status > 0)
                (void) XMagickCommand(display,resource_info,windows,SaveCommand,
                  &display_image,exception);
          }
      }
  if ((windows->visual_info->klass == GrayScale) ||
      (windows->visual_info->klass == PseudoColor) ||
      (windows->visual_info->klass == DirectColor))
    {
      /*
        Withdraw pan and Magnify window.
      */
      if (windows->info.mapped != MagickFalse)
        (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
      if (windows->magnify.mapped != MagickFalse)
        (void) XWithdrawWindow(display,windows->magnify.id,
          windows->magnify.screen);
      if (windows->command.mapped != MagickFalse)
        (void) XWithdrawWindow(display,windows->command.id,
          windows->command.screen);
    }
  if (windows->pan.mapped != MagickFalse)
    (void) XWithdrawWindow(display,windows->pan.id,windows->pan.screen);
  if (resource_info->backdrop == MagickFalse)
    if (windows->backdrop.mapped)
      {
        (void) XWithdrawWindow(display,windows->backdrop.id,
          windows->backdrop.screen);
        (void) XDestroyWindow(display,windows->backdrop.id);
        windows->backdrop.id=(Window) NULL;
        (void) XWithdrawWindow(display,windows->image.id,
          windows->image.screen);
        (void) XDestroyWindow(display,windows->image.id);
        windows->image.id=(Window) NULL;
      }
  XSetCursorState(display,windows,MagickTrue);
  XCheckRefreshWindows(display,windows);
  if (((*state & FormerImageState) != 0) || ((*state & NextImageState) != 0))
    *state&=(~ExitState);
  if (*state & ExitState)
    {
      /*
        Free Standard Colormap.
      */
      (void) XFreeStandardColormap(display,icon_visual,icon_map,icon_pixel);
      if (resource_info->map_type == (char *) NULL)
        (void) XFreeStandardColormap(display,visual_info,map_info,pixel);
      /*
        Free X resources.
      */
      if (resource_info->copy_image != (Image *) NULL)
        {
          resource_info->copy_image=DestroyImage(resource_info->copy_image);
          resource_info->copy_image=NewImageList();
        }
      DestroyXResources();
    }
  (void) XSync(display,MagickFalse);
  /*
    Restore our progress monitor and warning handlers.
  */
  (void) SetErrorHandler(warning_handler);
  (void) SetWarningHandler(warning_handler);
  /*
    Change to home directory.
  */
  directory=getcwd(working_directory,MagickPathExtent);
  (void) directory;
  {
    int
      status;

    if (*resource_info->home_directory == '\0')
      (void) CopyMagickString(resource_info->home_directory,".",MagickPathExtent);
    status=chdir(resource_info->home_directory);
    if (status == -1)
      (void) ThrowMagickException(exception,GetMagickModule(),FileOpenError,
        "UnableToOpenFile","%s",resource_info->home_directory);
  }
  *image=display_image;
  return(nexus);
}
#else

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   D i s p l a y I m a g e s                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  DisplayImages() displays an image sequence to any X window screen.  It
%  returns a value other than 0 if successful.  Check the exception member
%  of image to determine the reason for any failure.
%
%  The format of the DisplayImages method is:
%
%      MagickBooleanType DisplayImages(const ImageInfo *image_info,
%        Image *images,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image_info: the image info.
%
%    o image: the image.
%
%    o exception: return any errors or warnings in this structure.
%
*/
MagickExport MagickBooleanType DisplayImages(const ImageInfo *image_info,
  Image *image,ExceptionInfo *exception)
{
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickCoreSignature);
  assert(image != (Image *) NULL);
  assert(image->signature == MagickCoreSignature);
  (void) image_info;
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError,
    "DelegateLibrarySupportNotBuiltIn","'%s' (X11)",image->filename);
  return(MagickFalse);
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   R e m o t e D i s p l a y C o m m a n d                                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  RemoteDisplayCommand() encourages a remote display program to display the
%  specified image filename.
%
%  The format of the RemoteDisplayCommand method is:
%
%      MagickBooleanType RemoteDisplayCommand(const ImageInfo *image,
%        const char *window,const char *filename,ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image_info: the image info.
%
%    o window: Specifies the name or id of an X window.
%
%    o filename: the name of the image filename to display.
%
%    o exception: return any errors or warnings in this structure.
%
*/
MagickExport MagickBooleanType RemoteDisplayCommand(const ImageInfo *image_info,
  const char *window,const char *filename,ExceptionInfo *exception)
{
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickCoreSignature);
  assert(filename != (char *) NULL);
  (void) window;
  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
  (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError,
    "DelegateLibrarySupportNotBuiltIn","'%s' (X11)",image_info->filename);
  return(MagickFalse);
}
#endif
