xwindow.c

Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                                                                             %
00006 %              X   X  W   W  IIIII  N   N  DDDD    OOO   W   W                %
00007 %               X X   W   W    I    NN  N  D   D  O   O  W   W                %
00008 %                X    W   W    I    N N N  D   D  O   O  W   W                %
00009 %               X X   W W W    I    N  NN  D   D  O   O  W W W                %
00010 %              X   X   W W   IIIII  N   N  DDDD    OOO    W W                 %
00011 %                                                                             %
00012 %                                                                             %
00013 %                       MagickCore X11 Utility Methods                        %
00014 %                                                                             %
00015 %                               Software Design                               %
00016 %                                 John Cristy                                 %
00017 %                                  July 1992                                  %
00018 %                                                                             %
00019 %                                                                             %
00020 %  Copyright 1999-2008 ImageMagick Studio LLC, a non-profit organization      %
00021 %  dedicated to making software imaging solutions freely available.           %
00022 %                                                                             %
00023 %  You may not use this file except in compliance with the License.  You may  %
00024 %  obtain a copy of the License at                                            %
00025 %                                                                             %
00026 %    http://www.imagemagick.org/script/license.php                            %
00027 %                                                                             %
00028 %  Unless required by applicable law or agreed to in writing, software        %
00029 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00030 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00031 %  See the License for the specific language governing permissions and        %
00032 %  limitations under the License.                                             %
00033 %                                                                             %
00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00035 %
00036 %
00037 */
00038 
00039 /*
00040   Include declarations.
00041 */
00042 #include "magick/studio.h"
00043 #include "magick/animate.h"
00044 #include "magick/blob.h"
00045 #include "magick/cache.h"
00046 #include "magick/client.h"
00047 #include "magick/color.h"
00048 #include "magick/color-private.h"
00049 #include "magick/composite.h"
00050 #include "magick/display.h"
00051 #include "magick/exception.h"
00052 #include "magick/exception-private.h"
00053 #include "magick/geometry.h"
00054 #include "magick/identify.h"
00055 #include "magick/image.h"
00056 #include "magick/image-private.h"
00057 #include "magick/list.h"
00058 #include "magick/locale_.h"
00059 #include "magick/log.h"
00060 #include "magick/magick.h"
00061 #include "magick/memory_.h"
00062 #include "magick/monitor.h"
00063 #include "magick/option.h"
00064 #include "magick/PreRvIcccm.h"
00065 #include "magick/quantize.h"
00066 #include "magick/quantum.h"
00067 #include "magick/quantum-private.h"
00068 #include "magick/resource_.h"
00069 #include "magick/resize.h"
00070 #include "magick/shear.h"
00071 #include "magick/statistic.h"
00072 #include "magick/string_.h"
00073 #include "magick/transform.h"
00074 #include "magick/utility.h"
00075 #include "magick/widget.h"
00076 #include "magick/xwindow.h"
00077 #include "magick/xwindow-private.h"
00078 #include "magick/version.h"
00079 #if defined(__BEOS__)
00080 #include <OS.h>
00081 #endif
00082 #if defined(MAGICKCORE_X11_DELEGATE)
00083 #include <X11/Xproto.h>
00084 #include <X11/Xlocale.h>
00085 #if defined(MAGICK_HAVE_POLL)
00086 # include <sys/poll.h>
00087 #endif
00088 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
00089 #if defined(MAGICKCORE_HAVE_MACHINE_PARAM_H)
00090 # include <machine/param.h>
00091 #endif
00092 #include <sys/ipc.h>
00093 #include <sys/shm.h>
00094 #include <X11/extensions/XShm.h>
00095 #endif
00096 #if defined(MAGICKCORE_HAVE_SHAPE)
00097 #include <X11/extensions/shape.h>
00098 #endif
00099 
00100 /*
00101   X defines.
00102 */
00103 #define XBlueGamma(color) RoundToQuantum(blue_gamma == 1.0 ? (double) \
00104   (color) : ((pow(((double) QuantumScale*(color)),1.0/(double) blue_gamma)* \
00105   QuantumRange)))
00106 #define XGammaPixel(map,color)  (unsigned long) (map->base_pixel+ \
00107   ((ScaleQuantumToShort(XRedGamma((color)->red))*map->red_max/65535L)* \
00108     map->red_mult)+ \
00109   ((ScaleQuantumToShort(XGreenGamma((color)->green))*map->green_max/65535L)* \
00110     map->green_mult)+ \
00111   ((ScaleQuantumToShort(XBlueGamma((color)->blue))*map->blue_max/65535L)* \
00112     map->blue_mult))
00113 #define XGreenGamma(color) RoundToQuantum(green_gamma == 1.0 ? (double) \
00114   (color) : ((pow(((double) QuantumScale*(color)),1.0/(double) green_gamma)* \
00115   QuantumRange)))
00116 #define XRedGamma(color) RoundToQuantum(red_gamma == 1.0 ? (double) \
00117   (color) : ((pow(((double) QuantumScale*(color)),1.0/(double) red_gamma)* \
00118   QuantumRange)))
00119 #define XStandardPixel(map,color)  (unsigned long) (map->base_pixel+ \
00120   (((color)->red*map->red_max/65535L)*map->red_mult)+ \
00121   (((color)->green*map->green_max/65535L)*map->green_mult)+ \
00122   (((color)->blue*map->blue_max/65535L)*map->blue_mult))
00123 
00124 #define AccentuateModulate  ScaleCharToQuantum(80)
00125 #define HighlightModulate  ScaleCharToQuantum(125)
00126 #define ShadowModulate  ScaleCharToQuantum(135)
00127 #define DepthModulate  ScaleCharToQuantum(185)
00128 #define TroughModulate  ScaleCharToQuantum(110)
00129 
00130 #define XLIB_ILLEGAL_ACCESS  1
00131 #undef ForgetGravity
00132 #undef NorthWestGravity
00133 #undef NorthGravity
00134 #undef NorthEastGravity
00135 #undef WestGravity
00136 #undef CenterGravity
00137 #undef EastGravity
00138 #undef SouthWestGravity
00139 #undef SouthGravity
00140 #undef SouthEastGravity
00141 #undef StaticGravity
00142 
00143 #undef index
00144 #if defined(hpux9)
00145 #define XFD_SET  int
00146 #else
00147 #define XFD_SET  fd_set
00148 #endif
00149 
00150 /*
00151   Enumeration declarations.
00152 */
00153 typedef enum
00154 {
00155 #undef DoRed
00156   DoRed = 0x0001,
00157 #undef DoGreen
00158   DoGreen = 0x0002,
00159 #undef DoBlue
00160   DoBlue = 0x0004,
00161   DoMatte = 0x0008
00162 } XColorFlags;
00163 
00164 /*
00165   Typedef declarations.
00166 */
00167 typedef struct _DiversityPacket
00168 {
00169   Quantum
00170     red,
00171     green,
00172     blue;
00173 
00174   unsigned short
00175     index;
00176 
00177   unsigned long
00178     count;
00179 } DiversityPacket;
00180 
00181 /*
00182   Constant declaractions.
00183 */
00184 static MagickBooleanType
00185   xerror_alert = MagickFalse;
00186 
00187 /*
00188   Method prototypes.
00189 */
00190 static const char
00191   *XVisualClassName(const int);
00192 
00193 static MagickRealType
00194   blue_gamma = 1.0,
00195   green_gamma = 1.0,
00196   red_gamma = 1.0;
00197 
00198 static MagickBooleanType
00199   XMakePixmap(Display *,const XResourceInfo *,XWindowInfo *);
00200 
00201 static void
00202   XMakeImageLSBFirst(const XResourceInfo *,const XWindowInfo *,Image *,
00203     XImage *,XImage *),
00204   XMakeImageMSBFirst(const XResourceInfo *,const XWindowInfo *,Image *,
00205     XImage *,XImage *);
00206 
00207 static Window
00208   XSelectWindow(Display *,RectangleInfo *);
00209 
00210 /*
00211 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00212 %                                                                             %
00213 %                                                                             %
00214 %                                                                             %
00215 %   D e s t r o y X R e s o u r c e s                                         %
00216 %                                                                             %
00217 %                                                                             %
00218 %                                                                             %
00219 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00220 %
00221 %  DestroyXResources() destroys any X resources.
00222 %
00223 %  The format of the DestroyXResources method is:
00224 %
00225 %      void DestroyXResources()
00226 %
00227 %  A description of each parameter follows:
00228 %
00229 */
00230 MagickExport void DestroyXResources(void)
00231 {
00232   register int
00233     i;
00234 
00235   unsigned int
00236     number_windows;
00237 
00238   XWindowInfo
00239     *magick_windows[MaxXWindows];
00240 
00241   XWindows
00242     *windows;
00243 
00244   DestroyXWidget();
00245   windows=XSetWindows((XWindows *) ~0);
00246   if ((windows == (XWindows *) NULL) || (windows->display == (Display *) NULL))
00247     return;
00248   number_windows=0;
00249   magick_windows[number_windows++]=(&windows->context);
00250   magick_windows[number_windows++]=(&windows->group_leader);
00251   magick_windows[number_windows++]=(&windows->backdrop);
00252   magick_windows[number_windows++]=(&windows->icon);
00253   magick_windows[number_windows++]=(&windows->image);
00254   magick_windows[number_windows++]=(&windows->info);
00255   magick_windows[number_windows++]=(&windows->magnify);
00256   magick_windows[number_windows++]=(&windows->pan);
00257   magick_windows[number_windows++]=(&windows->command);
00258   magick_windows[number_windows++]=(&windows->widget);
00259   magick_windows[number_windows++]=(&windows->popup);
00260   magick_windows[number_windows++]=(&windows->context);
00261   for (i=0; i < (int) number_windows; i++)
00262   {
00263     if (magick_windows[i]->mapped != MagickFalse)
00264       {
00265         (void) XWithdrawWindow(windows->display,magick_windows[i]->id,
00266           magick_windows[i]->screen);
00267         magick_windows[i]->mapped=MagickFalse;
00268       }
00269     if (magick_windows[i]->name != (char *) NULL)
00270       magick_windows[i]->name=(char *)
00271         RelinquishMagickMemory(magick_windows[i]->name);
00272     if (magick_windows[i]->icon_name != (char *) NULL)
00273       magick_windows[i]->icon_name=(char *)
00274         RelinquishMagickMemory(magick_windows[i]->icon_name);
00275     if (magick_windows[i]->cursor != (Cursor) NULL)
00276       {
00277         (void) XFreeCursor(windows->display,magick_windows[i]->cursor);
00278         magick_windows[i]->cursor=(Cursor) NULL;
00279       }
00280     if (magick_windows[i]->busy_cursor != (Cursor) NULL)
00281       {
00282         (void) XFreeCursor(windows->display,magick_windows[i]->busy_cursor);
00283         magick_windows[i]->busy_cursor=(Cursor) NULL;
00284       }
00285     if (magick_windows[i]->highlight_stipple != (Pixmap) NULL)
00286       {
00287         (void) XFreePixmap(windows->display,
00288           magick_windows[i]->highlight_stipple);
00289         magick_windows[i]->highlight_stipple=(Pixmap) NULL;
00290       }
00291     if (magick_windows[i]->shadow_stipple != (Pixmap) NULL)
00292       {
00293         (void) XFreePixmap(windows->display,magick_windows[i]->shadow_stipple);
00294         magick_windows[i]->shadow_stipple=(Pixmap) NULL;
00295       }
00296     if (magick_windows[i]->ximage != (XImage *) NULL)
00297       {
00298         XDestroyImage(magick_windows[i]->ximage);
00299         magick_windows[i]->ximage=(XImage *) NULL;
00300       }
00301     if (magick_windows[i]->pixmap != (Pixmap) NULL)
00302       {
00303         (void) XFreePixmap(windows->display,magick_windows[i]->pixmap);
00304         magick_windows[i]->pixmap=(Pixmap) NULL;
00305       }
00306     if (magick_windows[i]->id != (Window) NULL)
00307       {
00308         (void) XDestroyWindow(windows->display,magick_windows[i]->id);
00309         magick_windows[i]->id=(Window) NULL;
00310       }
00311     if (magick_windows[i]->destroy != MagickFalse)
00312       {
00313         if (magick_windows[i]->image != (Image *) NULL)
00314           {
00315             magick_windows[i]->image=DestroyImage(magick_windows[i]->image);
00316             magick_windows[i]->image=NewImageList();
00317           }
00318         if (magick_windows[i]->matte_pixmap != (Pixmap) NULL)
00319           {
00320             (void) XFreePixmap(windows->display,
00321               magick_windows[i]->matte_pixmap);
00322             magick_windows[i]->matte_pixmap=(Pixmap) NULL;
00323           }
00324       }
00325     if (magick_windows[i]->segment_info != (void *) NULL)
00326       {
00327 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
00328         XShmSegmentInfo
00329           *segment_info;
00330 
00331         segment_info=(XShmSegmentInfo *) magick_windows[i]->segment_info;
00332         if (segment_info != (XShmSegmentInfo *) NULL)
00333           if (segment_info[0].shmid >= 0)
00334             {
00335               if (segment_info[0].shmaddr != NULL)
00336                 (void) shmdt(segment_info[0].shmaddr);
00337               (void) shmctl(segment_info[0].shmid,IPC_RMID,0);
00338               segment_info[0].shmaddr=NULL;
00339               segment_info[0].shmid=(-1);
00340             }
00341 #endif
00342         magick_windows[i]->segment_info=(void *)
00343           RelinquishMagickMemory(magick_windows[i]->segment_info);
00344       }
00345   }
00346   windows->icon_resources=(XResourceInfo *)
00347     RelinquishMagickMemory(windows->icon_resources);
00348   if (windows->icon_pixel != (XPixelInfo *) NULL)
00349     {
00350       if (windows->icon_pixel->pixels != (unsigned long *) NULL)
00351         windows->icon_pixel->pixels=(unsigned long *)
00352           RelinquishMagickMemory(windows->icon_pixel->pixels);
00353       if (windows->icon_pixel->annotate_context != (GC) NULL)
00354         XFreeGC(windows->display,windows->icon_pixel->annotate_context);
00355       windows->icon_pixel=(XPixelInfo *)
00356         RelinquishMagickMemory(windows->icon_pixel);
00357     }
00358   if (windows->pixel_info != (XPixelInfo *) NULL)
00359     {
00360       if (windows->pixel_info->pixels != (unsigned long *) NULL)
00361         windows->pixel_info->pixels=(unsigned long *)
00362           RelinquishMagickMemory(windows->pixel_info->pixels);
00363       if (windows->pixel_info->annotate_context != (GC) NULL)
00364         XFreeGC(windows->display,windows->pixel_info->annotate_context);
00365       if (windows->pixel_info->widget_context != (GC) NULL)
00366         XFreeGC(windows->display,windows->pixel_info->widget_context);
00367       if (windows->pixel_info->highlight_context != (GC) NULL)
00368         XFreeGC(windows->display,windows->pixel_info->highlight_context);
00369       windows->pixel_info=(XPixelInfo *)
00370         RelinquishMagickMemory(windows->pixel_info);
00371     }
00372   if (windows->font_info != (XFontStruct *) NULL)
00373     {
00374       XFreeFont(windows->display,windows->font_info);
00375       windows->font_info=(XFontStruct *) NULL;
00376     }
00377   if (windows->class_hints != (XClassHint *) NULL)
00378     {
00379       XFree(windows->class_hints);
00380       windows->class_hints=(XClassHint *) NULL;
00381     }
00382   if (windows->manager_hints != (XWMHints *) NULL)
00383     {
00384       XFree(windows->manager_hints);
00385       windows->manager_hints=(XWMHints *) NULL;
00386     }
00387   if (windows->map_info != (XStandardColormap *) NULL)
00388     {
00389       XFree(windows->map_info);
00390       windows->map_info=(XStandardColormap *) NULL;
00391     }
00392   if (windows->icon_map != (XStandardColormap *) NULL)
00393     {
00394       XFree(windows->icon_map);
00395       windows->icon_map=(XStandardColormap *) NULL;
00396     }
00397   if (windows->visual_info != (XVisualInfo *) NULL)
00398     {
00399       XFree(windows->visual_info);
00400       windows->visual_info=(XVisualInfo *) NULL;
00401     }
00402   if (windows->icon_visual != (XVisualInfo *) NULL)
00403     {
00404       XFree(windows->icon_visual);
00405       windows->icon_visual=(XVisualInfo *) NULL;
00406     }
00407   (void) XSetWindows((XWindows *) NULL);
00408 }
00409 
00410 /*
00411 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00412 %                                                                             %
00413 %                                                                             %
00414 %                                                                             %
00415 %   X A n n o t a t e I m a g e                                               %
00416 %                                                                             %
00417 %                                                                             %
00418 %                                                                             %
00419 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00420 %
00421 %  XAnnotateImage() annotates the image with text.
00422 %
00423 %  The format of the XAnnotateImage method is:
00424 %
00425 %      MagickBooleanType XAnnotateImage(Display *display,
00426 %        const XPixelInfo *pixel,XAnnotateInfo *annotate_info,Image *image)
00427 %
00428 %  A description of each parameter follows:
00429 %
00430 %    o display: Specifies a connection to an X server;  returned from
00431 %      XOpenDisplay.
00432 %
00433 %    o pixel: Specifies a pointer to a XPixelInfo structure.
00434 %
00435 %    o annotate_info: Specifies a pointer to a XAnnotateInfo structure.
00436 %
00437 %    o image: the image.
00438 %
00439 */
00440 MagickExport MagickBooleanType XAnnotateImage(Display *display,
00441   const XPixelInfo *pixel,XAnnotateInfo *annotate_info,Image *image)
00442 {
00443   GC
00444     annotate_context;
00445 
00446   ExceptionInfo
00447     *exception;
00448 
00449   Image
00450     *annotate_image;
00451 
00452   int
00453     x,
00454     y;
00455 
00456   MagickBooleanType
00457     matte;
00458 
00459   Pixmap
00460     annotate_pixmap;
00461 
00462   register PixelPacket
00463     *q;
00464 
00465   unsigned int
00466     depth,
00467     height,
00468     width;
00469 
00470   Window
00471     root_window;
00472 
00473   XGCValues
00474     context_values;
00475 
00476   XImage
00477     *annotate_ximage;
00478 
00479   /*
00480     Initialize annotated image.
00481   */
00482   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00483   assert(display != (Display *) NULL);
00484   assert(pixel != (XPixelInfo *) NULL);
00485   assert(annotate_info != (XAnnotateInfo *) NULL);
00486   assert(image != (Image *) NULL);
00487   /*
00488     Initialize annotated pixmap.
00489   */
00490   root_window=XRootWindow(display,XDefaultScreen(display));
00491   depth=(unsigned int) XDefaultDepth(display,XDefaultScreen(display));
00492   annotate_pixmap=XCreatePixmap(display,root_window,annotate_info->width,
00493     annotate_info->height,depth);
00494   if (annotate_pixmap == (Pixmap) NULL)
00495     return(MagickFalse);
00496   /*
00497     Initialize graphics info.
00498   */
00499   context_values.background=0;
00500   context_values.foreground=(unsigned long) (~0);
00501   context_values.font=annotate_info->font_info->fid;
00502   annotate_context=XCreateGC(display,root_window,(unsigned long)
00503     GCBackground | GCFont | GCForeground,&context_values);
00504   if (annotate_context == (GC) NULL)
00505     return(MagickFalse);
00506   /*
00507     Draw text to pixmap.
00508   */
00509   (void) XDrawImageString(display,annotate_pixmap,annotate_context,0,
00510     (int) annotate_info->font_info->ascent,annotate_info->text,
00511     (int) strlen(annotate_info->text));
00512   (void) XFreeGC(display,annotate_context);
00513   /*
00514     Initialize annotated X image.
00515   */
00516   annotate_ximage=XGetImage(display,annotate_pixmap,0,0,annotate_info->width,
00517     annotate_info->height,AllPlanes,ZPixmap);
00518   if (annotate_ximage == (XImage *) NULL)
00519     return(MagickFalse);
00520   (void) XFreePixmap(display,annotate_pixmap);
00521   /*
00522     Initialize annotated image.
00523   */
00524   annotate_image=AcquireImage((ImageInfo *) NULL);
00525   if (annotate_image == (Image *) NULL)
00526     return(MagickFalse);
00527   annotate_image->columns=annotate_info->width;
00528   annotate_image->rows=annotate_info->height;
00529   /*
00530     Transfer annotated X image to image.
00531   */
00532   width=(unsigned int) image->columns;
00533   height=(unsigned int) image->rows;
00534   x=0;
00535   y=0;
00536   (void) XParseGeometry(annotate_info->geometry,&x,&y,&width,&height);
00537   (void) GetOneVirtualPixel(image,x,y,&annotate_image->background_color,
00538     &image->exception);
00539   if (annotate_info->stencil == ForegroundStencil)
00540     annotate_image->matte=MagickTrue;
00541   exception=(&image->exception);
00542   for (y=0; y < (int) annotate_image->rows; y++)
00543   {
00544     q=GetAuthenticPixels(annotate_image,0,y,annotate_image->columns,1,exception);
00545     if (q == (PixelPacket *) NULL)
00546       break;
00547     for (x=0; x < (int) annotate_image->columns; x++)
00548     {
00549       q->opacity=OpaqueOpacity;
00550       if (XGetPixel(annotate_ximage,x,y) == 0)
00551         {
00552           /*
00553             Set this pixel to the background color.
00554           */
00555           q->red=ScaleShortToQuantum(pixel->box_color.red);
00556           q->green=ScaleShortToQuantum(pixel->box_color.green);
00557           q->blue=ScaleShortToQuantum(pixel->box_color.blue);
00558           if ((annotate_info->stencil == ForegroundStencil) ||
00559               (annotate_info->stencil == OpaqueStencil))
00560             q->opacity=(Quantum) TransparentOpacity;
00561         }
00562       else
00563         {
00564           /*
00565             Set this pixel to the pen color.
00566           */
00567           q->red=ScaleShortToQuantum(pixel->pen_color.red);
00568           q->green=ScaleShortToQuantum(pixel->pen_color.green);
00569           q->blue=ScaleShortToQuantum(pixel->pen_color.blue);
00570           if (annotate_info->stencil == BackgroundStencil)
00571             q->opacity=(Quantum) TransparentOpacity;
00572         }
00573       q++;
00574     }
00575     if (SyncAuthenticPixels(annotate_image,exception) == MagickFalse)
00576       break;
00577   }
00578   XDestroyImage(annotate_ximage);
00579   /*
00580     Determine annotate geometry.
00581   */
00582   (void) XParseGeometry(annotate_info->geometry,&x,&y,&width,&height);
00583   if ((width != (unsigned int) annotate_image->columns) ||
00584       (height != (unsigned int) annotate_image->rows))
00585     {
00586       char
00587         image_geometry[MaxTextExtent];
00588 
00589       /*
00590         Scale image.
00591       */
00592       (void) FormatMagickString(image_geometry,MaxTextExtent,"%ux%u",
00593         width,height);
00594       (void) TransformImage(&annotate_image,(char *) NULL,image_geometry);
00595     }
00596   if (annotate_info->degrees != 0.0)
00597     {
00598       Image
00599         *rotate_image;
00600 
00601       int
00602         rotations;
00603 
00604       MagickRealType
00605         normalized_degrees;
00606 
00607       /*
00608         Rotate image.
00609       */
00610       rotate_image=
00611         RotateImage(annotate_image,annotate_info->degrees,&image->exception);
00612       if (rotate_image == (Image *) NULL)
00613         return(MagickFalse);
00614       annotate_image=DestroyImage(annotate_image);
00615       annotate_image=rotate_image;
00616       /*
00617         Annotation is relative to the degree of rotation.
00618       */
00619       normalized_degrees=annotate_info->degrees;
00620       while (normalized_degrees < -45.0)
00621         normalized_degrees+=360.0;
00622       for (rotations=0; normalized_degrees > 45.0; rotations++)
00623         normalized_degrees-=90.0;
00624       switch (rotations % 4)
00625       {
00626         default:
00627         case 0:
00628           break;
00629         case 1:
00630         {
00631           /*
00632             Rotate 90 degrees.
00633           */
00634           x-=(int) annotate_image->columns/2;
00635           y+=(int) annotate_image->columns/2;
00636           break;
00637         }
00638         case 2:
00639         {
00640           /*
00641             Rotate 180 degrees.
00642           */
00643           x=x-(int) annotate_image->columns;
00644           break;
00645         }
00646         case 3:
00647         {
00648           /*
00649             Rotate 270 degrees.
00650           */
00651           x=x-(int) annotate_image->columns/2;
00652           y=y-(int) (annotate_image->rows-(annotate_image->columns/2));
00653           break;
00654         }
00655       }
00656     }
00657   /*
00658     Composite text onto the image.
00659   */
00660   (void) XParseGeometry(annotate_info->geometry,&x,&y,&width,&height);
00661   matte=image->matte;
00662   (void) CompositeImage(image,annotate_image->matte != MagickFalse ?
00663     OverCompositeOp : CopyCompositeOp,annotate_image,x,y);
00664   image->matte=matte;
00665   annotate_image=DestroyImage(annotate_image);
00666   return(MagickTrue);
00667 }
00668 
00669 /*
00670 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00671 %                                                                             %
00672 %                                                                             %
00673 %                                                                             %
00674 %   X B e s t F o n t                                                         %
00675 %                                                                             %
00676 %                                                                             %
00677 %                                                                             %
00678 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00679 %
00680 %  XBestFont() returns the "best" font.  "Best" is defined as a font specified
00681 %  in the X resource database or a font such that the text width displayed
00682 %  with the font does not exceed the specified maximum width.
00683 %
00684 %  The format of the XBestFont method is:
00685 %
00686 %      XFontStruct *XBestFont(Display *display,
00687 %        const XResourceInfo *resource_info,const MagickBooleanType text_font)
00688 %
00689 %  A description of each parameter follows:
00690 %
00691 %    o font: XBestFont returns a pointer to a XFontStruct structure.
00692 %
00693 %    o display: Specifies a connection to an X server;  returned from
00694 %      XOpenDisplay.
00695 %
00696 %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
00697 %
00698 %    o text_font:  True is font should be mono-spaced (typewriter style).
00699 %
00700 %
00701 */
00702 
00703 static char **FontToList(char *font)
00704 {
00705   char
00706     **fontlist;
00707 
00708   register char
00709     *p,
00710     *q;
00711 
00712   register int
00713     i;
00714 
00715   unsigned int
00716     fonts;
00717 
00718   if (font == (char *) NULL)
00719     return((char **) NULL);
00720   /*
00721     Convert string to an ASCII list.
00722   */
00723   fonts=1U;
00724   for (p=font; *p != '\0'; p++)
00725     if ((*p == ':') || (*p == ';') || (*p == ','))
00726       fonts++;
00727   fontlist=(char **) AcquireQuantumMemory((size_t) fonts+1UL,sizeof(*fontlist));
00728   if (fontlist == (char **) NULL)
00729     {
00730       ThrowXWindowFatalException(ResourceLimitError,"MemoryAllocationFailed",
00731         font);
00732       return((char **) NULL);
00733     }
00734   p=font;
00735   for (i=0; i < (int) fonts; i++)
00736   {
00737     for (q=p; *q != '\0'; q++)
00738       if ((*q == ':') || (*q == ';') || (*q == ','))
00739         break;
00740     fontlist[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+1UL,
00741       sizeof(*fontlist[i]));
00742     if (fontlist[i] == (char *) NULL)
00743       {
00744         ThrowXWindowFatalException(ResourceLimitError,"MemoryAllocationFailed",
00745           font);
00746         return((char **) NULL);
00747       }
00748     (void) CopyMagickString(fontlist[i],p,(size_t) (q-p+1));
00749     p=q+1;
00750   }
00751   fontlist[i]=(char *) NULL;
00752   return(fontlist);
00753 }
00754 
00755 MagickExport XFontStruct *XBestFont(Display *display,
00756   const XResourceInfo *resource_info,const MagickBooleanType text_font)
00757 {
00758   static const char
00759     *Fonts[]=
00760     {
00761       "-*-helvetica-medium-r-normal--12-*-*-*-*-*-iso8859-1",
00762       "-*-arial-medium-r-normal--12-*-*-*-*-*-iso8859-1",
00763       "-*-helvetica-medium-r-normal--12-*-*-*-*-*-iso8859-15",
00764       "-*-arial-medium-r-normal--12-*-*-*-*-*-iso8859-15",
00765       "-*-helvetica-medium-r-normal--12-*-*-*-*-*-*-*",
00766       "-*-arial-medium-r-normal--12-*-*-*-*-*-*-*",
00767       "variable",
00768       "fixed",
00769       (char *) NULL
00770     },
00771     *TextFonts[]=
00772     {
00773       "-*-courier-medium-r-normal-*-12-*-*-*-*-*-iso8859-1",
00774       "-*-courier-medium-r-normal-*-12-*-*-*-*-*-iso8859-15",
00775       "-*-fixed-medium-r-normal-*-12-*-*-*-*-*-*-*",
00776       "fixed",
00777       (char *) NULL
00778     };
00779 
00780   char
00781     *font_name;
00782 
00783   register const char
00784     **p;
00785 
00786   XFontStruct
00787     *font_info;
00788 
00789   font_info=(XFontStruct *) NULL;
00790   font_name=resource_info->font;
00791   if (text_font != MagickFalse)
00792     font_name=resource_info->text_font;
00793   if ((font_name != (char *) NULL) && (*font_name != '\0'))
00794     {
00795       char
00796         **fontlist;
00797 
00798       register int
00799         i;
00800 
00801       /*
00802         Load preferred font specified in the X resource database.
00803       */
00804       fontlist=FontToList(font_name);
00805       if (fontlist != (char **) NULL)
00806         {
00807           for (i=0; fontlist[i] != (char *) NULL; i++)
00808           {
00809             if (font_info == (XFontStruct *) NULL)
00810               font_info=XLoadQueryFont(display,fontlist[i]);
00811             fontlist[i]=DestroyString(fontlist[i]);
00812           }
00813           fontlist=(char **) RelinquishMagickMemory(fontlist);
00814         }
00815       if (font_info == (XFontStruct *) NULL)
00816         ThrowXWindowFatalException(XServerError,"UnableToLoadFont",font_name);
00817     }
00818   /*
00819     Load fonts from list of fonts until one is found.
00820   */
00821   p=Fonts;
00822   if (text_font != MagickFalse)
00823     p=TextFonts;
00824   if (XDisplayHeight(display,XDefaultScreen(display)) >= 748)
00825     p++;
00826   while (*p != (char *) NULL)
00827   {
00828     if (font_info != (XFontStruct *) NULL)
00829       break;
00830     font_info=XLoadQueryFont(display,(char *) *p);
00831     p++;
00832   }
00833   return(font_info);
00834 }
00835 
00836 /*
00837 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00838 %                                                                             %
00839 %                                                                             %
00840 %                                                                             %
00841 %   X B e s t I c o n S i z e                                                 %
00842 %                                                                             %
00843 %                                                                             %
00844 %                                                                             %
00845 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00846 %
00847 %  XBestIconSize() returns the "best" icon size.  "Best" is defined as an icon
00848 %  size that maintains the aspect ratio of the image.  If the window manager
00849 %  has preferred icon sizes, one of the preferred sizes is used.
00850 %
00851 %  The format of the XBestIconSize method is:
00852 %
00853 %      void XBestIconSize(Display *display,XWindowInfo *window,Image *image)
00854 %
00855 %  A description of each parameter follows:
00856 %
00857 %    o display: Specifies a connection to an X server;  returned from
00858 %      XOpenDisplay.
00859 %
00860 %    o image: the image.
00861 %
00862 */
00863 MagickExport void XBestIconSize(Display *display,XWindowInfo *window,
00864   Image *image)
00865 {
00866   int
00867     i,
00868     number_sizes;
00869 
00870   MagickRealType
00871     scale_factor;
00872 
00873   unsigned int
00874     height,
00875     icon_height,
00876     icon_width,
00877     width;
00878 
00879   Window
00880     root_window;
00881 
00882   XIconSize
00883     *icon_size,
00884     *size_list;
00885 
00886   /*
00887     Determine if the window manager has specified preferred icon sizes.
00888   */
00889   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00890   assert(display != (Display *) NULL);
00891   assert(window != (XWindowInfo *) NULL);
00892   assert(image != (Image *) NULL);
00893   window->width=MaxIconSize;
00894   window->height=MaxIconSize;
00895   icon_size=(XIconSize *) NULL;
00896   number_sizes=0;
00897   root_window=XRootWindow(display,window->screen);
00898   if (XGetIconSizes(display,root_window,&size_list,&number_sizes) != 0)
00899     if ((number_sizes > 0) && (size_list != (XIconSize *) NULL))
00900       icon_size=size_list;
00901   if (icon_size == (XIconSize *) NULL)
00902     {
00903       /*
00904         Window manager does not restrict icon size.
00905       */
00906       icon_size=XAllocIconSize();
00907       if (icon_size == (XIconSize *) NULL)
00908         {
00909           ThrowXWindowFatalException(ResourceLimitError,
00910             "MemoryAllocationFailed",image->filename);
00911           return;
00912         }
00913       icon_size->min_width=1;
00914       icon_size->max_width=MaxIconSize;
00915       icon_size->min_height=1;
00916       icon_size->max_height=MaxIconSize;
00917       icon_size->width_inc=1;
00918       icon_size->height_inc=1;
00919     }
00920   /*
00921     Determine aspect ratio of image.
00922   */
00923   width=(unsigned int) image->columns;
00924   height=(unsigned int) image->rows;
00925   i=0;
00926   if (window->crop_geometry)
00927     (void) XParseGeometry(window->crop_geometry,&i,&i,&width,&height);
00928   /*
00929     Look for an icon size that maintains the aspect ratio of image.
00930   */
00931   scale_factor=(MagickRealType) icon_size->max_width/width;
00932   if (scale_factor > ((MagickRealType) icon_size->max_height/height))
00933     scale_factor=(MagickRealType) icon_size->max_height/height;
00934   icon_width=(unsigned int) icon_size->min_width;
00935   while ((int) icon_width < icon_size->max_width)
00936   {
00937     if (icon_width >= (unsigned int) (scale_factor*width+0.5))
00938       break;
00939     icon_width+=icon_size->width_inc;
00940   }
00941   icon_height=(unsigned int) icon_size->min_height;
00942   while ((int) icon_height < icon_size->max_height)
00943   {
00944     if (icon_height >= (unsigned int) (scale_factor*height+0.5))
00945       break;
00946     icon_height+=icon_size->height_inc;
00947   }
00948   (void) XFree((void *) icon_size);
00949   window->width=icon_width;
00950   window->height=icon_height;
00951 }
00952 
00953 /*
00954 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00955 %                                                                             %
00956 %                                                                             %
00957 %                                                                             %
00958 %   X B e s t P i x e l                                                       %
00959 %                                                                             %
00960 %                                                                             %
00961 %                                                                             %
00962 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00963 %
00964 %  XBestPixel() returns a pixel from an array of pixels that is closest to the
00965 %  requested color.  If the color array is NULL, the colors are obtained from
00966 %  the X server.
00967 %
00968 %  The format of the XBestPixel method is:
00969 %
00970 %      void XBestPixel(Display *display,const Colormap colormap,XColor *colors,
00971 %        unsigned int number_colors,XColor *color)
00972 %
00973 %  A description of each parameter follows:
00974 %
00975 %    o pixel: XBestPixel returns the pixel value closest to the requested
00976 %      color.
00977 %
00978 %    o display: Specifies a connection to an X server;  returned from
00979 %      XOpenDisplay.
00980 %
00981 %    o colormap: Specifies the ID of the X server colormap.
00982 %
00983 %    o colors: Specifies an array of XColor structures.
00984 %
00985 %    o number_colors: Specifies the number of XColor structures in the
00986 %      color definition array.
00987 %
00988 %    o color: Specifies the desired RGB value to find in the colors array.
00989 %
00990 */
00991 MagickExport void XBestPixel(Display *display,const Colormap colormap,
00992   XColor *colors,unsigned int number_colors,XColor *color)
00993 {
00994   MagickBooleanType
00995     query_server;
00996 
00997   MagickPixelPacket
00998     pixel;
00999 
01000   MagickRealType
01001     min_distance;
01002 
01003   register MagickRealType
01004     distance;
01005 
01006   register int
01007     i,
01008     j;
01009 
01010   Status
01011     status;
01012 
01013   /*
01014     Find closest representation for the requested RGB color.
01015   */
01016   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
01017   assert(display != (Display *) NULL);
01018   assert(color != (XColor *) NULL);
01019   status=XAllocColor(display,colormap,color);
01020   if (status != False)
01021     return;
01022   query_server=colors == (XColor *) NULL ? MagickTrue : MagickFalse;
01023   if (query_server != MagickFalse)
01024     {
01025       /*
01026         Read X server colormap.
01027       */
01028       colors=(XColor *) AcquireQuantumMemory(number_colors,sizeof(*colors));
01029       if (colors == (XColor *) NULL)
01030         {
01031           ThrowXWindowFatalException(ResourceLimitError,
01032             "MemoryAllocationFailed","...");
01033           return;
01034         }
01035       for (i=0; i < (int) number_colors; i++)
01036         colors[i].pixel=(unsigned long) i;
01037       if (number_colors > 256)
01038         number_colors=256;
01039       (void) XQueryColors(display,colormap,colors,(int) number_colors);
01040     }
01041   min_distance=3.0*((MagickRealType) QuantumRange+1.0)*((MagickRealType)
01042     QuantumRange+1.0);
01043   j=0;
01044   for (i=0; i < (int) number_colors; i++)
01045   {
01046     pixel.red=colors[i].red-(MagickRealType) color->red;
01047     distance=pixel.red*pixel.red;
01048     if (distance > min_distance)
01049       continue;
01050     pixel.green=colors[i].green-(MagickRealType) color->green;
01051     distance+=pixel.green*pixel.green;
01052     if (distance > min_distance)
01053       continue;
01054     pixel.blue=colors[i].blue-(MagickRealType) color->blue;
01055     distance+=pixel.blue*pixel.blue;
01056     if (distance > min_distance)
01057       continue;
01058     min_distance=distance;
01059     color->pixel=colors[i].pixel;
01060     j=i;
01061   }
01062   (void) XAllocColor(display,colormap,&colors[j]);
01063   if (query_server != MagickFalse)
01064     colors=(XColor *) RelinquishMagickMemory(colors);
01065 }
01066 
01067 /*
01068 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01069 %                                                                             %
01070 %                                                                             %
01071 %                                                                             %
01072 %   X B e s t V i s u a l I n f o                                             %
01073 %                                                                             %
01074 %                                                                             %
01075 %                                                                             %
01076 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01077 %
01078 %  XBestVisualInfo() returns visual information for a visual that is the "best"
01079 %  the server supports.  "Best" is defined as:
01080 %
01081 %    1. Restrict the visual list to those supported by the default screen.
01082 %
01083 %    2. If a visual type is specified, restrict the visual list to those of
01084 %       that type.
01085 %
01086 %    3. If a map type is specified, choose the visual that matches the id
01087 %       specified by the Standard Colormap.
01088 %
01089 %    4  From the list of visuals, choose one that can display the most
01090 %       simultaneous colors.  If more than one visual can display the same
01091 %       number of simultaneous colors, one is chosen based on a rank.
01092 %
01093 %  The format of the XBestVisualInfo method is:
01094 %
01095 %      XVisualInfo *XBestVisualInfo(Display *display,
01096 %        XStandardColormap *map_info,XResourceInfo *resource_info)
01097 %
01098 %  A description of each parameter follows:
01099 %
01100 %    o visual_info: XBestVisualInfo returns a pointer to a X11 XVisualInfo
01101 %      structure.
01102 %
01103 %    o display: Specifies a connection to an X server;  returned from
01104 %      XOpenDisplay.
01105 %
01106 %    o map_info: If map_type is specified, this structure is initialized
01107 %      with info from the Standard Colormap.
01108 %
01109 %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
01110 %
01111 */
01112 
01113 static inline int MagickMax(const int x,const int y)
01114 {
01115   if (x > y)
01116     return(x);
01117   return(y);
01118 }
01119 
01120 static inline unsigned long MagickMin(const unsigned int x,
01121   const unsigned int y)
01122 {
01123   if (x < y)
01124     return(x);
01125   return(y);
01126 }
01127 
01128 MagickExport XVisualInfo *XBestVisualInfo(Display *display,
01129   XStandardColormap *map_info,XResourceInfo *resource_info)
01130 {
01131 #define MaxStandardColormaps  7
01132 #define XVisualColormapSize(visual_info) MagickMin((unsigned int) (\
01133   (visual_info->klass == TrueColor) || (visual_info->klass == DirectColor) ? \
01134    visual_info->red_mask | visual_info->green_mask | visual_info->blue_mask : \
01135    (unsigned int) visual_info->colormap_size),1U << visual_info->depth)
01136 
01137   char
01138     *map_type,
01139     *visual_type;
01140 
01141   long
01142     visual_mask;
01143 
01144   register int
01145     i;
01146 
01147   static int
01148     number_visuals;
01149 
01150   static XVisualInfo
01151     visual_template;
01152 
01153   XVisualInfo
01154     *visual_info,
01155     *visual_list;
01156 
01157   /*
01158     Restrict visual search by screen number.
01159   */
01160   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
01161   assert(display != (Display *) NULL);
01162   assert(map_info != (XStandardColormap *) NULL);
01163   assert(resource_info != (XResourceInfo *) NULL);
01164   map_type=resource_info->map_type;
01165   visual_type=resource_info->visual_type;
01166   visual_mask=VisualScreenMask;
01167   visual_template.screen=XDefaultScreen(display);
01168   visual_template.depth=XDefaultDepth(display,XDefaultScreen(display));
01169   if ((resource_info->immutable != MagickFalse) && (resource_info->colors != 0))
01170     if (resource_info->colors <= (1UL << (unsigned long) visual_template.depth))
01171       visual_mask|=VisualDepthMask;
01172   if (visual_type != (char *) NULL)
01173     {
01174       /*
01175         Restrict visual search by class or visual id.
01176       */
01177       if (LocaleCompare("staticgray",visual_type) == 0)
01178         {
01179           visual_mask|=VisualClassMask;
01180           visual_template.klass=StaticGray;
01181         }
01182       else
01183         if (LocaleCompare("grayscale",visual_type) == 0)
01184           {
01185             visual_mask|=VisualClassMask;
01186             visual_template.klass=GrayScale;
01187           }
01188         else
01189           if (LocaleCompare("staticcolor",visual_type) == 0)
01190             {
01191               visual_mask|=VisualClassMask;
01192               visual_template.klass=StaticColor;
01193             }
01194           else
01195             if (LocaleCompare("pseudocolor",visual_type) == 0)
01196               {
01197                 visual_mask|=VisualClassMask;
01198                 visual_template.klass=PseudoColor;
01199               }
01200             else
01201               if (LocaleCompare("truecolor",visual_type) == 0)
01202                 {
01203                   visual_mask|=VisualClassMask;
01204                   visual_template.klass=TrueColor;
01205                 }
01206               else
01207                 if (LocaleCompare("directcolor",visual_type) == 0)
01208                   {
01209                     visual_mask|=VisualClassMask;
01210                     visual_template.klass=DirectColor;
01211                   }
01212                 else
01213                   if (LocaleCompare("default",visual_type) == 0)
01214                     {
01215                       visual_mask|=VisualIDMask;
01216                       visual_template.visualid=XVisualIDFromVisual(
01217                         XDefaultVisual(display,XDefaultScreen(display)));
01218                     }
01219                   else
01220                     if (isdigit((int) ((unsigned char) *visual_type)) != 0)
01221                       {
01222                         visual_mask|=VisualIDMask;
01223                         visual_template.visualid=
01224                           strtol(visual_type,(char **) NULL,0);
01225                       }
01226                     else
01227                       ThrowXWindowFatalException(XServerError,
01228                         "UnrecognizedVisualSpecifier",visual_type);
01229     }
01230   /*
01231     Get all visuals that meet our criteria so far.
01232   */
01233   number_visuals=0;
01234   visual_list=XGetVisualInfo(display,visual_mask,&visual_template,
01235     &number_visuals);
01236   visual_mask=VisualScreenMask | VisualIDMask;
01237   if ((number_visuals == 0) || (visual_list == (XVisualInfo *) NULL))
01238     {
01239       /*
01240         Failed to get visual;  try using the default visual.
01241       */
01242       ThrowXWindowFatalException(XServerWarning,"UnableToGetVisual",
01243         visual_type);
01244       visual_template.visualid=XVisualIDFromVisual(XDefaultVisual(display,
01245         XDefaultScreen(display)));
01246       visual_list=XGetVisualInfo(display,visual_mask,&visual_template,
01247         &number_visuals);
01248       if ((number_visuals == 0) || (visual_list == (XVisualInfo *) NULL))
01249         return((XVisualInfo *) NULL);
01250       ThrowXWindowFatalException(XServerWarning,"UsingDefaultVisual",
01251         XVisualClassName(visual_list->klass));
01252     }
01253   resource_info->color_recovery=MagickFalse;
01254   if ((map_info != (XStandardColormap *) NULL) && (map_type != (char *) NULL))
01255     {
01256       Atom
01257         map_property;
01258 
01259       char
01260         map_name[MaxTextExtent];
01261 
01262       int
01263         j,
01264         number_maps;
01265 
01266       Status
01267         status;
01268 
01269       Window
01270         root_window;
01271 
01272       XStandardColormap
01273         *map_list;
01274 
01275       /*
01276         Choose a visual associated with a standard colormap.
01277       */
01278       root_window=XRootWindow(display,XDefaultScreen(display));
01279       status=False;
01280       if (LocaleCompare(map_type,"list") != 0)
01281         {
01282           /*
01283             User specified Standard Colormap.
01284           */
01285           (void) FormatMagickString((char *) map_name,MaxTextExtent,
01286             "RGB_%s_MAP",map_type);
01287           LocaleUpper(map_name);
01288           map_property=XInternAtom(display,(char *) map_name,MagickTrue);
01289           if (map_property != (Atom) NULL)
01290             status=XGetRGBColormaps(display,root_window,&map_list,&number_maps,
01291               map_property);
01292         }
01293       else
01294         {
01295           static const char
01296             *colormap[MaxStandardColormaps]=
01297             {
01298               "_HP_RGB_SMOOTH_MAP_LIST",
01299               "RGB_BEST_MAP",
01300               "RGB_DEFAULT_MAP",
01301               "RGB_GRAY_MAP",
01302               "RGB_RED_MAP",
01303               "RGB_GREEN_MAP",
01304               "RGB_BLUE_MAP",
01305             };
01306 
01307           /*
01308             Choose a standard colormap from a list.
01309           */
01310           for (i=0; i < MaxStandardColormaps; i++)
01311           {
01312             map_property=XInternAtom(display,(char *) colormap[i],MagickTrue);
01313             if (map_property == (Atom) NULL)
01314               continue;
01315             status=XGetRGBColormaps(display,root_window,&map_list,&number_maps,
01316               map_property);
01317             if (status != False)
01318               break;
01319           }
01320           resource_info->color_recovery=i == 0 ? MagickTrue : MagickFalse;
01321         }
01322       if (status == False)
01323         {
01324           ThrowXWindowFatalException(XServerError,"UnableToGetStandardColormap",
01325             map_type);
01326           return((XVisualInfo *) NULL);
01327         }
01328       /*
01329         Search all Standard Colormaps and visuals for ids that match.
01330       */
01331       *map_info=map_list[0];
01332 #if !defined(PRE_R4_ICCCM)
01333