Home | History | Annotate | Download | only in MagickCore
      1 /*
      2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      3 %                                                                             %
      4 %                                                                             %
      5 %                                                                             %
      6 %              X   X  W   W  IIIII  N   N  DDDD    OOO   W   W                %
      7 %               X X   W   W    I    NN  N  D   D  O   O  W   W                %
      8 %                X    W   W    I    N N N  D   D  O   O  W   W                %
      9 %               X X   W W W    I    N  NN  D   D  O   O  W W W                %
     10 %              X   X   W W   IIIII  N   N  DDDD    OOO    W W                 %
     11 %                                                                             %
     12 %                                                                             %
     13 %                       MagickCore X11 Utility Methods                        %
     14 %                                                                             %
     15 %                               Software Design                               %
     16 %                                    Cristy                                   %
     17 %                                  July 1992                                  %
     18 %                                                                             %
     19 %                                                                             %
     20 %  Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization      %
     21 %  dedicated to making software imaging solutions freely available.           %
     22 %                                                                             %
     23 %  You may not use this file except in compliance with the License.  You may  %
     24 %  obtain a copy of the License at                                            %
     25 %                                                                             %
     26 %    http://www.imagemagick.org/script/license.php                            %
     27 %                                                                             %
     28 %  Unless required by applicable law or agreed to in writing, software        %
     29 %  distributed under the License is distributed on an "AS IS" BASIS,          %
     30 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
     31 %  See the License for the specific language governing permissions and        %
     32 %  limitations under the License.                                             %
     33 %                                                                             %
     34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     35 %
     36 %
     37 */
     38 
     39 /*
     41   Include declarations.
     42 */
     43 #include "MagickCore/studio.h"
     44 #include "MagickCore/animate.h"
     45 #include "MagickCore/artifact.h"
     46 #include "MagickCore/blob.h"
     47 #include "MagickCore/cache.h"
     48 #include "MagickCore/client.h"
     49 #include "MagickCore/color.h"
     50 #include "MagickCore/color-private.h"
     51 #include "MagickCore/colormap.h"
     52 #include "MagickCore/composite.h"
     53 #include "MagickCore/constitute.h"
     54 #include "MagickCore/display.h"
     55 #include "MagickCore/distort.h"
     56 #include "MagickCore/exception.h"
     57 #include "MagickCore/exception-private.h"
     58 #include "MagickCore/geometry.h"
     59 #include "MagickCore/identify.h"
     60 #include "MagickCore/image.h"
     61 #include "MagickCore/image-private.h"
     62 #include "MagickCore/list.h"
     63 #include "MagickCore/locale_.h"
     64 #include "MagickCore/log.h"
     65 #include "MagickCore/magick.h"
     66 #include "MagickCore/memory_.h"
     67 #include "MagickCore/monitor.h"
     68 #include "MagickCore/nt-base-private.h"
     69 #include "MagickCore/option.h"
     70 #include "MagickCore/pixel-accessor.h"
     71 #include "MagickCore/quantize.h"
     72 #include "MagickCore/quantum.h"
     73 #include "MagickCore/quantum-private.h"
     74 #include "MagickCore/resource_.h"
     75 #include "MagickCore/resize.h"
     76 #include "MagickCore/statistic.h"
     77 #include "MagickCore/string_.h"
     78 #include "MagickCore/string-private.h"
     79 #include "MagickCore/transform.h"
     80 #include "MagickCore/transform-private.h"
     81 #include "MagickCore/token.h"
     82 #include "MagickCore/utility.h"
     83 #include "MagickCore/utility-private.h"
     84 #include "MagickCore/widget.h"
     85 #include "MagickCore/widget-private.h"
     86 #include "MagickCore/xwindow.h"
     87 #include "MagickCore/xwindow-private.h"
     88 #include "MagickCore/version.h"
     89 #if defined(__BEOS__)
     90 #include <OS.h>
     91 #endif
     92 #if defined(MAGICKCORE_X11_DELEGATE)
     93 #include <X11/Xproto.h>
     94 #include <X11/Xlocale.h>
     95 #if defined(MAGICK_HAVE_POLL)
     96 # include <sys/poll.h>
     97 #endif
     98 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
     99 #if defined(MAGICKCORE_HAVE_MACHINE_PARAM_H)
    100 # include <machine/param.h>
    101 #endif
    102 #include <sys/ipc.h>
    103 #include <sys/shm.h>
    104 #include <X11/extensions/XShm.h>
    105 #endif
    106 #if defined(MAGICKCORE_HAVE_SHAPE)
    107 #include <X11/extensions/shape.h>
    108 #endif
    109 
    110 /*
    112   X defines.
    113 */
    114 #define XBlueGamma(color) ClampToQuantum(blue_gamma == 1.0 ? (double) \
    115   (color) : ((pow(((double) QuantumScale*(color)),1.0/(double) blue_gamma)* \
    116   QuantumRange)))
    117 #define XGammaPacket(map,color)  (size_t) (map->base_pixel+ \
    118   ((ScaleQuantumToShort(XRedGamma((color)->red))*map->red_max/65535L)* \
    119     map->red_mult)+ \
    120   ((ScaleQuantumToShort(XGreenGamma((color)->green))*map->green_max/65535L)* \
    121     map->green_mult)+ \
    122   ((ScaleQuantumToShort(XBlueGamma((color)->blue))*map->blue_max/65535L)* \
    123     map->blue_mult))
    124 #define XGammaPixel(image,map,color)  (size_t) (map->base_pixel+ \
    125   ((ScaleQuantumToShort(XRedGamma(GetPixelRed(image,color)))*map->red_max/65535L)* \
    126     map->red_mult)+ \
    127   ((ScaleQuantumToShort(XGreenGamma(GetPixelGreen(image,color)))*map->green_max/65535L)* \
    128     map->green_mult)+ \
    129   ((ScaleQuantumToShort(XBlueGamma(GetPixelBlue(image,color)))*map->blue_max/65535L)* \
    130     map->blue_mult))
    131 #define XGreenGamma(color) ClampToQuantum(green_gamma == 1.0 ? (double) \
    132   (color) : ((pow(((double) QuantumScale*(color)),1.0/(double) green_gamma)* \
    133   QuantumRange)))
    134 #define XRedGamma(color) ClampToQuantum(red_gamma == 1.0 ? (double) \
    135   (color) : ((pow(((double) QuantumScale*(color)),1.0/(double) red_gamma)* \
    136   QuantumRange)))
    137 #define XStandardPixel(map,color)  (size_t) (map->base_pixel+ \
    138   (((color)->red*map->red_max/65535L)*map->red_mult)+ \
    139   (((color)->green*map->green_max/65535L)*map->green_mult)+ \
    140   (((color)->blue*map->blue_max/65535L)*map->blue_mult))
    141 
    142 #define AccentuateModulate  ScaleCharToQuantum(80)
    143 #define HighlightModulate  ScaleCharToQuantum(125)
    144 #define ShadowModulate  ScaleCharToQuantum(135)
    145 #define DepthModulate  ScaleCharToQuantum(185)
    146 #define TroughModulate  ScaleCharToQuantum(110)
    147 
    148 #define XLIB_ILLEGAL_ACCESS  1
    149 #undef ForgetGravity
    150 #undef NorthWestGravity
    151 #undef NorthGravity
    152 #undef NorthEastGravity
    153 #undef WestGravity
    154 #undef CenterGravity
    155 #undef EastGravity
    156 #undef SouthWestGravity
    157 #undef SouthGravity
    158 #undef SouthEastGravity
    159 #undef StaticGravity
    160 
    161 #undef index
    162 #if defined(hpux9)
    163 #define XFD_SET  int
    164 #else
    165 #define XFD_SET  fd_set
    166 #endif
    167 
    168 /*
    169   Enumeration declarations.
    170 */
    171 typedef enum
    172 {
    173 #undef DoRed
    174   DoRed = 0x0001,
    175 #undef DoGreen
    176   DoGreen = 0x0002,
    177 #undef DoBlue
    178   DoBlue = 0x0004,
    179   DoMatte = 0x0008
    180 } XColorFlags;
    181 
    182 /*
    183   Typedef declarations.
    184 */
    185 typedef struct _DiversityPacket
    186 {
    187   Quantum
    188     red,
    189     green,
    190     blue;
    191 
    192   unsigned short
    193     index;
    194 
    195   size_t
    196     count;
    197 } DiversityPacket;
    198 
    199 /*
    201   Constant declaractions.
    202 */
    203 static MagickBooleanType
    204   xerror_alert = MagickFalse;
    205 
    206 /*
    208   Method prototypes.
    209 */
    210 static const char
    211   *XVisualClassName(const int);
    212 
    213 static double
    214   blue_gamma = 1.0,
    215   green_gamma = 1.0,
    216   red_gamma = 1.0;
    217 
    218 static MagickBooleanType
    219   XMakePixmap(Display *,const XResourceInfo *,XWindowInfo *);
    220 
    221 static void
    222   XMakeImageLSBFirst(const XResourceInfo *,const XWindowInfo *,Image *,
    223     XImage *,XImage *,ExceptionInfo *),
    224   XMakeImageMSBFirst(const XResourceInfo *,const XWindowInfo *,Image *,
    225     XImage *,XImage *,ExceptionInfo *);
    226 
    227 static Window
    228   XSelectWindow(Display *,RectangleInfo *);
    229 
    230 /*
    232 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    233 %                                                                             %
    234 %                                                                             %
    235 %                                                                             %
    236 %   D e s t r o y X R e s o u r c e s                                         %
    237 %                                                                             %
    238 %                                                                             %
    239 %                                                                             %
    240 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    241 %
    242 %  DestroyXResources() destroys any X resources.
    243 %
    244 %  The format of the DestroyXResources method is:
    245 %
    246 %      void DestroyXResources()
    247 %
    248 %  A description of each parameter follows:
    249 %
    250 */
    251 MagickExport void DestroyXResources(void)
    252 {
    253   register int
    254     i;
    255 
    256   unsigned int
    257     number_windows;
    258 
    259   XWindowInfo
    260     *magick_windows[MaxXWindows];
    261 
    262   XWindows
    263     *windows;
    264 
    265   DestroyXWidget();
    266   windows=XSetWindows((XWindows *) ~0);
    267   if ((windows == (XWindows *) NULL) || (windows->display == (Display *) NULL))
    268     return;
    269   number_windows=0;
    270   magick_windows[number_windows++]=(&windows->context);
    271   magick_windows[number_windows++]=(&windows->group_leader);
    272   magick_windows[number_windows++]=(&windows->backdrop);
    273   magick_windows[number_windows++]=(&windows->icon);
    274   magick_windows[number_windows++]=(&windows->image);
    275   magick_windows[number_windows++]=(&windows->info);
    276   magick_windows[number_windows++]=(&windows->magnify);
    277   magick_windows[number_windows++]=(&windows->pan);
    278   magick_windows[number_windows++]=(&windows->command);
    279   magick_windows[number_windows++]=(&windows->widget);
    280   magick_windows[number_windows++]=(&windows->popup);
    281   magick_windows[number_windows++]=(&windows->context);
    282   for (i=0; i < (int) number_windows; i++)
    283   {
    284     if (magick_windows[i]->mapped != MagickFalse)
    285       {
    286         (void) XWithdrawWindow(windows->display,magick_windows[i]->id,
    287           magick_windows[i]->screen);
    288         magick_windows[i]->mapped=MagickFalse;
    289       }
    290     if (magick_windows[i]->name != (char *) NULL)
    291       magick_windows[i]->name=(char *)
    292         RelinquishMagickMemory(magick_windows[i]->name);
    293     if (magick_windows[i]->icon_name != (char *) NULL)
    294       magick_windows[i]->icon_name=(char *)
    295         RelinquishMagickMemory(magick_windows[i]->icon_name);
    296     if (magick_windows[i]->cursor != (Cursor) NULL)
    297       {
    298         (void) XFreeCursor(windows->display,magick_windows[i]->cursor);
    299         magick_windows[i]->cursor=(Cursor) NULL;
    300       }
    301     if (magick_windows[i]->busy_cursor != (Cursor) NULL)
    302       {
    303         (void) XFreeCursor(windows->display,magick_windows[i]->busy_cursor);
    304         magick_windows[i]->busy_cursor=(Cursor) NULL;
    305       }
    306     if (magick_windows[i]->highlight_stipple != (Pixmap) NULL)
    307       {
    308         (void) XFreePixmap(windows->display,
    309           magick_windows[i]->highlight_stipple);
    310         magick_windows[i]->highlight_stipple=(Pixmap) NULL;
    311       }
    312     if (magick_windows[i]->shadow_stipple != (Pixmap) NULL)
    313       {
    314         (void) XFreePixmap(windows->display,magick_windows[i]->shadow_stipple);
    315         magick_windows[i]->shadow_stipple=(Pixmap) NULL;
    316       }
    317     if (magick_windows[i]->ximage != (XImage *) NULL)
    318       {
    319         XDestroyImage(magick_windows[i]->ximage);
    320         magick_windows[i]->ximage=(XImage *) NULL;
    321       }
    322     if (magick_windows[i]->pixmap != (Pixmap) NULL)
    323       {
    324         (void) XFreePixmap(windows->display,magick_windows[i]->pixmap);
    325         magick_windows[i]->pixmap=(Pixmap) NULL;
    326       }
    327     if (magick_windows[i]->id != (Window) NULL)
    328       {
    329         (void) XDestroyWindow(windows->display,magick_windows[i]->id);
    330         magick_windows[i]->id=(Window) NULL;
    331       }
    332     if (magick_windows[i]->destroy != MagickFalse)
    333       {
    334         if (magick_windows[i]->image != (Image *) NULL)
    335           {
    336             magick_windows[i]->image=DestroyImage(magick_windows[i]->image);
    337             magick_windows[i]->image=NewImageList();
    338           }
    339         if (magick_windows[i]->matte_pixmap != (Pixmap) NULL)
    340           {
    341             (void) XFreePixmap(windows->display,
    342               magick_windows[i]->matte_pixmap);
    343             magick_windows[i]->matte_pixmap=(Pixmap) NULL;
    344           }
    345       }
    346     if (magick_windows[i]->segment_info != (void *) NULL)
    347       {
    348 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
    349         XShmSegmentInfo
    350           *segment_info;
    351 
    352         segment_info=(XShmSegmentInfo *) magick_windows[i]->segment_info;
    353         if (segment_info != (XShmSegmentInfo *) NULL)
    354           if (segment_info[0].shmid >= 0)
    355             {
    356               if (segment_info[0].shmaddr != NULL)
    357                 (void) shmdt(segment_info[0].shmaddr);
    358               (void) shmctl(segment_info[0].shmid,IPC_RMID,0);
    359               segment_info[0].shmaddr=NULL;
    360               segment_info[0].shmid=(-1);
    361             }
    362 #endif
    363         magick_windows[i]->segment_info=(void *)
    364           RelinquishMagickMemory(magick_windows[i]->segment_info);
    365       }
    366   }
    367   windows->icon_resources=(XResourceInfo *)
    368     RelinquishMagickMemory(windows->icon_resources);
    369   if (windows->icon_pixel != (XPixelInfo *) NULL)
    370     {
    371       if (windows->icon_pixel->pixels != (unsigned long *) NULL)
    372         windows->icon_pixel->pixels=(unsigned long *)
    373           RelinquishMagickMemory(windows->icon_pixel->pixels);
    374       if (windows->icon_pixel->annotate_context != (GC) NULL)
    375         XFreeGC(windows->display,windows->icon_pixel->annotate_context);
    376       windows->icon_pixel=(XPixelInfo *)
    377         RelinquishMagickMemory(windows->icon_pixel);
    378     }
    379   if (windows->pixel_info != (XPixelInfo *) NULL)
    380     {
    381       if (windows->pixel_info->pixels != (unsigned long *) NULL)
    382         windows->pixel_info->pixels=(unsigned long *)
    383           RelinquishMagickMemory(windows->pixel_info->pixels);
    384       if (windows->pixel_info->annotate_context != (GC) NULL)
    385         XFreeGC(windows->display,windows->pixel_info->annotate_context);
    386       if (windows->pixel_info->widget_context != (GC) NULL)
    387         XFreeGC(windows->display,windows->pixel_info->widget_context);
    388       if (windows->pixel_info->highlight_context != (GC) NULL)
    389         XFreeGC(windows->display,windows->pixel_info->highlight_context);
    390       windows->pixel_info=(XPixelInfo *)
    391         RelinquishMagickMemory(windows->pixel_info);
    392     }
    393   if (windows->font_info != (XFontStruct *) NULL)
    394     {
    395       XFreeFont(windows->display,windows->font_info);
    396       windows->font_info=(XFontStruct *) NULL;
    397     }
    398   if (windows->class_hints != (XClassHint *) NULL)
    399     {
    400       if (windows->class_hints->res_name != (char *) NULL)
    401         windows->class_hints->res_name=DestroyString(
    402           windows->class_hints->res_name);
    403       if (windows->class_hints->res_class != (char *) NULL)
    404         windows->class_hints->res_class=DestroyString(
    405           windows->class_hints->res_class);
    406       XFree(windows->class_hints);
    407       windows->class_hints=(XClassHint *) NULL;
    408     }
    409   if (windows->manager_hints != (XWMHints *) NULL)
    410     {
    411       XFree(windows->manager_hints);
    412       windows->manager_hints=(XWMHints *) NULL;
    413     }
    414   if (windows->map_info != (XStandardColormap *) NULL)
    415     {
    416       XFree(windows->map_info);
    417       windows->map_info=(XStandardColormap *) NULL;
    418     }
    419   if (windows->icon_map != (XStandardColormap *) NULL)
    420     {
    421       XFree(windows->icon_map);
    422       windows->icon_map=(XStandardColormap *) NULL;
    423     }
    424   if (windows->visual_info != (XVisualInfo *) NULL)
    425     {
    426       XFree(windows->visual_info);
    427       windows->visual_info=(XVisualInfo *) NULL;
    428     }
    429   if (windows->icon_visual != (XVisualInfo *) NULL)
    430     {
    431       XFree(windows->icon_visual);
    432       windows->icon_visual=(XVisualInfo *) NULL;
    433     }
    434   (void) XSetWindows((XWindows *) NULL);
    435 }
    436 
    437 /*
    439 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    440 %                                                                             %
    441 %                                                                             %
    442 %                                                                             %
    443 %   X A n n o t a t e I m a g e                                               %
    444 %                                                                             %
    445 %                                                                             %
    446 %                                                                             %
    447 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    448 %
    449 %  XAnnotateImage() annotates the image with text.
    450 %
    451 %  The format of the XAnnotateImage method is:
    452 %
    453 %      MagickBooleanType XAnnotateImage(Display *display,
    454 %        const XPixelInfo *pixel,XAnnotateInfo *annotate_info,Image *image,
    455 %        ExceptionInfo *exception)
    456 %
    457 %  A description of each parameter follows:
    458 %
    459 %    o display: Specifies a connection to an X server;  returned from
    460 %      XOpenDisplay.
    461 %
    462 %    o pixel: Specifies a pointer to a XPixelInfo structure.
    463 %
    464 %    o annotate_info: Specifies a pointer to a XAnnotateInfo structure.
    465 %
    466 %    o image: the image.
    467 %
    468 %    o exception: return any errors or warnings in this structure.
    469 %
    470 */
    471 MagickPrivate MagickBooleanType XAnnotateImage(Display *display,
    472   const XPixelInfo *pixel,XAnnotateInfo *annotate_info,Image *image,
    473   ExceptionInfo *exception)
    474 {
    475   CacheView
    476     *annotate_view;
    477 
    478   GC
    479     annotate_context;
    480 
    481   Image
    482     *annotate_image;
    483 
    484   int
    485     x,
    486     y;
    487 
    488   PixelTrait
    489     alpha_trait;
    490 
    491   Pixmap
    492     annotate_pixmap;
    493 
    494   unsigned int
    495     depth,
    496     height,
    497     width;
    498 
    499   Window
    500     root_window;
    501 
    502   XGCValues
    503     context_values;
    504 
    505   XImage
    506     *annotate_ximage;
    507 
    508   /*
    509     Initialize annotated image.
    510   */
    511   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
    512   assert(display != (Display *) NULL);
    513   assert(pixel != (XPixelInfo *) NULL);
    514   assert(annotate_info != (XAnnotateInfo *) NULL);
    515   assert(image != (Image *) NULL);
    516   /*
    517     Initialize annotated pixmap.
    518   */
    519   root_window=XRootWindow(display,XDefaultScreen(display));
    520   depth=(unsigned int) XDefaultDepth(display,XDefaultScreen(display));
    521   annotate_pixmap=XCreatePixmap(display,root_window,annotate_info->width,
    522     annotate_info->height,depth);
    523   if (annotate_pixmap == (Pixmap) NULL)
    524     return(MagickFalse);
    525   /*
    526     Initialize graphics info.
    527   */
    528   context_values.background=0;
    529   context_values.foreground=(size_t) (~0);
    530   context_values.font=annotate_info->font_info->fid;
    531   annotate_context=XCreateGC(display,root_window,(unsigned long)
    532     (GCBackground | GCFont | GCForeground),&context_values);
    533   if (annotate_context == (GC) NULL)
    534     return(MagickFalse);
    535   /*
    536     Draw text to pixmap.
    537   */
    538   (void) XDrawImageString(display,annotate_pixmap,annotate_context,0,
    539     (int) annotate_info->font_info->ascent,annotate_info->text,
    540     (int) strlen(annotate_info->text));
    541   (void) XFreeGC(display,annotate_context);
    542   /*
    543     Initialize annotated X image.
    544   */
    545   annotate_ximage=XGetImage(display,annotate_pixmap,0,0,annotate_info->width,
    546     annotate_info->height,AllPlanes,ZPixmap);
    547   if (annotate_ximage == (XImage *) NULL)
    548     return(MagickFalse);
    549   (void) XFreePixmap(display,annotate_pixmap);
    550   /*
    551     Initialize annotated image.
    552   */
    553   annotate_image=AcquireImage((ImageInfo *) NULL,exception);
    554   if (annotate_image == (Image *) NULL)
    555     return(MagickFalse);
    556   annotate_image->columns=annotate_info->width;
    557   annotate_image->rows=annotate_info->height;
    558   /*
    559     Transfer annotated X image to image.
    560   */
    561   width=(unsigned int) image->columns;
    562   height=(unsigned int) image->rows;
    563   x=0;
    564   y=0;
    565   (void) XParseGeometry(annotate_info->geometry,&x,&y,&width,&height);
    566   (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,(ssize_t) x,
    567     (ssize_t) y,&annotate_image->background_color,exception);
    568   if (annotate_info->stencil == ForegroundStencil)
    569     annotate_image->alpha_trait=BlendPixelTrait;
    570   annotate_view=AcquireAuthenticCacheView(annotate_image,exception);
    571   for (y=0; y < (int) annotate_image->rows; y++)
    572   {
    573     register int
    574       x;
    575 
    576     register Quantum
    577       *magick_restrict q;
    578 
    579     q=GetCacheViewAuthenticPixels(annotate_view,0,(ssize_t) y,
    580       annotate_image->columns,1,exception);
    581     if (q == (Quantum *) NULL)
    582       break;
    583     for (x=0; x < (int) annotate_image->columns; x++)
    584     {
    585       SetPixelAlpha(annotate_image,OpaqueAlpha,q);
    586       if (XGetPixel(annotate_ximage,x,y) == 0)
    587         {
    588           /*
    589             Set this pixel to the background color.
    590           */
    591           SetPixelRed(annotate_image,ScaleShortToQuantum(
    592             pixel->box_color.red),q);
    593           SetPixelGreen(annotate_image,ScaleShortToQuantum(
    594             pixel->box_color.green),q);
    595           SetPixelBlue(annotate_image,ScaleShortToQuantum(
    596             pixel->box_color.blue),q);
    597           if ((annotate_info->stencil == ForegroundStencil) ||
    598               (annotate_info->stencil == OpaqueStencil))
    599             SetPixelAlpha(annotate_image,TransparentAlpha,q);
    600         }
    601       else
    602         {
    603           /*
    604             Set this pixel to the pen color.
    605           */
    606           SetPixelRed(annotate_image,ScaleShortToQuantum(
    607             pixel->pen_color.red),q);
    608           SetPixelGreen(annotate_image,ScaleShortToQuantum(
    609             pixel->pen_color.green),q);
    610           SetPixelBlue(annotate_image,ScaleShortToQuantum(
    611             pixel->pen_color.blue),q);
    612           if (annotate_info->stencil == BackgroundStencil)
    613             SetPixelAlpha(annotate_image,TransparentAlpha,q);
    614         }
    615       q+=GetPixelChannels(annotate_image);
    616     }
    617     if (SyncCacheViewAuthenticPixels(annotate_view,exception) == MagickFalse)
    618       break;
    619   }
    620   annotate_view=DestroyCacheView(annotate_view);
    621   XDestroyImage(annotate_ximage);
    622   /*
    623     Determine annotate geometry.
    624   */
    625   (void) XParseGeometry(annotate_info->geometry,&x,&y,&width,&height);
    626   if ((width != (unsigned int) annotate_image->columns) ||
    627       (height != (unsigned int) annotate_image->rows))
    628     {
    629       char
    630         image_geometry[MagickPathExtent];
    631 
    632       /*
    633         Scale image.
    634       */
    635       (void) FormatLocaleString(image_geometry,MagickPathExtent,"%ux%u",
    636         width,height);
    637       (void) TransformImage(&annotate_image,(char *) NULL,image_geometry,
    638         exception);
    639     }
    640   if (annotate_info->degrees != 0.0)
    641     {
    642       Image
    643         *rotate_image;
    644 
    645       int
    646         rotations;
    647 
    648       double
    649         normalized_degrees;
    650 
    651       /*
    652         Rotate image.
    653       */
    654       rotate_image=RotateImage(annotate_image,annotate_info->degrees,exception);
    655       if (rotate_image == (Image *) NULL)
    656         return(MagickFalse);
    657       annotate_image=DestroyImage(annotate_image);
    658       annotate_image=rotate_image;
    659       /*
    660         Annotation is relative to the degree of rotation.
    661       */
    662       normalized_degrees=annotate_info->degrees;
    663       while (normalized_degrees < -45.0)
    664         normalized_degrees+=360.0;
    665       for (rotations=0; normalized_degrees > 45.0; rotations++)
    666         normalized_degrees-=90.0;
    667       switch (rotations % 4)
    668       {
    669         default:
    670         case 0:
    671           break;
    672         case 1:
    673         {
    674           /*
    675             Rotate 90 degrees.
    676           */
    677           x-=(int) annotate_image->columns/2;
    678           y+=(int) annotate_image->columns/2;
    679           break;
    680         }
    681         case 2:
    682         {
    683           /*
    684             Rotate 180 degrees.
    685           */
    686           x=x-(int) annotate_image->columns;
    687           break;
    688         }
    689         case 3:
    690         {
    691           /*
    692             Rotate 270 degrees.
    693           */
    694           x=x-(int) annotate_image->columns/2;
    695           y=y-(int) (annotate_image->rows-(annotate_image->columns/2));
    696           break;
    697         }
    698       }
    699     }
    700   /*
    701     Composite text onto the image.
    702   */
    703   (void) XParseGeometry(annotate_info->geometry,&x,&y,&width,&height);
    704   alpha_trait=image->alpha_trait;
    705   (void) CompositeImage(image,annotate_image,
    706     annotate_image->alpha_trait != UndefinedPixelTrait ? OverCompositeOp :
    707     CopyCompositeOp,MagickTrue,(ssize_t) x,(ssize_t) y,exception);
    708   image->alpha_trait=alpha_trait;
    709   annotate_image=DestroyImage(annotate_image);
    710   return(MagickTrue);
    711 }
    712 
    713 /*
    715 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    716 %                                                                             %
    717 %                                                                             %
    718 %                                                                             %
    719 %   X B e s t F o n t                                                         %
    720 %                                                                             %
    721 %                                                                             %
    722 %                                                                             %
    723 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    724 %
    725 %  XBestFont() returns the "best" font.  "Best" is defined as a font specified
    726 %  in the X resource database or a font such that the text width displayed
    727 %  with the font does not exceed the specified maximum width.
    728 %
    729 %  The format of the XBestFont method is:
    730 %
    731 %      XFontStruct *XBestFont(Display *display,
    732 %        const XResourceInfo *resource_info,const MagickBooleanType text_font)
    733 %
    734 %  A description of each parameter follows:
    735 %
    736 %    o font: XBestFont returns a pointer to a XFontStruct structure.
    737 %
    738 %    o display: Specifies a connection to an X server;  returned from
    739 %      XOpenDisplay.
    740 %
    741 %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
    742 %
    743 %    o text_font:  True is font should be mono-spaced (typewriter style).
    744 %
    745 */
    746 
    747 static char **FontToList(char *font)
    748 {
    749   char
    750     **fontlist;
    751 
    752   register char
    753     *p,
    754     *q;
    755 
    756   register int
    757     i;
    758 
    759   unsigned int
    760     fonts;
    761 
    762   if (font == (char *) NULL)
    763     return((char **) NULL);
    764   /*
    765     Convert string to an ASCII list.
    766   */
    767   fonts=1U;
    768   for (p=font; *p != '\0'; p++)
    769     if ((*p == ':') || (*p == ';') || (*p == ','))
    770       fonts++;
    771   fontlist=(char **) AcquireQuantumMemory((size_t) fonts+1UL,sizeof(*fontlist));
    772   if (fontlist == (char **) NULL)
    773     {
    774       ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed",font);
    775       return((char **) NULL);
    776     }
    777   p=font;
    778   for (i=0; i < (int) fonts; i++)
    779   {
    780     for (q=p; *q != '\0'; q++)
    781       if ((*q == ':') || (*q == ';') || (*q == ','))
    782         break;
    783     fontlist[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+1UL,
    784       sizeof(*fontlist[i]));
    785     if (fontlist[i] == (char *) NULL)
    786       {
    787         ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed",font);
    788         return((char **) NULL);
    789       }
    790     (void) CopyMagickString(fontlist[i],p,(size_t) (q-p+1));
    791     p=q+1;
    792   }
    793   fontlist[i]=(char *) NULL;
    794   return(fontlist);
    795 }
    796 
    797 MagickPrivate XFontStruct *XBestFont(Display *display,
    798   const XResourceInfo *resource_info,const MagickBooleanType text_font)
    799 {
    800   static const char
    801     *Fonts[]=
    802     {
    803       "-*-helvetica-medium-r-normal--12-*-*-*-*-*-iso8859-1",
    804       "-*-arial-medium-r-normal--12-*-*-*-*-*-iso8859-1",
    805       "-*-helvetica-medium-r-normal--12-*-*-*-*-*-iso8859-15",
    806       "-*-arial-medium-r-normal--12-*-*-*-*-*-iso8859-15",
    807       "-*-helvetica-medium-r-normal--12-*-*-*-*-*-*-*",
    808       "-*-arial-medium-r-normal--12-*-*-*-*-*-*-*",
    809       "variable",
    810       "fixed",
    811       (char *) NULL
    812     },
    813     *TextFonts[]=
    814     {
    815       "-*-courier-medium-r-normal-*-12-*-*-*-*-*-iso8859-1",
    816       "-*-courier-medium-r-normal-*-12-*-*-*-*-*-iso8859-15",
    817       "-*-fixed-medium-r-normal-*-12-*-*-*-*-*-*-*",
    818       "fixed",
    819       (char *) NULL
    820     };
    821 
    822   char
    823     *font_name;
    824 
    825   register const char
    826     **p;
    827 
    828   XFontStruct
    829     *font_info;
    830 
    831   font_info=(XFontStruct *) NULL;
    832   font_name=resource_info->font;
    833   if (text_font != MagickFalse)
    834     font_name=resource_info->text_font;
    835   if ((font_name != (char *) NULL) && (*font_name != '\0'))
    836     {
    837       char
    838         **fontlist;
    839 
    840       register int
    841         i;
    842 
    843       /*
    844         Load preferred font specified in the X resource database.
    845       */
    846       fontlist=FontToList(font_name);
    847       if (fontlist != (char **) NULL)
    848         {
    849           for (i=0; fontlist[i] != (char *) NULL; i++)
    850           {
    851             if (font_info == (XFontStruct *) NULL)
    852               font_info=XLoadQueryFont(display,fontlist[i]);
    853             fontlist[i]=DestroyString(fontlist[i]);
    854           }
    855           fontlist=(char **) RelinquishMagickMemory(fontlist);
    856         }
    857       if (font_info == (XFontStruct *) NULL)
    858         ThrowXWindowException(XServerError,"UnableToLoadFont",font_name);
    859     }
    860   /*
    861     Load fonts from list of fonts until one is found.
    862   */
    863   p=Fonts;
    864   if (text_font != MagickFalse)
    865     p=TextFonts;
    866   if (XDisplayHeight(display,XDefaultScreen(display)) >= 748)
    867     p++;
    868   while (*p != (char *) NULL)
    869   {
    870     if (font_info != (XFontStruct *) NULL)
    871       break;
    872     font_info=XLoadQueryFont(display,(char *) *p);
    873     p++;
    874   }
    875   return(font_info);
    876 }
    877 
    878 /*
    880 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    881 %                                                                             %
    882 %                                                                             %
    883 %                                                                             %
    884 %   X B e s t I c o n S i z e                                                 %
    885 %                                                                             %
    886 %                                                                             %
    887 %                                                                             %
    888 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    889 %
    890 %  XBestIconSize() returns the "best" icon size.  "Best" is defined as an icon
    891 %  size that maintains the aspect ratio of the image.  If the window manager
    892 %  has preferred icon sizes, one of the preferred sizes is used.
    893 %
    894 %  The format of the XBestIconSize method is:
    895 %
    896 %      void XBestIconSize(Display *display,XWindowInfo *window,Image *image)
    897 %
    898 %  A description of each parameter follows:
    899 %
    900 %    o display: Specifies a connection to an X server;  returned from
    901 %      XOpenDisplay.
    902 %
    903 %    o image: the image.
    904 %
    905 */
    906 MagickPrivate void XBestIconSize(Display *display,XWindowInfo *window,
    907   Image *image)
    908 {
    909   int
    910     i,
    911     number_sizes;
    912 
    913   double
    914     scale_factor;
    915 
    916   unsigned int
    917     height,
    918     icon_height,
    919     icon_width,
    920     width;
    921 
    922   Window
    923     root_window;
    924 
    925   XIconSize
    926     *icon_size,
    927     *size_list;
    928 
    929   /*
    930     Determine if the window manager has specified preferred icon sizes.
    931   */
    932   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
    933   assert(display != (Display *) NULL);
    934   assert(window != (XWindowInfo *) NULL);
    935   assert(image != (Image *) NULL);
    936   window->width=MaxIconSize;
    937   window->height=MaxIconSize;
    938   icon_size=(XIconSize *) NULL;
    939   number_sizes=0;
    940   root_window=XRootWindow(display,window->screen);
    941   if (XGetIconSizes(display,root_window,&size_list,&number_sizes) != 0)
    942     if ((number_sizes > 0) && (size_list != (XIconSize *) NULL))
    943       icon_size=size_list;
    944   if (icon_size == (XIconSize *) NULL)
    945     {
    946       /*
    947         Window manager does not restrict icon size.
    948       */
    949       icon_size=XAllocIconSize();
    950       if (icon_size == (XIconSize *) NULL)
    951         {
    952           ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed",
    953             image->filename);
    954           return;
    955         }
    956       icon_size->min_width=1;
    957       icon_size->max_width=MaxIconSize;
    958       icon_size->min_height=1;
    959       icon_size->max_height=MaxIconSize;
    960       icon_size->width_inc=1;
    961       icon_size->height_inc=1;
    962     }
    963   /*
    964     Determine aspect ratio of image.
    965   */
    966   width=(unsigned int) image->columns;
    967   height=(unsigned int) image->rows;
    968   i=0;
    969   if (window->crop_geometry)
    970     (void) XParseGeometry(window->crop_geometry,&i,&i,&width,&height);
    971   /*
    972     Look for an icon size that maintains the aspect ratio of image.
    973   */
    974   scale_factor=(double) icon_size->max_width/width;
    975   if (scale_factor > ((double) icon_size->max_height/height))
    976     scale_factor=(double) icon_size->max_height/height;
    977   icon_width=(unsigned int) icon_size->min_width;
    978   while ((int) icon_width < icon_size->max_width)
    979   {
    980     if (icon_width >= (unsigned int) (scale_factor*width+0.5))
    981       break;
    982     icon_width+=icon_size->width_inc;
    983   }
    984   icon_height=(unsigned int) icon_size->min_height;
    985   while ((int) icon_height < icon_size->max_height)
    986   {
    987     if (icon_height >= (unsigned int) (scale_factor*height+0.5))
    988       break;
    989     icon_height+=icon_size->height_inc;
    990   }
    991   (void) XFree((void *) icon_size);
    992   window->width=icon_width;
    993   window->height=icon_height;
    994 }
    995 
    996 /*
    998 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    999 %                                                                             %
   1000 %                                                                             %
   1001 %                                                                             %
   1002 %   X B e s t P i x e l                                                       %
   1003 %                                                                             %
   1004 %                                                                             %
   1005 %                                                                             %
   1006 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1007 %
   1008 %  XBestPixel() returns a pixel from an array of pixels that is closest to the
   1009 %  requested color.  If the color array is NULL, the colors are obtained from
   1010 %  the X server.
   1011 %
   1012 %  The format of the XBestPixel method is:
   1013 %
   1014 %      void XBestPixel(Display *display,const Colormap colormap,XColor *colors,
   1015 %        unsigned int number_colors,XColor *color)
   1016 %
   1017 %  A description of each parameter follows:
   1018 %
   1019 %    o pixel: XBestPixel returns the pixel value closest to the requested
   1020 %      color.
   1021 %
   1022 %    o display: Specifies a connection to an X server;  returned from
   1023 %      XOpenDisplay.
   1024 %
   1025 %    o colormap: Specifies the ID of the X server colormap.
   1026 %
   1027 %    o colors: Specifies an array of XColor structures.
   1028 %
   1029 %    o number_colors: Specifies the number of XColor structures in the
   1030 %      color definition array.
   1031 %
   1032 %    o color: Specifies the desired RGB value to find in the colors array.
   1033 %
   1034 */
   1035 MagickPrivate void XBestPixel(Display *display,const Colormap colormap,
   1036   XColor *colors,unsigned int number_colors,XColor *color)
   1037 {
   1038   MagickBooleanType
   1039     query_server;
   1040 
   1041   PixelInfo
   1042     pixel;
   1043 
   1044   double
   1045     min_distance;
   1046 
   1047   register double
   1048     distance;
   1049 
   1050   register int
   1051     i,
   1052     j;
   1053 
   1054   Status
   1055     status;
   1056 
   1057   /*
   1058     Find closest representation for the requested RGB color.
   1059   */
   1060   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   1061   assert(display != (Display *) NULL);
   1062   assert(color != (XColor *) NULL);
   1063   status=XAllocColor(display,colormap,color);
   1064   if (status != False)
   1065     return;
   1066   query_server=colors == (XColor *) NULL ? MagickTrue : MagickFalse;
   1067   if (query_server != MagickFalse)
   1068     {
   1069       /*
   1070         Read X server colormap.
   1071       */
   1072       colors=(XColor *) AcquireQuantumMemory(number_colors,sizeof(*colors));
   1073       if (colors == (XColor *) NULL)
   1074         {
   1075           ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed",
   1076             "...");
   1077           return;
   1078         }
   1079       for (i=0; i < (int) number_colors; i++)
   1080         colors[i].pixel=(size_t) i;
   1081       if (number_colors > 256)
   1082         number_colors=256;
   1083       (void) XQueryColors(display,colormap,colors,(int) number_colors);
   1084     }
   1085   min_distance=3.0*((double) QuantumRange+1.0)*((double)
   1086     QuantumRange+1.0);
   1087   j=0;
   1088   for (i=0; i < (int) number_colors; i++)
   1089   {
   1090     pixel.red=colors[i].red-(double) color->red;
   1091     distance=pixel.red*pixel.red;
   1092     if (distance > min_distance)
   1093       continue;
   1094     pixel.green=colors[i].green-(double) color->green;
   1095     distance+=pixel.green*pixel.green;
   1096     if (distance > min_distance)
   1097       continue;
   1098     pixel.blue=colors[i].blue-(double) color->blue;
   1099     distance+=pixel.blue*pixel.blue;
   1100     if (distance > min_distance)
   1101       continue;
   1102     min_distance=distance;
   1103     color->pixel=colors[i].pixel;
   1104     j=i;
   1105   }
   1106   (void) XAllocColor(display,colormap,&colors[j]);
   1107   if (query_server != MagickFalse)
   1108     colors=(XColor *) RelinquishMagickMemory(colors);
   1109 }
   1110 
   1111 /*
   1113 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1114 %                                                                             %
   1115 %                                                                             %
   1116 %                                                                             %
   1117 %   X B e s t V i s u a l I n f o                                             %
   1118 %                                                                             %
   1119 %                                                                             %
   1120 %                                                                             %
   1121 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1122 %
   1123 %  XBestVisualInfo() returns visual information for a visual that is the "best"
   1124 %  the server supports.  "Best" is defined as:
   1125 %
   1126 %    1. Restrict the visual list to those supported by the default screen.
   1127 %
   1128 %    2. If a visual type is specified, restrict the visual list to those of
   1129 %       that type.
   1130 %
   1131 %    3. If a map type is specified, choose the visual that matches the id
   1132 %       specified by the Standard Colormap.
   1133 %
   1134 %    4  From the list of visuals, choose one that can display the most
   1135 %       simultaneous colors.  If more than one visual can display the same
   1136 %       number of simultaneous colors, one is chosen based on a rank.
   1137 %
   1138 %  The format of the XBestVisualInfo method is:
   1139 %
   1140 %      XVisualInfo *XBestVisualInfo(Display *display,
   1141 %        XStandardColormap *map_info,XResourceInfo *resource_info)
   1142 %
   1143 %  A description of each parameter follows:
   1144 %
   1145 %    o visual_info: XBestVisualInfo returns a pointer to a X11 XVisualInfo
   1146 %      structure.
   1147 %
   1148 %    o display: Specifies a connection to an X server;  returned from
   1149 %      XOpenDisplay.
   1150 %
   1151 %    o map_info: If map_type is specified, this structure is initialized
   1152 %      with info from the Standard Colormap.
   1153 %
   1154 %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
   1155 %
   1156 */
   1157 MagickPrivate XVisualInfo *XBestVisualInfo(Display *display,
   1158   XStandardColormap *map_info,XResourceInfo *resource_info)
   1159 {
   1160 #define MaxStandardColormaps  7
   1161 #define XVisualColormapSize(visual_info) MagickMin((unsigned int) (\
   1162   (visual_info->klass == TrueColor) || (visual_info->klass == DirectColor) ? \
   1163    visual_info->red_mask | visual_info->green_mask | visual_info->blue_mask : \
   1164    (unsigned long) visual_info->colormap_size),1UL << visual_info->depth)
   1165 
   1166   char
   1167     *map_type,
   1168     *visual_type;
   1169 
   1170   int
   1171     visual_mask;
   1172 
   1173   register int
   1174     i;
   1175 
   1176   size_t
   1177     one;
   1178 
   1179   static int
   1180     number_visuals;
   1181 
   1182   static XVisualInfo
   1183     visual_template;
   1184 
   1185   XVisualInfo
   1186     *visual_info,
   1187     *visual_list;
   1188 
   1189   /*
   1190     Restrict visual search by screen number.
   1191   */
   1192   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   1193   assert(display != (Display *) NULL);
   1194   assert(map_info != (XStandardColormap *) NULL);
   1195   assert(resource_info != (XResourceInfo *) NULL);
   1196   map_type=resource_info->map_type;
   1197   visual_type=resource_info->visual_type;
   1198   visual_mask=VisualScreenMask;
   1199   visual_template.screen=XDefaultScreen(display);
   1200   visual_template.depth=XDefaultDepth(display,XDefaultScreen(display));
   1201   one=1;
   1202   if ((resource_info->immutable != MagickFalse) && (resource_info->colors != 0))
   1203     if (resource_info->colors <= (one << (size_t) visual_template.depth))
   1204       visual_mask|=VisualDepthMask;
   1205   if (visual_type != (char *) NULL)
   1206     {
   1207       /*
   1208         Restrict visual search by class or visual id.
   1209       */
   1210       if (LocaleCompare("staticgray",visual_type) == 0)
   1211         {
   1212           visual_mask|=VisualClassMask;
   1213           visual_template.klass=StaticGray;
   1214         }
   1215       else
   1216         if (LocaleCompare("grayscale",visual_type) == 0)
   1217           {
   1218             visual_mask|=VisualClassMask;
   1219             visual_template.klass=GrayScale;
   1220           }
   1221         else
   1222           if (LocaleCompare("staticcolor",visual_type) == 0)
   1223             {
   1224               visual_mask|=VisualClassMask;
   1225               visual_template.klass=StaticColor;
   1226             }
   1227           else
   1228             if (LocaleCompare("pseudocolor",visual_type) == 0)
   1229               {
   1230                 visual_mask|=VisualClassMask;
   1231                 visual_template.klass=PseudoColor;
   1232               }
   1233             else
   1234               if (LocaleCompare("truecolor",visual_type) == 0)
   1235                 {
   1236                   visual_mask|=VisualClassMask;
   1237                   visual_template.klass=TrueColor;
   1238                 }
   1239               else
   1240                 if (LocaleCompare("directcolor",visual_type) == 0)
   1241                   {
   1242                     visual_mask|=VisualClassMask;
   1243                     visual_template.klass=DirectColor;
   1244                   }
   1245                 else
   1246                   if (LocaleCompare("default",visual_type) == 0)
   1247                     {
   1248                       visual_mask|=VisualIDMask;
   1249                       visual_template.visualid=XVisualIDFromVisual(
   1250                         XDefaultVisual(display,XDefaultScreen(display)));
   1251                     }
   1252                   else
   1253                     if (isdigit((int) ((unsigned char) *visual_type)) != 0)
   1254                       {
   1255                         visual_mask|=VisualIDMask;
   1256                         visual_template.visualid=
   1257                           strtol(visual_type,(char **) NULL,0);
   1258                       }
   1259                     else
   1260                       ThrowXWindowException(XServerError,
   1261                         "UnrecognizedVisualSpecifier",visual_type);
   1262     }
   1263   /*
   1264     Get all visuals that meet our criteria so far.
   1265   */
   1266   number_visuals=0;
   1267   visual_list=XGetVisualInfo(display,visual_mask,&visual_template,
   1268     &number_visuals);
   1269   visual_mask=VisualScreenMask | VisualIDMask;
   1270   if ((number_visuals == 0) || (visual_list == (XVisualInfo *) NULL))
   1271     {
   1272       /*
   1273         Failed to get visual;  try using the default visual.
   1274       */
   1275       ThrowXWindowException(XServerWarning,"UnableToGetVisual",visual_type);
   1276       visual_template.visualid=XVisualIDFromVisual(XDefaultVisual(display,
   1277         XDefaultScreen(display)));
   1278       visual_list=XGetVisualInfo(display,visual_mask,&visual_template,
   1279         &number_visuals);
   1280       if ((number_visuals == 0) || (visual_list == (XVisualInfo *) NULL))
   1281         return((XVisualInfo *) NULL);
   1282       ThrowXWindowException(XServerWarning,"UsingDefaultVisual",
   1283         XVisualClassName(visual_list->klass));
   1284     }
   1285   resource_info->color_recovery=MagickFalse;
   1286   if ((map_info != (XStandardColormap *) NULL) && (map_type != (char *) NULL))
   1287     {
   1288       Atom
   1289         map_property;
   1290 
   1291       char
   1292         map_name[MagickPathExtent];
   1293 
   1294       int
   1295         j,
   1296         number_maps;
   1297 
   1298       Status
   1299         status;
   1300 
   1301       Window
   1302         root_window;
   1303 
   1304       XStandardColormap
   1305         *map_list;
   1306 
   1307       /*
   1308         Choose a visual associated with a standard colormap.
   1309       */
   1310       root_window=XRootWindow(display,XDefaultScreen(display));
   1311       status=False;
   1312       number_maps=0;
   1313       if (LocaleCompare(map_type,"list") != 0)
   1314         {
   1315           /*
   1316             User specified Standard Colormap.
   1317           */
   1318           (void) FormatLocaleString((char *) map_name,MagickPathExtent,
   1319             "RGB_%s_MAP",map_type);
   1320           LocaleUpper(map_name);
   1321           map_property=XInternAtom(display,(char *) map_name,MagickTrue);
   1322           if (map_property != (Atom) NULL)
   1323             status=XGetRGBColormaps(display,root_window,&map_list,&number_maps,
   1324               map_property);
   1325         }
   1326       else
   1327         {
   1328           static const char
   1329             *colormap[MaxStandardColormaps]=
   1330             {
   1331               "_HP_RGB_SMOOTH_MAP_LIST",
   1332               "RGB_BEST_MAP",
   1333               "RGB_DEFAULT_MAP",
   1334               "RGB_GRAY_MAP",
   1335               "RGB_RED_MAP",
   1336               "RGB_GREEN_MAP",
   1337               "RGB_BLUE_MAP",
   1338             };
   1339 
   1340           /*
   1341             Choose a standard colormap from a list.
   1342           */
   1343           for (i=0; i < MaxStandardColormaps; i++)
   1344           {
   1345             map_property=XInternAtom(display,(char *) colormap[i],MagickTrue);
   1346             if (map_property == (Atom) NULL)
   1347               continue;
   1348             status=XGetRGBColormaps(display,root_window,&map_list,&number_maps,
   1349               map_property);
   1350             if (status != False)
   1351               break;
   1352           }
   1353           resource_info->color_recovery=i == 0 ? MagickTrue : MagickFalse;
   1354         }
   1355       if (status == False)
   1356         {
   1357           ThrowXWindowException(XServerError,"UnableToGetStandardColormap",
   1358             map_type);
   1359           return((XVisualInfo *) NULL);
   1360         }
   1361       /*
   1362         Search all Standard Colormaps and visuals for ids that match.
   1363       */
   1364       *map_info=map_list[0];
   1365 #if !defined(PRE_R4_ICCCM)
   1366       visual_template.visualid=XVisualIDFromVisual(visual_list[0].visual);
   1367       for (i=0; i < number_maps; i++)
   1368         for (j=0; j < number_visuals; j++)
   1369           if (map_list[i].visualid ==
   1370               XVisualIDFromVisual(visual_list[j].visual))
   1371             {
   1372               *map_info=map_list[i];
   1373               visual_template.visualid=XVisualIDFromVisual(
   1374                 visual_list[j].visual);
   1375               break;
   1376             }
   1377       if (map_info->visualid != visual_template.visualid)
   1378         {
   1379           ThrowXWindowException(XServerError,
   1380             "UnableToMatchVisualToStandardColormap",map_type);
   1381           return((XVisualInfo *) NULL);
   1382         }
   1383 #endif
   1384       if (map_info->colormap == (Colormap) NULL)
   1385         {
   1386           ThrowXWindowException(XServerError,"StandardColormapIsNotInitialized",
   1387             map_type);
   1388           return((XVisualInfo *) NULL);
   1389         }
   1390       (void) XFree((void *) map_list);
   1391     }
   1392   else
   1393     {
   1394       static const unsigned int
   1395         rank[]=
   1396           {
   1397             StaticGray,
   1398             GrayScale,
   1399             StaticColor,
   1400             DirectColor,
   1401             TrueColor,
   1402             PseudoColor
   1403           };
   1404 
   1405       XVisualInfo
   1406         *p;
   1407 
   1408       /*
   1409         Pick one visual that displays the most simultaneous colors.
   1410       */
   1411       visual_info=visual_list;
   1412       p=visual_list;
   1413       for (i=1; i < number_visuals; i++)
   1414       {
   1415         p++;
   1416         if (XVisualColormapSize(p) > XVisualColormapSize(visual_info))
   1417           visual_info=p;
   1418         else
   1419           if (XVisualColormapSize(p) == XVisualColormapSize(visual_info))
   1420             if (rank[p->klass] > rank[visual_info->klass])
   1421               visual_info=p;
   1422       }
   1423       visual_template.visualid=XVisualIDFromVisual(visual_info->visual);
   1424     }
   1425   (void) XFree((void *) visual_list);
   1426   /*
   1427     Retrieve only one visual by its screen & id number.
   1428   */
   1429   visual_info=XGetVisualInfo(display,visual_mask,&visual_template,
   1430     &number_visuals);
   1431   if ((number_visuals == 0) || (visual_info == (XVisualInfo *) NULL))
   1432     return((XVisualInfo *) NULL);
   1433   return(visual_info);
   1434 }
   1435 
   1436 /*
   1438 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1439 %                                                                             %
   1440 %                                                                             %
   1441 %                                                                             %
   1442 %   X C h e c k D e f i n e C u r s o r                                       %
   1443 %                                                                             %
   1444 %                                                                             %
   1445 %                                                                             %
   1446 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1447 %
   1448 %  XCheckDefineCursor() prevents cursor changes on the root window.
   1449 %
   1450 %  The format of the XXCheckDefineCursor method is:
   1451 %
   1452 %      XCheckDefineCursor(display,window,cursor)
   1453 %
   1454 %  A description of each parameter follows:
   1455 %
   1456 %    o display: Specifies a connection to an X server;  returned from
   1457 %      XOpenDisplay.
   1458 %
   1459 %    o window: the window.
   1460 %
   1461 %    o cursor: the cursor.
   1462 %
   1463 */
   1464 MagickPrivate int XCheckDefineCursor(Display *display,Window window,
   1465   Cursor cursor)
   1466 {
   1467   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   1468   assert(display != (Display *) NULL);
   1469   if (window == XRootWindow(display,XDefaultScreen(display)))
   1470     return(0);
   1471   return(XDefineCursor(display,window,cursor));
   1472 }
   1473 
   1474 /*
   1476 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1477 %                                                                             %
   1478 %                                                                             %
   1479 %                                                                             %
   1480 %   X C h e c k R e f r e s h W i n d o w s                                   %
   1481 %                                                                             %
   1482 %                                                                             %
   1483 %                                                                             %
   1484 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1485 %
   1486 %  XCheckRefreshWindows() checks the X server for exposure events for a
   1487 %  particular window and updates the areassociated with the exposure event.
   1488 %
   1489 %  The format of the XCheckRefreshWindows method is:
   1490 %
   1491 %      void XCheckRefreshWindows(Display *display,XWindows *windows)
   1492 %
   1493 %  A description of each parameter follows:
   1494 %
   1495 %    o display: Specifies a connection to an X server;  returned from
   1496 %      XOpenDisplay.
   1497 %
   1498 %    o windows: Specifies a pointer to a XWindows structure.
   1499 %
   1500 */
   1501 MagickPrivate void XCheckRefreshWindows(Display *display,XWindows *windows)
   1502 {
   1503   Window
   1504     id;
   1505 
   1506   XEvent
   1507     event;
   1508 
   1509   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   1510   assert(display != (Display *) NULL);
   1511   assert(windows != (XWindows *) NULL);
   1512   XDelay(display,SuspendTime);
   1513   id=windows->command.id;
   1514   while (XCheckTypedWindowEvent(display,id,Expose,&event) != MagickFalse)
   1515     (void) XCommandWidget(display,windows,(char const **) NULL,&event);
   1516   id=windows->image.id;
   1517   while (XCheckTypedWindowEvent(display,id,Expose,&event) != MagickFalse)
   1518     XRefreshWindow(display,&windows->image,&event);
   1519   XDelay(display,SuspendTime << 1);
   1520   id=windows->command.id;
   1521   while (XCheckTypedWindowEvent(display,id,Expose,&event) != MagickFalse)
   1522     (void) XCommandWidget(display,windows,(char const **) NULL,&event);
   1523   id=windows->image.id;
   1524   while (XCheckTypedWindowEvent(display,id,Expose,&event) != MagickFalse)
   1525     XRefreshWindow(display,&windows->image,&event);
   1526 }
   1527 
   1528 /*
   1530 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1531 %                                                                             %
   1532 %                                                                             %
   1533 %                                                                             %
   1534 %   X C l i e n t M e s s a g e                                               %
   1535 %                                                                             %
   1536 %                                                                             %
   1537 %                                                                             %
   1538 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1539 %
   1540 %  XClientMessage() sends a reason to a window with XSendEvent.  The reason is
   1541 %  initialized with a particular protocol type and atom.
   1542 %
   1543 %  The format of the XClientMessage function is:
   1544 %
   1545 %      XClientMessage(display,window,protocol,reason,timestamp)
   1546 %
   1547 %  A description of each parameter follows:
   1548 %
   1549 %    o display: Specifies a pointer to the Display structure;  returned from
   1550 %      XOpenDisplay.
   1551 %
   1552 %    o window: Specifies a pointer to a Window structure.
   1553 %
   1554 %    o protocol: Specifies an atom value.
   1555 %
   1556 %    o reason: Specifies an atom value which is the reason to send.
   1557 %
   1558 %    o timestamp: Specifies a value of type Time.
   1559 %
   1560 */
   1561 MagickPrivate void XClientMessage(Display *display,const Window window,
   1562   const Atom protocol,const Atom reason,const Time timestamp)
   1563 {
   1564   XClientMessageEvent
   1565     client_event;
   1566 
   1567   assert(display != (Display *) NULL);
   1568   client_event.type=ClientMessage;
   1569   client_event.window=window;
   1570   client_event.message_type=protocol;
   1571   client_event.format=32;
   1572   client_event.data.l[0]=(long) reason;
   1573   client_event.data.l[1]=(long) timestamp;
   1574   (void) XSendEvent(display,window,MagickFalse,NoEventMask,(XEvent *) &client_event);
   1575 }
   1576 
   1577 /*
   1579 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1580 %                                                                             %
   1581 %                                                                             %
   1582 %                                                                             %
   1583 +   X C l i e n t W i n d o w                                                 %
   1584 %                                                                             %
   1585 %                                                                             %
   1586 %                                                                             %
   1587 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1588 %
   1589 %  XClientWindow() finds a window, at or below the specified window, which has
   1590 %  a WM_STATE property.  If such a window is found, it is returned, otherwise
   1591 %  the argument window is returned.
   1592 %
   1593 %  The format of the XClientWindow function is:
   1594 %
   1595 %      client_window=XClientWindow(display,target_window)
   1596 %
   1597 %  A description of each parameter follows:
   1598 %
   1599 %    o client_window: XClientWindow returns a window, at or below the specified
   1600 %      window, which has a WM_STATE property otherwise the argument
   1601 %      target_window is returned.
   1602 %
   1603 %    o display: Specifies a pointer to the Display structure;  returned from
   1604 %      XOpenDisplay.
   1605 %
   1606 %    o target_window: Specifies the window to find a WM_STATE property.
   1607 %
   1608 */
   1609 static Window XClientWindow(Display *display,Window target_window)
   1610 {
   1611   Atom
   1612     state,
   1613     type;
   1614 
   1615   int
   1616     format;
   1617 
   1618   Status
   1619     status;
   1620 
   1621   unsigned char
   1622     *data;
   1623 
   1624   unsigned long
   1625     after,
   1626     number_items;
   1627 
   1628   Window
   1629     client_window;
   1630 
   1631   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   1632   assert(display != (Display *) NULL);
   1633   state=XInternAtom(display,"WM_STATE",MagickTrue);
   1634   if (state == (Atom) NULL)
   1635     return(target_window);
   1636   type=(Atom) NULL;
   1637   status=XGetWindowProperty(display,target_window,state,0L,0L,MagickFalse,
   1638     (Atom) AnyPropertyType,&type,&format,&number_items,&after,&data);
   1639   if ((status == Success) && (type != (Atom) NULL))
   1640     return(target_window);
   1641   client_window=XWindowByProperty(display,target_window,state);
   1642   if (client_window == (Window) NULL)
   1643     return(target_window);
   1644   return(client_window);
   1645 }
   1646 
   1647 /*
   1649 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1650 %                                                                             %
   1651 %                                                                             %
   1652 %                                                                             %
   1653 +   X C o m p o n e n t T e r m i n u s                                       %
   1654 %                                                                             %
   1655 %                                                                             %
   1656 %                                                                             %
   1657 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1658 %
   1659 %  XComponentTerminus() destroys the module component.
   1660 %
   1661 %  The format of the XComponentTerminus method is:
   1662 %
   1663 %      XComponentTerminus(void)
   1664 %
   1665 */
   1666 MagickPrivate void XComponentTerminus(void)
   1667 {
   1668   DestroyXResources();
   1669 }
   1670 
   1671 /*
   1673 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1674 %                                                                             %
   1675 %                                                                             %
   1676 %                                                                             %
   1677 %   X C o n f i g u r e I m a g e C o l o r m a p                             %
   1678 %                                                                             %
   1679 %                                                                             %
   1680 %                                                                             %
   1681 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1682 %
   1683 %  XConfigureImageColormap() creates a new X colormap.
   1684 %
   1685 %  The format of the XConfigureImageColormap method is:
   1686 %
   1687 %      void XConfigureImageColormap(Display *display,
   1688 %        XResourceInfo *resource_info,XWindows *windows,Image *image,
   1689 %        ExceptionInfo *exception)
   1690 %
   1691 %  A description of each parameter follows:
   1692 %
   1693 %    o display: Specifies a connection to an X server; returned from
   1694 %      XOpenDisplay.
   1695 %
   1696 %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
   1697 %
   1698 %    o windows: Specifies a pointer to a XWindows structure.
   1699 %
   1700 %    o image: the image.
   1701 %
   1702 %    o exception: return any errors or warnings in this structure.
   1703 %
   1704 */
   1705 MagickPrivate void XConfigureImageColormap(Display *display,
   1706   XResourceInfo *resource_info,XWindows *windows,Image *image,
   1707   ExceptionInfo *exception)
   1708 {
   1709   Colormap
   1710     colormap;
   1711 
   1712   /*
   1713     Make standard colormap.
   1714   */
   1715   XSetCursorState(display,windows,MagickTrue);
   1716   XCheckRefreshWindows(display,windows);
   1717   XMakeStandardColormap(display,windows->visual_info,resource_info,image,
   1718     windows->map_info,windows->pixel_info,exception);
   1719   colormap=windows->map_info->colormap;
   1720   (void) XSetWindowColormap(display,windows->image.id,colormap);
   1721   (void) XSetWindowColormap(display,windows->command.id,colormap);
   1722   (void) XSetWindowColormap(display,windows->widget.id,colormap);
   1723   if (windows->magnify.mapped != MagickFalse)
   1724     (void) XSetWindowColormap(display,windows->magnify.id,colormap);
   1725   if (windows->pan.mapped != MagickFalse)
   1726     (void) XSetWindowColormap(display,windows->pan.id,colormap);
   1727   XSetCursorState(display,windows,MagickFalse);
   1728   XClientMessage(display,windows->image.id,windows->im_protocols,
   1729     windows->im_update_colormap,CurrentTime);
   1730 }
   1731 
   1732 /*
   1734 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1735 %                                                                             %
   1736 %                                                                             %
   1737 %                                                                             %
   1738 %   X C o n s t r a i n W i n d o w P o s i t i o n                           %
   1739 %                                                                             %
   1740 %                                                                             %
   1741 %                                                                             %
   1742 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1743 %
   1744 %  XConstrainWindowPosition() assures a window is positioned within the X
   1745 %  server boundaries.
   1746 %
   1747 %  The format of the XConstrainWindowPosition method is:
   1748 %
   1749 %      void XConstrainWindowPosition(Display *display,XWindowInfo *window_info)
   1750 %
   1751 %  A description of each parameter follows:
   1752 %
   1753 %    o display: Specifies a pointer to the Display structure;  returned from
   1754 %      XOpenDisplay.
   1755 %
   1756 %    o window_info: Specifies a pointer to a XWindowInfo structure.
   1757 %
   1758 */
   1759 MagickPrivate void XConstrainWindowPosition(Display *display,
   1760   XWindowInfo *window_info)
   1761 {
   1762   int
   1763     limit;
   1764 
   1765   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   1766   assert(display != (Display *) NULL);
   1767   assert(window_info != (XWindowInfo *) NULL);
   1768   limit=XDisplayWidth(display,window_info->screen)-window_info->width;
   1769   if (window_info->x < 0)
   1770     window_info->x=0;
   1771   else
   1772     if (window_info->x > (int) limit)
   1773       window_info->x=(int) limit;
   1774   limit=XDisplayHeight(display,window_info->screen)-window_info->height;
   1775   if (window_info->y < 0)
   1776     window_info->y=0;
   1777   else
   1778     if (window_info->y > limit)
   1779       window_info->y=limit;
   1780 }
   1781 
   1782 /*
   1784 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1785 %                                                                             %
   1786 %                                                                             %
   1787 %                                                                             %
   1788 %   X D e l a y                                                               %
   1789 %                                                                             %
   1790 %                                                                             %
   1791 %                                                                             %
   1792 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1793 %
   1794 %  XDelay() suspends program execution for the number of milliseconds
   1795 %  specified.
   1796 %
   1797 %  The format of the Delay method is:
   1798 %
   1799 %      void XDelay(Display *display,const size_t milliseconds)
   1800 %
   1801 %  A description of each parameter follows:
   1802 %
   1803 %    o display: Specifies a pointer to the Display structure;  returned from
   1804 %      XOpenDisplay.
   1805 %
   1806 %    o milliseconds: Specifies the number of milliseconds to delay before
   1807 %      returning.
   1808 %
   1809 */
   1810 MagickPrivate void XDelay(Display *display,const size_t milliseconds)
   1811 {
   1812   assert(display != (Display *) NULL);
   1813   (void) XFlush(display);
   1814   MagickDelay(milliseconds);
   1815 }
   1816 
   1817 /*
   1819 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1820 %                                                                             %
   1821 %                                                                             %
   1822 %                                                                             %
   1823 %   X D e s t r o y R e s o u r c e I n f o                                   %
   1824 %                                                                             %
   1825 %                                                                             %
   1826 %                                                                             %
   1827 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1828 %
   1829 %  XDestroyResourceInfo() frees memory associated with the XResourceInfo
   1830 %  structure.
   1831 %
   1832 %  The format of the XDestroyResourceInfo method is:
   1833 %
   1834 %      void XDestroyResourceInfo(XResourceInfo *resource_info)
   1835 %
   1836 %  A description of each parameter follows:
   1837 %
   1838 %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
   1839 %
   1840 */
   1841 MagickExport void XDestroyResourceInfo(XResourceInfo *resource_info)
   1842 {
   1843   if (resource_info->image_geometry != (char *) NULL)
   1844     resource_info->image_geometry=(char *)
   1845       RelinquishMagickMemory(resource_info->image_geometry);
   1846   if (resource_info->quantize_info != (QuantizeInfo *) NULL)
   1847     resource_info->quantize_info=DestroyQuantizeInfo(
   1848       resource_info->quantize_info);
   1849   if (resource_info->client_name != (char *) NULL)
   1850     resource_info->client_name=(char *)
   1851       RelinquishMagickMemory(resource_info->client_name);
   1852   if (resource_info->name != (char *) NULL)
   1853     resource_info->name=DestroyString(resource_info->name);
   1854   (void) ResetMagickMemory(resource_info,0,sizeof(*resource_info));
   1855 }
   1856 
   1857 /*
   1859 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1860 %                                                                             %
   1861 %                                                                             %
   1862 %                                                                             %
   1863 %   X D e s t r o y W i n d o w C o l o r s                                   %
   1864 %                                                                             %
   1865 %                                                                             %
   1866 %                                                                             %
   1867 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1868 %
   1869 %  XDestroyWindowColors() frees X11 color resources previously saved on a
   1870 %  window by XRetainWindowColors or programs like xsetroot.
   1871 %
   1872 %  The format of the XDestroyWindowColors method is:
   1873 %
   1874 %      void XDestroyWindowColors(Display *display,Window window)
   1875 %
   1876 %  A description of each parameter follows:
   1877 %
   1878 %    o display: Specifies a connection to an X server; returned from
   1879 %      XOpenDisplay.
   1880 %
   1881 %    o window: Specifies a pointer to a Window structure.
   1882 %
   1883 */
   1884 MagickPrivate void XDestroyWindowColors(Display *display,Window window)
   1885 {
   1886   Atom
   1887     property,
   1888     type;
   1889 
   1890   int
   1891     format;
   1892 
   1893   Status
   1894     status;
   1895 
   1896   unsigned char
   1897     *data;
   1898 
   1899   unsigned long
   1900     after,
   1901     length;
   1902 
   1903   /*
   1904     If there are previous resources on the root window, destroy them.
   1905   */
   1906   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   1907   assert(display != (Display *) NULL);
   1908   property=XInternAtom(display,"_XSETROOT_ID",MagickFalse);
   1909   if (property == (Atom) NULL)
   1910     {
   1911       ThrowXWindowException(XServerError,"UnableToCreateProperty",
   1912         "_XSETROOT_ID");
   1913       return;
   1914     }
   1915   status=XGetWindowProperty(display,window,property,0L,1L,MagickTrue,
   1916     (Atom) AnyPropertyType,&type,&format,&length,&after,&data);
   1917   if (status != Success)
   1918     return;
   1919   if ((type == XA_PIXMAP) && (format == 32) && (length == 1) && (after == 0))
   1920     {
   1921       (void) XKillClient(display,(XID) (*((Pixmap *) data)));
   1922       (void) XDeleteProperty(display,window,property);
   1923     }
   1924   if (type != None)
   1925     (void) XFree((void *) data);
   1926 }
   1927 
   1928 /*
   1930 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1931 %                                                                             %
   1932 %                                                                             %
   1933 %                                                                             %
   1934 %   X D i s p l a y I m a g e I n f o                                         %
   1935 %                                                                             %
   1936 %                                                                             %
   1937 %                                                                             %
   1938 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1939 %
   1940 %  XDisplayImageInfo() displays information about an X image.
   1941 %
   1942 %  The format of the XDisplayImageInfo method is:
   1943 %
   1944 %      void XDisplayImageInfo(Display *display,
   1945 %        const XResourceInfo *resource_info,XWindows *windows,Image *undo_image,
   1946 %        Image *image,ExceptionInfo *exception)
   1947 %
   1948 %  A description of each parameter follows:
   1949 %
   1950 %    o display: Specifies a connection to an X server;  returned from
   1951 %      XOpenDisplay.
   1952 %
   1953 %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
   1954 %
   1955 %    o windows: Specifies a pointer to a XWindows structure.
   1956 %
   1957 %    o undo_image: the undo image.
   1958 %
   1959 %    o image: the image.
   1960 %
   1961 %    o exception: return any errors or warnings in this structure.
   1962 %
   1963 */
   1964 MagickPrivate void XDisplayImageInfo(Display *display,
   1965   const XResourceInfo *resource_info,XWindows *windows,Image *undo_image,
   1966   Image *image,ExceptionInfo *exception)
   1967 {
   1968   char
   1969     filename[MagickPathExtent],
   1970     *text,
   1971     **textlist;
   1972 
   1973   FILE
   1974     *file;
   1975 
   1976   int
   1977     unique_file;
   1978 
   1979   register ssize_t
   1980     i;
   1981 
   1982   size_t
   1983     number_pixels;
   1984 
   1985   ssize_t
   1986     bytes;
   1987 
   1988   unsigned int
   1989     levels;
   1990 
   1991   /*
   1992     Write info about the X server to a file.
   1993   */
   1994   assert(display != (Display *) NULL);
   1995   assert(resource_info != (XResourceInfo *) NULL);
   1996   assert(windows != (XWindows *) NULL);
   1997   assert(image != (Image *) NULL);
   1998   if (image->debug)
   1999     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   2000   file=(FILE *) NULL;
   2001   unique_file=AcquireUniqueFileResource(filename);
   2002   if (unique_file != -1)
   2003     file=fdopen(unique_file,"w");
   2004   if ((unique_file == -1) || (file == (FILE *) NULL))
   2005     {
   2006       XNoticeWidget(display,windows,"Unable to display image info",filename);
   2007       return;
   2008     }
   2009   if (resource_info->gamma_correct != MagickFalse)
   2010     if (resource_info->display_gamma != (char *) NULL)
   2011       (void) FormatLocaleFile(file,"Display\n  gamma: %s\n\n",
   2012         resource_info->display_gamma);
   2013   /*
   2014     Write info about the X image to a file.
   2015   */
   2016   (void) FormatLocaleFile(file,"X\n  visual: %s\n",
   2017     XVisualClassName((int) windows->image.storage_class));
   2018   (void) FormatLocaleFile(file,"  depth: %d\n",windows->image.ximage->depth);
   2019   if (windows->visual_info->colormap_size != 0)
   2020     (void) FormatLocaleFile(file,"  colormap size: %d\n",
   2021       windows->visual_info->colormap_size);
   2022   if (resource_info->colormap== SharedColormap)
   2023     (void) FormatLocaleFile(file,"  colormap type: Shared\n");
   2024   else
   2025     (void) FormatLocaleFile(file,"  colormap type: Private\n");
   2026   (void) FormatLocaleFile(file,"  geometry: %dx%d\n",
   2027     windows->image.ximage->width,windows->image.ximage->height);
   2028   if (windows->image.crop_geometry != (char *) NULL)
   2029     (void) FormatLocaleFile(file,"  crop geometry: %s\n",
   2030       windows->image.crop_geometry);
   2031   if (windows->image.pixmap == (Pixmap) NULL)
   2032     (void) FormatLocaleFile(file,"  type: X Image\n");
   2033   else
   2034     (void) FormatLocaleFile(file,"  type: Pixmap\n");
   2035   if (windows->image.shape != MagickFalse)
   2036     (void) FormatLocaleFile(file,"  non-rectangular shape: True\n");
   2037   else
   2038     (void) FormatLocaleFile(file,"  non-rectangular shape: False\n");
   2039   if (windows->image.shared_memory != MagickFalse)
   2040     (void) FormatLocaleFile(file,"  shared memory: True\n");
   2041   else
   2042     (void) FormatLocaleFile(file,"  shared memory: False\n");
   2043   (void) FormatLocaleFile(file,"\n");
   2044   if (resource_info->font != (char *) NULL)
   2045     (void) FormatLocaleFile(file,"Font: %s\n\n",resource_info->font);
   2046   if (resource_info->text_font != (char *) NULL)
   2047     (void) FormatLocaleFile(file,"Text font: %s\n\n",resource_info->text_font);
   2048   /*
   2049     Write info about the undo cache to a file.
   2050   */
   2051   bytes=0;
   2052   for (levels=0; undo_image != (Image *) NULL; levels++)
   2053   {
   2054     number_pixels=undo_image->list->columns*undo_image->list->rows;
   2055     bytes+=number_pixels*sizeof(PixelInfo);
   2056     undo_image=GetPreviousImageInList(undo_image);
   2057   }
   2058   (void) FormatLocaleFile(file,"Undo Edit Cache\n  levels: %u\n",levels);
   2059   (void) FormatLocaleFile(file,"  bytes: %.20gmb\n",(double)
   2060     ((bytes+(1 << 19)) >> 20));
   2061   (void) FormatLocaleFile(file,"  limit: %.20gmb\n\n",(double)
   2062     resource_info->undo_cache);
   2063   /*
   2064     Write info about the image to a file.
   2065   */
   2066   (void) IdentifyImage(image,file,MagickTrue,exception);
   2067   (void) fclose(file);
   2068   text=FileToString(filename,~0UL,exception);
   2069   (void) RelinquishUniqueFileResource(filename);
   2070   if (text == (char *) NULL)
   2071     {
   2072       XNoticeWidget(display,windows,"MemoryAllocationFailed",
   2073         "UnableToDisplayImageInfo");
   2074       return;
   2075     }
   2076   textlist=StringToList(text);
   2077   if (textlist != (char **) NULL)
   2078     {
   2079       char
   2080         title[MagickPathExtent];
   2081 
   2082       /*
   2083         Display information about the image in the Text View widget.
   2084       */
   2085       (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
   2086       (void) FormatLocaleString(title,MagickPathExtent,"Image Info: %s",
   2087         image->filename);
   2088       XTextViewWidget(display,resource_info,windows,MagickTrue,title,
   2089         (char const **) textlist);
   2090       for (i=0; textlist[i] != (char *) NULL; i++)
   2091         textlist[i]=DestroyString(textlist[i]);
   2092       textlist=(char **) RelinquishMagickMemory(textlist);
   2093     }
   2094   text=DestroyString(text);
   2095 }
   2096 
   2097 /*
   2099 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2100 %                                                                             %
   2101 %                                                                             %
   2102 %                                                                             %
   2103 +     X D i t h e r I m a g e                                                 %
   2104 %                                                                             %
   2105 %                                                                             %
   2106 %                                                                             %
   2107 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2108 %
   2109 %  XDitherImage() dithers the reference image as required by the HP Color
   2110 %  Recovery algorithm.  The color values are quantized to 3 bits of red and
   2111 %  green, and 2 bits of blue (3/3/2) and can be used as indices into a 8-bit X
   2112 %  standard colormap.
   2113 %
   2114 %  The format of the XDitherImage method is:
   2115 %
   2116 %      void XDitherImage(Image *image,XImage *ximage,ExceptionInfo *exception)
   2117 %
   2118 %  A description of each parameter follows:
   2119 %
   2120 %    o image: the image.
   2121 %
   2122 %    o ximage: Specifies a pointer to a XImage structure;  returned from
   2123 %      XCreateImage.
   2124 %
   2125 %    o exception: return any errors or warnings in this structure.
   2126 %
   2127 */
   2128 static void XDitherImage(Image *image,XImage *ximage,ExceptionInfo *exception)
   2129 {
   2130   static const short int
   2131     dither_red[2][16]=
   2132     {
   2133       {-16,  4, -1, 11,-14,  6, -3,  9,-15,  5, -2, 10,-13,  7, -4,  8},
   2134       { 15, -5,  0,-12, 13, -7,  2,-10, 14, -6,  1,-11, 12, -8,  3, -9}
   2135     },
   2136     dither_green[2][16]=
   2137     {
   2138       { 11,-15,  7, -3,  8,-14,  4, -2, 10,-16,  6, -4,  9,-13,  5, -1},
   2139       {-12, 14, -8,  2, -9, 13, -5,  1,-11, 15, -7,  3,-10, 12, -6,  0}
   2140     },
   2141     dither_blue[2][16]=
   2142     {
   2143       { -3,  9,-13,  7, -1, 11,-15,  5, -4,  8,-14,  6, -2, 10,-16,  4},
   2144       {  2,-10, 12, -8,  0,-12, 14, -6,  3, -9, 13, -7,  1,-11, 15, -5}
   2145     };
   2146 
   2147   CacheView
   2148     *image_view;
   2149 
   2150   int
   2151     value,
   2152     y;
   2153 
   2154   PixelInfo
   2155     color;
   2156 
   2157   register char
   2158     *q;
   2159 
   2160   register const Quantum
   2161     *p;
   2162 
   2163   register int
   2164     i,
   2165     j,
   2166     x;
   2167 
   2168   unsigned int
   2169     scanline_pad;
   2170 
   2171   register size_t
   2172     pixel;
   2173 
   2174   unsigned char
   2175     *blue_map[2][16],
   2176     *green_map[2][16],
   2177     *red_map[2][16];
   2178 
   2179   /*
   2180     Allocate and initialize dither maps.
   2181   */
   2182   for (i=0; i < 2; i++)
   2183     for (j=0; j < 16; j++)
   2184     {
   2185       red_map[i][j]=(unsigned char *) AcquireQuantumMemory(256UL,
   2186         sizeof(*red_map));
   2187       green_map[i][j]=(unsigned char *) AcquireQuantumMemory(256UL,
   2188         sizeof(*green_map));
   2189       blue_map[i][j]=(unsigned char *) AcquireQuantumMemory(256UL,
   2190         sizeof(*blue_map));
   2191       if ((red_map[i][j] == (unsigned char *) NULL) ||
   2192           (green_map[i][j] == (unsigned char *) NULL) ||
   2193           (blue_map[i][j] == (unsigned char *) NULL))
   2194         {
   2195           ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed",
   2196             image->filename);
   2197           return;
   2198         }
   2199     }
   2200   /*
   2201     Initialize dither tables.
   2202   */
   2203   for (i=0; i < 2; i++)
   2204     for (j=0; j < 16; j++)
   2205       for (x=0; x < 256; x++)
   2206       {
   2207         value=x-16;
   2208         if (x < 48)
   2209           value=x/2+8;
   2210         value+=dither_red[i][j];
   2211         red_map[i][j][x]=(unsigned char)
   2212           ((value < 0) ? 0 : (value > 255) ? 255 : value);
   2213         value=x-16;
   2214         if (x < 48)
   2215           value=x/2+8;
   2216         value+=dither_green[i][j];
   2217         green_map[i][j][x]=(unsigned char)
   2218           ((value < 0) ? 0 : (value > 255) ? 255 : value);
   2219         value=x-32;
   2220         if (x < 112)
   2221           value=x/2+24;
   2222         value+=((size_t) dither_blue[i][j] << 1);
   2223         blue_map[i][j][x]=(unsigned char)
   2224           ((value < 0) ? 0 : (value > 255) ? 255 : value);
   2225       }
   2226   /*
   2227     Dither image.
   2228   */
   2229   scanline_pad=(unsigned int) (ximage->bytes_per_line-
   2230     ((size_t) (ximage->width*ximage->bits_per_pixel) >> 3));
   2231   i=0;
   2232   j=0;
   2233   q=ximage->data;
   2234   image_view=AcquireVirtualCacheView(image,exception);
   2235   for (y=0; y < (int) image->rows; y++)
   2236   {
   2237     p=GetCacheViewVirtualPixels(image_view,0,(ssize_t) y,image->columns,1,
   2238       exception);
   2239     if (p == (const Quantum *) NULL)
   2240       break;
   2241     for (x=0; x < (int) image->columns; x++)
   2242     {
   2243       color.red=(double) ClampToQuantum((double) (red_map[i][j][
   2244         (int) ScaleQuantumToChar(GetPixelRed(image,p))] << 8));
   2245       color.green=(double) ClampToQuantum((double) (green_map[i][j][
   2246         (int) ScaleQuantumToChar(GetPixelGreen(image,p))] << 8));
   2247       color.blue=(double) ClampToQuantum((double) (blue_map[i][j][
   2248         (int) ScaleQuantumToChar(GetPixelBlue(image,p))] << 8));
   2249       pixel=(size_t) (((size_t) color.red & 0xe0) |
   2250         (((size_t) color.green & 0xe0) >> 3) |
   2251         (((size_t) color.blue & 0xc0) >> 6));
   2252       *q++=(char) pixel;
   2253       p+=GetPixelChannels(image);
   2254       j++;
   2255       if (j == 16)
   2256         j=0;
   2257     }
   2258     q+=scanline_pad;
   2259     i++;
   2260     if (i == 2)
   2261       i=0;
   2262   }
   2263   image_view=DestroyCacheView(image_view);
   2264   /*
   2265     Free allocated memory.
   2266   */
   2267   for (i=0; i < 2; i++)
   2268     for (j=0; j < 16; j++)
   2269     {
   2270       green_map[i][j]=(unsigned char *) RelinquishMagickMemory(green_map[i][j]);
   2271       blue_map[i][j]=(unsigned char *) RelinquishMagickMemory(blue_map[i][j]);
   2272       red_map[i][j]=(unsigned char *) RelinquishMagickMemory(red_map[i][j]);
   2273     }
   2274 }
   2275 
   2276 /*
   2278 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2279 %                                                                             %
   2280 %                                                                             %
   2281 %                                                                             %
   2282 %   X D r a w I m a g e                                                       %
   2283 %                                                                             %
   2284 %                                                                             %
   2285 %                                                                             %
   2286 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2287 %
   2288 %  XDrawImage() draws a line on the image.
   2289 %
   2290 %  The format of the XDrawImage method is:
   2291 %
   2292 %    MagickBooleanType XDrawImage(Display *display,const XPixelInfo *pixel,
   2293 %      XDrawInfo *draw_info,Image *image,ExceptionInfo *exception)
   2294 %
   2295 %  A description of each parameter follows:
   2296 %
   2297 %    o display: Specifies a connection to an X server;  returned from
   2298 %      XOpenDisplay.
   2299 %
   2300 %    o pixel: Specifies a pointer to a XPixelInfo structure.
   2301 %
   2302 %    o draw_info: Specifies a pointer to a XDrawInfo structure.
   2303 %
   2304 %    o image: the image.
   2305 %
   2306 %    o exception: return any errors or warnings in this structure.
   2307 %
   2308 */
   2309 MagickPrivate MagickBooleanType XDrawImage(Display *display,
   2310   const XPixelInfo *pixel,XDrawInfo *draw_info,Image *image,
   2311   ExceptionInfo *exception)
   2312 {
   2313   CacheView
   2314     *draw_view;
   2315 
   2316   GC
   2317     draw_context;
   2318 
   2319   Image
   2320     *draw_image;
   2321 
   2322   int
   2323     x,
   2324     y;
   2325 
   2326   PixelTrait
   2327     alpha_trait;
   2328 
   2329   Pixmap
   2330     draw_pixmap;
   2331 
   2332   unsigned int
   2333     depth,
   2334     height,
   2335     width;
   2336 
   2337   Window
   2338     root_window;
   2339 
   2340   XGCValues
   2341     context_values;
   2342 
   2343   XImage
   2344     *draw_ximage;
   2345 
   2346   /*
   2347     Initialize drawd image.
   2348   */
   2349   assert(display != (Display *) NULL);
   2350   assert(pixel != (XPixelInfo *) NULL);
   2351   assert(draw_info != (XDrawInfo *) NULL);
   2352   assert(image != (Image *) NULL);
   2353   if (image->debug != MagickFalse)
   2354     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   2355   /*
   2356     Initialize drawd pixmap.
   2357   */
   2358   root_window=XRootWindow(display,XDefaultScreen(display));
   2359   depth=(unsigned int) XDefaultDepth(display,XDefaultScreen(display));
   2360   draw_pixmap=XCreatePixmap(display,root_window,draw_info->width,
   2361     draw_info->height,depth);
   2362   if (draw_pixmap == (Pixmap) NULL)
   2363     return(MagickFalse);
   2364   /*
   2365     Initialize graphics info.
   2366   */
   2367   context_values.background=(size_t) (~0);
   2368   context_values.foreground=0;
   2369   context_values.line_width=(int) draw_info->line_width;
   2370   draw_context=XCreateGC(display,root_window,(size_t)
   2371     (GCBackground | GCForeground | GCLineWidth),&context_values);
   2372   if (draw_context == (GC) NULL)
   2373     return(MagickFalse);
   2374   /*
   2375     Clear pixmap.
   2376   */
   2377   (void) XFillRectangle(display,draw_pixmap,draw_context,0,0,draw_info->width,
   2378     draw_info->height);
   2379   /*
   2380     Draw line to pixmap.
   2381   */
   2382   (void) XSetBackground(display,draw_context,0);
   2383   (void) XSetForeground(display,draw_context,(size_t) (~0));
   2384   if (draw_info->stipple !=  (Pixmap) NULL)
   2385     {
   2386       (void) XSetFillStyle(display,draw_context,FillOpaqueStippled);
   2387       (void) XSetStipple(display,draw_context,draw_info->stipple);
   2388     }
   2389   switch (draw_info->element)
   2390   {
   2391     case PointElement:
   2392     default:
   2393     {
   2394       (void) XDrawLines(display,draw_pixmap,draw_context,
   2395         draw_info->coordinate_info,(int) draw_info->number_coordinates,
   2396         CoordModeOrigin);
   2397       break;
   2398     }
   2399     case LineElement:
   2400     {
   2401       (void) XDrawLine(display,draw_pixmap,draw_context,draw_info->line_info.x1,
   2402         draw_info->line_info.y1,draw_info->line_info.x2,
   2403         draw_info->line_info.y2);
   2404       break;
   2405     }
   2406     case RectangleElement:
   2407     {
   2408       (void) XDrawRectangle(display,draw_pixmap,draw_context,
   2409         (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y,
   2410         (unsigned int) draw_info->rectangle_info.width,
   2411         (unsigned int) draw_info->rectangle_info.height);
   2412       break;
   2413     }
   2414     case FillRectangleElement:
   2415     {
   2416       (void) XFillRectangle(display,draw_pixmap,draw_context,
   2417         (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y,
   2418         (unsigned int) draw_info->rectangle_info.width,
   2419         (unsigned int) draw_info->rectangle_info.height);
   2420       break;
   2421     }
   2422     case CircleElement:
   2423     case EllipseElement:
   2424     {
   2425       (void) XDrawArc(display,draw_pixmap,draw_context,
   2426         (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y,
   2427         (unsigned int) draw_info->rectangle_info.width,
   2428         (unsigned int) draw_info->rectangle_info.height,0,360*64);
   2429       break;
   2430     }
   2431     case FillCircleElement:
   2432     case FillEllipseElement:
   2433     {
   2434       (void) XFillArc(display,draw_pixmap,draw_context,
   2435         (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y,
   2436         (unsigned int) draw_info->rectangle_info.width,
   2437         (unsigned int) draw_info->rectangle_info.height,0,360*64);
   2438       break;
   2439     }
   2440     case PolygonElement:
   2441     {
   2442       XPoint
   2443         *coordinate_info;
   2444 
   2445       coordinate_info=draw_info->coordinate_info;
   2446       (void) XDrawLines(display,draw_pixmap,draw_context,coordinate_info,
   2447         (int) draw_info->number_coordinates,CoordModeOrigin);
   2448       (void) XDrawLine(display,draw_pixmap,draw_context,
   2449         coordinate_info[draw_info->number_coordinates-1].x,
   2450         coordinate_info[draw_info->number_coordinates-1].y,
   2451         coordinate_info[0].x,coordinate_info[0].y);
   2452       break;
   2453     }
   2454     case FillPolygonElement:
   2455     {
   2456       (void) XFillPolygon(display,draw_pixmap,draw_context,
   2457         draw_info->coordinate_info,(int) draw_info->number_coordinates,Complex,
   2458         CoordModeOrigin);
   2459       break;
   2460     }
   2461   }
   2462   (void) XFreeGC(display,draw_context);
   2463   /*
   2464     Initialize X image.
   2465   */
   2466   draw_ximage=XGetImage(display,draw_pixmap,0,0,draw_info->width,
   2467     draw_info->height,AllPlanes,ZPixmap);
   2468   if (draw_ximage == (XImage *) NULL)
   2469     return(MagickFalse);
   2470   (void) XFreePixmap(display,draw_pixmap);
   2471   /*
   2472     Initialize draw image.
   2473   */
   2474   draw_image=AcquireImage((ImageInfo *) NULL,exception);
   2475   if (draw_image == (Image *) NULL)
   2476     return(MagickFalse);
   2477   draw_image->columns=draw_info->width;
   2478   draw_image->rows=draw_info->height;
   2479   /*
   2480     Transfer drawn X image to image.
   2481   */
   2482   width=(unsigned int) image->columns;
   2483   height=(unsigned int) image->rows;
   2484   x=0;
   2485   y=0;
   2486   (void) XParseGeometry(draw_info->geometry,&x,&y,&width,&height);
   2487   (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,(ssize_t) x,
   2488     (ssize_t) y,&draw_image->background_color,exception);
   2489   if (SetImageStorageClass(draw_image,DirectClass,exception) == MagickFalse)
   2490     return(MagickFalse);
   2491   draw_image->alpha_trait=BlendPixelTrait;
   2492   draw_view=AcquireAuthenticCacheView(draw_image,exception);
   2493   for (y=0; y < (int) draw_image->rows; y++)
   2494   {
   2495     register int
   2496       x;
   2497 
   2498     register Quantum
   2499       *magick_restrict q;
   2500 
   2501     q=QueueCacheViewAuthenticPixels(draw_view,0,(ssize_t) y,draw_image->columns,
   2502       1,exception);
   2503     if (q == (Quantum *) NULL)
   2504       break;
   2505     for (x=0; x < (int) draw_image->columns; x++)
   2506     {
   2507       if (XGetPixel(draw_ximage,x,y) == 0)
   2508         {
   2509           /*
   2510             Set this pixel to the background color.
   2511           */
   2512           SetPixelViaPixelInfo(draw_image,&draw_image->background_color,q);
   2513           SetPixelAlpha(draw_image,(Quantum) (draw_info->stencil ==
   2514             OpaqueStencil ? TransparentAlpha : OpaqueAlpha),q);
   2515         }
   2516       else
   2517         {
   2518           /*
   2519             Set this pixel to the pen color.
   2520           */
   2521           SetPixelRed(draw_image,ScaleShortToQuantum(
   2522             pixel->pen_color.red),q);
   2523           SetPixelGreen(draw_image,ScaleShortToQuantum(
   2524             pixel->pen_color.green),q);
   2525           SetPixelBlue(draw_image,ScaleShortToQuantum(
   2526             pixel->pen_color.blue),q);
   2527           SetPixelAlpha(draw_image,(Quantum) (draw_info->stencil ==
   2528             OpaqueStencil ? OpaqueAlpha : TransparentAlpha),q);
   2529         }
   2530       q+=GetPixelChannels(draw_image);
   2531     }
   2532     if (SyncCacheViewAuthenticPixels(draw_view,exception) == MagickFalse)
   2533       break;
   2534   }
   2535   draw_view=DestroyCacheView(draw_view);
   2536   XDestroyImage(draw_ximage);
   2537   /*
   2538     Determine draw geometry.
   2539   */
   2540   (void) XParseGeometry(draw_info->geometry,&x,&y,&width,&height);
   2541   if ((width != (unsigned int) draw_image->columns) ||
   2542       (height != (unsigned int) draw_image->rows))
   2543     {
   2544       char
   2545         image_geometry[MagickPathExtent];
   2546 
   2547       /*
   2548         Scale image.
   2549       */
   2550       (void) FormatLocaleString(image_geometry,MagickPathExtent,"%ux%u",
   2551         width,height);
   2552       (void) TransformImage(&draw_image,(char *) NULL,image_geometry,
   2553         exception);
   2554     }
   2555   if (draw_info->degrees != 0.0)
   2556     {
   2557       Image
   2558         *rotate_image;
   2559 
   2560       int
   2561         rotations;
   2562 
   2563       double
   2564         normalized_degrees;
   2565 
   2566       /*
   2567         Rotate image.
   2568       */
   2569       rotate_image=RotateImage(draw_image,draw_info->degrees,exception);
   2570       if (rotate_image == (Image *) NULL)
   2571         return(MagickFalse);
   2572       draw_image=DestroyImage(draw_image);
   2573       draw_image=rotate_image;
   2574       /*
   2575         Annotation is relative to the degree of rotation.
   2576       */
   2577       normalized_degrees=draw_info->degrees;
   2578       while (normalized_degrees < -45.0)
   2579         normalized_degrees+=360.0;
   2580       for (rotations=0; normalized_degrees > 45.0; rotations++)
   2581         normalized_degrees-=90.0;
   2582       switch (rotations % 4)
   2583       {
   2584         default:
   2585         case 0:
   2586           break;
   2587         case 1:
   2588         {
   2589           /*
   2590             Rotate 90 degrees.
   2591           */
   2592           x=x-(int) draw_image->columns/2;
   2593           y=y+(int) draw_image->columns/2;
   2594           break;
   2595         }
   2596         case 2:
   2597         {
   2598           /*
   2599             Rotate 180 degrees.
   2600           */
   2601           x=x-(int) draw_image->columns;
   2602           break;
   2603         }
   2604         case 3:
   2605         {
   2606           /*
   2607             Rotate 270 degrees.
   2608           */
   2609           x=x-(int) draw_image->columns/2;
   2610           y=y-(int) (draw_image->rows-(draw_image->columns/2));
   2611           break;
   2612         }
   2613       }
   2614     }
   2615   /*
   2616     Composite text onto the image.
   2617   */
   2618   draw_view=AcquireAuthenticCacheView(draw_image,exception);
   2619   for (y=0; y < (int) draw_image->rows; y++)
   2620   {
   2621     register int
   2622       x;
   2623 
   2624     register Quantum
   2625       *magick_restrict q;
   2626 
   2627     q=GetCacheViewAuthenticPixels(draw_view,0,(ssize_t) y,draw_image->columns,1,
   2628       exception);
   2629     if (q == (Quantum *) NULL)
   2630       break;
   2631     for (x=0; x < (int) draw_image->columns; x++)
   2632     {
   2633       if (GetPixelAlpha(image,q) != TransparentAlpha)
   2634         SetPixelAlpha(draw_image,OpaqueAlpha,q);
   2635       q+=GetPixelChannels(draw_image);
   2636     }
   2637     if (SyncCacheViewAuthenticPixels(draw_view,exception) == MagickFalse)
   2638       break;
   2639   }
   2640   draw_view=DestroyCacheView(draw_view);
   2641   (void) XParseGeometry(draw_info->geometry,&x,&y,&width,&height);
   2642   if (draw_info->stencil == TransparentStencil)
   2643     (void) CompositeImage(image,draw_image,CopyAlphaCompositeOp,MagickTrue,
   2644       (ssize_t) x,(ssize_t) y,exception);
   2645   else
   2646     {
   2647       alpha_trait=image->alpha_trait;
   2648       (void) CompositeImage(image,draw_image,OverCompositeOp,MagickTrue,
   2649         (ssize_t) x,(ssize_t) y,exception);
   2650       image->alpha_trait=alpha_trait;
   2651     }
   2652   draw_image=DestroyImage(draw_image);
   2653   return(MagickTrue);
   2654 }
   2655 
   2656 /*
   2658 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2659 %                                                                             %
   2660 %                                                                             %
   2661 %                                                                             %
   2662 %   X E r r o r                                                               %
   2663 %                                                                             %
   2664 %                                                                             %
   2665 %                                                                             %
   2666 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2667 %
   2668 %  XError() ignores BadWindow errors for XQueryTree and XGetWindowAttributes,
   2669 %  and ignores BadDrawable errors for XGetGeometry, and ignores BadValue errors
   2670 %  for XQueryColor.  It returns MagickFalse in those cases.  Otherwise it
   2671 %  returns True.
   2672 %
   2673 %  The format of the XError function is:
   2674 %
   2675 %      int XError(display,error)
   2676 %
   2677 %  A description of each parameter follows:
   2678 %
   2679 %    o display: Specifies a pointer to the Display structure;  returned from
   2680 %      XOpenDisplay.
   2681 %
   2682 %    o error: Specifies the error event.
   2683 %
   2684 */
   2685 
   2686 #if defined(__cplusplus) || defined(c_plusplus)
   2687 extern "C" {
   2688 #endif
   2689 
   2690 MagickExport int XError(Display *display,XErrorEvent *error)
   2691 {
   2692   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   2693   assert(display != (Display *) NULL);
   2694   assert(error != (XErrorEvent *) NULL);
   2695   xerror_alert=MagickTrue;
   2696   switch (error->request_code)
   2697   {
   2698     case X_GetGeometry:
   2699     {
   2700       if ((int) error->error_code == BadDrawable)
   2701         return(MagickFalse);
   2702       break;
   2703     }
   2704     case X_GetWindowAttributes:
   2705     case X_QueryTree:
   2706     {
   2707       if ((int) error->error_code == BadWindow)
   2708         return(MagickFalse);
   2709       break;
   2710     }
   2711     case X_QueryColors:
   2712     {
   2713       if ((int) error->error_code == BadValue)
   2714         return(MagickFalse);
   2715       break;
   2716     }
   2717   }
   2718   return(MagickTrue);
   2719 }
   2720 
   2721 #if defined(__cplusplus) || defined(c_plusplus)
   2722 }
   2723 #endif
   2724 
   2725 /*
   2727 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2728 %                                                                             %
   2729 %                                                                             %
   2730 %                                                                             %
   2731 %   X F r e e R e s o u r c e s                                               %
   2732 %                                                                             %
   2733 %                                                                             %
   2734 %                                                                             %
   2735 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2736 %
   2737 %  XFreeResources() frees X11 resources.
   2738 %
   2739 %  The format of the XFreeResources method is:
   2740 %
   2741 %      void XFreeResources(Display *display,XVisualInfo *visual_info,
   2742 %        XStandardColormap *map_info,XPixelInfo *pixel,XFontStruct *font_info,
   2743 %        XResourceInfo *resource_info,XWindowInfo *window_info)
   2744 %        resource_info,window_info)
   2745 %
   2746 %  A description of each parameter follows:
   2747 %
   2748 %    o display: Specifies a connection to an X server; returned from
   2749 %      XOpenDisplay.
   2750 %
   2751 %    o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
   2752 %      returned from XGetVisualInfo.
   2753 %
   2754 %    o map_info: If map_type is specified, this structure is initialized
   2755 %      with info from the Standard Colormap.
   2756 %
   2757 %    o pixel: Specifies a pointer to a XPixelInfo structure.
   2758 %
   2759 %    o font_info: Specifies a pointer to a XFontStruct structure.
   2760 %
   2761 %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
   2762 %
   2763 %    o window_info: Specifies a pointer to a X11 XWindowInfo structure.
   2764 %
   2765 */
   2766 MagickPrivate void XFreeResources(Display *display,XVisualInfo *visual_info,
   2767   XStandardColormap *map_info,XPixelInfo *pixel,XFontStruct *font_info,
   2768   XResourceInfo *resource_info,XWindowInfo *window_info)
   2769 {
   2770   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   2771   assert(display != (Display *) NULL);
   2772   assert(resource_info != (XResourceInfo *) NULL);
   2773   if (window_info != (XWindowInfo *) NULL)
   2774     {
   2775       /*
   2776         Free X image.
   2777       */
   2778       if (window_info->ximage != (XImage *) NULL)
   2779         XDestroyImage(window_info->ximage);
   2780       if (window_info->id != (Window) NULL)
   2781         {
   2782           /*
   2783             Free destroy window and free cursors.
   2784           */
   2785           if (window_info->id != XRootWindow(display,visual_info->screen))
   2786             (void) XDestroyWindow(display,window_info->id);
   2787           if (window_info->annotate_context != (GC) NULL)
   2788             (void) XFreeGC(display,window_info->annotate_context);
   2789           if (window_info->highlight_context != (GC) NULL)
   2790             (void) XFreeGC(display,window_info->highlight_context);
   2791           if (window_info->widget_context != (GC) NULL)
   2792             (void) XFreeGC(display,window_info->widget_context);
   2793           if (window_info->cursor != (Cursor) NULL)
   2794             (void) XFreeCursor(display,window_info->cursor);
   2795           window_info->cursor=(Cursor) NULL;
   2796           if (window_info->busy_cursor != (Cursor) NULL)
   2797             (void) XFreeCursor(display,window_info->busy_cursor);
   2798           window_info->busy_cursor=(Cursor) NULL;
   2799         }
   2800     }
   2801   /*
   2802     Free font.
   2803   */
   2804   if (font_info != (XFontStruct *) NULL)
   2805     {
   2806       (void) XFreeFont(display,font_info);
   2807       font_info=(XFontStruct *) NULL;
   2808     }
   2809   if (map_info != (XStandardColormap *) NULL)
   2810     {
   2811       /*
   2812         Free X Standard Colormap.
   2813       */
   2814       if (resource_info->map_type == (char *) NULL)
   2815         (void) XFreeStandardColormap(display,visual_info,map_info,pixel);
   2816       (void) XFree((void *) map_info);
   2817     }
   2818   /*
   2819     Free X visual info.
   2820   */
   2821   if (visual_info != (XVisualInfo *) NULL)
   2822     (void) XFree((void *) visual_info);
   2823   if (resource_info->close_server != MagickFalse)
   2824     (void) XCloseDisplay(display);
   2825 }
   2826 
   2827 /*
   2829 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2830 %                                                                             %
   2831 %                                                                             %
   2832 %                                                                             %
   2833 %   X F r e e S t a n d a r d C o l o r m a p                                 %
   2834 %                                                                             %
   2835 %                                                                             %
   2836 %                                                                             %
   2837 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2838 %
   2839 %  XFreeStandardColormap() frees an X11 colormap.
   2840 %
   2841 %  The format of the XFreeStandardColormap method is:
   2842 %
   2843 %      void XFreeStandardColormap(Display *display,
   2844 %        const XVisualInfo *visual_info,XStandardColormap *map_info,
   2845 %        XPixelInfo *pixel)
   2846 %
   2847 %  A description of each parameter follows:
   2848 %
   2849 %    o display: Specifies a connection to an X server; returned from
   2850 %      XOpenDisplay.
   2851 %
   2852 %    o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
   2853 %      returned from XGetVisualInfo.
   2854 %
   2855 %    o map_info: If map_type is specified, this structure is initialized
   2856 %      with info from the Standard Colormap.
   2857 %
   2858 %    o pixel: Specifies a pointer to a XPixelInfo structure.
   2859 %
   2860 */
   2861 MagickPrivate void XFreeStandardColormap(Display *display,
   2862   const XVisualInfo *visual_info,XStandardColormap *map_info,XPixelInfo *pixel)
   2863 {
   2864   /*
   2865     Free colormap.
   2866   */
   2867   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   2868   assert(display != (Display *) NULL);
   2869   assert(visual_info != (XVisualInfo *) NULL);
   2870   assert(map_info != (XStandardColormap *) NULL);
   2871   (void) XFlush(display);
   2872   if (map_info->colormap != (Colormap) NULL)
   2873     {
   2874       if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
   2875         (void) XFreeColormap(display,map_info->colormap);
   2876       else
   2877         if (pixel != (XPixelInfo *) NULL)
   2878           if ((visual_info->klass != TrueColor) &&
   2879               (visual_info->klass != DirectColor))
   2880             (void) XFreeColors(display,map_info->colormap,pixel->pixels,
   2881               (int) pixel->colors,0);
   2882     }
   2883   map_info->colormap=(Colormap) NULL;
   2884   if (pixel != (XPixelInfo *) NULL)
   2885     {
   2886       if (pixel->pixels != (unsigned long *) NULL)
   2887         pixel->pixels=(unsigned long *) RelinquishMagickMemory(pixel->pixels);
   2888       pixel->pixels=(unsigned long *) NULL;
   2889     }
   2890 }
   2891 
   2892 /*
   2894 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2895 %                                                                             %
   2896 %                                                                             %
   2897 %                                                                             %
   2898 %   X G e t A n n o t a t e I n f o                                           %
   2899 %                                                                             %
   2900 %                                                                             %
   2901 %                                                                             %
   2902 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2903 %
   2904 %  XGetAnnotateInfo() initializes the AnnotateInfo structure.
   2905 %
   2906 %  The format of the XGetAnnotateInfo method is:
   2907 %
   2908 %      void XGetAnnotateInfo(XAnnotateInfo *annotate_info)
   2909 %
   2910 %  A description of each parameter follows:
   2911 %
   2912 %    o annotate_info: Specifies a pointer to a XAnnotateInfo structure.
   2913 %
   2914 */
   2915 MagickPrivate void XGetAnnotateInfo(XAnnotateInfo *annotate_info)
   2916 {
   2917   /*
   2918     Initialize annotate structure.
   2919   */
   2920   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   2921   assert(annotate_info != (XAnnotateInfo *) NULL);
   2922   annotate_info->x=0;
   2923   annotate_info->y=0;
   2924   annotate_info->width=0;
   2925   annotate_info->height=0;
   2926   annotate_info->stencil=ForegroundStencil;
   2927   annotate_info->degrees=0.0;
   2928   annotate_info->font_info=(XFontStruct *) NULL;
   2929   annotate_info->text=(char *) NULL;
   2930   *annotate_info->geometry='\0';
   2931   annotate_info->previous=(XAnnotateInfo *) NULL;
   2932   annotate_info->next=(XAnnotateInfo *) NULL;
   2933   (void) XSupportsLocale();
   2934   (void) XSetLocaleModifiers("");
   2935 }
   2936 
   2937 /*
   2939 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2940 %                                                                             %
   2941 %                                                                             %
   2942 %                                                                             %
   2943 %   X G e t M a p I n f o                                                     %
   2944 %                                                                             %
   2945 %                                                                             %
   2946 %                                                                             %
   2947 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   2948 %
   2949 %  XGetMapInfo() initializes the XStandardColormap structure.
   2950 %
   2951 %  The format of the XStandardColormap method is:
   2952 %
   2953 %      void XGetMapInfo(const XVisualInfo *visual_info,const Colormap colormap,
   2954 %        XStandardColormap *map_info)
   2955 %
   2956 %  A description of each parameter follows:
   2957 %
   2958 %    o colormap: Specifies the ID of the X server colormap.
   2959 %
   2960 %    o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
   2961 %      returned from XGetVisualInfo.
   2962 %
   2963 %    o map_info: Specifies a pointer to a X11 XStandardColormap structure.
   2964 %
   2965 */
   2966 MagickPrivate void XGetMapInfo(const XVisualInfo *visual_info,
   2967   const Colormap colormap,XStandardColormap *map_info)
   2968 {
   2969   /*
   2970     Initialize map info.
   2971   */
   2972   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   2973   assert(visual_info != (XVisualInfo *) NULL);
   2974   assert(map_info != (XStandardColormap *) NULL);
   2975   map_info->colormap=colormap;
   2976   map_info->red_max=visual_info->red_mask;
   2977   map_info->red_mult=(size_t) (map_info->red_max != 0 ? 1 : 0);
   2978   if (map_info->red_max != 0)
   2979     while ((map_info->red_max & 0x01) == 0)
   2980     {
   2981       map_info->red_max>>=1;
   2982       map_info->red_mult<<=1;
   2983     }
   2984   map_info->green_max=visual_info->green_mask;
   2985   map_info->green_mult=(size_t) (map_info->green_max != 0 ? 1 : 0);
   2986   if (map_info->green_max != 0)
   2987     while ((map_info->green_max & 0x01) == 0)
   2988     {
   2989       map_info->green_max>>=1;
   2990       map_info->green_mult<<=1;
   2991     }
   2992   map_info->blue_max=visual_info->blue_mask;
   2993   map_info->blue_mult=(size_t) (map_info->blue_max != 0 ? 1 : 0);
   2994   if (map_info->blue_max != 0)
   2995     while ((map_info->blue_max & 0x01) == 0)
   2996     {
   2997       map_info->blue_max>>=1;
   2998       map_info->blue_mult<<=1;
   2999     }
   3000   map_info->base_pixel=0;
   3001 }
   3002 
   3003 /*
   3005 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3006 %                                                                             %
   3007 %                                                                             %
   3008 %                                                                             %
   3009 %   X G e t P i x e l I n f o                                                 %
   3010 %                                                                             %
   3011 %                                                                             %
   3012 %                                                                             %
   3013 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3014 %
   3015 %  XGetPixelInfo() initializes the PixelInfo structure.
   3016 %
   3017 %  The format of the XGetPixelInfo method is:
   3018 %
   3019 %      void XGetPixelInfo(Display *display,const XVisualInfo *visual_info,
   3020 %        const XStandardColormap *map_info,const XResourceInfo *resource_info,
   3021 %        Image *image,XPixelInfo *pixel)
   3022 %        pixel)
   3023 %
   3024 %  A description of each parameter follows:
   3025 %
   3026 %    o display: Specifies a connection to an X server; returned from
   3027 %      XOpenDisplay.
   3028 %
   3029 %    o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
   3030 %      returned from XGetVisualInfo.
   3031 %
   3032 %    o map_info: If map_type is specified, this structure is initialized
   3033 %      with info from the Standard Colormap.
   3034 %
   3035 %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
   3036 %
   3037 %    o image: the image.
   3038 %
   3039 %    o pixel: Specifies a pointer to a XPixelInfo structure.
   3040 %
   3041 */
   3042 MagickPrivate void XGetPixelInfo(Display *display,
   3043   const XVisualInfo *visual_info,const XStandardColormap *map_info,
   3044   const XResourceInfo *resource_info,Image *image,XPixelInfo *pixel)
   3045 {
   3046   static const char
   3047     *PenColors[MaxNumberPens]=
   3048     {
   3049       "#000000000000",  /* black */
   3050       "#00000000ffff",  /* blue */
   3051       "#0000ffffffff",  /* cyan */
   3052       "#0000ffff0000",  /* green */
   3053       "#bdbdbdbdbdbd",  /* gray */
   3054       "#ffff00000000",  /* red */
   3055       "#ffff0000ffff",  /* magenta */
   3056       "#ffffffff0000",  /* yellow */
   3057       "#ffffffffffff",  /* white */
   3058       "#bdbdbdbdbdbd",  /* gray */
   3059       "#bdbdbdbdbdbd"   /* gray */
   3060     };
   3061 
   3062   Colormap
   3063     colormap;
   3064 
   3065   extern const char
   3066     BorderColor[],
   3067     ForegroundColor[];
   3068 
   3069   register ssize_t
   3070     i;
   3071 
   3072   Status
   3073     status;
   3074 
   3075   unsigned int
   3076     packets;
   3077 
   3078   /*
   3079     Initialize pixel info.
   3080   */
   3081   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   3082   assert(display != (Display *) NULL);
   3083   assert(visual_info != (XVisualInfo *) NULL);
   3084   assert(map_info != (XStandardColormap *) NULL);
   3085   assert(resource_info != (XResourceInfo *) NULL);
   3086   assert(pixel != (XPixelInfo *) NULL);
   3087   pixel->colors=0;
   3088   if (image != (Image *) NULL)
   3089     if (image->storage_class == PseudoClass)
   3090       pixel->colors=(ssize_t) image->colors;
   3091   packets=(unsigned int)
   3092     MagickMax((int) pixel->colors,visual_info->colormap_size)+MaxNumberPens;
   3093   if (pixel->pixels != (unsigned long *) NULL)
   3094     pixel->pixels=(unsigned long *) RelinquishMagickMemory(pixel->pixels);
   3095   pixel->pixels=(unsigned long *) AcquireQuantumMemory(packets,
   3096     sizeof(*pixel->pixels));
   3097   if (pixel->pixels == (unsigned long *) NULL)
   3098     ThrowXWindowFatalException(ResourceLimitFatalError,"UnableToGetPixelInfo",
   3099       image->filename);
   3100   /*
   3101     Set foreground color.
   3102   */
   3103   colormap=map_info->colormap;
   3104   (void) XParseColor(display,colormap,(char *) ForegroundColor,
   3105     &pixel->foreground_color);
   3106   status=XParseColor(display,colormap,resource_info->foreground_color,
   3107     &pixel->foreground_color);
   3108   if (status == False)
   3109     ThrowXWindowException(XServerError,"ColorIsNotKnownToServer",
   3110       resource_info->foreground_color);
   3111   pixel->foreground_color.pixel=
   3112     XStandardPixel(map_info,&pixel->foreground_color);
   3113   pixel->foreground_color.flags=(char) (DoRed | DoGreen | DoBlue);
   3114   /*
   3115     Set background color.
   3116   */
   3117   (void) XParseColor(display,colormap,"#d6d6d6d6d6d6",&pixel->background_color);
   3118   status=XParseColor(display,colormap,resource_info->background_color,
   3119     &pixel->background_color);
   3120   if (status == False)
   3121     ThrowXWindowException(XServerError,"ColorIsNotKnownToServer",
   3122       resource_info->background_color);
   3123   pixel->background_color.pixel=
   3124     XStandardPixel(map_info,&pixel->background_color);
   3125   pixel->background_color.flags=(char) (DoRed | DoGreen | DoBlue);
   3126   /*
   3127     Set border color.
   3128   */
   3129   (void) XParseColor(display,colormap,(char *) BorderColor,
   3130     &pixel->border_color);
   3131   status=XParseColor(display,colormap,resource_info->border_color,
   3132     &pixel->border_color);
   3133   if (status == False)
   3134     ThrowXWindowException(XServerError,"ColorIsNotKnownToServer",
   3135       resource_info->border_color);
   3136   pixel->border_color.pixel=XStandardPixel(map_info,&pixel->border_color);
   3137   pixel->border_color.flags=(char) (DoRed | DoGreen | DoBlue);
   3138   /*
   3139     Set matte color.
   3140   */
   3141   pixel->alpha_color=pixel->background_color;
   3142   if (resource_info->alpha_color != (char *) NULL)
   3143     {
   3144       /*
   3145         Matte color is specified as a X resource or command line argument.
   3146       */
   3147       status=XParseColor(display,colormap,resource_info->alpha_color,
   3148         &pixel->alpha_color);
   3149       if (status == False)
   3150         ThrowXWindowException(XServerError,"ColorIsNotKnownToServer",
   3151           resource_info->alpha_color);
   3152       pixel->alpha_color.pixel=XStandardPixel(map_info,&pixel->alpha_color);
   3153       pixel->alpha_color.flags=(char) (DoRed | DoGreen | DoBlue);
   3154     }
   3155   /*
   3156     Set highlight color.
   3157   */
   3158   pixel->highlight_color.red=(unsigned short) (((double)
   3159     pixel->alpha_color.red*ScaleQuantumToShort(HighlightModulate))/65535L+
   3160     (ScaleQuantumToShort((Quantum) (QuantumRange-HighlightModulate))));
   3161   pixel->highlight_color.green=(unsigned short) (((double)
   3162     pixel->alpha_color.green*ScaleQuantumToShort(HighlightModulate))/65535L+
   3163     (ScaleQuantumToShort((Quantum) (QuantumRange-HighlightModulate))));
   3164   pixel->highlight_color.blue=(unsigned short) (((double)
   3165     pixel->alpha_color.blue*ScaleQuantumToShort(HighlightModulate))/65535L+
   3166     (ScaleQuantumToShort((Quantum) (QuantumRange-HighlightModulate))));
   3167   pixel->highlight_color.pixel=XStandardPixel(map_info,&pixel->highlight_color);
   3168   pixel->highlight_color.flags=(char) (DoRed | DoGreen | DoBlue);
   3169   /*
   3170     Set shadow color.
   3171   */
   3172   pixel->shadow_color.red=(unsigned short) (((double)
   3173     pixel->alpha_color.red*ScaleQuantumToShort(ShadowModulate))/65535L);
   3174   pixel->shadow_color.green=(unsigned short) (((double)
   3175     pixel->alpha_color.green*ScaleQuantumToShort(ShadowModulate))/65535L);
   3176   pixel->shadow_color.blue=(unsigned short) (((double)
   3177     pixel->alpha_color.blue*ScaleQuantumToShort(ShadowModulate))/65535L);
   3178   pixel->shadow_color.pixel=XStandardPixel(map_info,&pixel->shadow_color);
   3179   pixel->shadow_color.flags=(char) (DoRed | DoGreen | DoBlue);
   3180   /*
   3181     Set depth color.
   3182   */
   3183   pixel->depth_color.red=(unsigned short) (((double)
   3184     pixel->alpha_color.red*ScaleQuantumToShort(DepthModulate))/65535L);
   3185   pixel->depth_color.green=(unsigned short) (((double)
   3186     pixel->alpha_color.green*ScaleQuantumToShort(DepthModulate))/65535L);
   3187   pixel->depth_color.blue=(unsigned short) (((double)
   3188     pixel->alpha_color.blue*ScaleQuantumToShort(DepthModulate))/65535L);
   3189   pixel->depth_color.pixel=XStandardPixel(map_info,&pixel->depth_color);
   3190   pixel->depth_color.flags=(char) (DoRed | DoGreen | DoBlue);
   3191   /*
   3192     Set trough color.
   3193   */
   3194   pixel->trough_color.red=(unsigned short) (((double)
   3195     pixel->alpha_color.red*ScaleQuantumToShort(TroughModulate))/65535L);
   3196   pixel->trough_color.green=(unsigned short) (((double)
   3197     pixel->alpha_color.green*ScaleQuantumToShort(TroughModulate))/65535L);
   3198   pixel->trough_color.blue=(unsigned short) (((double)
   3199     pixel->alpha_color.blue*ScaleQuantumToShort(TroughModulate))/65535L);
   3200   pixel->trough_color.pixel=XStandardPixel(map_info,&pixel->trough_color);
   3201   pixel->trough_color.flags=(char) (DoRed | DoGreen | DoBlue);
   3202   /*
   3203     Set pen color.
   3204   */
   3205   for (i=0; i < MaxNumberPens; i++)
   3206   {
   3207     (void) XParseColor(display,colormap,(char *) PenColors[i],
   3208       &pixel->pen_colors[i]);
   3209     status=XParseColor(display,colormap,resource_info->pen_colors[i],
   3210       &pixel->pen_colors[i]);
   3211     if (status == False)
   3212       ThrowXWindowException(XServerError,"ColorIsNotKnownToServer",
   3213         resource_info->pen_colors[i]);
   3214     pixel->pen_colors[i].pixel=XStandardPixel(map_info,&pixel->pen_colors[i]);
   3215     pixel->pen_colors[i].flags=(char) (DoRed | DoGreen | DoBlue);
   3216   }
   3217   pixel->box_color=pixel->background_color;
   3218   pixel->pen_color=pixel->foreground_color;
   3219   pixel->box_index=0;
   3220   pixel->pen_index=1;
   3221   if (image != (Image *) NULL)
   3222     {
   3223       if ((resource_info->gamma_correct != MagickFalse) &&
   3224           (image->gamma != 0.0))
   3225         {
   3226           GeometryInfo
   3227             geometry_info;
   3228 
   3229           MagickStatusType
   3230             flags;
   3231 
   3232           /*
   3233             Initialize map relative to display and image gamma.
   3234           */
   3235           flags=ParseGeometry(resource_info->display_gamma,&geometry_info);
   3236           red_gamma=geometry_info.rho;
   3237           green_gamma=geometry_info.sigma;
   3238           if ((flags & SigmaValue) == 0)
   3239             green_gamma=red_gamma;
   3240           blue_gamma=geometry_info.xi;
   3241           if ((flags & XiValue) == 0)
   3242             blue_gamma=red_gamma;
   3243           red_gamma*=image->gamma;
   3244           green_gamma*=image->gamma;
   3245           blue_gamma*=image->gamma;
   3246         }
   3247       if (image->storage_class == PseudoClass)
   3248         {
   3249           /*
   3250             Initialize pixel array for images of type PseudoClass.
   3251           */
   3252           for (i=0; i < (ssize_t) image->colors; i++)
   3253             pixel->pixels[i]=XGammaPacket(map_info,image->colormap+i);
   3254           for (i=0; i < MaxNumberPens; i++)
   3255             pixel->pixels[image->colors+i]=pixel->pen_colors[i].pixel;
   3256           pixel->colors+=MaxNumberPens;
   3257         }
   3258     }
   3259 }
   3260 
   3261 /*
   3263 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3264 %                                                                             %
   3265 %                                                                             %
   3266 %                                                                             %
   3267 %   X G e t R e s o u r c e C l a s s                                         %
   3268 %                                                                             %
   3269 %                                                                             %
   3270 %                                                                             %
   3271 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3272 %
   3273 %  XGetResourceClass() queries the X server for the specified resource name or
   3274 %  class.  If the resource name or class is not defined in the database, the
   3275 %  supplied default value is returned.
   3276 %
   3277 %  The format of the XGetResourceClass method is:
   3278 %
   3279 %      char *XGetResourceClass(XrmDatabase database,const char *client_name,
   3280 %        const char *keyword,char *resource_default)
   3281 %
   3282 %  A description of each parameter follows:
   3283 %
   3284 %    o database: Specifies a resource database; returned from
   3285 %      XrmGetStringDatabase.
   3286 %
   3287 %    o client_name:  Specifies the application name used to retrieve resource
   3288 %      info from the X server database.
   3289 %
   3290 %    o keyword: Specifies the keyword of the value being retrieved.
   3291 %
   3292 %    o resource_default: Specifies the default value to return if the query
   3293 %      fails to find the specified keyword/class.
   3294 %
   3295 */
   3296 MagickExport char *XGetResourceClass(XrmDatabase database,
   3297   const char *client_name,const char *keyword,char *resource_default)
   3298 {
   3299   char
   3300     resource_class[MagickPathExtent],
   3301     resource_name[MagickPathExtent];
   3302 
   3303   static char
   3304     *resource_type;
   3305 
   3306   Status
   3307     status;
   3308 
   3309   XrmValue
   3310     resource_value;
   3311 
   3312   if (database == (XrmDatabase) NULL)
   3313     return(resource_default);
   3314   *resource_name='\0';
   3315   *resource_class='\0';
   3316   if (keyword != (char *) NULL)
   3317     {
   3318       int
   3319         c,
   3320         k;
   3321 
   3322       /*
   3323         Initialize resource keyword and class.
   3324       */
   3325       (void) FormatLocaleString(resource_name,MagickPathExtent,"%s.%s",
   3326         client_name,keyword);
   3327       c=(int) (*client_name);
   3328       if ((c >= XK_a) && (c <= XK_z))
   3329         c-=(XK_a-XK_A);
   3330       else
   3331         if ((c >= XK_agrave) && (c <= XK_odiaeresis))
   3332           c-=(XK_agrave-XK_Agrave);
   3333         else
   3334           if ((c >= XK_oslash) && (c <= XK_thorn))
   3335             c-=(XK_oslash-XK_Ooblique);
   3336       k=(int) (*keyword);
   3337       if ((k >= XK_a) && (k <= XK_z))
   3338         k-=(XK_a-XK_A);
   3339       else
   3340         if ((k >= XK_agrave) && (k <= XK_odiaeresis))
   3341           k-=(XK_agrave-XK_Agrave);
   3342         else
   3343           if ((k >= XK_oslash) && (k <= XK_thorn))
   3344             k-=(XK_oslash-XK_Ooblique);
   3345       (void) FormatLocaleString(resource_class,MagickPathExtent,"%c%s.%c%s",c,
   3346         client_name+1,k,keyword+1);
   3347     }
   3348   status=XrmGetResource(database,resource_name,resource_class,&resource_type,
   3349     &resource_value);
   3350   if (status == False)
   3351     return(resource_default);
   3352   return(resource_value.addr);
   3353 }
   3354 
   3355 /*
   3357 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3358 %                                                                             %
   3359 %                                                                             %
   3360 %                                                                             %
   3361 %   X G e t R e s o u r c e D a t a b a s e                                   %
   3362 %                                                                             %
   3363 %                                                                             %
   3364 %                                                                             %
   3365 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3366 %
   3367 %  XGetResourceDatabase() creates a new resource database and initializes it.
   3368 %
   3369 %  The format of the XGetResourceDatabase method is:
   3370 %
   3371 %      XrmDatabase XGetResourceDatabase(Display *display,
   3372 %        const char *client_name)
   3373 %
   3374 %  A description of each parameter follows:
   3375 %
   3376 %    o database: XGetResourceDatabase() returns the database after it is
   3377 %      initialized.
   3378 %
   3379 %    o display: Specifies a connection to an X server;  returned from
   3380 %      XOpenDisplay.
   3381 %
   3382 %    o client_name:  Specifies the application name used to retrieve resource
   3383 %      info from the X server database.
   3384 %
   3385 */
   3386 MagickExport XrmDatabase XGetResourceDatabase(Display *display,
   3387   const char *client_name)
   3388 {
   3389   char
   3390     filename[MagickPathExtent];
   3391 
   3392   int
   3393     c;
   3394 
   3395   register const char
   3396     *p;
   3397 
   3398   XrmDatabase
   3399     resource_database,
   3400     server_database;
   3401 
   3402   if (display == (Display *) NULL)
   3403     return((XrmDatabase) NULL);
   3404   assert(client_name != (char *) NULL);
   3405   /*
   3406     Initialize resource database.
   3407   */
   3408   XrmInitialize();
   3409   (void) XGetDefault(display,(char *) client_name,"dummy");
   3410   resource_database=XrmGetDatabase(display);
   3411   /*
   3412     Combine application database.
   3413   */
   3414   if (client_name != (char *) NULL)
   3415     {
   3416       /*
   3417         Get basename of client.
   3418       */
   3419       p=client_name+(strlen(client_name)-1);
   3420       while ((p > client_name) && (*p != '/'))
   3421         p--;
   3422       if (*p == '/')
   3423         client_name=p+1;
   3424     }
   3425   c=(int) (*client_name);
   3426   if ((c >= XK_a) && (c <= XK_z))
   3427     c-=(XK_a-XK_A);
   3428   else
   3429     if ((c >= XK_agrave) && (c <= XK_odiaeresis))
   3430       c-=(XK_agrave-XK_Agrave);
   3431     else
   3432       if ((c >= XK_oslash) && (c <= XK_thorn))
   3433         c-=(XK_oslash-XK_Ooblique);
   3434 #if defined(X11_APPLICATION_PATH)
   3435   (void) FormatLocaleString(filename,MagickPathExtent,"%s%c%s",
   3436     X11_APPLICATION_PATH,c,client_name+1);
   3437   (void) XrmCombineFileDatabase(filename,&resource_database,MagickFalse);
   3438 #endif
   3439   if (XResourceManagerString(display) != (char *) NULL)
   3440     {
   3441       /*
   3442         Combine server database.
   3443       */
   3444       server_database=XrmGetStringDatabase(XResourceManagerString(display));
   3445       XrmCombineDatabase(server_database,&resource_database,MagickFalse);
   3446     }
   3447   /*
   3448     Merge user preferences database.
   3449   */
   3450 #if defined(X11_PREFERENCES_PATH)
   3451   (void) FormatLocaleString(filename,MagickPathExtent,"%s%src",
   3452     X11_PREFERENCES_PATH,client_name);
   3453   ExpandFilename(filename);
   3454   (void) XrmCombineFileDatabase(filename,&resource_database,MagickFalse);
   3455 #endif
   3456   return(resource_database);
   3457 }
   3458 
   3459 /*
   3461 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3462 %                                                                             %
   3463 %                                                                             %
   3464 %                                                                             %
   3465 %   X G e t R e s o u r c e I n f o                                           %
   3466 %                                                                             %
   3467 %                                                                             %
   3468 %                                                                             %
   3469 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3470 %
   3471 %  XGetResourceInfo(image_info,) initializes the ResourceInfo structure.
   3472 %
   3473 %  The format of the XGetResourceInfo method is:
   3474 %
   3475 %      void XGetResourceInfo(const ImageInfo *image_info,XrmDatabase database,
   3476 %        const char *client_name,XResourceInfo *resource_info)
   3477 %
   3478 %  A description of each parameter follows:
   3479 %
   3480 %    o image_info: the image info.
   3481 %
   3482 %    o database: Specifies a resource database; returned from
   3483 %      XrmGetStringDatabase.
   3484 %
   3485 %    o client_name:  Specifies the application name used to retrieve
   3486 %      resource info from the X server database.
   3487 %
   3488 %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
   3489 %
   3490 */
   3491 MagickExport void XGetResourceInfo(const ImageInfo *image_info,
   3492   XrmDatabase database,const char *client_name,XResourceInfo *resource_info)
   3493 {
   3494   char
   3495     *directory,
   3496     *resource_value;
   3497 
   3498   extern const char
   3499     BorderColor[],
   3500     ForegroundColor[];
   3501 
   3502   /*
   3503     Initialize resource info fields.
   3504   */
   3505   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   3506   assert(resource_info != (XResourceInfo *) NULL);
   3507   (void) ResetMagickMemory(resource_info,0,sizeof(*resource_info));
   3508   resource_info->resource_database=database;
   3509   resource_info->image_info=(ImageInfo *) image_info;
   3510   (void) SetImageInfoProgressMonitor(resource_info->image_info,
   3511     XMagickProgressMonitor,(void *) NULL);
   3512   resource_info->quantize_info=CloneQuantizeInfo((QuantizeInfo *) NULL);
   3513   resource_info->close_server=MagickTrue;
   3514   resource_info->client_name=AcquireString(client_name);
   3515   resource_info->alpha_color=XGetResourceInstance(database,client_name,
   3516     "alpha-color",(char *) NULL);
   3517   resource_value=XGetResourceClass(database,client_name,"backdrop",
   3518     (char *) "False");
   3519   resource_info->backdrop=IsStringTrue(resource_value);
   3520   resource_info->background_color=XGetResourceInstance(database,client_name,
   3521     "background",(char *) "#d6d6d6d6d6d6");
   3522   resource_info->border_color=XGetResourceInstance(database,client_name,
   3523     "borderColor",BorderColor);
   3524   resource_value=XGetResourceClass(database,client_name,"borderWidth",
   3525     (char *) "2");
   3526   resource_info->border_width=(unsigned int) StringToUnsignedLong(
   3527     resource_value);
   3528   resource_value=XGetResourceClass(database,client_name,"colormap",
   3529     (char *) "shared");
   3530   resource_info->colormap=UndefinedColormap;
   3531   if (LocaleCompare("private",resource_value) == 0)
   3532     resource_info->colormap=PrivateColormap;
   3533   if (LocaleCompare("shared",resource_value) == 0)
   3534     resource_info->colormap=SharedColormap;
   3535   if (resource_info->colormap == UndefinedColormap)
   3536     ThrowXWindowException(OptionError,"UnrecognizedColormapType",
   3537       resource_value);
   3538   resource_value=XGetResourceClass(database,client_name,
   3539     "colorRecovery",(char *) "False");
   3540   resource_info->color_recovery=IsStringTrue(resource_value);
   3541   resource_value=XGetResourceClass(database,client_name,"confirmExit",
   3542     (char *) "False");
   3543   resource_info->confirm_exit=IsStringTrue(resource_value);
   3544   resource_value=XGetResourceClass(database,client_name,"confirmEdit",
   3545     (char *) "False");
   3546   resource_info->confirm_edit=IsStringTrue(resource_value);
   3547   resource_value=XGetResourceClass(database,client_name,"delay",(char *) "1");
   3548   resource_info->delay=(unsigned int) StringToUnsignedLong(resource_value);
   3549   resource_info->display_gamma=XGetResourceClass(database,client_name,
   3550     "displayGamma",(char *) "2.2");
   3551   resource_value=XGetResourceClass(database,client_name,"displayWarnings",
   3552     (char *) "True");
   3553   resource_info->display_warnings=IsStringTrue(resource_value);
   3554   resource_info->font=XGetResourceClass(database,client_name,"font",
   3555     (char *) NULL);
   3556   resource_info->font=XGetResourceClass(database,client_name,"fontList",
   3557     resource_info->font);
   3558   resource_info->font_name[0]=XGetResourceClass(database,client_name,"font1",
   3559     (char *) "fixed");
   3560   resource_info->font_name[1]=XGetResourceClass(database,client_name,"font2",
   3561     (char *) "variable");
   3562   resource_info->font_name[2]=XGetResourceClass(database,client_name,"font3",
   3563     (char *) "5x8");
   3564   resource_info->font_name[3]=XGetResourceClass(database,client_name,"font4",
   3565     (char *) "6x10");
   3566   resource_info->font_name[4]=XGetResourceClass(database,client_name,"font5",
   3567     (char *) "7x13bold");
   3568   resource_info->font_name[5]=XGetResourceClass(database,client_name,"font6",
   3569     (char *) "8x13bold");
   3570   resource_info->font_name[6]=XGetResourceClass(database,client_name,"font7",
   3571     (char *) "9x15bold");
   3572   resource_info->font_name[7]=XGetResourceClass(database,client_name,"font8",
   3573     (char *) "10x20");
   3574   resource_info->font_name[8]=XGetResourceClass(database,client_name,"font9",
   3575     (char *) "12x24");
   3576   resource_info->font_name[9]=XGetResourceClass(database,client_name,"font0",
   3577     (char *) "fixed");
   3578   resource_info->font_name[10]=XGetResourceClass(database,client_name,"font0",
   3579     (char *) "fixed");
   3580   resource_info->foreground_color=XGetResourceInstance(database,client_name,
   3581     "foreground",ForegroundColor);
   3582   resource_value=XGetResourceClass(database,client_name,"gammaCorrect",
   3583     (char *) "False");
   3584   resource_info->gamma_correct=IsStringTrue(resource_value);
   3585   resource_info->image_geometry=ConstantString(XGetResourceClass(database,
   3586     client_name,"geometry",(char *) NULL));
   3587   resource_value=XGetResourceClass(database,client_name,"gravity",
   3588     (char *) "Center");
   3589   resource_info->gravity=(GravityType) ParseCommandOption(MagickGravityOptions,
   3590     MagickFalse,resource_value);
   3591   directory=getcwd(resource_info->home_directory,MagickPathExtent);
   3592   (void) directory;
   3593   resource_info->icon_geometry=XGetResourceClass(database,client_name,
   3594     "iconGeometry",(char *) NULL);
   3595   resource_value=XGetResourceClass(database,client_name,"iconic",
   3596     (char *) "False");
   3597   resource_info->iconic=IsStringTrue(resource_value);
   3598   resource_value=XGetResourceClass(database,client_name,"immutable",
   3599     LocaleCompare(client_name,"PerlMagick") == 0 ? (char *) "True" :
   3600     (char *) "False");
   3601   resource_info->immutable=IsStringTrue(resource_value);
   3602   resource_value=XGetResourceClass(database,client_name,"magnify",
   3603     (char *) "3");
   3604   resource_info->magnify=(unsigned int) StringToUnsignedLong(resource_value);
   3605   resource_info->map_type=XGetResourceClass(database,client_name,"map",
   3606     (char *) NULL);
   3607   resource_info->name=ConstantString(XGetResourceClass(database,client_name,
   3608     "name",(char *) NULL));
   3609   resource_info->pen_colors[0]=XGetResourceClass(database,client_name,"pen1",
   3610     (char *) "black");
   3611   resource_info->pen_colors[1]=XGetResourceClass(database,client_name,"pen2",
   3612     (char *) "blue");
   3613   resource_info->pen_colors[2]=XGetResourceClass(database,client_name,"pen3",
   3614     (char *) "cyan");
   3615   resource_info->pen_colors[3]=XGetResourceClass(database,client_name,"pen4",
   3616     (char *) "green");
   3617   resource_info->pen_colors[4]=XGetResourceClass(database,client_name,"pen5",
   3618     (char *) "gray");
   3619   resource_info->pen_colors[5]=XGetResourceClass(database,client_name,"pen6",
   3620     (char *) "red");
   3621   resource_info->pen_colors[6]=XGetResourceClass(database,client_name,"pen7",
   3622     (char *) "magenta");
   3623   resource_info->pen_colors[7]=XGetResourceClass(database,client_name,"pen8",
   3624     (char *) "yellow");
   3625   resource_info->pen_colors[8]=XGetResourceClass(database,client_name,"pen9",
   3626     (char *) "white");
   3627   resource_info->pen_colors[9]=XGetResourceClass(database,client_name,"pen0",
   3628     (char *) "gray");
   3629   resource_info->pen_colors[10]=XGetResourceClass(database,client_name,"pen0",
   3630     (char *) "gray");
   3631   resource_value=XGetResourceClass(database,client_name,"pause",(char *) "0");
   3632   resource_info->pause=(unsigned int) StringToUnsignedLong(resource_value);
   3633   resource_value=XGetResourceClass(database,client_name,"quantum",(char *) "1");
   3634   resource_info->quantum=StringToLong(resource_value);
   3635   resource_info->text_font=XGetResourceClass(database,client_name,(char *)
   3636     "font",(char *) "fixed");
   3637   resource_info->text_font=XGetResourceClass(database,client_name,
   3638     "textFontList",resource_info->text_font);
   3639   resource_info->title=XGetResourceClass(database,client_name,"title",
   3640     (char *) NULL);
   3641   resource_value=XGetResourceClass(database,client_name,"undoCache",
   3642     (char *) "256");
   3643   resource_info->undo_cache=(unsigned int) StringToUnsignedLong(resource_value);
   3644   resource_value=XGetResourceClass(database,client_name,"update",
   3645     (char *) "False");
   3646   resource_info->update=IsStringTrue(resource_value);
   3647   resource_value=XGetResourceClass(database,client_name,"usePixmap",
   3648     (char *) "True");
   3649   resource_info->use_pixmap=IsStringTrue(resource_value);
   3650   resource_value=XGetResourceClass(database,client_name,"sharedMemory",
   3651     (char *) "True");
   3652   resource_info->use_shared_memory=IsStringTrue(resource_value);
   3653   resource_info->visual_type=XGetResourceClass(database,client_name,"visual",
   3654     (char *) NULL);
   3655   resource_info->window_group=XGetResourceClass(database,client_name,
   3656     "windowGroup",(char *) NULL);
   3657   resource_info->window_id=XGetResourceClass(database,client_name,"window",
   3658     (char *) NULL);
   3659   resource_info->write_filename=XGetResourceClass(database,client_name,
   3660     "writeFilename",(char *) NULL);
   3661 }
   3662 
   3663 /*
   3665 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3666 %                                                                             %
   3667 %                                                                             %
   3668 %                                                                             %
   3669 %   X G e t R e s o u r c e I n s t a n c e                                   %
   3670 %                                                                             %
   3671 %                                                                             %
   3672 %                                                                             %
   3673 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3674 %
   3675 %  XGetResourceInstance() queries the X server for the specified resource name.
   3676 %  If the resource name is not defined in the database, the supplied default
   3677 %  value is returned.
   3678 %
   3679 %  The format of the XGetResourceInstance method is:
   3680 %
   3681 %      char *XGetResourceInstance(XrmDatabase database,const char *client_name,
   3682 %        const char *keyword,const char *resource_default)
   3683 %
   3684 %  A description of each parameter follows:
   3685 %
   3686 %    o database: Specifies a resource database; returned from
   3687 %      XrmGetStringDatabase.
   3688 %
   3689 %    o client_name:  Specifies the application name used to retrieve
   3690 %      resource info from the X server database.
   3691 %
   3692 %    o keyword: Specifies the keyword of the value being retrieved.
   3693 %
   3694 %    o resource_default: Specifies the default value to return if the query
   3695 %      fails to find the specified keyword/class.
   3696 %
   3697 */
   3698 MagickExport char *XGetResourceInstance(XrmDatabase database,
   3699   const char *client_name,const char *keyword,const char *resource_default)
   3700 {
   3701   char
   3702     *resource_type,
   3703     resource_name[MagickPathExtent];
   3704 
   3705   Status
   3706     status;
   3707 
   3708   XrmValue
   3709     resource_value;
   3710 
   3711   if (database == (XrmDatabase) NULL)
   3712     return((char *) resource_default);
   3713   *resource_name='\0';
   3714   if (keyword != (char *) NULL)
   3715     (void) FormatLocaleString(resource_name,MagickPathExtent,"%s.%s",client_name,
   3716       keyword);
   3717   status=XrmGetResource(database,resource_name,"ImageMagick",&resource_type,
   3718     &resource_value);
   3719   if (status == False)
   3720     return((char *) resource_default);
   3721   return(resource_value.addr);
   3722 }
   3723 
   3724 /*
   3726 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3727 %                                                                             %
   3728 %                                                                             %
   3729 %                                                                             %
   3730 %   X G e t S c r e e n D e n s i t y                                         %
   3731 %                                                                             %
   3732 %                                                                             %
   3733 %                                                                             %
   3734 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3735 %
   3736 %  XGetScreenDensity() returns the density of the X server screen in
   3737 %  dots-per-inch.
   3738 %
   3739 %  The format of the XGetScreenDensity method is:
   3740 %
   3741 %      char *XGetScreenDensity(Display *display)
   3742 %
   3743 %  A description of each parameter follows:
   3744 %
   3745 %    o density: XGetScreenDensity() returns the density of the X screen in
   3746 %      dots-per-inch.
   3747 %
   3748 %    o display: Specifies a connection to an X server;  returned from
   3749 %      XOpenDisplay.
   3750 %
   3751 */
   3752 MagickExport char *XGetScreenDensity(Display *display)
   3753 {
   3754   char
   3755     density[MagickPathExtent];
   3756 
   3757   double
   3758     x_density,
   3759     y_density;
   3760 
   3761   /*
   3762     Set density as determined by screen size.
   3763   */
   3764   x_density=((((double) DisplayWidth(display,XDefaultScreen(display)))*25.4)/
   3765     ((double) DisplayWidthMM(display,XDefaultScreen(display))));
   3766   y_density=((((double) DisplayHeight(display,XDefaultScreen(display)))*25.4)/
   3767     ((double) DisplayHeightMM(display,XDefaultScreen(display))));
   3768   (void) FormatLocaleString(density,MagickPathExtent,"%gx%g",x_density,
   3769     y_density);
   3770   return(GetPageGeometry(density));
   3771 }
   3772 
   3773 /*
   3775 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3776 %                                                                             %
   3777 %                                                                             %
   3778 %                                                                             %
   3779 +   X G e t S u b w i n d o w                                                 %
   3780 %                                                                             %
   3781 %                                                                             %
   3782 %                                                                             %
   3783 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3784 %
   3785 %  XGetSubwindow() returns the subwindow of a window chosen the user with the
   3786 %  pointer and a button press.
   3787 %
   3788 %  The format of the XGetSubwindow method is:
   3789 %
   3790 %      Window XGetSubwindow(Display *display,Window window,int x,int y)
   3791 %
   3792 %  A description of each parameter follows:
   3793 %
   3794 %    o subwindow: XGetSubwindow() returns NULL if no subwindow is found
   3795 %      otherwise the subwindow is returned.
   3796 %
   3797 %    o display: Specifies a connection to an X server;  returned from
   3798 %      XOpenDisplay.
   3799 %
   3800 %    o window: Specifies a pointer to a Window.
   3801 %
   3802 %    o x: the x coordinate of the pointer relative to the origin of the
   3803 %      window.
   3804 %
   3805 %    o y: the y coordinate of the pointer relative to the origin of the
   3806 %      window.
   3807 %
   3808 */
   3809 static Window XGetSubwindow(Display *display,Window window,int x,int y)
   3810 {
   3811   int
   3812     x_offset,
   3813     y_offset;
   3814 
   3815   Status
   3816     status;
   3817 
   3818   Window
   3819     source_window,
   3820     target_window;
   3821 
   3822   assert(display != (Display *) NULL);
   3823   source_window=XRootWindow(display,XDefaultScreen(display));
   3824   if (window == (Window) NULL)
   3825     return(source_window);
   3826   target_window=window;
   3827   for ( ; ; )
   3828   {
   3829     status=XTranslateCoordinates(display,source_window,window,x,y,
   3830       &x_offset,&y_offset,&target_window);
   3831     if (status != True)
   3832       break;
   3833     if (target_window == (Window) NULL)
   3834       break;
   3835     source_window=window;
   3836     window=target_window;
   3837     x=x_offset;
   3838     y=y_offset;
   3839   }
   3840   if (target_window == (Window) NULL)
   3841     target_window=window;
   3842   return(target_window);
   3843 }
   3844 
   3845 /*
   3847 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3848 %                                                                             %
   3849 %                                                                             %
   3850 %                                                                             %
   3851 %   X G e t W i n d o w C o l o r                                             %
   3852 %                                                                             %
   3853 %                                                                             %
   3854 %                                                                             %
   3855 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3856 %
   3857 %  XGetWindowColor() returns the color of a pixel interactively chosen from the
   3858 %  X server.
   3859 %
   3860 %  The format of the XGetWindowColor method is:
   3861 %
   3862 %      MagickBooleanType XGetWindowColor(Display *display,XWindows *windows,
   3863 %        char *name,ExceptionInfo *exception)
   3864 %
   3865 %  A description of each parameter follows:
   3866 %
   3867 %    o display: Specifies a connection to an X server;  returned from
   3868 %      XOpenDisplay.
   3869 %
   3870 %    o windows: Specifies a pointer to a XWindows structure.
   3871 %
   3872 %    o name: the name of the color if found in the X Color Database is
   3873 %      returned in this character string.
   3874 %
   3875 %    o exception: return any errors or warnings in this structure.
   3876 %
   3877 */
   3878 MagickPrivate MagickBooleanType XGetWindowColor(Display *display,
   3879   XWindows *windows,char *name,ExceptionInfo *exception)
   3880 {
   3881   int
   3882     x,
   3883     y;
   3884 
   3885   PixelInfo
   3886     pixel;
   3887 
   3888   RectangleInfo
   3889     crop_info;
   3890 
   3891   Status
   3892     status;
   3893 
   3894   Window
   3895     child,
   3896     client_window,
   3897     root_window,
   3898     target_window;
   3899 
   3900   XColor
   3901     color;
   3902 
   3903   XImage
   3904     *ximage;
   3905 
   3906   XWindowAttributes
   3907     window_attributes;
   3908 
   3909   /*
   3910     Choose a pixel from the X server.
   3911   */
   3912   assert(display != (Display *) NULL);
   3913   assert(name != (char *) NULL);
   3914   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
   3915   *name='\0';
   3916   target_window=XSelectWindow(display,&crop_info);
   3917   if (target_window == (Window) NULL)
   3918     return(MagickFalse);
   3919   root_window=XRootWindow(display,XDefaultScreen(display));
   3920   client_window=target_window;
   3921   if (target_window != root_window)
   3922     {
   3923       unsigned int
   3924         d;
   3925 
   3926       /*
   3927         Get client window.
   3928       */
   3929       status=XGetGeometry(display,target_window,&root_window,&x,&x,&d,&d,&d,&d);
   3930       if (status != False)
   3931         {
   3932           client_window=XClientWindow(display,target_window);
   3933           target_window=client_window;
   3934         }
   3935     }
   3936   /*
   3937     Verify window is viewable.
   3938   */
   3939   status=XGetWindowAttributes(display,target_window,&window_attributes);
   3940   if ((status == False) || (window_attributes.map_state != IsViewable))
   3941     return(MagickFalse);
   3942   /*
   3943     Get window X image.
   3944   */
   3945   (void) XTranslateCoordinates(display,root_window,target_window,
   3946     (int) crop_info.x,(int) crop_info.y,&x,&y,&child);
   3947   ximage=XGetImage(display,target_window,x,y,1,1,AllPlanes,ZPixmap);
   3948   if (ximage == (XImage *) NULL)
   3949     return(MagickFalse);
   3950   color.pixel=XGetPixel(ximage,0,0);
   3951   XDestroyImage(ximage);
   3952   /*
   3953     Match color against the color database.
   3954   */
   3955   (void) XQueryColor(display,window_attributes.colormap,&color);
   3956   pixel.red=(double) ScaleShortToQuantum(color.red);
   3957   pixel.green=(double) ScaleShortToQuantum(color.green);
   3958   pixel.blue=(double) ScaleShortToQuantum(color.blue);
   3959   pixel.alpha=OpaqueAlpha;
   3960   (void) QueryColorname(windows->image.image,&pixel,X11Compliance,name,
   3961     exception);
   3962   return(MagickTrue);
   3963 }
   3964 
   3965 /*
   3967 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3968 %                                                                             %
   3969 %                                                                             %
   3970 %                                                                             %
   3971 +   X G e t W i n d o w I m a g e                                             %
   3972 %                                                                             %
   3973 %                                                                             %
   3974 %                                                                             %
   3975 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   3976 %
   3977 %  XGetWindowImage() reads an image from the target X window and returns it.
   3978 %  XGetWindowImage() optionally descends the window hierarchy and overlays the
   3979 %  target image with each child image in an optimized fashion.  Any child
   3980 %  window that have the same visual, colormap, and are contained by its parent
   3981 %  are exempted.
   3982 %
   3983 %  The format of the XGetWindowImage method is:
   3984 %
   3985 %      Image *XGetWindowImage(Display *display,const Window window,
   3986 %        const unsigned int borders,const unsigned int level,
   3987 %        ExceptionInfo *exception)
   3988 %
   3989 %  A description of each parameter follows:
   3990 %
   3991 %    o display: Specifies a connection to an X server;  returned from
   3992 %      XOpenDisplay.
   3993 %
   3994 %    o window: Specifies the window to obtain the image from.
   3995 %
   3996 %    o borders: Specifies whether borders pixels are to be saved with
   3997 %      the image.
   3998 %
   3999 %    o level: Specifies an unsigned integer representing the level of
   4000 %      decent in the window hierarchy.  This value must be zero or one on
   4001 %      the initial call to XGetWindowImage.  A value of zero returns after
   4002 %      one call.  A value of one causes the function to descend the window
   4003 %      hierarchy and overlay the target image with each subwindow image.
   4004 %
   4005 %    o exception: return any errors or warnings in this structure.
   4006 %
   4007 */
   4008 static Image *XGetWindowImage(Display *display,const Window window,
   4009   const unsigned int borders,const unsigned int level,ExceptionInfo *exception)
   4010 {
   4011   typedef struct _ColormapInfo
   4012   {
   4013     Colormap
   4014       colormap;
   4015 
   4016     XColor
   4017       *colors;
   4018 
   4019     struct _ColormapInfo
   4020       *next;
   4021   } ColormapInfo;
   4022 
   4023   typedef struct _WindowInfo
   4024   {
   4025     Window
   4026       window,
   4027       parent;
   4028 
   4029     Visual
   4030       *visual;
   4031 
   4032     Colormap
   4033       colormap;
   4034 
   4035     XSegment
   4036       bounds;
   4037 
   4038     RectangleInfo
   4039       crop_info;
   4040   } WindowInfo;
   4041 
   4042   int
   4043     display_height,
   4044     display_width,
   4045     id,
   4046     x_offset,
   4047     y_offset;
   4048 
   4049   Quantum
   4050     index;
   4051 
   4052   RectangleInfo
   4053     crop_info;
   4054 
   4055   register int
   4056     i;
   4057 
   4058   static ColormapInfo
   4059     *colormap_info = (ColormapInfo *) NULL;
   4060 
   4061   static int
   4062     max_windows = 0,
   4063     number_windows = 0;
   4064 
   4065   static WindowInfo
   4066     *window_info;
   4067 
   4068   Status
   4069     status;
   4070 
   4071   Window
   4072     child,
   4073     root_window;
   4074 
   4075   XWindowAttributes
   4076     window_attributes;
   4077 
   4078   /*
   4079     Verify window is viewable.
   4080   */
   4081   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   4082   assert(display != (Display *) NULL);
   4083   status=XGetWindowAttributes(display,window,&window_attributes);
   4084   if ((status == False) || (window_attributes.map_state != IsViewable))
   4085     return((Image *) NULL);
   4086   /*
   4087     Cropping rectangle is relative to root window.
   4088   */
   4089   root_window=XRootWindow(display,XDefaultScreen(display));
   4090   (void) XTranslateCoordinates(display,window,root_window,0,0,&x_offset,
   4091     &y_offset,&child);
   4092   crop_info.x=(ssize_t) x_offset;
   4093   crop_info.y=(ssize_t) y_offset;
   4094   crop_info.width=(size_t) window_attributes.width;
   4095   crop_info.height=(size_t) window_attributes.height;
   4096   if (borders != MagickFalse)
   4097     {
   4098       /*
   4099         Include border in image.
   4100       */
   4101       crop_info.x-=(ssize_t) window_attributes.border_width;
   4102       crop_info.y-=(ssize_t) window_attributes.border_width;
   4103       crop_info.width+=(size_t) (window_attributes.border_width << 1);
   4104       crop_info.height+=(size_t) (window_attributes.border_width << 1);
   4105     }
   4106   /*
   4107     Crop to root window.
   4108   */
   4109   if (crop_info.x < 0)
   4110     {
   4111       crop_info.width+=crop_info.x;
   4112       crop_info.x=0;
   4113     }
   4114   if (crop_info.y < 0)
   4115     {
   4116       crop_info.height+=crop_info.y;
   4117       crop_info.y=0;
   4118     }
   4119   display_width=XDisplayWidth(display,XDefaultScreen(display));
   4120   if ((int) (crop_info.x+crop_info.width) > display_width)
   4121     crop_info.width=(size_t) (display_width-crop_info.x);
   4122   display_height=XDisplayHeight(display,XDefaultScreen(display));
   4123   if ((int) (crop_info.y+crop_info.height) > display_height)
   4124     crop_info.height=(size_t) (display_height-crop_info.y);
   4125   /*
   4126     Initialize window info attributes.
   4127   */
   4128   if (number_windows >= max_windows)
   4129     {
   4130       /*
   4131         Allocate or resize window info buffer.
   4132       */
   4133       max_windows+=1024;
   4134       if (window_info == (WindowInfo *) NULL)
   4135         window_info=(WindowInfo *) AcquireQuantumMemory((size_t) max_windows,
   4136           sizeof(*window_info));
   4137       else
   4138         window_info=(WindowInfo *) ResizeQuantumMemory(window_info,(size_t)
   4139           max_windows,sizeof(*window_info));
   4140     }
   4141   if (window_info == (WindowInfo *) NULL)
   4142     {
   4143       ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed","...");
   4144       return((Image *) NULL);
   4145     }
   4146   id=number_windows++;
   4147   window_info[id].window=window;
   4148   window_info[id].visual=window_attributes.visual;
   4149   window_info[id].colormap=window_attributes.colormap;
   4150   window_info[id].bounds.x1=(short) crop_info.x;
   4151   window_info[id].bounds.y1=(short) crop_info.y;
   4152   window_info[id].bounds.x2=(short) (crop_info.x+(int) crop_info.width-1);
   4153   window_info[id].bounds.y2=(short) (crop_info.y+(int) crop_info.height-1);
   4154   crop_info.x-=x_offset;
   4155   crop_info.y-=y_offset;
   4156   window_info[id].crop_info=crop_info;
   4157   if (level != 0)
   4158     {
   4159       unsigned int
   4160         number_children;
   4161 
   4162       Window
   4163         *children;
   4164 
   4165       /*
   4166         Descend the window hierarchy.
   4167       */
   4168       status=XQueryTree(display,window,&root_window,&window_info[id].parent,
   4169         &children,&number_children);
   4170       for (i=0; i < id; i++)
   4171         if ((window_info[i].window == window_info[id].parent) &&
   4172             (window_info[i].visual == window_info[id].visual) &&
   4173             (window_info[i].colormap == window_info[id].colormap))
   4174           {
   4175             if ((window_info[id].bounds.x1 < window_info[i].bounds.x1) ||
   4176                 (window_info[id].bounds.x2 > window_info[i].bounds.x2) ||
   4177                 (window_info[id].bounds.y1 < window_info[i].bounds.y1) ||
   4178                 (window_info[id].bounds.y2 > window_info[i].bounds.y2))
   4179               {
   4180                 /*
   4181                   Eliminate windows not circumscribed by their parent.
   4182                 */
   4183                 number_windows--;
   4184                 break;
   4185               }
   4186           }
   4187       if ((status == True) && (number_children != 0))
   4188         {
   4189           for (i=0; i < (int) number_children; i++)
   4190             (void) XGetWindowImage(display,children[i],MagickFalse,level+1,
   4191               exception);
   4192           (void) XFree((void *) children);
   4193         }
   4194     }
   4195   if (level <= 1)
   4196     {
   4197       CacheView
   4198         *composite_view;
   4199 
   4200       ColormapInfo
   4201         *next;
   4202 
   4203       Image
   4204         *composite_image,
   4205         *image;
   4206 
   4207       int
   4208         y;
   4209 
   4210       MagickBooleanType
   4211         import;
   4212 
   4213       register int
   4214         j,
   4215         x;
   4216 
   4217       register Quantum
   4218         *magick_restrict q;
   4219 
   4220       register size_t
   4221         pixel;
   4222 
   4223       unsigned int
   4224         number_colors;
   4225 
   4226       XColor
   4227         *colors;
   4228 
   4229       XImage
   4230         *ximage;
   4231 
   4232       /*
   4233         Get X image for each window in the list.
   4234       */
   4235       image=NewImageList();
   4236       for (id=0; id < number_windows; id++)
   4237       {
   4238         /*
   4239           Does target window intersect top level window?
   4240         */
   4241         import=((window_info[id].bounds.x2 >= window_info[0].bounds.x1) &&
   4242            (window_info[id].bounds.x1 <= window_info[0].bounds.x2) &&
   4243            (window_info[id].bounds.y2 >= window_info[0].bounds.y1) &&
   4244            (window_info[id].bounds.y1 <= window_info[0].bounds.y2)) ?
   4245           MagickTrue : MagickFalse;
   4246         /*
   4247           Is target window contained by another window with the same colormap?
   4248         */
   4249         for (j=0; j < id; j++)
   4250           if ((window_info[id].visual == window_info[j].visual) &&
   4251               (window_info[id].colormap == window_info[j].colormap))
   4252             {
   4253               if ((window_info[id].bounds.x1 >= window_info[j].bounds.x1) &&
   4254                   (window_info[id].bounds.x2 <= window_info[j].bounds.x2) &&
   4255                   (window_info[id].bounds.y1 >= window_info[j].bounds.y1) &&
   4256                   (window_info[id].bounds.y2 <= window_info[j].bounds.y2))
   4257                 import=MagickFalse;
   4258             }
   4259         if (import == MagickFalse)
   4260           continue;
   4261         /*
   4262           Get X image.
   4263         */
   4264         ximage=XGetImage(display,window_info[id].window,(int)
   4265           window_info[id].crop_info.x,(int) window_info[id].crop_info.y,
   4266           (unsigned int) window_info[id].crop_info.width,(unsigned int)
   4267           window_info[id].crop_info.height,AllPlanes,ZPixmap);
   4268         if (ximage == (XImage *) NULL)
   4269           continue;
   4270         /*
   4271           Initialize window colormap.
   4272         */
   4273         number_colors=0;
   4274         colors=(XColor *) NULL;
   4275         if (window_info[id].colormap != (Colormap) NULL)
   4276           {
   4277             ColormapInfo
   4278               *p;
   4279 
   4280             /*
   4281               Search colormap list for window colormap.
   4282             */
   4283             number_colors=(unsigned int) window_info[id].visual->map_entries;
   4284             for (p=colormap_info; p != (ColormapInfo *) NULL; p=p->next)
   4285               if (p->colormap == window_info[id].colormap)
   4286                 break;
   4287             if (p == (ColormapInfo *) NULL)
   4288               {
   4289                 /*
   4290                   Get the window colormap.
   4291                 */
   4292                 colors=(XColor *) AcquireQuantumMemory(number_colors,
   4293                   sizeof(*colors));
   4294                 if (colors == (XColor *) NULL)
   4295                   {
   4296                     XDestroyImage(ximage);
   4297                     return((Image *) NULL);
   4298                   }
   4299                 if ((window_info[id].visual->klass != DirectColor) &&
   4300                     (window_info[id].visual->klass != TrueColor))
   4301                   for (i=0; i < (int) number_colors; i++)
   4302                   {
   4303                     colors[i].pixel=(size_t) i;
   4304                     colors[i].pad='\0';
   4305                   }
   4306                 else
   4307                   {
   4308                     size_t
   4309                       blue,
   4310                       blue_bit,
   4311                       green,
   4312                       green_bit,
   4313                       red,
   4314                       red_bit;
   4315 
   4316                     /*
   4317                       DirectColor or TrueColor visual.
   4318                     */
   4319                     red=0;
   4320                     green=0;
   4321                     blue=0;
   4322                     red_bit=window_info[id].visual->red_mask &
   4323                       (~(window_info[id].visual->red_mask)+1);
   4324                     green_bit=window_info[id].visual->green_mask &
   4325                       (~(window_info[id].visual->green_mask)+1);
   4326                     blue_bit=window_info[id].visual->blue_mask &
   4327                       (~(window_info[id].visual->blue_mask)+1);
   4328                     for (i=0; i < (int) number_colors; i++)
   4329                     {
   4330                       colors[i].pixel=(unsigned long) (red | green | blue);
   4331                       colors[i].pad='\0';
   4332                       red+=red_bit;
   4333                       if (red > window_info[id].visual->red_mask)
   4334                         red=0;
   4335                       green+=green_bit;
   4336                       if (green > window_info[id].visual->green_mask)
   4337                         green=0;
   4338                       blue+=blue_bit;
   4339                       if (blue > window_info[id].visual->blue_mask)
   4340                         blue=0;
   4341                     }
   4342                   }
   4343                 (void) XQueryColors(display,window_info[id].colormap,colors,
   4344                   (int) number_colors);
   4345                 /*
   4346                   Append colormap to colormap list.
   4347                 */
   4348                 p=(ColormapInfo *) AcquireMagickMemory(sizeof(*p));
   4349                 if (p == (ColormapInfo *) NULL)
   4350                   return((Image *) NULL);
   4351                 p->colormap=window_info[id].colormap;
   4352                 p->colors=colors;
   4353                 p->next=colormap_info;
   4354                 colormap_info=p;
   4355               }
   4356             colors=p->colors;
   4357           }
   4358         /*
   4359           Allocate image structure.
   4360         */
   4361         composite_image=AcquireImage((ImageInfo *) NULL,exception);
   4362         if (composite_image == (Image *) NULL)
   4363           {
   4364             XDestroyImage(ximage);
   4365             return((Image *) NULL);
   4366           }
   4367         /*
   4368           Convert X image to MIFF format.
   4369         */
   4370         if ((window_info[id].visual->klass != TrueColor) &&
   4371             (window_info[id].visual->klass != DirectColor))
   4372           composite_image->storage_class=PseudoClass;
   4373         composite_image->columns=(size_t) ximage->width;
   4374         composite_image->rows=(size_t) ximage->height;
   4375         composite_view=AcquireAuthenticCacheView(composite_image,exception);
   4376         switch (composite_image->storage_class)
   4377         {
   4378           case DirectClass:
   4379           default:
   4380           {
   4381             register size_t
   4382               color,
   4383               index;
   4384 
   4385             size_t
   4386               blue_mask,
   4387               blue_shift,
   4388               green_mask,
   4389               green_shift,
   4390               red_mask,
   4391               red_shift;
   4392 
   4393             /*
   4394               Determine shift and mask for red, green, and blue.
   4395             */
   4396             red_mask=window_info[id].visual->red_mask;
   4397             red_shift=0;
   4398             while ((red_mask != 0) && ((red_mask & 0x01) == 0))
   4399             {
   4400               red_mask>>=1;
   4401               red_shift++;
   4402             }
   4403             green_mask=window_info[id].visual->green_mask;
   4404             green_shift=0;
   4405             while ((green_mask != 0) && ((green_mask & 0x01) == 0))
   4406             {
   4407               green_mask>>=1;
   4408               green_shift++;
   4409             }
   4410             blue_mask=window_info[id].visual->blue_mask;
   4411             blue_shift=0;
   4412             while ((blue_mask != 0) && ((blue_mask & 0x01) == 0))
   4413             {
   4414               blue_mask>>=1;
   4415               blue_shift++;
   4416             }
   4417             /*
   4418               Convert X image to DirectClass packets.
   4419             */
   4420             if ((number_colors != 0) &&
   4421                 (window_info[id].visual->klass == DirectColor))
   4422               for (y=0; y < (int) composite_image->rows; y++)
   4423               {
   4424                 q=QueueCacheViewAuthenticPixels(composite_view,0,(ssize_t) y,
   4425                   composite_image->columns,1,exception);
   4426                 if (q == (Quantum *) NULL)
   4427                   break;
   4428                 for (x=0; x < (int) composite_image->columns; x++)
   4429                 {
   4430                   pixel=XGetPixel(ximage,x,y);
   4431                   index=(pixel >> red_shift) & red_mask;
   4432                   SetPixelRed(composite_image,
   4433                     ScaleShortToQuantum(colors[index].red),q);
   4434                   index=(pixel >> green_shift) & green_mask;
   4435                   SetPixelGreen(composite_image,
   4436                     ScaleShortToQuantum(colors[index].green),q);
   4437                   index=(pixel >> blue_shift) & blue_mask;
   4438                   SetPixelBlue(composite_image,
   4439                     ScaleShortToQuantum(colors[index].blue),q);
   4440                   q+=GetPixelChannels(composite_image);
   4441                 }
   4442                 status=SyncCacheViewAuthenticPixels(composite_view,exception);
   4443                 if (status == MagickFalse)
   4444                   break;
   4445               }
   4446             else
   4447               for (y=0; y < (int) composite_image->rows; y++)
   4448               {
   4449                 q=QueueCacheViewAuthenticPixels(composite_view,0,(ssize_t) y,
   4450                   composite_image->columns,1,exception);
   4451                 if (q == (Quantum *) NULL)
   4452                   break;
   4453                 for (x=0; x < (int) composite_image->columns; x++)
   4454                 {
   4455                   pixel=XGetPixel(ximage,x,y);
   4456                   color=(pixel >> red_shift) & red_mask;
   4457                   if (red_mask != 0)
   4458                     color=(65535UL*color)/red_mask;
   4459                   SetPixelRed(composite_image,ScaleShortToQuantum(
   4460                     (unsigned short) color),q);
   4461                   color=(pixel >> green_shift) & green_mask;
   4462                   if (green_mask != 0)
   4463                     color=(65535UL*color)/green_mask;
   4464                   SetPixelGreen(composite_image,ScaleShortToQuantum(
   4465                     (unsigned short) color),q);
   4466                   color=(pixel >> blue_shift) & blue_mask;
   4467                   if (blue_mask != 0)
   4468                     color=(65535UL*color)/blue_mask;
   4469                   SetPixelBlue(composite_image,ScaleShortToQuantum(
   4470                     (unsigned short) color),q);
   4471                   q+=GetPixelChannels(composite_image);
   4472                 }
   4473                 status=SyncCacheViewAuthenticPixels(composite_view,exception);
   4474                 if (status == MagickFalse)
   4475                   break;
   4476               }
   4477             break;
   4478           }
   4479           case PseudoClass:
   4480           {
   4481             /*
   4482               Create colormap.
   4483             */
   4484             status=AcquireImageColormap(composite_image,number_colors,
   4485               exception);
   4486             if (status == MagickFalse)
   4487               {
   4488                 XDestroyImage(ximage);
   4489                 composite_image=DestroyImage(composite_image);
   4490                 return((Image *) NULL);
   4491               }
   4492             for (i=0; i < (int) composite_image->colors; i++)
   4493             {
   4494               composite_image->colormap[colors[i].pixel].red=(double)
   4495                 ScaleShortToQuantum(colors[i].red);
   4496               composite_image->colormap[colors[i].pixel].green=(double)
   4497                 ScaleShortToQuantum(colors[i].green);
   4498               composite_image->colormap[colors[i].pixel].blue=(double)
   4499                 ScaleShortToQuantum(colors[i].blue);
   4500             }
   4501             /*
   4502               Convert X image to PseudoClass packets.
   4503             */
   4504             for (y=0; y < (int) composite_image->rows; y++)
   4505             {
   4506               q=QueueCacheViewAuthenticPixels(composite_view,0,(ssize_t) y,
   4507                 composite_image->columns,1,exception);
   4508               if (q == (Quantum *) NULL)
   4509                 break;
   4510               for (x=0; x < (int) composite_image->columns; x++)
   4511               {
   4512                 index=(Quantum) XGetPixel(ximage,x,y);
   4513                 SetPixelIndex(composite_image,index,q);
   4514                 SetPixelViaPixelInfo(composite_image,
   4515                   composite_image->colormap+(ssize_t) index,q);
   4516                 q+=GetPixelChannels(composite_image);
   4517               }
   4518               status=SyncCacheViewAuthenticPixels(composite_view,exception);
   4519               if (status == MagickFalse)
   4520                 break;
   4521             }
   4522             break;
   4523           }
   4524         }
   4525         composite_view=DestroyCacheView(composite_view);
   4526         XDestroyImage(ximage);
   4527         if (image == (Image *) NULL)
   4528           {
   4529             image=composite_image;
   4530             continue;
   4531           }
   4532         /*
   4533           Composite any children in back-to-front order.
   4534         */
   4535         (void) XTranslateCoordinates(display,window_info[id].window,window,0,0,
   4536           &x_offset,&y_offset,&child);
   4537         x_offset-=(int) crop_info.x;
   4538         if (x_offset < 0)
   4539           x_offset=0;
   4540         y_offset-=(int) crop_info.y;
   4541         if (y_offset < 0)
   4542           y_offset=0;
   4543         (void) CompositeImage(image,composite_image,CopyCompositeOp,MagickTrue,
   4544           (ssize_t) x_offset,(ssize_t) y_offset,exception);
   4545         composite_image=DestroyImage(composite_image);
   4546       }
   4547       /*
   4548         Relinquish resources.
   4549       */
   4550       while (colormap_info != (ColormapInfo *) NULL)
   4551       {
   4552         next=colormap_info->next;
   4553         colormap_info->colors=(XColor *) RelinquishMagickMemory(
   4554           colormap_info->colors);
   4555         colormap_info=(ColormapInfo *) RelinquishMagickMemory(colormap_info);
   4556         colormap_info=next;
   4557       }
   4558       /*
   4559         Relinquish resources and restore initial state.
   4560       */
   4561       window_info=(WindowInfo *) RelinquishMagickMemory(window_info);
   4562       max_windows=0;
   4563       number_windows=0;
   4564       colormap_info=(ColormapInfo *) NULL;
   4565       return(image);
   4566     }
   4567   return((Image *) NULL);
   4568 }
   4569 
   4570 /*
   4572 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4573 %                                                                             %
   4574 %                                                                             %
   4575 %                                                                             %
   4576 %   X G e t W i n d o w I n f o                                               %
   4577 %                                                                             %
   4578 %                                                                             %
   4579 %                                                                             %
   4580 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4581 %
   4582 %  XGetWindowInfo() initializes the XWindowInfo structure.
   4583 %
   4584 %  The format of the XGetWindowInfo method is:
   4585 %
   4586 %      void XGetWindowInfo(Display *display,XVisualInfo *visual_info,
   4587 %        XStandardColormap *map_info,XPixelInfo *pixel,XFontStruct *font_info,
   4588 %        XResourceInfo *resource_info,XWindowInfo *window)
   4589 %        resource_info,window)
   4590 %
   4591 %  A description of each parameter follows:
   4592 %
   4593 %    o display: Specifies a connection to an X server; returned from
   4594 %      XOpenDisplay.
   4595 %
   4596 %    o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
   4597 %      returned from XGetVisualInfo.
   4598 %
   4599 %    o map_info: If map_type is specified, this structure is initialized
   4600 %      with info from the Standard Colormap.
   4601 %
   4602 %    o pixel: Specifies a pointer to a XPixelInfo structure.
   4603 %
   4604 %    o font_info: Specifies a pointer to a XFontStruct structure.
   4605 %
   4606 %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
   4607 %
   4608 */
   4609 MagickPrivate void XGetWindowInfo(Display *display,XVisualInfo *visual_info,
   4610   XStandardColormap *map_info,XPixelInfo *pixel,XFontStruct *font_info,
   4611   XResourceInfo *resource_info,XWindowInfo *window)
   4612 {
   4613   /*
   4614     Initialize window info.
   4615   */
   4616   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   4617   assert(display != (Display *) NULL);
   4618   assert(visual_info != (XVisualInfo *) NULL);
   4619   assert(map_info != (XStandardColormap *) NULL);
   4620   assert(pixel != (XPixelInfo *) NULL);
   4621   assert(resource_info != (XResourceInfo *) NULL);
   4622   assert(window != (XWindowInfo *) NULL);
   4623   if (window->id != (Window) NULL)
   4624     {
   4625       if (window->cursor != (Cursor) NULL)
   4626         (void) XFreeCursor(display,window->cursor);
   4627       if (window->busy_cursor != (Cursor) NULL)
   4628         (void) XFreeCursor(display,window->busy_cursor);
   4629       if (window->highlight_stipple != (Pixmap) NULL)
   4630         (void) XFreePixmap(display,window->highlight_stipple);
   4631       if (window->shadow_stipple != (Pixmap) NULL)
   4632         (void) XFreePixmap(display,window->shadow_stipple);
   4633       if (window->name == (char *) NULL)
   4634         window->name=AcquireString("");
   4635       if (window->icon_name == (char *) NULL)
   4636         window->icon_name=AcquireString("");
   4637     }
   4638   else
   4639     {
   4640       /*
   4641         Initialize these attributes just once.
   4642       */
   4643       window->id=(Window) NULL;
   4644       if (window->name == (char *) NULL)
   4645         window->name=AcquireString("");
   4646       if (window->icon_name == (char *) NULL)
   4647         window->icon_name=AcquireString("");
   4648       window->x=XDisplayWidth(display,visual_info->screen) >> 1;
   4649       window->y=XDisplayWidth(display,visual_info->screen) >> 1;
   4650       window->ximage=(XImage *) NULL;
   4651       window->matte_image=(XImage *) NULL;
   4652       window->pixmap=(Pixmap) NULL;
   4653       window->matte_pixmap=(Pixmap) NULL;
   4654       window->mapped=MagickFalse;
   4655       window->stasis=MagickFalse;
   4656       window->shared_memory=MagickTrue;
   4657       window->segment_info=(void *) NULL;
   4658 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
   4659       {
   4660         XShmSegmentInfo
   4661           *segment_info;
   4662 
   4663         if (window->segment_info == (void *) NULL)
   4664           window->segment_info=AcquireQuantumMemory(2,sizeof(*segment_info));
   4665         segment_info=(XShmSegmentInfo *) window->segment_info;
   4666         segment_info[0].shmid=(-1);
   4667         segment_info[0].shmaddr=(char *) NULL;
   4668         segment_info[1].shmid=(-1);
   4669         segment_info[1].shmaddr=(char *) NULL;
   4670       }
   4671 #endif
   4672     }
   4673   /*
   4674     Initialize these attributes every time function is called.
   4675   */
   4676   window->screen=visual_info->screen;
   4677   window->root=XRootWindow(display,visual_info->screen);
   4678   window->visual=visual_info->visual;
   4679   window->storage_class=(unsigned int) visual_info->klass;
   4680   window->depth=(unsigned int) visual_info->depth;
   4681   window->visual_info=visual_info;
   4682   window->map_info=map_info;
   4683   window->pixel_info=pixel;
   4684   window->font_info=font_info;
   4685   window->cursor=XCreateFontCursor(display,XC_left_ptr);
   4686   window->busy_cursor=XCreateFontCursor(display,XC_watch);
   4687   window->geometry=(char *) NULL;
   4688   window->icon_geometry=(char *) NULL;
   4689   if (resource_info->icon_geometry != (char *) NULL)
   4690     (void) CloneString(&window->icon_geometry,resource_info->icon_geometry);
   4691   window->crop_geometry=(char *) NULL;
   4692   window->flags=(size_t) PSize;
   4693   window->width=1;
   4694   window->height=1;
   4695   window->min_width=1;
   4696   window->min_height=1;
   4697   window->width_inc=1;
   4698   window->height_inc=1;
   4699   window->border_width=resource_info->border_width;
   4700   window->annotate_context=pixel->annotate_context;
   4701   window->highlight_context=pixel->highlight_context;
   4702   window->widget_context=pixel->widget_context;
   4703   window->shadow_stipple=(Pixmap) NULL;
   4704   window->highlight_stipple=(Pixmap) NULL;
   4705   window->use_pixmap=MagickTrue;
   4706   window->immutable=MagickFalse;
   4707   window->shape=MagickFalse;
   4708   window->data=0;
   4709   window->mask=(int) (CWBackingStore | CWBackPixel | CWBackPixmap |
   4710     CWBitGravity | CWBorderPixel | CWColormap | CWCursor | CWDontPropagate |
   4711     CWEventMask | CWOverrideRedirect | CWSaveUnder | CWWinGravity);
   4712   window->attributes.background_pixel=pixel->background_color.pixel;
   4713   window->attributes.background_pixmap=(Pixmap) NULL;
   4714   window->attributes.bit_gravity=ForgetGravity;
   4715   window->attributes.backing_store=WhenMapped;
   4716   window->attributes.save_under=MagickTrue;
   4717   window->attributes.border_pixel=pixel->border_color.pixel;
   4718   window->attributes.colormap=map_info->colormap;
   4719   window->attributes.cursor=window->cursor;
   4720   window->attributes.do_not_propagate_mask=NoEventMask;
   4721   window->attributes.event_mask=NoEventMask;
   4722   window->attributes.override_redirect=MagickFalse;
   4723   window->attributes.win_gravity=NorthWestGravity;
   4724   window->orphan=MagickFalse;
   4725 }
   4726 
   4727 /*
   4729 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4730 %                                                                             %
   4731 %                                                                             %
   4732 %                                                                             %
   4733 %   X H i g h l i g h t E l l i p s e                                         %
   4734 %                                                                             %
   4735 %                                                                             %
   4736 %                                                                             %
   4737 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4738 %
   4739 %  XHighlightEllipse() puts a border on the X server around a region defined by
   4740 %  highlight_info.
   4741 %
   4742 %  The format of the XHighlightEllipse method is:
   4743 %
   4744 %      void XHighlightEllipse(Display *display,Window window,
   4745 %        GC annotate_context,const RectangleInfo *highlight_info)
   4746 %
   4747 %  A description of each parameter follows:
   4748 %
   4749 %    o display: Specifies a connection to an X server; returned from
   4750 %      XOpenDisplay.
   4751 %
   4752 %    o window: Specifies a pointer to a Window structure.
   4753 %
   4754 %    o annotate_context: Specifies a pointer to a GC structure.
   4755 %
   4756 %    o highlight_info: Specifies a pointer to a RectangleInfo structure.  It
   4757 %      contains the extents of any highlighting rectangle.
   4758 %
   4759 */
   4760 MagickPrivate void XHighlightEllipse(Display *display,Window window,
   4761   GC annotate_context,const RectangleInfo *highlight_info)
   4762 {
   4763   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   4764   assert(display != (Display *) NULL);
   4765   assert(window != (Window) NULL);
   4766   assert(annotate_context != (GC) NULL);
   4767   assert(highlight_info != (RectangleInfo *) NULL);
   4768   if ((highlight_info->width < 4) || (highlight_info->height < 4))
   4769     return;
   4770   (void) XDrawArc(display,window,annotate_context,(int) highlight_info->x,
   4771     (int) highlight_info->y,(unsigned int) highlight_info->width-1,
   4772     (unsigned int) highlight_info->height-1,0,360*64);
   4773   (void) XDrawArc(display,window,annotate_context,(int) highlight_info->x+1,
   4774     (int) highlight_info->y+1,(unsigned int) highlight_info->width-3,
   4775     (unsigned int) highlight_info->height-3,0,360*64);
   4776 }
   4777 
   4778 /*
   4780 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4781 %                                                                             %
   4782 %                                                                             %
   4783 %                                                                             %
   4784 %   X H i g h l i g h t L i n e                                               %
   4785 %                                                                             %
   4786 %                                                                             %
   4787 %                                                                             %
   4788 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4789 %
   4790 %  XHighlightLine() puts a border on the X server around a region defined by
   4791 %  highlight_info.
   4792 %
   4793 %  The format of the XHighlightLine method is:
   4794 %
   4795 %      void XHighlightLine(Display *display,Window window,GC annotate_context,
   4796 %        const XSegment *highlight_info)
   4797 %
   4798 %  A description of each parameter follows:
   4799 %
   4800 %    o display: Specifies a connection to an X server; returned from
   4801 %      XOpenDisplay.
   4802 %
   4803 %    o window: Specifies a pointer to a Window structure.
   4804 %
   4805 %    o annotate_context: Specifies a pointer to a GC structure.
   4806 %
   4807 %    o highlight_info: Specifies a pointer to a RectangleInfo structure.  It
   4808 %      contains the extents of any highlighting rectangle.
   4809 %
   4810 */
   4811 MagickPrivate void XHighlightLine(Display *display,Window window,
   4812   GC annotate_context,const XSegment *highlight_info)
   4813 {
   4814   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   4815   assert(display != (Display *) NULL);
   4816   assert(window != (Window) NULL);
   4817   assert(annotate_context != (GC) NULL);
   4818   assert(highlight_info != (XSegment *) NULL);
   4819   (void) XDrawLine(display,window,annotate_context,highlight_info->x1,
   4820     highlight_info->y1,highlight_info->x2,highlight_info->y2);
   4821 }
   4822 
   4823 /*
   4825 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4826 %                                                                             %
   4827 %                                                                             %
   4828 %                                                                             %
   4829 %   X H i g h l i g h t R e c t a n g l e                                     %
   4830 %                                                                             %
   4831 %                                                                             %
   4832 %                                                                             %
   4833 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4834 %
   4835 %  XHighlightRectangle() puts a border on the X server around a region defined
   4836 %  by highlight_info.
   4837 %
   4838 %  The format of the XHighlightRectangle method is:
   4839 %
   4840 %      void XHighlightRectangle(Display *display,Window window,
   4841 %        GC annotate_context,const RectangleInfo *highlight_info)
   4842 %
   4843 %  A description of each parameter follows:
   4844 %
   4845 %    o display: Specifies a connection to an X server; returned from
   4846 %      XOpenDisplay.
   4847 %
   4848 %    o window: Specifies a pointer to a Window structure.
   4849 %
   4850 %    o annotate_context: Specifies a pointer to a GC structure.
   4851 %
   4852 %    o highlight_info: Specifies a pointer to a RectangleInfo structure.  It
   4853 %      contains the extents of any highlighting rectangle.
   4854 %
   4855 */
   4856 MagickPrivate void XHighlightRectangle(Display *display,Window window,
   4857   GC annotate_context,const RectangleInfo *highlight_info)
   4858 {
   4859   assert(display != (Display *) NULL);
   4860   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   4861   assert(window != (Window) NULL);
   4862   assert(annotate_context != (GC) NULL);
   4863   assert(highlight_info != (RectangleInfo *) NULL);
   4864   if ((highlight_info->width < 4) || (highlight_info->height < 4))
   4865     return;
   4866   (void) XDrawRectangle(display,window,annotate_context,(int) highlight_info->x,
   4867     (int) highlight_info->y,(unsigned int) highlight_info->width-1,
   4868     (unsigned int) highlight_info->height-1);
   4869   (void) XDrawRectangle(display,window,annotate_context,(int) highlight_info->x+
   4870     1,(int) highlight_info->y+1,(unsigned int) highlight_info->width-3,
   4871     (unsigned int) highlight_info->height-3);
   4872 }
   4873 
   4874 /*
   4876 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4877 %                                                                             %
   4878 %                                                                             %
   4879 %                                                                             %
   4880 %   X I m p o r t I m a g e                                                   %
   4881 %                                                                             %
   4882 %                                                                             %
   4883 %                                                                             %
   4884 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   4885 %
   4886 %  XImportImage() reads an image from an X window.
   4887 %
   4888 %  The format of the XImportImage method is:
   4889 %
   4890 %      Image *XImportImage(const ImageInfo *image_info,XImportInfo *ximage_info,
   4891 %        ExceptionInfo *exception)
   4892 %
   4893 %  A description of each parameter follows:
   4894 %
   4895 %    o image_info: the image info.
   4896 %
   4897 %    o ximage_info: Specifies a pointer to an XImportInfo structure.
   4898 %
   4899 %    o exception: return any errors or warnings in this structure.
   4900 %
   4901 */
   4902 MagickExport Image *XImportImage(const ImageInfo *image_info,
   4903   XImportInfo *ximage_info,ExceptionInfo *exception)
   4904 {
   4905   Colormap
   4906     *colormaps;
   4907 
   4908   Display
   4909     *display;
   4910 
   4911   Image
   4912     *image;
   4913 
   4914   int
   4915     number_colormaps,
   4916     number_windows,
   4917     x;
   4918 
   4919   RectangleInfo
   4920     crop_info;
   4921 
   4922   Status
   4923     status;
   4924 
   4925   Window
   4926     *children,
   4927     client,
   4928     prior_target,
   4929     root,
   4930     target;
   4931 
   4932   XTextProperty
   4933     window_name;
   4934 
   4935   /*
   4936     Open X server connection.
   4937   */
   4938   assert(image_info != (const ImageInfo *) NULL);
   4939   assert(image_info->signature == MagickCoreSignature);
   4940   if (image_info->debug != MagickFalse)
   4941     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
   4942       image_info->filename);
   4943   assert(ximage_info != (XImportInfo *) NULL);
   4944   display=XOpenDisplay(image_info->server_name);
   4945   if (display == (Display *) NULL)
   4946     {
   4947       ThrowXWindowException(XServerError,"UnableToOpenXServer",
   4948         XDisplayName(image_info->server_name));
   4949       return((Image *) NULL);
   4950     }
   4951   /*
   4952     Set our forgiving exception handler.
   4953   */
   4954   (void) XSetErrorHandler(XError);
   4955   /*
   4956     Select target window.
   4957   */
   4958   crop_info.x=0;
   4959   crop_info.y=0;
   4960   crop_info.width=0;
   4961   crop_info.height=0;
   4962   root=XRootWindow(display,XDefaultScreen(display));
   4963   target=(Window) NULL;
   4964   if (*image_info->filename != '\0')
   4965     {
   4966       if (LocaleCompare(image_info->filename,"root") == 0)
   4967         target=root;
   4968       else
   4969         {
   4970           /*
   4971             Select window by ID or name.
   4972           */
   4973           if (isdigit((int) ((unsigned char) *image_info->filename)) != 0)
   4974             target=XWindowByID(display,root,(Window)
   4975               strtol(image_info->filename,(char **) NULL,0));
   4976           if (target == (Window) NULL)
   4977             target=XWindowByName(display,root,image_info->filename);
   4978           if (target == (Window) NULL)
   4979             ThrowXWindowException(XServerError,"NoWindowWithSpecifiedIDExists",
   4980               image_info->filename);
   4981         }
   4982     }
   4983   /*
   4984     If target window is not defined, interactively select one.
   4985   */
   4986   prior_target=target;
   4987   if (target == (Window) NULL)
   4988     target=XSelectWindow(display,&crop_info);
   4989   if (target == (Window) NULL)
   4990     ThrowXWindowException(XServerError,"UnableToReadXWindowImage",
   4991       image_info->filename);
   4992   client=target;   /* obsolete */
   4993   if (target != root)
   4994     {
   4995       unsigned int
   4996         d;
   4997 
   4998       status=XGetGeometry(display,target,&root,&x,&x,&d,&d,&d,&d);
   4999       if (status != False)
   5000         {
   5001           for ( ; ; )
   5002           {
   5003             Window
   5004               parent;
   5005 
   5006             /*
   5007               Find window manager frame.
   5008             */
   5009             status=XQueryTree(display,target,&root,&parent,&children,&d);
   5010             if ((status != False) && (children != (Window *) NULL))
   5011               (void) XFree((char *) children);
   5012             if ((status == False) || (parent == (Window) NULL) ||
   5013                 (parent == root))
   5014               break;
   5015             target=parent;
   5016           }
   5017           /*
   5018             Get client window.
   5019           */
   5020           client=XClientWindow(display,target);
   5021           if (ximage_info->frame == MagickFalse)
   5022             target=client;
   5023           if ((ximage_info->frame == MagickFalse) &&
   5024               (prior_target != MagickFalse))
   5025             target=prior_target;
   5026         }
   5027     }
   5028   if (ximage_info->screen)
   5029     {
   5030       int
   5031         y;
   5032 
   5033       Window
   5034         child;
   5035 
   5036       XWindowAttributes
   5037         window_attributes;
   5038 
   5039       /*
   5040         Obtain window image directly from screen.
   5041       */
   5042       status=XGetWindowAttributes(display,target,&window_attributes);
   5043       if (status == False)
   5044         {
   5045           ThrowXWindowException(XServerError,"UnableToReadXWindowAttributes",
   5046             image_info->filename);
   5047           (void) XCloseDisplay(display);
   5048           return((Image *) NULL);
   5049         }
   5050       (void) XTranslateCoordinates(display,target,root,0,0,&x,&y,&child);
   5051       crop_info.x=(ssize_t) x;
   5052       crop_info.y=(ssize_t) y;
   5053       crop_info.width=(size_t) window_attributes.width;
   5054       crop_info.height=(size_t) window_attributes.height;
   5055       if (ximage_info->borders != 0)
   5056         {
   5057           /*
   5058             Include border in image.
   5059           */
   5060           crop_info.x-=window_attributes.border_width;
   5061           crop_info.y-=window_attributes.border_width;
   5062           crop_info.width+=window_attributes.border_width << 1;
   5063           crop_info.height+=window_attributes.border_width << 1;
   5064         }
   5065       target=root;
   5066     }
   5067   /*
   5068     If WM_COLORMAP_WINDOWS property is set or multiple colormaps, descend.
   5069   */
   5070   number_windows=0;
   5071   status=XGetWMColormapWindows(display,target,&children,&number_windows);
   5072   if ((status == True) && (number_windows > 0))
   5073     {
   5074       ximage_info->descend=MagickTrue;
   5075       (void) XFree ((char *) children);
   5076     }
   5077   colormaps=XListInstalledColormaps(display,target,&number_colormaps);
   5078   if (number_colormaps > 0)
   5079     {
   5080       if (number_colormaps > 1)
   5081         ximage_info->descend=MagickTrue;
   5082       (void) XFree((char *) colormaps);
   5083     }
   5084   /*
   5085     Alert the user not to alter the screen.
   5086   */
   5087   if (ximage_info->silent == MagickFalse)
   5088     (void) XBell(display,0);
   5089   /*
   5090     Get image by window id.
   5091   */
   5092   (void) XGrabServer(display);
   5093   image=XGetWindowImage(display,target,ximage_info->borders,
   5094     ximage_info->descend ? 1U : 0U,exception);
   5095   (void) XUngrabServer(display);
   5096   if (image == (Image *) NULL)
   5097     ThrowXWindowException(XServerError,"UnableToReadXWindowImage",
   5098       image_info->filename)
   5099   else
   5100     {
   5101       (void) CopyMagickString(image->filename,image_info->filename,
   5102         MagickPathExtent);
   5103       if ((crop_info.width != 0) && (crop_info.height != 0))
   5104         {
   5105           Image
   5106             *clone_image,
   5107             *crop_image;
   5108 
   5109           /*
   5110             Crop image as defined by the cropping rectangle.
   5111           */
   5112           clone_image=CloneImage(image,0,0,MagickTrue,exception);
   5113           if (clone_image != (Image *) NULL)
   5114             {
   5115               crop_image=CropImage(clone_image,&crop_info,exception);
   5116               if (crop_image != (Image *) NULL)
   5117                 {
   5118                   image=DestroyImage(image);
   5119                   image=crop_image;
   5120                 }
   5121             }
   5122         }
   5123       status=XGetWMName(display,target,&window_name);
   5124       if (status == True)
   5125         {
   5126           if (*image_info->filename == '\0')
   5127             (void) CopyMagickString(image->filename,(char *) window_name.value,
   5128               (size_t) window_name.nitems+1);
   5129           (void) XFree((void *) window_name.value);
   5130         }
   5131     }
   5132   if (ximage_info->silent == MagickFalse)
   5133     {
   5134       /*
   5135         Alert the user we're done.
   5136       */
   5137       (void) XBell(display,0);
   5138       (void) XBell(display,0);
   5139     }
   5140   (void) XCloseDisplay(display);
   5141   return(image);
   5142 }
   5143 
   5144 /*
   5146 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5147 %                                                                             %
   5148 %                                                                             %
   5149 %                                                                             %
   5150 %   X I n i t i a l i z e W i n d o w s                                       %
   5151 %                                                                             %
   5152 %                                                                             %
   5153 %                                                                             %
   5154 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5155 %
   5156 %  XInitializeWindows() initializes the XWindows structure.
   5157 %
   5158 %  The format of the XInitializeWindows method is:
   5159 %
   5160 %      XWindows *XInitializeWindows(Display *display,
   5161 %        XResourceInfo *resource_info)
   5162 %
   5163 %  A description of each parameter follows:
   5164 %
   5165 %    o windows: XInitializeWindows returns a pointer to a XWindows structure.
   5166 %
   5167 %    o display: Specifies a connection to an X server;  returned from
   5168 %      XOpenDisplay.
   5169 %
   5170 %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
   5171 %
   5172 */
   5173 MagickPrivate XWindows *XInitializeWindows(Display *display,
   5174   XResourceInfo *resource_info)
   5175 {
   5176   Window
   5177     root_window;
   5178 
   5179   XWindows
   5180     *windows;
   5181 
   5182   /*
   5183     Allocate windows structure.
   5184   */
   5185   windows=(XWindows *) AcquireMagickMemory(sizeof(*windows));
   5186   if (windows == (XWindows *) NULL)
   5187     {
   5188       ThrowXWindowFatalException(XServerFatalError,"MemoryAllocationFailed",
   5189         "...");
   5190       return((XWindows *) NULL);
   5191     }
   5192   (void) ResetMagickMemory(windows,0,sizeof(*windows));
   5193   windows->pixel_info=(XPixelInfo *) AcquireMagickMemory(
   5194     sizeof(*windows->pixel_info));
   5195   windows->icon_pixel=(XPixelInfo *) AcquireMagickMemory(
   5196     sizeof(*windows->icon_pixel));
   5197   windows->icon_resources=(XResourceInfo *) AcquireMagickMemory(
   5198     sizeof(*windows->icon_resources));
   5199   if ((windows->pixel_info == (XPixelInfo *) NULL) ||
   5200       (windows->icon_pixel == (XPixelInfo *) NULL) ||
   5201       (windows->icon_resources == (XResourceInfo *) NULL))
   5202     {
   5203       ThrowXWindowFatalException(XServerFatalError,"MemoryAllocationFailed",
   5204         "...");
   5205       return((XWindows *) NULL);
   5206     }
   5207   /*
   5208     Initialize windows structure.
   5209   */
   5210   windows->display=display;
   5211   windows->wm_protocols=XInternAtom(display,"WM_PROTOCOLS",MagickFalse);
   5212   windows->wm_delete_window=XInternAtom(display,"WM_DELETE_WINDOW",MagickFalse);
   5213   windows->wm_take_focus=XInternAtom(display,"WM_TAKE_FOCUS",MagickFalse);
   5214   windows->im_protocols=XInternAtom(display,"IM_PROTOCOLS",MagickFalse);
   5215   windows->im_remote_command=
   5216     XInternAtom(display,"IM_REMOTE_COMMAND",MagickFalse);
   5217   windows->im_update_widget=XInternAtom(display,"IM_UPDATE_WIDGET",MagickFalse);
   5218   windows->im_update_colormap=
   5219     XInternAtom(display,"IM_UPDATE_COLORMAP",MagickFalse);
   5220   windows->im_former_image=XInternAtom(display,"IM_FORMER_IMAGE",MagickFalse);
   5221   windows->im_next_image=XInternAtom(display,"IM_NEXT_IMAGE",MagickFalse);
   5222   windows->im_retain_colors=XInternAtom(display,"IM_RETAIN_COLORS",MagickFalse);
   5223   windows->im_exit=XInternAtom(display,"IM_EXIT",MagickFalse);
   5224   windows->dnd_protocols=XInternAtom(display,"DndProtocol",MagickFalse);
   5225 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
   5226   (void) XSynchronize(display,IsWindows95());
   5227 #endif
   5228   if (IsEventLogging())
   5229     {
   5230       (void) XSynchronize(display,MagickTrue);
   5231       (void) LogMagickEvent(X11Event,GetMagickModule(),"Version: %s",
   5232         GetMagickVersion((size_t *) NULL));
   5233       (void) LogMagickEvent(X11Event,GetMagickModule(),"Protocols:");
   5234       (void) LogMagickEvent(X11Event,GetMagickModule(),
   5235         "  Window Manager: 0x%lx",windows->wm_protocols);
   5236       (void) LogMagickEvent(X11Event,GetMagickModule(),
   5237         "    delete window: 0x%lx",windows->wm_delete_window);
   5238       (void) LogMagickEvent(X11Event,GetMagickModule(),"    take focus: 0x%lx",
   5239         windows->wm_take_focus);
   5240       (void) LogMagickEvent(X11Event,GetMagickModule(),"  ImageMagick: 0x%lx",
   5241         windows->im_protocols);
   5242       (void) LogMagickEvent(X11Event,GetMagickModule(),
   5243         "    remote command: 0x%lx",windows->im_remote_command);
   5244       (void) LogMagickEvent(X11Event,GetMagickModule(),
   5245         "    update widget: 0x%lx",windows->im_update_widget);
   5246       (void) LogMagickEvent(X11Event,GetMagickModule(),
   5247         "    update colormap: 0x%lx",windows->im_update_colormap);
   5248       (void) LogMagickEvent(X11Event,GetMagickModule(),
   5249         "    former image: 0x%lx",windows->im_former_image);
   5250       (void) LogMagickEvent(X11Event,GetMagickModule(),"    next image: 0x%lx",
   5251         windows->im_next_image);
   5252       (void) LogMagickEvent(X11Event,GetMagickModule(),
   5253         "    retain colors: 0x%lx",windows->im_retain_colors);
   5254       (void) LogMagickEvent(X11Event,GetMagickModule(),"    exit: 0x%lx",
   5255         windows->im_exit);
   5256       (void) LogMagickEvent(X11Event,GetMagickModule(),"  Drag and Drop: 0x%lx",
   5257         windows->dnd_protocols);
   5258     }
   5259   /*
   5260     Allocate standard colormap.
   5261   */
   5262   windows->map_info=XAllocStandardColormap();
   5263   windows->icon_map=XAllocStandardColormap();
   5264   if ((windows->map_info == (XStandardColormap *) NULL) ||
   5265       (windows->icon_map == (XStandardColormap *) NULL))
   5266     ThrowXWindowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
   5267       "...");
   5268   windows->map_info->colormap=(Colormap) NULL;
   5269   windows->icon_map->colormap=(Colormap) NULL;
   5270   windows->pixel_info->pixels=(unsigned long *) NULL;
   5271   windows->pixel_info->annotate_context=(GC) NULL;
   5272   windows->pixel_info->highlight_context=(GC) NULL;
   5273   windows->pixel_info->widget_context=(GC) NULL;
   5274   windows->font_info=(XFontStruct *) NULL;
   5275   windows->icon_pixel->annotate_context=(GC) NULL;
   5276   windows->icon_pixel->pixels=(unsigned long *) NULL;
   5277   /*
   5278     Allocate visual.
   5279   */
   5280   *windows->icon_resources=(*resource_info);
   5281   windows->icon_resources->visual_type=(char *) "default";
   5282   windows->icon_resources->colormap=SharedColormap;
   5283   windows->visual_info=
   5284     XBestVisualInfo(display,windows->map_info,resource_info);
   5285   windows->icon_visual=
   5286     XBestVisualInfo(display,windows->icon_map,windows->icon_resources);
   5287   if ((windows->visual_info == (XVisualInfo *) NULL) ||
   5288       (windows->icon_visual == (XVisualInfo *) NULL))
   5289     ThrowXWindowFatalException(XServerFatalError,"UnableToGetVisual",
   5290       resource_info->visual_type);
   5291   if (IsEventLogging())
   5292     {
   5293       (void) LogMagickEvent(X11Event,GetMagickModule(),"Visual:");
   5294       (void) LogMagickEvent(X11Event,GetMagickModule(),"  visual id: 0x%lx",
   5295         windows->visual_info->visualid);
   5296       (void) LogMagickEvent(X11Event,GetMagickModule(),"  class: %s",
   5297         XVisualClassName(windows->visual_info->klass));
   5298       (void) LogMagickEvent(X11Event,GetMagickModule(),"  depth: %d planes",
   5299         windows->visual_info->depth);
   5300       (void) LogMagickEvent(X11Event,GetMagickModule(),
   5301         "  size of colormap: %d entries",windows->visual_info->colormap_size);
   5302       (void) LogMagickEvent(X11Event,GetMagickModule(),
   5303         "  red, green, blue masks: 0x%lx 0x%lx 0x%lx",
   5304         windows->visual_info->red_mask,windows->visual_info->green_mask,
   5305         windows->visual_info->blue_mask);
   5306       (void) LogMagickEvent(X11Event,GetMagickModule(),
   5307         "  significant bits in color: %d bits",
   5308         windows->visual_info->bits_per_rgb);
   5309     }
   5310   /*
   5311     Allocate class and manager hints.
   5312   */
   5313   windows->class_hints=XAllocClassHint();
   5314   windows->manager_hints=XAllocWMHints();
   5315   if ((windows->class_hints == (XClassHint *) NULL) ||
   5316       (windows->manager_hints == (XWMHints *) NULL))
   5317     ThrowXWindowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
   5318       "...");
   5319   /*
   5320     Determine group leader if we have one.
   5321   */
   5322   root_window=XRootWindow(display,windows->visual_info->screen);
   5323   windows->group_leader.id=(Window) NULL;
   5324   if (resource_info->window_group != (char *) NULL)
   5325     {
   5326       if (isdigit((int) ((unsigned char) *resource_info->window_group)) != 0)
   5327         windows->group_leader.id=XWindowByID(display,root_window,(Window)
   5328           strtol((char *) resource_info->window_group,(char **) NULL,0));
   5329       if (windows->group_leader.id == (Window) NULL)
   5330         windows->group_leader.id=
   5331           XWindowByName(display,root_window,resource_info->window_group);
   5332     }
   5333   return(windows);
   5334 }
   5335 
   5336 /*
   5338 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5339 %                                                                             %
   5340 %                                                                             %
   5341 %                                                                             %
   5342 %   X M a k e C u r s o r                                                     %
   5343 %                                                                             %
   5344 %                                                                             %
   5345 %                                                                             %
   5346 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5347 %
   5348 %  XMakeCursor() creates a crosshairs X11 cursor.
   5349 %
   5350 %  The format of the XMakeCursor method is:
   5351 %
   5352 %      Cursor XMakeCursor(Display *display,Window window,Colormap colormap,
   5353 %        char *background_color,char *foreground_color)
   5354 %
   5355 %  A description of each parameter follows:
   5356 %
   5357 %    o display: Specifies a connection to an X server;  returned from
   5358 %      XOpenDisplay.
   5359 %
   5360 %    o window: Specifies the ID of the window for which the cursor is
   5361 %      assigned.
   5362 %
   5363 %    o colormap: Specifies the ID of the colormap from which the background
   5364 %      and foreground color will be retrieved.
   5365 %
   5366 %    o background_color: Specifies the color to use for the cursor background.
   5367 %
   5368 %    o foreground_color: Specifies the color to use for the cursor foreground.
   5369 %
   5370 */
   5371 MagickPrivate Cursor XMakeCursor(Display *display,Window window,
   5372   Colormap colormap,char *background_color,char *foreground_color)
   5373 {
   5374 #define scope_height 17
   5375 #define scope_x_hot 8
   5376 #define scope_y_hot 8
   5377 #define scope_width 17
   5378 
   5379   static const unsigned char
   5380     scope_bits[] =
   5381     {
   5382       0x80, 0x03, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02,
   5383       0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x7f,
   5384       0xfc, 0x01, 0x01, 0x00, 0x01, 0x7f, 0xfc, 0x01, 0x80, 0x02, 0x00,
   5385       0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02,
   5386       0x00, 0x80, 0x02, 0x00, 0x80, 0x03, 0x00
   5387     },
   5388     scope_mask_bits[] =
   5389     {
   5390       0xc0, 0x07, 0x00, 0xc0, 0x07, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06,
   5391       0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xff, 0xfe, 0x01, 0x7f,
   5392       0xfc, 0x01, 0x03, 0x80, 0x01, 0x7f, 0xfc, 0x01, 0xff, 0xfe, 0x01,
   5393       0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06,
   5394       0x00, 0xc0, 0x07, 0x00, 0xc0, 0x07, 0x00
   5395     };
   5396 
   5397   Cursor
   5398     cursor;
   5399 
   5400   Pixmap
   5401     mask,
   5402     source;
   5403 
   5404   XColor
   5405     background,
   5406     foreground;
   5407 
   5408   assert(display != (Display *) NULL);
   5409   assert(window != (Window) NULL);
   5410   assert(colormap != (Colormap) NULL);
   5411   assert(background_color != (char *) NULL);
   5412   assert(foreground_color != (char *) NULL);
   5413   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",background_color);
   5414   source=XCreateBitmapFromData(display,window,(char *) scope_bits,scope_width,
   5415     scope_height);
   5416   mask=XCreateBitmapFromData(display,window,(char *) scope_mask_bits,
   5417     scope_width,scope_height);
   5418   if ((source == (Pixmap) NULL) || (mask == (Pixmap) NULL))
   5419     {
   5420       ThrowXWindowException(XServerError,"UnableToCreatePixmap","...");
   5421       return((Cursor) NULL);
   5422     }
   5423   (void) XParseColor(display,colormap,background_color,&background);
   5424   (void) XParseColor(display,colormap,foreground_color,&foreground);
   5425   cursor=XCreatePixmapCursor(display,source,mask,&foreground,&background,
   5426     scope_x_hot,scope_y_hot);
   5427   (void) XFreePixmap(display,source);
   5428   (void) XFreePixmap(display,mask);
   5429   return(cursor);
   5430 }
   5431 
   5432 /*
   5434 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5435 %                                                                             %
   5436 %                                                                             %
   5437 %                                                                             %
   5438 %   X M a k e I m a g e                                                       %
   5439 %                                                                             %
   5440 %                                                                             %
   5441 %                                                                             %
   5442 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5443 %
   5444 %  XMakeImage() creates an X11 image.  If the image size differs from the X11
   5445 %  image size, the image is first resized.
   5446 %
   5447 %  The format of the XMakeImage method is:
   5448 %
   5449 %      MagickBooleanType XMakeImage(Display *display,
   5450 %        const XResourceInfo *resource_info,XWindowInfo *window,Image *image,
   5451 %        unsigned int width,unsigned int height,ExceptionInfo *exception)
   5452 %
   5453 %  A description of each parameter follows:
   5454 %
   5455 %    o display: Specifies a connection to an X server; returned from
   5456 %      XOpenDisplay.
   5457 %
   5458 %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
   5459 %
   5460 %    o window: Specifies a pointer to a XWindowInfo structure.
   5461 %
   5462 %    o image: the image.
   5463 %
   5464 %    o width: Specifies the width in pixels of the rectangular area to
   5465 %      display.
   5466 %
   5467 %    o height: Specifies the height in pixels of the rectangular area to
   5468 %      display.
   5469 %
   5470 %    o exception: return any errors or warnings in this structure.
   5471 %
   5472 */
   5473 MagickPrivate MagickBooleanType XMakeImage(Display *display,
   5474   const XResourceInfo *resource_info,XWindowInfo *window,Image *image,
   5475   unsigned int width,unsigned int height,ExceptionInfo *exception)
   5476 {
   5477 #define CheckOverflowException(length,width,height) \
   5478   (((height) != 0) && ((length)/((size_t) height) != ((size_t) width)))
   5479 
   5480   int
   5481     depth,
   5482     format;
   5483 
   5484   size_t
   5485     length;
   5486 
   5487   XImage
   5488     *matte_image,
   5489     *ximage;
   5490 
   5491   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   5492   assert(display != (Display *) NULL);
   5493   assert(resource_info != (XResourceInfo *) NULL);
   5494   assert(window != (XWindowInfo *) NULL);
   5495   assert(width != 0);
   5496   assert(height != 0);
   5497   if ((window->width == 0) || (window->height == 0))
   5498     return(MagickFalse);
   5499   /*
   5500     Apply user transforms to the image.
   5501   */
   5502   (void) XCheckDefineCursor(display,window->id,window->busy_cursor);
   5503   (void) XFlush(display);
   5504   depth=(int) window->depth;
   5505   if (window->destroy)
   5506     window->image=DestroyImage(window->image);
   5507   window->image=image;
   5508   window->destroy=MagickFalse;
   5509   if (window->image != (Image *) NULL)
   5510     {
   5511       if (window->crop_geometry != (char *) NULL)
   5512         {
   5513           Image
   5514             *crop_image;
   5515 
   5516           RectangleInfo
   5517             crop_info;
   5518 
   5519           /*
   5520             Crop image.
   5521           */
   5522           window->image->page.x=0;
   5523           window->image->page.y=0;
   5524           (void) ParsePageGeometry(window->image,window->crop_geometry,
   5525             &crop_info,exception);
   5526           crop_image=CropImage(window->image,&crop_info,exception);
   5527           if (crop_image != (Image *) NULL)
   5528             {
   5529               if (window->image != image)
   5530                 window->image=DestroyImage(window->image);
   5531               window->image=crop_image;
   5532               window->destroy=MagickTrue;
   5533             }
   5534         }
   5535       if ((width != (unsigned int) window->image->columns) ||
   5536           (height != (unsigned int) window->image->rows))
   5537         {
   5538           Image
   5539             *resize_image;
   5540 
   5541           /*
   5542             Resize image.
   5543           */
   5544           resize_image=NewImageList();
   5545           if ((window->pixel_info->colors == 0) &&
   5546               (window->image->rows > (unsigned long) XDisplayHeight(display,window->screen)) &&
   5547               (window->image->columns > (unsigned long) XDisplayWidth(display,window->screen)))
   5548               resize_image=ResizeImage(window->image,width,height,
   5549                 image->filter,exception);
   5550           else
   5551             {
   5552               if (window->image->storage_class == PseudoClass)
   5553                 resize_image=SampleImage(window->image,width,height,
   5554                   exception);
   5555               else
   5556                 resize_image=ThumbnailImage(window->image,width,height,
   5557                   exception);
   5558             }
   5559           if (resize_image != (Image *) NULL)
   5560             {
   5561               if (window->image != image)
   5562                 window->image=DestroyImage(window->image);
   5563               window->image=resize_image;
   5564               window->destroy=MagickTrue;
   5565             }
   5566         }
   5567       width=(unsigned int) window->image->columns;
   5568       assert((size_t) width == window->image->columns);
   5569       height=(unsigned int) window->image->rows;
   5570       assert((size_t) height == window->image->rows);
   5571     }
   5572   /*
   5573     Create X image.
   5574   */
   5575   ximage=(XImage *) NULL;
   5576   format=(depth == 1) ? XYBitmap : ZPixmap;
   5577 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
   5578   if (window->shared_memory != MagickFalse)
   5579     {
   5580       XShmSegmentInfo
   5581         *segment_info;
   5582 
   5583       segment_info=(XShmSegmentInfo *) window->segment_info;
   5584       segment_info[1].shmid=(-1);
   5585       segment_info[1].shmaddr=(char *) NULL;
   5586       ximage=XShmCreateImage(display,window->visual,(unsigned int) depth,format,
   5587         (char *) NULL,&segment_info[1],width,height);
   5588       if (ximage == (XImage *) NULL)
   5589         window->shared_memory=MagickFalse;
   5590       else
   5591         {
   5592           length=(size_t) ximage->bytes_per_line*ximage->height;
   5593           if (CheckOverflowException(length,ximage->bytes_per_line,ximage->height))
   5594             window->shared_memory=MagickFalse;
   5595         }
   5596       if (window->shared_memory != MagickFalse)
   5597         segment_info[1].shmid=shmget(IPC_PRIVATE,length,IPC_CREAT | 0777);
   5598       if (window->shared_memory != MagickFalse)
   5599         segment_info[1].shmaddr=(char *) shmat(segment_info[1].shmid,0,0);
   5600       if (segment_info[1].shmid < 0)
   5601         window->shared_memory=MagickFalse;
   5602       if (window->shared_memory != MagickFalse)
   5603         (void) shmctl(segment_info[1].shmid,IPC_RMID,0);
   5604       else
   5605         {
   5606           if (ximage != (XImage *) NULL)
   5607             XDestroyImage(ximage);
   5608           ximage=(XImage *) NULL;
   5609           if (segment_info[1].shmaddr)
   5610             {
   5611               (void) shmdt(segment_info[1].shmaddr);
   5612               segment_info[1].shmaddr=(char *) NULL;
   5613             }
   5614           if (segment_info[1].shmid >= 0)
   5615             {
   5616               (void) shmctl(segment_info[1].shmid,IPC_RMID,0);
   5617               segment_info[1].shmid=(-1);
   5618             }
   5619         }
   5620     }
   5621 #endif
   5622   /*
   5623     Allocate X image pixel data.
   5624   */
   5625 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
   5626   if (window->shared_memory)
   5627     {
   5628       Status
   5629         status;
   5630 
   5631       XShmSegmentInfo
   5632         *segment_info;
   5633 
   5634       (void) XSync(display,MagickFalse);
   5635       xerror_alert=MagickFalse;
   5636       segment_info=(XShmSegmentInfo *) window->segment_info;
   5637       ximage->data=segment_info[1].shmaddr;
   5638       segment_info[1].readOnly=MagickFalse;
   5639       status=XShmAttach(display,&segment_info[1]);
   5640       if (status != False)
   5641         (void) XSync(display,MagickFalse);
   5642       if ((status == False) || (xerror_alert != MagickFalse))
   5643         {
   5644           window->shared_memory=MagickFalse;
   5645           if (status != False)
   5646             XShmDetach(display,&segment_info[1]);
   5647           ximage->data=NULL;
   5648           XDestroyImage(ximage);
   5649           ximage=(XImage *) NULL;
   5650           if (segment_info[1].shmid >= 0)
   5651             {
   5652               if (segment_info[1].shmaddr != NULL)
   5653                 (void) shmdt(segment_info[1].shmaddr);
   5654               (void) shmctl(segment_info[1].shmid,IPC_RMID,0);
   5655               segment_info[1].shmid=(-1);
   5656               segment_info[1].shmaddr=(char *) NULL;
   5657             }
   5658         }
   5659     }
   5660 #endif
   5661   if (window->shared_memory == MagickFalse)
   5662     ximage=XCreateImage(display,window->visual,(unsigned int) depth,format,0,
   5663       (char *) NULL,width,height,XBitmapPad(display),0);
   5664   if (ximage == (XImage *) NULL)
   5665     {
   5666       /*
   5667         Unable to create X image.
   5668       */
   5669       (void) XCheckDefineCursor(display,window->id,window->cursor);
   5670       return(MagickFalse);
   5671     }
   5672   length=(size_t) ximage->bytes_per_line*ximage->height;
   5673   if (IsEventLogging())
   5674     {
   5675       (void) LogMagickEvent(X11Event,GetMagickModule(),"XImage:");
   5676       (void) LogMagickEvent(X11Event,GetMagickModule(),"  width, height: %dx%d",
   5677         ximage->width,ximage->height);
   5678       (void) LogMagickEvent(X11Event,GetMagickModule(),"  format: %d",
   5679         ximage->format);
   5680       (void) LogMagickEvent(X11Event,GetMagickModule(),"  byte order: %d",
   5681         ximage->byte_order);
   5682       (void) LogMagickEvent(X11Event,GetMagickModule(),
   5683         "  bitmap unit, bit order, pad: %d %d %d",ximage->bitmap_unit,
   5684         ximage->bitmap_bit_order,ximage->bitmap_pad);
   5685       (void) LogMagickEvent(X11Event,GetMagickModule(),"  depth: %d",
   5686         ximage->depth);
   5687       (void) LogMagickEvent(X11Event,GetMagickModule(),"  bytes per line: %d",
   5688         ximage->bytes_per_line);
   5689       (void) LogMagickEvent(X11Event,GetMagickModule(),"  bits per pixel: %d",
   5690         ximage->bits_per_pixel);
   5691       (void) LogMagickEvent(X11Event,GetMagickModule(),
   5692         "  red, green, blue masks: 0x%lx 0x%lx 0x%lx",ximage->red_mask,
   5693         ximage->green_mask,ximage->blue_mask);
   5694     }
   5695   if (window->shared_memory == MagickFalse)
   5696     {
   5697       if (ximage->format != XYBitmap)
   5698         ximage->data=(char *) malloc((size_t) ximage->bytes_per_line*
   5699           ximage->height);
   5700       else
   5701         ximage->data=(char *) malloc((size_t) ximage->bytes_per_line*
   5702           ximage->depth*ximage->height);
   5703     }
   5704   if (ximage->data == (char *) NULL)
   5705     {
   5706       /*
   5707         Unable to allocate pixel data.
   5708       */
   5709       XDestroyImage(ximage);
   5710       ximage=(XImage *) NULL;
   5711       (void) XCheckDefineCursor(display,window->id,window->cursor);
   5712       return(MagickFalse);
   5713     }
   5714   if (window->ximage != (XImage *) NULL)
   5715     {
   5716       /*
   5717         Destroy previous X image.
   5718       */
   5719       length=(size_t) window->ximage->bytes_per_line*window->ximage->height;
   5720 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
   5721       if (window->segment_info != (XShmSegmentInfo *) NULL)
   5722         {
   5723           XShmSegmentInfo
   5724             *segment_info;
   5725 
   5726           segment_info=(XShmSegmentInfo *) window->segment_info;
   5727           if (segment_info[0].shmid >= 0)
   5728             {
   5729               (void) XSync(display,MagickFalse);
   5730               (void) XShmDetach(display,&segment_info[0]);
   5731               (void) XSync(display,MagickFalse);
   5732               if (segment_info[0].shmaddr != (char *) NULL)
   5733                 (void) shmdt(segment_info[0].shmaddr);
   5734               (void) shmctl(segment_info[0].shmid,IPC_RMID,0);
   5735               segment_info[0].shmid=(-1);
   5736               segment_info[0].shmaddr=(char *) NULL;
   5737               window->ximage->data=(char *) NULL;
   5738           }
   5739         }
   5740 #endif
   5741       if (window->ximage->data != (char *) NULL)
   5742         free(window->ximage->data);
   5743       window->ximage->data=(char *) NULL;
   5744       XDestroyImage(window->ximage);
   5745       window->ximage=(XImage *) NULL;
   5746     }
   5747 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
   5748   if (window->segment_info != (XShmSegmentInfo *) NULL)
   5749     {
   5750       XShmSegmentInfo
   5751         *segment_info;
   5752 
   5753       segment_info=(XShmSegmentInfo *) window->segment_info;
   5754       segment_info[0]=segment_info[1];
   5755     }
   5756 #endif
   5757   window->ximage=ximage;
   5758   matte_image=(XImage *) NULL;
   5759   if ((window->shape != MagickFalse) && (window->image != (Image *) NULL))
   5760     if ((window->image->alpha_trait != UndefinedPixelTrait) &&
   5761         ((int) width <= XDisplayWidth(display,window->screen)) &&
   5762         ((int) height <= XDisplayHeight(display,window->screen)))
   5763       {
   5764         /*
   5765           Create matte image.
   5766         */
   5767         matte_image=XCreateImage(display,window->visual,1,XYBitmap,0,
   5768           (char *) NULL,width,height,XBitmapPad(display),0);
   5769         if (IsEventLogging())
   5770           {
   5771             (void) LogMagickEvent(X11Event,GetMagickModule(),"Matte Image:");
   5772             (void) LogMagickEvent(X11Event,GetMagickModule(),
   5773               "  width, height: %dx%d",matte_image->width,matte_image->height);
   5774           }
   5775         if (matte_image != (XImage *) NULL)
   5776           {
   5777             /*
   5778               Allocate matte image pixel data.
   5779             */
   5780             matte_image->data=(char *) malloc((size_t)
   5781               matte_image->bytes_per_line*matte_image->depth*
   5782               matte_image->height);
   5783             if (matte_image->data == (char *) NULL)
   5784               {
   5785                 XDestroyImage(matte_image);
   5786                 matte_image=(XImage *) NULL;
   5787               }
   5788           }
   5789       }
   5790   if (window->matte_image != (XImage *) NULL)
   5791     {
   5792       /*
   5793         Free matte image.
   5794       */
   5795       if (window->matte_image->data != (char *) NULL)
   5796         free(window->matte_image->data);
   5797       window->matte_image->data=(char *) NULL;
   5798       XDestroyImage(window->matte_image);
   5799       window->matte_image=(XImage *) NULL;
   5800     }
   5801   window->matte_image=matte_image;
   5802   if (window->matte_pixmap != (Pixmap) NULL)
   5803     {
   5804       (void) XFreePixmap(display,window->matte_pixmap);
   5805       window->matte_pixmap=(Pixmap) NULL;
   5806 #if defined(MAGICKCORE_HAVE_SHAPE)
   5807       if (window->shape != MagickFalse)
   5808         XShapeCombineMask(display,window->id,ShapeBounding,0,0,None,ShapeSet);
   5809 #endif
   5810     }
   5811   window->stasis=MagickFalse;
   5812   /*
   5813     Convert pixels to X image data.
   5814   */
   5815   if (window->image != (Image *) NULL)
   5816     {
   5817       if ((ximage->byte_order == LSBFirst) || ((ximage->format == XYBitmap) &&
   5818           (ximage->bitmap_bit_order == LSBFirst)))
   5819         XMakeImageLSBFirst(resource_info,window,window->image,ximage,
   5820           matte_image,exception);
   5821       else
   5822         XMakeImageMSBFirst(resource_info,window,window->image,ximage,
   5823           matte_image,exception);
   5824     }
   5825   if (window->matte_image != (XImage *) NULL)
   5826     {
   5827       /*
   5828         Create matte pixmap.
   5829       */
   5830       window->matte_pixmap=XCreatePixmap(display,window->id,width,height,1);
   5831       if (window->matte_pixmap != (Pixmap) NULL)
   5832         {
   5833           GC
   5834             graphics_context;
   5835 
   5836           XGCValues
   5837             context_values;
   5838 
   5839           /*
   5840             Copy matte image to matte pixmap.
   5841           */
   5842           context_values.background=0;
   5843           context_values.foreground=1;
   5844           graphics_context=XCreateGC(display,window->matte_pixmap,
   5845             (size_t) (GCBackground | GCForeground),&context_values);
   5846           (void) XPutImage(display,window->matte_pixmap,graphics_context,
   5847             window->matte_image,0,0,0,0,width,height);
   5848           (void) XFreeGC(display,graphics_context);
   5849 #if defined(MAGICKCORE_HAVE_SHAPE)
   5850           if (window->shape != MagickFalse)
   5851             XShapeCombineMask(display,window->id,ShapeBounding,0,0,
   5852               window->matte_pixmap,ShapeSet);
   5853 #endif
   5854         }
   5855       }
   5856   (void) XMakePixmap(display,resource_info,window);
   5857   /*
   5858     Restore cursor.
   5859   */
   5860   (void) XCheckDefineCursor(display,window->id,window->cursor);
   5861   return(MagickTrue);
   5862 }
   5863 
   5864 /*
   5866 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5867 %                                                                             %
   5868 %                                                                             %
   5869 %                                                                             %
   5870 +   X M a k e I m a g e L S B F i r s t                                       %
   5871 %                                                                             %
   5872 %                                                                             %
   5873 %                                                                             %
   5874 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   5875 %
   5876 %  XMakeImageLSBFirst() initializes the pixel data of an X11 Image. The X image
   5877 %  pixels are copied in least-significant bit and byte first order.  The
   5878 %  server's scanline pad is respected.  Rather than using one or two general
   5879 %  cases, many special cases are found here to help speed up the image
   5880 %  conversion.
   5881 %
   5882 %  The format of the XMakeImageLSBFirst method is:
   5883 %
   5884 %      void XMakeImageLSBFirst(Display *display,XWindows *windows,
   5885 %        ExceptionInfo *exception)
   5886 %
   5887 %  A description of each parameter follows:
   5888 %
   5889 %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
   5890 %
   5891 %    o window: Specifies a pointer to a XWindowInfo structure.
   5892 %
   5893 %    o image: the image.
   5894 %
   5895 %    o ximage: Specifies a pointer to a XImage structure;  returned from
   5896 %      XCreateImage.
   5897 %
   5898 %    o matte_image: Specifies a pointer to a XImage structure;  returned from
   5899 %      XCreateImage.
   5900 %
   5901 %    o exception: return any errors or warnings in this structure.
   5902 %
   5903 */
   5904 static void XMakeImageLSBFirst(const XResourceInfo *resource_info,
   5905   const XWindowInfo *window,Image *image,XImage *ximage,XImage *matte_image,
   5906   ExceptionInfo *exception)
   5907 {
   5908   CacheView
   5909     *canvas_view;
   5910 
   5911   Image
   5912     *canvas;
   5913 
   5914   int
   5915     y;
   5916 
   5917   register const Quantum
   5918     *p;
   5919 
   5920   register int
   5921     x;
   5922 
   5923   register unsigned char
   5924     *q;
   5925 
   5926   unsigned char
   5927     bit,
   5928     byte;
   5929 
   5930   unsigned int
   5931     scanline_pad;
   5932 
   5933   unsigned long
   5934     pixel,
   5935     *pixels;
   5936 
   5937   XStandardColormap
   5938     *map_info;
   5939 
   5940   assert(resource_info != (XResourceInfo *) NULL);
   5941   assert(window != (XWindowInfo *) NULL);
   5942   assert(image != (Image *) NULL);
   5943   if (image->debug != MagickFalse)
   5944     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   5945   canvas=image;
   5946   if ((window->immutable == MagickFalse) &&
   5947       (image->storage_class == DirectClass) && (image->alpha_trait != UndefinedPixelTrait))
   5948     {
   5949       char
   5950         size[MagickPathExtent];
   5951 
   5952       Image
   5953         *pattern;
   5954 
   5955       ImageInfo
   5956         *image_info;
   5957 
   5958       image_info=AcquireImageInfo();
   5959       (void) CopyMagickString(image_info->filename,
   5960         resource_info->image_info->texture != (char *) NULL ?
   5961         resource_info->image_info->texture : "pattern:checkerboard",
   5962         MagickPathExtent);
   5963       (void) FormatLocaleString(size,MagickPathExtent,"%.20gx%.20g",(double)
   5964         image->columns,(double) image->rows);
   5965       image_info->size=ConstantString(size);
   5966       pattern=ReadImage(image_info,exception);
   5967       image_info=DestroyImageInfo(image_info);
   5968       if (pattern != (Image *) NULL)
   5969         {
   5970           canvas=CloneImage(image,0,0,MagickTrue,exception);
   5971           if (canvas != (Image *) NULL)
   5972             (void) CompositeImage(canvas,pattern,DstOverCompositeOp,MagickTrue,
   5973               0,0,exception);
   5974           pattern=DestroyImage(pattern);
   5975         }
   5976     }
   5977   scanline_pad=(unsigned int) (ximage->bytes_per_line-((ximage->width*
   5978     ximage->bits_per_pixel) >> 3));
   5979   map_info=window->map_info;
   5980   pixels=window->pixel_info->pixels;
   5981   q=(unsigned char *) ximage->data;
   5982   x=0;
   5983   canvas_view=AcquireVirtualCacheView(canvas,exception);
   5984   if (ximage->format == XYBitmap)
   5985     {
   5986       register unsigned short
   5987         polarity;
   5988 
   5989       unsigned char
   5990         background,
   5991         foreground;
   5992 
   5993       /*
   5994         Convert canvas to big-endian bitmap.
   5995       */
   5996       background=(unsigned char)
   5997         (XPixelIntensity(&window->pixel_info->foreground_color) <
   5998          XPixelIntensity(&window->pixel_info->background_color) ? 0x80 : 0x00);
   5999       foreground=(unsigned char)
   6000         (XPixelIntensity(&window->pixel_info->background_color) <
   6001          XPixelIntensity(&window->pixel_info->foreground_color) ? 0x80 : 0x00);
   6002       polarity=(unsigned short) ((GetPixelInfoIntensity(image,
   6003         &canvas->colormap[0])) < (QuantumRange/2.0) ? 1 : 0);
   6004       if (canvas->colors == 2)
   6005         polarity=GetPixelInfoIntensity(image,&canvas->colormap[0]) <
   6006           GetPixelInfoIntensity(image,&canvas->colormap[1]);
   6007       for (y=0; y < (int) canvas->rows; y++)
   6008       {
   6009         p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,canvas->columns,1,
   6010           exception);
   6011         if (p == (const Quantum *) NULL)
   6012           break;
   6013         bit=0;
   6014         byte=0;
   6015         for (x=0; x < (int) canvas->columns; x++)
   6016         {
   6017           byte>>=1;
   6018           if (GetPixelIndex(canvas,p) == (Quantum) polarity)
   6019             byte|=foreground;
   6020           else
   6021             byte|=background;
   6022           bit++;
   6023           if (bit == 8)
   6024             {
   6025               *q++=byte;
   6026               bit=0;
   6027               byte=0;
   6028             }
   6029           p+=GetPixelChannels(canvas);
   6030         }
   6031         if (bit != 0)
   6032           *q=byte >> (8-bit);
   6033         q+=scanline_pad;
   6034       }
   6035     }
   6036   else
   6037     if (window->pixel_info->colors != 0)
   6038       switch (ximage->bits_per_pixel)
   6039       {
   6040         case 2:
   6041         {
   6042           register unsigned int
   6043             nibble;
   6044 
   6045           /*
   6046             Convert to 2 bit color-mapped X canvas.
   6047           */
   6048           for (y=0; y < (int) canvas->rows; y++)
   6049           {
   6050             p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
   6051               canvas->columns,1,exception);
   6052             if (p == (const Quantum *) NULL)
   6053               break;
   6054             nibble=0;
   6055             for (x=0; x < (int) canvas->columns; x++)
   6056             {
   6057               pixel=pixels[(ssize_t) GetPixelIndex(canvas,p)] & 0x0f;
   6058               switch (nibble)
   6059               {
   6060                 case 0:
   6061                 {
   6062                   *q=(unsigned char) pixel;
   6063                   nibble++;
   6064                   break;
   6065                 }
   6066                 case 1:
   6067                 {
   6068                   *q|=(unsigned char) (pixel << 2);
   6069                   nibble++;
   6070                   break;
   6071                 }
   6072                 case 2:
   6073                 {
   6074                   *q|=(unsigned char) (pixel << 4);
   6075                   nibble++;
   6076                   break;
   6077                 }
   6078                 case 3:
   6079                 {
   6080                   *q|=(unsigned char) (pixel << 6);
   6081                   q++;
   6082                   nibble=0;
   6083                   break;
   6084                 }
   6085               }
   6086               p+=GetPixelChannels(canvas);
   6087             }
   6088             q+=scanline_pad;
   6089           }
   6090           break;
   6091         }
   6092         case 4:
   6093         {
   6094           register unsigned int
   6095             nibble;
   6096 
   6097           /*
   6098             Convert to 4 bit color-mapped X canvas.
   6099           */
   6100           for (y=0; y < (int) canvas->rows; y++)
   6101           {
   6102             p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
   6103               canvas->columns,1,exception);
   6104             if (p == (const Quantum *) NULL)
   6105               break;
   6106             nibble=0;
   6107             for (x=0; x < (int) canvas->columns; x++)
   6108             {
   6109               pixel=pixels[(ssize_t) GetPixelIndex(canvas,p)] & 0xf;
   6110               switch (nibble)
   6111               {
   6112                 case 0:
   6113                 {
   6114                   *q=(unsigned char) pixel;
   6115                   nibble++;
   6116                   break;
   6117                 }
   6118                 case 1:
   6119                 {
   6120                   *q|=(unsigned char) (pixel << 4);
   6121                   q++;
   6122                   nibble=0;
   6123                   break;
   6124                 }
   6125               }
   6126               p+=GetPixelChannels(canvas);
   6127             }
   6128             q+=scanline_pad;
   6129           }
   6130           break;
   6131         }
   6132         case 6:
   6133         case 8:
   6134         {
   6135           /*
   6136             Convert to 8 bit color-mapped X canvas.
   6137           */
   6138           if (resource_info->color_recovery &&
   6139               resource_info->quantize_info->dither_method != NoDitherMethod)
   6140             {
   6141               XDitherImage(canvas,ximage,exception);
   6142               break;
   6143             }
   6144           for (y=0; y < (int) canvas->rows; y++)
   6145           {
   6146             p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
   6147               canvas->columns,1,exception);
   6148             if (p == (const Quantum *) NULL)
   6149               break;
   6150             for (x=0; x < (int) canvas->columns; x++)
   6151             {
   6152               pixel=pixels[(ssize_t) GetPixelIndex(canvas,p)];
   6153               *q++=(unsigned char) pixel;
   6154               p+=GetPixelChannels(canvas);
   6155             }
   6156             q+=scanline_pad;
   6157           }
   6158           break;
   6159         }
   6160         default:
   6161         {
   6162           register int
   6163             k;
   6164 
   6165           register unsigned int
   6166             bytes_per_pixel;
   6167 
   6168           /*
   6169             Convert to multi-byte color-mapped X canvas.
   6170           */
   6171           bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3);
   6172           for (y=0; y < (int) canvas->rows; y++)
   6173           {
   6174             p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
   6175               canvas->columns,1,exception);
   6176             if (p == (const Quantum *) NULL)
   6177               break;
   6178             for (x=0; x < (int) canvas->columns; x++)
   6179             {
   6180               pixel=pixels[(ssize_t) GetPixelIndex(canvas,p)];
   6181               for (k=0; k < (int) bytes_per_pixel; k++)
   6182               {
   6183                 *q++=(unsigned char) (pixel & 0xff);
   6184                 pixel>>=8;
   6185               }
   6186               p+=GetPixelChannels(canvas);
   6187             }
   6188             q+=scanline_pad;
   6189           }
   6190           break;
   6191         }
   6192       }
   6193     else
   6194       switch (ximage->bits_per_pixel)
   6195       {
   6196         case 2:
   6197         {
   6198           register unsigned int
   6199             nibble;
   6200 
   6201           /*
   6202             Convert to contiguous 2 bit continuous-tone X canvas.
   6203           */
   6204           for (y=0; y < (int) canvas->rows; y++)
   6205           {
   6206             nibble=0;
   6207             p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
   6208               canvas->columns,1,exception);
   6209             if (p == (const Quantum *) NULL)
   6210               break;
   6211             for (x=0; x < (int) canvas->columns; x++)
   6212             {
   6213               pixel=XGammaPixel(canvas,map_info,p);
   6214               pixel&=0xf;
   6215               switch (nibble)
   6216               {
   6217                 case 0:
   6218                 {
   6219                   *q=(unsigned char) pixel;
   6220                   nibble++;
   6221                   break;
   6222                 }
   6223                 case 1:
   6224                 {
   6225                   *q|=(unsigned char) (pixel << 2);
   6226                   nibble++;
   6227                   break;
   6228                 }
   6229                 case 2:
   6230                 {
   6231                   *q|=(unsigned char) (pixel << 4);
   6232                   nibble++;
   6233                   break;
   6234                 }
   6235                 case 3:
   6236                 {
   6237                   *q|=(unsigned char) (pixel << 6);
   6238                   q++;
   6239                   nibble=0;
   6240                   break;
   6241                 }
   6242               }
   6243               p+=GetPixelChannels(canvas);
   6244             }
   6245             q+=scanline_pad;
   6246           }
   6247           break;
   6248         }
   6249         case 4:
   6250         {
   6251           register unsigned int
   6252             nibble;
   6253 
   6254           /*
   6255             Convert to contiguous 4 bit continuous-tone X canvas.
   6256           */
   6257           for (y=0; y < (int) canvas->rows; y++)
   6258           {
   6259             p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
   6260               canvas->columns,1,exception);
   6261             if (p == (const Quantum *) NULL)
   6262               break;
   6263             nibble=0;
   6264             for (x=0; x < (int) canvas->columns; x++)
   6265             {
   6266               pixel=XGammaPixel(canvas,map_info,p);
   6267               pixel&=0xf;
   6268               switch (nibble)
   6269               {
   6270                 case 0:
   6271                 {
   6272                   *q=(unsigned char) pixel;
   6273                   nibble++;
   6274                   break;
   6275                 }
   6276                 case 1:
   6277                 {
   6278                   *q|=(unsigned char) (pixel << 4);
   6279                   q++;
   6280                   nibble=0;
   6281                   break;
   6282                 }
   6283               }
   6284               p+=GetPixelChannels(canvas);
   6285             }
   6286             q+=scanline_pad;
   6287           }
   6288           break;
   6289         }
   6290         case 6:
   6291         case 8:
   6292         {
   6293           /*
   6294             Convert to contiguous 8 bit continuous-tone X canvas.
   6295           */
   6296           if (resource_info->color_recovery &&
   6297               resource_info->quantize_info->dither_method != NoDitherMethod)
   6298             {
   6299               XDitherImage(canvas,ximage,exception);
   6300               break;
   6301             }
   6302           for (y=0; y < (int) canvas->rows; y++)
   6303           {
   6304             p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
   6305               canvas->columns,1,exception);
   6306             if (p == (const Quantum *) NULL)
   6307               break;
   6308             for (x=0; x < (int) canvas->columns; x++)
   6309             {
   6310               pixel=XGammaPixel(canvas,map_info,p);
   6311               *q++=(unsigned char) pixel;
   6312               p+=GetPixelChannels(canvas);
   6313             }
   6314             q+=scanline_pad;
   6315           }
   6316           break;
   6317         }
   6318         default:
   6319         {
   6320           if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) &&
   6321               (map_info->green_max == 255) && (map_info->blue_max == 255) &&
   6322               (map_info->red_mult == 65536L) && (map_info->green_mult == 256) &&
   6323               (map_info->blue_mult == 1))
   6324             {
   6325               /*
   6326                 Convert to 32 bit continuous-tone X canvas.
   6327               */
   6328               for (y=0; y < (int) canvas->rows; y++)
   6329               {
   6330                 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
   6331                   canvas->columns,1,exception);
   6332                 if (p == (const Quantum *) NULL)
   6333                   break;
   6334                 if ((red_gamma != 1.0) || (green_gamma != 1.0) ||
   6335                     (blue_gamma != 1.0))
   6336                   {
   6337                     /*
   6338                       Gamma correct canvas.
   6339                     */
   6340                     for (x=(int) canvas->columns-1; x >= 0; x--)
   6341                     {
   6342                       *q++=ScaleQuantumToChar(XBlueGamma(
   6343                         GetPixelBlue(canvas,p)));
   6344                       *q++=ScaleQuantumToChar(XGreenGamma(
   6345                         GetPixelGreen(canvas,p)));
   6346                       *q++=ScaleQuantumToChar(XRedGamma(
   6347                         GetPixelRed(canvas,p)));
   6348                       *q++=0;
   6349                       p+=GetPixelChannels(canvas);
   6350                     }
   6351                     continue;
   6352                   }
   6353                 for (x=(int) canvas->columns-1; x >= 0; x--)
   6354                 {
   6355                   *q++=ScaleQuantumToChar((Quantum) GetPixelBlue(canvas,p));
   6356                   *q++=ScaleQuantumToChar((Quantum) GetPixelGreen(canvas,p));
   6357                   *q++=ScaleQuantumToChar((Quantum) GetPixelRed(canvas,p));
   6358                   *q++=0;
   6359                   p+=GetPixelChannels(canvas);
   6360                 }
   6361               }
   6362             }
   6363           else
   6364             if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) &&
   6365                 (map_info->green_max == 255) && (map_info->blue_max == 255) &&
   6366                 (map_info->red_mult == 1) && (map_info->green_mult == 256) &&
   6367                 (map_info->blue_mult == 65536L))
   6368               {
   6369                 /*
   6370                   Convert to 32 bit continuous-tone X canvas.
   6371                 */
   6372                 for (y=0; y < (int) canvas->rows; y++)
   6373                 {
   6374                   p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
   6375                     canvas->columns,1,exception);
   6376                   if (p == (const Quantum *) NULL)
   6377                     break;
   6378                   if ((red_gamma != 1.0) || (green_gamma != 1.0) ||
   6379                       (blue_gamma != 1.0))
   6380                     {
   6381                       /*
   6382                         Gamma correct canvas.
   6383                       */
   6384                       for (x=(int) canvas->columns-1; x >= 0; x--)
   6385                       {
   6386                         *q++=ScaleQuantumToChar(XRedGamma(
   6387                           GetPixelRed(canvas,p)));
   6388                         *q++=ScaleQuantumToChar(XGreenGamma(
   6389                           GetPixelGreen(canvas,p)));
   6390                         *q++=ScaleQuantumToChar(XBlueGamma(
   6391                           GetPixelBlue(canvas,p)));
   6392                         *q++=0;
   6393                         p+=GetPixelChannels(canvas);
   6394                       }
   6395                       continue;
   6396                     }
   6397                   for (x=(int) canvas->columns-1; x >= 0; x--)
   6398                   {
   6399                     *q++=ScaleQuantumToChar((Quantum) GetPixelRed(canvas,p));
   6400                     *q++=ScaleQuantumToChar((Quantum) GetPixelGreen(canvas,p));
   6401                     *q++=ScaleQuantumToChar((Quantum) GetPixelBlue(canvas,p));
   6402                     *q++=0;
   6403                     p+=GetPixelChannels(canvas);
   6404                   }
   6405                 }
   6406               }
   6407             else
   6408               {
   6409                 register int
   6410                   k;
   6411 
   6412                 register unsigned int
   6413                   bytes_per_pixel;
   6414 
   6415                 /*
   6416                   Convert to multi-byte continuous-tone X canvas.
   6417                 */
   6418                 bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3);
   6419                 for (y=0; y < (int) canvas->rows; y++)
   6420                 {
   6421                   p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
   6422                     canvas->columns,1,exception);
   6423                   if (p == (const Quantum *) NULL)
   6424                     break;
   6425                   for (x=0; x < (int) canvas->columns; x++)
   6426                   {
   6427                     pixel=XGammaPixel(canvas,map_info,p);
   6428                     for (k=0; k < (int) bytes_per_pixel; k++)
   6429                     {
   6430                       *q++=(unsigned char) (pixel & 0xff);
   6431                       pixel>>=8;
   6432                     }
   6433                     p+=GetPixelChannels(canvas);
   6434                   }
   6435                   q+=scanline_pad;
   6436                 }
   6437               }
   6438           break;
   6439         }
   6440       }
   6441   if (matte_image != (XImage *) NULL)
   6442     {
   6443       /*
   6444         Initialize matte canvas.
   6445       */
   6446       scanline_pad=(unsigned int) (matte_image->bytes_per_line-
   6447         ((matte_image->width*matte_image->bits_per_pixel) >> 3));
   6448       q=(unsigned char *) matte_image->data;
   6449       for (y=0; y < (int) canvas->rows; y++)
   6450       {
   6451         p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,canvas->columns,1,
   6452           exception);
   6453         if (p == (const Quantum *) NULL)
   6454           break;
   6455         bit=0;
   6456         byte=0;
   6457         for (x=(int) canvas->columns-1; x >= 0; x--)
   6458         {
   6459           byte>>=1;
   6460           if (GetPixelAlpha(canvas,p) > (QuantumRange/2))
   6461             byte|=0x80;
   6462           bit++;
   6463           if (bit == 8)
   6464             {
   6465               *q++=byte;
   6466               bit=0;
   6467               byte=0;
   6468             }
   6469           p+=GetPixelChannels(canvas);
   6470         }
   6471         if (bit != 0)
   6472           *q=byte >> (8-bit);
   6473         q+=scanline_pad;
   6474       }
   6475     }
   6476   canvas_view=DestroyCacheView(canvas_view);
   6477   if (canvas != image)
   6478     canvas=DestroyImage(canvas);
   6479 }
   6480 
   6481 /*
   6483 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6484 %                                                                             %
   6485 %                                                                             %
   6486 %                                                                             %
   6487 +   X M a k e I m a g e M S B F i r s t                                       %
   6488 %                                                                             %
   6489 %                                                                             %
   6490 %                                                                             %
   6491 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   6492 %
   6493 %  XMakeImageMSBFirst() initializes the pixel data of an X11 Image.  The X
   6494 %  image pixels are copied in most-significant bit and byte first order.  The
   6495 %  server's scanline pad is also respected. Rather than using one or two
   6496 %  general cases, many special cases are found here to help speed up the image
   6497 %  conversion.
   6498 %
   6499 %  The format of the XMakeImageMSBFirst method is:
   6500 %
   6501 %      XMakeImageMSBFirst(resource_info,window,image,ximage,matte_image,
   6502 %        ExceptionInfo *exception)
   6503 %
   6504 %  A description of each parameter follows:
   6505 %
   6506 %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
   6507 %
   6508 %    o window: Specifies a pointer to a XWindowInfo structure.
   6509 %
   6510 %    o image: the image.
   6511 %
   6512 %    o ximage: Specifies a pointer to a XImage structure;  returned from
   6513 %      XCreateImage.
   6514 %
   6515 %    o matte_image: Specifies a pointer to a XImage structure;  returned from
   6516 %      XCreateImage.
   6517 %
   6518 %    o exception: return any errors or warnings in this structure.
   6519 %
   6520 */
   6521 static void XMakeImageMSBFirst(const XResourceInfo *resource_info,
   6522   const XWindowInfo *window,Image *image,XImage *ximage,XImage *matte_image,
   6523   ExceptionInfo *exception)
   6524 {
   6525   CacheView
   6526     *canvas_view;
   6527 
   6528   Image
   6529     *canvas;
   6530 
   6531   int
   6532     y;
   6533 
   6534   register int
   6535     x;
   6536 
   6537   register const Quantum
   6538     *p;
   6539 
   6540   register unsigned char
   6541     *q;
   6542 
   6543   unsigned char
   6544     bit,
   6545     byte;
   6546 
   6547   unsigned int
   6548     scanline_pad;
   6549 
   6550   unsigned long
   6551     pixel,
   6552     *pixels;
   6553 
   6554   XStandardColormap
   6555     *map_info;
   6556 
   6557   assert(resource_info != (XResourceInfo *) NULL);
   6558   assert(window != (XWindowInfo *) NULL);
   6559   assert(image != (Image *) NULL);
   6560   if (image->debug != MagickFalse)
   6561     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   6562   canvas=image;
   6563   if ((window->immutable != MagickFalse) &&
   6564       (image->storage_class == DirectClass) &&
   6565       (image->alpha_trait != UndefinedPixelTrait))
   6566     {
   6567       char
   6568         size[MagickPathExtent];
   6569 
   6570       Image
   6571         *pattern;
   6572 
   6573       ImageInfo
   6574         *image_info;
   6575 
   6576       image_info=AcquireImageInfo();
   6577       (void) CopyMagickString(image_info->filename,
   6578         resource_info->image_info->texture != (char *) NULL ?
   6579         resource_info->image_info->texture : "pattern:checkerboard",
   6580         MagickPathExtent);
   6581       (void) FormatLocaleString(size,MagickPathExtent,"%.20gx%.20g",(double)
   6582         image->columns,(double) image->rows);
   6583       image_info->size=ConstantString(size);
   6584       pattern=ReadImage(image_info,exception);
   6585       image_info=DestroyImageInfo(image_info);
   6586       if (pattern != (Image *) NULL)
   6587         {
   6588           canvas=CloneImage(image,0,0,MagickTrue,exception);
   6589           if (canvas != (Image *) NULL)
   6590             (void) CompositeImage(canvas,pattern,DstOverCompositeOp,MagickFalse,
   6591               0,0,exception);
   6592           pattern=DestroyImage(pattern);
   6593         }
   6594     }
   6595   scanline_pad=(unsigned int) (ximage->bytes_per_line-((ximage->width*
   6596     ximage->bits_per_pixel) >> 3));
   6597   map_info=window->map_info;
   6598   pixels=window->pixel_info->pixels;
   6599   q=(unsigned char *) ximage->data;
   6600   x=0;
   6601   canvas_view=AcquireVirtualCacheView(canvas,exception);
   6602   if (ximage->format == XYBitmap)
   6603     {
   6604       register unsigned short
   6605         polarity;
   6606 
   6607       unsigned char
   6608         background,
   6609         foreground;
   6610 
   6611       /*
   6612         Convert canvas to big-endian bitmap.
   6613       */
   6614       background=(unsigned char)
   6615         (XPixelIntensity(&window->pixel_info->foreground_color) <
   6616          XPixelIntensity(&window->pixel_info->background_color) ?  0x01 : 0x00);
   6617       foreground=(unsigned char)
   6618         (XPixelIntensity(&window->pixel_info->background_color) <
   6619          XPixelIntensity(&window->pixel_info->foreground_color) ?  0x01 : 0x00);
   6620       polarity=(unsigned short) ((GetPixelInfoIntensity(image,
   6621         &canvas->colormap[0])) < (QuantumRange/2.0) ? 1 : 0);
   6622       if (canvas->colors == 2)
   6623         polarity=GetPixelInfoIntensity(image,&canvas->colormap[0]) <
   6624           GetPixelInfoIntensity(image,&canvas->colormap[1]);
   6625       for (y=0; y < (int) canvas->rows; y++)
   6626       {
   6627         p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,canvas->columns,1,
   6628           exception);
   6629         if (p == (const Quantum *) NULL)
   6630           break;
   6631         bit=0;
   6632         byte=0;
   6633         for (x=(int) canvas->columns-1; x >= 0; x--)
   6634         {
   6635           byte<<=1;
   6636           if (GetPixelIndex(canvas,p) == (Quantum) polarity)
   6637             byte|=foreground;
   6638           else
   6639             byte|=background;
   6640           bit++;
   6641           if (bit == 8)
   6642             {
   6643               *q++=byte;
   6644               bit=0;
   6645               byte=0;
   6646             }
   6647           p+=GetPixelChannels(canvas);
   6648         }
   6649         if (bit != 0)
   6650           *q=byte << (8-bit);
   6651         q+=scanline_pad;
   6652       }
   6653     }
   6654   else
   6655     if (window->pixel_info->colors != 0)
   6656       switch (ximage->bits_per_pixel)
   6657       {
   6658         case 2:
   6659         {
   6660           register unsigned int
   6661             nibble;
   6662 
   6663           /*
   6664             Convert to 2 bit color-mapped X canvas.
   6665           */
   6666           for (y=0; y < (int) canvas->rows; y++)
   6667           {
   6668             p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
   6669               canvas->columns,1,exception);
   6670             if (p == (const Quantum *) NULL)
   6671               break;
   6672             nibble=0;
   6673             for (x=0; x < (int) canvas->columns; x++)
   6674             {
   6675               pixel=pixels[(ssize_t)
   6676                 GetPixelIndex(canvas,p)] & 0xf;
   6677               switch (nibble)
   6678               {
   6679                 case 0:
   6680                 {
   6681                   *q=(unsigned char) (pixel << 6);
   6682                   nibble++;
   6683                   break;
   6684                 }
   6685                 case 1:
   6686                 {
   6687                   *q|=(unsigned char) (pixel << 4);
   6688                   nibble++;
   6689                   break;
   6690                 }
   6691                 case 2:
   6692                 {
   6693                   *q|=(unsigned char) (pixel << 2);
   6694                   nibble++;
   6695                   break;
   6696                 }
   6697                 case 3:
   6698                 {
   6699                   *q|=(unsigned char) pixel;
   6700                   q++;
   6701                   nibble=0;
   6702                   break;
   6703                 }
   6704               }
   6705               p+=GetPixelChannels(canvas);
   6706             }
   6707             q+=scanline_pad;
   6708           }
   6709           break;
   6710         }
   6711         case 4:
   6712         {
   6713           register unsigned int
   6714             nibble;
   6715 
   6716           /*
   6717             Convert to 4 bit color-mapped X canvas.
   6718           */
   6719           for (y=0; y < (int) canvas->rows; y++)
   6720           {
   6721             p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
   6722               canvas->columns,1,exception);
   6723             if (p == (const Quantum *) NULL)
   6724               break;
   6725             nibble=0;
   6726             for (x=0; x < (int) canvas->columns; x++)
   6727             {
   6728               pixel=pixels[(ssize_t)
   6729                 GetPixelIndex(canvas,p)] & 0xf;
   6730               switch (nibble)
   6731               {
   6732                 case 0:
   6733                 {
   6734                   *q=(unsigned char) (pixel << 4);
   6735                   nibble++;
   6736                   break;
   6737                 }
   6738                 case 1:
   6739                 {
   6740                   *q|=(unsigned char) pixel;
   6741                   q++;
   6742                   nibble=0;
   6743                   break;
   6744                 }
   6745               }
   6746               p+=GetPixelChannels(canvas);
   6747             }
   6748             q+=scanline_pad;
   6749           }
   6750           break;
   6751         }
   6752         case 6:
   6753         case 8:
   6754         {
   6755           /*
   6756             Convert to 8 bit color-mapped X canvas.
   6757           */
   6758           if (resource_info->color_recovery &&
   6759               resource_info->quantize_info->dither_method != NoDitherMethod)
   6760             {
   6761               XDitherImage(canvas,ximage,exception);
   6762               break;
   6763             }
   6764           for (y=0; y < (int) canvas->rows; y++)
   6765           {
   6766             p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
   6767               canvas->columns,1,exception);
   6768             if (p == (const Quantum *) NULL)
   6769               break;
   6770             for (x=0; x < (int) canvas->columns; x++)
   6771             {
   6772               pixel=pixels[(ssize_t) GetPixelIndex(canvas,p)];
   6773               *q++=(unsigned char) pixel;
   6774               p+=GetPixelChannels(canvas);
   6775             }
   6776             q+=scanline_pad;
   6777           }
   6778           break;
   6779         }
   6780         default:
   6781         {
   6782           register int
   6783             k;
   6784 
   6785           register unsigned int
   6786             bytes_per_pixel;
   6787 
   6788           unsigned char
   6789             channel[sizeof(size_t)];
   6790 
   6791           /*
   6792             Convert to 8 bit color-mapped X canvas.
   6793           */
   6794           bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3);
   6795           for (y=0; y < (int) canvas->rows; y++)
   6796           {
   6797             p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
   6798               canvas->columns,1,exception);
   6799             if (p == (const Quantum *) NULL)
   6800               break;
   6801             for (x=0; x < (int) canvas->columns; x++)
   6802             {
   6803               pixel=pixels[(ssize_t)
   6804                 GetPixelIndex(canvas,p)];
   6805               for (k=(int) bytes_per_pixel-1; k >= 0; k--)
   6806               {
   6807                 channel[k]=(unsigned char) pixel;
   6808                 pixel>>=8;
   6809               }
   6810               for (k=0; k < (int) bytes_per_pixel; k++)
   6811                 *q++=channel[k];
   6812               p+=GetPixelChannels(canvas);
   6813             }
   6814             q+=scanline_pad;
   6815           }
   6816           break;
   6817         }
   6818       }
   6819     else
   6820       switch (ximage->bits_per_pixel)
   6821       {
   6822         case 2:
   6823         {
   6824           register unsigned int
   6825             nibble;
   6826 
   6827           /*
   6828             Convert to 4 bit continuous-tone X canvas.
   6829           */
   6830           for (y=0; y < (int) canvas->rows; y++)
   6831           {
   6832             p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
   6833               canvas->columns,1,exception);
   6834             if (p == (const Quantum *) NULL)
   6835               break;
   6836             nibble=0;
   6837             for (x=(int) canvas->columns-1; x >= 0; x--)
   6838             {
   6839               pixel=XGammaPixel(canvas,map_info,p);
   6840               pixel&=0xf;
   6841               switch (nibble)
   6842               {
   6843                 case 0:
   6844                 {
   6845                   *q=(unsigned char) (pixel << 6);
   6846                   nibble++;
   6847                   break;
   6848                 }
   6849                 case 1:
   6850                 {
   6851                   *q|=(unsigned char) (pixel << 4);
   6852                   nibble++;
   6853                   break;
   6854                 }
   6855                 case 2:
   6856                 {
   6857                   *q|=(unsigned char) (pixel << 2);
   6858                   nibble++;
   6859                   break;
   6860                 }
   6861                 case 3:
   6862                 {
   6863                   *q|=(unsigned char) pixel;
   6864                   q++;
   6865                   nibble=0;
   6866                   break;
   6867                 }
   6868               }
   6869               p+=GetPixelChannels(canvas);
   6870             }
   6871             q+=scanline_pad;
   6872           }
   6873           break;
   6874         }
   6875         case 4:
   6876         {
   6877           register unsigned int
   6878             nibble;
   6879 
   6880           /*
   6881             Convert to 4 bit continuous-tone X canvas.
   6882           */
   6883           for (y=0; y < (int) canvas->rows; y++)
   6884           {
   6885             p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
   6886               canvas->columns,1,exception);
   6887             if (p == (const Quantum *) NULL)
   6888               break;
   6889             nibble=0;
   6890             for (x=(int) canvas->columns-1; x >= 0; x--)
   6891             {
   6892               pixel=XGammaPixel(canvas,map_info,p);
   6893               pixel&=0xf;
   6894               switch (nibble)
   6895               {
   6896                 case 0:
   6897                 {
   6898                   *q=(unsigned char) (pixel << 4);
   6899                   nibble++;
   6900                   break;
   6901                 }
   6902                 case 1:
   6903                 {
   6904                   *q|=(unsigned char) pixel;
   6905                   q++;
   6906                   nibble=0;
   6907                   break;
   6908                 }
   6909               }
   6910               p+=GetPixelChannels(canvas);
   6911             }
   6912             q+=scanline_pad;
   6913           }
   6914           break;
   6915         }
   6916         case 6:
   6917         case 8:
   6918         {
   6919           /*
   6920             Convert to 8 bit continuous-tone X canvas.
   6921           */
   6922           if (resource_info->color_recovery &&
   6923               resource_info->quantize_info->dither_method != NoDitherMethod)
   6924             {
   6925               XDitherImage(canvas,ximage,exception);
   6926               break;
   6927             }
   6928           for (y=0; y < (int) canvas->rows; y++)
   6929           {
   6930             p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
   6931               canvas->columns,1,exception);
   6932             if (p == (const Quantum *) NULL)
   6933               break;
   6934             for (x=(int) canvas->columns-1; x >= 0; x--)
   6935             {
   6936               pixel=XGammaPixel(canvas,map_info,p);
   6937               *q++=(unsigned char) pixel;
   6938               p+=GetPixelChannels(canvas);
   6939             }
   6940             q+=scanline_pad;
   6941           }
   6942           break;
   6943         }
   6944         default:
   6945         {
   6946           if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) &&
   6947               (map_info->green_max == 255) && (map_info->blue_max == 255) &&
   6948               (map_info->red_mult == 65536L) && (map_info->green_mult == 256) &&
   6949               (map_info->blue_mult == 1))
   6950             {
   6951               /*
   6952                 Convert to 32 bit continuous-tone X canvas.
   6953               */
   6954               for (y=0; y < (int) canvas->rows; y++)
   6955               {
   6956                 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
   6957                   canvas->columns,1,exception);
   6958                 if (p == (const Quantum *) NULL)
   6959                   break;
   6960                 if ((red_gamma != 1.0) || (green_gamma != 1.0) ||
   6961                     (blue_gamma != 1.0))
   6962                   {
   6963                     /*
   6964                       Gamma correct canvas.
   6965                     */
   6966                     for (x=(int) canvas->columns-1; x >= 0; x--)
   6967                     {
   6968                       *q++=0;
   6969                       *q++=ScaleQuantumToChar(XRedGamma(
   6970                         GetPixelRed(canvas,p)));
   6971                       *q++=ScaleQuantumToChar(XGreenGamma(
   6972                         GetPixelGreen(canvas,p)));
   6973                       *q++=ScaleQuantumToChar(XBlueGamma(
   6974                         GetPixelBlue(canvas,p)));
   6975                       p+=GetPixelChannels(canvas);
   6976                     }
   6977                     continue;
   6978                   }
   6979                 for (x=(int) canvas->columns-1; x >= 0; x--)
   6980                 {
   6981                   *q++=0;
   6982                   *q++=ScaleQuantumToChar((Quantum) GetPixelRed(canvas,p));
   6983                   *q++=ScaleQuantumToChar((Quantum) GetPixelGreen(canvas,p));
   6984                   *q++=ScaleQuantumToChar((Quantum) GetPixelBlue(canvas,p));
   6985                   p+=GetPixelChannels(canvas);
   6986                 }
   6987               }
   6988             }
   6989           else
   6990             if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) &&
   6991                 (map_info->green_max == 255) && (map_info->blue_max == 255) &&
   6992                 (map_info->red_mult == 1) && (map_info->green_mult == 256) &&
   6993                 (map_info->blue_mult == 65536L))
   6994               {
   6995                 /*
   6996                   Convert to 32 bit continuous-tone X canvas.
   6997                 */
   6998                 for (y=0; y < (int) canvas->rows; y++)
   6999                 {
   7000                   p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
   7001                     canvas->columns,1,exception);
   7002                   if (p == (const Quantum *) NULL)
   7003                     break;
   7004                   if ((red_gamma != 1.0) || (green_gamma != 1.0) ||
   7005                       (blue_gamma != 1.0))
   7006                     {
   7007                       /*
   7008                         Gamma correct canvas.
   7009                       */
   7010                       for (x=(int) canvas->columns-1; x >= 0; x--)
   7011                       {
   7012                         *q++=0;
   7013                         *q++=ScaleQuantumToChar(XBlueGamma(
   7014                           GetPixelBlue(canvas,p)));
   7015                         *q++=ScaleQuantumToChar(XGreenGamma(
   7016                           GetPixelGreen(canvas,p)));
   7017                         *q++=ScaleQuantumToChar(XRedGamma(
   7018                           GetPixelRed(canvas,p)));
   7019                         p+=GetPixelChannels(canvas);
   7020                       }
   7021                       continue;
   7022                     }
   7023                   for (x=(int) canvas->columns-1; x >= 0; x--)
   7024                   {
   7025                     *q++=0;
   7026                     *q++=ScaleQuantumToChar((Quantum) GetPixelBlue(canvas,p));
   7027                     *q++=ScaleQuantumToChar((Quantum) GetPixelGreen(canvas,p));
   7028                     *q++=ScaleQuantumToChar((Quantum) GetPixelRed(canvas,p));
   7029                     p+=GetPixelChannels(canvas);
   7030                   }
   7031                 }
   7032               }
   7033             else
   7034               {
   7035                 register int
   7036                   k;
   7037 
   7038                 register unsigned int
   7039                   bytes_per_pixel;
   7040 
   7041                 unsigned char
   7042                   channel[sizeof(size_t)];
   7043 
   7044                 /*
   7045                   Convert to multi-byte continuous-tone X canvas.
   7046                 */
   7047                 bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3);
   7048                 for (y=0; y < (int) canvas->rows; y++)
   7049                 {
   7050                   p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
   7051                     canvas->columns,1,exception);
   7052                   if (p == (const Quantum *) NULL)
   7053                     break;
   7054                   for (x=(int) canvas->columns-1; x >= 0; x--)
   7055                   {
   7056                     pixel=XGammaPixel(canvas,map_info,p);
   7057                     for (k=(int) bytes_per_pixel-1; k >= 0; k--)
   7058                     {
   7059                       channel[k]=(unsigned char) pixel;
   7060                       pixel>>=8;
   7061                     }
   7062                     for (k=0; k < (int) bytes_per_pixel; k++)
   7063                       *q++=channel[k];
   7064                     p+=GetPixelChannels(canvas);
   7065                   }
   7066                   q+=scanline_pad;
   7067                 }
   7068               }
   7069           break;
   7070         }
   7071       }
   7072   if (matte_image != (XImage *) NULL)
   7073     {
   7074       /*
   7075         Initialize matte canvas.
   7076       */
   7077       scanline_pad=(unsigned int) (matte_image->bytes_per_line-
   7078         ((matte_image->width*matte_image->bits_per_pixel) >> 3));
   7079       q=(unsigned char *) matte_image->data;
   7080       for (y=0; y < (int) canvas->rows; y++)
   7081       {
   7082         p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,canvas->columns,1,
   7083           exception);
   7084         if (p == (const Quantum *) NULL)
   7085           break;
   7086         bit=0;
   7087         byte=0;
   7088         for (x=(int) canvas->columns-1; x >= 0; x--)
   7089         {
   7090           byte<<=1;
   7091           if (GetPixelAlpha(canvas,p) > (QuantumRange/2))
   7092             byte|=0x01;
   7093           bit++;
   7094           if (bit == 8)
   7095             {
   7096               *q++=byte;
   7097               bit=0;
   7098               byte=0;
   7099             }
   7100           p+=GetPixelChannels(canvas);
   7101         }
   7102         if (bit != 0)
   7103           *q=byte << (8-bit);
   7104         q+=scanline_pad;
   7105       }
   7106     }
   7107   canvas_view=DestroyCacheView(canvas_view);
   7108   if (canvas != image)
   7109     canvas=DestroyImage(canvas);
   7110 }
   7111 
   7112 /*
   7114 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   7115 %                                                                             %
   7116 %                                                                             %
   7117 %                                                                             %
   7118 %   X M a k e M a g n i f y I m a g e                                         %
   7119 %                                                                             %
   7120 %                                                                             %
   7121 %                                                                             %
   7122 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   7123 %
   7124 %  XMakeMagnifyImage() magnifies a region of an X image and displays it.
   7125 %
   7126 %  The format of the XMakeMagnifyImage method is:
   7127 %
   7128 %      void XMakeMagnifyImage(Display *display,XWindows *windows,
   7129 %        ExceptionInfo *exception)
   7130 %
   7131 %  A description of each parameter follows:
   7132 %
   7133 %    o display: Specifies a connection to an X server;  returned from
   7134 %      XOpenDisplay.
   7135 %
   7136 %    o windows: Specifies a pointer to a XWindows structure.
   7137 %
   7138 %    o exception: return any errors or warnings in this structure.
   7139 %
   7140 */
   7141 MagickPrivate void XMakeMagnifyImage(Display *display,XWindows *windows,
   7142   ExceptionInfo *exception)
   7143 {
   7144   char
   7145     tuple[MagickPathExtent];
   7146 
   7147   int
   7148     y;
   7149 
   7150   PixelInfo
   7151     pixel;
   7152 
   7153   register int
   7154     x;
   7155 
   7156   register ssize_t
   7157     i;
   7158 
   7159   register unsigned char
   7160     *p,
   7161     *q;
   7162 
   7163   ssize_t
   7164     n;
   7165 
   7166   static unsigned int
   7167     previous_magnify = 0;
   7168 
   7169   static XWindowInfo
   7170     magnify_window;
   7171 
   7172   unsigned int
   7173     height,
   7174     j,
   7175     k,
   7176     l,
   7177     magnify,
   7178     scanline_pad,
   7179     width;
   7180 
   7181   XImage
   7182     *ximage;
   7183 
   7184   /*
   7185     Check boundary conditions.
   7186   */
   7187   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   7188   assert(display != (Display *) NULL);
   7189   assert(windows != (XWindows *) NULL);
   7190   magnify=1;
   7191   for (n=1; n < (ssize_t) windows->magnify.data; n++)
   7192     magnify<<=1;
   7193   while ((magnify*windows->image.ximage->width) < windows->magnify.width)
   7194     magnify<<=1;
   7195   while ((magnify*windows->image.ximage->height) < windows->magnify.height)
   7196     magnify<<=1;
   7197   while (magnify > windows->magnify.width)
   7198     magnify>>=1;
   7199   while (magnify > windows->magnify.height)
   7200     magnify>>=1;
   7201   if (magnify == 0)
   7202     magnify=1;
   7203   if (magnify != previous_magnify)
   7204     {
   7205       Status
   7206         status;
   7207 
   7208       XTextProperty
   7209         window_name;
   7210 
   7211       /*
   7212         New magnify factor:  update magnify window name.
   7213       */
   7214       i=0;
   7215       while ((1 << i) <= (int) magnify)
   7216         i++;
   7217       (void) FormatLocaleString(windows->magnify.name,MagickPathExtent,
   7218         "Magnify %.20gX",(double) i);
   7219       status=XStringListToTextProperty(&windows->magnify.name,1,&window_name);
   7220       if (status != False)
   7221         {
   7222           XSetWMName(display,windows->magnify.id,&window_name);
   7223           XSetWMIconName(display,windows->magnify.id,&window_name);
   7224           (void) XFree((void *) window_name.value);
   7225         }
   7226     }
   7227   previous_magnify=magnify;
   7228   ximage=windows->image.ximage;
   7229   width=(unsigned int) windows->magnify.ximage->width;
   7230   height=(unsigned int) windows->magnify.ximage->height;
   7231   if ((windows->magnify.x < 0) ||
   7232       (windows->magnify.x >= windows->image.ximage->width))
   7233     windows->magnify.x=windows->image.ximage->width >> 1;
   7234   x=windows->magnify.x-((width/magnify) >> 1);
   7235   if (x < 0)
   7236     x=0;
   7237   else
   7238     if (x > (int) (ximage->width-(width/magnify)))
   7239       x=ximage->width-width/magnify;
   7240   if ((windows->magnify.y < 0) ||
   7241       (windows->magnify.y >= windows->image.ximage->height))
   7242     windows->magnify.y=windows->image.ximage->height >> 1;
   7243   y=windows->magnify.y-((height/magnify) >> 1);
   7244   if (y < 0)
   7245     y=0;
   7246   else
   7247     if (y > (int) (ximage->height-(height/magnify)))
   7248       y=ximage->height-height/magnify;
   7249   q=(unsigned char *) windows->magnify.ximage->data;
   7250   scanline_pad=(unsigned int) (windows->magnify.ximage->bytes_per_line-
   7251     ((width*windows->magnify.ximage->bits_per_pixel) >> 3));
   7252   if (ximage->bits_per_pixel < 8)
   7253     {
   7254       register unsigned char
   7255         background,
   7256         byte,
   7257         foreground,
   7258         p_bit,
   7259         q_bit;
   7260 
   7261       register unsigned int
   7262         plane;
   7263 
   7264       XPixelInfo
   7265         *pixel_info;
   7266 
   7267       pixel_info=windows->magnify.pixel_info;
   7268       switch (ximage->bitmap_bit_order)
   7269       {
   7270         case LSBFirst:
   7271         {
   7272           /*
   7273             Magnify little-endian bitmap.
   7274           */
   7275           background=0x00;
   7276           foreground=0x80;
   7277           if (ximage->format == XYBitmap)
   7278             {
   7279               background=(unsigned char)
   7280                 (XPixelIntensity(&pixel_info->foreground_color) <
   7281                  XPixelIntensity(&pixel_info->background_color) ?  0x80 : 0x00);
   7282               foreground=(unsigned char)
   7283                 (XPixelIntensity(&pixel_info->background_color) <
   7284                  XPixelIntensity(&pixel_info->foreground_color) ?  0x80 : 0x00);
   7285               if (windows->magnify.depth > 1)
   7286                 Swap(background,foreground);
   7287             }
   7288           for (i=0; i < (ssize_t) height; i+=magnify)
   7289           {
   7290             /*
   7291               Propogate pixel magnify rows.
   7292             */
   7293             for (j=0; j < magnify; j++)
   7294             {
   7295               p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
   7296                 ((x*ximage->bits_per_pixel) >> 3);
   7297               p_bit=(unsigned char) (x*ximage->bits_per_pixel) & 0x07;
   7298               q_bit=0;
   7299               byte=0;
   7300               for (k=0; k < width; k+=magnify)
   7301               {
   7302                 /*
   7303                   Propogate pixel magnify columns.
   7304                 */
   7305                 for (l=0; l < magnify; l++)
   7306                 {
   7307                   /*
   7308                     Propogate each bit plane.
   7309                   */
   7310                   for (plane=0; (int) plane < ximage->bits_per_pixel; plane++)
   7311                   {
   7312                     byte>>=1;
   7313                     if (*p & (0x01 << (p_bit+plane)))
   7314                       byte|=foreground;
   7315                     else
   7316                       byte|=background;
   7317                     q_bit++;
   7318                     if (q_bit == 8)
   7319                       {
   7320                         *q++=byte;
   7321                         q_bit=0;
   7322                         byte=0;
   7323                       }
   7324                   }
   7325                 }
   7326                 p_bit+=ximage->bits_per_pixel;
   7327                 if (p_bit == 8)
   7328                   {
   7329                     p++;
   7330                     p_bit=0;
   7331                   }
   7332                 if (q_bit != 0)
   7333                   *q=byte >> (8-q_bit);
   7334                 q+=scanline_pad;
   7335               }
   7336             }
   7337             y++;
   7338           }
   7339           break;
   7340         }
   7341         case MSBFirst:
   7342         default:
   7343         {
   7344           /*
   7345             Magnify big-endian bitmap.
   7346           */
   7347           background=0x00;
   7348           foreground=0x01;
   7349           if (ximage->format == XYBitmap)
   7350             {
   7351               background=(unsigned char)
   7352                 (XPixelIntensity(&pixel_info->foreground_color) <
   7353                  XPixelIntensity(&pixel_info->background_color) ?  0x01 : 0x00);
   7354               foreground=(unsigned char)
   7355                 (XPixelIntensity(&pixel_info->background_color) <
   7356                  XPixelIntensity(&pixel_info->foreground_color) ?  0x01 : 0x00);
   7357               if (windows->magnify.depth > 1)
   7358                 Swap(background,foreground);
   7359             }
   7360           for (i=0; i < (ssize_t) height; i+=magnify)
   7361           {
   7362             /*
   7363               Propogate pixel magnify rows.
   7364             */
   7365             for (j=0; j < magnify; j++)
   7366             {
   7367               p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
   7368                 ((x*ximage->bits_per_pixel) >> 3);
   7369               p_bit=(unsigned char) (x*ximage->bits_per_pixel) & 0x07;
   7370               q_bit=0;
   7371               byte=0;
   7372               for (k=0; k < width; k+=magnify)
   7373               {
   7374                 /*
   7375                   Propogate pixel magnify columns.
   7376                 */
   7377                 for (l=0; l < magnify; l++)
   7378                 {
   7379                   /*
   7380                     Propogate each bit plane.
   7381                   */
   7382                   for (plane=0; (int) plane < ximage->bits_per_pixel; plane++)
   7383                   {
   7384                     byte<<=1;
   7385                     if (*p & (0x80 >> (p_bit+plane)))
   7386                       byte|=foreground;
   7387                     else
   7388                       byte|=background;
   7389                     q_bit++;
   7390                     if (q_bit == 8)
   7391                       {
   7392                         *q++=byte;
   7393                         q_bit=0;
   7394                         byte=0;
   7395                       }
   7396                   }
   7397                 }
   7398                 p_bit+=ximage->bits_per_pixel;
   7399                 if (p_bit == 8)
   7400                   {
   7401                     p++;
   7402                     p_bit=0;
   7403                   }
   7404                 if (q_bit != 0)
   7405                   *q=byte << (8-q_bit);
   7406                 q+=scanline_pad;
   7407               }
   7408             }
   7409             y++;
   7410           }
   7411           break;
   7412         }
   7413       }
   7414     }
   7415   else
   7416     switch (ximage->bits_per_pixel)
   7417     {
   7418       case 6:
   7419       case 8:
   7420       {
   7421         /*
   7422           Magnify 8 bit X image.
   7423         */
   7424         for (i=0; i < (ssize_t) height; i+=magnify)
   7425         {
   7426           /*
   7427             Propogate pixel magnify rows.
   7428           */
   7429           for (j=0; j < magnify; j++)
   7430           {
   7431             p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
   7432               ((x*ximage->bits_per_pixel) >> 3);
   7433             for (k=0; k < width; k+=magnify)
   7434             {
   7435               /*
   7436                 Propogate pixel magnify columns.
   7437               */
   7438               for (l=0; l < magnify; l++)
   7439                 *q++=(*p);
   7440               p++;
   7441             }
   7442             q+=scanline_pad;
   7443           }
   7444           y++;
   7445         }
   7446         break;
   7447       }
   7448       default:
   7449       {
   7450         register unsigned int
   7451           bytes_per_pixel,
   7452           m;
   7453 
   7454         /*
   7455           Magnify multi-byte X image.
   7456         */
   7457         bytes_per_pixel=(unsigned int) ximage->bits_per_pixel >> 3;
   7458         for (i=0; i < (ssize_t) height; i+=magnify)
   7459         {
   7460           /*
   7461             Propogate pixel magnify rows.
   7462           */
   7463           for (j=0; j < magnify; j++)
   7464           {
   7465             p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
   7466               ((x*ximage->bits_per_pixel) >> 3);
   7467             for (k=0; k < width; k+=magnify)
   7468             {
   7469               /*
   7470                 Propogate pixel magnify columns.
   7471               */
   7472               for (l=0; l < magnify; l++)
   7473                 for (m=0; m < bytes_per_pixel; m++)
   7474                   *q++=(*(p+m));
   7475               p+=bytes_per_pixel;
   7476             }
   7477             q+=scanline_pad;
   7478           }
   7479           y++;
   7480         }
   7481         break;
   7482       }
   7483     }
   7484   /*
   7485     Copy X image to magnify pixmap.
   7486   */
   7487   x=windows->magnify.x-((width/magnify) >> 1);
   7488   if (x < 0)
   7489     x=(int) ((width >> 1)-windows->magnify.x*magnify);
   7490   else
   7491     if (x > (int) (ximage->width-(width/magnify)))
   7492       x=(int) ((ximage->width-windows->magnify.x)*magnify-(width >> 1));
   7493     else
   7494       x=0;
   7495   y=windows->magnify.y-((height/magnify) >> 1);
   7496   if (y < 0)
   7497     y=(int) ((height >> 1)-windows->magnify.y*magnify);
   7498   else
   7499     if (y > (int) (ximage->height-(height/magnify)))
   7500       y=(int) ((ximage->height-windows->magnify.y)*magnify-(height >> 1));
   7501     else
   7502       y=0;
   7503   if ((x != 0) || (y != 0))
   7504     (void) XFillRectangle(display,windows->magnify.pixmap,
   7505       windows->magnify.annotate_context,0,0,width,height);
   7506   (void) XPutImage(display,windows->magnify.pixmap,
   7507     windows->magnify.annotate_context,windows->magnify.ximage,0,0,x,y,width-x,
   7508     height-y);
   7509   if ((magnify > 1) && ((magnify <= (width >> 1)) &&
   7510       (magnify <= (height >> 1))))
   7511     {
   7512       RectangleInfo
   7513         highlight_info;
   7514 
   7515       /*
   7516         Highlight center pixel.
   7517       */
   7518       highlight_info.x=(ssize_t) windows->magnify.width >> 1;
   7519       highlight_info.y=(ssize_t) windows->magnify.height >> 1;
   7520       highlight_info.width=magnify;
   7521       highlight_info.height=magnify;
   7522       (void) XDrawRectangle(display,windows->magnify.pixmap,
   7523         windows->magnify.highlight_context,(int) highlight_info.x,
   7524         (int) highlight_info.y,(unsigned int) highlight_info.width-1,
   7525         (unsigned int) highlight_info.height-1);
   7526       if (magnify > 2)
   7527         (void) XDrawRectangle(display,windows->magnify.pixmap,
   7528           windows->magnify.annotate_context,(int) highlight_info.x+1,
   7529           (int) highlight_info.y+1,(unsigned int) highlight_info.width-3,
   7530           (unsigned int) highlight_info.height-3);
   7531     }
   7532   /*
   7533     Show center pixel color.
   7534   */
   7535   (void) GetOneVirtualPixelInfo(windows->image.image,TileVirtualPixelMethod,
   7536     (ssize_t) windows->magnify.x,(ssize_t) windows->magnify.y,&pixel,exception);
   7537   (void) FormatLocaleString(tuple,MagickPathExtent,"%d,%d: ",
   7538     windows->magnify.x,windows->magnify.y);
   7539   (void) ConcatenateMagickString(tuple,"(",MagickPathExtent);
   7540   ConcatenateColorComponent(&pixel,RedPixelChannel,X11Compliance,tuple);
   7541   (void) ConcatenateMagickString(tuple,",",MagickPathExtent);
   7542   ConcatenateColorComponent(&pixel,GreenPixelChannel,X11Compliance,tuple);
   7543   (void) ConcatenateMagickString(tuple,",",MagickPathExtent);
   7544   ConcatenateColorComponent(&pixel,BluePixelChannel,X11Compliance,tuple);
   7545   if (pixel.colorspace == CMYKColorspace)
   7546     {
   7547       (void) ConcatenateMagickString(tuple,",",MagickPathExtent);
   7548       ConcatenateColorComponent(&pixel,BlackPixelChannel,X11Compliance,tuple);
   7549     }
   7550   if (pixel.alpha_trait != UndefinedPixelTrait)
   7551     {
   7552       (void) ConcatenateMagickString(tuple,",",MagickPathExtent);
   7553       ConcatenateColorComponent(&pixel,AlphaPixelChannel,X11Compliance,tuple);
   7554     }
   7555   (void) ConcatenateMagickString(tuple,")",MagickPathExtent);
   7556   height=(unsigned int) windows->magnify.font_info->ascent+
   7557     windows->magnify.font_info->descent;
   7558   x=windows->magnify.font_info->max_bounds.width >> 1;
   7559   y=windows->magnify.font_info->ascent+(height >> 2);
   7560   (void) XDrawImageString(display,windows->magnify.pixmap,
   7561     windows->magnify.annotate_context,x,y,tuple,(int) strlen(tuple));
   7562   GetColorTuple(&pixel,MagickTrue,tuple);
   7563   y+=height;
   7564   (void) XDrawImageString(display,windows->magnify.pixmap,
   7565     windows->magnify.annotate_context,x,y,tuple,(int) strlen(tuple));
   7566   (void) QueryColorname(windows->image.image,&pixel,SVGCompliance,tuple,
   7567     exception);
   7568   y+=height;
   7569   (void) XDrawImageString(display,windows->magnify.pixmap,
   7570     windows->magnify.annotate_context,x,y,tuple,(int) strlen(tuple));
   7571   /*
   7572     Refresh magnify window.
   7573   */
   7574   magnify_window=windows->magnify;
   7575   magnify_window.x=0;
   7576   magnify_window.y=0;
   7577   XRefreshWindow(display,&magnify_window,(XEvent *) NULL);
   7578 }
   7579 
   7580 /*
   7582 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   7583 %                                                                             %
   7584 %                                                                             %
   7585 %                                                                             %
   7586 %   X M a k e P i x m a p                                                     %
   7587 %                                                                             %
   7588 %                                                                             %
   7589 %                                                                             %
   7590 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   7591 %
   7592 %  XMakePixmap() creates an X11 pixmap.
   7593 %
   7594 %  The format of the XMakePixmap method is:
   7595 %
   7596 %      void XMakeStandardColormap(Display *display,XVisualInfo *visual_info,
   7597 %        XResourceInfo *resource_info,Image *image,XStandardColormap *map_info,
   7598 %        XPixelInfo *pixel)
   7599 %
   7600 %  A description of each parameter follows:
   7601 %
   7602 %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
   7603 %
   7604 %    o display: Specifies a connection to an X server; returned from
   7605 %      XOpenDisplay.
   7606 %
   7607 %    o window: Specifies a pointer to a XWindowInfo structure.
   7608 %
   7609 */
   7610 static MagickBooleanType XMakePixmap(Display *display,
   7611   const XResourceInfo *resource_info,XWindowInfo *window)
   7612 {
   7613   unsigned int
   7614     height,
   7615     width;
   7616 
   7617   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   7618   assert(display != (Display *) NULL);
   7619   assert(resource_info != (XResourceInfo *) NULL);
   7620   assert(window != (XWindowInfo  *) NULL);
   7621   if (window->pixmap != (Pixmap) NULL)
   7622     {
   7623       /*
   7624         Destroy previous X pixmap.
   7625       */
   7626       (void) XFreePixmap(display,window->pixmap);
   7627       window->pixmap=(Pixmap) NULL;
   7628     }
   7629   if (window->use_pixmap == MagickFalse)
   7630     return(MagickFalse);
   7631   if (window->ximage == (XImage *) NULL)
   7632     return(MagickFalse);
   7633   /*
   7634     Display busy cursor.
   7635   */
   7636   (void) XCheckDefineCursor(display,window->id,window->busy_cursor);
   7637   (void) XFlush(display);
   7638   /*
   7639     Create pixmap.
   7640   */
   7641   width=(unsigned int) window->ximage->width;
   7642   height=(unsigned int) window->ximage->height;
   7643   window->pixmap=XCreatePixmap(display,window->id,width,height,window->depth);
   7644   if (window->pixmap == (Pixmap) NULL)
   7645     {
   7646       /*
   7647         Unable to allocate pixmap.
   7648       */
   7649       (void) XCheckDefineCursor(display,window->id,window->cursor);
   7650       return(MagickFalse);
   7651     }
   7652   /*
   7653     Copy X image to pixmap.
   7654   */
   7655 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
   7656   if (window->shared_memory)
   7657     (void) XShmPutImage(display,window->pixmap,window->annotate_context,
   7658       window->ximage,0,0,0,0,width,height,MagickTrue);
   7659 #endif
   7660   if (window->shared_memory == MagickFalse)
   7661     (void) XPutImage(display,window->pixmap,window->annotate_context,
   7662       window->ximage,0,0,0,0,width,height);
   7663   if (IsEventLogging())
   7664     {
   7665       (void) LogMagickEvent(X11Event,GetMagickModule(),"Pixmap:");
   7666       (void) LogMagickEvent(X11Event,GetMagickModule(),"  width, height: %ux%u",
   7667         width,height);
   7668     }
   7669   /*
   7670     Restore cursor.
   7671   */
   7672   (void) XCheckDefineCursor(display,window->id,window->cursor);
   7673   return(MagickTrue);
   7674 }
   7675 
   7676 /*
   7678 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   7679 %                                                                             %
   7680 %                                                                             %
   7681 %                                                                             %
   7682 %   X M a k e S t a n d a r d C o l o r m a p                                 %
   7683 %                                                                             %
   7684 %                                                                             %
   7685 %                                                                             %
   7686 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   7687 %
   7688 %  XMakeStandardColormap() creates an X11 Standard Colormap.
   7689 %
   7690 %  The format of the XMakeStandardColormap method is:
   7691 %
   7692 %      void XMakeStandardColormap(Display *display,XVisualInfo *visual_info,
   7693 %        XResourceInfo *resource_info,Image *image,XStandardColormap *map_info,
   7694 %        XPixelInfo *pixel,ExceptionInfo *exception)
   7695 %
   7696 %  A description of each parameter follows:
   7697 %
   7698 %    o display: Specifies a connection to an X server; returned from
   7699 %      XOpenDisplay.
   7700 %
   7701 %    o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
   7702 %      returned from XGetVisualInfo.
   7703 %
   7704 %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
   7705 %
   7706 %    o image: the image.
   7707 %
   7708 %    o map_info: If a Standard Colormap type is specified, this structure is
   7709 %      initialized with info from the Standard Colormap.
   7710 %
   7711 %    o pixel: Specifies a pointer to a XPixelInfo structure.
   7712 %
   7713 %    o exception: return any errors or warnings in this structure.
   7714 %
   7715 */
   7716 
   7717 #if defined(__cplusplus) || defined(c_plusplus)
   7718 extern "C" {
   7719 #endif
   7720 
   7721 static inline double DiversityPixelIntensity(
   7722   const DiversityPacket *pixel)
   7723 {
   7724   double
   7725     intensity;
   7726 
   7727   intensity=0.212656*pixel->red+0.715158*pixel->green+0.072186*pixel->blue;
   7728   return(intensity);
   7729 }
   7730 
   7731 static int IntensityCompare(const void *x,const void *y)
   7732 {
   7733   DiversityPacket
   7734     *color_1,
   7735     *color_2;
   7736 
   7737   int
   7738     diversity;
   7739 
   7740   color_1=(DiversityPacket *) x;
   7741   color_2=(DiversityPacket *) y;
   7742   diversity=(int) (DiversityPixelIntensity(color_2)-
   7743     DiversityPixelIntensity(color_1));
   7744   return(diversity);
   7745 }
   7746 
   7747 static int PopularityCompare(const void *x,const void *y)
   7748 {
   7749   DiversityPacket
   7750     *color_1,
   7751     *color_2;
   7752 
   7753   color_1=(DiversityPacket *) x;
   7754   color_2=(DiversityPacket *) y;
   7755   return((int) color_2->count-(int) color_1->count);
   7756 }
   7757 
   7758 #if defined(__cplusplus) || defined(c_plusplus)
   7759 }
   7760 #endif
   7761 
   7762 static inline Quantum ScaleXToQuantum(const size_t x,
   7763   const size_t scale)
   7764 {
   7765   return((Quantum) (((double) QuantumRange*x)/scale+0.5));
   7766 }
   7767 
   7768 MagickPrivate void XMakeStandardColormap(Display *display,
   7769   XVisualInfo *visual_info,XResourceInfo *resource_info,Image *image,
   7770   XStandardColormap *map_info,XPixelInfo *pixel,ExceptionInfo *exception)
   7771 {
   7772   Colormap
   7773     colormap;
   7774 
   7775   register ssize_t
   7776     i;
   7777 
   7778   Status
   7779     status;
   7780 
   7781   size_t
   7782     number_colors,
   7783     retain_colors;
   7784 
   7785   unsigned short
   7786     gray_value;
   7787 
   7788   XColor
   7789     color,
   7790     *colors,
   7791     *p;
   7792 
   7793   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   7794   assert(display != (Display *) NULL);
   7795   assert(visual_info != (XVisualInfo *) NULL);
   7796   assert(map_info != (XStandardColormap *) NULL);
   7797   assert(resource_info != (XResourceInfo *) NULL);
   7798   assert(pixel != (XPixelInfo *) NULL);
   7799   if (resource_info->map_type != (char *) NULL)
   7800     {
   7801       /*
   7802         Standard Colormap is already defined (i.e. xstdcmap).
   7803       */
   7804       XGetPixelInfo(display,visual_info,map_info,resource_info,image,
   7805         pixel);
   7806       number_colors=(unsigned int) (map_info->base_pixel+
   7807         (map_info->red_max+1)*(map_info->green_max+1)*(map_info->blue_max+1));
   7808       if ((map_info->red_max*map_info->green_max*map_info->blue_max) != 0)
   7809         if ((image->alpha_trait == UndefinedPixelTrait) &&
   7810             (resource_info->color_recovery == MagickFalse) &&
   7811             (resource_info->quantize_info->dither_method != NoDitherMethod) &&
   7812             (number_colors < MaxColormapSize))
   7813           {
   7814             Image
   7815               *affinity_image;
   7816 
   7817             register Quantum
   7818               *magick_restrict q;
   7819 
   7820             /*
   7821               Improve image appearance with error diffusion.
   7822             */
   7823             affinity_image=AcquireImage((ImageInfo *) NULL,exception);
   7824             if (affinity_image == (Image *) NULL)
   7825               ThrowXWindowFatalException(ResourceLimitFatalError,
   7826                 "UnableToDitherImage",image->filename);
   7827             affinity_image->columns=number_colors;
   7828             affinity_image->rows=1;
   7829             /*
   7830               Initialize colormap image.
   7831             */
   7832             q=QueueAuthenticPixels(affinity_image,0,0,affinity_image->columns,
   7833               1,exception);
   7834             if (q != (Quantum *) NULL)
   7835               {
   7836                 for (i=0; i < (ssize_t) number_colors; i++)
   7837                 {
   7838                   SetPixelRed(affinity_image,0,q);
   7839                   if (map_info->red_max != 0)
   7840                     SetPixelRed(affinity_image,ScaleXToQuantum((size_t)
   7841                       (i/map_info->red_mult),map_info->red_max),q);
   7842                   SetPixelGreen(affinity_image,0,q);
   7843                   if (map_info->green_max != 0)
   7844                     SetPixelGreen(affinity_image,ScaleXToQuantum((size_t)
   7845                       ((i/map_info->green_mult) % (map_info->green_max+1)),
   7846                       map_info->green_max),q);
   7847                   SetPixelBlue(affinity_image,0,q);
   7848                   if (map_info->blue_max != 0)
   7849                     SetPixelBlue(affinity_image,ScaleXToQuantum((size_t)
   7850                       (i % map_info->green_mult),map_info->blue_max),q);
   7851                   SetPixelAlpha(affinity_image,
   7852                     TransparentAlpha,q);
   7853                   q+=GetPixelChannels(affinity_image);
   7854                 }
   7855                 (void) SyncAuthenticPixels(affinity_image,exception);
   7856                 (void) RemapImage(resource_info->quantize_info,image,
   7857                   affinity_image,exception);
   7858               }
   7859             XGetPixelInfo(display,visual_info,map_info,resource_info,image,
   7860               pixel);
   7861             (void) SetImageStorageClass(image,DirectClass,exception);
   7862             affinity_image=DestroyImage(affinity_image);
   7863           }
   7864       if (IsEventLogging())
   7865         {
   7866           (void) LogMagickEvent(X11Event,GetMagickModule(),
   7867             "Standard Colormap:");
   7868           (void) LogMagickEvent(X11Event,GetMagickModule(),
   7869             "  colormap id: 0x%lx",map_info->colormap);
   7870           (void) LogMagickEvent(X11Event,GetMagickModule(),
   7871             "  red, green, blue max: %lu %lu %lu",map_info->red_max,
   7872             map_info->green_max,map_info->blue_max);
   7873           (void) LogMagickEvent(X11Event,GetMagickModule(),
   7874             "  red, green, blue mult: %lu %lu %lu",map_info->red_mult,
   7875             map_info->green_mult,map_info->blue_mult);
   7876         }
   7877       return;
   7878     }
   7879   if ((visual_info->klass != DirectColor) &&
   7880       (visual_info->klass != TrueColor))
   7881     if ((image->storage_class == DirectClass) ||
   7882         ((int) image->colors > visual_info->colormap_size))
   7883       {
   7884         QuantizeInfo
   7885           quantize_info;
   7886 
   7887         /*
   7888           Image has more colors than the visual supports.
   7889         */
   7890         quantize_info=(*resource_info->quantize_info);
   7891         quantize_info.number_colors=(size_t) visual_info->colormap_size;
   7892         (void) QuantizeImage(&quantize_info,image,exception);
   7893       }
   7894   /*
   7895     Free previous and create new colormap.
   7896   */
   7897   (void) XFreeStandardColormap(display,visual_info,map_info,pixel);
   7898   colormap=XDefaultColormap(display,visual_info->screen);
   7899   if (visual_info->visual != XDefaultVisual(display,visual_info->screen))
   7900     colormap=XCreateColormap(display,XRootWindow(display,visual_info->screen),
   7901       visual_info->visual,visual_info->klass == DirectColor ?
   7902       AllocAll : AllocNone);
   7903   if (colormap == (Colormap) NULL)
   7904     ThrowXWindowFatalException(ResourceLimitFatalError,"UnableToCreateColormap",
   7905       image->filename);
   7906   /*
   7907     Initialize the map and pixel info structures.
   7908   */
   7909   XGetMapInfo(visual_info,colormap,map_info);
   7910   XGetPixelInfo(display,visual_info,map_info,resource_info,image,pixel);
   7911   /*
   7912     Allocating colors in server colormap is based on visual class.
   7913   */
   7914   switch (visual_info->klass)
   7915   {
   7916     case StaticGray:
   7917     case StaticColor:
   7918     {
   7919       /*
   7920         Define Standard Colormap for StaticGray or StaticColor visual.
   7921       */
   7922       number_colors=image->colors;
   7923       colors=(XColor *) AcquireQuantumMemory((size_t)
   7924         visual_info->colormap_size,sizeof(*colors));
   7925       if (colors == (XColor *) NULL)
   7926         ThrowXWindowFatalException(ResourceLimitFatalError,
   7927           "UnableToCreateColormap",image->filename);
   7928       p=colors;
   7929       color.flags=(char) (DoRed | DoGreen | DoBlue);
   7930       for (i=0; i < (ssize_t) image->colors; i++)
   7931       {
   7932         color.red=ScaleQuantumToShort(XRedGamma(image->colormap[i].red));
   7933         color.green=ScaleQuantumToShort(XGreenGamma(image->colormap[i].green));
   7934         color.blue=ScaleQuantumToShort(XBlueGamma(image->colormap[i].blue));
   7935         if (visual_info->klass != StaticColor)
   7936           {
   7937             gray_value=(unsigned short) XPixelIntensity(&color);
   7938             color.red=gray_value;
   7939             color.green=gray_value;
   7940             color.blue=gray_value;
   7941           }
   7942         status=XAllocColor(display,colormap,&color);
   7943         if (status == False)
   7944           {
   7945             colormap=XCopyColormapAndFree(display,colormap);
   7946             (void) XAllocColor(display,colormap,&color);
   7947           }
   7948         pixel->pixels[i]=color.pixel;
   7949         *p++=color;
   7950       }
   7951       break;
   7952     }
   7953     case GrayScale:
   7954     case PseudoColor:
   7955     {
   7956       unsigned int
   7957         colormap_type;
   7958 
   7959       /*
   7960         Define Standard Colormap for GrayScale or PseudoColor visual.
   7961       */
   7962       number_colors=image->colors;
   7963       colors=(XColor *) AcquireQuantumMemory((size_t)
   7964         visual_info->colormap_size,sizeof(*colors));
   7965       if (colors == (XColor *) NULL)
   7966         ThrowXWindowFatalException(ResourceLimitFatalError,
   7967           "UnableToCreateColormap",image->filename);
   7968       /*
   7969         Preallocate our GUI colors.
   7970       */
   7971       (void) XAllocColor(display,colormap,&pixel->foreground_color);
   7972       (void) XAllocColor(display,colormap,&pixel->background_color);
   7973       (void) XAllocColor(display,colormap,&pixel->border_color);
   7974       (void) XAllocColor(display,colormap,&pixel->alpha_color);
   7975       (void) XAllocColor(display,colormap,&pixel->highlight_color);
   7976       (void) XAllocColor(display,colormap,&pixel->shadow_color);
   7977       (void) XAllocColor(display,colormap,&pixel->depth_color);
   7978       (void) XAllocColor(display,colormap,&pixel->trough_color);
   7979       for (i=0; i < MaxNumberPens; i++)
   7980         (void) XAllocColor(display,colormap,&pixel->pen_colors[i]);
   7981       /*
   7982         Determine if image colors will "fit" into X server colormap.
   7983       */
   7984       colormap_type=resource_info->colormap;
   7985       status=XAllocColorCells(display,colormap,MagickFalse,(unsigned long *)
   7986         NULL,0,pixel->pixels,(unsigned int) image->colors);
   7987       if (status != False)
   7988         colormap_type=PrivateColormap;
   7989       if (colormap_type == SharedColormap)
   7990         {
   7991           CacheView
   7992             *image_view;
   7993 
   7994           DiversityPacket
   7995             *diversity;
   7996 
   7997           int
   7998             y;
   7999 
   8000           register int
   8001             x;
   8002 
   8003           unsigned short
   8004             index;
   8005 
   8006           XColor
   8007             *server_colors;
   8008 
   8009           /*
   8010             Define Standard colormap for shared GrayScale or PseudoColor visual.
   8011           */
   8012           diversity=(DiversityPacket *) AcquireQuantumMemory(image->colors,
   8013             sizeof(*diversity));
   8014           if (diversity == (DiversityPacket *) NULL)
   8015             ThrowXWindowFatalException(ResourceLimitFatalError,
   8016               "UnableToCreateColormap",image->filename);
   8017           for (i=0; i < (ssize_t) image->colors; i++)
   8018           {
   8019             diversity[i].red=ClampToQuantum(image->colormap[i].red);
   8020             diversity[i].green=ClampToQuantum(image->colormap[i].green);
   8021             diversity[i].blue=ClampToQuantum(image->colormap[i].blue);
   8022             diversity[i].index=(unsigned short) i;
   8023             diversity[i].count=0;
   8024           }
   8025           image_view=AcquireAuthenticCacheView(image,exception);
   8026           for (y=0; y < (int) image->rows; y++)
   8027           {
   8028             register int
   8029               x;
   8030 
   8031             register const Quantum
   8032               *magick_restrict p;
   8033 
   8034             p=GetCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
   8035               image->columns,1,exception);
   8036             if (p == (const Quantum *) NULL)
   8037               break;
   8038             for (x=(int) image->columns-1; x >= 0; x--)
   8039             {
   8040               diversity[(ssize_t) GetPixelIndex(image,p)].count++;
   8041               p+=GetPixelChannels(image);
   8042             }
   8043           }
   8044           image_view=DestroyCacheView(image_view);
   8045           /*
   8046             Sort colors by decreasing intensity.
   8047           */
   8048           qsort((void *) diversity,image->colors,sizeof(*diversity),
   8049             IntensityCompare);
   8050           for (i=0; i < (ssize_t) image->colors; )
   8051           {
   8052             diversity[i].count<<=4;  /* increase this colors popularity */
   8053             i+=MagickMax((int) (image->colors >> 4),2);
   8054           }
   8055           diversity[image->colors-1].count<<=4;
   8056           qsort((void *) diversity,image->colors,sizeof(*diversity),
   8057             PopularityCompare);
   8058           /*
   8059             Allocate colors.
   8060           */
   8061           p=colors;
   8062           color.flags=(char) (DoRed | DoGreen | DoBlue);
   8063           for (i=0; i < (ssize_t) image->colors; i++)
   8064           {
   8065             index=diversity[i].index;
   8066             color.red=
   8067               ScaleQuantumToShort(XRedGamma(image->colormap[index].red));
   8068             color.green=
   8069               ScaleQuantumToShort(XGreenGamma(image->colormap[index].green));
   8070             color.blue=
   8071               ScaleQuantumToShort(XBlueGamma(image->colormap[index].blue));
   8072             if (visual_info->klass != PseudoColor)
   8073               {
   8074                 gray_value=(unsigned short) XPixelIntensity(&color);
   8075                 color.red=gray_value;
   8076                 color.green=gray_value;
   8077                 color.blue=gray_value;
   8078               }
   8079             status=XAllocColor(display,colormap,&color);
   8080             if (status == False)
   8081               break;
   8082             pixel->pixels[index]=color.pixel;
   8083             *p++=color;
   8084           }
   8085           /*
   8086             Read X server colormap.
   8087           */
   8088           server_colors=(XColor *) AcquireQuantumMemory((size_t)
   8089             visual_info->colormap_size,sizeof(*server_colors));
   8090           if (server_colors == (XColor *) NULL)
   8091             ThrowXWindowFatalException(ResourceLimitFatalError,
   8092               "UnableToCreateColormap",image->filename);
   8093           for (x=visual_info->colormap_size-1; x >= 0; x--)
   8094             server_colors[x].pixel=(size_t) x;
   8095           (void) XQueryColors(display,colormap,server_colors,
   8096             (int) MagickMin((unsigned int) visual_info->colormap_size,256));
   8097           /*
   8098             Select remaining colors from X server colormap.
   8099           */
   8100           for (; i < (ssize_t) image->colors; i++)
   8101           {
   8102             index=diversity[i].index;
   8103             color.red=ScaleQuantumToShort(
   8104               XRedGamma(image->colormap[index].red));
   8105             color.green=ScaleQuantumToShort(
   8106               XGreenGamma(image->colormap[index].green));
   8107             color.blue=ScaleQuantumToShort(
   8108               XBlueGamma(image->colormap[index].blue));
   8109             if (visual_info->klass != PseudoColor)
   8110               {
   8111                 gray_value=(unsigned short) XPixelIntensity(&color);
   8112                 color.red=gray_value;
   8113                 color.green=gray_value;
   8114                 color.blue=gray_value;
   8115               }
   8116             XBestPixel(display,colormap,server_colors,(unsigned int)
   8117               visual_info->colormap_size,&color);
   8118             pixel->pixels[index]=color.pixel;
   8119             *p++=color;
   8120           }
   8121           if ((int) image->colors < visual_info->colormap_size)
   8122             {
   8123               /*
   8124                 Fill up colors array-- more choices for pen colors.
   8125               */
   8126               retain_colors=MagickMin((unsigned int)
   8127                (visual_info->colormap_size-image->colors),256);
   8128               for (i=0; i < (ssize_t) retain_colors; i++)
   8129                 *p++=server_colors[i];
   8130               number_colors+=retain_colors;
   8131             }
   8132           server_colors=(XColor *) RelinquishMagickMemory(server_colors);
   8133           diversity=(DiversityPacket *) RelinquishMagickMemory(diversity);
   8134           break;
   8135         }
   8136       /*
   8137         Define Standard colormap for private GrayScale or PseudoColor visual.
   8138       */
   8139       if (status == False)
   8140         {
   8141           /*
   8142             Not enough colormap entries in the colormap-- Create a new colormap.
   8143           */
   8144           colormap=XCreateColormap(display,
   8145             XRootWindow(display,visual_info->screen),visual_info->visual,
   8146             AllocNone);
   8147           if (colormap == (Colormap) NULL)
   8148             ThrowXWindowFatalException(ResourceLimitFatalError,
   8149               "UnableToCreateColormap",image->filename);
   8150           map_info->colormap=colormap;
   8151           if ((int) image->colors < visual_info->colormap_size)
   8152             {
   8153               /*
   8154                 Retain colors from the default colormap to help lessens the
   8155                 effects of colormap flashing.
   8156               */
   8157               retain_colors=MagickMin((unsigned int)
   8158                 (visual_info->colormap_size-image->colors),256);
   8159               p=colors+image->colors;
   8160               for (i=0; i < (ssize_t) retain_colors; i++)
   8161               {
   8162                 p->pixel=(unsigned long) i;
   8163                 p++;
   8164               }
   8165               (void) XQueryColors(display,
   8166                 XDefaultColormap(display,visual_info->screen),
   8167                 colors+image->colors,(int) retain_colors);
   8168               /*
   8169                 Transfer colors from default to private colormap.
   8170               */
   8171               (void) XAllocColorCells(display,colormap,MagickFalse,
   8172                 (unsigned long *) NULL,0,pixel->pixels,(unsigned int)
   8173                 retain_colors);
   8174               p=colors+image->colors;
   8175               for (i=0; i < (ssize_t) retain_colors; i++)
   8176               {
   8177                 p->pixel=pixel->pixels[i];
   8178                 p++;
   8179               }
   8180               (void) XStoreColors(display,colormap,colors+image->colors,
   8181                 (int) retain_colors);
   8182               number_colors+=retain_colors;
   8183             }
   8184           (void) XAllocColorCells(display,colormap,MagickFalse,
   8185             (unsigned long *) NULL,0,pixel->pixels,(unsigned int)
   8186             image->colors);
   8187         }
   8188       /*
   8189         Store the image colormap.
   8190       */
   8191       p=colors;
   8192       color.flags=(char) (DoRed | DoGreen | DoBlue);
   8193       for (i=0; i < (ssize_t) image->colors; i++)
   8194       {
   8195         color.red=ScaleQuantumToShort(XRedGamma(image->colormap[i].red));
   8196         color.green=ScaleQuantumToShort(XGreenGamma(image->colormap[i].green));
   8197         color.blue=ScaleQuantumToShort(XBlueGamma(image->colormap[i].blue));
   8198         if (visual_info->klass != PseudoColor)
   8199           {
   8200             gray_value=(unsigned short) XPixelIntensity(&color);
   8201             color.red=gray_value;
   8202             color.green=gray_value;
   8203             color.blue=gray_value;
   8204           }
   8205         color.pixel=pixel->pixels[i];
   8206         *p++=color;
   8207       }
   8208       (void) XStoreColors(display,colormap,colors,(int) image->colors);
   8209       break;
   8210     }
   8211     case TrueColor:
   8212     case DirectColor:
   8213     default:
   8214     {
   8215       MagickBooleanType
   8216         linear_colormap;
   8217 
   8218       /*
   8219         Define Standard Colormap for TrueColor or DirectColor visual.
   8220       */
   8221       number_colors=(unsigned int) ((map_info->red_max*map_info->red_mult)+
   8222         (map_info->green_max*map_info->green_mult)+
   8223         (map_info->blue_max*map_info->blue_mult)+1);
   8224       linear_colormap=(number_colors > 4096) ||
   8225         (((int) (map_info->red_max+1) == visual_info->colormap_size) &&
   8226          ((int) (map_info->green_max+1) == visual_info->colormap_size) &&
   8227          ((int) (map_info->blue_max+1) == visual_info->colormap_size)) ?
   8228          MagickTrue : MagickFalse;
   8229       if (linear_colormap != MagickFalse)
   8230         number_colors=(size_t) visual_info->colormap_size;
   8231       /*
   8232         Allocate color array.
   8233       */
   8234       colors=(XColor *) AcquireQuantumMemory(number_colors,sizeof(*colors));
   8235       if (colors == (XColor *) NULL)
   8236         ThrowXWindowFatalException(ResourceLimitFatalError,
   8237           "UnableToCreateColormap",image->filename);
   8238       /*
   8239         Initialize linear color ramp.
   8240       */
   8241       p=colors;
   8242       color.flags=(char) (DoRed | DoGreen | DoBlue);
   8243       if (linear_colormap != MagickFalse)
   8244         for (i=0; i < (ssize_t) number_colors; i++)
   8245         {
   8246           color.blue=(unsigned short) 0;
   8247           if (map_info->blue_max != 0)
   8248             color.blue=(unsigned short) ((size_t)
   8249               ((65535L*(i % map_info->green_mult))/map_info->blue_max));
   8250           color.green=color.blue;
   8251           color.red=color.blue;
   8252           color.pixel=XStandardPixel(map_info,&color);
   8253           *p++=color;
   8254         }
   8255       else
   8256         for (i=0; i < (ssize_t) number_colors; i++)
   8257         {
   8258           color.red=(unsigned short) 0;
   8259           if (map_info->red_max != 0)
   8260             color.red=(unsigned short) ((size_t)
   8261               ((65535L*(i/map_info->red_mult))/map_info->red_max));
   8262           color.green=(unsigned int) 0;
   8263           if (map_info->green_max != 0)
   8264             color.green=(unsigned short) ((size_t)
   8265               ((65535L*((i/map_info->green_mult) % (map_info->green_max+1)))/
   8266                 map_info->green_max));
   8267           color.blue=(unsigned short) 0;
   8268           if (map_info->blue_max != 0)
   8269             color.blue=(unsigned short) ((size_t)
   8270               ((65535L*(i % map_info->green_mult))/map_info->blue_max));
   8271           color.pixel=XStandardPixel(map_info,&color);
   8272           *p++=color;
   8273         }
   8274       if ((visual_info->klass == DirectColor) &&
   8275           (colormap != XDefaultColormap(display,visual_info->screen)))
   8276         (void) XStoreColors(display,colormap,colors,(int) number_colors);
   8277       else
   8278         for (i=0; i < (ssize_t) number_colors; i++)
   8279           (void) XAllocColor(display,colormap,&colors[i]);
   8280       break;
   8281     }
   8282   }
   8283   if ((visual_info->klass != DirectColor) &&
   8284       (visual_info->klass != TrueColor))
   8285     {
   8286       /*
   8287         Set foreground, background, border, etc. pixels.
   8288       */
   8289       XBestPixel(display,colormap,colors,(unsigned int) number_colors,
   8290         &pixel->foreground_color);
   8291       XBestPixel(display,colormap,colors,(unsigned int) number_colors,
   8292         &pixel->background_color);
   8293       if (pixel->background_color.pixel == pixel->foreground_color.pixel)
   8294         {
   8295           /*
   8296             Foreground and background colors must differ.
   8297           */
   8298           pixel->background_color.red=(~pixel->foreground_color.red);
   8299           pixel->background_color.green=
   8300             (~pixel->foreground_color.green);
   8301           pixel->background_color.blue=
   8302             (~pixel->foreground_color.blue);
   8303           XBestPixel(display,colormap,colors,(unsigned int) number_colors,
   8304             &pixel->background_color);
   8305         }
   8306       XBestPixel(display,colormap,colors,(unsigned int) number_colors,
   8307         &pixel->border_color);
   8308       XBestPixel(display,colormap,colors,(unsigned int) number_colors,
   8309         &pixel->alpha_color);
   8310       XBestPixel(display,colormap,colors,(unsigned int) number_colors,
   8311         &pixel->highlight_color);
   8312       XBestPixel(display,colormap,colors,(unsigned int) number_colors,
   8313         &pixel->shadow_color);
   8314       XBestPixel(display,colormap,colors,(unsigned int) number_colors,
   8315         &pixel->depth_color);
   8316       XBestPixel(display,colormap,colors,(unsigned int) number_colors,
   8317         &pixel->trough_color);
   8318       for (i=0; i < MaxNumberPens; i++)
   8319       {
   8320         XBestPixel(display,colormap,colors,(unsigned int) number_colors,
   8321           &pixel->pen_colors[i]);
   8322         pixel->pixels[image->colors+i]=pixel->pen_colors[i].pixel;
   8323       }
   8324       pixel->colors=(ssize_t) (image->colors+MaxNumberPens);
   8325     }
   8326   colors=(XColor *) RelinquishMagickMemory(colors);
   8327   if (IsEventLogging())
   8328     {
   8329       (void) LogMagickEvent(X11Event,GetMagickModule(),"Standard Colormap:");
   8330       (void) LogMagickEvent(X11Event,GetMagickModule(),"  colormap id: 0x%lx",
   8331         map_info->colormap);
   8332       (void) LogMagickEvent(X11Event,GetMagickModule(),
   8333         "  red, green, blue max: %lu %lu %lu",map_info->red_max,
   8334         map_info->green_max,map_info->blue_max);
   8335       (void) LogMagickEvent(X11Event,GetMagickModule(),
   8336         "  red, green, blue mult: %lu %lu %lu",map_info->red_mult,
   8337         map_info->green_mult,map_info->blue_mult);
   8338     }
   8339 }
   8340 
   8341 /*
   8343 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   8344 %                                                                             %
   8345 %                                                                             %
   8346 %                                                                             %
   8347 %   X M a k e W i n d o w                                                     %
   8348 %                                                                             %
   8349 %                                                                             %
   8350 %                                                                             %
   8351 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   8352 %
   8353 %  XMakeWindow() creates an X11 window.
   8354 %
   8355 %  The format of the XMakeWindow method is:
   8356 %
   8357 %      void XMakeWindow(Display *display,Window parent,char **argv,int argc,
   8358 %        XClassHint *class_hint,XWMHints *manager_hints,
   8359 %        XWindowInfo *window_info)
   8360 %
   8361 %  A description of each parameter follows:
   8362 %
   8363 %    o display: Specifies a connection to an X server; returned from
   8364 %      XOpenDisplay.
   8365 %
   8366 %    o parent: Specifies the parent window_info.
   8367 %
   8368 %    o argv: Specifies the application's argument list.
   8369 %
   8370 %    o argc: Specifies the number of arguments.
   8371 %
   8372 %    o class_hint: Specifies a pointer to a X11 XClassHint structure.
   8373 %
   8374 %    o manager_hints: Specifies a pointer to a X11 XWMHints structure.
   8375 %
   8376 %    o window_info: Specifies a pointer to a X11 XWindowInfo structure.
   8377 %
   8378 */
   8379 MagickPrivate void XMakeWindow(Display *display,Window parent,char **argv,
   8380   int argc,XClassHint *class_hint,XWMHints *manager_hints,
   8381   XWindowInfo *window_info)
   8382 {
   8383 #define MinWindowSize  64
   8384 
   8385   Atom
   8386     atom_list[2];
   8387 
   8388   int
   8389     gravity;
   8390 
   8391   static XTextProperty
   8392     icon_name,
   8393     window_name;
   8394 
   8395   Status
   8396     status;
   8397 
   8398   XSizeHints
   8399     *size_hints;
   8400 
   8401   /*
   8402     Set window info hints.
   8403   */
   8404   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   8405   assert(display != (Display *) NULL);
   8406   assert(window_info != (XWindowInfo *) NULL);
   8407   size_hints=XAllocSizeHints();
   8408   if (size_hints == (XSizeHints *) NULL)
   8409     ThrowXWindowFatalException(XServerFatalError,"UnableToMakeXWindow",argv[0]);
   8410   size_hints->flags=(int) window_info->flags;
   8411   size_hints->x=window_info->x;
   8412   size_hints->y=window_info->y;
   8413   size_hints->width=(int) window_info->width;
   8414   size_hints->height=(int) window_info->height;
   8415   if (window_info->immutable != MagickFalse)
   8416     {
   8417       /*
   8418         Window size cannot be changed.
   8419       */
   8420       size_hints->min_width=size_hints->width;
   8421       size_hints->min_height=size_hints->height;
   8422       size_hints->max_width=size_hints->width;
   8423       size_hints->max_height=size_hints->height;
   8424       size_hints->flags|=PMinSize;
   8425       size_hints->flags|=PMaxSize;
   8426     }
   8427   else
   8428     {
   8429       /*
   8430         Window size can be changed.
   8431       */
   8432       size_hints->min_width=(int) window_info->min_width;
   8433       size_hints->min_height=(int) window_info->min_height;
   8434       size_hints->flags|=PResizeInc;
   8435       size_hints->width_inc=(int) window_info->width_inc;
   8436       size_hints->height_inc=(int) window_info->height_inc;
   8437 #if !defined(PRE_R4_ICCCM)
   8438       size_hints->flags|=PBaseSize;
   8439       size_hints->base_width=size_hints->width_inc;
   8440       size_hints->base_height=size_hints->height_inc;
   8441 #endif
   8442     }
   8443   gravity=NorthWestGravity;
   8444   if (window_info->geometry != (char *) NULL)
   8445     {
   8446       char
   8447         default_geometry[MagickPathExtent],
   8448         geometry[MagickPathExtent];
   8449 
   8450       int
   8451         flags;
   8452 
   8453       register char
   8454         *p;
   8455 
   8456       /*
   8457         User specified geometry.
   8458       */
   8459       (void) FormatLocaleString(default_geometry,MagickPathExtent,"%dx%d",
   8460         size_hints->width,size_hints->height);
   8461       (void) CopyMagickString(geometry,window_info->geometry,MagickPathExtent);
   8462       p=geometry;
   8463       while (strlen(p) != 0)
   8464       {
   8465         if ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '%'))
   8466           p++;
   8467         else
   8468           (void) CopyMagickString(p,p+1,MagickPathExtent-(p-geometry));
   8469       }
   8470       flags=XWMGeometry(display,window_info->screen,geometry,default_geometry,
   8471         window_info->border_width,size_hints,&size_hints->x,&size_hints->y,
   8472         &size_hints->width,&size_hints->height,&gravity);
   8473       if ((flags & WidthValue) && (flags & HeightValue))
   8474         size_hints->flags|=USSize;
   8475       if ((flags & XValue) && (flags & YValue))
   8476         {
   8477           size_hints->flags|=USPosition;
   8478           window_info->x=size_hints->x;
   8479           window_info->y=size_hints->y;
   8480         }
   8481     }
   8482 #if !defined(PRE_R4_ICCCM)
   8483   size_hints->win_gravity=gravity;
   8484   size_hints->flags|=PWinGravity;
   8485 #endif
   8486   if (window_info->id == (Window) NULL)
   8487     window_info->id=XCreateWindow(display,parent,window_info->x,window_info->y,
   8488       (unsigned int) size_hints->width,(unsigned int) size_hints->height,
   8489       window_info->border_width,(int) window_info->depth,InputOutput,
   8490       window_info->visual,(unsigned long) window_info->mask,
   8491       &window_info->attributes);
   8492   else
   8493     {
   8494       MagickStatusType
   8495         mask;
   8496 
   8497       XEvent
   8498         sans_event;
   8499 
   8500       XWindowChanges
   8501         window_changes;
   8502 
   8503       /*
   8504         Window already exists;  change relevant attributes.
   8505       */
   8506       (void) XChangeWindowAttributes(display,window_info->id,(unsigned long)
   8507         window_info->mask,&window_info->attributes);
   8508       mask=ConfigureNotify;
   8509       while (XCheckTypedWindowEvent(display,window_info->id,(int) mask,&sans_event)) ;
   8510       window_changes.x=window_info->x;
   8511       window_changes.y=window_info->y;
   8512       window_changes.width=(int) window_info->width;
   8513       window_changes.height=(int) window_info->height;
   8514       mask=(MagickStatusType) (CWWidth | CWHeight);
   8515       if (window_info->flags & USPosition)
   8516         mask|=CWX | CWY;
   8517       (void) XReconfigureWMWindow(display,window_info->id,window_info->screen,
   8518         mask,&window_changes);
   8519     }
   8520   if (window_info->id == (Window) NULL)
   8521     ThrowXWindowFatalException(XServerFatalError,"UnableToCreateWindow",
   8522       window_info->name);
   8523   status=XStringListToTextProperty(&window_info->name,1,&window_name);
   8524   if (status == False)
   8525     ThrowXWindowFatalException(XServerFatalError,"UnableToCreateTextProperty",
   8526       window_info->name);
   8527   status=XStringListToTextProperty(&window_info->icon_name,1,&icon_name);
   8528   if (status == False)
   8529     ThrowXWindowFatalException(XServerFatalError,"UnableToCreateTextProperty",
   8530       window_info->icon_name);
   8531   if (window_info->icon_geometry != (char *) NULL)
   8532     {
   8533       int
   8534         flags,
   8535         height,
   8536         width;
   8537 
   8538       /*
   8539         User specified icon geometry.
   8540       */
   8541       size_hints->flags|=USPosition;
   8542       flags=XWMGeometry(display,window_info->screen,window_info->icon_geometry,
   8543         (char *) NULL,0,size_hints,&manager_hints->icon_x,
   8544         &manager_hints->icon_y,&width,&height,&gravity);
   8545       if ((flags & XValue) && (flags & YValue))
   8546         manager_hints->flags|=IconPositionHint;
   8547     }
   8548   XSetWMProperties(display,window_info->id,&window_name,&icon_name,argv,argc,
   8549     size_hints,manager_hints,class_hint);
   8550   if (window_name.value != (void *) NULL)
   8551     {
   8552       (void) XFree((void *) window_name.value);
   8553       window_name.value=(unsigned char *) NULL;
   8554       window_name.nitems=0;
   8555     }
   8556   if (icon_name.value != (void *) NULL)
   8557     {
   8558       (void) XFree((void *) icon_name.value);
   8559       icon_name.value=(unsigned char *) NULL;
   8560       icon_name.nitems=0;
   8561     }
   8562   atom_list[0]=XInternAtom(display,"WM_DELETE_WINDOW",MagickFalse);
   8563   atom_list[1]=XInternAtom(display,"WM_TAKE_FOCUS",MagickFalse);
   8564   (void) XSetWMProtocols(display,window_info->id,atom_list,2);
   8565   (void) XFree((void *) size_hints);
   8566   if (window_info->shape != MagickFalse)
   8567     {
   8568 #if defined(MAGICKCORE_HAVE_SHAPE)
   8569       int
   8570         error_base,
   8571         event_base;
   8572 
   8573       /*
   8574         Can we apply a non-rectangular shaping mask?
   8575       */
   8576       error_base=0;
   8577       event_base=0;
   8578       if (XShapeQueryExtension(display,&error_base,&event_base) == 0)
   8579         window_info->shape=MagickFalse;
   8580 #else
   8581       window_info->shape=MagickFalse;
   8582 #endif
   8583     }
   8584   if (window_info->shared_memory)
   8585     {
   8586 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
   8587       /*
   8588         Can we use shared memory with this window?
   8589       */
   8590       if (XShmQueryExtension(display) == 0)
   8591         window_info->shared_memory=MagickFalse;
   8592 #else
   8593       window_info->shared_memory=MagickFalse;
   8594 #endif
   8595     }
   8596   window_info->image=NewImageList();
   8597   window_info->destroy=MagickFalse;
   8598 }
   8599 
   8600 /*
   8602 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   8603 %                                                                             %
   8604 %                                                                             %
   8605 %                                                                             %
   8606 %   X M a g i c k P r o g r e s s M o n i t o r                               %
   8607 %                                                                             %
   8608 %                                                                             %
   8609 %                                                                             %
   8610 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   8611 %
   8612 %  XMagickProgressMonitor() displays the progress a task is making in
   8613 %  completing a task.
   8614 %
   8615 %  The format of the XMagickProgressMonitor method is:
   8616 %
   8617 %      void XMagickProgressMonitor(const char *task,
   8618 %        const MagickOffsetType quantum,const MagickSizeType span,
   8619 %        void *client_data)
   8620 %
   8621 %  A description of each parameter follows:
   8622 %
   8623 %    o task: Identifies the task in progress.
   8624 %
   8625 %    o quantum: Specifies the quantum position within the span which represents
   8626 %      how much progress has been made in completing a task.
   8627 %
   8628 %    o span: Specifies the span relative to completing a task.
   8629 %
   8630 %    o client_data: Pointer to any client data.
   8631 %
   8632 */
   8633 
   8634 static const char *GetLocaleMonitorMessage(const char *text)
   8635 {
   8636   char
   8637     message[MagickPathExtent],
   8638     tag[MagickPathExtent];
   8639 
   8640   const char
   8641     *locale_message;
   8642 
   8643   register char
   8644     *p;
   8645 
   8646   (void) CopyMagickString(tag,text,MagickPathExtent);
   8647   p=strrchr(tag,'/');
   8648   if (p != (char *) NULL)
   8649     *p='\0';
   8650   (void) FormatLocaleString(message,MagickPathExtent,"Monitor/%s",tag);
   8651   locale_message=GetLocaleMessage(message);
   8652   if (locale_message == message)
   8653     return(text);
   8654   return(locale_message);
   8655 }
   8656 
   8657 MagickPrivate MagickBooleanType XMagickProgressMonitor(const char *tag,
   8658   const MagickOffsetType quantum,const MagickSizeType span,
   8659   void *magick_unused(client_data))
   8660 {
   8661   XWindows
   8662     *windows;
   8663 
   8664   windows=XSetWindows((XWindows *) ~0);
   8665   if (windows == (XWindows *) NULL)
   8666     return(MagickTrue);
   8667   if (windows->info.mapped != MagickFalse)
   8668     XProgressMonitorWidget(windows->display,windows,
   8669       GetLocaleMonitorMessage(tag),quantum,span);
   8670   return(MagickTrue);
   8671 }
   8672 
   8673 /*
   8675 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   8676 %                                                                             %
   8677 %                                                                             %
   8678 %                                                                             %
   8679 %   X Q u e r y C o l o r D a t a b a s e                                     %
   8680 %                                                                             %
   8681 %                                                                             %
   8682 %                                                                             %
   8683 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   8684 %
   8685 %  XQueryColorCompliance() looks up a RGB values for a color given in the target
   8686 %  string.
   8687 %
   8688 %  The format of the XQueryColorDatabase method is:
   8689 %
   8690 %      MagickBooleanType XQueryColorCompliance(const char *target,XColor *color)
   8691 %
   8692 %  A description of each parameter follows:
   8693 %
   8694 %    o target: Specifies the color to lookup in the X color database.
   8695 %
   8696 %    o color: A pointer to an PixelInfo structure.  The RGB value of the target
   8697 %      color is returned as this value.
   8698 %
   8699 */
   8700 MagickPrivate MagickBooleanType XQueryColorCompliance(const char *target,
   8701   XColor *color)
   8702 {
   8703   Colormap
   8704     colormap;
   8705 
   8706   static Display
   8707     *display = (Display *) NULL;
   8708 
   8709   Status
   8710     status;
   8711 
   8712   XColor
   8713     xcolor;
   8714 
   8715   /*
   8716     Initialize color return value.
   8717   */
   8718   assert(color != (XColor *) NULL);
   8719   color->red=0;
   8720   color->green=0;
   8721   color->blue=0;
   8722   color->flags=(char) (DoRed | DoGreen | DoBlue);
   8723   if ((target == (char *) NULL) || (*target == '\0'))
   8724     target="#ffffffffffff";
   8725   /*
   8726     Let the X server define the color for us.
   8727   */
   8728   if (display == (Display *) NULL)
   8729     display=XOpenDisplay((char *) NULL);
   8730   if (display == (Display *) NULL)
   8731     {
   8732       ThrowXWindowException(XServerError,"ColorIsNotKnownToServer",target);
   8733       return(MagickFalse);
   8734     }
   8735   colormap=XDefaultColormap(display,XDefaultScreen(display));
   8736   status=XParseColor(display,colormap,(char *) target,&xcolor);
   8737   if (status == False)
   8738     ThrowXWindowException(XServerError,"ColorIsNotKnownToServer",target)
   8739   else
   8740     {
   8741       color->red=xcolor.red;
   8742       color->green=xcolor.green;
   8743       color->blue=xcolor.blue;
   8744       color->flags=xcolor.flags;
   8745     }
   8746   return(status != False ? MagickTrue : MagickFalse);
   8747 }
   8748 
   8749 /*
   8751 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   8752 %                                                                             %
   8753 %                                                                             %
   8754 %                                                                             %
   8755 %   X Q u e r y P o s i t i o n                                               %
   8756 %                                                                             %
   8757 %                                                                             %
   8758 %                                                                             %
   8759 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   8760 %
   8761 %  XQueryPosition() gets the pointer coordinates relative to a window.
   8762 %
   8763 %  The format of the XQueryPosition method is:
   8764 %
   8765 %      void XQueryPosition(Display *display,const Window window,int *x,int *y)
   8766 %
   8767 %  A description of each parameter follows:
   8768 %
   8769 %    o display: Specifies a connection to an X server;  returned from
   8770 %      XOpenDisplay.
   8771 %
   8772 %    o window: Specifies a pointer to a Window.
   8773 %
   8774 %    o x: Return the x coordinate of the pointer relative to the origin of the
   8775 %      window.
   8776 %
   8777 %    o y: Return the y coordinate of the pointer relative to the origin of the
   8778 %      window.
   8779 %
   8780 */
   8781 MagickPrivate void XQueryPosition(Display *display,const Window window,int *x,
   8782   int *y)
   8783 {
   8784   int
   8785     x_root,
   8786     y_root;
   8787 
   8788   unsigned int
   8789     mask;
   8790 
   8791   Window
   8792     root_window;
   8793 
   8794   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   8795   assert(display != (Display *) NULL);
   8796   assert(window != (Window) NULL);
   8797   assert(x != (int *) NULL);
   8798   assert(y != (int *) NULL);
   8799   (void) XQueryPointer(display,window,&root_window,&root_window,&x_root,&y_root,
   8800     x,y,&mask);
   8801 }
   8802 
   8803 /*
   8805 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   8806 %                                                                             %
   8807 %                                                                             %
   8808 %                                                                             %
   8809 %   X R e f r e s h W i n d o w                                               %
   8810 %                                                                             %
   8811 %                                                                             %
   8812 %                                                                             %
   8813 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   8814 %
   8815 %  XRefreshWindow() refreshes an image in a X window.
   8816 %
   8817 %  The format of the XRefreshWindow method is:
   8818 %
   8819 %      void XRefreshWindow(Display *display,const XWindowInfo *window,
   8820 %        const XEvent *event)
   8821 %
   8822 %  A description of each parameter follows:
   8823 %
   8824 %    o display: Specifies a connection to an X server;  returned from
   8825 %      XOpenDisplay.
   8826 %
   8827 %    o window: Specifies a pointer to a XWindowInfo structure.
   8828 %
   8829 %    o event: Specifies a pointer to a XEvent structure.  If it is NULL,
   8830 %      the entire image is refreshed.
   8831 %
   8832 */
   8833 MagickPrivate void XRefreshWindow(Display *display,const XWindowInfo *window,
   8834   const XEvent *event)
   8835 {
   8836   int
   8837     x,
   8838     y;
   8839 
   8840   unsigned int
   8841     height,
   8842     width;
   8843 
   8844   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   8845   assert(display != (Display *) NULL);
   8846   assert(window != (XWindowInfo *) NULL);
   8847   if (window->ximage == (XImage *) NULL)
   8848     return;
   8849   if (event != (XEvent *) NULL)
   8850     {
   8851       /*
   8852         Determine geometry from expose event.
   8853       */
   8854       x=event->xexpose.x;
   8855       y=event->xexpose.y;
   8856       width=(unsigned int) event->xexpose.width;
   8857       height=(unsigned int) event->xexpose.height;
   8858     }
   8859   else
   8860     {
   8861       XEvent
   8862         sans_event;
   8863 
   8864       /*
   8865         Refresh entire window; discard outstanding expose events.
   8866       */
   8867       x=0;
   8868       y=0;
   8869       width=window->width;
   8870       height=window->height;
   8871       while (XCheckTypedWindowEvent(display,window->id,Expose,&sans_event)) ;
   8872       if (window->matte_pixmap != (Pixmap) NULL)
   8873         {
   8874 #if defined(MAGICKCORE_HAVE_SHAPE)
   8875           if (window->shape != MagickFalse)
   8876             XShapeCombineMask(display,window->id,ShapeBounding,0,0,
   8877               window->matte_pixmap,ShapeSet);
   8878 #endif
   8879         }
   8880     }
   8881   /*
   8882     Check boundary conditions.
   8883   */
   8884   if ((window->ximage->width-(x+window->x)) < (int) width)
   8885     width=(unsigned int) (window->ximage->width-(x+window->x));
   8886   if ((window->ximage->height-(y+window->y)) < (int) height)
   8887     height=(unsigned int) (window->ximage->height-(y+window->y));
   8888   /*
   8889     Refresh image.
   8890   */
   8891   if (window->matte_pixmap != (Pixmap) NULL)
   8892     (void) XSetClipMask(display,window->annotate_context,window->matte_pixmap);
   8893   if (window->pixmap != (Pixmap) NULL)
   8894     {
   8895       if (window->depth > 1)
   8896         (void) XCopyArea(display,window->pixmap,window->id,
   8897           window->annotate_context,x+window->x,y+window->y,width,height,x,y);
   8898       else
   8899         (void) XCopyPlane(display,window->pixmap,window->id,
   8900           window->highlight_context,x+window->x,y+window->y,width,height,x,y,
   8901           1L);
   8902     }
   8903   else
   8904     {
   8905 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
   8906       if (window->shared_memory)
   8907         (void) XShmPutImage(display,window->id,window->annotate_context,
   8908           window->ximage,x+window->x,y+window->y,x,y,width,height,MagickTrue);
   8909 #endif
   8910       if (window->shared_memory == MagickFalse)
   8911         (void) XPutImage(display,window->id,window->annotate_context,
   8912           window->ximage,x+window->x,y+window->y,x,y,width,height);
   8913     }
   8914   if (window->matte_pixmap != (Pixmap) NULL)
   8915     (void) XSetClipMask(display,window->annotate_context,None);
   8916   (void) XFlush(display);
   8917 }
   8918 
   8919 /*
   8921 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   8922 %                                                                             %
   8923 %                                                                             %
   8924 %                                                                             %
   8925 %   X R e m o t e C o m m a n d                                               %
   8926 %                                                                             %
   8927 %                                                                             %
   8928 %                                                                             %
   8929 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   8930 %
   8931 %  XRemoteCommand() forces a remote display(1) to display the specified
   8932 %  image filename.
   8933 %
   8934 %  The format of the XRemoteCommand method is:
   8935 %
   8936 %      MagickBooleanType XRemoteCommand(Display *display,const char *window,
   8937 %        const char *filename)
   8938 %
   8939 %  A description of each parameter follows:
   8940 %
   8941 %    o display: Specifies a connection to an X server; returned from
   8942 %      XOpenDisplay.
   8943 %
   8944 %    o window: Specifies the name or id of an X window.
   8945 %
   8946 %    o filename: the name of the image filename to display.
   8947 %
   8948 */
   8949 MagickExport MagickBooleanType XRemoteCommand(Display *display,
   8950   const char *window,const char *filename)
   8951 {
   8952   Atom
   8953     remote_atom;
   8954 
   8955   Window
   8956     remote_window,
   8957     root_window;
   8958 
   8959   assert(filename != (char *) NULL);
   8960   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
   8961   if (display == (Display *) NULL)
   8962     display=XOpenDisplay((char *) NULL);
   8963   if (display == (Display *) NULL)
   8964     {
   8965       ThrowXWindowException(XServerError,"UnableToOpenXServer",filename);
   8966       return(MagickFalse);
   8967     }
   8968   remote_atom=XInternAtom(display,"IM_PROTOCOLS",MagickFalse);
   8969   remote_window=(Window) NULL;
   8970   root_window=XRootWindow(display,XDefaultScreen(display));
   8971   if (window != (char *) NULL)
   8972     {
   8973       /*
   8974         Search window hierarchy and identify any clients by name or ID.
   8975       */
   8976       if (isdigit((int) ((unsigned char) *window)) != 0)
   8977         remote_window=XWindowByID(display,root_window,(Window)
   8978           strtol((char *) window,(char **) NULL,0));
   8979       if (remote_window == (Window) NULL)
   8980         remote_window=XWindowByName(display,root_window,window);
   8981     }
   8982   if (remote_window == (Window) NULL)
   8983     remote_window=XWindowByProperty(display,root_window,remote_atom);
   8984   if (remote_window == (Window) NULL)
   8985     {
   8986       ThrowXWindowException(XServerError,"UnableToConnectToRemoteDisplay",
   8987         filename);
   8988       return(MagickFalse);
   8989     }
   8990   /*
   8991     Send remote command.
   8992   */
   8993   remote_atom=XInternAtom(display,"IM_REMOTE_COMMAND",MagickFalse);
   8994   (void) XChangeProperty(display,remote_window,remote_atom,XA_STRING,8,
   8995     PropModeReplace,(unsigned char *) filename,(int) strlen(filename));
   8996   (void) XSync(display,MagickFalse);
   8997   return(MagickTrue);
   8998 }
   8999 
   9000 /*
   9002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   9003 %                                                                             %
   9004 %                                                                             %
   9005 %                                                                             %
   9006 %   X R e n d e r I m a g e                                                   %
   9007 %                                                                             %
   9008 %                                                                             %
   9009 %                                                                             %
   9010 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   9011 %
   9012 %  XRenderImage() renders text on the image with an X11 font.  It also returns
   9013 %  the bounding box of the text relative to the image.
   9014 %
   9015 %  The format of the XRenderImage method is:
   9016 %
   9017 %      MagickBooleanType XRenderImage(Image *image,DrawInfo *draw_info,
   9018 %        const PointInfo *offset,TypeMetric *metrics,ExceptionInfo *exception)
   9019 %
   9020 %  A description of each parameter follows:
   9021 %
   9022 %    o image: the image.
   9023 %
   9024 %    o draw_info: the draw info.
   9025 %
   9026 %    o offset: (x,y) location of text relative to image.
   9027 %
   9028 %    o metrics: bounding box of text.
   9029 %
   9030 %    o exception: return any errors or warnings in this structure.
   9031 %
   9032 */
   9033 MagickPrivate MagickBooleanType XRenderImage(Image *image,
   9034   const DrawInfo *draw_info,const PointInfo *offset,TypeMetric *metrics,
   9035   ExceptionInfo *exception)
   9036 {
   9037   const char
   9038     *client_name;
   9039 
   9040   DrawInfo
   9041     cache_info;
   9042 
   9043   Display
   9044     *display;
   9045 
   9046   ImageInfo
   9047     *image_info;
   9048 
   9049   MagickBooleanType
   9050     status;
   9051 
   9052   size_t
   9053     height,
   9054     width;
   9055 
   9056   XAnnotateInfo
   9057     annotate_info;
   9058 
   9059   XFontStruct
   9060     *font_info;
   9061 
   9062   XPixelInfo
   9063     pixel;
   9064 
   9065   XResourceInfo
   9066     resource_info;
   9067 
   9068   XrmDatabase
   9069     resource_database;
   9070 
   9071   XStandardColormap
   9072     *map_info;
   9073 
   9074   XVisualInfo
   9075     *visual_info;
   9076 
   9077   /*
   9078     Open X server connection.
   9079   */
   9080   display=XOpenDisplay(draw_info->server_name);
   9081   if (display == (Display *) NULL)
   9082     {
   9083       ThrowXWindowException(XServerError,"UnableToOpenXServer",
   9084         draw_info->server_name);
   9085       return(MagickFalse);
   9086     }
   9087   /*
   9088     Get user defaults from X resource database.
   9089   */
   9090   (void) XSetErrorHandler(XError);
   9091   image_info=AcquireImageInfo();
   9092   client_name=GetClientName();
   9093   resource_database=XGetResourceDatabase(display,client_name);
   9094   XGetResourceInfo(image_info,resource_database,client_name,&resource_info);
   9095   resource_info.close_server=MagickFalse;
   9096   resource_info.colormap=PrivateColormap;
   9097   resource_info.font=AcquireString(draw_info->font);
   9098   resource_info.background_color=AcquireString("#ffffffffffff");
   9099   resource_info.foreground_color=AcquireString("#000000000000");
   9100   map_info=XAllocStandardColormap();
   9101   visual_info=(XVisualInfo *) NULL;
   9102   font_info=(XFontStruct *) NULL;
   9103   pixel.pixels=(unsigned long *) NULL;
   9104   if (map_info == (XStandardColormap *) NULL)
   9105     {
   9106       ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed",
   9107         image->filename);
   9108       return(MagickFalse);
   9109     }
   9110   /*
   9111     Initialize visual info.
   9112   */
   9113   visual_info=XBestVisualInfo(display,map_info,&resource_info);
   9114   if (visual_info == (XVisualInfo *) NULL)
   9115     {
   9116       XFreeResources(display,visual_info,map_info,&pixel,font_info,
   9117         &resource_info,(XWindowInfo *) NULL);
   9118       ThrowXWindowException(XServerError,"UnableToGetVisual",image->filename);
   9119       return(MagickFalse);
   9120     }
   9121   map_info->colormap=(Colormap) NULL;
   9122   /*
   9123     Initialize Standard Colormap info.
   9124   */
   9125   XGetMapInfo(visual_info,XDefaultColormap(display,visual_info->screen),
   9126     map_info);
   9127   XGetPixelInfo(display,visual_info,map_info,&resource_info,(Image *) NULL,
   9128     &pixel);
   9129   pixel.annotate_context=XDefaultGC(display,visual_info->screen);
   9130   /*
   9131     Initialize font info.
   9132   */
   9133   font_info=XBestFont(display,&resource_info,MagickFalse);
   9134   if (font_info == (XFontStruct *) NULL)
   9135     {
   9136       XFreeResources(display,visual_info,map_info,&pixel,font_info,
   9137         &resource_info,(XWindowInfo *) NULL);
   9138       ThrowXWindowException(XServerError,"UnableToLoadFont",draw_info->font);
   9139       return(MagickFalse);
   9140     }
   9141   cache_info=(*draw_info);
   9142   /*
   9143     Initialize annotate info.
   9144   */
   9145   XGetAnnotateInfo(&annotate_info);
   9146   annotate_info.stencil=ForegroundStencil;
   9147   if (cache_info.font != draw_info->font)
   9148     {
   9149       /*
   9150         Type name has changed.
   9151       */
   9152       (void) XFreeFont(display,font_info);
   9153       (void) CloneString(&resource_info.font,draw_info->font);
   9154       font_info=XBestFont(display,&resource_info,MagickFalse);
   9155       if (font_info == (XFontStruct *) NULL)
   9156         {
   9157           ThrowXWindowException(XServerError,"UnableToLoadFont",
   9158             draw_info->font);
   9159           return(MagickFalse);
   9160         }
   9161     }
   9162   if (image->debug != MagickFalse)
   9163     (void) LogMagickEvent(AnnotateEvent,GetMagickModule(),
   9164       "Font %s; pointsize %g",draw_info->font != (char *) NULL ?
   9165       draw_info->font : "none",draw_info->pointsize);
   9166   cache_info=(*draw_info);
   9167   annotate_info.font_info=font_info;
   9168   annotate_info.text=(char *) draw_info->text;
   9169   annotate_info.width=(unsigned int) XTextWidth(font_info,draw_info->text,(int)
   9170     strlen(draw_info->text));
   9171   annotate_info.height=(unsigned int) font_info->ascent+font_info->descent;
   9172   metrics->pixels_per_em.x=(double) font_info->max_bounds.width;
   9173   metrics->pixels_per_em.y=(double) font_info->ascent+font_info->descent;
   9174   metrics->ascent=(double) font_info->ascent+4;
   9175   metrics->descent=(double) (-font_info->descent);
   9176   metrics->width=annotate_info.width/ExpandAffine(&draw_info->affine);
   9177   metrics->height=font_info->ascent+font_info->descent;
   9178   metrics->max_advance=(double) font_info->max_bounds.width;
   9179   metrics->bounds.x1=0.0;
   9180   metrics->bounds.y1=metrics->descent;
   9181   metrics->bounds.x2=metrics->ascent+metrics->descent;
   9182   metrics->bounds.y2=metrics->ascent+metrics->descent;
   9183   metrics->underline_position=(-2.0);
   9184   metrics->underline_thickness=1.0;
   9185   if (draw_info->render == MagickFalse)
   9186     return(MagickTrue);
   9187   if (draw_info->fill.alpha == TransparentAlpha)
   9188     return(MagickTrue);
   9189   /*
   9190     Render fill color.
   9191   */
   9192   width=annotate_info.width;
   9193   height=annotate_info.height;
   9194   if ((fabs(draw_info->affine.rx) >= MagickEpsilon) ||
   9195       (fabs(draw_info->affine.ry) >= MagickEpsilon))
   9196     {
   9197       if ((fabs(draw_info->affine.sx-draw_info->affine.sy) < MagickEpsilon) &&
   9198           (fabs(draw_info->affine.rx+draw_info->affine.ry) < MagickEpsilon))
   9199         annotate_info.degrees=(double) (180.0/MagickPI)*
   9200           atan2(draw_info->affine.rx,draw_info->affine.sx);
   9201     }
   9202   (void) FormatLocaleString(annotate_info.geometry,MagickPathExtent,
   9203     "%.20gx%.20g%+.20g%+.20g",(double) width,(double) height,
   9204     ceil(offset->x-0.5),ceil(offset->y-metrics->ascent-metrics->descent+
   9205     draw_info->interline_spacing-0.5));
   9206   pixel.pen_color.red=ScaleQuantumToShort(draw_info->fill.red);
   9207   pixel.pen_color.green=ScaleQuantumToShort(draw_info->fill.green);
   9208   pixel.pen_color.blue=ScaleQuantumToShort(draw_info->fill.blue);
   9209   status=XAnnotateImage(display,&pixel,&annotate_info,image,exception);
   9210   if (status == 0)
   9211     {
   9212       ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed",
   9213         image->filename);
   9214       return(MagickFalse);
   9215     }
   9216   return(MagickTrue);
   9217 }
   9218 
   9219 /*
   9221 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   9222 %                                                                             %
   9223 %                                                                             %
   9224 %                                                                             %
   9225 %   X R e t a i n W i n d o w C o l o r s                                     %
   9226 %                                                                             %
   9227 %                                                                             %
   9228 %                                                                             %
   9229 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   9230 %
   9231 %  XRetainWindowColors() sets X11 color resources on a window.  This preserves
   9232 %  the colors associated with an image displayed on the window.
   9233 %
   9234 %  The format of the XRetainWindowColors method is:
   9235 %
   9236 %      void XRetainWindowColors(Display *display,const Window window)
   9237 %
   9238 %  A description of each parameter follows:
   9239 %
   9240 %    o display: Specifies a connection to an X server; returned from
   9241 %      XOpenDisplay.
   9242 %
   9243 %    o window: Specifies a pointer to a XWindowInfo structure.
   9244 %
   9245 */
   9246 MagickExport void XRetainWindowColors(Display *display,const Window window)
   9247 {
   9248   Atom
   9249     property;
   9250 
   9251   Pixmap
   9252     pixmap;
   9253 
   9254   /*
   9255     Put property on the window.
   9256   */
   9257   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   9258   assert(display != (Display *) NULL);
   9259   assert(window != (Window) NULL);
   9260   property=XInternAtom(display,"_XSETROOT_ID",MagickFalse);
   9261   if (property == (Atom) NULL)
   9262     {
   9263       ThrowXWindowException(XServerError,"UnableToCreateProperty",
   9264         "_XSETROOT_ID");
   9265       return;
   9266     }
   9267   pixmap=XCreatePixmap(display,window,1,1,1);
   9268   if (pixmap == (Pixmap) NULL)
   9269     {
   9270       ThrowXWindowException(XServerError,"UnableToCreateBitmap","");
   9271       return;
   9272     }
   9273   (void) XChangeProperty(display,window,property,XA_PIXMAP,32,PropModeReplace,
   9274     (unsigned char *) &pixmap,1);
   9275   (void) XSetCloseDownMode(display,RetainPermanent);
   9276 }
   9277 
   9278 /*
   9280 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   9281 %                                                                             %
   9282 %                                                                             %
   9283 %                                                                             %
   9284 %   X S e l e c t W i n d o w                                                 %
   9285 %                                                                             %
   9286 %                                                                             %
   9287 %                                                                             %
   9288 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   9289 %
   9290 %  XSelectWindow() allows a user to select a window using the mouse.  If the
   9291 %  mouse moves, a cropping rectangle is drawn and the extents of the rectangle
   9292 %  is returned in the crop_info structure.
   9293 %
   9294 %  The format of the XSelectWindow function is:
   9295 %
   9296 %      target_window=XSelectWindow(display,crop_info)
   9297 %
   9298 %  A description of each parameter follows:
   9299 %
   9300 %    o window: XSelectWindow returns the window id.
   9301 %
   9302 %    o display: Specifies a pointer to the Display structure;  returned from
   9303 %      XOpenDisplay.
   9304 %
   9305 %    o crop_info: Specifies a pointer to a RectangleInfo structure.  It
   9306 %      contains the extents of any cropping rectangle.
   9307 %
   9308 */
   9309 static Window XSelectWindow(Display *display,RectangleInfo *crop_info)
   9310 {
   9311 #define MinimumCropArea  (unsigned int) 9
   9312 
   9313   Cursor
   9314     target_cursor;
   9315 
   9316   GC
   9317     annotate_context;
   9318 
   9319   int
   9320     presses,
   9321     x_offset,
   9322     y_offset;
   9323 
   9324   Status
   9325     status;
   9326 
   9327   Window
   9328     root_window,
   9329     target_window;
   9330 
   9331   XEvent
   9332     event;
   9333 
   9334   XGCValues
   9335     context_values;
   9336 
   9337   /*
   9338     Initialize graphic context.
   9339   */
   9340   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   9341   assert(display != (Display *) NULL);
   9342   assert(crop_info != (RectangleInfo *) NULL);
   9343   root_window=XRootWindow(display,XDefaultScreen(display));
   9344   context_values.background=XBlackPixel(display,XDefaultScreen(display));
   9345   context_values.foreground=XWhitePixel(display,XDefaultScreen(display));
   9346   context_values.function=GXinvert;
   9347   context_values.plane_mask=
   9348     context_values.background ^ context_values.foreground;
   9349   context_values.subwindow_mode=IncludeInferiors;
   9350   annotate_context=XCreateGC(display,root_window,(size_t) (GCBackground |
   9351     GCForeground | GCFunction | GCSubwindowMode),&context_values);
   9352   if (annotate_context == (GC) NULL)
   9353     return(MagickFalse);
   9354   /*
   9355     Grab the pointer using target cursor.
   9356   */
   9357   target_cursor=XMakeCursor(display,root_window,XDefaultColormap(display,
   9358     XDefaultScreen(display)),(char * ) "white",(char * ) "black");
   9359   status=XGrabPointer(display,root_window,MagickFalse,(unsigned int)
   9360     (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask),GrabModeSync,
   9361     GrabModeAsync,root_window,target_cursor,CurrentTime);
   9362   if (status != GrabSuccess)
   9363     {
   9364       ThrowXWindowException(XServerError,"UnableToGrabMouse","");
   9365       return((Window) NULL);
   9366     }
   9367   /*
   9368     Select a window.
   9369   */
   9370   crop_info->width=0;
   9371   crop_info->height=0;
   9372   presses=0;
   9373   target_window=(Window) NULL;
   9374   x_offset=0;
   9375   y_offset=0;
   9376   do
   9377   {
   9378     if ((crop_info->width*crop_info->height) >= MinimumCropArea)
   9379       (void) XDrawRectangle(display,root_window,annotate_context,
   9380         (int) crop_info->x,(int) crop_info->y,(unsigned int) crop_info->width-1,
   9381         (unsigned int) crop_info->height-1);
   9382     /*
   9383       Allow another event.
   9384     */
   9385     (void) XAllowEvents(display,SyncPointer,CurrentTime);
   9386     (void) XWindowEvent(display,root_window,ButtonPressMask |
   9387       ButtonReleaseMask | ButtonMotionMask,&event);
   9388     if ((crop_info->width*crop_info->height) >= MinimumCropArea)
   9389       (void) XDrawRectangle(display,root_window,annotate_context,
   9390         (int) crop_info->x,(int) crop_info->y,(unsigned int) crop_info->width-1,
   9391         (unsigned int) crop_info->height-1);
   9392     switch (event.type)
   9393     {
   9394       case ButtonPress:
   9395       {
   9396         target_window=XGetSubwindow(display,event.xbutton.subwindow,
   9397           event.xbutton.x,event.xbutton.y);
   9398         if (target_window == (Window) NULL)
   9399           target_window=root_window;
   9400         x_offset=event.xbutton.x_root;
   9401         y_offset=event.xbutton.y_root;
   9402         crop_info->x=(ssize_t) x_offset;
   9403         crop_info->y=(ssize_t) y_offset;
   9404         crop_info->width=0;
   9405         crop_info->height=0;
   9406         presses++;
   9407         break;
   9408       }
   9409       case ButtonRelease:
   9410       {
   9411         presses--;
   9412         break;
   9413       }
   9414       case MotionNotify:
   9415       {
   9416         /*
   9417           Discard pending button motion events.
   9418         */
   9419         while (XCheckMaskEvent(display,ButtonMotionMask,&event)) ;
   9420         crop_info->x=(ssize_t) event.xmotion.x;
   9421         crop_info->y=(ssize_t) event.xmotion.y;
   9422         /*
   9423           Check boundary conditions.
   9424         */
   9425         if ((int) crop_info->x < x_offset)
   9426           crop_info->width=(size_t) (x_offset-crop_info->x);
   9427         else
   9428           {
   9429             crop_info->width=(size_t) (crop_info->x-x_offset);
   9430             crop_info->x=(ssize_t) x_offset;
   9431           }
   9432         if ((int) crop_info->y < y_offset)
   9433           crop_info->height=(size_t) (y_offset-crop_info->y);
   9434         else
   9435           {
   9436             crop_info->height=(size_t) (crop_info->y-y_offset);
   9437             crop_info->y=(ssize_t) y_offset;
   9438           }
   9439       }
   9440       default:
   9441         break;
   9442     }
   9443   } while ((target_window == (Window) NULL) || (presses > 0));
   9444   (void) XUngrabPointer(display,CurrentTime);
   9445   (void) XFreeCursor(display,target_cursor);
   9446   (void) XFreeGC(display,annotate_context);
   9447   if ((crop_info->width*crop_info->height) < MinimumCropArea)
   9448     {
   9449       crop_info->width=0;
   9450       crop_info->height=0;
   9451     }
   9452   if ((crop_info->width != 0) && (crop_info->height != 0))
   9453     target_window=root_window;
   9454   return(target_window);
   9455 }
   9456 
   9457 /*
   9459 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   9460 %                                                                             %
   9461 %                                                                             %
   9462 %                                                                             %
   9463 %   X S e t C u r s o r S t a t e                                             %
   9464 %                                                                             %
   9465 %                                                                             %
   9466 %                                                                             %
   9467 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   9468 %
   9469 %  XSetCursorState() sets the cursor state to busy, otherwise the cursor are
   9470 %  reset to their default.
   9471 %
   9472 %  The format of the XXSetCursorState method is:
   9473 %
   9474 %      XSetCursorState(display,windows,const MagickStatusType state)
   9475 %
   9476 %  A description of each parameter follows:
   9477 %
   9478 %    o display: Specifies a connection to an X server;  returned from
   9479 %      XOpenDisplay.
   9480 %
   9481 %    o windows: Specifies a pointer to a XWindows structure.
   9482 %
   9483 %    o state: An unsigned integer greater than 0 sets the cursor state
   9484 %      to busy, otherwise the cursor are reset to their default.
   9485 %
   9486 */
   9487 MagickPrivate void XSetCursorState(Display *display,XWindows *windows,
   9488   const MagickStatusType state)
   9489 {
   9490   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   9491   assert(display != (Display *) NULL);
   9492   assert(windows != (XWindows *) NULL);
   9493   if (state)
   9494     {
   9495       (void) XCheckDefineCursor(display,windows->image.id,
   9496         windows->image.busy_cursor);
   9497       (void) XCheckDefineCursor(display,windows->pan.id,
   9498         windows->pan.busy_cursor);
   9499       (void) XCheckDefineCursor(display,windows->magnify.id,
   9500         windows->magnify.busy_cursor);
   9501       (void) XCheckDefineCursor(display,windows->command.id,
   9502         windows->command.busy_cursor);
   9503     }
   9504   else
   9505     {
   9506       (void) XCheckDefineCursor(display,windows->image.id,
   9507         windows->image.cursor);
   9508       (void) XCheckDefineCursor(display,windows->pan.id,windows->pan.cursor);
   9509       (void) XCheckDefineCursor(display,windows->magnify.id,
   9510         windows->magnify.cursor);
   9511       (void) XCheckDefineCursor(display,windows->command.id,
   9512         windows->command.cursor);
   9513       (void) XCheckDefineCursor(display,windows->command.id,
   9514         windows->widget.cursor);
   9515       (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
   9516     }
   9517   windows->info.mapped=MagickFalse;
   9518 }
   9519 
   9520 /*
   9522 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   9523 %                                                                             %
   9524 %                                                                             %
   9525 %                                                                             %
   9526 %   X S e t W i n d o w s                                                     %
   9527 %                                                                             %
   9528 %                                                                             %
   9529 %                                                                             %
   9530 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   9531 %
   9532 %  XSetWindows() sets the X windows structure if the windows info is specified.
   9533 %  Otherwise the current windows structure is returned.
   9534 %
   9535 %  The format of the XSetWindows method is:
   9536 %
   9537 %      XWindows *XSetWindows(XWindows *windows_info)
   9538 %
   9539 %  A description of each parameter follows:
   9540 %
   9541 %    o windows_info: Initialize the Windows structure with this information.
   9542 %
   9543 */
   9544 MagickPrivate XWindows *XSetWindows(XWindows *windows_info)
   9545 {
   9546   static XWindows
   9547     *windows = (XWindows *) NULL;
   9548 
   9549   if (windows_info != (XWindows *) ~0)
   9550     {
   9551       windows=(XWindows *) RelinquishMagickMemory(windows);
   9552       windows=windows_info;
   9553     }
   9554   return(windows);
   9555 }
   9556 /*
   9557 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   9558 %                                                                             %
   9559 %                                                                             %
   9560 %                                                                             %
   9561 %   X U s e r P r e f e r e n c e s                                           %
   9562 %                                                                             %
   9563 %                                                                             %
   9564 %                                                                             %
   9565 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   9566 %
   9567 %  XUserPreferences() saves the preferences in a configuration file in the
   9568 %  users' home directory.
   9569 %
   9570 %  The format of the XUserPreferences method is:
   9571 %
   9572 %      void XUserPreferences(XResourceInfo *resource_info)
   9573 %
   9574 %  A description of each parameter follows:
   9575 %
   9576 %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
   9577 %
   9578 */
   9579 MagickPrivate void XUserPreferences(XResourceInfo *resource_info)
   9580 {
   9581 #if defined(X11_PREFERENCES_PATH)
   9582   char
   9583     cache[MagickPathExtent],
   9584     filename[MagickPathExtent],
   9585     specifier[MagickPathExtent];
   9586 
   9587   const char
   9588     *client_name,
   9589     *value;
   9590 
   9591   XrmDatabase
   9592     preferences_database;
   9593 
   9594   /*
   9595     Save user preferences to the client configuration file.
   9596   */
   9597   assert(resource_info != (XResourceInfo *) NULL);
   9598   client_name=GetClientName();
   9599   preferences_database=XrmGetStringDatabase("");
   9600   (void) FormatLocaleString(specifier,MagickPathExtent,"%s.backdrop",client_name);
   9601   value=resource_info->backdrop ? "True" : "False";
   9602   XrmPutStringResource(&preferences_database,specifier,(char *) value);
   9603   (void) FormatLocaleString(specifier,MagickPathExtent,"%s.colormap",client_name);
   9604   value=resource_info->colormap == SharedColormap ? "Shared" : "Private";
   9605   XrmPutStringResource(&preferences_database,specifier,(char *) value);
   9606   (void) FormatLocaleString(specifier,MagickPathExtent,"%s.confirmExit",
   9607     client_name);
   9608   value=resource_info->confirm_exit ? "True" : "False";
   9609   XrmPutStringResource(&preferences_database,specifier,(char *) value);
   9610   (void) FormatLocaleString(specifier,MagickPathExtent,"%s.confirmEdit",
   9611     client_name);
   9612   value=resource_info->confirm_edit ? "True" : "False";
   9613   XrmPutStringResource(&preferences_database,specifier,(char *) value);
   9614   (void) FormatLocaleString(specifier,MagickPathExtent,"%s.displayWarnings",
   9615     client_name);
   9616   value=resource_info->display_warnings ? "True" : "False";
   9617   XrmPutStringResource(&preferences_database,specifier,(char *) value);
   9618   (void) FormatLocaleString(specifier,MagickPathExtent,"%s.dither",client_name);
   9619   value=resource_info->quantize_info->dither_method != NoDitherMethod ?
   9620     "True" : "False";
   9621   XrmPutStringResource(&preferences_database,specifier,(char *) value);
   9622   (void) FormatLocaleString(specifier,MagickPathExtent,"%s.gammaCorrect",
   9623     client_name);
   9624   value=resource_info->gamma_correct ? "True" : "False";
   9625   XrmPutStringResource(&preferences_database,specifier,(char *) value);
   9626   (void) FormatLocaleString(specifier,MagickPathExtent,"%s.undoCache",client_name);
   9627   (void) FormatLocaleString(cache,MagickPathExtent,"%.20g",(double)
   9628     resource_info->undo_cache);
   9629   XrmPutStringResource(&preferences_database,specifier,cache);
   9630   (void) FormatLocaleString(specifier,MagickPathExtent,"%s.usePixmap",client_name);
   9631   value=resource_info->use_pixmap ? "True" : "False";
   9632   XrmPutStringResource(&preferences_database,specifier,(char *) value);
   9633   (void) FormatLocaleString(filename,MagickPathExtent,"%s%src",
   9634     X11_PREFERENCES_PATH,client_name);
   9635   ExpandFilename(filename);
   9636   XrmPutFileDatabase(preferences_database,filename);
   9637 #endif
   9638 }
   9639 
   9640 /*
   9642 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   9643 %                                                                             %
   9644 %                                                                             %
   9645 %                                                                             %
   9646 %   X V i s u a l C l a s s N a m e                                           %
   9647 %                                                                             %
   9648 %                                                                             %
   9649 %                                                                             %
   9650 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   9651 %
   9652 %  XVisualClassName() returns the visual class name as a character string.
   9653 %
   9654 %  The format of the XVisualClassName method is:
   9655 %
   9656 %      char *XVisualClassName(const int visual_class)
   9657 %
   9658 %  A description of each parameter follows:
   9659 %
   9660 %    o visual_type: XVisualClassName returns the visual class as a character
   9661 %      string.
   9662 %
   9663 %    o class: Specifies the visual class.
   9664 %
   9665 */
   9666 static const char *XVisualClassName(const int visual_class)
   9667 {
   9668   switch (visual_class)
   9669   {
   9670     case StaticGray: return("StaticGray");
   9671     case GrayScale: return("GrayScale");
   9672     case StaticColor: return("StaticColor");
   9673     case PseudoColor: return("PseudoColor");
   9674     case TrueColor: return("TrueColor");
   9675     case DirectColor: return("DirectColor");
   9676   }
   9677   return("unknown visual class");
   9678 }
   9679 
   9680 /*
   9682 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   9683 %                                                                             %
   9684 %                                                                             %
   9685 %                                                                             %
   9686 %   X W a r n i n g                                                           %
   9687 %                                                                             %
   9688 %                                                                             %
   9689 %                                                                             %
   9690 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   9691 %
   9692 %  XWarning() displays a warning reason in a Notice widget.
   9693 %
   9694 %  The format of the XWarning method is:
   9695 %
   9696 %      void XWarning(const unsigned int warning,const char *reason,
   9697 %        const char *description)
   9698 %
   9699 %  A description of each parameter follows:
   9700 %
   9701 %    o warning: Specifies the numeric warning category.
   9702 %
   9703 %    o reason: Specifies the reason to display before terminating the
   9704 %      program.
   9705 %
   9706 %    o description: Specifies any description to the reason.
   9707 %
   9708 */
   9709 MagickPrivate void XWarning(const ExceptionType magick_unused(warning),
   9710   const char *reason,const char *description)
   9711 {
   9712   char
   9713     text[MagickPathExtent];
   9714 
   9715   XWindows
   9716     *windows;
   9717 
   9718   if (reason == (char *) NULL)
   9719     return;
   9720   (void) CopyMagickString(text,reason,MagickPathExtent);
   9721   (void) ConcatenateMagickString(text,":",MagickPathExtent);
   9722   windows=XSetWindows((XWindows *) ~0);
   9723   XNoticeWidget(windows->display,windows,text,(char *) description);
   9724 }
   9725 
   9726 /*
   9728 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   9729 %                                                                             %
   9730 %                                                                             %
   9731 %                                                                             %
   9732 %   X W i n d o w B y I D                                                     %
   9733 %                                                                             %
   9734 %                                                                             %
   9735 %                                                                             %
   9736 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   9737 %
   9738 %  XWindowByID() locates a child window with a given ID.  If not window with
   9739 %  the given name is found, 0 is returned.   Only the window specified and its
   9740 %  subwindows are searched.
   9741 %
   9742 %  The format of the XWindowByID function is:
   9743 %
   9744 %      child=XWindowByID(display,window,id)
   9745 %
   9746 %  A description of each parameter follows:
   9747 %
   9748 %    o child: XWindowByID returns the window with the specified
   9749 %      id.  If no windows are found, XWindowByID returns 0.
   9750 %
   9751 %    o display: Specifies a pointer to the Display structure;  returned from
   9752 %      XOpenDisplay.
   9753 %
   9754 %    o id: Specifies the id of the window to locate.
   9755 %
   9756 */
   9757 MagickPrivate Window XWindowByID(Display *display,const Window root_window,
   9758   const size_t id)
   9759 {
   9760   RectangleInfo
   9761     rectangle_info;
   9762 
   9763   register int
   9764     i;
   9765 
   9766   Status
   9767     status;
   9768 
   9769   unsigned int
   9770     number_children;
   9771 
   9772   Window
   9773     child,
   9774     *children,
   9775     window;
   9776 
   9777   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   9778   assert(display != (Display *) NULL);
   9779   assert(root_window != (Window) NULL);
   9780   if (id == 0)
   9781     return(XSelectWindow(display,&rectangle_info));
   9782   if (root_window == id)
   9783     return(root_window);
   9784   status=XQueryTree(display,root_window,&child,&child,&children,
   9785     &number_children);
   9786   if (status == False)
   9787     return((Window) NULL);
   9788   window=(Window) NULL;
   9789   for (i=0; i < (int) number_children; i++)
   9790   {
   9791     /*
   9792       Search each child and their children.
   9793     */
   9794     window=XWindowByID(display,children[i],id);
   9795     if (window != (Window) NULL)
   9796       break;
   9797   }
   9798   if (children != (Window *) NULL)
   9799     (void) XFree((void *) children);
   9800   return(window);
   9801 }
   9802 
   9803 /*
   9805 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   9806 %                                                                             %
   9807 %                                                                             %
   9808 %                                                                             %
   9809 %   X W i n d o w B y N a m e                                                 %
   9810 %                                                                             %
   9811 %                                                                             %
   9812 %                                                                             %
   9813 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   9814 %
   9815 %  XWindowByName() locates a window with a given name on a display.  If no
   9816 %  window with the given name is found, 0 is returned. If more than one window
   9817 %  has the given name, the first one is returned.  Only root and its children
   9818 %  are searched.
   9819 %
   9820 %  The format of the XWindowByName function is:
   9821 %
   9822 %      window=XWindowByName(display,root_window,name)
   9823 %
   9824 %  A description of each parameter follows:
   9825 %
   9826 %    o window: XWindowByName returns the window id.
   9827 %
   9828 %    o display: Specifies a pointer to the Display structure;  returned from
   9829 %      XOpenDisplay.
   9830 %
   9831 %    o root_window: Specifies the id of the root window.
   9832 %
   9833 %    o name: Specifies the name of the window to locate.
   9834 %
   9835 */
   9836 MagickPrivate Window XWindowByName(Display *display,const Window root_window,
   9837   const char *name)
   9838 {
   9839   register int
   9840     i;
   9841 
   9842   Status
   9843     status;
   9844 
   9845   unsigned int
   9846     number_children;
   9847 
   9848   Window
   9849     *children,
   9850     child,
   9851     window;
   9852 
   9853   XTextProperty
   9854     window_name;
   9855 
   9856   assert(display != (Display *) NULL);
   9857   assert(root_window != (Window) NULL);
   9858   assert(name != (char *) NULL);
   9859   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
   9860   if (XGetWMName(display,root_window,&window_name) != 0)
   9861     if (LocaleCompare((char *) window_name.value,name) == 0)
   9862       return(root_window);
   9863   status=XQueryTree(display,root_window,&child,&child,&children,
   9864     &number_children);
   9865   if (status == False)
   9866     return((Window) NULL);
   9867   window=(Window) NULL;
   9868   for (i=0; i < (int) number_children; i++)
   9869   {
   9870     /*
   9871       Search each child and their children.
   9872     */
   9873     window=XWindowByName(display,children[i],name);
   9874     if (window != (Window) NULL)
   9875       break;
   9876   }
   9877   if (children != (Window *) NULL)
   9878     (void) XFree((void *) children);
   9879   return(window);
   9880 }
   9881 
   9882 /*
   9884 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   9885 %                                                                             %
   9886 %                                                                             %
   9887 %                                                                             %
   9888 %   X W i n d o w B y P r o p e r y                                           %
   9889 %                                                                             %
   9890 %                                                                             %
   9891 %                                                                             %
   9892 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   9893 %
   9894 %  XWindowByProperty() locates a child window with a given property. If not
   9895 %  window with the given name is found, 0 is returned.  If more than one window
   9896 %  has the given property, the first one is returned.  Only the window
   9897 %  specified and its subwindows are searched.
   9898 %
   9899 %  The format of the XWindowByProperty function is:
   9900 %
   9901 %      child=XWindowByProperty(display,window,property)
   9902 %
   9903 %  A description of each parameter follows:
   9904 %
   9905 %    o child: XWindowByProperty returns the window id with the specified
   9906 %      property.  If no windows are found, XWindowByProperty returns 0.
   9907 %
   9908 %    o display: Specifies a pointer to the Display structure;  returned from
   9909 %      XOpenDisplay.
   9910 %
   9911 %    o property: Specifies the property of the window to locate.
   9912 %
   9913 */
   9914 MagickPrivate Window XWindowByProperty(Display *display,const Window window,
   9915   const Atom property)
   9916 {
   9917   Atom
   9918     type;
   9919 
   9920   int
   9921     format;
   9922 
   9923   Status
   9924     status;
   9925 
   9926   unsigned char
   9927     *data;
   9928 
   9929   unsigned int
   9930     i,
   9931     number_children;
   9932 
   9933   unsigned long
   9934     after,
   9935     number_items;
   9936 
   9937   Window
   9938     child,
   9939     *children,
   9940     parent,
   9941     root;
   9942 
   9943   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   9944   assert(display != (Display *) NULL);
   9945   assert(window != (Window) NULL);
   9946   assert(property != (Atom) NULL);
   9947   status=XQueryTree(display,window,&root,&parent,&children,&number_children);
   9948   if (status == False)
   9949     return((Window) NULL);
   9950   type=(Atom) NULL;
   9951   child=(Window) NULL;
   9952   for (i=0; (i < number_children) && (child == (Window) NULL); i++)
   9953   {
   9954     status=XGetWindowProperty(display,children[i],property,0L,0L,MagickFalse,
   9955       (Atom) AnyPropertyType,&type,&format,&number_items,&after,&data);
   9956     if (data != NULL)
   9957       (void) XFree((void *) data);
   9958     if ((status == Success) && (type != (Atom) NULL))
   9959       child=children[i];
   9960   }
   9961   for (i=0; (i < number_children) && (child == (Window) NULL); i++)
   9962     child=XWindowByProperty(display,children[i],property);
   9963   if (children != (Window *) NULL)
   9964     (void) XFree((void *) children);
   9965   return(child);
   9966 }
   9967 #else
   9968 
   9969 /*
   9971 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   9972 %                                                                             %
   9973 %                                                                             %
   9974 %                                                                             %
   9975 %   X I m p o r t I m a g e                                                   %
   9976 %                                                                             %
   9977 %                                                                             %
   9978 %                                                                             %
   9979 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   9980 %
   9981 %  XImportImage() reads an image from an X window.
   9982 %
   9983 %  The format of the XImportImage method is:
   9984 %
   9985 %      Image *XImportImage(const ImageInfo *image_info,XImportInfo *ximage_info,
   9986 %        ExceptionInfo *exception)
   9987 %
   9988 %  A description of each parameter follows:
   9989 %
   9990 %    o image_info: the image info..
   9991 %
   9992 %    o ximage_info: Specifies a pointer to an XImportInfo structure.
   9993 %
   9994 %    o exception: return any errors or warnings in this structure.
   9995 %
   9996 */
   9997 MagickExport Image *XImportImage(const ImageInfo *image_info,
   9998   XImportInfo *ximage_info,ExceptionInfo *exception)
   9999 {
   10000   assert(image_info != (const ImageInfo *) NULL);
   10001   assert(image_info->signature == MagickCoreSignature);
   10002   if (image_info->debug != MagickFalse)
   10003     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
   10004       image_info->filename);
   10005   assert(ximage_info != (XImportInfo *) NULL);
   10006   assert(exception != (ExceptionInfo *) NULL);
   10007   assert(exception->signature == MagickCoreSignature);
   10008   return((Image *) NULL);
   10009 }
   10010 
   10011 /*
   10013 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   10014 %                                                                             %
   10015 %                                                                             %
   10016 %                                                                             %
   10017 %   X R e n d e r X 1 1                                                       %
   10018 %                                                                             %
   10019 %                                                                             %
   10020 %                                                                             %
   10021 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   10022 %
   10023 %  XRenderImage() renders text on the image with an X11 font.  It also returns
   10024 %  the bounding box of the text relative to the image.
   10025 %
   10026 %  The format of the XRenderImage method is:
   10027 %
   10028 %      MagickBooleanType XRenderImage(Image *image,DrawInfo *draw_info,
   10029 %        const PointInfo *offset,TypeMetric *metrics,ExceptionInfo *exception)
   10030 %
   10031 %  A description of each parameter follows:
   10032 %
   10033 %    o image: the image.
   10034 %
   10035 %    o draw_info: the draw info.
   10036 %
   10037 %    o offset: (x,y) location of text relative to image.
   10038 %
   10039 %    o metrics: bounding box of text.
   10040 %
   10041 %    o exception: return any errors or warnings in this structure.
   10042 %
   10043 */
   10044 MagickPrivate MagickBooleanType XRenderImage(Image *image,
   10045   const DrawInfo *draw_info,const PointInfo *offset,TypeMetric *metrics,
   10046   ExceptionInfo *exception)
   10047 {
   10048   (void) draw_info;
   10049   (void) offset;
   10050   (void) metrics;
   10051   (void) ThrowMagickException(exception,GetMagickModule(),
   10052     MissingDelegateError,"DelegateLibrarySupportNotBuiltIn","'%s' (X11)",
   10053     image->filename);
   10054   return(MagickFalse);
   10055 }
   10056 #endif
   10057 
   10058 /*
   10060 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   10061 %                                                                             %
   10062 %                                                                             %
   10063 %                                                                             %
   10064 +   X C o m p o n e n t G e n e s i s                                         %
   10065 %                                                                             %
   10066 %                                                                             %
   10067 %                                                                             %
   10068 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   10069 %
   10070 %  XComponentGenesis() instantiates the X component.
   10071 %
   10072 %  The format of the XComponentGenesis method is:
   10073 %
   10074 %      MagickBooleanType XComponentGenesis(void)
   10075 %
   10076 */
   10077 MagickPrivate MagickBooleanType XComponentGenesis(void)
   10078 {
   10079   return(MagickTrue);
   10080 }
   10081 
   10082 /*
   10084 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   10085 %                                                                             %
   10086 %                                                                             %
   10087 %                                                                             %
   10088 %   X G e t I m p o r t I n f o                                               %
   10089 %                                                                             %
   10090 %                                                                             %
   10091 %                                                                             %
   10092 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   10093 %
   10094 %  XGetImportInfo() initializes the XImportInfo structure.
   10095 %
   10096 %  The format of the XGetImportInfo method is:
   10097 %
   10098 %      void XGetImportInfo(XImportInfo *ximage_info)
   10099 %
   10100 %  A description of each parameter follows:
   10101 %
   10102 %    o ximage_info: Specifies a pointer to an ImageInfo structure.
   10103 %
   10104 */
   10105 MagickExport void XGetImportInfo(XImportInfo *ximage_info)
   10106 {
   10107   assert(ximage_info != (XImportInfo *) NULL);
   10108   ximage_info->frame=MagickFalse;
   10109   ximage_info->borders=MagickFalse;
   10110   ximage_info->screen=MagickFalse;
   10111   ximage_info->descend=MagickTrue;
   10112   ximage_info->silent=MagickFalse;
   10113 }
   10114