2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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 %
13 % MagickCore X11 Utility Methods %
20 % Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
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. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42 #include "MagickCore/studio.h"
43 #include "MagickCore/animate.h"
44 #include "MagickCore/artifact.h"
45 #include "MagickCore/blob.h"
46 #include "MagickCore/cache.h"
47 #include "MagickCore/client.h"
48 #include "MagickCore/color.h"
49 #include "MagickCore/color-private.h"
50 #include "MagickCore/colormap.h"
51 #include "MagickCore/composite.h"
52 #include "MagickCore/display.h"
53 #include "MagickCore/exception.h"
54 #include "MagickCore/exception-private.h"
55 #include "MagickCore/geometry.h"
56 #include "MagickCore/identify.h"
57 #include "MagickCore/image.h"
58 #include "MagickCore/image-private.h"
59 #include "MagickCore/list.h"
60 #include "MagickCore/locale_.h"
61 #include "MagickCore/log.h"
62 #include "MagickCore/magick.h"
63 #include "MagickCore/memory_.h"
64 #include "MagickCore/monitor.h"
65 #include "MagickCore/option.h"
66 #include "MagickCore/pixel-accessor.h"
67 #include "MagickCore/PreRvIcccm.h"
68 #include "MagickCore/quantize.h"
69 #include "MagickCore/quantum.h"
70 #include "MagickCore/quantum-private.h"
71 #include "MagickCore/resource_.h"
72 #include "MagickCore/resize.h"
73 #include "MagickCore/shear.h"
74 #include "MagickCore/statistic.h"
75 #include "MagickCore/string_.h"
76 #include "MagickCore/string-private.h"
77 #include "MagickCore/transform.h"
78 #include "MagickCore/utility.h"
79 #include "MagickCore/utility-private.h"
80 #include "MagickCore/widget.h"
81 #include "MagickCore/widget-private.h"
82 #include "MagickCore/xwindow.h"
83 #include "MagickCore/xwindow-private.h"
84 #include "MagickCore/version.h"
88 #if defined(MAGICKCORE_X11_DELEGATE)
89 #include <X11/Xproto.h>
90 #include <X11/Xlocale.h>
91 #if defined(MAGICK_HAVE_POLL)
92 # include <sys/poll.h>
94 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
95 #if defined(MAGICKCORE_HAVE_MACHINE_PARAM_H)
96 # include <machine/param.h>
100 #include <X11/extensions/XShm.h>
102 #if defined(MAGICKCORE_HAVE_SHAPE)
103 #include <X11/extensions/shape.h>
109 #define XBlueGamma(color) ClampToQuantum(blue_gamma == 1.0 ? (double) \
110 (color) : ((pow(((double) QuantumScale*(color)),1.0/(double) blue_gamma)* \
112 #define XGammaPacket(map,color) (size_t) (map->base_pixel+ \
113 ((ScaleQuantumToShort(XRedGamma((color)->red))*map->red_max/65535L)* \
115 ((ScaleQuantumToShort(XGreenGamma((color)->green))*map->green_max/65535L)* \
117 ((ScaleQuantumToShort(XBlueGamma((color)->blue))*map->blue_max/65535L)* \
119 #define XGammaPixel(image,map,color) (size_t) (map->base_pixel+ \
120 ((ScaleQuantumToShort(XRedGamma(GetPixelRed(image,color)))*map->red_max/65535L)* \
122 ((ScaleQuantumToShort(XGreenGamma(GetPixelGreen(image,color)))*map->green_max/65535L)* \
124 ((ScaleQuantumToShort(XBlueGamma(GetPixelBlue(image,color)))*map->blue_max/65535L)* \
126 #define XGreenGamma(color) ClampToQuantum(green_gamma == 1.0 ? (double) \
127 (color) : ((pow(((double) QuantumScale*(color)),1.0/(double) green_gamma)* \
129 #define XRedGamma(color) ClampToQuantum(red_gamma == 1.0 ? (double) \
130 (color) : ((pow(((double) QuantumScale*(color)),1.0/(double) red_gamma)* \
132 #define XStandardPixel(map,color) (size_t) (map->base_pixel+ \
133 (((color)->red*map->red_max/65535L)*map->red_mult)+ \
134 (((color)->green*map->green_max/65535L)*map->green_mult)+ \
135 (((color)->blue*map->blue_max/65535L)*map->blue_mult))
137 #define AccentuateModulate ScaleCharToQuantum(80)
138 #define HighlightModulate ScaleCharToQuantum(125)
139 #define ShadowModulate ScaleCharToQuantum(135)
140 #define DepthModulate ScaleCharToQuantum(185)
141 #define TroughModulate ScaleCharToQuantum(110)
143 #define XLIB_ILLEGAL_ACCESS 1
145 #undef NorthWestGravity
147 #undef NorthEastGravity
151 #undef SouthWestGravity
153 #undef SouthEastGravity
160 #define XFD_SET fd_set
164 Enumeration declarations.
178 Typedef declarations.
180 typedef struct _DiversityPacket
195 Constant declaractions.
197 static MagickBooleanType
198 xerror_alert = MagickFalse;
204 *XVisualClassName(const int);
206 static MagickRealType
211 static MagickBooleanType
212 XMakePixmap(Display *,const XResourceInfo *,XWindowInfo *);
215 XMakeImageLSBFirst(const XResourceInfo *,const XWindowInfo *,Image *,
217 XMakeImageMSBFirst(const XResourceInfo *,const XWindowInfo *,Image *,
221 XSelectWindow(Display *,RectangleInfo *);
224 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
228 % D e s t r o y X R e s o u r c e s %
232 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
234 % DestroyXResources() destroys any X resources.
236 % The format of the DestroyXResources method is:
238 % void DestroyXResources()
240 % A description of each parameter follows:
243 MagickExport void DestroyXResources(void)
252 *magick_windows[MaxXWindows];
258 windows=XSetWindows((XWindows *) ~0);
259 if ((windows == (XWindows *) NULL) || (windows->display == (Display *) NULL))
262 magick_windows[number_windows++]=(&windows->context);
263 magick_windows[number_windows++]=(&windows->group_leader);
264 magick_windows[number_windows++]=(&windows->backdrop);
265 magick_windows[number_windows++]=(&windows->icon);
266 magick_windows[number_windows++]=(&windows->image);
267 magick_windows[number_windows++]=(&windows->info);
268 magick_windows[number_windows++]=(&windows->magnify);
269 magick_windows[number_windows++]=(&windows->pan);
270 magick_windows[number_windows++]=(&windows->command);
271 magick_windows[number_windows++]=(&windows->widget);
272 magick_windows[number_windows++]=(&windows->popup);
273 magick_windows[number_windows++]=(&windows->context);
274 for (i=0; i < (int) number_windows; i++)
276 if (magick_windows[i]->mapped != MagickFalse)
278 (void) XWithdrawWindow(windows->display,magick_windows[i]->id,
279 magick_windows[i]->screen);
280 magick_windows[i]->mapped=MagickFalse;
282 if (magick_windows[i]->name != (char *) NULL)
283 magick_windows[i]->name=(char *)
284 RelinquishMagickMemory(magick_windows[i]->name);
285 if (magick_windows[i]->icon_name != (char *) NULL)
286 magick_windows[i]->icon_name=(char *)
287 RelinquishMagickMemory(magick_windows[i]->icon_name);
288 if (magick_windows[i]->cursor != (Cursor) NULL)
290 (void) XFreeCursor(windows->display,magick_windows[i]->cursor);
291 magick_windows[i]->cursor=(Cursor) NULL;
293 if (magick_windows[i]->busy_cursor != (Cursor) NULL)
295 (void) XFreeCursor(windows->display,magick_windows[i]->busy_cursor);
296 magick_windows[i]->busy_cursor=(Cursor) NULL;
298 if (magick_windows[i]->highlight_stipple != (Pixmap) NULL)
300 (void) XFreePixmap(windows->display,
301 magick_windows[i]->highlight_stipple);
302 magick_windows[i]->highlight_stipple=(Pixmap) NULL;
304 if (magick_windows[i]->shadow_stipple != (Pixmap) NULL)
306 (void) XFreePixmap(windows->display,magick_windows[i]->shadow_stipple);
307 magick_windows[i]->shadow_stipple=(Pixmap) NULL;
309 if (magick_windows[i]->ximage != (XImage *) NULL)
311 XDestroyImage(magick_windows[i]->ximage);
312 magick_windows[i]->ximage=(XImage *) NULL;
314 if (magick_windows[i]->pixmap != (Pixmap) NULL)
316 (void) XFreePixmap(windows->display,magick_windows[i]->pixmap);
317 magick_windows[i]->pixmap=(Pixmap) NULL;
319 if (magick_windows[i]->id != (Window) NULL)
321 (void) XDestroyWindow(windows->display,magick_windows[i]->id);
322 magick_windows[i]->id=(Window) NULL;
324 if (magick_windows[i]->destroy != MagickFalse)
326 if (magick_windows[i]->image != (Image *) NULL)
328 magick_windows[i]->image=DestroyImage(magick_windows[i]->image);
329 magick_windows[i]->image=NewImageList();
331 if (magick_windows[i]->matte_pixmap != (Pixmap) NULL)
333 (void) XFreePixmap(windows->display,
334 magick_windows[i]->matte_pixmap);
335 magick_windows[i]->matte_pixmap=(Pixmap) NULL;
338 if (magick_windows[i]->segment_info != (void *) NULL)
340 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
344 segment_info=(XShmSegmentInfo *) magick_windows[i]->segment_info;
345 if (segment_info != (XShmSegmentInfo *) NULL)
346 if (segment_info[0].shmid >= 0)
348 if (segment_info[0].shmaddr != NULL)
349 (void) shmdt(segment_info[0].shmaddr);
350 (void) shmctl(segment_info[0].shmid,IPC_RMID,0);
351 segment_info[0].shmaddr=NULL;
352 segment_info[0].shmid=(-1);
355 magick_windows[i]->segment_info=(void *)
356 RelinquishMagickMemory(magick_windows[i]->segment_info);
359 windows->icon_resources=(XResourceInfo *)
360 RelinquishMagickMemory(windows->icon_resources);
361 if (windows->icon_pixel != (XPixelInfo *) NULL)
363 if (windows->icon_pixel->pixels != (unsigned long *) NULL)
364 windows->icon_pixel->pixels=(unsigned long *)
365 RelinquishMagickMemory(windows->icon_pixel->pixels);
366 if (windows->icon_pixel->annotate_context != (GC) NULL)
367 XFreeGC(windows->display,windows->icon_pixel->annotate_context);
368 windows->icon_pixel=(XPixelInfo *)
369 RelinquishMagickMemory(windows->icon_pixel);
371 if (windows->pixel_info != (XPixelInfo *) NULL)
373 if (windows->pixel_info->pixels != (unsigned long *) NULL)
374 windows->pixel_info->pixels=(unsigned long *)
375 RelinquishMagickMemory(windows->pixel_info->pixels);
376 if (windows->pixel_info->annotate_context != (GC) NULL)
377 XFreeGC(windows->display,windows->pixel_info->annotate_context);
378 if (windows->pixel_info->widget_context != (GC) NULL)
379 XFreeGC(windows->display,windows->pixel_info->widget_context);
380 if (windows->pixel_info->highlight_context != (GC) NULL)
381 XFreeGC(windows->display,windows->pixel_info->highlight_context);
382 windows->pixel_info=(XPixelInfo *)
383 RelinquishMagickMemory(windows->pixel_info);
385 if (windows->font_info != (XFontStruct *) NULL)
387 XFreeFont(windows->display,windows->font_info);
388 windows->font_info=(XFontStruct *) NULL;
390 if (windows->class_hints != (XClassHint *) NULL)
392 if (windows->class_hints->res_name != (char *) NULL)
393 XFree(windows->class_hints->res_name);
394 if (windows->class_hints->res_class != (char *) NULL)
395 XFree(windows->class_hints->res_class);
396 XFree(windows->class_hints);
397 windows->class_hints=(XClassHint *) NULL;
399 if (windows->manager_hints != (XWMHints *) NULL)
401 XFree(windows->manager_hints);
402 windows->manager_hints=(XWMHints *) NULL;
404 if (windows->map_info != (XStandardColormap *) NULL)
406 XFree(windows->map_info);
407 windows->map_info=(XStandardColormap *) NULL;
409 if (windows->icon_map != (XStandardColormap *) NULL)
411 XFree(windows->icon_map);
412 windows->icon_map=(XStandardColormap *) NULL;
414 if (windows->visual_info != (XVisualInfo *) NULL)
416 XFree(windows->visual_info);
417 windows->visual_info=(XVisualInfo *) NULL;
419 if (windows->icon_visual != (XVisualInfo *) NULL)
421 XFree(windows->icon_visual);
422 windows->icon_visual=(XVisualInfo *) NULL;
424 (void) XSetWindows((XWindows *) NULL);
428 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
432 % X A n n o t a t e I m a g e %
436 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
438 % XAnnotateImage() annotates the image with text.
440 % The format of the XAnnotateImage method is:
442 % MagickBooleanType XAnnotateImage(Display *display,
443 % const XPixelInfo *pixel,XAnnotateInfo *annotate_info,Image *image)
445 % A description of each parameter follows:
447 % o display: Specifies a connection to an X server; returned from
450 % o pixel: Specifies a pointer to a XPixelInfo structure.
452 % o annotate_info: Specifies a pointer to a XAnnotateInfo structure.
454 % o image: the image.
457 MagickPrivate MagickBooleanType XAnnotateImage(Display *display,
458 const XPixelInfo *pixel,XAnnotateInfo *annotate_info,Image *image)
497 Initialize annotated image.
499 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
500 assert(display != (Display *) NULL);
501 assert(pixel != (XPixelInfo *) NULL);
502 assert(annotate_info != (XAnnotateInfo *) NULL);
503 assert(image != (Image *) NULL);
505 Initialize annotated pixmap.
507 root_window=XRootWindow(display,XDefaultScreen(display));
508 depth=(unsigned int) XDefaultDepth(display,XDefaultScreen(display));
509 annotate_pixmap=XCreatePixmap(display,root_window,annotate_info->width,
510 annotate_info->height,depth);
511 if (annotate_pixmap == (Pixmap) NULL)
514 Initialize graphics info.
516 context_values.background=0;
517 context_values.foreground=(size_t) (~0);
518 context_values.font=annotate_info->font_info->fid;
519 annotate_context=XCreateGC(display,root_window,(unsigned long)
520 (GCBackground | GCFont | GCForeground),&context_values);
521 if (annotate_context == (GC) NULL)
526 (void) XDrawImageString(display,annotate_pixmap,annotate_context,0,
527 (int) annotate_info->font_info->ascent,annotate_info->text,
528 (int) strlen(annotate_info->text));
529 (void) XFreeGC(display,annotate_context);
531 Initialize annotated X image.
533 annotate_ximage=XGetImage(display,annotate_pixmap,0,0,annotate_info->width,
534 annotate_info->height,AllPlanes,ZPixmap);
535 if (annotate_ximage == (XImage *) NULL)
537 (void) XFreePixmap(display,annotate_pixmap);
539 Initialize annotated image.
541 annotate_image=AcquireImage((ImageInfo *) NULL);
542 if (annotate_image == (Image *) NULL)
544 annotate_image->columns=annotate_info->width;
545 annotate_image->rows=annotate_info->height;
547 Transfer annotated X image to image.
549 width=(unsigned int) image->columns;
550 height=(unsigned int) image->rows;
553 (void) XParseGeometry(annotate_info->geometry,&x,&y,&width,&height);
554 (void) GetOneVirtualPixel(image,(ssize_t) x,(ssize_t) y,
555 &annotate_image->background_color,&image->exception);
556 if (annotate_info->stencil == ForegroundStencil)
557 annotate_image->matte=MagickTrue;
558 exception=(&image->exception);
559 annotate_view=AcquireCacheView(annotate_image);
560 for (y=0; y < (int) annotate_image->rows; y++)
568 q=GetCacheViewAuthenticPixels(annotate_view,0,(ssize_t) y,
569 annotate_image->columns,1,exception);
570 if (q == (Quantum *) NULL)
572 for (x=0; x < (int) annotate_image->columns; x++)
574 SetPixelAlpha(annotate_image,OpaqueAlpha,q);
575 if (XGetPixel(annotate_ximage,x,y) == 0)
578 Set this pixel to the background color.
580 SetPixelRed(annotate_image,ScaleShortToQuantum(
581 pixel->box_color.red),q);
582 SetPixelGreen(annotate_image,ScaleShortToQuantum(
583 pixel->box_color.green),q);
584 SetPixelBlue(annotate_image,ScaleShortToQuantum(
585 pixel->box_color.blue),q);
586 if ((annotate_info->stencil == ForegroundStencil) ||
587 (annotate_info->stencil == OpaqueStencil))
588 SetPixelAlpha(annotate_image,TransparentAlpha,q);
593 Set this pixel to the pen color.
595 SetPixelRed(annotate_image,ScaleShortToQuantum(
596 pixel->pen_color.red),q);
597 SetPixelGreen(annotate_image,ScaleShortToQuantum(
598 pixel->pen_color.green),q);
599 SetPixelBlue(annotate_image,ScaleShortToQuantum(
600 pixel->pen_color.blue),q);
601 if (annotate_info->stencil == BackgroundStencil)
602 SetPixelAlpha(annotate_image,TransparentAlpha,q);
604 q+=GetPixelChannels(annotate_image);
606 if (SyncCacheViewAuthenticPixels(annotate_view,exception) == MagickFalse)
609 annotate_view=DestroyCacheView(annotate_view);
610 XDestroyImage(annotate_ximage);
612 Determine annotate geometry.
614 (void) XParseGeometry(annotate_info->geometry,&x,&y,&width,&height);
615 if ((width != (unsigned int) annotate_image->columns) ||
616 (height != (unsigned int) annotate_image->rows))
619 image_geometry[MaxTextExtent];
624 (void) FormatLocaleString(image_geometry,MaxTextExtent,"%ux%u",
626 (void) TransformImage(&annotate_image,(char *) NULL,image_geometry);
628 if (annotate_info->degrees != 0.0)
643 RotateImage(annotate_image,annotate_info->degrees,&image->exception);
644 if (rotate_image == (Image *) NULL)
646 annotate_image=DestroyImage(annotate_image);
647 annotate_image=rotate_image;
649 Annotation is relative to the degree of rotation.
651 normalized_degrees=annotate_info->degrees;
652 while (normalized_degrees < -45.0)
653 normalized_degrees+=360.0;
654 for (rotations=0; normalized_degrees > 45.0; rotations++)
655 normalized_degrees-=90.0;
656 switch (rotations % 4)
666 x-=(int) annotate_image->columns/2;
667 y+=(int) annotate_image->columns/2;
675 x=x-(int) annotate_image->columns;
683 x=x-(int) annotate_image->columns/2;
684 y=y-(int) (annotate_image->rows-(annotate_image->columns/2));
690 Composite text onto the image.
692 (void) XParseGeometry(annotate_info->geometry,&x,&y,&width,&height);
694 (void) CompositeImage(image,annotate_image->matte != MagickFalse ?
695 OverCompositeOp : CopyCompositeOp,annotate_image,(ssize_t) x,(ssize_t) y);
697 annotate_image=DestroyImage(annotate_image);
702 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
706 % X B e s t F o n t %
710 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
712 % XBestFont() returns the "best" font. "Best" is defined as a font specified
713 % in the X resource database or a font such that the text width displayed
714 % with the font does not exceed the specified maximum width.
716 % The format of the XBestFont method is:
718 % XFontStruct *XBestFont(Display *display,
719 % const XResourceInfo *resource_info,const MagickBooleanType text_font)
721 % A description of each parameter follows:
723 % o font: XBestFont returns a pointer to a XFontStruct structure.
725 % o display: Specifies a connection to an X server; returned from
728 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
730 % o text_font: True is font should be mono-spaced (typewriter style).
734 static char **FontToList(char *font)
749 if (font == (char *) NULL)
750 return((char **) NULL);
752 Convert string to an ASCII list.
755 for (p=font; *p != '\0'; p++)
756 if ((*p == ':') || (*p == ';') || (*p == ','))
758 fontlist=(char **) AcquireQuantumMemory((size_t) fonts+1UL,sizeof(*fontlist));
759 if (fontlist == (char **) NULL)
761 ThrowXWindowFatalException(ResourceLimitError,"MemoryAllocationFailed",
763 return((char **) NULL);
766 for (i=0; i < (int) fonts; i++)
768 for (q=p; *q != '\0'; q++)
769 if ((*q == ':') || (*q == ';') || (*q == ','))
771 fontlist[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+1UL,
772 sizeof(*fontlist[i]));
773 if (fontlist[i] == (char *) NULL)
775 ThrowXWindowFatalException(ResourceLimitError,"MemoryAllocationFailed",
777 return((char **) NULL);
779 (void) CopyMagickString(fontlist[i],p,(size_t) (q-p+1));
782 fontlist[i]=(char *) NULL;
786 MagickPrivate XFontStruct *XBestFont(Display *display,
787 const XResourceInfo *resource_info,const MagickBooleanType text_font)
792 "-*-helvetica-medium-r-normal--12-*-*-*-*-*-iso8859-1",
793 "-*-arial-medium-r-normal--12-*-*-*-*-*-iso8859-1",
794 "-*-helvetica-medium-r-normal--12-*-*-*-*-*-iso8859-15",
795 "-*-arial-medium-r-normal--12-*-*-*-*-*-iso8859-15",
796 "-*-helvetica-medium-r-normal--12-*-*-*-*-*-*-*",
797 "-*-arial-medium-r-normal--12-*-*-*-*-*-*-*",
804 "-*-courier-medium-r-normal-*-12-*-*-*-*-*-iso8859-1",
805 "-*-courier-medium-r-normal-*-12-*-*-*-*-*-iso8859-15",
806 "-*-fixed-medium-r-normal-*-12-*-*-*-*-*-*-*",
820 font_info=(XFontStruct *) NULL;
821 font_name=resource_info->font;
822 if (text_font != MagickFalse)
823 font_name=resource_info->text_font;
824 if ((font_name != (char *) NULL) && (*font_name != '\0'))
833 Load preferred font specified in the X resource database.
835 fontlist=FontToList(font_name);
836 if (fontlist != (char **) NULL)
838 for (i=0; fontlist[i] != (char *) NULL; i++)
840 if (font_info == (XFontStruct *) NULL)
841 font_info=XLoadQueryFont(display,fontlist[i]);
842 fontlist[i]=DestroyString(fontlist[i]);
844 fontlist=(char **) RelinquishMagickMemory(fontlist);
846 if (font_info == (XFontStruct *) NULL)
847 ThrowXWindowFatalException(XServerError,"UnableToLoadFont",font_name);
850 Load fonts from list of fonts until one is found.
853 if (text_font != MagickFalse)
855 if (XDisplayHeight(display,XDefaultScreen(display)) >= 748)
857 while (*p != (char *) NULL)
859 if (font_info != (XFontStruct *) NULL)
861 font_info=XLoadQueryFont(display,(char *) *p);
868 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
872 % X B e s t I c o n S i z e %
876 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
878 % XBestIconSize() returns the "best" icon size. "Best" is defined as an icon
879 % size that maintains the aspect ratio of the image. If the window manager
880 % has preferred icon sizes, one of the preferred sizes is used.
882 % The format of the XBestIconSize method is:
884 % void XBestIconSize(Display *display,XWindowInfo *window,Image *image)
886 % A description of each parameter follows:
888 % o display: Specifies a connection to an X server; returned from
891 % o image: the image.
894 MagickPrivate void XBestIconSize(Display *display,XWindowInfo *window,
918 Determine if the window manager has specified preferred icon sizes.
920 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
921 assert(display != (Display *) NULL);
922 assert(window != (XWindowInfo *) NULL);
923 assert(image != (Image *) NULL);
924 window->width=MaxIconSize;
925 window->height=MaxIconSize;
926 icon_size=(XIconSize *) NULL;
928 root_window=XRootWindow(display,window->screen);
929 if (XGetIconSizes(display,root_window,&size_list,&number_sizes) != 0)
930 if ((number_sizes > 0) && (size_list != (XIconSize *) NULL))
932 if (icon_size == (XIconSize *) NULL)
935 Window manager does not restrict icon size.
937 icon_size=XAllocIconSize();
938 if (icon_size == (XIconSize *) NULL)
940 ThrowXWindowFatalException(ResourceLimitError,
941 "MemoryAllocationFailed",image->filename);
944 icon_size->min_width=1;
945 icon_size->max_width=MaxIconSize;
946 icon_size->min_height=1;
947 icon_size->max_height=MaxIconSize;
948 icon_size->width_inc=1;
949 icon_size->height_inc=1;
952 Determine aspect ratio of image.
954 width=(unsigned int) image->columns;
955 height=(unsigned int) image->rows;
957 if (window->crop_geometry)
958 (void) XParseGeometry(window->crop_geometry,&i,&i,&width,&height);
960 Look for an icon size that maintains the aspect ratio of image.
962 scale_factor=(MagickRealType) icon_size->max_width/width;
963 if (scale_factor > ((MagickRealType) icon_size->max_height/height))
964 scale_factor=(MagickRealType) icon_size->max_height/height;
965 icon_width=(unsigned int) icon_size->min_width;
966 while ((int) icon_width < icon_size->max_width)
968 if (icon_width >= (unsigned int) (scale_factor*width+0.5))
970 icon_width+=icon_size->width_inc;
972 icon_height=(unsigned int) icon_size->min_height;
973 while ((int) icon_height < icon_size->max_height)
975 if (icon_height >= (unsigned int) (scale_factor*height+0.5))
977 icon_height+=icon_size->height_inc;
979 (void) XFree((void *) icon_size);
980 window->width=icon_width;
981 window->height=icon_height;
985 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
989 % X B e s t P i x e l %
993 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
995 % XBestPixel() returns a pixel from an array of pixels that is closest to the
996 % requested color. If the color array is NULL, the colors are obtained from
999 % The format of the XBestPixel method is:
1001 % void XBestPixel(Display *display,const Colormap colormap,XColor *colors,
1002 % unsigned int number_colors,XColor *color)
1004 % A description of each parameter follows:
1006 % o pixel: XBestPixel returns the pixel value closest to the requested
1009 % o display: Specifies a connection to an X server; returned from
1012 % o colormap: Specifies the ID of the X server colormap.
1014 % o colors: Specifies an array of XColor structures.
1016 % o number_colors: Specifies the number of XColor structures in the
1017 % color definition array.
1019 % o color: Specifies the desired RGB value to find in the colors array.
1022 MagickPrivate void XBestPixel(Display *display,const Colormap colormap,
1023 XColor *colors,unsigned int number_colors,XColor *color)
1034 register MagickRealType
1045 Find closest representation for the requested RGB color.
1047 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1048 assert(display != (Display *) NULL);
1049 assert(color != (XColor *) NULL);
1050 status=XAllocColor(display,colormap,color);
1051 if (status != False)
1053 query_server=colors == (XColor *) NULL ? MagickTrue : MagickFalse;
1054 if (query_server != MagickFalse)
1057 Read X server colormap.
1059 colors=(XColor *) AcquireQuantumMemory(number_colors,sizeof(*colors));
1060 if (colors == (XColor *) NULL)
1062 ThrowXWindowFatalException(ResourceLimitError,
1063 "MemoryAllocationFailed","...");
1066 for (i=0; i < (int) number_colors; i++)
1067 colors[i].pixel=(size_t) i;
1068 if (number_colors > 256)
1070 (void) XQueryColors(display,colormap,colors,(int) number_colors);
1072 min_distance=3.0*((MagickRealType) QuantumRange+1.0)*((MagickRealType)
1075 for (i=0; i < (int) number_colors; i++)
1077 pixel.red=colors[i].red-(MagickRealType) color->red;
1078 distance=pixel.red*pixel.red;
1079 if (distance > min_distance)
1081 pixel.green=colors[i].green-(MagickRealType) color->green;
1082 distance+=pixel.green*pixel.green;
1083 if (distance > min_distance)
1085 pixel.blue=colors[i].blue-(MagickRealType) color->blue;
1086 distance+=pixel.blue*pixel.blue;
1087 if (distance > min_distance)
1089 min_distance=distance;
1090 color->pixel=colors[i].pixel;
1093 (void) XAllocColor(display,colormap,&colors[j]);
1094 if (query_server != MagickFalse)
1095 colors=(XColor *) RelinquishMagickMemory(colors);
1099 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1103 % X B e s t V i s u a l I n f o %
1107 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1109 % XBestVisualInfo() returns visual information for a visual that is the "best"
1110 % the server supports. "Best" is defined as:
1112 % 1. Restrict the visual list to those supported by the default screen.
1114 % 2. If a visual type is specified, restrict the visual list to those of
1117 % 3. If a map type is specified, choose the visual that matches the id
1118 % specified by the Standard Colormap.
1120 % 4 From the list of visuals, choose one that can display the most
1121 % simultaneous colors. If more than one visual can display the same
1122 % number of simultaneous colors, one is chosen based on a rank.
1124 % The format of the XBestVisualInfo method is:
1126 % XVisualInfo *XBestVisualInfo(Display *display,
1127 % XStandardColormap *map_info,XResourceInfo *resource_info)
1129 % A description of each parameter follows:
1131 % o visual_info: XBestVisualInfo returns a pointer to a X11 XVisualInfo
1134 % o display: Specifies a connection to an X server; returned from
1137 % o map_info: If map_type is specified, this structure is initialized
1138 % with info from the Standard Colormap.
1140 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
1144 static inline int MagickMax(const int x,const int y)
1151 static inline size_t MagickMin(const unsigned int x,
1152 const unsigned int y)
1159 MagickPrivate XVisualInfo *XBestVisualInfo(Display *display,
1160 XStandardColormap *map_info,XResourceInfo *resource_info)
1162 #define MaxStandardColormaps 7
1163 #define XVisualColormapSize(visual_info) MagickMin((unsigned int) (\
1164 (visual_info->klass == TrueColor) || (visual_info->klass == DirectColor) ? \
1165 visual_info->red_mask | visual_info->green_mask | visual_info->blue_mask : \
1166 (unsigned int) visual_info->colormap_size),1U << visual_info->depth)
1192 Restrict visual search by screen number.
1194 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1195 assert(display != (Display *) NULL);
1196 assert(map_info != (XStandardColormap *) NULL);
1197 assert(resource_info != (XResourceInfo *) NULL);
1198 map_type=resource_info->map_type;
1199 visual_type=resource_info->visual_type;
1200 visual_mask=VisualScreenMask;
1201 visual_template.screen=XDefaultScreen(display);
1202 visual_template.depth=XDefaultDepth(display,XDefaultScreen(display));
1204 if ((resource_info->immutable != MagickFalse) && (resource_info->colors != 0))
1205 if (resource_info->colors <= (one << (size_t) visual_template.depth))
1206 visual_mask|=VisualDepthMask;
1207 if (visual_type != (char *) NULL)
1210 Restrict visual search by class or visual id.
1212 if (LocaleCompare("staticgray",visual_type) == 0)
1214 visual_mask|=VisualClassMask;
1215 visual_template.klass=StaticGray;
1218 if (LocaleCompare("grayscale",visual_type) == 0)
1220 visual_mask|=VisualClassMask;
1221 visual_template.klass=GrayScale;
1224 if (LocaleCompare("staticcolor",visual_type) == 0)
1226 visual_mask|=VisualClassMask;
1227 visual_template.klass=StaticColor;
1230 if (LocaleCompare("pseudocolor",visual_type) == 0)
1232 visual_mask|=VisualClassMask;
1233 visual_template.klass=PseudoColor;
1236 if (LocaleCompare("truecolor",visual_type) == 0)
1238 visual_mask|=VisualClassMask;
1239 visual_template.klass=TrueColor;
1242 if (LocaleCompare("directcolor",visual_type) == 0)
1244 visual_mask|=VisualClassMask;
1245 visual_template.klass=DirectColor;
1248 if (LocaleCompare("default",visual_type) == 0)
1250 visual_mask|=VisualIDMask;
1251 visual_template.visualid=XVisualIDFromVisual(
1252 XDefaultVisual(display,XDefaultScreen(display)));
1255 if (isdigit((int) ((unsigned char) *visual_type)) != 0)
1257 visual_mask|=VisualIDMask;
1258 visual_template.visualid=
1259 strtol(visual_type,(char **) NULL,0);
1262 ThrowXWindowFatalException(XServerError,
1263 "UnrecognizedVisualSpecifier",visual_type);
1266 Get all visuals that meet our criteria so far.
1269 visual_list=XGetVisualInfo(display,visual_mask,&visual_template,
1271 visual_mask=VisualScreenMask | VisualIDMask;
1272 if ((number_visuals == 0) || (visual_list == (XVisualInfo *) NULL))
1275 Failed to get visual; try using the default visual.
1277 ThrowXWindowFatalException(XServerWarning,"UnableToGetVisual",
1279 visual_template.visualid=XVisualIDFromVisual(XDefaultVisual(display,
1280 XDefaultScreen(display)));
1281 visual_list=XGetVisualInfo(display,visual_mask,&visual_template,
1283 if ((number_visuals == 0) || (visual_list == (XVisualInfo *) NULL))
1284 return((XVisualInfo *) NULL);
1285 ThrowXWindowFatalException(XServerWarning,"UsingDefaultVisual",
1286 XVisualClassName(visual_list->klass));
1288 resource_info->color_recovery=MagickFalse;
1289 if ((map_info != (XStandardColormap *) NULL) && (map_type != (char *) NULL))
1295 map_name[MaxTextExtent];
1311 Choose a visual associated with a standard colormap.
1313 root_window=XRootWindow(display,XDefaultScreen(display));
1315 if (LocaleCompare(map_type,"list") != 0)
1318 User specified Standard Colormap.
1320 (void) FormatLocaleString((char *) map_name,MaxTextExtent,
1321 "RGB_%s_MAP",map_type);
1322 LocaleUpper(map_name);
1323 map_property=XInternAtom(display,(char *) map_name,MagickTrue);
1324 if (map_property != (Atom) NULL)
1325 status=XGetRGBColormaps(display,root_window,&map_list,&number_maps,
1331 *colormap[MaxStandardColormaps]=
1333 "_HP_RGB_SMOOTH_MAP_LIST",
1343 Choose a standard colormap from a list.
1345 for (i=0; i < MaxStandardColormaps; i++)
1347 map_property=XInternAtom(display,(char *) colormap[i],MagickTrue);
1348 if (map_property == (Atom) NULL)
1350 status=XGetRGBColormaps(display,root_window,&map_list,&number_maps,
1352 if (status != False)
1355 resource_info->color_recovery=i == 0 ? MagickTrue : MagickFalse;
1357 if (status == False)
1359 ThrowXWindowFatalException(XServerError,"UnableToGetStandardColormap",
1361 return((XVisualInfo *) NULL);
1364 Search all Standard Colormaps and visuals for ids that match.
1366 *map_info=map_list[0];
1367 #if !defined(PRE_R4_ICCCM)
1368 visual_template.visualid=XVisualIDFromVisual(visual_list[0].visual);
1369 for (i=0; i < number_maps; i++)
1370 for (j=0; j < number_visuals; j++)
1371 if (map_list[i].visualid ==
1372 XVisualIDFromVisual(visual_list[j].visual))
1374 *map_info=map_list[i];
1375 visual_template.visualid=XVisualIDFromVisual(
1376 visual_list[j].visual);
1379 if (map_info->visualid != visual_template.visualid)
1381 ThrowXWindowFatalException(XServerError,
1382 "UnableToMatchVisualToStandardColormap",map_type);
1383 return((XVisualInfo *) NULL);
1386 if (map_info->colormap == (Colormap) NULL)
1388 ThrowXWindowFatalException(XServerError,
1389 "StandardColormapIsNotInitialized",map_type);
1390 return((XVisualInfo *) NULL);
1392 (void) XFree((void *) map_list);
1396 static const unsigned int
1411 Pick one visual that displays the most simultaneous colors.
1413 visual_info=visual_list;
1415 for (i=1; i < number_visuals; i++)
1418 if (XVisualColormapSize(p) > XVisualColormapSize(visual_info))
1421 if (XVisualColormapSize(p) == XVisualColormapSize(visual_info))
1422 if (rank[p->klass] > rank[visual_info->klass])
1425 visual_template.visualid=XVisualIDFromVisual(visual_info->visual);
1427 (void) XFree((void *) visual_list);
1429 Retrieve only one visual by its screen & id number.
1431 visual_info=XGetVisualInfo(display,visual_mask,&visual_template,
1433 if ((number_visuals == 0) || (visual_info == (XVisualInfo *) NULL))
1434 return((XVisualInfo *) NULL);
1435 return(visual_info);
1439 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1443 % X C h e c k D e f i n e C u r s o r %
1447 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1449 % XCheckDefineCursor() prevents cursor changes on the root window.
1451 % The format of the XXCheckDefineCursor method is:
1453 % XCheckDefineCursor(display,window,cursor)
1455 % A description of each parameter follows:
1457 % o display: Specifies a connection to an X server; returned from
1460 % o window: the window.
1462 % o cursor: the cursor.
1465 MagickPrivate int XCheckDefineCursor(Display *display,Window window,
1468 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1469 assert(display != (Display *) NULL);
1470 if (window == XRootWindow(display,XDefaultScreen(display)))
1472 return(XDefineCursor(display,window,cursor));
1476 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1480 % X C h e c k R e f r e s h W i n d o w s %
1484 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1486 % XCheckRefreshWindows() checks the X server for exposure events for a
1487 % particular window and updates the areassociated with the exposure event.
1489 % The format of the XCheckRefreshWindows method is:
1491 % void XCheckRefreshWindows(Display *display,XWindows *windows)
1493 % A description of each parameter follows:
1495 % o display: Specifies a connection to an X server; returned from
1498 % o windows: Specifies a pointer to a XWindows structure.
1501 MagickPrivate void XCheckRefreshWindows(Display *display,XWindows *windows)
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);
1529 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1533 % X C l i e n t M e s s a g e %
1537 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1539 % XClientMessage() sends a reason to a window with XSendEvent. The reason is
1540 % initialized with a particular protocol type and atom.
1542 % The format of the XClientMessage function is:
1544 % XClientMessage(display,window,protocol,reason,timestamp)
1546 % A description of each parameter follows:
1548 % o display: Specifies a pointer to the Display structure; returned from
1551 % o window: Specifies a pointer to a Window structure.
1553 % o protocol: Specifies an atom value.
1555 % o reason: Specifies an atom value which is the reason to send.
1557 % o timestamp: Specifies a value of type Time.
1560 MagickPrivate void XClientMessage(Display *display,const Window window,
1561 const Atom protocol,const Atom reason,const Time timestamp)
1566 assert(display != (Display *) NULL);
1567 client_event.type=ClientMessage;
1568 client_event.window=window;
1569 client_event.message_type=protocol;
1570 client_event.format=32;
1571 client_event.data.l[0]=(long) reason;
1572 client_event.data.l[1]=(long) timestamp;
1573 (void) XSendEvent(display,window,MagickFalse,NoEventMask,(XEvent *) &client_event);
1577 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1581 + X C l i e n t W i n d o w %
1585 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1587 % XClientWindow() finds a window, at or below the specified window, which has
1588 % a WM_STATE property. If such a window is found, it is returned, otherwise
1589 % the argument window is returned.
1591 % The format of the XClientWindow function is:
1593 % client_window=XClientWindow(display,target_window)
1595 % A description of each parameter follows:
1597 % o client_window: XClientWindow returns a window, at or below the specified
1598 % window, which has a WM_STATE property otherwise the argument
1599 % target_window is returned.
1601 % o display: Specifies a pointer to the Display structure; returned from
1604 % o target_window: Specifies the window to find a WM_STATE property.
1607 static Window XClientWindow(Display *display,Window target_window)
1629 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1630 assert(display != (Display *) NULL);
1631 state=XInternAtom(display,"WM_STATE",MagickTrue);
1632 if (state == (Atom) NULL)
1633 return(target_window);
1635 status=XGetWindowProperty(display,target_window,state,0L,0L,MagickFalse,
1636 (Atom) AnyPropertyType,&type,&format,&number_items,&after,&data);
1637 if ((status == Success) && (type != (Atom) NULL))
1638 return(target_window);
1639 client_window=XWindowByProperty(display,target_window,state);
1640 if (client_window == (Window) NULL)
1641 return(target_window);
1642 return(client_window);
1646 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1650 + X C o m p o n e n t T e r m i n u s %
1654 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1656 % XComponentTerminus() destroys the module component.
1658 % The format of the XComponentTerminus method is:
1660 % XComponentTerminus(void)
1663 MagickPrivate void XComponentTerminus(void)
1665 DestroyXResources();
1669 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1673 % X C o n f i g u r e I m a g e C o l o r m a p %
1677 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1679 % XConfigureImageColormap() creates a new X colormap.
1681 % The format of the XConfigureImageColormap method is:
1683 % void XConfigureImageColormap(Display *display,
1684 % XResourceInfo *resource_info,XWindows *windows,Image *image)
1686 % A description of each parameter follows:
1688 % o display: Specifies a connection to an X server; returned from
1691 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
1693 % o windows: Specifies a pointer to a XWindows structure.
1695 % o image: the image.
1698 MagickPrivate void XConfigureImageColormap(Display *display,
1699 XResourceInfo *resource_info,XWindows *windows,Image *image)
1705 Make standard colormap.
1707 XSetCursorState(display,windows,MagickTrue);
1708 XCheckRefreshWindows(display,windows);
1709 XMakeStandardColormap(display,windows->visual_info,resource_info,image,
1710 windows->map_info,windows->pixel_info);
1711 colormap=windows->map_info->colormap;
1712 (void) XSetWindowColormap(display,windows->image.id,colormap);
1713 (void) XSetWindowColormap(display,windows->command.id,colormap);
1714 (void) XSetWindowColormap(display,windows->widget.id,colormap);
1715 if (windows->magnify.mapped != MagickFalse)
1716 (void) XSetWindowColormap(display,windows->magnify.id,colormap);
1717 if (windows->pan.mapped != MagickFalse)
1718 (void) XSetWindowColormap(display,windows->pan.id,colormap);
1719 XSetCursorState(display,windows,MagickFalse);
1720 XClientMessage(display,windows->image.id,windows->im_protocols,
1721 windows->im_update_colormap,CurrentTime);
1725 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1729 % X C o n s t r a i n W i n d o w P o s i t i o n %
1733 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1735 % XConstrainWindowPosition() assures a window is positioned within the X
1736 % server boundaries.
1738 % The format of the XConstrainWindowPosition method is:
1740 % void XConstrainWindowPosition(Display *display,XWindowInfo *window_info)
1742 % A description of each parameter follows:
1744 % o display: Specifies a pointer to the Display structure; returned from
1747 % o window_info: Specifies a pointer to a XWindowInfo structure.
1750 MagickPrivate void XConstrainWindowPosition(Display *display,
1751 XWindowInfo *window_info)
1756 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1757 assert(display != (Display *) NULL);
1758 assert(window_info != (XWindowInfo *) NULL);
1759 limit=XDisplayWidth(display,window_info->screen)-window_info->width;
1760 if (window_info->x < 0)
1763 if (window_info->x > (int) limit)
1764 window_info->x=(int) limit;
1765 limit=XDisplayHeight(display,window_info->screen)-window_info->height;
1766 if (window_info->y < 0)
1769 if (window_info->y > limit)
1770 window_info->y=limit;
1774 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1782 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1784 % XDelay() suspends program execution for the number of milliseconds
1787 % The format of the Delay method is:
1789 % void XDelay(Display *display,const size_t milliseconds)
1791 % A description of each parameter follows:
1793 % o display: Specifies a pointer to the Display structure; returned from
1796 % o milliseconds: Specifies the number of milliseconds to delay before
1800 MagickPrivate void XDelay(Display *display,const size_t milliseconds)
1802 assert(display != (Display *) NULL);
1803 (void) XFlush(display);
1804 MagickDelay(milliseconds);
1808 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1812 % X D e s t r o y R e s o u r c e I n f o %
1816 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1818 % XDestroyResourceInfo() frees memory associated with the XResourceInfo
1821 % The format of the XDestroyResourceInfo method is:
1823 % void XDestroyResourceInfo(XResourceInfo *resource_info)
1825 % A description of each parameter follows:
1827 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
1830 MagickExport void XDestroyResourceInfo(XResourceInfo *resource_info)
1832 if (resource_info->image_geometry != (char *) NULL)
1833 resource_info->image_geometry=(char *)
1834 RelinquishMagickMemory(resource_info->image_geometry);
1835 if (resource_info->quantize_info != (QuantizeInfo *) NULL)
1836 resource_info->quantize_info=DestroyQuantizeInfo(
1837 resource_info->quantize_info);
1838 if (resource_info->client_name != (char *) NULL)
1839 resource_info->client_name=(char *)
1840 RelinquishMagickMemory(resource_info->client_name);
1841 if (resource_info->name != (char *) NULL)
1842 resource_info->name=DestroyString(resource_info->name);
1843 (void) ResetMagickMemory(resource_info,0,sizeof(*resource_info));
1847 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1851 % X D e s t r o y W i n d o w C o l o r s %
1855 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1857 % XDestroyWindowColors() frees X11 color resources previously saved on a
1858 % window by XRetainWindowColors or programs like xsetroot.
1860 % The format of the XDestroyWindowColors method is:
1862 % void XDestroyWindowColors(Display *display,Window window)
1864 % A description of each parameter follows:
1866 % o display: Specifies a connection to an X server; returned from
1869 % o window: Specifies a pointer to a Window structure.
1872 MagickPrivate void XDestroyWindowColors(Display *display,Window window)
1892 If there are previous resources on the root window, destroy them.
1894 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1895 assert(display != (Display *) NULL);
1896 property=XInternAtom(display,"_XSETROOT_ID",MagickFalse);
1897 if (property == (Atom) NULL)
1899 ThrowXWindowFatalException(XServerError,"UnableToCreateProperty",
1903 status=XGetWindowProperty(display,window,property,0L,1L,MagickTrue,
1904 (Atom) AnyPropertyType,&type,&format,&length,&after,&data);
1905 if (status != Success)
1907 if ((type == XA_PIXMAP) && (format == 32) && (length == 1) && (after == 0))
1909 (void) XKillClient(display,(XID) (*((Pixmap *) data)));
1910 (void) XDeleteProperty(display,window,property);
1913 (void) XFree((void *) data);
1917 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1921 % X D i s p l a y I m a g e I n f o %
1925 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1927 % XDisplayImageInfo() displays information about an X image.
1929 % The format of the XDisplayImageInfo method is:
1931 % void XDisplayImageInfo(Display *display,
1932 % const XResourceInfo *resource_info,XWindows *windows,Image *undo_image,
1935 % A description of each parameter follows:
1937 % o display: Specifies a connection to an X server; returned from
1940 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
1942 % o windows: Specifies a pointer to a XWindows structure.
1944 % o undo_image: the undo image.
1946 % o image: the image.
1949 MagickPrivate void XDisplayImageInfo(Display *display,
1950 const XResourceInfo *resource_info,XWindows *windows,Image *undo_image,
1954 filename[MaxTextExtent],
1977 Write info about the X server to a file.
1979 assert(display != (Display *) NULL);
1980 assert(resource_info != (XResourceInfo *) NULL);
1981 assert(windows != (XWindows *) NULL);
1982 assert(image != (Image *) NULL);
1984 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1986 unique_file=AcquireUniqueFileResource(filename);
1987 if (unique_file != -1)
1988 file=fdopen(unique_file,"w");
1989 if ((unique_file == -1) || (file == (FILE *) NULL))
1991 XNoticeWidget(display,windows,"Unable to display image info",filename);
1994 if (resource_info->gamma_correct != MagickFalse)
1995 if (resource_info->display_gamma != (char *) NULL)
1996 (void) FormatLocaleFile(file,"Display\n gamma: %s\n\n",
1997 resource_info->display_gamma);
1999 Write info about the X image to a file.
2001 (void) FormatLocaleFile(file,"X\n visual: %s\n",
2002 XVisualClassName((int) windows->image.storage_class));
2003 (void) FormatLocaleFile(file," depth: %d\n",windows->image.ximage->depth);
2004 if (windows->visual_info->colormap_size != 0)
2005 (void) FormatLocaleFile(file," colormap size: %d\n",
2006 windows->visual_info->colormap_size);
2007 if (resource_info->colormap== SharedColormap)
2008 (void) FormatLocaleFile(file," colormap type: Shared\n");
2010 (void) FormatLocaleFile(file," colormap type: Private\n");
2011 (void) FormatLocaleFile(file," geometry: %dx%d\n",
2012 windows->image.ximage->width,windows->image.ximage->height);
2013 if (windows->image.crop_geometry != (char *) NULL)
2014 (void) FormatLocaleFile(file," crop geometry: %s\n",
2015 windows->image.crop_geometry);
2016 if (windows->image.pixmap == (Pixmap) NULL)
2017 (void) FormatLocaleFile(file," type: X Image\n");
2019 (void) FormatLocaleFile(file," type: Pixmap\n");
2020 if (windows->image.shape != MagickFalse)
2021 (void) FormatLocaleFile(file," non-rectangular shape: True\n");
2023 (void) FormatLocaleFile(file," non-rectangular shape: False\n");
2024 if (windows->image.shared_memory != MagickFalse)
2025 (void) FormatLocaleFile(file," shared memory: True\n");
2027 (void) FormatLocaleFile(file," shared memory: False\n");
2028 (void) FormatLocaleFile(file,"\n");
2029 if (resource_info->font != (char *) NULL)
2030 (void) FormatLocaleFile(file,"Font: %s\n\n",resource_info->font);
2031 if (resource_info->text_font != (char *) NULL)
2032 (void) FormatLocaleFile(file,"Text font: %s\n\n",resource_info->text_font);
2034 Write info about the undo cache to a file.
2037 for (levels=0; undo_image != (Image *) NULL; levels++)
2039 number_pixels=undo_image->list->columns*undo_image->list->rows;
2040 bytes+=number_pixels*sizeof(PixelPacket);
2041 undo_image=GetPreviousImageInList(undo_image);
2043 (void) FormatLocaleFile(file,"Undo Edit Cache\n levels: %u\n",levels);
2044 (void) FormatLocaleFile(file," bytes: %.20gmb\n",(double)
2045 ((bytes+(1 << 19)) >> 20));
2046 (void) FormatLocaleFile(file," limit: %.20gmb\n\n",(double)
2047 resource_info->undo_cache);
2049 Write info about the image to a file.
2051 (void) IdentifyImage(image,file,MagickTrue,&image->exception);
2052 (void) fclose(file);
2053 text=FileToString(filename,~0,&image->exception);
2054 (void) RelinquishUniqueFileResource(filename);
2055 if (text == (char *) NULL)
2057 XNoticeWidget(display,windows,"MemoryAllocationFailed",
2058 "UnableToDisplayImageInfo");
2061 textlist=StringToList(text);
2062 if (textlist != (char **) NULL)
2065 title[MaxTextExtent];
2068 Display information about the image in the Text View widget.
2070 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
2071 (void) FormatLocaleString(title,MaxTextExtent,"Image Info: %s",
2073 XTextViewWidget(display,resource_info,windows,MagickTrue,title,
2074 (char const **) textlist);
2075 for (i=0; textlist[i] != (char *) NULL; i++)
2076 textlist[i]=DestroyString(textlist[i]);
2077 textlist=(char **) RelinquishMagickMemory(textlist);
2079 text=DestroyString(text);
2083 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2087 + X D i t h e r I m a g e %
2091 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2093 % XDitherImage() dithers the reference image as required by the HP Color
2094 % Recovery algorithm. The color values are quantized to 3 bits of red and
2095 % green, and 2 bits of blue (3/3/2) and can be used as indices into a 8-bit X
2096 % standard colormap.
2098 % The format of the XDitherImage method is:
2100 % void XDitherImage(Image *image,XImage *ximage)
2102 % A description of each parameter follows:
2104 % o image: the image.
2106 % o ximage: Specifies a pointer to a XImage structure; returned from
2110 static void XDitherImage(Image *image,XImage *ximage)
2112 static const short int
2115 {-16, 4, -1, 11,-14, 6, -3, 9,-15, 5, -2, 10,-13, 7, -4, 8},
2116 { 15, -5, 0,-12, 13, -7, 2,-10, 14, -6, 1,-11, 12, -8, 3, -9}
2118 dither_green[2][16]=
2120 { 11,-15, 7, -3, 8,-14, 4, -2, 10,-16, 6, -4, 9,-13, 5, -1},
2121 {-12, 14, -8, 2, -9, 13, -5, 1,-11, 15, -7, 3,-10, 12, -6, 0}
2125 { -3, 9,-13, 7, -1, 11,-15, 5, -4, 8,-14, 6, -2, 10,-16, 4},
2126 { 2,-10, 12, -8, 0,-12, 14, -6, 3, -9, 13, -7, 1,-11, 15, -5}
2142 register const Quantum
2162 Allocate and initialize dither maps.
2164 for (i=0; i < 2; i++)
2165 for (j=0; j < 16; j++)
2167 red_map[i][j]=(unsigned char *) AcquireQuantumMemory(256UL,
2169 green_map[i][j]=(unsigned char *) AcquireQuantumMemory(256UL,
2170 sizeof(*green_map));
2171 blue_map[i][j]=(unsigned char *) AcquireQuantumMemory(256UL,
2173 if ((red_map[i][j] == (unsigned char *) NULL) ||
2174 (green_map[i][j] == (unsigned char *) NULL) ||
2175 (blue_map[i][j] == (unsigned char *) NULL))
2177 ThrowXWindowFatalException(ResourceLimitError,
2178 "MemoryAllocationFailed",image->filename);
2183 Initialize dither tables.
2185 for (i=0; i < 2; i++)
2186 for (j=0; j < 16; j++)
2187 for (x=0; x < 256; x++)
2192 value+=dither_red[i][j];
2193 red_map[i][j][x]=(unsigned char)
2194 ((value < 0) ? 0 : (value > 255) ? 255 : value);
2198 value+=dither_green[i][j];
2199 green_map[i][j][x]=(unsigned char)
2200 ((value < 0) ? 0 : (value > 255) ? 255 : value);
2204 value+=((size_t) dither_blue[i][j] << 1);
2205 blue_map[i][j][x]=(unsigned char)
2206 ((value < 0) ? 0 : (value > 255) ? 255 : value);
2211 scanline_pad=(unsigned int) (ximage->bytes_per_line-
2212 ((size_t) (ximage->width*ximage->bits_per_pixel) >> 3));
2216 image_view=AcquireCacheView(image);
2217 for (y=0; y < (int) image->rows; y++)
2219 p=GetCacheViewVirtualPixels(image_view,0,(ssize_t) y,image->columns,1,
2221 if (p == (const Quantum *) NULL)
2223 for (x=0; x < (int) image->columns; x++)
2225 color.red=ClampToQuantum((MagickRealType) (red_map[i][j][(int)
2226 ScaleQuantumToChar(GetPixelRed(image,p))] << 8));
2227 color.green=ClampToQuantum((MagickRealType) (green_map[i][j][(int)
2228 ScaleQuantumToChar(GetPixelGreen(image,p))] << 8));
2229 color.blue=ClampToQuantum((MagickRealType) (blue_map[i][j][(int)
2230 ScaleQuantumToChar(GetPixelBlue(image,p))] << 8));
2231 pixel=(size_t) (((size_t) color.red & 0xe0) |
2232 (((size_t) color.green & 0xe0) >> 3) |
2233 (((size_t) color.blue & 0xc0) >> 6));
2235 p+=GetPixelChannels(image);
2245 image_view=DestroyCacheView(image_view);
2247 Free allocated memory.
2249 for (i=0; i < 2; i++)
2250 for (j=0; j < 16; j++)
2252 green_map[i][j]=(unsigned char *) RelinquishMagickMemory(green_map[i][j]);
2253 blue_map[i][j]=(unsigned char *) RelinquishMagickMemory(blue_map[i][j]);
2254 red_map[i][j]=(unsigned char *) RelinquishMagickMemory(red_map[i][j]);
2259 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2263 % X D r a w I m a g e %
2267 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2269 % XDrawImage() draws a line on the image.
2271 % The format of the XDrawImage method is:
2273 % MagickBooleanType XDrawImage(display,pixel,draw_info,image)
2275 % A description of each parameter follows:
2277 % o display: Specifies a connection to an X server; returned from
2280 % o pixel: Specifies a pointer to a XPixelInfo structure.
2282 % o draw_info: Specifies a pointer to a XDrawInfo structure.
2284 % o image: the image.
2287 MagickPrivate MagickBooleanType XDrawImage(Display *display,
2288 const XPixelInfo *pixel,XDrawInfo *draw_info,Image *image)
2327 Initialize drawd image.
2329 assert(display != (Display *) NULL);
2330 assert(pixel != (XPixelInfo *) NULL);
2331 assert(draw_info != (XDrawInfo *) NULL);
2332 assert(image != (Image *) NULL);
2333 if (image->debug != MagickFalse)
2334 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2336 Initialize drawd pixmap.
2338 root_window=XRootWindow(display,XDefaultScreen(display));
2339 depth=(unsigned int) XDefaultDepth(display,XDefaultScreen(display));
2340 draw_pixmap=XCreatePixmap(display,root_window,draw_info->width,
2341 draw_info->height,depth);
2342 if (draw_pixmap == (Pixmap) NULL)
2343 return(MagickFalse);
2345 Initialize graphics info.
2347 context_values.background=(size_t) (~0);
2348 context_values.foreground=0;
2349 context_values.line_width=(int) draw_info->line_width;
2350 draw_context=XCreateGC(display,root_window,(size_t)
2351 (GCBackground | GCForeground | GCLineWidth),&context_values);
2352 if (draw_context == (GC) NULL)
2353 return(MagickFalse);
2357 (void) XFillRectangle(display,draw_pixmap,draw_context,0,0,draw_info->width,
2360 Draw line to pixmap.
2362 (void) XSetBackground(display,draw_context,0);
2363 (void) XSetForeground(display,draw_context,(size_t) (~0));
2364 if (draw_info->stipple != (Pixmap) NULL)
2366 (void) XSetFillStyle(display,draw_context,FillOpaqueStippled);
2367 (void) XSetStipple(display,draw_context,draw_info->stipple);
2369 switch (draw_info->element)
2374 (void) XDrawLines(display,draw_pixmap,draw_context,
2375 draw_info->coordinate_info,(int) draw_info->number_coordinates,
2381 (void) XDrawLine(display,draw_pixmap,draw_context,draw_info->line_info.x1,
2382 draw_info->line_info.y1,draw_info->line_info.x2,
2383 draw_info->line_info.y2);
2386 case RectangleElement:
2388 (void) XDrawRectangle(display,draw_pixmap,draw_context,
2389 (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y,
2390 (unsigned int) draw_info->rectangle_info.width,
2391 (unsigned int) draw_info->rectangle_info.height);
2394 case FillRectangleElement:
2396 (void) XFillRectangle(display,draw_pixmap,draw_context,
2397 (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y,
2398 (unsigned int) draw_info->rectangle_info.width,
2399 (unsigned int) draw_info->rectangle_info.height);
2403 case EllipseElement:
2405 (void) XDrawArc(display,draw_pixmap,draw_context,
2406 (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y,
2407 (unsigned int) draw_info->rectangle_info.width,
2408 (unsigned int) draw_info->rectangle_info.height,0,360*64);
2411 case FillCircleElement:
2412 case FillEllipseElement:
2414 (void) XFillArc(display,draw_pixmap,draw_context,
2415 (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y,
2416 (unsigned int) draw_info->rectangle_info.width,
2417 (unsigned int) draw_info->rectangle_info.height,0,360*64);
2420 case PolygonElement:
2425 coordinate_info=draw_info->coordinate_info;
2426 (void) XDrawLines(display,draw_pixmap,draw_context,coordinate_info,
2427 (int) draw_info->number_coordinates,CoordModeOrigin);
2428 (void) XDrawLine(display,draw_pixmap,draw_context,
2429 coordinate_info[draw_info->number_coordinates-1].x,
2430 coordinate_info[draw_info->number_coordinates-1].y,
2431 coordinate_info[0].x,coordinate_info[0].y);
2434 case FillPolygonElement:
2436 (void) XFillPolygon(display,draw_pixmap,draw_context,
2437 draw_info->coordinate_info,(int) draw_info->number_coordinates,Complex,
2442 (void) XFreeGC(display,draw_context);
2446 draw_ximage=XGetImage(display,draw_pixmap,0,0,draw_info->width,
2447 draw_info->height,AllPlanes,ZPixmap);
2448 if (draw_ximage == (XImage *) NULL)
2449 return(MagickFalse);
2450 (void) XFreePixmap(display,draw_pixmap);
2452 Initialize draw image.
2454 draw_image=AcquireImage((ImageInfo *) NULL);
2455 if (draw_image == (Image *) NULL)
2456 return(MagickFalse);
2457 draw_image->columns=draw_info->width;
2458 draw_image->rows=draw_info->height;
2460 Transfer drawn X image to image.
2462 width=(unsigned int) image->columns;
2463 height=(unsigned int) image->rows;
2466 (void) XParseGeometry(draw_info->geometry,&x,&y,&width,&height);
2467 (void) GetOneVirtualPixel(image,(ssize_t) x,(ssize_t) y,
2468 &draw_image->background_color,&image->exception);
2469 if (SetImageStorageClass(draw_image,DirectClass,&image->exception) == MagickFalse)
2470 return(MagickFalse);
2471 draw_image->matte=MagickTrue;
2472 exception=(&image->exception);
2473 draw_view=AcquireCacheView(draw_image);
2474 for (y=0; y < (int) draw_image->rows; y++)
2482 q=QueueCacheViewAuthenticPixels(draw_view,0,(ssize_t) y,draw_image->columns,
2484 if (q == (Quantum *) NULL)
2486 for (x=0; x < (int) draw_image->columns; x++)
2488 if (XGetPixel(draw_ximage,x,y) == 0)
2491 Set this pixel to the background color.
2493 SetPixelPacket(draw_image,&draw_image->background_color,q);
2494 SetPixelAlpha(draw_image,(Quantum) (draw_info->stencil ==
2495 OpaqueStencil ? TransparentAlpha : OpaqueAlpha),q);
2500 Set this pixel to the pen color.
2502 SetPixelRed(draw_image,ScaleShortToQuantum(
2503 pixel->pen_color.red),q);
2504 SetPixelGreen(draw_image,ScaleShortToQuantum(
2505 pixel->pen_color.green),q);
2506 SetPixelBlue(draw_image,ScaleShortToQuantum(
2507 pixel->pen_color.blue),q);
2508 SetPixelAlpha(draw_image,(Quantum) (draw_info->stencil ==
2509 OpaqueStencil ? OpaqueAlpha : TransparentAlpha),q);
2511 q+=GetPixelChannels(draw_image);
2513 if (SyncCacheViewAuthenticPixels(draw_view,exception) == MagickFalse)
2516 draw_view=DestroyCacheView(draw_view);
2517 XDestroyImage(draw_ximage);
2519 Determine draw geometry.
2521 (void) XParseGeometry(draw_info->geometry,&x,&y,&width,&height);
2522 if ((width != (unsigned int) draw_image->columns) ||
2523 (height != (unsigned int) draw_image->rows))
2526 image_geometry[MaxTextExtent];
2531 (void) FormatLocaleString(image_geometry,MaxTextExtent,"%ux%u",
2533 (void) TransformImage(&draw_image,(char *) NULL,image_geometry);
2535 if (draw_info->degrees != 0.0)
2549 rotate_image=RotateImage(draw_image,draw_info->degrees,&image->exception);
2550 if (rotate_image == (Image *) NULL)
2551 return(MagickFalse);
2552 draw_image=DestroyImage(draw_image);
2553 draw_image=rotate_image;
2555 Annotation is relative to the degree of rotation.
2557 normalized_degrees=draw_info->degrees;
2558 while (normalized_degrees < -45.0)
2559 normalized_degrees+=360.0;
2560 for (rotations=0; normalized_degrees > 45.0; rotations++)
2561 normalized_degrees-=90.0;
2562 switch (rotations % 4)
2572 x=x-(int) draw_image->columns/2;
2573 y=y+(int) draw_image->columns/2;
2581 x=x-(int) draw_image->columns;
2589 x=x-(int) draw_image->columns/2;
2590 y=y-(int) (draw_image->rows-(draw_image->columns/2));
2596 Composite text onto the image.
2598 draw_view=AcquireCacheView(draw_image);
2599 for (y=0; y < (int) draw_image->rows; y++)
2607 q=GetCacheViewAuthenticPixels(draw_view,0,(ssize_t) y,draw_image->columns,1,
2609 if (q == (Quantum *) NULL)
2611 for (x=0; x < (int) draw_image->columns; x++)
2613 if (GetPixelAlpha(image,q) != TransparentAlpha)
2614 SetPixelAlpha(draw_image,OpaqueAlpha,q);
2615 q+=GetPixelChannels(draw_image);
2617 if (SyncCacheViewAuthenticPixels(draw_view,exception) == MagickFalse)
2620 draw_view=DestroyCacheView(draw_view);
2621 (void) XParseGeometry(draw_info->geometry,&x,&y,&width,&height);
2622 if (draw_info->stencil == TransparentStencil)
2623 (void) CompositeImage(image,CopyOpacityCompositeOp,draw_image,(ssize_t) x,
2628 (void) CompositeImage(image,OverCompositeOp,draw_image,(ssize_t) x,
2632 draw_image=DestroyImage(draw_image);
2637 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2645 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2647 % XError() ignores BadWindow errors for XQueryTree and XGetWindowAttributes,
2648 % and ignores BadDrawable errors for XGetGeometry, and ignores BadValue errors
2649 % for XQueryColor. It returns MagickFalse in those cases. Otherwise it
2652 % The format of the XError function is:
2654 % int XError(display,error)
2656 % A description of each parameter follows:
2658 % o display: Specifies a pointer to the Display structure; returned from
2661 % o error: Specifies the error event.
2665 #if defined(__cplusplus) || defined(c_plusplus)
2669 MagickExport int XError(Display *display,XErrorEvent *error)
2671 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2672 assert(display != (Display *) NULL);
2673 assert(error != (XErrorEvent *) NULL);
2674 xerror_alert=MagickTrue;
2675 switch (error->request_code)
2679 if ((int) error->error_code == BadDrawable)
2680 return(MagickFalse);
2683 case X_GetWindowAttributes:
2686 if ((int) error->error_code == BadWindow)
2687 return(MagickFalse);
2692 if ((int) error->error_code == BadValue)
2693 return(MagickFalse);
2700 #if defined(__cplusplus) || defined(c_plusplus)
2705 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2709 % X F r e e R e s o u r c e s %
2713 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2715 % XFreeResources() frees X11 resources.
2717 % The format of the XFreeResources method is:
2719 % void XFreeResources(Display *display,XVisualInfo *visual_info,
2720 % XStandardColormap *map_info,XPixelInfo *pixel,XFontStruct *font_info,
2721 % XResourceInfo *resource_info,XWindowInfo *window_info)
2722 % resource_info,window_info)
2724 % A description of each parameter follows:
2726 % o display: Specifies a connection to an X server; returned from
2729 % o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
2730 % returned from XGetVisualInfo.
2732 % o map_info: If map_type is specified, this structure is initialized
2733 % with info from the Standard Colormap.
2735 % o pixel: Specifies a pointer to a XPixelInfo structure.
2737 % o font_info: Specifies a pointer to a XFontStruct structure.
2739 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
2741 % o window_info: Specifies a pointer to a X11 XWindowInfo structure.
2744 MagickPrivate void XFreeResources(Display *display,XVisualInfo *visual_info,
2745 XStandardColormap *map_info,XPixelInfo *pixel,XFontStruct *font_info,
2746 XResourceInfo *resource_info,XWindowInfo *window_info)
2748 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2749 assert(display != (Display *) NULL);
2750 assert(resource_info != (XResourceInfo *) NULL);
2751 if (window_info != (XWindowInfo *) NULL)
2756 if (window_info->ximage != (XImage *) NULL)
2757 XDestroyImage(window_info->ximage);
2758 if (window_info->id != (Window) NULL)
2761 Free destroy window and free cursors.
2763 if (window_info->id != XRootWindow(display,visual_info->screen))
2764 (void) XDestroyWindow(display,window_info->id);
2765 if (window_info->annotate_context != (GC) NULL)
2766 (void) XFreeGC(display,window_info->annotate_context);
2767 if (window_info->highlight_context != (GC) NULL)
2768 (void) XFreeGC(display,window_info->highlight_context);
2769 if (window_info->widget_context != (GC) NULL)
2770 (void) XFreeGC(display,window_info->widget_context);
2771 if (window_info->cursor != (Cursor) NULL)
2772 (void) XFreeCursor(display,window_info->cursor);
2773 window_info->cursor=(Cursor) NULL;
2774 if (window_info->busy_cursor != (Cursor) NULL)
2775 (void) XFreeCursor(display,window_info->busy_cursor);
2776 window_info->busy_cursor=(Cursor) NULL;
2782 if (font_info != (XFontStruct *) NULL)
2784 (void) XFreeFont(display,font_info);
2785 font_info=(XFontStruct *) NULL;
2787 if (map_info != (XStandardColormap *) NULL)
2790 Free X Standard Colormap.
2792 if (resource_info->map_type == (char *) NULL)
2793 (void) XFreeStandardColormap(display,visual_info,map_info,pixel);
2794 (void) XFree((void *) map_info);
2799 if (visual_info != (XVisualInfo *) NULL)
2800 (void) XFree((void *) visual_info);
2801 if (resource_info->close_server != MagickFalse)
2802 (void) XCloseDisplay(display);
2806 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2810 % X F r e e S t a n d a r d C o l o r m a p %
2814 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2816 % XFreeStandardColormap() frees an X11 colormap.
2818 % The format of the XFreeStandardColormap method is:
2820 % void XFreeStandardColormap(Display *display,
2821 % const XVisualInfo *visual_info,XStandardColormap *map_info,
2822 % XPixelInfo *pixel)
2824 % A description of each parameter follows:
2826 % o display: Specifies a connection to an X server; returned from
2829 % o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
2830 % returned from XGetVisualInfo.
2832 % o map_info: If map_type is specified, this structure is initialized
2833 % with info from the Standard Colormap.
2835 % o pixel: Specifies a pointer to a XPixelInfo structure.
2838 MagickPrivate void XFreeStandardColormap(Display *display,
2839 const XVisualInfo *visual_info,XStandardColormap *map_info,XPixelInfo *pixel)
2844 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2845 assert(display != (Display *) NULL);
2846 assert(visual_info != (XVisualInfo *) NULL);
2847 assert(map_info != (XStandardColormap *) NULL);
2848 (void) XFlush(display);
2849 if (map_info->colormap != (Colormap) NULL)
2851 if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
2852 (void) XFreeColormap(display,map_info->colormap);
2854 if (pixel != (XPixelInfo *) NULL)
2855 if ((visual_info->klass != TrueColor) &&
2856 (visual_info->klass != DirectColor))
2857 (void) XFreeColors(display,map_info->colormap,pixel->pixels,
2858 (int) pixel->colors,0);
2860 map_info->colormap=(Colormap) NULL;
2861 if (pixel != (XPixelInfo *) NULL)
2863 if (pixel->pixels != (unsigned long *) NULL)
2864 pixel->pixels=(unsigned long *) RelinquishMagickMemory(pixel->pixels);
2865 pixel->pixels=(unsigned long *) NULL;
2870 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2874 % X G e t A n n o t a t e I n f o %
2878 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2880 % XGetAnnotateInfo() initializes the AnnotateInfo structure.
2882 % The format of the XGetAnnotateInfo method is:
2884 % void XGetAnnotateInfo(XAnnotateInfo *annotate_info)
2886 % A description of each parameter follows:
2888 % o annotate_info: Specifies a pointer to a XAnnotateInfo structure.
2891 MagickPrivate void XGetAnnotateInfo(XAnnotateInfo *annotate_info)
2894 Initialize annotate structure.
2896 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2897 assert(annotate_info != (XAnnotateInfo *) NULL);
2900 annotate_info->width=0;
2901 annotate_info->height=0;
2902 annotate_info->stencil=ForegroundStencil;
2903 annotate_info->degrees=0.0;
2904 annotate_info->font_info=(XFontStruct *) NULL;
2905 annotate_info->text=(char *) NULL;
2906 *annotate_info->geometry='\0';
2907 annotate_info->previous=(XAnnotateInfo *) NULL;
2908 annotate_info->next=(XAnnotateInfo *) NULL;
2909 (void) XSupportsLocale();
2910 (void) XSetLocaleModifiers("");
2914 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2918 % X G e t M a p I n f o %
2922 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2924 % XGetMapInfo() initializes the XStandardColormap structure.
2926 % The format of the XStandardColormap method is:
2928 % void XGetMapInfo(const XVisualInfo *visual_info,const Colormap colormap,
2929 % XStandardColormap *map_info)
2931 % A description of each parameter follows:
2933 % o colormap: Specifies the ID of the X server colormap.
2935 % o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
2936 % returned from XGetVisualInfo.
2938 % o map_info: Specifies a pointer to a X11 XStandardColormap structure.
2941 MagickPrivate void XGetMapInfo(const XVisualInfo *visual_info,
2942 const Colormap colormap,XStandardColormap *map_info)
2945 Initialize map info.
2947 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2948 assert(visual_info != (XVisualInfo *) NULL);
2949 assert(map_info != (XStandardColormap *) NULL);
2950 map_info->colormap=colormap;
2951 map_info->red_max=visual_info->red_mask;
2952 map_info->red_mult=(size_t) (map_info->red_max != 0 ? 1 : 0);
2953 if (map_info->red_max != 0)
2954 while ((map_info->red_max & 0x01) == 0)
2956 map_info->red_max>>=1;
2957 map_info->red_mult<<=1;
2959 map_info->green_max=visual_info->green_mask;
2960 map_info->green_mult=(size_t) (map_info->green_max != 0 ? 1 : 0);
2961 if (map_info->green_max != 0)
2962 while ((map_info->green_max & 0x01) == 0)
2964 map_info->green_max>>=1;
2965 map_info->green_mult<<=1;
2967 map_info->blue_max=visual_info->blue_mask;
2968 map_info->blue_mult=(size_t) (map_info->blue_max != 0 ? 1 : 0);
2969 if (map_info->blue_max != 0)
2970 while ((map_info->blue_max & 0x01) == 0)
2972 map_info->blue_max>>=1;
2973 map_info->blue_mult<<=1;
2975 map_info->base_pixel=0;
2979 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2983 % X G e t P i x e l I n f o %
2987 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2989 % XGetPixelInfo() initializes the PixelPacket structure.
2991 % The format of the XGetPixelInfo method is:
2993 % void XGetPixelInfo(Display *display,const XVisualInfo *visual_info,
2994 % const XStandardColormap *map_info,const XResourceInfo *resource_info,
2995 % Image *image,XPixelInfo *pixel)
2998 % A description of each parameter follows:
3000 % o display: Specifies a connection to an X server; returned from
3003 % o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
3004 % returned from XGetVisualInfo.
3006 % o map_info: If map_type is specified, this structure is initialized
3007 % with info from the Standard Colormap.
3009 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
3011 % o image: the image.
3013 % o pixel: Specifies a pointer to a XPixelInfo structure.
3016 MagickPrivate void XGetPixelInfo(Display *display,
3017 const XVisualInfo *visual_info,const XStandardColormap *map_info,
3018 const XResourceInfo *resource_info,Image *image,XPixelInfo *pixel)
3021 *PenColors[MaxNumberPens]=
3023 "#000000000000", /* black */
3024 "#00000000ffff", /* blue */
3025 "#0000ffffffff", /* cyan */
3026 "#0000ffff0000", /* green */
3027 "#bdbdbdbdbdbd", /* gray */
3028 "#ffff00000000", /* red */
3029 "#ffff0000ffff", /* magenta */
3030 "#ffffffff0000", /* yellow */
3031 "#ffffffffffff", /* white */
3032 "#bdbdbdbdbdbd", /* gray */
3033 "#bdbdbdbdbdbd" /* gray */
3049 Initialize pixel info.
3051 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3052 assert(display != (Display *) NULL);
3053 assert(visual_info != (XVisualInfo *) NULL);
3054 assert(map_info != (XStandardColormap *) NULL);
3055 assert(resource_info != (XResourceInfo *) NULL);
3056 assert(pixel != (XPixelInfo *) NULL);
3058 if (image != (Image *) NULL)
3059 if (image->storage_class == PseudoClass)
3060 pixel->colors=(ssize_t) image->colors;
3061 packets=(unsigned int)
3062 MagickMax((int) pixel->colors,visual_info->colormap_size)+MaxNumberPens;
3063 if (pixel->pixels != (unsigned long *) NULL)
3064 pixel->pixels=(unsigned long *) RelinquishMagickMemory(pixel->pixels);
3065 pixel->pixels=(unsigned long *) AcquireQuantumMemory(packets,
3066 sizeof(pixel->pixels));
3067 if (pixel->pixels == (unsigned long *) NULL)
3068 ThrowXWindowFatalException(ResourceLimitFatalError,"UnableToGetPixelInfo",
3071 Set foreground color.
3073 colormap=map_info->colormap;
3074 (void) XParseColor(display,colormap,(char *) ForegroundColor,
3075 &pixel->foreground_color);
3076 status=XParseColor(display,colormap,resource_info->foreground_color,
3077 &pixel->foreground_color);
3078 if (status == False)
3079 ThrowXWindowFatalException(XServerError,"ColorIsNotKnownToServer",
3080 resource_info->foreground_color);
3081 pixel->foreground_color.pixel=
3082 XStandardPixel(map_info,&pixel->foreground_color);
3083 pixel->foreground_color.flags=(char) (DoRed | DoGreen | DoBlue);
3085 Set background color.
3087 (void) XParseColor(display,colormap,"#d6d6d6d6d6d6",&pixel->background_color);
3088 status=XParseColor(display,colormap,resource_info->background_color,
3089 &pixel->background_color);
3090 if (status == False)
3091 ThrowXWindowFatalException(XServerError,"ColorIsNotKnownToServer",
3092 resource_info->background_color);
3093 pixel->background_color.pixel=
3094 XStandardPixel(map_info,&pixel->background_color);
3095 pixel->background_color.flags=(char) (DoRed | DoGreen | DoBlue);
3099 (void) XParseColor(display,colormap,(char *) BorderColor,
3100 &pixel->border_color);
3101 status=XParseColor(display,colormap,resource_info->border_color,
3102 &pixel->border_color);
3103 if (status == False)
3104 ThrowXWindowFatalException(XServerError,"ColorIsNotKnownToServer",
3105 resource_info->border_color);
3106 pixel->border_color.pixel=XStandardPixel(map_info,&pixel->border_color);
3107 pixel->border_color.flags=(char) (DoRed | DoGreen | DoBlue);
3111 pixel->matte_color=pixel->background_color;
3112 if (resource_info->matte_color != (char *) NULL)
3115 Matte color is specified as a X resource or command line argument.
3117 status=XParseColor(display,colormap,resource_info->matte_color,
3118 &pixel->matte_color);
3119 if (status == False)
3120 ThrowXWindowFatalException(XServerError,"ColorIsNotKnownToServer",
3121 resource_info->matte_color);
3122 pixel->matte_color.pixel=XStandardPixel(map_info,&pixel->matte_color);
3123 pixel->matte_color.flags=(char) (DoRed | DoGreen | DoBlue);
3126 Set highlight color.
3128 pixel->highlight_color.red=(unsigned short) ((
3129 pixel->matte_color.red*ScaleQuantumToShort(HighlightModulate))/65535L+
3130 (ScaleQuantumToShort((Quantum) (QuantumRange-HighlightModulate))));
3131 pixel->highlight_color.green=(unsigned short) ((
3132 pixel->matte_color.green*ScaleQuantumToShort(HighlightModulate))/65535L+
3133 (ScaleQuantumToShort((Quantum) (QuantumRange-HighlightModulate))));
3134 pixel->highlight_color.blue=(unsigned short) ((
3135 pixel->matte_color.blue*ScaleQuantumToShort(HighlightModulate))/65535L+
3136 (ScaleQuantumToShort((Quantum) (QuantumRange-HighlightModulate))));
3137 pixel->highlight_color.pixel=
3138 XStandardPixel(map_info,&pixel->highlight_color);
3139 pixel->highlight_color.flags=(char) (DoRed | DoGreen | DoBlue);
3143 pixel->shadow_color.red=(unsigned short) (((MagickRealType)
3144 pixel->matte_color.red*ScaleQuantumToShort(ShadowModulate))/65535L);
3145 pixel->shadow_color.green=(unsigned short) (((MagickRealType)
3146 pixel->matte_color.green*ScaleQuantumToShort(ShadowModulate))/65535L);
3147 pixel->shadow_color.blue=(unsigned short) (((MagickRealType)
3148 pixel->matte_color.blue*ScaleQuantumToShort(ShadowModulate))/65535L);
3149 pixel->shadow_color.pixel=XStandardPixel(map_info,&pixel->shadow_color);
3150 pixel->shadow_color.flags=(char) (DoRed | DoGreen | DoBlue);
3154 pixel->depth_color.red=(unsigned short) (((MagickRealType)
3155 pixel->matte_color.red*ScaleQuantumToShort(DepthModulate))/65535L);
3156 pixel->depth_color.green=(unsigned short) (((MagickRealType)
3157 pixel->matte_color.green*ScaleQuantumToShort(DepthModulate))/65535L);
3158 pixel->depth_color.blue=(unsigned short) (((MagickRealType)
3159 pixel->matte_color.blue*ScaleQuantumToShort(DepthModulate))/65535L);
3160 pixel->depth_color.pixel=XStandardPixel(map_info,&pixel->depth_color);
3161 pixel->depth_color.flags=(char) (DoRed | DoGreen | DoBlue);
3165 pixel->trough_color.red=(unsigned short) (((MagickRealType)
3166 pixel->matte_color.red*ScaleQuantumToShort(TroughModulate))/65535L);
3167 pixel->trough_color.green=(unsigned short) (((MagickRealType)
3168 pixel->matte_color.green*ScaleQuantumToShort(TroughModulate))/65535L);
3169 pixel->trough_color.blue=(unsigned short) (((MagickRealType)
3170 pixel->matte_color.blue*ScaleQuantumToShort(TroughModulate))/65535L);
3171 pixel->trough_color.pixel=XStandardPixel(map_info,&pixel->trough_color);
3172 pixel->trough_color.flags=(char) (DoRed | DoGreen | DoBlue);
3176 for (i=0; i < MaxNumberPens; i++)
3178 (void) XParseColor(display,colormap,(char *) PenColors[i],
3179 &pixel->pen_colors[i]);
3180 status=XParseColor(display,colormap,resource_info->pen_colors[i],
3181 &pixel->pen_colors[i]);
3182 if (status == False)
3183 ThrowXWindowFatalException(XServerError,"ColorIsNotKnownToServer",
3184 resource_info->pen_colors[i]);
3185 pixel->pen_colors[i].pixel=XStandardPixel(map_info,&pixel->pen_colors[i]);
3186 pixel->pen_colors[i].flags=(char) (DoRed | DoGreen | DoBlue);
3188 pixel->box_color=pixel->background_color;
3189 pixel->pen_color=pixel->foreground_color;
3192 if (image != (Image *) NULL)
3194 if ((resource_info->gamma_correct != MagickFalse) &&
3195 (image->gamma != 0.0))
3204 Initialize map relative to display and image gamma.
3206 flags=ParseGeometry(resource_info->display_gamma,&geometry_info);
3207 red_gamma=geometry_info.rho;
3208 green_gamma=geometry_info.sigma;
3209 if ((flags & SigmaValue) == 0)
3210 green_gamma=red_gamma;
3211 blue_gamma=geometry_info.xi;
3212 if ((flags & XiValue) == 0)
3213 blue_gamma=red_gamma;
3214 red_gamma*=image->gamma;
3215 green_gamma*=image->gamma;
3216 blue_gamma*=image->gamma;
3218 if (image->storage_class == PseudoClass)
3221 Initialize pixel array for images of type PseudoClass.
3223 for (i=0; i < (ssize_t) image->colors; i++)
3224 pixel->pixels[i]=XGammaPacket(map_info,image->colormap+i);
3225 for (i=0; i < MaxNumberPens; i++)
3226 pixel->pixels[image->colors+i]=pixel->pen_colors[i].pixel;
3227 pixel->colors+=MaxNumberPens;
3233 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3237 % X G e t R e s o u r c e C l a s s %
3241 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3243 % XGetResourceClass() queries the X server for the specified resource name or
3244 % class. If the resource name or class is not defined in the database, the
3245 % supplied default value is returned.
3247 % The format of the XGetResourceClass method is:
3249 % char *XGetResourceClass(XrmDatabase database,const char *client_name,
3250 % const char *keyword,char *resource_default)
3252 % A description of each parameter follows:
3254 % o database: Specifies a resource database; returned from
3255 % XrmGetStringDatabase.
3257 % o client_name: Specifies the application name used to retrieve resource
3258 % info from the X server database.
3260 % o keyword: Specifies the keyword of the value being retrieved.
3262 % o resource_default: Specifies the default value to return if the query
3263 % fails to find the specified keyword/class.
3266 MagickExport char *XGetResourceClass(XrmDatabase database,
3267 const char *client_name,const char *keyword,char *resource_default)
3270 resource_class[MaxTextExtent],
3271 resource_name[MaxTextExtent];
3282 if (database == (XrmDatabase) NULL)
3283 return(resource_default);
3284 *resource_name='\0';
3285 *resource_class='\0';
3286 if (keyword != (char *) NULL)
3293 Initialize resource keyword and class.
3295 (void) FormatLocaleString(resource_name,MaxTextExtent,"%s.%s",
3296 client_name,keyword);
3297 c=(int) (*client_name);
3298 if ((c >= XK_a) && (c <= XK_z))
3301 if ((c >= XK_agrave) && (c <= XK_odiaeresis))
3302 c-=(XK_agrave-XK_Agrave);
3304 if ((c >= XK_oslash) && (c <= XK_thorn))
3305 c-=(XK_oslash-XK_Ooblique);
3307 if ((k >= XK_a) && (k <= XK_z))
3310 if ((k >= XK_agrave) && (k <= XK_odiaeresis))
3311 k-=(XK_agrave-XK_Agrave);
3313 if ((k >= XK_oslash) && (k <= XK_thorn))
3314 k-=(XK_oslash-XK_Ooblique);
3315 (void) FormatLocaleString(resource_class,MaxTextExtent,"%c%s.%c%s",c,
3316 client_name+1,k,keyword+1);
3318 status=XrmGetResource(database,resource_name,resource_class,&resource_type,
3320 if (status == False)
3321 return(resource_default);
3322 return(resource_value.addr);
3326 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3330 % X G e t R e s o u r c e D a t a b a s e %
3334 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3336 % XGetResourceDatabase() creates a new resource database and initializes it.
3338 % The format of the XGetResourceDatabase method is:
3340 % XrmDatabase XGetResourceDatabase(Display *display,
3341 % const char *client_name)
3343 % A description of each parameter follows:
3345 % o database: XGetResourceDatabase() returns the database after it is
3348 % o display: Specifies a connection to an X server; returned from
3351 % o client_name: Specifies the application name used to retrieve resource
3352 % info from the X server database.
3355 MagickExport XrmDatabase XGetResourceDatabase(Display *display,
3356 const char *client_name)
3359 filename[MaxTextExtent];
3371 if (display == (Display *) NULL)
3372 return((XrmDatabase) NULL);
3373 assert(client_name != (char *) NULL);
3375 Initialize resource database.
3378 (void) XGetDefault(display,(char *) client_name,"dummy");
3379 resource_database=XrmGetDatabase(display);
3381 Combine application database.
3383 if (client_name != (char *) NULL)
3386 Get basename of client.
3388 p=client_name+(strlen(client_name)-1);
3389 while ((p > client_name) && (*p != '/'))
3394 c=(int) (*client_name);
3395 if ((c >= XK_a) && (c <= XK_z))
3398 if ((c >= XK_agrave) && (c <= XK_odiaeresis))
3399 c-=(XK_agrave-XK_Agrave);
3401 if ((c >= XK_oslash) && (c <= XK_thorn))
3402 c-=(XK_oslash-XK_Ooblique);
3403 #if defined(X11_APPLICATION_PATH)
3404 (void) FormatLocaleString(filename,MaxTextExtent,"%s%c%s",
3405 X11_APPLICATION_PATH,c,client_name+1);
3406 (void) XrmCombineFileDatabase(filename,&resource_database,MagickFalse);
3408 if (XResourceManagerString(display) != (char *) NULL)
3411 Combine server database.
3413 server_database=XrmGetStringDatabase(XResourceManagerString(display));
3414 XrmCombineDatabase(server_database,&resource_database,MagickFalse);
3417 Merge user preferences database.
3419 #if defined(X11_PREFERENCES_PATH)
3420 (void) FormatLocaleString(filename,MaxTextExtent,"%s%src",
3421 X11_PREFERENCES_PATH,client_name);
3422 ExpandFilename(filename);
3423 (void) XrmCombineFileDatabase(filename,&resource_database,MagickFalse);
3425 return(resource_database);
3429 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3433 % X G e t R e s o u r c e I n f o %
3437 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3439 % XGetResourceInfo(image_info,) initializes the ResourceInfo structure.
3441 % The format of the XGetResourceInfo method is:
3443 % void XGetResourceInfo(const ImageInfo *image_info,XrmDatabase database,
3444 % const char *client_name,XResourceInfo *resource_info)
3446 % A description of each parameter follows:
3448 % o image_info: the image info.
3450 % o database: Specifies a resource database; returned from
3451 % XrmGetStringDatabase.
3453 % o client_name: Specifies the application name used to retrieve
3454 % resource info from the X server database.
3456 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
3459 MagickExport void XGetResourceInfo(const ImageInfo *image_info,
3460 XrmDatabase database,const char *client_name,XResourceInfo *resource_info)
3467 Initialize resource info fields.
3469 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3470 assert(resource_info != (XResourceInfo *) NULL);
3471 (void) ResetMagickMemory(resource_info,0,sizeof(*resource_info));
3472 resource_info->resource_database=database;
3473 resource_info->image_info=(ImageInfo *) image_info;
3474 (void) SetImageInfoProgressMonitor(resource_info->image_info,
3475 XMagickProgressMonitor,(void *) NULL);
3476 resource_info->quantize_info=CloneQuantizeInfo((QuantizeInfo *) NULL);
3477 resource_info->close_server=MagickTrue;
3478 resource_info->client_name=AcquireString(client_name);
3479 resource_value=XGetResourceClass(database,client_name,"backdrop",
3481 resource_info->backdrop=IsMagickTrue(resource_value);
3482 resource_info->background_color=XGetResourceInstance(database,client_name,
3483 "background",(char *) "#d6d6d6d6d6d6");
3484 resource_info->border_color=XGetResourceInstance(database,client_name,
3485 "borderColor",BorderColor);
3486 resource_value=XGetResourceClass(database,client_name,"borderWidth",
3488 resource_info->border_width=(unsigned int) StringToUnsignedLong(
3490 resource_value=XGetResourceClass(database,client_name,"colormap",
3492 resource_info->colormap=UndefinedColormap;
3493 if (LocaleCompare("private",resource_value) == 0)
3494 resource_info->colormap=PrivateColormap;
3495 if (LocaleCompare("shared",resource_value) == 0)
3496 resource_info->colormap=SharedColormap;
3497 if (resource_info->colormap == UndefinedColormap)
3498 ThrowXWindowFatalException(OptionError,"UnrecognizedColormapType",
3500 resource_value=XGetResourceClass(database,client_name,
3501 "colorRecovery",(char *) "False");
3502 resource_info->color_recovery=IsMagickTrue(resource_value);
3503 resource_value=XGetResourceClass(database,client_name,"confirmExit",
3505 resource_info->confirm_exit=IsMagickTrue(resource_value);
3506 resource_value=XGetResourceClass(database,client_name,"confirmEdit",
3508 resource_info->confirm_edit=IsMagickTrue(resource_value);
3509 resource_value=XGetResourceClass(database,client_name,"delay",(char *) "1");
3510 resource_info->delay=(unsigned int) StringToUnsignedLong(resource_value);
3511 resource_info->display_gamma=XGetResourceClass(database,client_name,
3512 "displayGamma",(char *) "2.2");
3513 resource_value=XGetResourceClass(database,client_name,"displayWarnings",
3515 resource_info->display_warnings=IsMagickTrue(resource_value);
3516 resource_info->font=XGetResourceClass(database,client_name,"font",
3518 resource_info->font=XGetResourceClass(database,client_name,"fontList",
3519 resource_info->font);
3520 resource_info->font_name[0]=XGetResourceClass(database,client_name,"font1",
3522 resource_info->font_name[1]=XGetResourceClass(database,client_name,"font2",
3523 (char *) "variable");
3524 resource_info->font_name[2]=XGetResourceClass(database,client_name,"font3",
3526 resource_info->font_name[3]=XGetResourceClass(database,client_name,"font4",
3528 resource_info->font_name[4]=XGetResourceClass(database,client_name,"font5",
3529 (char *) "7x13bold");
3530 resource_info->font_name[5]=XGetResourceClass(database,client_name,"font6",
3531 (char *) "8x13bold");
3532 resource_info->font_name[6]=XGetResourceClass(database,client_name,"font7",
3533 (char *) "9x15bold");
3534 resource_info->font_name[7]=XGetResourceClass(database,client_name,"font8",
3536 resource_info->font_name[8]=XGetResourceClass(database,client_name,"font9",
3538 resource_info->font_name[9]=XGetResourceClass(database,client_name,"font0",
3540 resource_info->font_name[10]=XGetResourceClass(database,client_name,"font0",
3542 resource_info->foreground_color=XGetResourceInstance(database,client_name,
3543 "foreground",ForegroundColor);
3544 resource_value=XGetResourceClass(database,client_name,"gammaCorrect",
3546 resource_info->gamma_correct=IsMagickTrue(resource_value);
3547 resource_info->image_geometry=ConstantString(XGetResourceClass(database,
3548 client_name,"geometry",(char *) NULL));
3549 resource_value=XGetResourceClass(database,client_name,"gravity",
3551 resource_info->gravity=(GravityType) ParseCommandOption(MagickGravityOptions,
3552 MagickFalse,resource_value);
3553 directory=getcwd(resource_info->home_directory,MaxTextExtent);
3555 resource_info->icon_geometry=XGetResourceClass(database,client_name,
3556 "iconGeometry",(char *) NULL);
3557 resource_value=XGetResourceClass(database,client_name,"iconic",
3559 resource_info->iconic=IsMagickTrue(resource_value);
3560 resource_value=XGetResourceClass(database,client_name,"immutable",
3561 LocaleCompare(client_name,"PerlMagick") == 0 ? (char *) "True" :
3563 resource_info->immutable=IsMagickTrue(resource_value);
3564 resource_value=XGetResourceClass(database,client_name,"magnify",
3566 resource_info->magnify=(unsigned int) StringToUnsignedLong(resource_value);
3567 resource_info->map_type=XGetResourceClass(database,client_name,"map",
3569 resource_info->matte_color=XGetResourceInstance(database,client_name,
3570 "mattecolor",(char *) NULL);
3571 resource_info->name=ConstantString(XGetResourceClass(database,client_name,
3572 "name",(char *) NULL));
3573 resource_info->pen_colors[0]=XGetResourceClass(database,client_name,"pen1",
3575 resource_info->pen_colors[1]=XGetResourceClass(database,client_name,"pen2",
3577 resource_info->pen_colors[2]=XGetResourceClass(database,client_name,"pen3",
3579 resource_info->pen_colors[3]=XGetResourceClass(database,client_name,"pen4",
3581 resource_info->pen_colors[4]=XGetResourceClass(database,client_name,"pen5",
3583 resource_info->pen_colors[5]=XGetResourceClass(database,client_name,"pen6",
3585 resource_info->pen_colors[6]=XGetResourceClass(database,client_name,"pen7",
3586 (char *) "magenta");
3587 resource_info->pen_colors[7]=XGetResourceClass(database,client_name,"pen8",
3589 resource_info->pen_colors[8]=XGetResourceClass(database,client_name,"pen9",
3591 resource_info->pen_colors[9]=XGetResourceClass(database,client_name,"pen0",
3593 resource_info->pen_colors[10]=XGetResourceClass(database,client_name,"pen0",
3595 resource_value=XGetResourceClass(database,client_name,"pause",(char *) "0");
3596 resource_info->pause=(unsigned int) StringToUnsignedLong(resource_value);
3597 resource_value=XGetResourceClass(database,client_name,"quantum",(char *) "1");
3598 resource_info->quantum=StringToLong(resource_value);
3599 resource_info->text_font=XGetResourceClass(database,client_name,(char *)
3600 "font",(char *) "fixed");
3601 resource_info->text_font=XGetResourceClass(database,client_name,
3602 "textFontList",resource_info->text_font);
3603 resource_info->title=XGetResourceClass(database,client_name,"title",
3605 resource_value=XGetResourceClass(database,client_name,"undoCache",
3607 resource_info->undo_cache=(unsigned int) StringToUnsignedLong(resource_value);
3608 resource_value=XGetResourceClass(database,client_name,"update",
3610 resource_info->update=IsMagickTrue(resource_value);
3611 resource_value=XGetResourceClass(database,client_name,"usePixmap",
3613 resource_info->use_pixmap=IsMagickTrue(resource_value);
3614 resource_value=XGetResourceClass(database,client_name,"sharedMemory",
3616 resource_info->use_shared_memory=IsMagickTrue(resource_value);
3617 resource_info->visual_type=XGetResourceClass(database,client_name,"visual",
3619 resource_info->window_group=XGetResourceClass(database,client_name,
3620 "windowGroup",(char *) NULL);
3621 resource_info->window_id=XGetResourceClass(database,client_name,"window",
3623 resource_info->write_filename=XGetResourceClass(database,client_name,
3624 "writeFilename",(char *) NULL);
3628 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3632 % X G e t R e s o u r c e I n s t a n c e %
3636 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3638 % XGetResourceInstance() queries the X server for the specified resource name.
3639 % If the resource name is not defined in the database, the supplied default
3640 % value is returned.
3642 % The format of the XGetResourceInstance method is:
3644 % char *XGetResourceInstance(XrmDatabase database,const char *client_name,
3645 % const char *keyword,const char *resource_default)
3647 % A description of each parameter follows:
3649 % o database: Specifies a resource database; returned from
3650 % XrmGetStringDatabase.
3652 % o client_name: Specifies the application name used to retrieve
3653 % resource info from the X server database.
3655 % o keyword: Specifies the keyword of the value being retrieved.
3657 % o resource_default: Specifies the default value to return if the query
3658 % fails to find the specified keyword/class.
3661 MagickExport char *XGetResourceInstance(XrmDatabase database,
3662 const char *client_name,const char *keyword,const char *resource_default)
3666 resource_name[MaxTextExtent];
3674 if (database == (XrmDatabase) NULL)
3675 return((char *) resource_default);
3676 *resource_name='\0';
3677 if (keyword != (char *) NULL)
3678 (void) FormatLocaleString(resource_name,MaxTextExtent,"%s.%s",client_name,
3680 status=XrmGetResource(database,resource_name,"ImageMagick",&resource_type,
3682 if (status == False)
3683 return((char *) resource_default);
3684 return(resource_value.addr);
3688 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3692 % X G e t S c r e e n D e n s i t y %
3696 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3698 % XGetScreenDensity() returns the density of the X server screen in
3701 % The format of the XGetScreenDensity method is:
3703 % char *XGetScreenDensity(Display *display)
3705 % A description of each parameter follows:
3707 % o density: XGetScreenDensity() returns the density of the X screen in
3710 % o display: Specifies a connection to an X server; returned from
3714 MagickExport char *XGetScreenDensity(Display *display)
3717 density[MaxTextExtent];
3724 Set density as determined by screen size.
3726 x_density=((((double) DisplayWidth(display,XDefaultScreen(display)))*25.4)/
3727 ((double) DisplayWidthMM(display,XDefaultScreen(display))));
3728 y_density=((((double) DisplayHeight(display,XDefaultScreen(display)))*25.4)/
3729 ((double) DisplayHeightMM(display,XDefaultScreen(display))));
3730 (void) FormatLocaleString(density,MaxTextExtent,"%gx%g",x_density,
3732 return(GetPageGeometry(density));
3736 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3740 + X G e t S u b w i n d o w %
3744 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3746 % XGetSubwindow() returns the subwindow of a window chosen the user with the
3747 % pointer and a button press.
3749 % The format of the XGetSubwindow method is:
3751 % Window XGetSubwindow(Display *display,Window window,int x,int y)
3753 % A description of each parameter follows:
3755 % o subwindow: XGetSubwindow() returns NULL if no subwindow is found
3756 % otherwise the subwindow is returned.
3758 % o display: Specifies a connection to an X server; returned from
3761 % o window: Specifies a pointer to a Window.
3763 % o x: the x coordinate of the pointer relative to the origin of the
3766 % o y: the y coordinate of the pointer relative to the origin of the
3770 static Window XGetSubwindow(Display *display,Window window,int x,int y)
3783 assert(display != (Display *) NULL);
3784 source_window=XRootWindow(display,XDefaultScreen(display));
3785 if (window == (Window) NULL)
3786 return(source_window);
3787 target_window=window;
3790 status=XTranslateCoordinates(display,source_window,window,x,y,
3791 &x_offset,&y_offset,&target_window);
3794 if (target_window == (Window) NULL)
3796 source_window=window;
3797 window=target_window;
3801 if (target_window == (Window) NULL)
3802 target_window=window;
3803 return(target_window);
3807 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3811 % X G e t W i n d o w C o l o r %
3815 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3817 % XGetWindowColor() returns the color of a pixel interactively chosen from the
3820 % The format of the XGetWindowColor method is:
3822 % MagickBooleanType XGetWindowColor(Display *display,XWindows *windows,
3825 % A description of each parameter follows:
3827 % o display: Specifies a connection to an X server; returned from
3830 % o windows: Specifies a pointer to a XWindows structure.
3832 % o name: the name of the color if found in the X Color Database is
3833 % returned in this character string.
3836 MagickPrivate MagickBooleanType XGetWindowColor(Display *display,
3837 XWindows *windows,char *name)
3868 Choose a pixel from the X server.
3870 assert(display != (Display *) NULL);
3871 assert(name != (char *) NULL);
3872 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
3874 target_window=XSelectWindow(display,&crop_info);
3875 if (target_window == (Window) NULL)
3876 return(MagickFalse);
3877 root_window=XRootWindow(display,XDefaultScreen(display));
3878 client_window=target_window;
3879 if (target_window != root_window)
3887 status=XGetGeometry(display,target_window,&root_window,&x,&x,&d,&d,&d,&d);
3888 if (status != False)
3890 client_window=XClientWindow(display,target_window);
3891 target_window=client_window;
3895 Verify window is viewable.
3897 status=XGetWindowAttributes(display,target_window,&window_attributes);
3898 if ((status == False) || (window_attributes.map_state != IsViewable))
3899 return(MagickFalse);
3903 (void) XTranslateCoordinates(display,root_window,target_window,
3904 (int) crop_info.x,(int) crop_info.y,&x,&y,&child);
3905 ximage=XGetImage(display,target_window,x,y,1,1,AllPlanes,ZPixmap);
3906 if (ximage == (XImage *) NULL)
3907 return(MagickFalse);
3908 color.pixel=XGetPixel(ximage,0,0);
3909 XDestroyImage(ximage);
3911 Match color against the color database.
3913 (void) XQueryColor(display,window_attributes.colormap,&color);
3914 pixel.red=ScaleShortToQuantum(color.red);
3915 pixel.green=ScaleShortToQuantum(color.green);
3916 pixel.blue=ScaleShortToQuantum(color.blue);
3917 pixel.alpha=OpaqueAlpha;
3918 (void) QueryColorname(windows->image.image,&pixel,X11Compliance,name,
3919 &windows->image.image->exception);
3924 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3928 + X G e t W i n d o w I m a g e %
3932 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3934 % XGetWindowImage() reads an image from the target X window and returns it.
3935 % XGetWindowImage() optionally descends the window hierarchy and overlays the
3936 % target image with each child image in an optimized fashion. Any child
3937 % window that have the same visual, colormap, and are contained by its parent
3940 % The format of the XGetWindowImage method is:
3942 % Image *XGetWindowImage(Display *display,const Window window,
3943 % const unsigned int borders,const unsigned int level)
3945 % A description of each parameter follows:
3947 % o display: Specifies a connection to an X server; returned from
3950 % o window: Specifies the window to obtain the image from.
3952 % o borders: Specifies whether borders pixels are to be saved with
3955 % o level: Specifies an unsigned integer representing the level of
3956 % decent in the window hierarchy. This value must be zero or one on
3957 % the initial call to XGetWindowImage. A value of zero returns after
3958 % one call. A value of one causes the function to descend the window
3959 % hierarchy and overlay the target image with each subwindow image.
3962 static Image *XGetWindowImage(Display *display,const Window window,
3963 const unsigned int borders,const unsigned int level)
3965 typedef struct _ColormapInfo
3973 struct _ColormapInfo
3977 typedef struct _WindowInfo
4013 *colormap_info = (ColormapInfo *) NULL;
4033 Verify window is viewable.
4035 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
4036 assert(display != (Display *) NULL);
4037 status=XGetWindowAttributes(display,window,&window_attributes);
4038 if ((status == False) || (window_attributes.map_state != IsViewable))
4039 return((Image *) NULL);
4041 Cropping rectangle is relative to root window.
4043 root_window=XRootWindow(display,XDefaultScreen(display));
4044 (void) XTranslateCoordinates(display,window,root_window,0,0,&x_offset,
4046 crop_info.x=(ssize_t) x_offset;
4047 crop_info.y=(ssize_t) y_offset;
4048 crop_info.width=(size_t) window_attributes.width;
4049 crop_info.height=(size_t) window_attributes.height;
4050 if (borders != MagickFalse)
4053 Include border in image.
4055 crop_info.x-=(ssize_t) window_attributes.border_width;
4056 crop_info.y-=(ssize_t) window_attributes.border_width;
4057 crop_info.width+=(size_t) (window_attributes.border_width << 1);
4058 crop_info.height+=(size_t) (window_attributes.border_width << 1);
4061 Crop to root window.
4063 if (crop_info.x < 0)
4065 crop_info.width+=crop_info.x;
4068 if (crop_info.y < 0)
4070 crop_info.height+=crop_info.y;
4073 display_width=XDisplayWidth(display,XDefaultScreen(display));
4074 if ((int) (crop_info.x+crop_info.width) > display_width)
4075 crop_info.width=(size_t) (display_width-crop_info.x);
4076 display_height=XDisplayHeight(display,XDefaultScreen(display));
4077 if ((int) (crop_info.y+crop_info.height) > display_height)
4078 crop_info.height=(size_t) (display_height-crop_info.y);
4080 Initialize window info attributes.
4082 if (number_windows >= max_windows)
4085 Allocate or resize window info buffer.
4088 if (window_info == (WindowInfo *) NULL)
4089 window_info=(WindowInfo *) AcquireQuantumMemory((size_t) max_windows,
4090 sizeof(*window_info));
4092 window_info=(WindowInfo *) ResizeQuantumMemory(window_info,(size_t)
4093 max_windows,sizeof(*window_info));
4095 if (window_info == (WindowInfo *) NULL)
4097 ThrowXWindowFatalException(ResourceLimitError,
4098 "MemoryAllocationFailed","...");
4099 return((Image *) NULL);
4101 id=number_windows++;
4102 window_info[id].window=window;
4103 window_info[id].visual=window_attributes.visual;
4104 window_info[id].colormap=window_attributes.colormap;
4105 window_info[id].bounds.x1=(short) crop_info.x;
4106 window_info[id].bounds.y1=(short) crop_info.y;
4107 window_info[id].bounds.x2=(short) (crop_info.x+(int) crop_info.width-1);
4108 window_info[id].bounds.y2=(short) (crop_info.y+(int) crop_info.height-1);
4109 crop_info.x-=x_offset;
4110 crop_info.y-=y_offset;
4111 window_info[id].crop_info=crop_info;
4121 Descend the window hierarchy.
4123 status=XQueryTree(display,window,&root_window,&window_info[id].parent,
4124 &children,&number_children);
4125 for (i=0; i < id; i++)
4126 if ((window_info[i].window == window_info[id].parent) &&
4127 (window_info[i].visual == window_info[id].visual) &&
4128 (window_info[i].colormap == window_info[id].colormap))
4130 if ((window_info[id].bounds.x1 <= window_info[i].bounds.x1) ||
4131 (window_info[id].bounds.x1 >= window_info[i].bounds.x2) ||
4132 (window_info[id].bounds.y1 <= window_info[i].bounds.y1) ||
4133 (window_info[id].bounds.y1 >= window_info[i].bounds.y2))
4136 Eliminate windows not circumscribed by their parent.
4142 if ((status == True) && (number_children != 0))
4144 for (i=0; i < (int) number_children; i++)
4145 (void) XGetWindowImage(display,children[i],MagickFalse,level+1);
4146 (void) XFree((void *) children);
4190 Get X image for each window in the list.
4192 image=NewImageList();
4193 for (id=0; id < number_windows; id++)
4196 Does target window intersect top level window?
4199 ((window_info[id].bounds.x2 >= window_info[0].bounds.x1) &&
4200 (window_info[id].bounds.x1 <= window_info[0].bounds.x2) &&
4201 (window_info[id].bounds.y2 >= window_info[0].bounds.y1) &&
4202 (window_info[id].bounds.y1 <= window_info[0].bounds.y2)) ?
4203 MagickTrue : MagickFalse;
4205 Is target window contained by another window with the same colormap?
4207 for (j=0; j < id; j++)
4208 if ((window_info[id].visual == window_info[j].visual) &&
4209 (window_info[id].colormap == window_info[j].colormap))
4211 if ((window_info[id].bounds.x1 <= window_info[j].bounds.x1) ||
4212 (window_info[id].bounds.x1 >= window_info[j].bounds.x2) ||
4213 (window_info[id].bounds.y1 <= window_info[j].bounds.y1) ||
4214 (window_info[id].bounds.y1 >= window_info[j].bounds.y2))
4218 if ((window_info[id].visual != window_info[j].visual) ||
4219 (window_info[id].colormap != window_info[j].colormap))
4221 if ((window_info[id].bounds.x2 > window_info[j].bounds.x1) &&
4222 (window_info[id].bounds.x1 < window_info[j].bounds.x2) &&
4223 (window_info[id].bounds.y2 > window_info[j].bounds.y1) &&
4224 (window_info[id].bounds.y1 < window_info[j].bounds.y2))
4227 if (import == MagickFalse)
4232 ximage=XGetImage(display,window_info[id].window,(int)
4233 window_info[id].crop_info.x,(int) window_info[id].crop_info.y,
4234 (unsigned int) window_info[id].crop_info.width,(unsigned int)
4235 window_info[id].crop_info.height,AllPlanes,ZPixmap);
4236 if (ximage == (XImage *) NULL)
4239 Initialize window colormap.
4242 colors=(XColor *) NULL;
4243 if (window_info[id].colormap != (Colormap) NULL)
4249 Search colormap list for window colormap.
4251 number_colors=(unsigned int) window_info[id].visual->map_entries;
4252 for (p=colormap_info; p != (ColormapInfo *) NULL; p=p->next)
4253 if (p->colormap == window_info[id].colormap)
4255 if (p == (ColormapInfo *) NULL)
4258 Get the window colormap.
4260 colors=(XColor *) AcquireQuantumMemory(number_colors,
4262 if (colors == (XColor *) NULL)
4264 XDestroyImage(ximage);
4265 return((Image *) NULL);
4267 if ((window_info[id].visual->klass != DirectColor) &&
4268 (window_info[id].visual->klass != TrueColor))
4269 for (i=0; i < (int) number_colors; i++)
4271 colors[i].pixel=(size_t) i;
4285 DirectColor or TrueColor visual.
4290 red_bit=window_info[id].visual->red_mask &
4291 (~(window_info[id].visual->red_mask)+1);
4292 green_bit=window_info[id].visual->green_mask &
4293 (~(window_info[id].visual->green_mask)+1);
4294 blue_bit=window_info[id].visual->blue_mask &
4295 (~(window_info[id].visual->blue_mask)+1);
4296 for (i=0; i < (int) number_colors; i++)
4298 colors[i].pixel=(unsigned long) (red | green | blue);
4301 if (red > window_info[id].visual->red_mask)
4304 if (green > window_info[id].visual->green_mask)
4307 if (blue > window_info[id].visual->blue_mask)
4311 (void) XQueryColors(display,window_info[id].colormap,colors,
4312 (int) number_colors);
4314 Append colormap to colormap list.
4316 p=(ColormapInfo *) AcquireMagickMemory(sizeof(*p));
4317 if (p == (ColormapInfo *) NULL)
4318 return((Image *) NULL);
4319 p->colormap=window_info[id].colormap;
4321 p->next=colormap_info;
4327 Allocate image structure.
4329 composite_image=AcquireImage((ImageInfo *) NULL);
4330 if (composite_image == (Image *) NULL)
4332 XDestroyImage(ximage);
4333 return((Image *) NULL);
4336 Convert X image to MIFF format.
4338 if ((window_info[id].visual->klass != TrueColor) &&
4339 (window_info[id].visual->klass != DirectColor))
4340 composite_image->storage_class=PseudoClass;
4341 composite_image->columns=(size_t) ximage->width;
4342 composite_image->rows=(size_t) ximage->height;
4343 exception=(&composite_image->exception);
4344 composite_view=AcquireCacheView(composite_image);
4345 switch (composite_image->storage_class)
4363 Determine shift and mask for red, green, and blue.
4365 red_mask=window_info[id].visual->red_mask;
4367 while ((red_mask != 0) && ((red_mask & 0x01) == 0))
4372 green_mask=window_info[id].visual->green_mask;
4374 while ((green_mask != 0) && ((green_mask & 0x01) == 0))
4379 blue_mask=window_info[id].visual->blue_mask;
4381 while ((blue_mask != 0) && ((blue_mask & 0x01) == 0))
4387 Convert X image to DirectClass packets.
4389 if ((number_colors != 0) &&
4390 (window_info[id].visual->klass == DirectColor))
4391 for (y=0; y < (int) composite_image->rows; y++)
4393 q=QueueCacheViewAuthenticPixels(composite_view,0,(ssize_t) y,
4394 composite_image->columns,1,exception);
4395 if (q == (Quantum *) NULL)
4397 for (x=0; x < (int) composite_image->columns; x++)
4399 pixel=XGetPixel(ximage,x,y);
4400 index=(pixel >> red_shift) & red_mask;
4401 SetPixelRed(composite_image,
4402 ScaleShortToQuantum(colors[index].red),q);
4403 index=(pixel >> green_shift) & green_mask;
4404 SetPixelGreen(composite_image,
4405 ScaleShortToQuantum(colors[index].green),q);
4406 index=(pixel >> blue_shift) & blue_mask;
4407 SetPixelBlue(composite_image,
4408 ScaleShortToQuantum(colors[index].blue),q);
4409 q+=GetPixelChannels(composite_image);
4411 if (SyncCacheViewAuthenticPixels(composite_view,exception) == MagickFalse)
4415 for (y=0; y < (int) composite_image->rows; y++)
4417 q=QueueCacheViewAuthenticPixels(composite_view,0,(ssize_t) y,
4418 composite_image->columns,1,exception);
4419 if (q == (Quantum *) NULL)
4421 for (x=0; x < (int) composite_image->columns; x++)
4423 pixel=XGetPixel(ximage,x,y);
4424 color=(pixel >> red_shift) & red_mask;
4425 color=(65535UL*color)/red_mask;
4426 SetPixelRed(composite_image,
4427 ScaleShortToQuantum((unsigned short) color),q);
4428 color=(pixel >> green_shift) & green_mask;
4429 color=(65535UL*color)/green_mask;
4430 SetPixelGreen(composite_image,
4431 ScaleShortToQuantum((unsigned short) color),q);
4432 color=(pixel >> blue_shift) & blue_mask;
4433 color=(65535UL*color)/blue_mask;
4434 SetPixelBlue(composite_image,
4435 ScaleShortToQuantum((unsigned short) color),q);
4436 q+=GetPixelChannels(composite_image);
4438 if (SyncCacheViewAuthenticPixels(composite_view,exception) == MagickFalse)
4448 if (AcquireImageColormap(composite_image,number_colors,exception) == MagickFalse)
4450 XDestroyImage(ximage);
4451 composite_image=DestroyImage(composite_image);
4452 return((Image *) NULL);
4454 for (i=0; i < (int) composite_image->colors; i++)
4456 composite_image->colormap[colors[i].pixel].red=
4457 ScaleShortToQuantum(colors[i].red);
4458 composite_image->colormap[colors[i].pixel].green=
4459 ScaleShortToQuantum(colors[i].green);
4460 composite_image->colormap[colors[i].pixel].blue=
4461 ScaleShortToQuantum(colors[i].blue);
4464 Convert X image to PseudoClass packets.
4466 for (y=0; y < (int) composite_image->rows; y++)
4468 q=QueueCacheViewAuthenticPixels(composite_view,0,(ssize_t) y,
4469 composite_image->columns,1,exception);
4470 if (q == (Quantum *) NULL)
4472 for (x=0; x < (int) composite_image->columns; x++)
4474 index=(Quantum) XGetPixel(ximage,x,y);
4475 SetPixelIndex(composite_image,index,q);
4476 SetPixelPacket(composite_image,
4477 composite_image->colormap+(ssize_t) index,q);
4478 q+=GetPixelChannels(composite_image);
4480 if (SyncCacheViewAuthenticPixels(composite_view,exception) == MagickFalse)
4486 composite_view=DestroyCacheView(composite_view);
4487 XDestroyImage(ximage);
4488 if (image == (Image *) NULL)
4490 image=composite_image;
4494 Composite any children in back-to-front order.
4496 (void) XTranslateCoordinates(display,window_info[id].window,window,0,0,
4497 &x_offset,&y_offset,&child);
4498 x_offset-=(int) crop_info.x;
4501 y_offset-=(int) crop_info.y;
4504 (void) CompositeImage(image,CopyCompositeOp,composite_image,(ssize_t)
4505 x_offset,(ssize_t) y_offset);
4508 Relinquish resources.
4510 while (colormap_info != (ColormapInfo *) NULL)
4512 next=colormap_info->next;
4513 colormap_info->colors=(XColor *)
4514 RelinquishMagickMemory(colormap_info->colors);
4515 colormap_info=(ColormapInfo *) RelinquishMagickMemory(colormap_info);
4519 Relinquish resources and restore initial state.
4521 window_info=(WindowInfo *) RelinquishMagickMemory(window_info);
4524 colormap_info=(ColormapInfo *) NULL;
4527 return((Image *) NULL);
4531 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4535 % X G e t W i n d o w I n f o %
4539 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4541 % XGetWindowInfo() initializes the XWindowInfo structure.
4543 % The format of the XGetWindowInfo method is:
4545 % void XGetWindowInfo(Display *display,XVisualInfo *visual_info,
4546 % XStandardColormap *map_info,XPixelInfo *pixel,XFontStruct *font_info,
4547 % XResourceInfo *resource_info,XWindowInfo *window)
4548 % resource_info,window)
4550 % A description of each parameter follows:
4552 % o display: Specifies a connection to an X server; returned from
4555 % o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
4556 % returned from XGetVisualInfo.
4558 % o map_info: If map_type is specified, this structure is initialized
4559 % with info from the Standard Colormap.
4561 % o pixel: Specifies a pointer to a XPixelInfo structure.
4563 % o font_info: Specifies a pointer to a XFontStruct structure.
4565 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
4568 MagickPrivate void XGetWindowInfo(Display *display,XVisualInfo *visual_info,
4569 XStandardColormap *map_info,XPixelInfo *pixel,XFontStruct *font_info,
4570 XResourceInfo *resource_info,XWindowInfo *window)
4573 Initialize window info.
4575 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
4576 assert(display != (Display *) NULL);
4577 assert(visual_info != (XVisualInfo *) NULL);
4578 assert(map_info != (XStandardColormap *) NULL);
4579 assert(pixel != (XPixelInfo *) NULL);
4580 assert(resource_info != (XResourceInfo *) NULL);
4581 assert(window != (XWindowInfo *) NULL);
4582 if (window->id != (Window) NULL)
4584 if (window->cursor != (Cursor) NULL)
4585 (void) XFreeCursor(display,window->cursor);
4586 if (window->busy_cursor != (Cursor) NULL)
4587 (void) XFreeCursor(display,window->busy_cursor);
4588 if (window->highlight_stipple != (Pixmap) NULL)
4589 (void) XFreePixmap(display,window->highlight_stipple);
4590 if (window->shadow_stipple != (Pixmap) NULL)
4591 (void) XFreePixmap(display,window->shadow_stipple);
4592 if (window->name == (char *) NULL)
4593 window->name=AcquireString("");
4594 if (window->icon_name == (char *) NULL)
4595 window->icon_name=AcquireString("");
4600 Initialize these attributes just once.
4602 window->id=(Window) NULL;
4603 if (window->name == (char *) NULL)
4604 window->name=AcquireString("");
4605 if (window->icon_name == (char *) NULL)
4606 window->icon_name=AcquireString("");
4607 window->x=XDisplayWidth(display,visual_info->screen) >> 1;
4608 window->y=XDisplayWidth(display,visual_info->screen) >> 1;
4609 window->ximage=(XImage *) NULL;
4610 window->matte_image=(XImage *) NULL;
4611 window->pixmap=(Pixmap) NULL;
4612 window->matte_pixmap=(Pixmap) NULL;
4613 window->mapped=MagickFalse;
4614 window->stasis=MagickFalse;
4615 window->shared_memory=MagickTrue;
4616 window->segment_info=(void *) NULL;
4617 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
4622 if (window->segment_info == (void *) NULL)
4623 window->segment_info=AcquireQuantumMemory(2,sizeof(*segment_info));
4624 segment_info=(XShmSegmentInfo *) window->segment_info;
4625 segment_info[0].shmid=(-1);
4626 segment_info[0].shmaddr=(char *) NULL;
4627 segment_info[1].shmid=(-1);
4628 segment_info[1].shmaddr=(char *) NULL;
4633 Initialize these attributes every time function is called.
4635 window->screen=visual_info->screen;
4636 window->root=XRootWindow(display,visual_info->screen);
4637 window->visual=visual_info->visual;
4638 window->storage_class=(unsigned int) visual_info->klass;
4639 window->depth=(unsigned int) visual_info->depth;
4640 window->visual_info=visual_info;
4641 window->map_info=map_info;
4642 window->pixel_info=pixel;
4643 window->font_info=font_info;
4644 window->cursor=XCreateFontCursor(display,XC_left_ptr);
4645 window->busy_cursor=XCreateFontCursor(display,XC_watch);
4646 window->geometry=(char *) NULL;
4647 window->icon_geometry=(char *) NULL;
4648 if (resource_info->icon_geometry != (char *) NULL)
4649 (void) CloneString(&window->icon_geometry,resource_info->icon_geometry);
4650 window->crop_geometry=(char *) NULL;
4651 window->flags=(size_t) PSize;
4654 window->min_width=1;
4655 window->min_height=1;
4656 window->width_inc=1;
4657 window->height_inc=1;
4658 window->border_width=resource_info->border_width;
4659 window->annotate_context=pixel->annotate_context;
4660 window->highlight_context=pixel->highlight_context;
4661 window->widget_context=pixel->widget_context;
4662 window->shadow_stipple=(Pixmap) NULL;
4663 window->highlight_stipple=(Pixmap) NULL;
4664 window->use_pixmap=MagickTrue;
4665 window->immutable=MagickFalse;
4666 window->shape=MagickFalse;
4668 window->mask=(int) (CWBackingStore | CWBackPixel | CWBackPixmap |
4669 CWBitGravity | CWBorderPixel | CWColormap | CWCursor | CWDontPropagate |
4670 CWEventMask | CWOverrideRedirect | CWSaveUnder | CWWinGravity);
4671 window->attributes.background_pixel=pixel->background_color.pixel;
4672 window->attributes.background_pixmap=(Pixmap) NULL;
4673 window->attributes.bit_gravity=ForgetGravity;
4674 window->attributes.backing_store=WhenMapped;
4675 window->attributes.save_under=MagickTrue;
4676 window->attributes.border_pixel=pixel->border_color.pixel;
4677 window->attributes.colormap=map_info->colormap;
4678 window->attributes.cursor=window->cursor;
4679 window->attributes.do_not_propagate_mask=NoEventMask;
4680 window->attributes.event_mask=NoEventMask;
4681 window->attributes.override_redirect=MagickFalse;
4682 window->attributes.win_gravity=NorthWestGravity;
4683 window->orphan=MagickFalse;
4687 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4691 % X H i g h l i g h t E l l i p s e %
4695 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4697 % XHighlightEllipse() puts a border on the X server around a region defined by
4700 % The format of the XHighlightEllipse method is:
4702 % void XHighlightEllipse(Display *display,Window window,
4703 % GC annotate_context,const RectangleInfo *highlight_info)
4705 % A description of each parameter follows:
4707 % o display: Specifies a connection to an X server; returned from
4710 % o window: Specifies a pointer to a Window structure.
4712 % o annotate_context: Specifies a pointer to a GC structure.
4714 % o highlight_info: Specifies a pointer to a RectangleInfo structure. It
4715 % contains the extents of any highlighting rectangle.
4718 MagickPrivate void XHighlightEllipse(Display *display,Window window,
4719 GC annotate_context,const RectangleInfo *highlight_info)
4721 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
4722 assert(display != (Display *) NULL);
4723 assert(window != (Window) NULL);
4724 assert(annotate_context != (GC) NULL);
4725 assert(highlight_info != (RectangleInfo *) NULL);
4726 if ((highlight_info->width < 4) || (highlight_info->height < 4))
4728 (void) XDrawArc(display,window,annotate_context,(int) highlight_info->x,
4729 (int) highlight_info->y,(unsigned int) highlight_info->width-1,
4730 (unsigned int) highlight_info->height-1,0,360*64);
4731 (void) XDrawArc(display,window,annotate_context,(int) highlight_info->x+1,
4732 (int) highlight_info->y+1,(unsigned int) highlight_info->width-3,
4733 (unsigned int) highlight_info->height-3,0,360*64);
4737 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4741 % X H i g h l i g h t L i n e %
4745 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4747 % XHighlightLine() puts a border on the X server around a region defined by
4750 % The format of the XHighlightLine method is:
4752 % void XHighlightLine(Display *display,Window window,GC annotate_context,
4753 % const XSegment *highlight_info)
4755 % A description of each parameter follows:
4757 % o display: Specifies a connection to an X server; returned from
4760 % o window: Specifies a pointer to a Window structure.
4762 % o annotate_context: Specifies a pointer to a GC structure.
4764 % o highlight_info: Specifies a pointer to a RectangleInfo structure. It
4765 % contains the extents of any highlighting rectangle.
4768 MagickPrivate void XHighlightLine(Display *display,Window window,
4769 GC annotate_context,const XSegment *highlight_info)
4771 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
4772 assert(display != (Display *) NULL);
4773 assert(window != (Window) NULL);
4774 assert(annotate_context != (GC) NULL);
4775 assert(highlight_info != (XSegment *) NULL);
4776 (void) XDrawLine(display,window,annotate_context,highlight_info->x1,
4777 highlight_info->y1,highlight_info->x2,highlight_info->y2);
4781 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4785 % X H i g h l i g h t R e c t a n g l e %
4789 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4791 % XHighlightRectangle() puts a border on the X server around a region defined
4792 % by highlight_info.
4794 % The format of the XHighlightRectangle method is:
4796 % void XHighlightRectangle(Display *display,Window window,
4797 % GC annotate_context,const RectangleInfo *highlight_info)
4799 % A description of each parameter follows:
4801 % o display: Specifies a connection to an X server; returned from
4804 % o window: Specifies a pointer to a Window structure.
4806 % o annotate_context: Specifies a pointer to a GC structure.
4808 % o highlight_info: Specifies a pointer to a RectangleInfo structure. It
4809 % contains the extents of any highlighting rectangle.
4812 MagickPrivate void XHighlightRectangle(Display *display,Window window,
4813 GC annotate_context,const RectangleInfo *highlight_info)
4815 assert(display != (Display *) NULL);
4816 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
4817 assert(window != (Window) NULL);
4818 assert(annotate_context != (GC) NULL);
4819 assert(highlight_info != (RectangleInfo *) NULL);
4820 if ((highlight_info->width < 4) || (highlight_info->height < 4))
4822 (void) XDrawRectangle(display,window,annotate_context,(int) highlight_info->x,
4823 (int) highlight_info->y,(unsigned int) highlight_info->width-1,
4824 (unsigned int) highlight_info->height-1);
4825 (void) XDrawRectangle(display,window,annotate_context,(int) highlight_info->x+
4826 1,(int) highlight_info->y+1,(unsigned int) highlight_info->width-3,
4827 (unsigned int) highlight_info->height-3);
4831 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4835 % X I m p o r t I m a g e %
4839 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4841 % XImportImage() reads an image from an X window.
4843 % The format of the XImportImage method is:
4845 % Image *XImportImage(const ImageInfo *image_info,XImportInfo *ximage_info)
4847 % A description of each parameter follows:
4849 % o image_info: the image info.
4851 % o ximage_info: Specifies a pointer to an XImportInfo structure.
4854 MagickExport Image *XImportImage(const ImageInfo *image_info,
4855 XImportInfo *ximage_info)
4888 Open X server connection.
4890 assert(image_info != (const ImageInfo *) NULL);
4891 assert(image_info->signature == MagickSignature);
4892 if (image_info->debug != MagickFalse)
4893 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
4894 image_info->filename);
4895 assert(ximage_info != (XImportInfo *) NULL);
4896 display=XOpenDisplay(image_info->server_name);
4897 if (display == (Display *) NULL)
4899 ThrowXWindowFatalException(XServerError,"UnableToOpenXServer",
4900 XDisplayName(image_info->server_name));
4901 return((Image *) NULL);
4904 Set our forgiving exception handler.
4906 (void) XSetErrorHandler(XError);
4908 Select target window.
4914 root=XRootWindow(display,XDefaultScreen(display));
4915 target=(Window) NULL;
4916 if ((image_info->filename != (char *) NULL) &&
4917 (*image_info->filename != '\0'))
4919 if (LocaleCompare(image_info->filename,"root") == 0)
4924 Select window by ID or name.
4926 if (isdigit((unsigned char) *image_info->filename) != 0)
4927 target=XWindowByID(display,root,(Window)
4928 strtol(image_info->filename,(char **) NULL,0));
4929 if (target == (Window) NULL)
4930 target=XWindowByName(display,root,image_info->filename);
4931 if (target == (Window) NULL)
4932 ThrowXWindowFatalException(XServerError,
4933 "NoWindowWithSpecifiedIDExists",image_info->filename);
4937 If target window is not defined, interactively select one.
4939 prior_target=target;
4940 if (target == (Window) NULL)
4941 target=XSelectWindow(display,&crop_info);
4942 if (target == (Window) NULL)
4943 ThrowXWindowFatalException(XServerError,"UnableToReadXWindowImage",
4944 image_info->filename);
4945 client=target; /* obsolete */
4951 status=XGetGeometry(display,target,&root,&x,&x,&d,&d,&d,&d);
4952 if (status != False)
4960 Find window manager frame.
4962 status=XQueryTree(display,target,&root,&parent,&children,&d);
4963 if ((status != False) && (children != (Window *) NULL))
4964 (void) XFree((char *) children);
4965 if ((status == False) || (parent == (Window) NULL) ||
4973 client=XClientWindow(display,target);
4974 if (ximage_info->frame == MagickFalse)
4976 if ((ximage_info->frame == MagickFalse) &&
4977 (prior_target != MagickFalse))
4978 target=prior_target;
4979 XDelay(display,SuspendTime << 4);
4982 if (ximage_info->screen)
4994 Obtain window image directly from screen.
4996 status=XGetWindowAttributes(display,target,&window_attributes);
4997 if (status == False)
4999 ThrowXWindowFatalException(XServerError,
5000 "UnableToReadXWindowAttributes",image_info->filename);
5001 (void) XCloseDisplay(display);
5002 return((Image *) NULL);
5004 (void) XTranslateCoordinates(display,target,root,0,0,&x,&y,&child);
5005 crop_info.x=(ssize_t) x;
5006 crop_info.y=(ssize_t) y;
5007 crop_info.width=(size_t) window_attributes.width;
5008 crop_info.height=(size_t) window_attributes.height;
5009 if (ximage_info->borders != 0)
5012 Include border in image.
5014 crop_info.x-=window_attributes.border_width;
5015 crop_info.y-=window_attributes.border_width;
5016 crop_info.width+=window_attributes.border_width << 1;
5017 crop_info.height+=window_attributes.border_width << 1;
5022 If WM_COLORMAP_WINDOWS property is set or multiple colormaps, descend.
5025 status=XGetWMColormapWindows(display,target,&children,&number_windows);
5026 if ((status == True) && (number_windows > 0))
5028 ximage_info->descend=MagickTrue;
5029 (void) XFree ((char *) children);
5031 colormaps=XListInstalledColormaps(display,target,&number_colormaps);
5032 if (number_colormaps > 0)
5034 if (number_colormaps > 1)
5035 ximage_info->descend=MagickTrue;
5036 (void) XFree((char *) colormaps);
5039 Alert the user not to alter the screen.
5041 if (ximage_info->silent == MagickFalse)
5042 (void) XBell(display,0);
5044 Get image by window id.
5046 (void) XGrabServer(display);
5047 image=XGetWindowImage(display,target,ximage_info->borders,
5048 ximage_info->descend ? 1U : 0U);
5049 (void) XUngrabServer(display);
5050 if (image == (Image *) NULL)
5051 ThrowXWindowFatalException(XServerError,"UnableToReadXWindowImage",
5052 image_info->filename)
5055 (void) CopyMagickString(image->filename,image_info->filename,
5057 if ((crop_info.width != 0) && (crop_info.height != 0))
5064 Crop image as defined by the cropping rectangle.
5066 clone_image=CloneImage(image,0,0,MagickTrue,&image->exception);
5067 if (clone_image != (Image *) NULL)
5069 crop_image=CropImage(clone_image,&crop_info,&image->exception);
5070 if (crop_image != (Image *) NULL)
5072 image=DestroyImage(image);
5077 status=XGetWMName(display,target,&window_name);
5080 if ((image_info->filename != (char *) NULL) &&
5081 (*image_info->filename == '\0'))
5082 (void) CopyMagickString(image->filename,(char *) window_name.value,
5083 (size_t) window_name.nitems+1);
5084 (void) XFree((void *) window_name.value);
5087 if (ximage_info->silent == MagickFalse)
5090 Alert the user we're done.
5092 (void) XBell(display,0);
5093 (void) XBell(display,0);
5095 (void) XCloseDisplay(display);
5100 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5104 % X I n i t i a l i z e W i n d o w s %
5108 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5110 % XInitializeWindows() initializes the XWindows structure.
5112 % The format of the XInitializeWindows method is:
5114 % XWindows *XInitializeWindows(Display *display,
5115 % XResourceInfo *resource_info)
5117 % A description of each parameter follows:
5119 % o windows: XInitializeWindows returns a pointer to a XWindows structure.
5121 % o display: Specifies a connection to an X server; returned from
5124 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
5127 MagickPrivate XWindows *XInitializeWindows(Display *display,
5128 XResourceInfo *resource_info)
5137 Allocate windows structure.
5139 windows=(XWindows *) AcquireMagickMemory(sizeof(*windows));
5140 if (windows == (XWindows *) NULL)
5142 ThrowXWindowFatalException(XServerFatalError,"MemoryAllocationFailed",
5144 return((XWindows *) NULL);
5146 (void) ResetMagickMemory(windows,0,sizeof(*windows));
5147 windows->pixel_info=(XPixelInfo *) AcquireMagickMemory(
5148 sizeof(*windows->pixel_info));
5149 windows->icon_pixel=(XPixelInfo *) AcquireMagickMemory(
5150 sizeof(*windows->icon_pixel));
5151 windows->icon_resources=(XResourceInfo *) AcquireMagickMemory(
5152 sizeof(*windows->icon_resources));
5153 if ((windows->pixel_info == (XPixelInfo *) NULL) ||
5154 (windows->icon_pixel == (XPixelInfo *) NULL) ||
5155 (windows->icon_resources == (XResourceInfo *) NULL))
5157 ThrowXWindowFatalException(XServerFatalError,"MemoryAllocationFailed",
5159 return((XWindows *) NULL);
5162 Initialize windows structure.
5164 windows->display=display;
5165 windows->wm_protocols=XInternAtom(display,"WM_PROTOCOLS",MagickFalse);
5166 windows->wm_delete_window=XInternAtom(display,"WM_DELETE_WINDOW",MagickFalse);
5167 windows->wm_take_focus=XInternAtom(display,"WM_TAKE_FOCUS",MagickFalse);
5168 windows->im_protocols=XInternAtom(display,"IM_PROTOCOLS",MagickFalse);
5169 windows->im_remote_command=
5170 XInternAtom(display,"IM_REMOTE_COMMAND",MagickFalse);
5171 windows->im_update_widget=XInternAtom(display,"IM_UPDATE_WIDGET",MagickFalse);
5172 windows->im_update_colormap=
5173 XInternAtom(display,"IM_UPDATE_COLORMAP",MagickFalse);
5174 windows->im_former_image=XInternAtom(display,"IM_FORMER_IMAGE",MagickFalse);
5175 windows->im_next_image=XInternAtom(display,"IM_NEXT_IMAGE",MagickFalse);
5176 windows->im_retain_colors=XInternAtom(display,"IM_RETAIN_COLORS",MagickFalse);
5177 windows->im_exit=XInternAtom(display,"IM_EXIT",MagickFalse);
5178 windows->dnd_protocols=XInternAtom(display,"DndProtocol",MagickFalse);
5179 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
5180 (void) XSynchronize(display,IsWindows95());
5182 if (IsEventLogging())
5184 (void) XSynchronize(display,MagickTrue);
5185 (void) LogMagickEvent(X11Event,GetMagickModule(),"Version: %s",
5186 GetMagickVersion((size_t *) NULL));
5187 (void) LogMagickEvent(X11Event,GetMagickModule(),"Protocols:");
5188 (void) LogMagickEvent(X11Event,GetMagickModule(),
5189 " Window Manager: 0x%lx",windows->wm_protocols);
5190 (void) LogMagickEvent(X11Event,GetMagickModule(),
5191 " delete window: 0x%lx",windows->wm_delete_window);
5192 (void) LogMagickEvent(X11Event,GetMagickModule()," take focus: 0x%lx",
5193 windows->wm_take_focus);
5194 (void) LogMagickEvent(X11Event,GetMagickModule()," ImageMagick: 0x%lx",
5195 windows->im_protocols);
5196 (void) LogMagickEvent(X11Event,GetMagickModule(),
5197 " remote command: 0x%lx",windows->im_remote_command);
5198 (void) LogMagickEvent(X11Event,GetMagickModule(),
5199 " update widget: 0x%lx",windows->im_update_widget);
5200 (void) LogMagickEvent(X11Event,GetMagickModule(),
5201 " update colormap: 0x%lx",windows->im_update_colormap);
5202 (void) LogMagickEvent(X11Event,GetMagickModule(),
5203 " former image: 0x%lx",windows->im_former_image);
5204 (void) LogMagickEvent(X11Event,GetMagickModule()," next image: 0x%lx",
5205 windows->im_next_image);
5206 (void) LogMagickEvent(X11Event,GetMagickModule(),
5207 " retain colors: 0x%lx",windows->im_retain_colors);
5208 (void) LogMagickEvent(X11Event,GetMagickModule()," exit: 0x%lx",
5210 (void) LogMagickEvent(X11Event,GetMagickModule()," Drag and Drop: 0x%lx",
5211 windows->dnd_protocols);
5214 Allocate standard colormap.
5216 windows->map_info=XAllocStandardColormap();
5217 windows->icon_map=XAllocStandardColormap();
5218 if ((windows->map_info == (XStandardColormap *) NULL) ||
5219 (windows->icon_map == (XStandardColormap *) NULL))
5220 ThrowXWindowFatalException(ResourceLimitFatalError,
5221 "MemoryAllocationFailed","...");
5222 windows->map_info->colormap=(Colormap) NULL;
5223 windows->icon_map->colormap=(Colormap) NULL;
5224 windows->pixel_info->pixels=(unsigned long *) NULL;
5225 windows->pixel_info->annotate_context=(GC) NULL;
5226 windows->pixel_info->highlight_context=(GC) NULL;
5227 windows->pixel_info->widget_context=(GC) NULL;
5228 windows->font_info=(XFontStruct *) NULL;
5229 windows->icon_pixel->annotate_context=(GC) NULL;
5230 windows->icon_pixel->pixels=(unsigned long *) NULL;
5234 *windows->icon_resources=(*resource_info);
5235 windows->icon_resources->visual_type=(char *) "default";
5236 windows->icon_resources->colormap=SharedColormap;
5237 windows->visual_info=
5238 XBestVisualInfo(display,windows->map_info,resource_info);
5239 windows->icon_visual=
5240 XBestVisualInfo(display,windows->icon_map,windows->icon_resources);
5241 if ((windows->visual_info == (XVisualInfo *) NULL) ||
5242 (windows->icon_visual == (XVisualInfo *) NULL))
5243 ThrowXWindowFatalException(XServerFatalError,"UnableToGetVisual",
5244 resource_info->visual_type);
5245 if (IsEventLogging())
5247 (void) LogMagickEvent(X11Event,GetMagickModule(),"Visual:");
5248 (void) LogMagickEvent(X11Event,GetMagickModule()," visual id: 0x%lx",
5249 windows->visual_info->visualid);
5250 (void) LogMagickEvent(X11Event,GetMagickModule()," class: %s",
5251 XVisualClassName(windows->visual_info->klass));
5252 (void) LogMagickEvent(X11Event,GetMagickModule()," depth: %d planes",
5253 windows->visual_info->depth);
5254 (void) LogMagickEvent(X11Event,GetMagickModule(),
5255 " size of colormap: %d entries",windows->visual_info->colormap_size);
5256 (void) LogMagickEvent(X11Event,GetMagickModule(),
5257 " red, green, blue masks: 0x%lx 0x%lx 0x%lx",
5258 windows->visual_info->red_mask,windows->visual_info->green_mask,
5259 windows->visual_info->blue_mask);
5260 (void) LogMagickEvent(X11Event,GetMagickModule(),
5261 " significant bits in color: %d bits",
5262 windows->visual_info->bits_per_rgb);
5265 Allocate class and manager hints.
5267 windows->class_hints=XAllocClassHint();
5268 windows->manager_hints=XAllocWMHints();
5269 if ((windows->class_hints == (XClassHint *) NULL) ||
5270 (windows->manager_hints == (XWMHints *) NULL))
5271 ThrowXWindowFatalException(ResourceLimitFatalError,
5272 "MemoryAllocationFailed","...");
5274 Determine group leader if we have one.
5276 root_window=XRootWindow(display,windows->visual_info->screen);
5277 windows->group_leader.id=(Window) NULL;
5278 if (resource_info->window_group != (char *) NULL)
5280 if (isdigit((unsigned char) *resource_info->window_group) != 0)
5281 windows->group_leader.id=XWindowByID(display,root_window,(Window)
5282 strtol((char *) resource_info->window_group,(char **) NULL,0));
5283 if (windows->group_leader.id == (Window) NULL)
5284 windows->group_leader.id=
5285 XWindowByName(display,root_window,resource_info->window_group);
5291 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5295 % X M a k e C u r s o r %
5299 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5301 % XMakeCursor() creates a crosshairs X11 cursor.
5303 % The format of the XMakeCursor method is:
5305 % Cursor XMakeCursor(Display *display,Window window,Colormap colormap,
5306 % char *background_color,char *foreground_color)
5308 % A description of each parameter follows:
5310 % o display: Specifies a connection to an X server; returned from
5313 % o window: Specifies the ID of the window for which the cursor is
5316 % o colormap: Specifies the ID of the colormap from which the background
5317 % and foreground color will be retrieved.
5319 % o background_color: Specifies the color to use for the cursor background.
5321 % o foreground_color: Specifies the color to use for the cursor foreground.
5324 MagickPrivate Cursor XMakeCursor(Display *display,Window window,
5325 Colormap colormap,char *background_color,char *foreground_color)
5327 #define scope_height 17
5328 #define scope_x_hot 8
5329 #define scope_y_hot 8
5330 #define scope_width 17
5332 static const unsigned char
5335 0x80, 0x03, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02,
5336 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x7f,
5337 0xfc, 0x01, 0x01, 0x00, 0x01, 0x7f, 0xfc, 0x01, 0x80, 0x02, 0x00,
5338 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02,
5339 0x00, 0x80, 0x02, 0x00, 0x80, 0x03, 0x00
5343 0xc0, 0x07, 0x00, 0xc0, 0x07, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06,
5344 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xff, 0xfe, 0x01, 0x7f,
5345 0xfc, 0x01, 0x03, 0x80, 0x01, 0x7f, 0xfc, 0x01, 0xff, 0xfe, 0x01,
5346 0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06,
5347 0x00, 0xc0, 0x07, 0x00, 0xc0, 0x07, 0x00
5361 assert(display != (Display *) NULL);
5362 assert(window != (Window) NULL);
5363 assert(colormap != (Colormap) NULL);
5364 assert(background_color != (char *) NULL);
5365 assert(foreground_color != (char *) NULL);
5366 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",background_color);
5367 source=XCreateBitmapFromData(display,window,(char *) scope_bits,scope_width,
5369 mask=XCreateBitmapFromData(display,window,(char *) scope_mask_bits,
5370 scope_width,scope_height);
5371 if ((source == (Pixmap) NULL) || (mask == (Pixmap) NULL))
5373 ThrowXWindowFatalException(XServerError,"UnableToCreatePixmap","...");
5374 return((Cursor) NULL);
5376 (void) XParseColor(display,colormap,background_color,&background);
5377 (void) XParseColor(display,colormap,foreground_color,&foreground);
5378 cursor=XCreatePixmapCursor(display,source,mask,&foreground,&background,
5379 scope_x_hot,scope_y_hot);
5380 (void) XFreePixmap(display,source);
5381 (void) XFreePixmap(display,mask);
5386 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5390 % X M a k e I m a g e %
5394 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5396 % XMakeImage() creates an X11 image. If the image size differs from the X11
5397 % image size, the image is first resized.
5399 % The format of the XMakeImage method is:
5401 % MagickBooleanType XMakeImage(Display *display,
5402 % const XResourceInfo *resource_info,XWindowInfo *window,Image *image,
5403 % unsigned int width,unsigned int height,ExceptionInfo *exception)
5405 % A description of each parameter follows:
5407 % o display: Specifies a connection to an X server; returned from
5410 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
5412 % o window: Specifies a pointer to a XWindowInfo structure.
5414 % o image: the image.
5416 % o width: Specifies the width in pixels of the rectangular area to
5419 % o height: Specifies the height in pixels of the rectangular area to
5422 % o exception: return any errors or warnings in this structure.
5425 MagickPrivate MagickBooleanType XMakeImage(Display *display,
5426 const XResourceInfo *resource_info,XWindowInfo *window,Image *image,
5427 unsigned int width,unsigned int height,ExceptionInfo *exception)
5429 #define CheckOverflowException(length,width,height) \
5430 (((height) != 0) && ((length)/((size_t) height) != ((size_t) width)))
5443 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
5444 assert(display != (Display *) NULL);
5445 assert(resource_info != (XResourceInfo *) NULL);
5446 assert(window != (XWindowInfo *) NULL);
5448 assert(height != 0);
5449 if ((window->width == 0) || (window->height == 0))
5450 return(MagickFalse);
5452 Apply user transforms to the image.
5454 (void) XCheckDefineCursor(display,window->id,window->busy_cursor);
5455 (void) XFlush(display);
5456 depth=(int) window->depth;
5457 if (window->destroy)
5458 window->image=DestroyImage(window->image);
5459 window->image=image;
5460 window->destroy=MagickFalse;
5461 if (window->image != (Image *) NULL)
5463 if (window->crop_geometry != (char *) NULL)
5474 window->image->page.x=0;
5475 window->image->page.y=0;
5476 (void) ParsePageGeometry(window->image,window->crop_geometry,
5477 &crop_info,&image->exception);
5478 crop_image=CropImage(window->image,&crop_info,&image->exception);
5479 if (crop_image != (Image *) NULL)
5481 if (window->image != image)
5482 window->image=DestroyImage(window->image);
5483 window->image=crop_image;
5484 window->destroy=MagickTrue;
5487 if ((width != (unsigned int) window->image->columns) ||
5488 (height != (unsigned int) window->image->rows))
5496 resize_image=NewImageList();
5497 if (window->pixel_info->colors != 0)
5498 resize_image=SampleImage(window->image,width,height,
5501 resize_image=ThumbnailImage(window->image,width,height,
5503 if (resize_image != (Image *) NULL)
5505 if (window->image != image)
5506 window->image=DestroyImage(window->image);
5507 window->image=resize_image;
5508 window->destroy=MagickTrue;
5511 width=(unsigned int) window->image->columns;
5512 assert((size_t) width == window->image->columns);
5513 height=(unsigned int) window->image->rows;
5514 assert((size_t) height == window->image->rows);
5519 ximage=(XImage *) NULL;
5520 format=(depth == 1) ? XYBitmap : ZPixmap;
5521 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
5522 if (window->shared_memory != MagickFalse)
5527 segment_info=(XShmSegmentInfo *) window->segment_info;
5528 segment_info[1].shmid=(-1);
5529 segment_info[1].shmaddr=(char *) NULL;
5530 ximage=XShmCreateImage(display,window->visual,(unsigned int) depth,format,
5531 (char *) NULL,&segment_info[1],width,height);
5532 if (ximage == (XImage *) NULL)
5533 window->shared_memory=MagickFalse;
5534 length=(size_t) ximage->bytes_per_line*ximage->height;
5535 if (CheckOverflowException(length,ximage->bytes_per_line,ximage->height))
5536 window->shared_memory=MagickFalse;
5537 if (window->shared_memory != MagickFalse)
5538 segment_info[1].shmid=shmget(IPC_PRIVATE,length,IPC_CREAT | 0777);
5539 if (window->shared_memory != MagickFalse)
5540 segment_info[1].shmaddr=(char *) shmat(segment_info[1].shmid,0,0);
5541 if (segment_info[1].shmid < 0)
5542 window->shared_memory=MagickFalse;
5543 if (window->shared_memory != MagickFalse)
5544 (void) shmctl(segment_info[1].shmid,IPC_RMID,0);
5547 if (ximage != (XImage *) NULL)
5548 XDestroyImage(ximage);
5549 ximage=(XImage *) NULL;
5550 if (segment_info[1].shmaddr)
5552 (void) shmdt(segment_info[1].shmaddr);
5553 segment_info[1].shmaddr=(char *) NULL;
5555 if (segment_info[1].shmid >= 0)
5557 (void) shmctl(segment_info[1].shmid,IPC_RMID,0);
5558 segment_info[1].shmid=(-1);
5564 Allocate X image pixel data.
5566 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
5567 if (window->shared_memory)
5575 (void) XSync(display,MagickFalse);
5576 xerror_alert=MagickFalse;
5577 segment_info=(XShmSegmentInfo *) window->segment_info;
5578 ximage->data=segment_info[1].shmaddr;
5579 segment_info[1].readOnly=MagickFalse;
5580 status=XShmAttach(display,&segment_info[1]);
5581 if (status != False)
5582 (void) XSync(display,MagickFalse);
5583 if ((status == False) || (xerror_alert != MagickFalse))
5585 window->shared_memory=MagickFalse;
5586 if (status != False)
5587 XShmDetach(display,&segment_info[1]);
5588 if (ximage != (XImage *) NULL)
5591 XDestroyImage(ximage);
5592 ximage=(XImage *) NULL;
5594 if (segment_info[1].shmid >= 0)
5596 if (segment_info[1].shmaddr != NULL)
5597 (void) shmdt(segment_info[1].shmaddr);
5598 (void) shmctl(segment_info[1].shmid,IPC_RMID,0);
5599 segment_info[1].shmid=(-1);
5600 segment_info[1].shmaddr=(char *) NULL;
5605 if (window->shared_memory == MagickFalse)
5606 ximage=XCreateImage(display,window->visual,(unsigned int) depth,format,0,
5607 (char *) NULL,width,height,XBitmapPad(display),0);
5608 if (ximage == (XImage *) NULL)
5611 Unable to create X image.
5613 (void) XCheckDefineCursor(display,window->id,window->cursor);
5614 return(MagickFalse);
5616 length=(size_t) ximage->bytes_per_line*ximage->height;
5617 if (IsEventLogging())
5619 (void) LogMagickEvent(X11Event,GetMagickModule(),"XImage:");
5620 (void) LogMagickEvent(X11Event,GetMagickModule()," width, height: %dx%d",
5621 ximage->width,ximage->height);
5622 (void) LogMagickEvent(X11Event,GetMagickModule()," format: %d",
5624 (void) LogMagickEvent(X11Event,GetMagickModule()," byte order: %d",
5625 ximage->byte_order);
5626 (void) LogMagickEvent(X11Event,GetMagickModule(),
5627 " bitmap unit, bit order, pad: %d %d %d",ximage->bitmap_unit,
5628 ximage->bitmap_bit_order,ximage->bitmap_pad);
5629 (void) LogMagickEvent(X11Event,GetMagickModule()," depth: %d",
5631 (void) LogMagickEvent(X11Event,GetMagickModule()," bytes per line: %d",
5632 ximage->bytes_per_line);
5633 (void) LogMagickEvent(X11Event,GetMagickModule()," bits per pixel: %d",
5634 ximage->bits_per_pixel);
5635 (void) LogMagickEvent(X11Event,GetMagickModule(),
5636 " red, green, blue masks: 0x%lx 0x%lx 0x%lx",ximage->red_mask,
5637 ximage->green_mask,ximage->blue_mask);
5639 if (window->shared_memory == MagickFalse)
5641 if (ximage->format != XYBitmap)
5642 ximage->data=(char *) AcquireQuantumMemory((size_t)
5643 ximage->bytes_per_line,(size_t) ximage->height);
5645 ximage->data=(char *) AcquireQuantumMemory((size_t)
5646 ximage->bytes_per_line*ximage->depth,(size_t) ximage->height);
5648 if (ximage->data == (char *) NULL)
5651 Unable to allocate pixel data.
5653 XDestroyImage(ximage);
5654 ximage=(XImage *) NULL;
5655 (void) XCheckDefineCursor(display,window->id,window->cursor);
5656 return(MagickFalse);
5658 if (window->ximage != (XImage *) NULL)
5661 Destroy previous X image.
5663 length=(size_t) window->ximage->bytes_per_line*window->ximage->height;
5664 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
5665 if (window->segment_info != (XShmSegmentInfo *) NULL)
5670 segment_info=(XShmSegmentInfo *) window->segment_info;
5671 if (segment_info[0].shmid >= 0)
5673 (void) XSync(display,MagickFalse);
5674 (void) XShmDetach(display,&segment_info[0]);
5675 (void) XSync(display,MagickFalse);
5676 if (segment_info[0].shmaddr != (char *) NULL)
5677 (void) shmdt(segment_info[0].shmaddr);
5678 (void) shmctl(segment_info[0].shmid,IPC_RMID,0);
5679 segment_info[0].shmid=(-1);
5680 segment_info[0].shmaddr=(char *) NULL;
5681 window->ximage->data=(char *) NULL;
5685 if (window->ximage->data != (char *) NULL)
5686 free(window->ximage->data);
5687 window->ximage->data=(char *) NULL;
5688 XDestroyImage(window->ximage);
5689 window->ximage=(XImage *) NULL;
5691 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
5692 if (window->segment_info != (XShmSegmentInfo *) NULL)
5697 segment_info=(XShmSegmentInfo *) window->segment_info;
5698 segment_info[0]=segment_info[1];
5701 window->ximage=ximage;
5702 matte_image=(XImage *) NULL;
5703 if ((window->shape != MagickFalse) && (window->image != (Image *) NULL))
5704 if ((window->image->matte != MagickFalse) &&
5705 ((int) width <= XDisplayWidth(display,window->screen)) &&
5706 ((int) height <= XDisplayHeight(display,window->screen)))
5711 matte_image=XCreateImage(display,window->visual,1,XYBitmap,0,
5712 (char *) NULL,width,height,XBitmapPad(display),0);
5713 if (IsEventLogging())
5715 (void) LogMagickEvent(X11Event,GetMagickModule(),"Matte Image:");
5716 (void) LogMagickEvent(X11Event,GetMagickModule(),
5717 " width, height: %dx%d",matte_image->width,matte_image->height);
5719 if (matte_image != (XImage *) NULL)
5722 Allocate matte image pixel data.
5724 matte_image->data=(char *) AcquireQuantumMemory((size_t)
5725 matte_image->bytes_per_line*matte_image->depth,
5726 (size_t) matte_image->height);
5727 if (matte_image->data == (char *) NULL)
5729 XDestroyImage(matte_image);
5730 matte_image=(XImage *) NULL;
5734 if (window->matte_image != (XImage *) NULL)
5739 if (window->matte_image->data != (char *) NULL)
5740 free(window->matte_image->data);
5741 window->matte_image->data=(char *) NULL;
5742 XDestroyImage(window->matte_image);
5743 window->matte_image=(XImage *) NULL;
5745 window->matte_image=matte_image;
5746 if (window->matte_pixmap != (Pixmap) NULL)
5748 (void) XFreePixmap(display,window->matte_pixmap);
5749 window->matte_pixmap=(Pixmap) NULL;
5750 #if defined(MAGICKCORE_HAVE_SHAPE)
5751 if (window->shape != MagickFalse)
5752 XShapeCombineMask(display,window->id,ShapeBounding,0,0,None,ShapeSet);
5755 window->stasis=MagickFalse;
5757 Convert pixels to X image data.
5759 if (window->image != (Image *) NULL)
5761 if ((ximage->byte_order == LSBFirst) || ((ximage->format == XYBitmap) &&
5762 (ximage->bitmap_bit_order == LSBFirst)))
5763 XMakeImageLSBFirst(resource_info,window,window->image,ximage,
5766 XMakeImageMSBFirst(resource_info,window,window->image,ximage,
5769 if (window->matte_image != (XImage *) NULL)
5772 Create matte pixmap.
5774 window->matte_pixmap=XCreatePixmap(display,window->id,width,height,1);
5775 if (window->matte_pixmap != (Pixmap) NULL)
5784 Copy matte image to matte pixmap.
5786 context_values.background=0;
5787 context_values.foreground=1;
5788 graphics_context=XCreateGC(display,window->matte_pixmap,
5789 (size_t) (GCBackground | GCForeground),&context_values);
5790 (void) XPutImage(display,window->matte_pixmap,graphics_context,
5791 window->matte_image,0,0,0,0,width,height);
5792 (void) XFreeGC(display,graphics_context);
5793 #if defined(MAGICKCORE_HAVE_SHAPE)
5794 if (window->shape != MagickFalse)
5795 XShapeCombineMask(display,window->id,ShapeBounding,0,0,
5796 window->matte_pixmap,ShapeSet);
5800 (void) XMakePixmap(display,resource_info,window);
5804 (void) XCheckDefineCursor(display,window->id,window->cursor);
5809 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5813 + X M a k e I m a g e L S B F i r s t %
5817 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5819 % XMakeImageLSBFirst() initializes the pixel data of an X11 Image. The X image
5820 % pixels are copied in least-significant bit and byte first order. The
5821 % server's scanline pad is respected. Rather than using one or two general
5822 % cases, many special cases are found here to help speed up the image
5825 % The format of the XMakeImageLSBFirst method is:
5827 % void XMakeImageLSBFirst(Display *display,XWindows *windows)
5829 % A description of each parameter follows:
5831 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
5833 % o window: Specifies a pointer to a XWindowInfo structure.
5835 % o image: the image.
5837 % o ximage: Specifies a pointer to a XImage structure; returned from
5840 % o matte_image: Specifies a pointer to a XImage structure; returned from
5844 static void XMakeImageLSBFirst(const XResourceInfo *resource_info,
5845 const XWindowInfo *window,Image *image,XImage *ximage,XImage *matte_image)
5856 register const Quantum
5862 register unsigned char
5879 assert(resource_info != (XResourceInfo *) NULL);
5880 assert(window != (XWindowInfo *) NULL);
5881 assert(image != (Image *) NULL);
5882 if (image->debug != MagickFalse)
5883 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
5885 if ((window->immutable == MagickFalse) &&
5886 (image->storage_class == DirectClass) && (image->matte != MagickFalse))
5889 size[MaxTextExtent];
5897 image_info=AcquireImageInfo();
5898 (void) CopyMagickString(image_info->filename,
5899 resource_info->image_info->texture != (char *) NULL ?
5900 resource_info->image_info->texture : "pattern:checkerboard",
5902 (void) FormatLocaleString(size,MaxTextExtent,"%.20gx%.20g",(double)
5903 image->columns,(double) image->rows);
5904 image_info->size=ConstantString(size);
5905 pattern=ReadImage(image_info,&image->exception);
5906 image_info=DestroyImageInfo(image_info);
5907 if (pattern != (Image *) NULL)
5909 canvas=CloneImage(image,0,0,MagickTrue,&image->exception);
5910 if (canvas != (Image *) NULL)
5911 (void) CompositeImage(canvas,DstOverCompositeOp,pattern,0,0);
5912 pattern=DestroyImage(pattern);
5915 scanline_pad=(unsigned int) (ximage->bytes_per_line-((ximage->width*
5916 ximage->bits_per_pixel) >> 3));
5917 map_info=window->map_info;
5918 pixels=window->pixel_info->pixels;
5919 q=(unsigned char *) ximage->data;
5921 canvas_view=AcquireCacheView(canvas);
5922 if (ximage->format == XYBitmap)
5924 register unsigned short
5932 Convert canvas to big-endian bitmap.
5934 background=(unsigned char)
5935 (XPixelIntensity(&window->pixel_info->foreground_color) <
5936 XPixelIntensity(&window->pixel_info->background_color) ? 0x80 : 0x00);
5937 foreground=(unsigned char)
5938 (XPixelIntensity(&window->pixel_info->background_color) <
5939 XPixelIntensity(&window->pixel_info->foreground_color) ? 0x80 : 0x00);
5940 polarity=(unsigned short) ((GetPixelPacketIntensity(
5941 &canvas->colormap[0])) < ((Quantum) QuantumRange/2) ? 1 : 0);
5942 if (canvas->colors == 2)
5943 polarity=GetPixelPacketIntensity(&canvas->colormap[0]) <
5944 GetPixelPacketIntensity(&canvas->colormap[1]);
5945 for (y=0; y < (int) canvas->rows; y++)
5947 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,canvas->columns,1,
5948 &canvas->exception);
5949 if (p == (const Quantum *) NULL)
5953 for (x=0; x < (int) canvas->columns; x++)
5956 if (GetPixelIndex(canvas,p) == (Quantum) polarity)
5967 p+=GetPixelChannels(canvas);
5975 if (window->pixel_info->colors != 0)
5976 switch (ximage->bits_per_pixel)
5980 register unsigned int
5984 Convert to 2 bit color-mapped X canvas.
5986 for (y=0; y < (int) canvas->rows; y++)
5988 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
5989 canvas->columns,1,&canvas->exception);
5990 if (p == (const Quantum *) NULL)
5993 for (x=0; x < (int) canvas->columns; x++)
5995 pixel=pixels[(ssize_t) GetPixelIndex(canvas,p)] & 0x0f;
6000 *q=(unsigned char) pixel;
6006 *q|=(unsigned char) (pixel << 2);
6012 *q|=(unsigned char) (pixel << 4);
6018 *q|=(unsigned char) (pixel << 6);
6024 p+=GetPixelChannels(canvas);
6032 register unsigned int
6036 Convert to 4 bit color-mapped X canvas.
6038 for (y=0; y < (int) canvas->rows; y++)
6040 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6041 canvas->columns,1,&canvas->exception);
6042 if (p == (const Quantum *) NULL)
6045 for (x=0; x < (int) canvas->columns; x++)
6047 pixel=pixels[(ssize_t) GetPixelIndex(canvas,p)] & 0xf;
6052 *q=(unsigned char) pixel;
6058 *q|=(unsigned char) (pixel << 4);
6064 p+=GetPixelChannels(canvas);
6074 Convert to 8 bit color-mapped X canvas.
6076 if (resource_info->color_recovery &&
6077 resource_info->quantize_info->dither)
6079 XDitherImage(canvas,ximage);
6082 for (y=0; y < (int) canvas->rows; y++)
6084 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6085 canvas->columns,1,&canvas->exception);
6086 if (p == (const Quantum *) NULL)
6088 for (x=0; x < (int) canvas->columns; x++)
6090 pixel=pixels[(ssize_t) GetPixelIndex(canvas,p)];
6091 *q++=(unsigned char) pixel;
6092 p+=GetPixelChannels(canvas);
6103 register unsigned int
6107 channel[sizeof(size_t)];
6110 Convert to multi-byte color-mapped X canvas.
6112 bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3);
6113 for (y=0; y < (int) canvas->rows; y++)
6115 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6116 canvas->columns,1,&canvas->exception);
6117 if (p == (const Quantum *) NULL)
6119 for (x=0; x < (int) canvas->columns; x++)
6121 pixel=pixels[(ssize_t) GetPixelIndex(canvas,p)];
6122 for (k=0; k < (int) bytes_per_pixel; k++)
6124 channel[k]=(unsigned char) pixel;
6127 for (k=0; k < (int) bytes_per_pixel; k++)
6129 p+=GetPixelChannels(canvas);
6137 switch (ximage->bits_per_pixel)
6141 register unsigned int
6145 Convert to contiguous 2 bit continuous-tone X canvas.
6147 for (y=0; y < (int) canvas->rows; y++)
6150 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6151 canvas->columns,1,&canvas->exception);
6152 if (p == (const Quantum *) NULL)
6154 for (x=0; x < (int) canvas->columns; x++)
6156 pixel=XGammaPixel(canvas,map_info,p);
6162 *q=(unsigned char) pixel;
6168 *q|=(unsigned char) (pixel << 2);
6174 *q|=(unsigned char) (pixel << 4);
6180 *q|=(unsigned char) (pixel << 6);
6186 p+=GetPixelChannels(canvas);
6194 register unsigned int
6198 Convert to contiguous 4 bit continuous-tone X canvas.
6200 for (y=0; y < (int) canvas->rows; y++)
6202 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6203 canvas->columns,1,&canvas->exception);
6204 if (p == (const Quantum *) NULL)
6207 for (x=0; x < (int) canvas->columns; x++)
6209 pixel=XGammaPixel(canvas,map_info,p);
6215 *q=(unsigned char) pixel;
6221 *q|=(unsigned char) (pixel << 4);
6227 p+=GetPixelChannels(canvas);
6237 Convert to contiguous 8 bit continuous-tone X canvas.
6239 if (resource_info->color_recovery &&
6240 resource_info->quantize_info->dither)
6242 XDitherImage(canvas,ximage);
6245 for (y=0; y < (int) canvas->rows; y++)
6247 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6248 canvas->columns,1,&canvas->exception);
6249 if (p == (const Quantum *) NULL)
6251 for (x=0; x < (int) canvas->columns; x++)
6253 pixel=XGammaPixel(canvas,map_info,p);
6254 *q++=(unsigned char) pixel;
6255 p+=GetPixelChannels(canvas);
6263 if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) &&
6264 (map_info->green_max == 255) && (map_info->blue_max == 255) &&
6265 (map_info->red_mult == 65536L) && (map_info->green_mult == 256) &&
6266 (map_info->blue_mult == 1))
6269 Convert to 32 bit continuous-tone X canvas.
6271 for (y=0; y < (int) canvas->rows; y++)
6273 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6274 canvas->columns,1,&canvas->exception);
6275 if (p == (const Quantum *) NULL)
6277 if ((red_gamma != 1.0) || (green_gamma != 1.0) ||
6278 (blue_gamma != 1.0))
6281 Gamma correct canvas.
6283 for (x=(int) canvas->columns-1; x >= 0; x--)
6285 *q++=ScaleQuantumToChar(XBlueGamma(
6286 GetPixelBlue(canvas,p)));
6287 *q++=ScaleQuantumToChar(XGreenGamma(
6288 GetPixelGreen(canvas,p)));
6289 *q++=ScaleQuantumToChar(XRedGamma(
6290 GetPixelRed(canvas,p)));
6292 p+=GetPixelChannels(canvas);
6296 for (x=(int) canvas->columns-1; x >= 0; x--)
6298 *q++=ScaleQuantumToChar((Quantum)
6299 GetPixelBlue(canvas,p));
6300 *q++=ScaleQuantumToChar((Quantum)
6301 GetPixelGreen(canvas,p));
6302 *q++=ScaleQuantumToChar((Quantum)
6303 GetPixelRed(canvas,p));
6305 p+=GetPixelChannels(canvas);
6310 if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) &&
6311 (map_info->green_max == 255) && (map_info->blue_max == 255) &&
6312 (map_info->red_mult == 1) && (map_info->green_mult == 256) &&
6313 (map_info->blue_mult == 65536L))
6316 Convert to 32 bit continuous-tone X canvas.
6318 for (y=0; y < (int) canvas->rows; y++)
6320 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6321 canvas->columns,1,&canvas->exception);
6322 if (p == (const Quantum *) NULL)
6324 if ((red_gamma != 1.0) || (green_gamma != 1.0) ||
6325 (blue_gamma != 1.0))
6328 Gamma correct canvas.
6330 for (x=(int) canvas->columns-1; x >= 0; x--)
6332 *q++=ScaleQuantumToChar(XRedGamma(
6333 GetPixelRed(canvas,p)));
6334 *q++=ScaleQuantumToChar(XGreenGamma(
6335 GetPixelGreen(canvas,p)));
6336 *q++=ScaleQuantumToChar(XBlueGamma(
6337 GetPixelBlue(canvas,p)));
6339 p+=GetPixelChannels(canvas);
6343 for (x=(int) canvas->columns-1; x >= 0; x--)
6345 *q++=ScaleQuantumToChar((Quantum)
6346 GetPixelRed(canvas,p));
6347 *q++=ScaleQuantumToChar((Quantum)
6348 GetPixelGreen(canvas,p));
6349 *q++=ScaleQuantumToChar((Quantum)
6350 GetPixelBlue(canvas,p));
6352 p+=GetPixelChannels(canvas);
6361 register unsigned int
6365 channel[sizeof(size_t)];
6368 Convert to multi-byte continuous-tone X canvas.
6370 bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3);
6371 for (y=0; y < (int) canvas->rows; y++)
6373 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6374 canvas->columns,1,&canvas->exception);
6375 if (p == (const Quantum *) NULL)
6377 for (x=0; x < (int) canvas->columns; x++)
6379 pixel=XGammaPixel(canvas,map_info,p);
6380 for (k=0; k < (int) bytes_per_pixel; k++)
6382 channel[k]=(unsigned char) pixel;
6385 for (k=0; k < (int) bytes_per_pixel; k++)
6387 p+=GetPixelChannels(canvas);
6395 if (matte_image != (XImage *) NULL)
6398 Initialize matte canvas.
6400 scanline_pad=(unsigned int) (matte_image->bytes_per_line-
6401 ((matte_image->width*matte_image->bits_per_pixel) >> 3));
6402 q=(unsigned char *) matte_image->data;
6403 for (y=0; y < (int) canvas->rows; y++)
6405 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,canvas->columns,1,
6406 &canvas->exception);
6407 if (p == (const Quantum *) NULL)
6411 for (x=(int) canvas->columns-1; x >= 0; x--)
6414 if (GetPixelAlpha(canvas,p) > (QuantumRange/2))
6423 p+=GetPixelChannels(canvas);
6430 canvas_view=DestroyCacheView(canvas_view);
6431 if (canvas != image)
6432 canvas=DestroyImage(canvas);
6436 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6440 + X M a k e I m a g e M S B F i r s t %
6444 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6446 % XMakeImageMSBFirst() initializes the pixel data of an X11 Image. The X
6447 % image pixels are copied in most-significant bit and byte first order. The
6448 % server's scanline pad is also respected. Rather than using one or two
6449 % general cases, many special cases are found here to help speed up the image
6452 % The format of the XMakeImageMSBFirst method is:
6454 % XMakeImageMSBFirst(resource_info,window,image,ximage,matte_image)
6456 % A description of each parameter follows:
6458 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
6460 % o window: Specifies a pointer to a XWindowInfo structure.
6462 % o image: the image.
6464 % o ximage: Specifies a pointer to a XImage structure; returned from
6467 % o matte_image: Specifies a pointer to a XImage structure; returned from
6471 static void XMakeImageMSBFirst(const XResourceInfo *resource_info,
6472 const XWindowInfo *window,Image *image,XImage *ximage,XImage *matte_image)
6486 register const Quantum
6489 register unsigned char
6506 assert(resource_info != (XResourceInfo *) NULL);
6507 assert(window != (XWindowInfo *) NULL);
6508 assert(image != (Image *) NULL);
6509 if (image->debug != MagickFalse)
6510 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
6512 if ((window->immutable != MagickFalse) &&
6513 (image->storage_class == DirectClass) && (image->matte != MagickFalse))
6516 size[MaxTextExtent];
6524 image_info=AcquireImageInfo();
6525 (void) CopyMagickString(image_info->filename,
6526 resource_info->image_info->texture != (char *) NULL ?
6527 resource_info->image_info->texture : "pattern:checkerboard",
6529 (void) FormatLocaleString(size,MaxTextExtent,"%.20gx%.20g",(double)
6530 image->columns,(double) image->rows);
6531 image_info->size=ConstantString(size);
6532 pattern=ReadImage(image_info,&image->exception);
6533 image_info=DestroyImageInfo(image_info);
6534 if (pattern != (Image *) NULL)
6536 canvas=CloneImage(image,0,0,MagickTrue,&image->exception);
6537 if (canvas != (Image *) NULL)
6538 (void) CompositeImage(canvas,DstOverCompositeOp,pattern,0,0);
6539 pattern=DestroyImage(pattern);
6542 scanline_pad=(unsigned int) (ximage->bytes_per_line-((ximage->width*
6543 ximage->bits_per_pixel) >> 3));
6544 map_info=window->map_info;
6545 pixels=window->pixel_info->pixels;
6546 q=(unsigned char *) ximage->data;
6548 canvas_view=AcquireCacheView(canvas);
6549 if (ximage->format == XYBitmap)
6551 register unsigned short
6559 Convert canvas to big-endian bitmap.
6561 background=(unsigned char)
6562 (XPixelIntensity(&window->pixel_info->foreground_color) <
6563 XPixelIntensity(&window->pixel_info->background_color) ? 0x01 : 0x00);
6564 foreground=(unsigned char)
6565 (XPixelIntensity(&window->pixel_info->background_color) <
6566 XPixelIntensity(&window->pixel_info->foreground_color) ? 0x01 : 0x00);
6567 polarity=(unsigned short) ((GetPixelPacketIntensity(
6568 &canvas->colormap[0])) < ((Quantum) QuantumRange/2) ? 1 : 0);
6569 if (canvas->colors == 2)
6570 polarity=GetPixelPacketIntensity(&canvas->colormap[0]) <
6571 GetPixelPacketIntensity(&canvas->colormap[1]);
6572 for (y=0; y < (int) canvas->rows; y++)
6574 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,canvas->columns,1,
6575 &canvas->exception);
6576 if (p == (const Quantum *) NULL)
6580 for (x=(int) canvas->columns-1; x >= 0; x--)
6583 if (GetPixelIndex(canvas,p) == (Quantum) polarity)
6594 p+=GetPixelChannels(canvas);
6602 if (window->pixel_info->colors != 0)
6603 switch (ximage->bits_per_pixel)
6607 register unsigned int
6611 Convert to 2 bit color-mapped X canvas.
6613 for (y=0; y < (int) canvas->rows; y++)
6615 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6616 canvas->columns,1,&canvas->exception);
6617 if (p == (const Quantum *) NULL)
6620 for (x=0; x < (int) canvas->columns; x++)
6622 pixel=pixels[(ssize_t)
6623 GetPixelIndex(canvas,p)] & 0xf;
6628 *q=(unsigned char) (pixel << 6);
6634 *q|=(unsigned char) (pixel << 4);
6640 *q|=(unsigned char) (pixel << 2);
6646 *q|=(unsigned char) pixel;
6652 p+=GetPixelChannels(canvas);
6660 register unsigned int
6664 Convert to 4 bit color-mapped X canvas.
6666 for (y=0; y < (int) canvas->rows; y++)
6668 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6669 canvas->columns,1,&canvas->exception);
6670 if (p == (const Quantum *) NULL)
6673 for (x=0; x < (int) canvas->columns; x++)
6675 pixel=pixels[(ssize_t)
6676 GetPixelIndex(canvas,p)] & 0xf;
6681 *q=(unsigned char) (pixel << 4);
6687 *q|=(unsigned char) pixel;
6693 p+=GetPixelChannels(canvas);
6703 Convert to 8 bit color-mapped X canvas.
6705 if (resource_info->color_recovery &&
6706 resource_info->quantize_info->dither)
6708 XDitherImage(canvas,ximage);
6711 for (y=0; y < (int) canvas->rows; y++)
6713 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6714 canvas->columns,1,&canvas->exception);
6715 if (p == (const Quantum *) NULL)
6717 for (x=0; x < (int) canvas->columns; x++)
6719 pixel=pixels[(ssize_t)
6720 GetPixelIndex(canvas,p)];
6721 *q++=(unsigned char) pixel;
6722 p+=GetPixelChannels(canvas);
6733 register unsigned int
6737 channel[sizeof(size_t)];
6740 Convert to 8 bit color-mapped X canvas.
6742 bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3);
6743 for (y=0; y < (int) canvas->rows; y++)
6745 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6746 canvas->columns,1,&canvas->exception);
6747 if (p == (const Quantum *) NULL)
6749 for (x=0; x < (int) canvas->columns; x++)
6751 pixel=pixels[(ssize_t)
6752 GetPixelIndex(canvas,p)];
6753 for (k=(int) bytes_per_pixel-1; k >= 0; k--)
6755 channel[k]=(unsigned char) pixel;
6758 for (k=0; k < (int) bytes_per_pixel; k++)
6760 p+=GetPixelChannels(canvas);
6768 switch (ximage->bits_per_pixel)
6772 register unsigned int
6776 Convert to 4 bit continuous-tone X canvas.
6778 for (y=0; y < (int) canvas->rows; y++)
6780 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6781 canvas->columns,1,&canvas->exception);
6782 if (p == (const Quantum *) NULL)
6785 for (x=(int) canvas->columns-1; x >= 0; x--)
6787 pixel=XGammaPixel(canvas,map_info,p);
6793 *q=(unsigned char) (pixel << 6);
6799 *q|=(unsigned char) (pixel << 4);
6805 *q|=(unsigned char) (pixel << 2);
6811 *q|=(unsigned char) pixel;
6817 p+=GetPixelChannels(canvas);
6825 register unsigned int
6829 Convert to 4 bit continuous-tone X canvas.
6831 for (y=0; y < (int) canvas->rows; y++)
6833 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6834 canvas->columns,1,&canvas->exception);
6835 if (p == (const Quantum *) NULL)
6838 for (x=(int) canvas->columns-1; x >= 0; x--)
6840 pixel=XGammaPixel(canvas,map_info,p);
6846 *q=(unsigned char) (pixel << 4);
6852 *q|=(unsigned char) pixel;
6858 p+=GetPixelChannels(canvas);
6868 Convert to 8 bit continuous-tone X canvas.
6870 if (resource_info->color_recovery &&
6871 resource_info->quantize_info->dither)
6873 XDitherImage(canvas,ximage);
6876 for (y=0; y < (int) canvas->rows; y++)
6878 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6879 canvas->columns,1,&canvas->exception);
6880 if (p == (const Quantum *) NULL)
6882 for (x=(int) canvas->columns-1; x >= 0; x--)
6884 pixel=XGammaPixel(canvas,map_info,p);
6885 *q++=(unsigned char) pixel;
6886 p+=GetPixelChannels(canvas);
6894 if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) &&
6895 (map_info->green_max == 255) && (map_info->blue_max == 255) &&
6896 (map_info->red_mult == 65536L) && (map_info->green_mult == 256) &&
6897 (map_info->blue_mult == 1))
6900 Convert to 32 bit continuous-tone X canvas.
6902 for (y=0; y < (int) canvas->rows; y++)
6904 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6905 canvas->columns,1,&canvas->exception);
6906 if (p == (const Quantum *) NULL)
6908 if ((red_gamma != 1.0) || (green_gamma != 1.0) ||
6909 (blue_gamma != 1.0))
6912 Gamma correct canvas.
6914 for (x=(int) canvas->columns-1; x >= 0; x--)
6917 *q++=ScaleQuantumToChar(XRedGamma(
6918 GetPixelRed(canvas,p)));
6919 *q++=ScaleQuantumToChar(XGreenGamma(
6920 GetPixelGreen(canvas,p)));
6921 *q++=ScaleQuantumToChar(XBlueGamma(
6922 GetPixelBlue(canvas,p)));
6923 p+=GetPixelChannels(canvas);
6927 for (x=(int) canvas->columns-1; x >= 0; x--)
6930 *q++=ScaleQuantumToChar((Quantum)
6931 GetPixelRed(canvas,p));
6932 *q++=ScaleQuantumToChar((Quantum)
6933 GetPixelGreen(canvas,p));
6934 *q++=ScaleQuantumToChar((Quantum)
6935 GetPixelBlue(canvas,p));
6936 p+=GetPixelChannels(canvas);
6941 if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) &&
6942 (map_info->green_max == 255) && (map_info->blue_max == 255) &&
6943 (map_info->red_mult == 1) && (map_info->green_mult == 256) &&
6944 (map_info->blue_mult == 65536L))
6947 Convert to 32 bit continuous-tone X canvas.
6949 for (y=0; y < (int) canvas->rows; y++)
6951 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6952 canvas->columns,1,&canvas->exception);
6953 if (p == (const Quantum *) NULL)
6955 if ((red_gamma != 1.0) || (green_gamma != 1.0) ||
6956 (blue_gamma != 1.0))
6959 Gamma correct canvas.
6961 for (x=(int) canvas->columns-1; x >= 0; x--)
6964 *q++=ScaleQuantumToChar(XBlueGamma(
6965 GetPixelBlue(canvas,p)));
6966 *q++=ScaleQuantumToChar(XGreenGamma(
6967 GetPixelGreen(canvas,p)));
6968 *q++=ScaleQuantumToChar(XRedGamma(
6969 GetPixelRed(canvas,p)));
6970 p+=GetPixelChannels(canvas);
6974 for (x=(int) canvas->columns-1; x >= 0; x--)
6977 *q++=ScaleQuantumToChar((Quantum)
6978 GetPixelBlue(canvas,p));
6979 *q++=ScaleQuantumToChar((Quantum)
6980 GetPixelGreen(canvas,p));
6981 *q++=ScaleQuantumToChar((Quantum)
6982 GetPixelRed(canvas,p));
6983 p+=GetPixelChannels(canvas);
6992 register unsigned int
6996 channel[sizeof(size_t)];
6999 Convert to multi-byte continuous-tone X canvas.
7001 bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3);
7002 for (y=0; y < (int) canvas->rows; y++)
7004 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
7005 canvas->columns,1,&canvas->exception);
7006 if (p == (const Quantum *) NULL)
7008 for (x=(int) canvas->columns-1; x >= 0; x--)
7010 pixel=XGammaPixel(canvas,map_info,p);
7011 for (k=(int) bytes_per_pixel-1; k >= 0; k--)
7013 channel[k]=(unsigned char) pixel;
7016 for (k=0; k < (int) bytes_per_pixel; k++)
7018 p+=GetPixelChannels(canvas);
7026 if (matte_image != (XImage *) NULL)
7029 Initialize matte canvas.
7031 scanline_pad=(unsigned int) (matte_image->bytes_per_line-
7032 ((matte_image->width*matte_image->bits_per_pixel) >> 3));
7033 q=(unsigned char *) matte_image->data;
7034 for (y=0; y < (int) canvas->rows; y++)
7036 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,canvas->columns,1,
7037 &canvas->exception);
7038 if (p == (const Quantum *) NULL)
7042 for (x=(int) canvas->columns-1; x >= 0; x--)
7045 if (GetPixelAlpha(canvas,p) > (QuantumRange/2))
7054 p+=GetPixelChannels(canvas);
7061 canvas_view=DestroyCacheView(canvas_view);
7062 if (canvas != image)
7063 canvas=DestroyImage(canvas);
7067 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7071 % X M a k e M a g n i f y I m a g e %
7075 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7077 % XMakeMagnifyImage() magnifies a region of an X image and displays it.
7079 % The format of the XMakeMagnifyImage method is:
7081 % void XMakeMagnifyImage(display,windows)
7083 % A description of each parameter follows:
7085 % o display: Specifies a connection to an X server; returned from
7088 % o windows: Specifies a pointer to a XWindows structure.
7091 MagickPrivate void XMakeMagnifyImage(Display *display,XWindows *windows)
7094 tuple[MaxTextExtent];
7108 register unsigned char
7116 previous_magnify = 0;
7134 Check boundary conditions.
7136 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
7137 assert(display != (Display *) NULL);
7138 assert(windows != (XWindows *) NULL);
7140 for (n=1; n < (ssize_t) windows->magnify.data; n++)
7142 while ((magnify*windows->image.ximage->width) < windows->magnify.width)
7144 while ((magnify*windows->image.ximage->height) < windows->magnify.height)
7146 while (magnify > windows->magnify.width)
7148 while (magnify > windows->magnify.height)
7150 if (magnify != previous_magnify)
7159 New magnify factor: update magnify window name.
7162 while ((1 << i) <= (int) magnify)
7164 (void) FormatLocaleString(windows->magnify.name,MaxTextExtent,
7165 "Magnify %.20gX",(double) i);
7166 status=XStringListToTextProperty(&windows->magnify.name,1,&window_name);
7167 if (status != False)
7169 XSetWMName(display,windows->magnify.id,&window_name);
7170 XSetWMIconName(display,windows->magnify.id,&window_name);
7171 (void) XFree((void *) window_name.value);
7174 previous_magnify=magnify;
7175 ximage=windows->image.ximage;
7176 width=(unsigned int) windows->magnify.ximage->width;
7177 height=(unsigned int) windows->magnify.ximage->height;
7178 if ((windows->magnify.x < 0) ||
7179 (windows->magnify.x >= windows->image.ximage->width))
7180 windows->magnify.x=windows->image.ximage->width >> 1;
7181 x=windows->magnify.x-((width/magnify) >> 1);
7185 if (x > (int) (ximage->width-(width/magnify)))
7186 x=ximage->width-width/magnify;
7187 if ((windows->magnify.y < 0) ||
7188 (windows->magnify.y >= windows->image.ximage->height))
7189 windows->magnify.y=windows->image.ximage->height >> 1;
7190 y=windows->magnify.y-((height/magnify) >> 1);
7194 if (y > (int) (ximage->height-(height/magnify)))
7195 y=ximage->height-height/magnify;
7196 q=(unsigned char *) windows->magnify.ximage->data;
7197 scanline_pad=(unsigned int) (windows->magnify.ximage->bytes_per_line-
7198 ((width*windows->magnify.ximage->bits_per_pixel) >> 3));
7199 if (ximage->bits_per_pixel < 8)
7201 register unsigned char
7208 register unsigned int
7214 pixel_info=windows->magnify.pixel_info;
7215 switch (ximage->bitmap_bit_order)
7220 Magnify little-endian bitmap.
7224 if (ximage->format == XYBitmap)
7226 background=(unsigned char)
7227 (XPixelIntensity(&pixel_info->foreground_color) <
7228 XPixelIntensity(&pixel_info->background_color) ? 0x80 : 0x00);
7229 foreground=(unsigned char)
7230 (XPixelIntensity(&pixel_info->background_color) <
7231 XPixelIntensity(&pixel_info->foreground_color) ? 0x80 : 0x00);
7232 if (windows->magnify.depth > 1)
7233 Swap(background,foreground);
7235 for (i=0; i < (ssize_t) height; i+=magnify)
7238 Propogate pixel magnify rows.
7240 for (j=0; j < magnify; j++)
7242 p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
7243 ((x*ximage->bits_per_pixel) >> 3);
7244 p_bit=(unsigned char) (x*ximage->bits_per_pixel) & 0x07;
7247 for (k=0; k < width; k+=magnify)
7250 Propogate pixel magnify columns.
7252 for (l=0; l < magnify; l++)
7255 Propogate each bit plane.
7257 for (plane=0; (int) plane < ximage->bits_per_pixel; plane++)
7260 if (*p & (0x01 << (p_bit+plane)))
7273 p_bit+=ximage->bits_per_pixel;
7280 *q=byte >> (8-q_bit);
7292 Magnify big-endian bitmap.
7296 if (ximage->format == XYBitmap)
7298 background=(unsigned char)
7299 (XPixelIntensity(&pixel_info->foreground_color) <
7300 XPixelIntensity(&pixel_info->background_color) ? 0x01 : 0x00);
7301 foreground=(unsigned char)
7302 (XPixelIntensity(&pixel_info->background_color) <
7303 XPixelIntensity(&pixel_info->foreground_color) ? 0x01 : 0x00);
7304 if (windows->magnify.depth > 1)
7305 Swap(background,foreground);
7307 for (i=0; i < (ssize_t) height; i+=magnify)
7310 Propogate pixel magnify rows.
7312 for (j=0; j < magnify; j++)
7314 p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
7315 ((x*ximage->bits_per_pixel) >> 3);
7316 p_bit=(unsigned char) (x*ximage->bits_per_pixel) & 0x07;
7319 for (k=0; k < width; k+=magnify)
7322 Propogate pixel magnify columns.
7324 for (l=0; l < magnify; l++)
7327 Propogate each bit plane.
7329 for (plane=0; (int) plane < ximage->bits_per_pixel; plane++)
7332 if (*p & (0x80 >> (p_bit+plane)))
7345 p_bit+=ximage->bits_per_pixel;
7352 *q=byte << (8-q_bit);
7363 switch (ximage->bits_per_pixel)
7369 Magnify 8 bit X image.
7371 for (i=0; i < (ssize_t) height; i+=magnify)
7374 Propogate pixel magnify rows.
7376 for (j=0; j < magnify; j++)
7378 p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
7379 ((x*ximage->bits_per_pixel) >> 3);
7380 for (k=0; k < width; k+=magnify)
7383 Propogate pixel magnify columns.
7385 for (l=0; l < magnify; l++)
7397 register unsigned int
7402 Magnify multi-byte X image.
7404 bytes_per_pixel=(unsigned int) ximage->bits_per_pixel >> 3;
7405 for (i=0; i < (ssize_t) height; i+=magnify)
7408 Propogate pixel magnify rows.
7410 for (j=0; j < magnify; j++)
7412 p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
7413 ((x*ximage->bits_per_pixel) >> 3);
7414 for (k=0; k < width; k+=magnify)
7417 Propogate pixel magnify columns.
7419 for (l=0; l < magnify; l++)
7420 for (m=0; m < bytes_per_pixel; m++)
7432 Copy X image to magnify pixmap.
7434 x=windows->magnify.x-((width/magnify) >> 1);
7436 x=(int) ((width >> 1)-windows->magnify.x*magnify);
7438 if (x > (int) (ximage->width-(width/magnify)))
7439 x=(int) ((ximage->width-windows->magnify.x)*magnify-(width >> 1));
7442 y=windows->magnify.y-((height/magnify) >> 1);
7444 y=(int) ((height >> 1)-windows->magnify.y*magnify);
7446 if (y > (int) (ximage->height-(height/magnify)))
7447 y=(int) ((ximage->height-windows->magnify.y)*magnify-(height >> 1));
7450 if ((x != 0) || (y != 0))
7451 (void) XFillRectangle(display,windows->magnify.pixmap,
7452 windows->magnify.annotate_context,0,0,width,height);
7453 (void) XPutImage(display,windows->magnify.pixmap,
7454 windows->magnify.annotate_context,windows->magnify.ximage,0,0,x,y,width-x,
7456 if ((magnify > 1) && ((magnify <= (width >> 1)) &&
7457 (magnify <= (height >> 1))))
7463 Highlight center pixel.
7465 highlight_info.x=(ssize_t) windows->magnify.width >> 1;
7466 highlight_info.y=(ssize_t) windows->magnify.height >> 1;
7467 highlight_info.width=magnify;
7468 highlight_info.height=magnify;
7469 (void) XDrawRectangle(display,windows->magnify.pixmap,
7470 windows->magnify.highlight_context,(int) highlight_info.x,
7471 (int) highlight_info.y,(unsigned int) highlight_info.width-1,
7472 (unsigned int) highlight_info.height-1);
7474 (void) XDrawRectangle(display,windows->magnify.pixmap,
7475 windows->magnify.annotate_context,(int) highlight_info.x+1,
7476 (int) highlight_info.y+1,(unsigned int) highlight_info.width-3,
7477 (unsigned int) highlight_info.height-3);
7480 Show center pixel color.
7482 (void) GetOneVirtualMagickPixel(windows->image.image,(ssize_t)
7483 windows->magnify.x,(ssize_t) windows->magnify.y,&pixel,
7484 &windows->image.image->exception);
7485 (void) FormatLocaleString(tuple,MaxTextExtent,"%d,%d: ",
7486 windows->magnify.x,windows->magnify.y);
7487 (void) ConcatenateMagickString(tuple,"(",MaxTextExtent);
7488 ConcatenateColorComponent(&pixel,RedPixelChannel,X11Compliance,tuple);
7489 (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
7490 ConcatenateColorComponent(&pixel,GreenPixelChannel,X11Compliance,tuple);
7491 (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
7492 ConcatenateColorComponent(&pixel,BluePixelChannel,X11Compliance,tuple);
7493 if (pixel.colorspace == CMYKColorspace)
7495 (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
7496 ConcatenateColorComponent(&pixel,BlackPixelChannel,X11Compliance,tuple);
7498 if (pixel.matte != MagickFalse)
7500 (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
7501 ConcatenateColorComponent(&pixel,AlphaPixelChannel,X11Compliance,tuple);
7503 (void) ConcatenateMagickString(tuple,")",MaxTextExtent);
7504 height=(unsigned int) windows->magnify.font_info->ascent+
7505 windows->magnify.font_info->descent;
7506 x=windows->magnify.font_info->max_bounds.width >> 1;
7507 y=windows->magnify.font_info->ascent+(height >> 2);
7508 (void) XDrawImageString(display,windows->magnify.pixmap,
7509 windows->magnify.annotate_context,x,y,tuple,(int) strlen(tuple));
7510 GetColorTuple(&pixel,MagickTrue,tuple);
7512 (void) XDrawImageString(display,windows->magnify.pixmap,
7513 windows->magnify.annotate_context,x,y,tuple,(int) strlen(tuple));
7514 (void) QueryMagickColorname(windows->image.image,&pixel,SVGCompliance,tuple,
7515 &windows->image.image->exception);
7517 (void) XDrawImageString(display,windows->magnify.pixmap,
7518 windows->magnify.annotate_context,x,y,tuple,(int) strlen(tuple));
7520 Refresh magnify window.
7522 magnify_window=windows->magnify;
7525 XRefreshWindow(display,&magnify_window,(XEvent *) NULL);
7529 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7533 % X M a k e P i x m a p %
7537 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7539 % XMakePixmap() creates an X11 pixmap.
7541 % The format of the XMakePixmap method is:
7543 % void XMakeStandardColormap(Display *display,XVisualInfo *visual_info,
7544 % XResourceInfo *resource_info,Image *image,XStandardColormap *map_info,
7545 % XPixelInfo *pixel)
7547 % A description of each parameter follows:
7549 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
7551 % o display: Specifies a connection to an X server; returned from
7554 % o window: Specifies a pointer to a XWindowInfo structure.
7557 static MagickBooleanType XMakePixmap(Display *display,
7558 const XResourceInfo *resource_info,XWindowInfo *window)
7564 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
7565 assert(display != (Display *) NULL);
7566 assert(resource_info != (XResourceInfo *) NULL);
7567 assert(window != (XWindowInfo *) NULL);
7568 if (window->pixmap != (Pixmap) NULL)
7571 Destroy previous X pixmap.
7573 (void) XFreePixmap(display,window->pixmap);
7574 window->pixmap=(Pixmap) NULL;
7576 if (window->use_pixmap == MagickFalse)
7577 return(MagickFalse);
7578 if (window->ximage == (XImage *) NULL)
7579 return(MagickFalse);
7581 Display busy cursor.
7583 (void) XCheckDefineCursor(display,window->id,window->busy_cursor);
7584 (void) XFlush(display);
7588 width=(unsigned int) window->ximage->width;
7589 height=(unsigned int) window->ximage->height;
7590 window->pixmap=XCreatePixmap(display,window->id,width,height,window->depth);
7591 if (window->pixmap == (Pixmap) NULL)
7594 Unable to allocate pixmap.
7596 (void) XCheckDefineCursor(display,window->id,window->cursor);
7597 return(MagickFalse);
7600 Copy X image to pixmap.
7602 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
7603 if (window->shared_memory)
7604 (void) XShmPutImage(display,window->pixmap,window->annotate_context,
7605 window->ximage,0,0,0,0,width,height,MagickTrue);
7607 if (window->shared_memory == MagickFalse)
7608 (void) XPutImage(display,window->pixmap,window->annotate_context,
7609 window->ximage,0,0,0,0,width,height);
7610 if (IsEventLogging())
7612 (void) LogMagickEvent(X11Event,GetMagickModule(),"Pixmap:");
7613 (void) LogMagickEvent(X11Event,GetMagickModule()," width, height: %ux%u",
7619 (void) XCheckDefineCursor(display,window->id,window->cursor);
7624 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7628 % X M a k e S t a n d a r d C o l o r m a p %
7632 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7634 % XMakeStandardColormap() creates an X11 Standard Colormap.
7636 % The format of the XMakeStandardColormap method is:
7638 % XMakeStandardColormap(display,visual_info,resource_info,image,
7641 % A description of each parameter follows:
7643 % o display: Specifies a connection to an X server; returned from
7646 % o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
7647 % returned from XGetVisualInfo.
7649 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
7651 % o image: the image.
7653 % o map_info: If a Standard Colormap type is specified, this structure is
7654 % initialized with info from the Standard Colormap.
7656 % o pixel: Specifies a pointer to a XPixelInfo structure.
7660 #if defined(__cplusplus) || defined(c_plusplus)
7664 static inline MagickRealType DiversityPixelIntensity(
7665 const DiversityPacket *pixel)
7670 intensity=0.299*pixel->red+0.587*pixel->green+0.114*pixel->blue;
7674 static int IntensityCompare(const void *x,const void *y)
7683 color_1=(DiversityPacket *) x;
7684 color_2=(DiversityPacket *) y;
7685 diversity=(int) (DiversityPixelIntensity(color_2)-
7686 DiversityPixelIntensity(color_1));
7690 static int PopularityCompare(const void *x,const void *y)
7696 color_1=(DiversityPacket *) x;
7697 color_2=(DiversityPacket *) y;
7698 return((int) color_2->count-(int) color_1->count);
7701 #if defined(__cplusplus) || defined(c_plusplus)
7705 static inline Quantum ScaleXToQuantum(const size_t x,
7708 return((Quantum) (((MagickRealType) QuantumRange*x)/scale+0.5));
7711 MagickPrivate void XMakeStandardColormap(Display *display,
7712 XVisualInfo *visual_info,XResourceInfo *resource_info,Image *image,
7713 XStandardColormap *map_info,XPixelInfo *pixel)
7739 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
7740 assert(display != (Display *) NULL);
7741 assert(visual_info != (XVisualInfo *) NULL);
7742 assert(map_info != (XStandardColormap *) NULL);
7743 assert(resource_info != (XResourceInfo *) NULL);
7744 assert(pixel != (XPixelInfo *) NULL);
7745 exception=(&image->exception);
7746 if (resource_info->map_type != (char *) NULL)
7749 Standard Colormap is already defined (i.e. xstdcmap).
7751 XGetPixelInfo(display,visual_info,map_info,resource_info,image,
7753 number_colors=(unsigned int) (map_info->base_pixel+
7754 (map_info->red_max+1)*(map_info->green_max+1)*(map_info->blue_max+1));
7755 if ((map_info->red_max*map_info->green_max*map_info->blue_max) != 0)
7756 if ((image->matte == MagickFalse) &&
7757 (resource_info->color_recovery == MagickFalse) &&
7758 resource_info->quantize_info->dither &&
7759 (number_colors < MaxColormapSize))
7768 Improve image appearance with error diffusion.
7770 affinity_image=AcquireImage((ImageInfo *) NULL);
7771 if (affinity_image == (Image *) NULL)
7772 ThrowXWindowFatalException(ResourceLimitFatalError,
7773 "UnableToDitherImage",image->filename);
7774 affinity_image->columns=number_colors;
7775 affinity_image->rows=1;
7777 Initialize colormap image.
7779 q=QueueAuthenticPixels(affinity_image,0,0,affinity_image->columns,
7781 if (q != (Quantum *) NULL)
7783 for (i=0; i < (ssize_t) number_colors; i++)
7785 SetPixelRed(affinity_image,0,q);
7786 if (map_info->red_max != 0)
7787 SetPixelRed(affinity_image,
7788 ScaleXToQuantum((size_t) (i/map_info->red_mult),
7789 map_info->red_max),q);
7790 SetPixelGreen(affinity_image,0,q);
7791 if (map_info->green_max != 0)
7792 SetPixelGreen(affinity_image,
7793 ScaleXToQuantum((size_t) ((i/map_info->green_mult) %
7794 (map_info->green_max+1)),map_info->green_max),q);
7795 SetPixelBlue(affinity_image,0,q);
7796 if (map_info->blue_max != 0)
7797 SetPixelBlue(affinity_image,
7798 ScaleXToQuantum((size_t) (i % map_info->green_mult),
7799 map_info->blue_max),q);
7800 SetPixelAlpha(affinity_image,
7801 TransparentAlpha,q);
7802 q+=GetPixelChannels(affinity_image);
7804 (void) SyncAuthenticPixels(affinity_image,exception);
7805 (void) RemapImage(resource_info->quantize_info,image,
7806 affinity_image,exception);
7808 XGetPixelInfo(display,visual_info,map_info,resource_info,image,
7810 (void) SetImageStorageClass(image,DirectClass,exception);
7811 affinity_image=DestroyImage(affinity_image);
7813 if (IsEventLogging())
7815 (void) LogMagickEvent(X11Event,GetMagickModule(),
7816 "Standard Colormap:");
7817 (void) LogMagickEvent(X11Event,GetMagickModule(),
7818 " colormap id: 0x%lx",map_info->colormap);
7819 (void) LogMagickEvent(X11Event,GetMagickModule(),
7820 " red, green, blue max: %lu %lu %lu",map_info->red_max,
7821 map_info->green_max,map_info->blue_max);
7822 (void) LogMagickEvent(X11Event,GetMagickModule(),
7823 " red, green, blue mult: %lu %lu %lu",map_info->red_mult,
7824 map_info->green_mult,map_info->blue_mult);
7828 if ((visual_info->klass != DirectColor) &&
7829 (visual_info->klass != TrueColor))
7830 if ((image->storage_class == DirectClass) ||
7831 ((int) image->colors > visual_info->colormap_size))
7837 Image has more colors than the visual supports.
7839 quantize_info=(*resource_info->quantize_info);
7840 quantize_info.number_colors=(size_t) visual_info->colormap_size;
7841 (void) QuantizeImage(&quantize_info,image,exception);
7844 Free previous and create new colormap.
7846 (void) XFreeStandardColormap(display,visual_info,map_info,pixel);
7847 colormap=XDefaultColormap(display,visual_info->screen);
7848 if (visual_info->visual != XDefaultVisual(display,visual_info->screen))
7849 colormap=XCreateColormap(display,XRootWindow(display,visual_info->screen),
7850 visual_info->visual,visual_info->klass == DirectColor ?
7851 AllocAll : AllocNone);
7852 if (colormap == (Colormap) NULL)
7853 ThrowXWindowFatalException(ResourceLimitFatalError,"UnableToCreateColormap",
7856 Initialize the map and pixel info structures.
7858 XGetMapInfo(visual_info,colormap,map_info);
7859 XGetPixelInfo(display,visual_info,map_info,resource_info,image,pixel);
7861 Allocating colors in server colormap is based on visual class.
7863 switch (visual_info->klass)
7869 Define Standard Colormap for StaticGray or StaticColor visual.
7871 number_colors=image->colors;
7872 colors=(XColor *) AcquireQuantumMemory((size_t)
7873 visual_info->colormap_size,sizeof(*colors));
7874 if (colors == (XColor *) NULL)
7875 ThrowXWindowFatalException(ResourceLimitFatalError,
7876 "UnableToCreateColormap",image->filename);
7878 color.flags=(char) (DoRed | DoGreen | DoBlue);
7879 for (i=0; i < (ssize_t) image->colors; i++)
7881 color.red=ScaleQuantumToShort(XRedGamma(image->colormap[i].red));
7882 color.green=ScaleQuantumToShort(XGreenGamma(image->colormap[i].green));
7883 color.blue=ScaleQuantumToShort(XBlueGamma(image->colormap[i].blue));
7884 if (visual_info->klass != StaticColor)
7886 gray_value=(unsigned short) XPixelIntensity(&color);
7887 color.red=gray_value;
7888 color.green=gray_value;
7889 color.blue=gray_value;
7891 status=XAllocColor(display,colormap,&color);
7892 if (status == False)
7894 colormap=XCopyColormapAndFree(display,colormap);
7895 (void) XAllocColor(display,colormap,&color);
7897 pixel->pixels[i]=color.pixel;
7909 Define Standard Colormap for GrayScale or PseudoColor visual.
7911 number_colors=image->colors;
7912 colors=(XColor *) AcquireQuantumMemory((size_t)
7913 visual_info->colormap_size,sizeof(*colors));
7914 if (colors == (XColor *) NULL)
7915 ThrowXWindowFatalException(ResourceLimitFatalError,
7916 "UnableToCreateColormap",image->filename);
7918 Preallocate our GUI colors.
7920 (void) XAllocColor(display,colormap,&pixel->foreground_color);
7921 (void) XAllocColor(display,colormap,&pixel->background_color);
7922 (void) XAllocColor(display,colormap,&pixel->border_color);
7923 (void) XAllocColor(display,colormap,&pixel->matte_color);
7924 (void) XAllocColor(display,colormap,&pixel->highlight_color);
7925 (void) XAllocColor(display,colormap,&pixel->shadow_color);
7926 (void) XAllocColor(display,colormap,&pixel->depth_color);
7927 (void) XAllocColor(display,colormap,&pixel->trough_color);
7928 for (i=0; i < MaxNumberPens; i++)
7929 (void) XAllocColor(display,colormap,&pixel->pen_colors[i]);
7931 Determine if image colors will "fit" into X server colormap.
7933 colormap_type=resource_info->colormap;
7934 status=XAllocColorCells(display,colormap,MagickFalse,(unsigned long *)
7935 NULL,0,pixel->pixels,(unsigned int) image->colors);
7936 if (status != False)
7937 colormap_type=PrivateColormap;
7938 if (colormap_type == SharedColormap)
7959 Define Standard colormap for shared GrayScale or PseudoColor visual.
7961 diversity=(DiversityPacket *) AcquireQuantumMemory(image->colors,
7962 sizeof(*diversity));
7963 if (diversity == (DiversityPacket *) NULL)
7964 ThrowXWindowFatalException(ResourceLimitFatalError,
7965 "UnableToCreateColormap",image->filename);
7966 for (i=0; i < (ssize_t) image->colors; i++)
7968 diversity[i].red=image->colormap[i].red;
7969 diversity[i].green=image->colormap[i].green;
7970 diversity[i].blue=image->colormap[i].blue;
7971 diversity[i].index=(unsigned short) i;
7972 diversity[i].count=0;
7974 image_view=AcquireCacheView(image);
7975 for (y=0; y < (int) image->rows; y++)
7980 register const Quantum
7983 p=GetCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
7984 image->columns,1,exception);
7985 if (p == (const Quantum *) NULL)
7987 for (x=(int) image->columns-1; x >= 0; x--)
7989 diversity[(ssize_t) GetPixelIndex(image,p)].count++;
7990 p+=GetPixelChannels(image);
7993 image_view=DestroyCacheView(image_view);
7995 Sort colors by decreasing intensity.
7997 qsort((void *) diversity,image->colors,sizeof(*diversity),
7999 for (i=0; i < (ssize_t) image->colors; )
8001 diversity[i].count<<=4; /* increase this colors popularity */
8002 i+=MagickMax((int) (image->colors >> 4),2);
8004 diversity[image->colors-1].count<<=4;
8005 qsort((void *) diversity,image->colors,sizeof(*diversity),
8011 color.flags=(char) (DoRed | DoGreen | DoBlue);
8012 for (i=0; i < (ssize_t) image->colors; i++)
8014 index=diversity[i].index;
8016 ScaleQuantumToShort(XRedGamma(image->colormap[index].red));
8018 ScaleQuantumToShort(XGreenGamma(image->colormap[index].green));
8020 ScaleQuantumToShort(XBlueGamma(image->colormap[index].blue));
8021 if (visual_info->klass != PseudoColor)
8023 gray_value=(unsigned short) XPixelIntensity(&color);
8024 color.red=gray_value;
8025 color.green=gray_value;
8026 color.blue=gray_value;
8028 status=XAllocColor(display,colormap,&color);
8029 if (status == False)
8031 pixel->pixels[index]=color.pixel;
8035 Read X server colormap.
8037 server_colors=(XColor *) AcquireQuantumMemory((size_t)
8038 visual_info->colormap_size,sizeof(*server_colors));
8039 if (server_colors == (XColor *) NULL)
8040 ThrowXWindowFatalException(ResourceLimitFatalError,
8041 "UnableToCreateColormap",image->filename);
8042 for (x=visual_info->colormap_size-1; x >= 0; x--)
8043 server_colors[x].pixel=(size_t) x;
8044 (void) XQueryColors(display,colormap,server_colors,
8045 (int) MagickMin((unsigned int) visual_info->colormap_size,256));
8047 Select remaining colors from X server colormap.
8049 for (; i < (ssize_t) image->colors; i++)
8051 index=diversity[i].index;
8053 ScaleQuantumToShort(XRedGamma(image->colormap[index].red));
8055 ScaleQuantumToShort(XGreenGamma(image->colormap[index].green));
8057 ScaleQuantumToShort(XBlueGamma(image->colormap[index].blue));
8058 if (visual_info->klass != PseudoColor)
8060 gray_value=(unsigned short) XPixelIntensity(&color);
8061 color.red=gray_value;
8062 color.green=gray_value;
8063 color.blue=gray_value;
8065 XBestPixel(display,colormap,server_colors,(unsigned int)
8066 visual_info->colormap_size,&color);
8067 pixel->pixels[index]=color.pixel;
8070 if ((int) image->colors < visual_info->colormap_size)
8073 Fill up colors array-- more choices for pen colors.
8075 retain_colors=MagickMin((unsigned int)
8076 (visual_info->colormap_size-image->colors),256);
8077 for (i=0; i < (ssize_t) retain_colors; i++)
8078 *p++=server_colors[i];
8079 number_colors+=retain_colors;
8081 server_colors=(XColor *) RelinquishMagickMemory(server_colors);
8082 diversity=(DiversityPacket *) RelinquishMagickMemory(diversity);
8086 Define Standard colormap for private GrayScale or PseudoColor visual.
8088 if (status == False)
8091 Not enough colormap entries in the colormap-- Create a new colormap.
8093 colormap=XCreateColormap(display,
8094 XRootWindow(display,visual_info->screen),visual_info->visual,
8096 if (colormap == (Colormap) NULL)
8097 ThrowXWindowFatalException(ResourceLimitFatalError,
8098 "UnableToCreateColormap",image->filename);
8099 map_info->colormap=colormap;
8100 if ((int) image->colors < visual_info->colormap_size)
8103 Retain colors from the default colormap to help lessens the
8104 effects of colormap flashing.
8106 retain_colors=MagickMin((unsigned int)
8107 (visual_info->colormap_size-image->colors),256);
8108 p=colors+image->colors;
8109 for (i=0; i < (ssize_t) retain_colors; i++)
8111 p->pixel=(unsigned long) i;
8114 (void) XQueryColors(display,
8115 XDefaultColormap(display,visual_info->screen),
8116 colors+image->colors,(int) retain_colors);
8118 Transfer colors from default to private colormap.
8120 (void) XAllocColorCells(display,colormap,MagickFalse,
8121 (unsigned long *) NULL,0,pixel->pixels,(unsigned int)
8123 p=colors+image->colors;
8124 for (i=0; i < (ssize_t) retain_colors; i++)
8126 p->pixel=pixel->pixels[i];
8129 (void) XStoreColors(display,colormap,colors+image->colors,
8130 (int) retain_colors);
8131 number_colors+=retain_colors;
8133 (void) XAllocColorCells(display,colormap,MagickFalse,
8134 (unsigned long *) NULL,0,pixel->pixels,(unsigned int)
8138 Store the image colormap.
8141 color.flags=(char) (DoRed | DoGreen | DoBlue);
8142 for (i=0; i < (ssize_t) image->colors; i++)
8144 color.red=ScaleQuantumToShort(XRedGamma(image->colormap[i].red));
8145 color.green=ScaleQuantumToShort(XGreenGamma(image->colormap[i].green));
8146 color.blue=ScaleQuantumToShort(XBlueGamma(image->colormap[i].blue));
8147 if (visual_info->klass != PseudoColor)
8149 gray_value=(unsigned short) XPixelIntensity(&color);
8150 color.red=gray_value;
8151 color.green=gray_value;
8152 color.blue=gray_value;
8154 color.pixel=pixel->pixels[i];
8157 (void) XStoreColors(display,colormap,colors,(int) image->colors);
8168 Define Standard Colormap for TrueColor or DirectColor visual.
8170 number_colors=(unsigned int) ((map_info->red_max*map_info->red_mult)+
8171 (map_info->green_max*map_info->green_mult)+
8172 (map_info->blue_max*map_info->blue_mult)+1);
8173 linear_colormap=(number_colors > 4096) ||
8174 (((int) (map_info->red_max+1) == visual_info->colormap_size) &&
8175 ((int) (map_info->green_max+1) == visual_info->colormap_size) &&
8176 ((int) (map_info->blue_max+1) == visual_info->colormap_size)) ?
8177 MagickTrue : MagickFalse;
8178 if (linear_colormap != MagickFalse)
8179 number_colors=(size_t) visual_info->colormap_size;
8181 Allocate color array.
8183 colors=(XColor *) AcquireQuantumMemory(number_colors,sizeof(*colors));
8184 if (colors == (XColor *) NULL)
8185 ThrowXWindowFatalException(ResourceLimitFatalError,
8186 "UnableToCreateColormap",image->filename);
8188 Initialize linear color ramp.
8191 color.flags=(char) (DoRed | DoGreen | DoBlue);
8192 if (linear_colormap != MagickFalse)
8193 for (i=0; i < (ssize_t) number_colors; i++)
8195 color.blue=(unsigned short) 0;
8196 if (map_info->blue_max != 0)
8197 color.blue=(unsigned short) ((size_t)
8198 ((65535L*(i % map_info->green_mult))/map_info->blue_max));
8199 color.green=color.blue;
8200 color.red=color.blue;
8201 color.pixel=XStandardPixel(map_info,&color);
8205 for (i=0; i < (ssize_t) number_colors; i++)
8207 color.red=(unsigned short) 0;
8208 if (map_info->red_max != 0)
8209 color.red=(unsigned short) ((size_t)
8210 ((65535L*(i/map_info->red_mult))/map_info->red_max));
8211 color.green=(unsigned int) 0;
8212 if (map_info->green_max != 0)
8213 color.green=(unsigned short) ((size_t)
8214 ((65535L*((i/map_info->green_mult) % (map_info->green_max+1)))/
8215 map_info->green_max));
8216 color.blue=(unsigned short) 0;
8217 if (map_info->blue_max != 0)
8218 color.blue=(unsigned short) ((size_t)
8219 ((65535L*(i % map_info->green_mult))/map_info->blue_max));
8220 color.pixel=XStandardPixel(map_info,&color);
8223 if ((visual_info->klass == DirectColor) &&
8224 (colormap != XDefaultColormap(display,visual_info->screen)))
8225 (void) XStoreColors(display,colormap,colors,(int) number_colors);
8227 for (i=0; i < (ssize_t) number_colors; i++)
8228 (void) XAllocColor(display,colormap,&colors[i]);
8232 if ((visual_info->klass != DirectColor) &&
8233 (visual_info->klass != TrueColor))
8236 Set foreground, background, border, etc. pixels.
8238 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8239 &pixel->foreground_color);
8240 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8241 &pixel->background_color);
8242 if (pixel->background_color.pixel == pixel->foreground_color.pixel)
8245 Foreground and background colors must differ.
8247 pixel->background_color.red=(~pixel->foreground_color.red);
8248 pixel->background_color.green=
8249 (~pixel->foreground_color.green);
8250 pixel->background_color.blue=
8251 (~pixel->foreground_color.blue);
8252 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8253 &pixel->background_color);
8255 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8256 &pixel->border_color);
8257 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8258 &pixel->matte_color);
8259 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8260 &pixel->highlight_color);
8261 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8262 &pixel->shadow_color);
8263 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8264 &pixel->depth_color);
8265 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8266 &pixel->trough_color);
8267 for (i=0; i < MaxNumberPens; i++)
8269 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8270 &pixel->pen_colors[i]);
8271 pixel->pixels[image->colors+i]=pixel->pen_colors[i].pixel;
8273 pixel->colors=(ssize_t) (image->colors+MaxNumberPens);
8275 colors=(XColor *) RelinquishMagickMemory(colors);
8276 if (IsEventLogging())
8278 (void) LogMagickEvent(X11Event,GetMagickModule(),"Standard Colormap:");
8279 (void) LogMagickEvent(X11Event,GetMagickModule()," colormap id: 0x%lx",
8280 map_info->colormap);
8281 (void) LogMagickEvent(X11Event,GetMagickModule(),
8282 " red, green, blue max: %lu %lu %lu",map_info->red_max,
8283 map_info->green_max,map_info->blue_max);
8284 (void) LogMagickEvent(X11Event,GetMagickModule(),
8285 " red, green, blue mult: %lu %lu %lu",map_info->red_mult,
8286 map_info->green_mult,map_info->blue_mult);
8291 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8295 % X M a k e W i n d o w %
8299 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8301 % XMakeWindow() creates an X11 window.
8303 % The format of the XMakeWindow method is:
8305 % void XMakeWindow(Display *display,Window parent,char **argv,int argc,
8306 % XClassHint *class_hint,XWMHints *manager_hints,
8307 % XWindowInfo *window_info)
8309 % A description of each parameter follows:
8311 % o display: Specifies a connection to an X server; returned from
8314 % o parent: Specifies the parent window_info.
8316 % o argv: Specifies the application's argument list.
8318 % o argc: Specifies the number of arguments.
8320 % o class_hint: Specifies a pointer to a X11 XClassHint structure.
8322 % o manager_hints: Specifies a pointer to a X11 XWMHints structure.
8324 % o window_info: Specifies a pointer to a X11 XWindowInfo structure.
8327 MagickPrivate void XMakeWindow(Display *display,Window parent,char **argv,
8328 int argc,XClassHint *class_hint,XWMHints *manager_hints,
8329 XWindowInfo *window_info)
8331 #define MinWindowSize 64
8339 static XTextProperty
8350 Set window info hints.
8352 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
8353 assert(display != (Display *) NULL);
8354 assert(window_info != (XWindowInfo *) NULL);
8355 size_hints=XAllocSizeHints();
8356 if (size_hints == (XSizeHints *) NULL)
8357 ThrowXWindowFatalException(XServerFatalError,"UnableToMakeXWindow",argv[0]);
8358 size_hints->flags=(int) window_info->flags;
8359 size_hints->x=window_info->x;
8360 size_hints->y=window_info->y;
8361 size_hints->width=(int) window_info->width;
8362 size_hints->height=(int) window_info->height;
8363 if (window_info->immutable != MagickFalse)
8366 Window size cannot be changed.
8368 size_hints->min_width=size_hints->width;
8369 size_hints->min_height=size_hints->height;
8370 size_hints->max_width=size_hints->width;
8371 size_hints->max_height=size_hints->height;
8372 size_hints->flags|=PMinSize;
8373 size_hints->flags|=PMaxSize;
8378 Window size can be changed.
8380 size_hints->min_width=(int) window_info->min_width;
8381 size_hints->min_height=(int) window_info->min_height;
8382 size_hints->flags|=PResizeInc;
8383 size_hints->width_inc=(int) window_info->width_inc;
8384 size_hints->height_inc=(int) window_info->height_inc;
8385 #if !defined(PRE_R4_ICCCM)
8386 size_hints->flags|=PBaseSize;
8387 size_hints->base_width=size_hints->width_inc;
8388 size_hints->base_height=size_hints->height_inc;
8391 gravity=NorthWestGravity;
8392 if (window_info->geometry != (char *) NULL)
8395 default_geometry[MaxTextExtent],
8396 geometry[MaxTextExtent];
8405 User specified geometry.
8407 (void) FormatLocaleString(default_geometry,MaxTextExtent,"%dx%d",
8408 size_hints->width,size_hints->height);
8409 (void) CopyMagickString(geometry,window_info->geometry,MaxTextExtent);
8411 while (strlen(p) != 0)
8413 if ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '%'))
8416 (void) CopyMagickString(p,p+1,MaxTextExtent);
8418 flags=XWMGeometry(display,window_info->screen,geometry,default_geometry,
8419 window_info->border_width,size_hints,&size_hints->x,&size_hints->y,
8420 &size_hints->width,&size_hints->height,&gravity);
8421 if ((flags & WidthValue) && (flags & HeightValue))
8422 size_hints->flags|=USSize;
8423 if ((flags & XValue) && (flags & YValue))
8425 size_hints->flags|=USPosition;
8426 window_info->x=size_hints->x;
8427 window_info->y=size_hints->y;
8430 #if !defined(PRE_R4_ICCCM)
8431 size_hints->win_gravity=gravity;
8432 size_hints->flags|=PWinGravity;
8434 if (window_info->id == (Window) NULL)
8435 window_info->id=XCreateWindow(display,parent,window_info->x,window_info->y,
8436 (unsigned int) size_hints->width,(unsigned int) size_hints->height,
8437 window_info->border_width,(int) window_info->depth,InputOutput,
8438 window_info->visual,(unsigned long) window_info->mask,
8439 &window_info->attributes);
8452 Window already exists; change relevant attributes.
8454 (void) XChangeWindowAttributes(display,window_info->id,(unsigned long)
8455 window_info->mask,&window_info->attributes);
8456 mask=ConfigureNotify;
8457 while (XCheckTypedWindowEvent(display,window_info->id,(int) mask,&sans_event)) ;
8458 window_changes.x=window_info->x;
8459 window_changes.y=window_info->y;
8460 window_changes.width=(int) window_info->width;
8461 window_changes.height=(int) window_info->height;
8462 mask=(MagickStatusType) (CWWidth | CWHeight);
8463 if (window_info->flags & USPosition)
8465 (void) XReconfigureWMWindow(display,window_info->id,window_info->screen,
8466 mask,&window_changes);
8468 if (window_info->id == (Window) NULL)
8469 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateWindow",
8471 status=XStringListToTextProperty(&window_info->name,1,&window_name);
8472 if (status == False)
8473 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateTextProperty",
8475 status=XStringListToTextProperty(&window_info->icon_name,1,&icon_name);
8476 if (status == False)
8477 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateTextProperty",
8478 window_info->icon_name);
8479 if (window_info->icon_geometry != (char *) NULL)
8487 User specified icon geometry.
8489 size_hints->flags|=USPosition;
8490 flags=XWMGeometry(display,window_info->screen,window_info->icon_geometry,
8491 (char *) NULL,0,size_hints,&manager_hints->icon_x,
8492 &manager_hints->icon_y,&width,&height,&gravity);
8493 if ((flags & XValue) && (flags & YValue))
8494 manager_hints->flags|=IconPositionHint;
8496 XSetWMProperties(display,window_info->id,&window_name,&icon_name,argv,argc,
8497 size_hints,manager_hints,class_hint);
8498 if (window_name.value != (void *) NULL)
8500 (void) XFree((void *) window_name.value);
8501 window_name.value=(unsigned char *) NULL;
8502 window_name.nitems=0;
8504 if (icon_name.value != (void *) NULL)
8506 (void) XFree((void *) icon_name.value);
8507 icon_name.value=(unsigned char *) NULL;
8510 atom_list[0]=XInternAtom(display,"WM_DELETE_WINDOW",MagickFalse);
8511 atom_list[1]=XInternAtom(display,"WM_TAKE_FOCUS",MagickFalse);
8512 (void) XSetWMProtocols(display,window_info->id,atom_list,2);
8513 (void) XFree((void *) size_hints);
8514 if (window_info->shape != MagickFalse)
8516 #if defined(MAGICKCORE_HAVE_SHAPE)
8522 Can we apply a non-rectangular shaping mask?
8526 if (XShapeQueryExtension(display,&error_base,&event_base) == 0)
8527 window_info->shape=MagickFalse;
8529 window_info->shape=MagickFalse;
8532 if (window_info->shared_memory)
8534 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
8536 Can we use shared memory with this window?
8538 if (XShmQueryExtension(display) == 0)
8539 window_info->shared_memory=MagickFalse;
8541 window_info->shared_memory=MagickFalse;
8544 window_info->image=NewImageList();
8545 window_info->destroy=MagickFalse;
8549 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8553 % X M a g i c k P r o g r e s s M o n i t o r %
8557 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8559 % XMagickProgressMonitor() displays the progress a task is making in
8560 % completing a task.
8562 % The format of the XMagickProgressMonitor method is:
8564 % void XMagickProgressMonitor(const char *task,
8565 % const MagickOffsetType quantum,const MagickSizeType span,
8566 % void *client_data)
8568 % A description of each parameter follows:
8570 % o task: Identifies the task in progress.
8572 % o quantum: Specifies the quantum position within the span which represents
8573 % how much progress has been made in completing a task.
8575 % o span: Specifies the span relative to completing a task.
8577 % o client_data: Pointer to any client data.
8581 static const char *GetLocaleMonitorMessage(const char *text)
8584 message[MaxTextExtent],
8593 (void) CopyMagickMemory(tag,text,MaxTextExtent);
8595 if (p != (char *) NULL)
8597 (void) FormatLocaleString(message,MaxTextExtent,"Monitor/%s",tag);
8598 locale_message=GetLocaleMessage(message);
8599 if (locale_message == message)
8601 return(locale_message);
8604 MagickPrivate MagickBooleanType XMagickProgressMonitor(const char *tag,
8605 const MagickOffsetType quantum,const MagickSizeType span,
8606 void *magick_unused(client_data))
8611 windows=XSetWindows((XWindows *) ~0);
8612 if (windows == (XWindows *) NULL)
8614 if (windows->info.mapped != MagickFalse)
8615 XProgressMonitorWidget(windows->display,windows,
8616 GetLocaleMonitorMessage(tag),quantum,span);
8621 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8625 % X Q u e r y C o l o r D a t a b a s e %
8629 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8631 % XQueryColorDatabase() looks up a RGB values for a color given in the target
8634 % The format of the XQueryColorDatabase method is:
8636 % MagickBooleanType XQueryColorDatabase(const char *target,XColor *color)
8638 % A description of each parameter follows:
8640 % o target: Specifies the color to lookup in the X color database.
8642 % o color: A pointer to an PixelPacket structure. The RGB value of the target
8643 % color is returned as this value.
8646 MagickPrivate MagickBooleanType XQueryColorDatabase(const char *target,
8653 *display = (Display *) NULL;
8662 Initialize color return value.
8664 assert(color != (XColor *) NULL);
8668 color->flags=(char) (DoRed | DoGreen | DoBlue);
8669 if ((target == (char *) NULL) || (*target == '\0'))
8670 target="#ffffffffffff";
8672 Let the X server define the color for us.
8674 if (display == (Display *) NULL)
8675 display=XOpenDisplay((char *) NULL);
8676 if (display == (Display *) NULL)
8678 ThrowXWindowFatalException(XServerError,"ColorIsNotKnownToServer",target);
8679 return(MagickFalse);
8681 colormap=XDefaultColormap(display,XDefaultScreen(display));
8682 status=XParseColor(display,colormap,(char *) target,&xcolor);
8683 if (status == False)
8684 ThrowXWindowFatalException(XServerError,"ColorIsNotKnownToServer",target)
8687 color->red=xcolor.red;
8688 color->green=xcolor.green;
8689 color->blue=xcolor.blue;
8690 color->flags=xcolor.flags;
8692 return(status != False ? MagickTrue : MagickFalse);
8696 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8700 % X Q u e r y P o s i t i o n %
8704 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8706 % XQueryPosition() gets the pointer coordinates relative to a window.
8708 % The format of the XQueryPosition method is:
8710 % void XQueryPosition(Display *display,const Window window,int *x,int *y)
8712 % A description of each parameter follows:
8714 % o display: Specifies a connection to an X server; returned from
8717 % o window: Specifies a pointer to a Window.
8719 % o x: Return the x coordinate of the pointer relative to the origin of the
8722 % o y: Return the y coordinate of the pointer relative to the origin of the
8726 MagickPrivate void XQueryPosition(Display *display,const Window window,int *x,int *y)
8738 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
8739 assert(display != (Display *) NULL);
8740 assert(window != (Window) NULL);
8741 assert(x != (int *) NULL);
8742 assert(y != (int *) NULL);
8743 (void) XQueryPointer(display,window,&root_window,&root_window,&x_root,&y_root,
8748 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8752 % X R e f r e s h W i n d o w %
8756 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8758 % XRefreshWindow() refreshes an image in a X window.
8760 % The format of the XRefreshWindow method is:
8762 % void XRefreshWindow(Display *display,const XWindowInfo *window,
8763 % const XEvent *event)
8765 % A description of each parameter follows:
8767 % o display: Specifies a connection to an X server; returned from
8770 % o window: Specifies a pointer to a XWindowInfo structure.
8772 % o event: Specifies a pointer to a XEvent structure. If it is NULL,
8773 % the entire image is refreshed.
8776 MagickPrivate void XRefreshWindow(Display *display,const XWindowInfo *window,
8777 const XEvent *event)
8787 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
8788 assert(display != (Display *) NULL);
8789 assert(window != (XWindowInfo *) NULL);
8790 if (window->ximage == (XImage *) NULL)
8792 if (event != (XEvent *) NULL)
8795 Determine geometry from expose event.
8799 width=(unsigned int) event->xexpose.width;
8800 height=(unsigned int) event->xexpose.height;
8808 Refresh entire window; discard outstanding expose events.
8812 width=window->width;
8813 height=window->height;
8814 while (XCheckTypedWindowEvent(display,window->id,Expose,&sans_event)) ;
8815 if (window->matte_pixmap != (Pixmap) NULL)
8817 #if defined(MAGICKCORE_HAVE_SHAPE)
8818 if (window->shape != MagickFalse)
8819 XShapeCombineMask(display,window->id,ShapeBounding,0,0,
8820 window->matte_pixmap,ShapeSet);
8825 Check boundary conditions.
8827 if ((window->ximage->width-(x+window->x)) < (int) width)
8828 width=(unsigned int) (window->ximage->width-(x+window->x));
8829 if ((window->ximage->height-(y+window->y)) < (int) height)
8830 height=(unsigned int) (window->ximage->height-(y+window->y));
8834 if (window->matte_pixmap != (Pixmap) NULL)
8835 (void) XSetClipMask(display,window->annotate_context,window->matte_pixmap);
8836 if (window->pixmap != (Pixmap) NULL)
8838 if (window->depth > 1)
8839 (void) XCopyArea(display,window->pixmap,window->id,
8840 window->annotate_context,x+window->x,y+window->y,width,height,x,y);
8842 (void) XCopyPlane(display,window->pixmap,window->id,
8843 window->highlight_context,x+window->x,y+window->y,width,height,x,y,
8848 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
8849 if (window->shared_memory)
8850 (void) XShmPutImage(display,window->id,window->annotate_context,
8851 window->ximage,x+window->x,y+window->y,x,y,width,height,MagickTrue);
8853 if (window->shared_memory == MagickFalse)
8854 (void) XPutImage(display,window->id,window->annotate_context,
8855 window->ximage,x+window->x,y+window->y,x,y,width,height);
8857 if (window->matte_pixmap != (Pixmap) NULL)
8858 (void) XSetClipMask(display,window->annotate_context,None);
8859 (void) XFlush(display);
8863 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8867 % X R e m o t e C o m m a n d %
8871 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8873 % XRemoteCommand() forces a remote display(1) to display the specified
8876 % The format of the XRemoteCommand method is:
8878 % MagickBooleanType XRemoteCommand(Display *display,const char *window,
8879 % const char *filename)
8881 % A description of each parameter follows:
8883 % o display: Specifies a connection to an X server; returned from
8886 % o window: Specifies the name or id of an X window.
8888 % o filename: the name of the image filename to display.
8891 MagickExport MagickBooleanType XRemoteCommand(Display *display,
8892 const char *window,const char *filename)
8901 assert(filename != (char *) NULL);
8902 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
8903 if (display == (Display *) NULL)
8904 display=XOpenDisplay((char *) NULL);
8905 if (display == (Display *) NULL)
8907 ThrowXWindowException(XServerError,"UnableToOpenXServer",filename);
8908 return(MagickFalse);
8910 remote_atom=XInternAtom(display,"IM_PROTOCOLS",MagickFalse);
8911 remote_window=(Window) NULL;
8912 root_window=XRootWindow(display,XDefaultScreen(display));
8913 if (window != (char *) NULL)
8916 Search window hierarchy and identify any clients by name or ID.
8918 if (isdigit((unsigned char) *window) != 0)
8919 remote_window=XWindowByID(display,root_window,(Window)
8920 strtol((char *) window,(char **) NULL,0));
8921 if (remote_window == (Window) NULL)
8922 remote_window=XWindowByName(display,root_window,window);
8924 if (remote_window == (Window) NULL)
8925 remote_window=XWindowByProperty(display,root_window,remote_atom);
8926 if (remote_window == (Window) NULL)
8928 ThrowXWindowException(XServerError,"UnableToConnectToRemoteDisplay",
8930 return(MagickFalse);
8933 Send remote command.
8935 remote_atom=XInternAtom(display,"IM_REMOTE_COMMAND",MagickFalse);
8936 (void) XChangeProperty(display,remote_window,remote_atom,XA_STRING,8,
8937 PropModeReplace,(unsigned char *) filename,(int) strlen(filename));
8938 (void) XSync(display,MagickFalse);
8943 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8947 % X R e t a i n W i n d o w C o l o r s %
8951 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8953 % XRetainWindowColors() sets X11 color resources on a window. This preserves
8954 % the colors associated with an image displayed on the window.
8956 % The format of the XRetainWindowColors method is:
8958 % void XRetainWindowColors(Display *display,const Window window)
8960 % A description of each parameter follows:
8962 % o display: Specifies a connection to an X server; returned from
8965 % o window: Specifies a pointer to a XWindowInfo structure.
8968 MagickExport void XRetainWindowColors(Display *display,const Window window)
8977 Put property on the window.
8979 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
8980 assert(display != (Display *) NULL);
8981 assert(window != (Window) NULL);
8982 property=XInternAtom(display,"_XSETROOT_ID",MagickFalse);
8983 if (property == (Atom) NULL)
8985 ThrowXWindowFatalException(XServerError,"UnableToCreateProperty",
8989 pixmap=XCreatePixmap(display,window,1,1,1);
8990 if (pixmap == (Pixmap) NULL)
8992 ThrowXWindowFatalException(XServerError,"UnableToCreateBitmap","");
8995 (void) XChangeProperty(display,window,property,XA_PIXMAP,32,PropModeReplace,
8996 (unsigned char *) &pixmap,1);
8997 (void) XSetCloseDownMode(display,RetainPermanent);
9001 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9005 % X S e l e c t W i n d o w %
9009 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9011 % XSelectWindow() allows a user to select a window using the mouse. If the
9012 % mouse moves, a cropping rectangle is drawn and the extents of the rectangle
9013 % is returned in the crop_info structure.
9015 % The format of the XSelectWindow function is:
9017 % target_window=XSelectWindow(display,crop_info)
9019 % A description of each parameter follows:
9021 % o window: XSelectWindow returns the window id.
9023 % o display: Specifies a pointer to the Display structure; returned from
9026 % o crop_info: Specifies a pointer to a RectangleInfo structure. It
9027 % contains the extents of any cropping rectangle.
9030 static Window XSelectWindow(Display *display,RectangleInfo *crop_info)
9032 #define MinimumCropArea (unsigned int) 9
9059 Initialize graphic context.
9061 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
9062 assert(display != (Display *) NULL);
9063 assert(crop_info != (RectangleInfo *) NULL);
9064 root_window=XRootWindow(display,XDefaultScreen(display));
9065 context_values.background=XBlackPixel(display,XDefaultScreen(display));
9066 context_values.foreground=XWhitePixel(display,XDefaultScreen(display));
9067 context_values.function=GXinvert;
9068 context_values.plane_mask=
9069 context_values.background ^ context_values.foreground;
9070 context_values.subwindow_mode=IncludeInferiors;
9071 annotate_context=XCreateGC(display,root_window,(size_t) (GCBackground |
9072 GCForeground | GCFunction | GCSubwindowMode),&context_values);
9073 if (annotate_context == (GC) NULL)
9074 return(MagickFalse);
9076 Grab the pointer using target cursor.
9078 target_cursor=XMakeCursor(display,root_window,XDefaultColormap(display,
9079 XDefaultScreen(display)),(char * ) "white",(char * ) "black");
9080 status=XGrabPointer(display,root_window,MagickFalse,(unsigned int)
9081 (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask),GrabModeSync,
9082 GrabModeAsync,root_window,target_cursor,CurrentTime);
9083 if (status != GrabSuccess)
9085 ThrowXWindowFatalException(XServerError,"UnableToGrabMouse","");
9086 return((Window) NULL);
9092 crop_info->height=0;
9094 target_window=(Window) NULL;
9099 if ((crop_info->width*crop_info->height) >= MinimumCropArea)
9100 (void) XDrawRectangle(display,root_window,annotate_context,
9101 (int) crop_info->x,(int) crop_info->y,(unsigned int) crop_info->width-1,
9102 (unsigned int) crop_info->height-1);
9104 Allow another event.
9106 (void) XAllowEvents(display,SyncPointer,CurrentTime);
9107 (void) XWindowEvent(display,root_window,ButtonPressMask |
9108 ButtonReleaseMask | ButtonMotionMask,&event);
9109 if ((crop_info->width*crop_info->height) >= MinimumCropArea)
9110 (void) XDrawRectangle(display,root_window,annotate_context,
9111 (int) crop_info->x,(int) crop_info->y,(unsigned int) crop_info->width-1,
9112 (unsigned int) crop_info->height-1);
9117 target_window=XGetSubwindow(display,event.xbutton.subwindow,
9118 event.xbutton.x,event.xbutton.y);
9119 if (target_window == (Window) NULL)
9120 target_window=root_window;
9121 x_offset=event.xbutton.x_root;
9122 y_offset=event.xbutton.y_root;
9123 crop_info->x=(ssize_t) x_offset;
9124 crop_info->y=(ssize_t) y_offset;
9126 crop_info->height=0;
9138 Discard pending button motion events.
9140 while (XCheckMaskEvent(display,ButtonMotionMask,&event)) ;
9141 crop_info->x=(ssize_t) event.xmotion.x;
9142 crop_info->y=(ssize_t) event.xmotion.y;
9144 Check boundary conditions.
9146 if ((int) crop_info->x < x_offset)
9147 crop_info->width=(size_t) (x_offset-crop_info->x);
9150 crop_info->width=(size_t) (crop_info->x-x_offset);
9151 crop_info->x=(ssize_t) x_offset;
9153 if ((int) crop_info->y < y_offset)
9154 crop_info->height=(size_t) (y_offset-crop_info->y);
9157 crop_info->height=(size_t) (crop_info->y-y_offset);
9158 crop_info->y=(ssize_t) y_offset;
9164 } while ((target_window == (Window) NULL) || (presses > 0));
9165 (void) XUngrabPointer(display,CurrentTime);
9166 (void) XFreeCursor(display,target_cursor);
9167 (void) XFreeGC(display,annotate_context);
9168 if ((crop_info->width*crop_info->height) < MinimumCropArea)
9171 crop_info->height=0;
9173 if ((crop_info->width != 0) && (crop_info->height != 0))
9174 target_window=root_window;
9175 return(target_window);
9179 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9183 % X S e t C u r s o r S t a t e %
9187 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9189 % XSetCursorState() sets the cursor state to busy, otherwise the cursor are
9190 % reset to their default.
9192 % The format of the XXSetCursorState method is:
9194 % XSetCursorState(display,windows,const MagickStatusType state)
9196 % A description of each parameter follows:
9198 % o display: Specifies a connection to an X server; returned from
9201 % o windows: Specifies a pointer to a XWindows structure.
9203 % o state: An unsigned integer greater than 0 sets the cursor state
9204 % to busy, otherwise the cursor are reset to their default.
9207 MagickPrivate void XSetCursorState(Display *display,XWindows *windows,
9208 const MagickStatusType state)
9210 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
9211 assert(display != (Display *) NULL);
9212 assert(windows != (XWindows *) NULL);
9215 (void) XCheckDefineCursor(display,windows->image.id,
9216 windows->image.busy_cursor);
9217 (void) XCheckDefineCursor(display,windows->pan.id,
9218 windows->pan.busy_cursor);
9219 (void) XCheckDefineCursor(display,windows->magnify.id,
9220 windows->magnify.busy_cursor);
9221 (void) XCheckDefineCursor(display,windows->command.id,
9222 windows->command.busy_cursor);
9226 (void) XCheckDefineCursor(display,windows->image.id,
9227 windows->image.cursor);
9228 (void) XCheckDefineCursor(display,windows->pan.id,windows->pan.cursor);
9229 (void) XCheckDefineCursor(display,windows->magnify.id,
9230 windows->magnify.cursor);
9231 (void) XCheckDefineCursor(display,windows->command.id,
9232 windows->command.cursor);
9233 (void) XCheckDefineCursor(display,windows->command.id,
9234 windows->widget.cursor);
9235 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
9237 windows->info.mapped=MagickFalse;
9241 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9245 % X S e t W i n d o w s %
9249 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9251 % XSetWindows() sets the X windows structure if the windows info is specified.
9252 % Otherwise the current windows structure is returned.
9254 % The format of the XSetWindows method is:
9256 % XWindows *XSetWindows(XWindows *windows_info)
9258 % A description of each parameter follows:
9260 % o windows_info: Initialize the Windows structure with this information.
9263 MagickPrivate XWindows *XSetWindows(XWindows *windows_info)
9266 *windows = (XWindows *) NULL;
9268 if (windows_info != (XWindows *) ~0)
9270 windows=(XWindows *) RelinquishMagickMemory(windows);
9271 windows=windows_info;
9276 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9280 % X U s e r P r e f e r e n c e s %
9284 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9286 % XUserPreferences() saves the preferences in a configuration file in the
9287 % users' home directory.
9289 % The format of the XUserPreferences method is:
9291 % void XUserPreferences(XResourceInfo *resource_info)
9293 % A description of each parameter follows:
9295 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
9298 MagickPrivate void XUserPreferences(XResourceInfo *resource_info)
9300 #if defined(X11_PREFERENCES_PATH)
9302 cache[MaxTextExtent],
9303 filename[MaxTextExtent],
9304 specifier[MaxTextExtent];
9311 preferences_database;
9314 Save user preferences to the client configuration file.
9316 assert(resource_info != (XResourceInfo *) NULL);
9317 client_name=GetClientName();
9318 preferences_database=XrmGetStringDatabase("");
9319 (void) FormatLocaleString(specifier,MaxTextExtent,"%s.backdrop",client_name);
9320 value=resource_info->backdrop ? "True" : "False";
9321 XrmPutStringResource(&preferences_database,specifier,(char *) value);
9322 (void) FormatLocaleString(specifier,MaxTextExtent,"%s.colormap",client_name);
9323 value=resource_info->colormap == SharedColormap ? "Shared" : "Private";
9324 XrmPutStringResource(&preferences_database,specifier,(char *) value);
9325 (void) FormatLocaleString(specifier,MaxTextExtent,"%s.confirmExit",
9327 value=resource_info->confirm_exit ? "True" : "False";
9328 XrmPutStringResource(&preferences_database,specifier,(char *) value);
9329 (void) FormatLocaleString(specifier,MaxTextExtent,"%s.confirmEdit",
9331 value=resource_info->confirm_edit ? "True" : "False";
9332 XrmPutStringResource(&preferences_database,specifier,(char *) value);
9333 (void) FormatLocaleString(specifier,MaxTextExtent,"%s.displayWarnings",
9335 value=resource_info->display_warnings ? "True" : "False";
9336 XrmPutStringResource(&preferences_database,specifier,(char *) value);
9337 (void) FormatLocaleString(specifier,MaxTextExtent,"%s.dither",client_name);
9338 value=resource_info->quantize_info->dither ? "True" : "False";
9339 XrmPutStringResource(&preferences_database,specifier,(char *) value);
9340 (void) FormatLocaleString(specifier,MaxTextExtent,"%s.gammaCorrect",
9342 value=resource_info->gamma_correct ? "True" : "False";
9343 XrmPutStringResource(&preferences_database,specifier,(char *) value);
9344 (void) FormatLocaleString(specifier,MaxTextExtent,"%s.undoCache",client_name);
9345 (void) FormatLocaleString(cache,MaxTextExtent,"%.20g",(double)
9346 resource_info->undo_cache);
9347 XrmPutStringResource(&preferences_database,specifier,cache);
9348 (void) FormatLocaleString(specifier,MaxTextExtent,"%s.usePixmap",client_name);
9349 value=resource_info->use_pixmap ? "True" : "False";
9350 XrmPutStringResource(&preferences_database,specifier,(char *) value);
9351 (void) FormatLocaleString(filename,MaxTextExtent,"%s%src",
9352 X11_PREFERENCES_PATH,client_name);
9353 ExpandFilename(filename);
9354 XrmPutFileDatabase(preferences_database,filename);
9359 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9363 % X V i s u a l C l a s s N a m e %
9367 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9369 % XVisualClassName() returns the visual class name as a character string.
9371 % The format of the XVisualClassName method is:
9373 % char *XVisualClassName(const int visual_class)
9375 % A description of each parameter follows:
9377 % o visual_type: XVisualClassName returns the visual class as a character
9380 % o class: Specifies the visual class.
9383 static const char *XVisualClassName(const int visual_class)
9385 switch (visual_class)
9387 case StaticGray: return("StaticGray");
9388 case GrayScale: return("GrayScale");
9389 case StaticColor: return("StaticColor");
9390 case PseudoColor: return("PseudoColor");
9391 case TrueColor: return("TrueColor");
9392 case DirectColor: return("DirectColor");
9394 return("unknown visual class");
9398 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9406 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9408 % XWarning() displays a warning reason in a Notice widget.
9410 % The format of the XWarning method is:
9412 % void XWarning(const unsigned int warning,const char *reason,
9413 % const char *description)
9415 % A description of each parameter follows:
9417 % o warning: Specifies the numeric warning category.
9419 % o reason: Specifies the reason to display before terminating the
9422 % o description: Specifies any description to the reason.
9425 MagickPrivate void XWarning(const ExceptionType magick_unused(warning),
9426 const char *reason,const char *description)
9429 text[MaxTextExtent];
9434 if (reason == (char *) NULL)
9436 (void) CopyMagickString(text,reason,MaxTextExtent);
9437 (void) ConcatenateMagickString(text,":",MaxTextExtent);
9438 windows=XSetWindows((XWindows *) ~0);
9439 XNoticeWidget(windows->display,windows,text,(char *) description);
9443 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9447 % X W i n d o w B y I D %
9451 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9453 % XWindowByID() locates a child window with a given ID. If not window with
9454 % the given name is found, 0 is returned. Only the window specified and its
9455 % subwindows are searched.
9457 % The format of the XWindowByID function is:
9459 % child=XWindowByID(display,window,id)
9461 % A description of each parameter follows:
9463 % o child: XWindowByID returns the window with the specified
9464 % id. If no windows are found, XWindowByID returns 0.
9466 % o display: Specifies a pointer to the Display structure; returned from
9469 % o id: Specifies the id of the window to locate.
9472 MagickPrivate Window XWindowByID(Display *display,const Window root_window,
9492 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
9493 assert(display != (Display *) NULL);
9494 assert(root_window != (Window) NULL);
9496 return(XSelectWindow(display,&rectangle_info));
9497 if (root_window == id)
9498 return(root_window);
9499 status=XQueryTree(display,root_window,&child,&child,&children,
9501 if (status == False)
9502 return((Window) NULL);
9503 window=(Window) NULL;
9504 for (i=0; i < (int) number_children; i++)
9507 Search each child and their children.
9509 window=XWindowByID(display,children[i],id);
9510 if (window != (Window) NULL)
9513 if (children != (Window *) NULL)
9514 (void) XFree((void *) children);
9519 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9523 % X W i n d o w B y N a m e %
9527 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9529 % XWindowByName() locates a window with a given name on a display. If no
9530 % window with the given name is found, 0 is returned. If more than one window
9531 % has the given name, the first one is returned. Only root and its children
9534 % The format of the XWindowByName function is:
9536 % window=XWindowByName(display,root_window,name)
9538 % A description of each parameter follows:
9540 % o window: XWindowByName returns the window id.
9542 % o display: Specifies a pointer to the Display structure; returned from
9545 % o root_window: Specifies the id of the root window.
9547 % o name: Specifies the name of the window to locate.
9550 MagickPrivate Window XWindowByName(Display *display,const Window root_window,
9570 assert(display != (Display *) NULL);
9571 assert(root_window != (Window) NULL);
9572 assert(name != (char *) NULL);
9573 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
9574 if (XGetWMName(display,root_window,&window_name) != 0)
9575 if (LocaleCompare((char *) window_name.value,name) == 0)
9576 return(root_window);
9577 status=XQueryTree(display,root_window,&child,&child,&children,
9579 if (status == False)
9580 return((Window) NULL);
9581 window=(Window) NULL;
9582 for (i=0; i < (int) number_children; i++)
9585 Search each child and their children.
9587 window=XWindowByName(display,children[i],name);
9588 if (window != (Window) NULL)
9591 if (children != (Window *) NULL)
9592 (void) XFree((void *) children);
9597 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9601 % X W i n d o w B y P r o p e r y %
9605 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9607 % XWindowByProperty() locates a child window with a given property. If not
9608 % window with the given name is found, 0 is returned. If more than one window
9609 % has the given property, the first one is returned. Only the window
9610 % specified and its subwindows are searched.
9612 % The format of the XWindowByProperty function is:
9614 % child=XWindowByProperty(display,window,property)
9616 % A description of each parameter follows:
9618 % o child: XWindowByProperty returns the window id with the specified
9619 % property. If no windows are found, XWindowByProperty returns 0.
9621 % o display: Specifies a pointer to the Display structure; returned from
9624 % o property: Specifies the property of the window to locate.
9627 MagickPrivate Window XWindowByProperty(Display *display,const Window window,
9628 const Atom property)
9656 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
9657 assert(display != (Display *) NULL);
9658 assert(window != (Window) NULL);
9659 assert(property != (Atom) NULL);
9660 status=XQueryTree(display,window,&root,&parent,&children,&number_children);
9661 if (status == False)
9662 return((Window) NULL);
9664 child=(Window) NULL;
9665 for (i=0; (i < number_children) && (child == (Window) NULL); i++)
9667 status=XGetWindowProperty(display,children[i],property,0L,0L,MagickFalse,
9668 (Atom) AnyPropertyType,&type,&format,&number_items,&after,&data);
9670 (void) XFree((void *) data);
9671 if ((status == Success) && (type != (Atom) NULL))
9674 for (i=0; (i < number_children) && (child == (Window) NULL); i++)
9675 child=XWindowByProperty(display,children[i],property);
9676 if (children != (Window *) NULL)
9677 (void) XFree((void *) children);
9683 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9687 % X I m p o r t I m a g e %
9691 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9693 % XImportImage() reads an image from an X window.
9695 % The format of the XImportImage method is:
9697 % Image *XImportImage(const ImageInfo *image_info,XImportInfo *ximage_info)
9699 % A description of each parameter follows:
9701 % o image_info: the image info..
9703 % o ximage_info: Specifies a pointer to an XImportInfo structure.
9706 MagickPrivate Image *XImportImage(const ImageInfo *image_info,
9707 XImportInfo *ximage_info)
9709 assert(image_info != (const ImageInfo *) NULL);
9710 assert(image_info->signature == MagickSignature);
9711 if (image_info->debug != MagickFalse)
9712 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
9713 image_info->filename);
9714 assert(ximage_info != (XImportInfo *) NULL);
9715 return((Image *) NULL);
9720 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9724 + X C o m p o n e n t G e n e s i s %
9728 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9730 % XComponentGenesis() instantiates the X component.
9732 % The format of the XComponentGenesis method is:
9734 % MagickBooleanType XComponentGenesis(void)
9737 MagickPrivate MagickBooleanType XComponentGenesis(void)
9743 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9747 % X G e t I m p o r t I n f o %
9751 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9753 % XGetImportInfo() initializes the XImportInfo structure.
9755 % The format of the XGetImportInfo method is:
9757 % void XGetImportInfo(XImportInfo *ximage_info)
9759 % A description of each parameter follows:
9761 % o ximage_info: Specifies a pointer to an ImageInfo structure.
9764 MagickExport void XGetImportInfo(XImportInfo *ximage_info)
9766 assert(ximage_info != (XImportInfo *) NULL);
9767 ximage_info->frame=MagickFalse;
9768 ximage_info->borders=MagickFalse;
9769 ximage_info->screen=MagickFalse;
9770 ximage_info->descend=MagickTrue;
9771 ximage_info->silent=MagickFalse;