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-2012 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/constitute.h"
53 #include "MagickCore/display.h"
54 #include "MagickCore/distort.h"
55 #include "MagickCore/exception.h"
56 #include "MagickCore/exception-private.h"
57 #include "MagickCore/geometry.h"
58 #include "MagickCore/identify.h"
59 #include "MagickCore/image.h"
60 #include "MagickCore/image-private.h"
61 #include "MagickCore/list.h"
62 #include "MagickCore/locale_.h"
63 #include "MagickCore/log.h"
64 #include "MagickCore/magick.h"
65 #include "MagickCore/memory_.h"
66 #include "MagickCore/monitor.h"
67 #include "MagickCore/nt-base-private.h"
68 #include "MagickCore/option.h"
69 #include "MagickCore/pixel-accessor.h"
70 #include "MagickCore/PreRvIcccm.h"
71 #include "MagickCore/quantize.h"
72 #include "MagickCore/quantum.h"
73 #include "MagickCore/quantum-private.h"
74 #include "MagickCore/resource_.h"
75 #include "MagickCore/resize.h"
76 #include "MagickCore/statistic.h"
77 #include "MagickCore/string_.h"
78 #include "MagickCore/string-private.h"
79 #include "MagickCore/transform.h"
80 #include "MagickCore/token.h"
81 #include "MagickCore/utility.h"
82 #include "MagickCore/utility-private.h"
83 #include "MagickCore/widget.h"
84 #include "MagickCore/widget-private.h"
85 #include "MagickCore/xwindow.h"
86 #include "MagickCore/xwindow-private.h"
87 #include "MagickCore/version.h"
91 #if defined(MAGICKCORE_X11_DELEGATE)
92 #include <X11/Xproto.h>
93 #include <X11/Xlocale.h>
94 #if defined(MAGICK_HAVE_POLL)
95 # include <sys/poll.h>
97 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
98 #if defined(MAGICKCORE_HAVE_MACHINE_PARAM_H)
99 # include <machine/param.h>
103 #include <X11/extensions/XShm.h>
105 #if defined(MAGICKCORE_HAVE_SHAPE)
106 #include <X11/extensions/shape.h>
112 #define XBlueGamma(color) ClampToQuantum(blue_gamma == 1.0 ? (double) \
113 (color) : ((pow(((double) QuantumScale*(color)),1.0/(double) blue_gamma)* \
115 #define XGammaPacket(map,color) (size_t) (map->base_pixel+ \
116 ((ScaleQuantumToShort(XRedGamma((color)->red))*map->red_max/65535L)* \
118 ((ScaleQuantumToShort(XGreenGamma((color)->green))*map->green_max/65535L)* \
120 ((ScaleQuantumToShort(XBlueGamma((color)->blue))*map->blue_max/65535L)* \
122 #define XGammaPixel(image,map,color) (size_t) (map->base_pixel+ \
123 ((ScaleQuantumToShort(XRedGamma(GetPixelRed(image,color)))*map->red_max/65535L)* \
125 ((ScaleQuantumToShort(XGreenGamma(GetPixelGreen(image,color)))*map->green_max/65535L)* \
127 ((ScaleQuantumToShort(XBlueGamma(GetPixelBlue(image,color)))*map->blue_max/65535L)* \
129 #define XGreenGamma(color) ClampToQuantum(green_gamma == 1.0 ? (double) \
130 (color) : ((pow(((double) QuantumScale*(color)),1.0/(double) green_gamma)* \
132 #define XRedGamma(color) ClampToQuantum(red_gamma == 1.0 ? (double) \
133 (color) : ((pow(((double) QuantumScale*(color)),1.0/(double) red_gamma)* \
135 #define XStandardPixel(map,color) (size_t) (map->base_pixel+ \
136 (((color)->red*map->red_max/65535L)*map->red_mult)+ \
137 (((color)->green*map->green_max/65535L)*map->green_mult)+ \
138 (((color)->blue*map->blue_max/65535L)*map->blue_mult))
140 #define AccentuateModulate ScaleCharToQuantum(80)
141 #define HighlightModulate ScaleCharToQuantum(125)
142 #define ShadowModulate ScaleCharToQuantum(135)
143 #define DepthModulate ScaleCharToQuantum(185)
144 #define TroughModulate ScaleCharToQuantum(110)
146 #define XLIB_ILLEGAL_ACCESS 1
148 #undef NorthWestGravity
150 #undef NorthEastGravity
154 #undef SouthWestGravity
156 #undef SouthEastGravity
163 #define XFD_SET fd_set
167 Enumeration declarations.
181 Typedef declarations.
183 typedef struct _DiversityPacket
198 Constant declaractions.
200 static MagickBooleanType
201 xerror_alert = MagickFalse;
207 *XVisualClassName(const int);
209 static MagickRealType
214 static MagickBooleanType
215 XMakePixmap(Display *,const XResourceInfo *,XWindowInfo *);
218 XMakeImageLSBFirst(const XResourceInfo *,const XWindowInfo *,Image *,
219 XImage *,XImage *,ExceptionInfo *),
220 XMakeImageMSBFirst(const XResourceInfo *,const XWindowInfo *,Image *,
221 XImage *,XImage *,ExceptionInfo *);
224 XSelectWindow(Display *,RectangleInfo *);
227 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
231 % D e s t r o y X R e s o u r c e s %
235 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
237 % DestroyXResources() destroys any X resources.
239 % The format of the DestroyXResources method is:
241 % void DestroyXResources()
243 % A description of each parameter follows:
246 MagickExport void DestroyXResources(void)
255 *magick_windows[MaxXWindows];
261 windows=XSetWindows((XWindows *) ~0);
262 if ((windows == (XWindows *) NULL) || (windows->display == (Display *) NULL))
265 magick_windows[number_windows++]=(&windows->context);
266 magick_windows[number_windows++]=(&windows->group_leader);
267 magick_windows[number_windows++]=(&windows->backdrop);
268 magick_windows[number_windows++]=(&windows->icon);
269 magick_windows[number_windows++]=(&windows->image);
270 magick_windows[number_windows++]=(&windows->info);
271 magick_windows[number_windows++]=(&windows->magnify);
272 magick_windows[number_windows++]=(&windows->pan);
273 magick_windows[number_windows++]=(&windows->command);
274 magick_windows[number_windows++]=(&windows->widget);
275 magick_windows[number_windows++]=(&windows->popup);
276 magick_windows[number_windows++]=(&windows->context);
277 for (i=0; i < (int) number_windows; i++)
279 if (magick_windows[i]->mapped != MagickFalse)
281 (void) XWithdrawWindow(windows->display,magick_windows[i]->id,
282 magick_windows[i]->screen);
283 magick_windows[i]->mapped=MagickFalse;
285 if (magick_windows[i]->name != (char *) NULL)
286 magick_windows[i]->name=(char *)
287 RelinquishMagickMemory(magick_windows[i]->name);
288 if (magick_windows[i]->icon_name != (char *) NULL)
289 magick_windows[i]->icon_name=(char *)
290 RelinquishMagickMemory(magick_windows[i]->icon_name);
291 if (magick_windows[i]->cursor != (Cursor) NULL)
293 (void) XFreeCursor(windows->display,magick_windows[i]->cursor);
294 magick_windows[i]->cursor=(Cursor) NULL;
296 if (magick_windows[i]->busy_cursor != (Cursor) NULL)
298 (void) XFreeCursor(windows->display,magick_windows[i]->busy_cursor);
299 magick_windows[i]->busy_cursor=(Cursor) NULL;
301 if (magick_windows[i]->highlight_stipple != (Pixmap) NULL)
303 (void) XFreePixmap(windows->display,
304 magick_windows[i]->highlight_stipple);
305 magick_windows[i]->highlight_stipple=(Pixmap) NULL;
307 if (magick_windows[i]->shadow_stipple != (Pixmap) NULL)
309 (void) XFreePixmap(windows->display,magick_windows[i]->shadow_stipple);
310 magick_windows[i]->shadow_stipple=(Pixmap) NULL;
312 if (magick_windows[i]->ximage != (XImage *) NULL)
314 XDestroyImage(magick_windows[i]->ximage);
315 magick_windows[i]->ximage=(XImage *) NULL;
317 if (magick_windows[i]->pixmap != (Pixmap) NULL)
319 (void) XFreePixmap(windows->display,magick_windows[i]->pixmap);
320 magick_windows[i]->pixmap=(Pixmap) NULL;
322 if (magick_windows[i]->id != (Window) NULL)
324 (void) XDestroyWindow(windows->display,magick_windows[i]->id);
325 magick_windows[i]->id=(Window) NULL;
327 if (magick_windows[i]->destroy != MagickFalse)
329 if (magick_windows[i]->image != (Image *) NULL)
331 magick_windows[i]->image=DestroyImage(magick_windows[i]->image);
332 magick_windows[i]->image=NewImageList();
334 if (magick_windows[i]->matte_pixmap != (Pixmap) NULL)
336 (void) XFreePixmap(windows->display,
337 magick_windows[i]->matte_pixmap);
338 magick_windows[i]->matte_pixmap=(Pixmap) NULL;
341 if (magick_windows[i]->segment_info != (void *) NULL)
343 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
347 segment_info=(XShmSegmentInfo *) magick_windows[i]->segment_info;
348 if (segment_info != (XShmSegmentInfo *) NULL)
349 if (segment_info[0].shmid >= 0)
351 if (segment_info[0].shmaddr != NULL)
352 (void) shmdt(segment_info[0].shmaddr);
353 (void) shmctl(segment_info[0].shmid,IPC_RMID,0);
354 segment_info[0].shmaddr=NULL;
355 segment_info[0].shmid=(-1);
358 magick_windows[i]->segment_info=(void *)
359 RelinquishMagickMemory(magick_windows[i]->segment_info);
362 windows->icon_resources=(XResourceInfo *)
363 RelinquishMagickMemory(windows->icon_resources);
364 if (windows->icon_pixel != (XPixelInfo *) NULL)
366 if (windows->icon_pixel->pixels != (unsigned long *) NULL)
367 windows->icon_pixel->pixels=(unsigned long *)
368 RelinquishMagickMemory(windows->icon_pixel->pixels);
369 if (windows->icon_pixel->annotate_context != (GC) NULL)
370 XFreeGC(windows->display,windows->icon_pixel->annotate_context);
371 windows->icon_pixel=(XPixelInfo *)
372 RelinquishMagickMemory(windows->icon_pixel);
374 if (windows->pixel_info != (XPixelInfo *) NULL)
376 if (windows->pixel_info->pixels != (unsigned long *) NULL)
377 windows->pixel_info->pixels=(unsigned long *)
378 RelinquishMagickMemory(windows->pixel_info->pixels);
379 if (windows->pixel_info->annotate_context != (GC) NULL)
380 XFreeGC(windows->display,windows->pixel_info->annotate_context);
381 if (windows->pixel_info->widget_context != (GC) NULL)
382 XFreeGC(windows->display,windows->pixel_info->widget_context);
383 if (windows->pixel_info->highlight_context != (GC) NULL)
384 XFreeGC(windows->display,windows->pixel_info->highlight_context);
385 windows->pixel_info=(XPixelInfo *)
386 RelinquishMagickMemory(windows->pixel_info);
388 if (windows->font_info != (XFontStruct *) NULL)
390 XFreeFont(windows->display,windows->font_info);
391 windows->font_info=(XFontStruct *) NULL;
393 if (windows->class_hints != (XClassHint *) NULL)
395 if (windows->class_hints->res_name != (char *) NULL)
396 windows->class_hints->res_name=DestroyString(
397 windows->class_hints->res_name);
398 if (windows->class_hints->res_class != (char *) NULL)
399 windows->class_hints->res_class=DestroyString(
400 windows->class_hints->res_class);
401 XFree(windows->class_hints);
402 windows->class_hints=(XClassHint *) NULL;
404 if (windows->manager_hints != (XWMHints *) NULL)
406 XFree(windows->manager_hints);
407 windows->manager_hints=(XWMHints *) NULL;
409 if (windows->map_info != (XStandardColormap *) NULL)
411 XFree(windows->map_info);
412 windows->map_info=(XStandardColormap *) NULL;
414 if (windows->icon_map != (XStandardColormap *) NULL)
416 XFree(windows->icon_map);
417 windows->icon_map=(XStandardColormap *) NULL;
419 if (windows->visual_info != (XVisualInfo *) NULL)
421 XFree(windows->visual_info);
422 windows->visual_info=(XVisualInfo *) NULL;
424 if (windows->icon_visual != (XVisualInfo *) NULL)
426 XFree(windows->icon_visual);
427 windows->icon_visual=(XVisualInfo *) NULL;
429 (void) XSetWindows((XWindows *) NULL);
433 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
437 % X A n n o t a t e I m a g e %
441 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
443 % XAnnotateImage() annotates the image with text.
445 % The format of the XAnnotateImage method is:
447 % MagickBooleanType XAnnotateImage(Display *display,
448 % const XPixelInfo *pixel,XAnnotateInfo *annotate_info,Image *image,
449 % ExceptionInfo *exception)
451 % A description of each parameter follows:
453 % o display: Specifies a connection to an X server; returned from
456 % o pixel: Specifies a pointer to a XPixelInfo structure.
458 % o annotate_info: Specifies a pointer to a XAnnotateInfo structure.
460 % o image: the image.
462 % o exception: return any errors or warnings in this structure.
465 MagickPrivate MagickBooleanType XAnnotateImage(Display *display,
466 const XPixelInfo *pixel,XAnnotateInfo *annotate_info,Image *image,
467 ExceptionInfo *exception)
503 Initialize annotated image.
505 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
506 assert(display != (Display *) NULL);
507 assert(pixel != (XPixelInfo *) NULL);
508 assert(annotate_info != (XAnnotateInfo *) NULL);
509 assert(image != (Image *) NULL);
511 Initialize annotated pixmap.
513 root_window=XRootWindow(display,XDefaultScreen(display));
514 depth=(unsigned int) XDefaultDepth(display,XDefaultScreen(display));
515 annotate_pixmap=XCreatePixmap(display,root_window,annotate_info->width,
516 annotate_info->height,depth);
517 if (annotate_pixmap == (Pixmap) NULL)
520 Initialize graphics info.
522 context_values.background=0;
523 context_values.foreground=(size_t) (~0);
524 context_values.font=annotate_info->font_info->fid;
525 annotate_context=XCreateGC(display,root_window,(unsigned long)
526 (GCBackground | GCFont | GCForeground),&context_values);
527 if (annotate_context == (GC) NULL)
532 (void) XDrawImageString(display,annotate_pixmap,annotate_context,0,
533 (int) annotate_info->font_info->ascent,annotate_info->text,
534 (int) strlen(annotate_info->text));
535 (void) XFreeGC(display,annotate_context);
537 Initialize annotated X image.
539 annotate_ximage=XGetImage(display,annotate_pixmap,0,0,annotate_info->width,
540 annotate_info->height,AllPlanes,ZPixmap);
541 if (annotate_ximage == (XImage *) NULL)
543 (void) XFreePixmap(display,annotate_pixmap);
545 Initialize annotated image.
547 annotate_image=AcquireImage((ImageInfo *) NULL,exception);
548 if (annotate_image == (Image *) NULL)
550 annotate_image->columns=annotate_info->width;
551 annotate_image->rows=annotate_info->height;
553 Transfer annotated X image to image.
555 width=(unsigned int) image->columns;
556 height=(unsigned int) image->rows;
559 (void) XParseGeometry(annotate_info->geometry,&x,&y,&width,&height);
560 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,(ssize_t) x,
561 (ssize_t) y,&annotate_image->background_color,exception);
562 if (annotate_info->stencil == ForegroundStencil)
563 annotate_image->matte=MagickTrue;
564 annotate_view=AcquireCacheView(annotate_image);
565 for (y=0; y < (int) annotate_image->rows; y++)
573 q=GetCacheViewAuthenticPixels(annotate_view,0,(ssize_t) y,
574 annotate_image->columns,1,exception);
575 if (q == (Quantum *) NULL)
577 for (x=0; x < (int) annotate_image->columns; x++)
579 SetPixelAlpha(annotate_image,OpaqueAlpha,q);
580 if (XGetPixel(annotate_ximage,x,y) == 0)
583 Set this pixel to the background color.
585 SetPixelRed(annotate_image,ScaleShortToQuantum(
586 pixel->box_color.red),q);
587 SetPixelGreen(annotate_image,ScaleShortToQuantum(
588 pixel->box_color.green),q);
589 SetPixelBlue(annotate_image,ScaleShortToQuantum(
590 pixel->box_color.blue),q);
591 if ((annotate_info->stencil == ForegroundStencil) ||
592 (annotate_info->stencil == OpaqueStencil))
593 SetPixelAlpha(annotate_image,TransparentAlpha,q);
598 Set this pixel to the pen color.
600 SetPixelRed(annotate_image,ScaleShortToQuantum(
601 pixel->pen_color.red),q);
602 SetPixelGreen(annotate_image,ScaleShortToQuantum(
603 pixel->pen_color.green),q);
604 SetPixelBlue(annotate_image,ScaleShortToQuantum(
605 pixel->pen_color.blue),q);
606 if (annotate_info->stencil == BackgroundStencil)
607 SetPixelAlpha(annotate_image,TransparentAlpha,q);
609 q+=GetPixelChannels(annotate_image);
611 if (SyncCacheViewAuthenticPixels(annotate_view,exception) == MagickFalse)
614 annotate_view=DestroyCacheView(annotate_view);
615 XDestroyImage(annotate_ximage);
617 Determine annotate geometry.
619 (void) XParseGeometry(annotate_info->geometry,&x,&y,&width,&height);
620 if ((width != (unsigned int) annotate_image->columns) ||
621 (height != (unsigned int) annotate_image->rows))
624 image_geometry[MaxTextExtent];
629 (void) FormatLocaleString(image_geometry,MaxTextExtent,"%ux%u",
631 (void) TransformImage(&annotate_image,(char *) NULL,image_geometry,
634 if (annotate_info->degrees != 0.0)
648 rotate_image=RotateImage(annotate_image,annotate_info->degrees,exception);
649 if (rotate_image == (Image *) NULL)
651 annotate_image=DestroyImage(annotate_image);
652 annotate_image=rotate_image;
654 Annotation is relative to the degree of rotation.
656 normalized_degrees=annotate_info->degrees;
657 while (normalized_degrees < -45.0)
658 normalized_degrees+=360.0;
659 for (rotations=0; normalized_degrees > 45.0; rotations++)
660 normalized_degrees-=90.0;
661 switch (rotations % 4)
671 x-=(int) annotate_image->columns/2;
672 y+=(int) annotate_image->columns/2;
680 x=x-(int) annotate_image->columns;
688 x=x-(int) annotate_image->columns/2;
689 y=y-(int) (annotate_image->rows-(annotate_image->columns/2));
695 Composite text onto the image.
697 (void) XParseGeometry(annotate_info->geometry,&x,&y,&width,&height);
699 (void) CompositeImage(image,annotate_image,
700 annotate_image->matte != MagickFalse ? OverCompositeOp : CopyCompositeOp,
701 MagickFalse,(ssize_t) x,(ssize_t) y,exception);
703 annotate_image=DestroyImage(annotate_image);
708 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
712 % X B e s t F o n t %
716 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
718 % XBestFont() returns the "best" font. "Best" is defined as a font specified
719 % in the X resource database or a font such that the text width displayed
720 % with the font does not exceed the specified maximum width.
722 % The format of the XBestFont method is:
724 % XFontStruct *XBestFont(Display *display,
725 % const XResourceInfo *resource_info,const MagickBooleanType text_font)
727 % A description of each parameter follows:
729 % o font: XBestFont returns a pointer to a XFontStruct structure.
731 % o display: Specifies a connection to an X server; returned from
734 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
736 % o text_font: True is font should be mono-spaced (typewriter style).
740 static char **FontToList(char *font)
755 if (font == (char *) NULL)
756 return((char **) NULL);
758 Convert string to an ASCII list.
761 for (p=font; *p != '\0'; p++)
762 if ((*p == ':') || (*p == ';') || (*p == ','))
764 fontlist=(char **) AcquireQuantumMemory((size_t) fonts+1UL,sizeof(*fontlist));
765 if (fontlist == (char **) NULL)
767 ThrowXWindowFatalException(ResourceLimitError,"MemoryAllocationFailed",
769 return((char **) NULL);
772 for (i=0; i < (int) fonts; i++)
774 for (q=p; *q != '\0'; q++)
775 if ((*q == ':') || (*q == ';') || (*q == ','))
777 fontlist[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+1UL,
778 sizeof(*fontlist[i]));
779 if (fontlist[i] == (char *) NULL)
781 ThrowXWindowFatalException(ResourceLimitError,"MemoryAllocationFailed",
783 return((char **) NULL);
785 (void) CopyMagickString(fontlist[i],p,(size_t) (q-p+1));
788 fontlist[i]=(char *) NULL;
792 MagickPrivate XFontStruct *XBestFont(Display *display,
793 const XResourceInfo *resource_info,const MagickBooleanType text_font)
798 "-*-helvetica-medium-r-normal--12-*-*-*-*-*-iso8859-1",
799 "-*-arial-medium-r-normal--12-*-*-*-*-*-iso8859-1",
800 "-*-helvetica-medium-r-normal--12-*-*-*-*-*-iso8859-15",
801 "-*-arial-medium-r-normal--12-*-*-*-*-*-iso8859-15",
802 "-*-helvetica-medium-r-normal--12-*-*-*-*-*-*-*",
803 "-*-arial-medium-r-normal--12-*-*-*-*-*-*-*",
810 "-*-courier-medium-r-normal-*-12-*-*-*-*-*-iso8859-1",
811 "-*-courier-medium-r-normal-*-12-*-*-*-*-*-iso8859-15",
812 "-*-fixed-medium-r-normal-*-12-*-*-*-*-*-*-*",
826 font_info=(XFontStruct *) NULL;
827 font_name=resource_info->font;
828 if (text_font != MagickFalse)
829 font_name=resource_info->text_font;
830 if ((font_name != (char *) NULL) && (*font_name != '\0'))
839 Load preferred font specified in the X resource database.
841 fontlist=FontToList(font_name);
842 if (fontlist != (char **) NULL)
844 for (i=0; fontlist[i] != (char *) NULL; i++)
846 if (font_info == (XFontStruct *) NULL)
847 font_info=XLoadQueryFont(display,fontlist[i]);
848 fontlist[i]=DestroyString(fontlist[i]);
850 fontlist=(char **) RelinquishMagickMemory(fontlist);
852 if (font_info == (XFontStruct *) NULL)
853 ThrowXWindowFatalException(XServerError,"UnableToLoadFont",font_name);
856 Load fonts from list of fonts until one is found.
859 if (text_font != MagickFalse)
861 if (XDisplayHeight(display,XDefaultScreen(display)) >= 748)
863 while (*p != (char *) NULL)
865 if (font_info != (XFontStruct *) NULL)
867 font_info=XLoadQueryFont(display,(char *) *p);
874 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
878 % X B e s t I c o n S i z e %
882 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
884 % XBestIconSize() returns the "best" icon size. "Best" is defined as an icon
885 % size that maintains the aspect ratio of the image. If the window manager
886 % has preferred icon sizes, one of the preferred sizes is used.
888 % The format of the XBestIconSize method is:
890 % void XBestIconSize(Display *display,XWindowInfo *window,Image *image)
892 % A description of each parameter follows:
894 % o display: Specifies a connection to an X server; returned from
897 % o image: the image.
900 MagickPrivate void XBestIconSize(Display *display,XWindowInfo *window,
924 Determine if the window manager has specified preferred icon sizes.
926 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
927 assert(display != (Display *) NULL);
928 assert(window != (XWindowInfo *) NULL);
929 assert(image != (Image *) NULL);
930 window->width=MaxIconSize;
931 window->height=MaxIconSize;
932 icon_size=(XIconSize *) NULL;
934 root_window=XRootWindow(display,window->screen);
935 if (XGetIconSizes(display,root_window,&size_list,&number_sizes) != 0)
936 if ((number_sizes > 0) && (size_list != (XIconSize *) NULL))
938 if (icon_size == (XIconSize *) NULL)
941 Window manager does not restrict icon size.
943 icon_size=XAllocIconSize();
944 if (icon_size == (XIconSize *) NULL)
946 ThrowXWindowFatalException(ResourceLimitError,
947 "MemoryAllocationFailed",image->filename);
950 icon_size->min_width=1;
951 icon_size->max_width=MaxIconSize;
952 icon_size->min_height=1;
953 icon_size->max_height=MaxIconSize;
954 icon_size->width_inc=1;
955 icon_size->height_inc=1;
958 Determine aspect ratio of image.
960 width=(unsigned int) image->columns;
961 height=(unsigned int) image->rows;
963 if (window->crop_geometry)
964 (void) XParseGeometry(window->crop_geometry,&i,&i,&width,&height);
966 Look for an icon size that maintains the aspect ratio of image.
968 scale_factor=(MagickRealType) icon_size->max_width/width;
969 if (scale_factor > ((MagickRealType) icon_size->max_height/height))
970 scale_factor=(MagickRealType) icon_size->max_height/height;
971 icon_width=(unsigned int) icon_size->min_width;
972 while ((int) icon_width < icon_size->max_width)
974 if (icon_width >= (unsigned int) (scale_factor*width+0.5))
976 icon_width+=icon_size->width_inc;
978 icon_height=(unsigned int) icon_size->min_height;
979 while ((int) icon_height < icon_size->max_height)
981 if (icon_height >= (unsigned int) (scale_factor*height+0.5))
983 icon_height+=icon_size->height_inc;
985 (void) XFree((void *) icon_size);
986 window->width=icon_width;
987 window->height=icon_height;
991 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
995 % X B e s t P i x e l %
999 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1001 % XBestPixel() returns a pixel from an array of pixels that is closest to the
1002 % requested color. If the color array is NULL, the colors are obtained from
1005 % The format of the XBestPixel method is:
1007 % void XBestPixel(Display *display,const Colormap colormap,XColor *colors,
1008 % unsigned int number_colors,XColor *color)
1010 % A description of each parameter follows:
1012 % o pixel: XBestPixel returns the pixel value closest to the requested
1015 % o display: Specifies a connection to an X server; returned from
1018 % o colormap: Specifies the ID of the X server colormap.
1020 % o colors: Specifies an array of XColor structures.
1022 % o number_colors: Specifies the number of XColor structures in the
1023 % color definition array.
1025 % o color: Specifies the desired RGB value to find in the colors array.
1028 MagickPrivate void XBestPixel(Display *display,const Colormap colormap,
1029 XColor *colors,unsigned int number_colors,XColor *color)
1040 register MagickRealType
1051 Find closest representation for the requested RGB color.
1053 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1054 assert(display != (Display *) NULL);
1055 assert(color != (XColor *) NULL);
1056 status=XAllocColor(display,colormap,color);
1057 if (status != False)
1059 query_server=colors == (XColor *) NULL ? MagickTrue : MagickFalse;
1060 if (query_server != MagickFalse)
1063 Read X server colormap.
1065 colors=(XColor *) AcquireQuantumMemory(number_colors,sizeof(*colors));
1066 if (colors == (XColor *) NULL)
1068 ThrowXWindowFatalException(ResourceLimitError,
1069 "MemoryAllocationFailed","...");
1072 for (i=0; i < (int) number_colors; i++)
1073 colors[i].pixel=(size_t) i;
1074 if (number_colors > 256)
1076 (void) XQueryColors(display,colormap,colors,(int) number_colors);
1078 min_distance=3.0*((MagickRealType) QuantumRange+1.0)*((MagickRealType)
1081 for (i=0; i < (int) number_colors; i++)
1083 pixel.red=colors[i].red-(MagickRealType) color->red;
1084 distance=pixel.red*pixel.red;
1085 if (distance > min_distance)
1087 pixel.green=colors[i].green-(MagickRealType) color->green;
1088 distance+=pixel.green*pixel.green;
1089 if (distance > min_distance)
1091 pixel.blue=colors[i].blue-(MagickRealType) color->blue;
1092 distance+=pixel.blue*pixel.blue;
1093 if (distance > min_distance)
1095 min_distance=distance;
1096 color->pixel=colors[i].pixel;
1099 (void) XAllocColor(display,colormap,&colors[j]);
1100 if (query_server != MagickFalse)
1101 colors=(XColor *) RelinquishMagickMemory(colors);
1105 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1109 % X B e s t V i s u a l I n f o %
1113 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1115 % XBestVisualInfo() returns visual information for a visual that is the "best"
1116 % the server supports. "Best" is defined as:
1118 % 1. Restrict the visual list to those supported by the default screen.
1120 % 2. If a visual type is specified, restrict the visual list to those of
1123 % 3. If a map type is specified, choose the visual that matches the id
1124 % specified by the Standard Colormap.
1126 % 4 From the list of visuals, choose one that can display the most
1127 % simultaneous colors. If more than one visual can display the same
1128 % number of simultaneous colors, one is chosen based on a rank.
1130 % The format of the XBestVisualInfo method is:
1132 % XVisualInfo *XBestVisualInfo(Display *display,
1133 % XStandardColormap *map_info,XResourceInfo *resource_info)
1135 % A description of each parameter follows:
1137 % o visual_info: XBestVisualInfo returns a pointer to a X11 XVisualInfo
1140 % o display: Specifies a connection to an X server; returned from
1143 % o map_info: If map_type is specified, this structure is initialized
1144 % with info from the Standard Colormap.
1146 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
1150 static inline int MagickMax(const int x,const int y)
1157 static inline size_t MagickMin(const unsigned int x,
1158 const unsigned int y)
1165 MagickPrivate XVisualInfo *XBestVisualInfo(Display *display,
1166 XStandardColormap *map_info,XResourceInfo *resource_info)
1168 #define MaxStandardColormaps 7
1169 #define XVisualColormapSize(visual_info) MagickMin((unsigned int) (\
1170 (visual_info->klass == TrueColor) || (visual_info->klass == DirectColor) ? \
1171 visual_info->red_mask | visual_info->green_mask | visual_info->blue_mask : \
1172 (unsigned int) visual_info->colormap_size),1U << visual_info->depth)
1198 Restrict visual search by screen number.
1200 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1201 assert(display != (Display *) NULL);
1202 assert(map_info != (XStandardColormap *) NULL);
1203 assert(resource_info != (XResourceInfo *) NULL);
1204 map_type=resource_info->map_type;
1205 visual_type=resource_info->visual_type;
1206 visual_mask=VisualScreenMask;
1207 visual_template.screen=XDefaultScreen(display);
1208 visual_template.depth=XDefaultDepth(display,XDefaultScreen(display));
1210 if ((resource_info->immutable != MagickFalse) && (resource_info->colors != 0))
1211 if (resource_info->colors <= (one << (size_t) visual_template.depth))
1212 visual_mask|=VisualDepthMask;
1213 if (visual_type != (char *) NULL)
1216 Restrict visual search by class or visual id.
1218 if (LocaleCompare("staticgray",visual_type) == 0)
1220 visual_mask|=VisualClassMask;
1221 visual_template.klass=StaticGray;
1224 if (LocaleCompare("grayscale",visual_type) == 0)
1226 visual_mask|=VisualClassMask;
1227 visual_template.klass=GrayScale;
1230 if (LocaleCompare("staticcolor",visual_type) == 0)
1232 visual_mask|=VisualClassMask;
1233 visual_template.klass=StaticColor;
1236 if (LocaleCompare("pseudocolor",visual_type) == 0)
1238 visual_mask|=VisualClassMask;
1239 visual_template.klass=PseudoColor;
1242 if (LocaleCompare("truecolor",visual_type) == 0)
1244 visual_mask|=VisualClassMask;
1245 visual_template.klass=TrueColor;
1248 if (LocaleCompare("directcolor",visual_type) == 0)
1250 visual_mask|=VisualClassMask;
1251 visual_template.klass=DirectColor;
1254 if (LocaleCompare("default",visual_type) == 0)
1256 visual_mask|=VisualIDMask;
1257 visual_template.visualid=XVisualIDFromVisual(
1258 XDefaultVisual(display,XDefaultScreen(display)));
1261 if (isdigit((int) ((unsigned char) *visual_type)) != 0)
1263 visual_mask|=VisualIDMask;
1264 visual_template.visualid=
1265 strtol(visual_type,(char **) NULL,0);
1268 ThrowXWindowFatalException(XServerError,
1269 "UnrecognizedVisualSpecifier",visual_type);
1272 Get all visuals that meet our criteria so far.
1275 visual_list=XGetVisualInfo(display,visual_mask,&visual_template,
1277 visual_mask=VisualScreenMask | VisualIDMask;
1278 if ((number_visuals == 0) || (visual_list == (XVisualInfo *) NULL))
1281 Failed to get visual; try using the default visual.
1283 ThrowXWindowFatalException(XServerWarning,"UnableToGetVisual",
1285 visual_template.visualid=XVisualIDFromVisual(XDefaultVisual(display,
1286 XDefaultScreen(display)));
1287 visual_list=XGetVisualInfo(display,visual_mask,&visual_template,
1289 if ((number_visuals == 0) || (visual_list == (XVisualInfo *) NULL))
1290 return((XVisualInfo *) NULL);
1291 ThrowXWindowFatalException(XServerWarning,"UsingDefaultVisual",
1292 XVisualClassName(visual_list->klass));
1294 resource_info->color_recovery=MagickFalse;
1295 if ((map_info != (XStandardColormap *) NULL) && (map_type != (char *) NULL))
1301 map_name[MaxTextExtent];
1317 Choose a visual associated with a standard colormap.
1319 root_window=XRootWindow(display,XDefaultScreen(display));
1321 if (LocaleCompare(map_type,"list") != 0)
1324 User specified Standard Colormap.
1326 (void) FormatLocaleString((char *) map_name,MaxTextExtent,
1327 "RGB_%s_MAP",map_type);
1328 LocaleUpper(map_name);
1329 map_property=XInternAtom(display,(char *) map_name,MagickTrue);
1330 if (map_property != (Atom) NULL)
1331 status=XGetRGBColormaps(display,root_window,&map_list,&number_maps,
1337 *colormap[MaxStandardColormaps]=
1339 "_HP_RGB_SMOOTH_MAP_LIST",
1349 Choose a standard colormap from a list.
1351 for (i=0; i < MaxStandardColormaps; i++)
1353 map_property=XInternAtom(display,(char *) colormap[i],MagickTrue);
1354 if (map_property == (Atom) NULL)
1356 status=XGetRGBColormaps(display,root_window,&map_list,&number_maps,
1358 if (status != False)
1361 resource_info->color_recovery=i == 0 ? MagickTrue : MagickFalse;
1363 if (status == False)
1365 ThrowXWindowFatalException(XServerError,"UnableToGetStandardColormap",
1367 return((XVisualInfo *) NULL);
1370 Search all Standard Colormaps and visuals for ids that match.
1372 *map_info=map_list[0];
1373 #if !defined(PRE_R4_ICCCM)
1374 visual_template.visualid=XVisualIDFromVisual(visual_list[0].visual);
1375 for (i=0; i < number_maps; i++)
1376 for (j=0; j < number_visuals; j++)
1377 if (map_list[i].visualid ==
1378 XVisualIDFromVisual(visual_list[j].visual))
1380 *map_info=map_list[i];
1381 visual_template.visualid=XVisualIDFromVisual(
1382 visual_list[j].visual);
1385 if (map_info->visualid != visual_template.visualid)
1387 ThrowXWindowFatalException(XServerError,
1388 "UnableToMatchVisualToStandardColormap",map_type);
1389 return((XVisualInfo *) NULL);
1392 if (map_info->colormap == (Colormap) NULL)
1394 ThrowXWindowFatalException(XServerError,
1395 "StandardColormapIsNotInitialized",map_type);
1396 return((XVisualInfo *) NULL);
1398 (void) XFree((void *) map_list);
1402 static const unsigned int
1417 Pick one visual that displays the most simultaneous colors.
1419 visual_info=visual_list;
1421 for (i=1; i < number_visuals; i++)
1424 if (XVisualColormapSize(p) > XVisualColormapSize(visual_info))
1427 if (XVisualColormapSize(p) == XVisualColormapSize(visual_info))
1428 if (rank[p->klass] > rank[visual_info->klass])
1431 visual_template.visualid=XVisualIDFromVisual(visual_info->visual);
1433 (void) XFree((void *) visual_list);
1435 Retrieve only one visual by its screen & id number.
1437 visual_info=XGetVisualInfo(display,visual_mask,&visual_template,
1439 if ((number_visuals == 0) || (visual_info == (XVisualInfo *) NULL))
1440 return((XVisualInfo *) NULL);
1441 return(visual_info);
1445 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1449 % X C h e c k D e f i n e C u r s o r %
1453 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1455 % XCheckDefineCursor() prevents cursor changes on the root window.
1457 % The format of the XXCheckDefineCursor method is:
1459 % XCheckDefineCursor(display,window,cursor)
1461 % A description of each parameter follows:
1463 % o display: Specifies a connection to an X server; returned from
1466 % o window: the window.
1468 % o cursor: the cursor.
1471 MagickPrivate int XCheckDefineCursor(Display *display,Window window,
1474 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1475 assert(display != (Display *) NULL);
1476 if (window == XRootWindow(display,XDefaultScreen(display)))
1478 return(XDefineCursor(display,window,cursor));
1482 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1486 % X C h e c k R e f r e s h W i n d o w s %
1490 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1492 % XCheckRefreshWindows() checks the X server for exposure events for a
1493 % particular window and updates the areassociated with the exposure event.
1495 % The format of the XCheckRefreshWindows method is:
1497 % void XCheckRefreshWindows(Display *display,XWindows *windows)
1499 % A description of each parameter follows:
1501 % o display: Specifies a connection to an X server; returned from
1504 % o windows: Specifies a pointer to a XWindows structure.
1507 MagickPrivate void XCheckRefreshWindows(Display *display,XWindows *windows)
1515 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1516 assert(display != (Display *) NULL);
1517 assert(windows != (XWindows *) NULL);
1518 XDelay(display,SuspendTime);
1519 id=windows->command.id;
1520 while (XCheckTypedWindowEvent(display,id,Expose,&event) != MagickFalse)
1521 (void) XCommandWidget(display,windows,(char const **) NULL,&event);
1522 id=windows->image.id;
1523 while (XCheckTypedWindowEvent(display,id,Expose,&event) != MagickFalse)
1524 XRefreshWindow(display,&windows->image,&event);
1525 XDelay(display,SuspendTime << 1);
1526 id=windows->command.id;
1527 while (XCheckTypedWindowEvent(display,id,Expose,&event) != MagickFalse)
1528 (void) XCommandWidget(display,windows,(char const **) NULL,&event);
1529 id=windows->image.id;
1530 while (XCheckTypedWindowEvent(display,id,Expose,&event) != MagickFalse)
1531 XRefreshWindow(display,&windows->image,&event);
1535 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1539 % X C l i e n t M e s s a g e %
1543 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1545 % XClientMessage() sends a reason to a window with XSendEvent. The reason is
1546 % initialized with a particular protocol type and atom.
1548 % The format of the XClientMessage function is:
1550 % XClientMessage(display,window,protocol,reason,timestamp)
1552 % A description of each parameter follows:
1554 % o display: Specifies a pointer to the Display structure; returned from
1557 % o window: Specifies a pointer to a Window structure.
1559 % o protocol: Specifies an atom value.
1561 % o reason: Specifies an atom value which is the reason to send.
1563 % o timestamp: Specifies a value of type Time.
1566 MagickPrivate void XClientMessage(Display *display,const Window window,
1567 const Atom protocol,const Atom reason,const Time timestamp)
1572 assert(display != (Display *) NULL);
1573 client_event.type=ClientMessage;
1574 client_event.window=window;
1575 client_event.message_type=protocol;
1576 client_event.format=32;
1577 client_event.data.l[0]=(long) reason;
1578 client_event.data.l[1]=(long) timestamp;
1579 (void) XSendEvent(display,window,MagickFalse,NoEventMask,(XEvent *) &client_event);
1583 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1587 + X C l i e n t W i n d o w %
1591 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1593 % XClientWindow() finds a window, at or below the specified window, which has
1594 % a WM_STATE property. If such a window is found, it is returned, otherwise
1595 % the argument window is returned.
1597 % The format of the XClientWindow function is:
1599 % client_window=XClientWindow(display,target_window)
1601 % A description of each parameter follows:
1603 % o client_window: XClientWindow returns a window, at or below the specified
1604 % window, which has a WM_STATE property otherwise the argument
1605 % target_window is returned.
1607 % o display: Specifies a pointer to the Display structure; returned from
1610 % o target_window: Specifies the window to find a WM_STATE property.
1613 static Window XClientWindow(Display *display,Window target_window)
1635 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1636 assert(display != (Display *) NULL);
1637 state=XInternAtom(display,"WM_STATE",MagickTrue);
1638 if (state == (Atom) NULL)
1639 return(target_window);
1641 status=XGetWindowProperty(display,target_window,state,0L,0L,MagickFalse,
1642 (Atom) AnyPropertyType,&type,&format,&number_items,&after,&data);
1643 if ((status == Success) && (type != (Atom) NULL))
1644 return(target_window);
1645 client_window=XWindowByProperty(display,target_window,state);
1646 if (client_window == (Window) NULL)
1647 return(target_window);
1648 return(client_window);
1652 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1656 + X C o m p o n e n t T e r m i n u s %
1660 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1662 % XComponentTerminus() destroys the module component.
1664 % The format of the XComponentTerminus method is:
1666 % XComponentTerminus(void)
1669 MagickPrivate void XComponentTerminus(void)
1671 DestroyXResources();
1675 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1679 % X C o n f i g u r e I m a g e C o l o r m a p %
1683 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1685 % XConfigureImageColormap() creates a new X colormap.
1687 % The format of the XConfigureImageColormap method is:
1689 % void XConfigureImageColormap(Display *display,
1690 % XResourceInfo *resource_info,XWindows *windows,Image *image,
1691 % ExceptionInfo *exception)
1693 % A description of each parameter follows:
1695 % o display: Specifies a connection to an X server; returned from
1698 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
1700 % o windows: Specifies a pointer to a XWindows structure.
1702 % o image: the image.
1704 % o exception: return any errors or warnings in this structure.
1707 MagickPrivate void XConfigureImageColormap(Display *display,
1708 XResourceInfo *resource_info,XWindows *windows,Image *image,
1709 ExceptionInfo *exception)
1715 Make standard colormap.
1717 XSetCursorState(display,windows,MagickTrue);
1718 XCheckRefreshWindows(display,windows);
1719 XMakeStandardColormap(display,windows->visual_info,resource_info,image,
1720 windows->map_info,windows->pixel_info,exception);
1721 colormap=windows->map_info->colormap;
1722 (void) XSetWindowColormap(display,windows->image.id,colormap);
1723 (void) XSetWindowColormap(display,windows->command.id,colormap);
1724 (void) XSetWindowColormap(display,windows->widget.id,colormap);
1725 if (windows->magnify.mapped != MagickFalse)
1726 (void) XSetWindowColormap(display,windows->magnify.id,colormap);
1727 if (windows->pan.mapped != MagickFalse)
1728 (void) XSetWindowColormap(display,windows->pan.id,colormap);
1729 XSetCursorState(display,windows,MagickFalse);
1730 XClientMessage(display,windows->image.id,windows->im_protocols,
1731 windows->im_update_colormap,CurrentTime);
1735 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1739 % X C o n s t r a i n W i n d o w P o s i t i o n %
1743 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1745 % XConstrainWindowPosition() assures a window is positioned within the X
1746 % server boundaries.
1748 % The format of the XConstrainWindowPosition method is:
1750 % void XConstrainWindowPosition(Display *display,XWindowInfo *window_info)
1752 % A description of each parameter follows:
1754 % o display: Specifies a pointer to the Display structure; returned from
1757 % o window_info: Specifies a pointer to a XWindowInfo structure.
1760 MagickPrivate void XConstrainWindowPosition(Display *display,
1761 XWindowInfo *window_info)
1766 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1767 assert(display != (Display *) NULL);
1768 assert(window_info != (XWindowInfo *) NULL);
1769 limit=XDisplayWidth(display,window_info->screen)-window_info->width;
1770 if (window_info->x < 0)
1773 if (window_info->x > (int) limit)
1774 window_info->x=(int) limit;
1775 limit=XDisplayHeight(display,window_info->screen)-window_info->height;
1776 if (window_info->y < 0)
1779 if (window_info->y > limit)
1780 window_info->y=limit;
1784 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1792 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1794 % XDelay() suspends program execution for the number of milliseconds
1797 % The format of the Delay method is:
1799 % void XDelay(Display *display,const size_t milliseconds)
1801 % A description of each parameter follows:
1803 % o display: Specifies a pointer to the Display structure; returned from
1806 % o milliseconds: Specifies the number of milliseconds to delay before
1810 MagickPrivate void XDelay(Display *display,const size_t milliseconds)
1812 assert(display != (Display *) NULL);
1813 (void) XFlush(display);
1814 MagickDelay(milliseconds);
1818 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1822 % X D e s t r o y R e s o u r c e I n f o %
1826 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1828 % XDestroyResourceInfo() frees memory associated with the XResourceInfo
1831 % The format of the XDestroyResourceInfo method is:
1833 % void XDestroyResourceInfo(XResourceInfo *resource_info)
1835 % A description of each parameter follows:
1837 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
1840 MagickExport void XDestroyResourceInfo(XResourceInfo *resource_info)
1842 if (resource_info->image_geometry != (char *) NULL)
1843 resource_info->image_geometry=(char *)
1844 RelinquishMagickMemory(resource_info->image_geometry);
1845 if (resource_info->quantize_info != (QuantizeInfo *) NULL)
1846 resource_info->quantize_info=DestroyQuantizeInfo(
1847 resource_info->quantize_info);
1848 if (resource_info->client_name != (char *) NULL)
1849 resource_info->client_name=(char *)
1850 RelinquishMagickMemory(resource_info->client_name);
1851 if (resource_info->name != (char *) NULL)
1852 resource_info->name=DestroyString(resource_info->name);
1853 (void) ResetMagickMemory(resource_info,0,sizeof(*resource_info));
1857 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1861 % X D e s t r o y W i n d o w C o l o r s %
1865 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1867 % XDestroyWindowColors() frees X11 color resources previously saved on a
1868 % window by XRetainWindowColors or programs like xsetroot.
1870 % The format of the XDestroyWindowColors method is:
1872 % void XDestroyWindowColors(Display *display,Window window)
1874 % A description of each parameter follows:
1876 % o display: Specifies a connection to an X server; returned from
1879 % o window: Specifies a pointer to a Window structure.
1882 MagickPrivate void XDestroyWindowColors(Display *display,Window window)
1902 If there are previous resources on the root window, destroy them.
1904 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1905 assert(display != (Display *) NULL);
1906 property=XInternAtom(display,"_XSETROOT_ID",MagickFalse);
1907 if (property == (Atom) NULL)
1909 ThrowXWindowFatalException(XServerError,"UnableToCreateProperty",
1913 status=XGetWindowProperty(display,window,property,0L,1L,MagickTrue,
1914 (Atom) AnyPropertyType,&type,&format,&length,&after,&data);
1915 if (status != Success)
1917 if ((type == XA_PIXMAP) && (format == 32) && (length == 1) && (after == 0))
1919 (void) XKillClient(display,(XID) (*((Pixmap *) data)));
1920 (void) XDeleteProperty(display,window,property);
1923 (void) XFree((void *) data);
1927 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1931 % X D i s p l a y I m a g e I n f o %
1935 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1937 % XDisplayImageInfo() displays information about an X image.
1939 % The format of the XDisplayImageInfo method is:
1941 % void XDisplayImageInfo(Display *display,
1942 % const XResourceInfo *resource_info,XWindows *windows,Image *undo_image,
1943 % Image *image,ExceptionInfo *exception)
1945 % A description of each parameter follows:
1947 % o display: Specifies a connection to an X server; returned from
1950 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
1952 % o windows: Specifies a pointer to a XWindows structure.
1954 % o undo_image: the undo image.
1956 % o image: the image.
1958 % o exception: return any errors or warnings in this structure.
1961 MagickPrivate void XDisplayImageInfo(Display *display,
1962 const XResourceInfo *resource_info,XWindows *windows,Image *undo_image,
1963 Image *image,ExceptionInfo *exception)
1966 filename[MaxTextExtent],
1989 Write info about the X server to a file.
1991 assert(display != (Display *) NULL);
1992 assert(resource_info != (XResourceInfo *) NULL);
1993 assert(windows != (XWindows *) NULL);
1994 assert(image != (Image *) NULL);
1996 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1998 unique_file=AcquireUniqueFileResource(filename);
1999 if (unique_file != -1)
2000 file=fdopen(unique_file,"w");
2001 if ((unique_file == -1) || (file == (FILE *) NULL))
2003 XNoticeWidget(display,windows,"Unable to display image info",filename);
2006 if (resource_info->gamma_correct != MagickFalse)
2007 if (resource_info->display_gamma != (char *) NULL)
2008 (void) FormatLocaleFile(file,"Display\n gamma: %s\n\n",
2009 resource_info->display_gamma);
2011 Write info about the X image to a file.
2013 (void) FormatLocaleFile(file,"X\n visual: %s\n",
2014 XVisualClassName((int) windows->image.storage_class));
2015 (void) FormatLocaleFile(file," depth: %d\n",windows->image.ximage->depth);
2016 if (windows->visual_info->colormap_size != 0)
2017 (void) FormatLocaleFile(file," colormap size: %d\n",
2018 windows->visual_info->colormap_size);
2019 if (resource_info->colormap== SharedColormap)
2020 (void) FormatLocaleFile(file," colormap type: Shared\n");
2022 (void) FormatLocaleFile(file," colormap type: Private\n");
2023 (void) FormatLocaleFile(file," geometry: %dx%d\n",
2024 windows->image.ximage->width,windows->image.ximage->height);
2025 if (windows->image.crop_geometry != (char *) NULL)
2026 (void) FormatLocaleFile(file," crop geometry: %s\n",
2027 windows->image.crop_geometry);
2028 if (windows->image.pixmap == (Pixmap) NULL)
2029 (void) FormatLocaleFile(file," type: X Image\n");
2031 (void) FormatLocaleFile(file," type: Pixmap\n");
2032 if (windows->image.shape != MagickFalse)
2033 (void) FormatLocaleFile(file," non-rectangular shape: True\n");
2035 (void) FormatLocaleFile(file," non-rectangular shape: False\n");
2036 if (windows->image.shared_memory != MagickFalse)
2037 (void) FormatLocaleFile(file," shared memory: True\n");
2039 (void) FormatLocaleFile(file," shared memory: False\n");
2040 (void) FormatLocaleFile(file,"\n");
2041 if (resource_info->font != (char *) NULL)
2042 (void) FormatLocaleFile(file,"Font: %s\n\n",resource_info->font);
2043 if (resource_info->text_font != (char *) NULL)
2044 (void) FormatLocaleFile(file,"Text font: %s\n\n",resource_info->text_font);
2046 Write info about the undo cache to a file.
2049 for (levels=0; undo_image != (Image *) NULL; levels++)
2051 number_pixels=undo_image->list->columns*undo_image->list->rows;
2052 bytes+=number_pixels*sizeof(PixelInfo);
2053 undo_image=GetPreviousImageInList(undo_image);
2055 (void) FormatLocaleFile(file,"Undo Edit Cache\n levels: %u\n",levels);
2056 (void) FormatLocaleFile(file," bytes: %.20gmb\n",(double)
2057 ((bytes+(1 << 19)) >> 20));
2058 (void) FormatLocaleFile(file," limit: %.20gmb\n\n",(double)
2059 resource_info->undo_cache);
2061 Write info about the image to a file.
2063 (void) IdentifyImage(image,file,MagickTrue,exception);
2064 (void) fclose(file);
2065 text=FileToString(filename,~0,exception);
2066 (void) RelinquishUniqueFileResource(filename);
2067 if (text == (char *) NULL)
2069 XNoticeWidget(display,windows,"MemoryAllocationFailed",
2070 "UnableToDisplayImageInfo");
2073 textlist=StringToList(text);
2074 if (textlist != (char **) NULL)
2077 title[MaxTextExtent];
2080 Display information about the image in the Text View widget.
2082 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
2083 (void) FormatLocaleString(title,MaxTextExtent,"Image Info: %s",
2085 XTextViewWidget(display,resource_info,windows,MagickTrue,title,
2086 (char const **) textlist);
2087 for (i=0; textlist[i] != (char *) NULL; i++)
2088 textlist[i]=DestroyString(textlist[i]);
2089 textlist=(char **) RelinquishMagickMemory(textlist);
2091 text=DestroyString(text);
2095 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2099 + X D i t h e r I m a g e %
2103 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2105 % XDitherImage() dithers the reference image as required by the HP Color
2106 % Recovery algorithm. The color values are quantized to 3 bits of red and
2107 % green, and 2 bits of blue (3/3/2) and can be used as indices into a 8-bit X
2108 % standard colormap.
2110 % The format of the XDitherImage method is:
2112 % void XDitherImage(Image *image,XImage *ximage,ExceptionInfo *exception)
2114 % A description of each parameter follows:
2116 % o image: the image.
2118 % o ximage: Specifies a pointer to a XImage structure; returned from
2121 % o exception: return any errors or warnings in this structure.
2124 static void XDitherImage(Image *image,XImage *ximage,ExceptionInfo *exception)
2126 static const short int
2129 {-16, 4, -1, 11,-14, 6, -3, 9,-15, 5, -2, 10,-13, 7, -4, 8},
2130 { 15, -5, 0,-12, 13, -7, 2,-10, 14, -6, 1,-11, 12, -8, 3, -9}
2132 dither_green[2][16]=
2134 { 11,-15, 7, -3, 8,-14, 4, -2, 10,-16, 6, -4, 9,-13, 5, -1},
2135 {-12, 14, -8, 2, -9, 13, -5, 1,-11, 15, -7, 3,-10, 12, -6, 0}
2139 { -3, 9,-13, 7, -1, 11,-15, 5, -4, 8,-14, 6, -2, 10,-16, 4},
2140 { 2,-10, 12, -8, 0,-12, 14, -6, 3, -9, 13, -7, 1,-11, 15, -5}
2156 register const Quantum
2176 Allocate and initialize dither maps.
2178 for (i=0; i < 2; i++)
2179 for (j=0; j < 16; j++)
2181 red_map[i][j]=(unsigned char *) AcquireQuantumMemory(256UL,
2183 green_map[i][j]=(unsigned char *) AcquireQuantumMemory(256UL,
2184 sizeof(*green_map));
2185 blue_map[i][j]=(unsigned char *) AcquireQuantumMemory(256UL,
2187 if ((red_map[i][j] == (unsigned char *) NULL) ||
2188 (green_map[i][j] == (unsigned char *) NULL) ||
2189 (blue_map[i][j] == (unsigned char *) NULL))
2191 ThrowXWindowFatalException(ResourceLimitError,
2192 "MemoryAllocationFailed",image->filename);
2197 Initialize dither tables.
2199 for (i=0; i < 2; i++)
2200 for (j=0; j < 16; j++)
2201 for (x=0; x < 256; x++)
2206 value+=dither_red[i][j];
2207 red_map[i][j][x]=(unsigned char)
2208 ((value < 0) ? 0 : (value > 255) ? 255 : value);
2212 value+=dither_green[i][j];
2213 green_map[i][j][x]=(unsigned char)
2214 ((value < 0) ? 0 : (value > 255) ? 255 : value);
2218 value+=((size_t) dither_blue[i][j] << 1);
2219 blue_map[i][j][x]=(unsigned char)
2220 ((value < 0) ? 0 : (value > 255) ? 255 : value);
2225 scanline_pad=(unsigned int) (ximage->bytes_per_line-
2226 ((size_t) (ximage->width*ximage->bits_per_pixel) >> 3));
2230 image_view=AcquireCacheView(image);
2231 for (y=0; y < (int) image->rows; y++)
2233 p=GetCacheViewVirtualPixels(image_view,0,(ssize_t) y,image->columns,1,
2235 if (p == (const Quantum *) NULL)
2237 for (x=0; x < (int) image->columns; x++)
2239 color.red=(double) ClampToQuantum((MagickRealType) (red_map[i][j][
2240 (int) ScaleQuantumToChar(GetPixelRed(image,p))] << 8));
2241 color.green=(double) ClampToQuantum((MagickRealType) (green_map[i][j][
2242 (int) ScaleQuantumToChar(GetPixelGreen(image,p))] << 8));
2243 color.blue=(double) ClampToQuantum((MagickRealType) (blue_map[i][j][
2244 (int) ScaleQuantumToChar(GetPixelBlue(image,p))] << 8));
2245 pixel=(size_t) (((size_t) color.red & 0xe0) |
2246 (((size_t) color.green & 0xe0) >> 3) |
2247 (((size_t) color.blue & 0xc0) >> 6));
2249 p+=GetPixelChannels(image);
2259 image_view=DestroyCacheView(image_view);
2261 Free allocated memory.
2263 for (i=0; i < 2; i++)
2264 for (j=0; j < 16; j++)
2266 green_map[i][j]=(unsigned char *) RelinquishMagickMemory(green_map[i][j]);
2267 blue_map[i][j]=(unsigned char *) RelinquishMagickMemory(blue_map[i][j]);
2268 red_map[i][j]=(unsigned char *) RelinquishMagickMemory(red_map[i][j]);
2273 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2277 % X D r a w I m a g e %
2281 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2283 % XDrawImage() draws a line on the image.
2285 % The format of the XDrawImage method is:
2287 % MagickBooleanType XDrawImage(Display *display,const XPixelInfo *pixel,
2288 % XDrawInfo *draw_info,Image *image,ExceptionInfo *exception)
2290 % A description of each parameter follows:
2292 % o display: Specifies a connection to an X server; returned from
2295 % o pixel: Specifies a pointer to a XPixelInfo structure.
2297 % o draw_info: Specifies a pointer to a XDrawInfo structure.
2299 % o image: the image.
2301 % o exception: return any errors or warnings in this structure.
2304 MagickPrivate MagickBooleanType XDrawImage(Display *display,
2305 const XPixelInfo *pixel,XDrawInfo *draw_info,Image *image,
2306 ExceptionInfo *exception)
2342 Initialize drawd image.
2344 assert(display != (Display *) NULL);
2345 assert(pixel != (XPixelInfo *) NULL);
2346 assert(draw_info != (XDrawInfo *) NULL);
2347 assert(image != (Image *) NULL);
2348 if (image->debug != MagickFalse)
2349 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2351 Initialize drawd pixmap.
2353 root_window=XRootWindow(display,XDefaultScreen(display));
2354 depth=(unsigned int) XDefaultDepth(display,XDefaultScreen(display));
2355 draw_pixmap=XCreatePixmap(display,root_window,draw_info->width,
2356 draw_info->height,depth);
2357 if (draw_pixmap == (Pixmap) NULL)
2358 return(MagickFalse);
2360 Initialize graphics info.
2362 context_values.background=(size_t) (~0);
2363 context_values.foreground=0;
2364 context_values.line_width=(int) draw_info->line_width;
2365 draw_context=XCreateGC(display,root_window,(size_t)
2366 (GCBackground | GCForeground | GCLineWidth),&context_values);
2367 if (draw_context == (GC) NULL)
2368 return(MagickFalse);
2372 (void) XFillRectangle(display,draw_pixmap,draw_context,0,0,draw_info->width,
2375 Draw line to pixmap.
2377 (void) XSetBackground(display,draw_context,0);
2378 (void) XSetForeground(display,draw_context,(size_t) (~0));
2379 if (draw_info->stipple != (Pixmap) NULL)
2381 (void) XSetFillStyle(display,draw_context,FillOpaqueStippled);
2382 (void) XSetStipple(display,draw_context,draw_info->stipple);
2384 switch (draw_info->element)
2389 (void) XDrawLines(display,draw_pixmap,draw_context,
2390 draw_info->coordinate_info,(int) draw_info->number_coordinates,
2396 (void) XDrawLine(display,draw_pixmap,draw_context,draw_info->line_info.x1,
2397 draw_info->line_info.y1,draw_info->line_info.x2,
2398 draw_info->line_info.y2);
2401 case RectangleElement:
2403 (void) XDrawRectangle(display,draw_pixmap,draw_context,
2404 (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y,
2405 (unsigned int) draw_info->rectangle_info.width,
2406 (unsigned int) draw_info->rectangle_info.height);
2409 case FillRectangleElement:
2411 (void) XFillRectangle(display,draw_pixmap,draw_context,
2412 (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y,
2413 (unsigned int) draw_info->rectangle_info.width,
2414 (unsigned int) draw_info->rectangle_info.height);
2418 case EllipseElement:
2420 (void) XDrawArc(display,draw_pixmap,draw_context,
2421 (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y,
2422 (unsigned int) draw_info->rectangle_info.width,
2423 (unsigned int) draw_info->rectangle_info.height,0,360*64);
2426 case FillCircleElement:
2427 case FillEllipseElement:
2429 (void) XFillArc(display,draw_pixmap,draw_context,
2430 (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y,
2431 (unsigned int) draw_info->rectangle_info.width,
2432 (unsigned int) draw_info->rectangle_info.height,0,360*64);
2435 case PolygonElement:
2440 coordinate_info=draw_info->coordinate_info;
2441 (void) XDrawLines(display,draw_pixmap,draw_context,coordinate_info,
2442 (int) draw_info->number_coordinates,CoordModeOrigin);
2443 (void) XDrawLine(display,draw_pixmap,draw_context,
2444 coordinate_info[draw_info->number_coordinates-1].x,
2445 coordinate_info[draw_info->number_coordinates-1].y,
2446 coordinate_info[0].x,coordinate_info[0].y);
2449 case FillPolygonElement:
2451 (void) XFillPolygon(display,draw_pixmap,draw_context,
2452 draw_info->coordinate_info,(int) draw_info->number_coordinates,Complex,
2457 (void) XFreeGC(display,draw_context);
2461 draw_ximage=XGetImage(display,draw_pixmap,0,0,draw_info->width,
2462 draw_info->height,AllPlanes,ZPixmap);
2463 if (draw_ximage == (XImage *) NULL)
2464 return(MagickFalse);
2465 (void) XFreePixmap(display,draw_pixmap);
2467 Initialize draw image.
2469 draw_image=AcquireImage((ImageInfo *) NULL,exception);
2470 if (draw_image == (Image *) NULL)
2471 return(MagickFalse);
2472 draw_image->columns=draw_info->width;
2473 draw_image->rows=draw_info->height;
2475 Transfer drawn X image to image.
2477 width=(unsigned int) image->columns;
2478 height=(unsigned int) image->rows;
2481 (void) XParseGeometry(draw_info->geometry,&x,&y,&width,&height);
2482 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,(ssize_t) x,
2483 (ssize_t) y,&draw_image->background_color,exception);
2484 if (SetImageStorageClass(draw_image,DirectClass,exception) == MagickFalse)
2485 return(MagickFalse);
2486 draw_image->matte=MagickTrue;
2487 draw_view=AcquireCacheView(draw_image);
2488 for (y=0; y < (int) draw_image->rows; y++)
2496 q=QueueCacheViewAuthenticPixels(draw_view,0,(ssize_t) y,draw_image->columns,
2498 if (q == (Quantum *) NULL)
2500 for (x=0; x < (int) draw_image->columns; x++)
2502 if (XGetPixel(draw_ximage,x,y) == 0)
2505 Set this pixel to the background color.
2507 SetPixelInfoPixel(draw_image,&draw_image->background_color,q);
2508 SetPixelAlpha(draw_image,(Quantum) (draw_info->stencil ==
2509 OpaqueStencil ? TransparentAlpha : OpaqueAlpha),q);
2514 Set this pixel to the pen color.
2516 SetPixelRed(draw_image,ScaleShortToQuantum(
2517 pixel->pen_color.red),q);
2518 SetPixelGreen(draw_image,ScaleShortToQuantum(
2519 pixel->pen_color.green),q);
2520 SetPixelBlue(draw_image,ScaleShortToQuantum(
2521 pixel->pen_color.blue),q);
2522 SetPixelAlpha(draw_image,(Quantum) (draw_info->stencil ==
2523 OpaqueStencil ? OpaqueAlpha : TransparentAlpha),q);
2525 q+=GetPixelChannels(draw_image);
2527 if (SyncCacheViewAuthenticPixels(draw_view,exception) == MagickFalse)
2530 draw_view=DestroyCacheView(draw_view);
2531 XDestroyImage(draw_ximage);
2533 Determine draw geometry.
2535 (void) XParseGeometry(draw_info->geometry,&x,&y,&width,&height);
2536 if ((width != (unsigned int) draw_image->columns) ||
2537 (height != (unsigned int) draw_image->rows))
2540 image_geometry[MaxTextExtent];
2545 (void) FormatLocaleString(image_geometry,MaxTextExtent,"%ux%u",
2547 (void) TransformImage(&draw_image,(char *) NULL,image_geometry,
2550 if (draw_info->degrees != 0.0)
2564 rotate_image=RotateImage(draw_image,draw_info->degrees,exception);
2565 if (rotate_image == (Image *) NULL)
2566 return(MagickFalse);
2567 draw_image=DestroyImage(draw_image);
2568 draw_image=rotate_image;
2570 Annotation is relative to the degree of rotation.
2572 normalized_degrees=draw_info->degrees;
2573 while (normalized_degrees < -45.0)
2574 normalized_degrees+=360.0;
2575 for (rotations=0; normalized_degrees > 45.0; rotations++)
2576 normalized_degrees-=90.0;
2577 switch (rotations % 4)
2587 x=x-(int) draw_image->columns/2;
2588 y=y+(int) draw_image->columns/2;
2596 x=x-(int) draw_image->columns;
2604 x=x-(int) draw_image->columns/2;
2605 y=y-(int) (draw_image->rows-(draw_image->columns/2));
2611 Composite text onto the image.
2613 draw_view=AcquireCacheView(draw_image);
2614 for (y=0; y < (int) draw_image->rows; y++)
2622 q=GetCacheViewAuthenticPixels(draw_view,0,(ssize_t) y,draw_image->columns,1,
2624 if (q == (Quantum *) NULL)
2626 for (x=0; x < (int) draw_image->columns; x++)
2628 if (GetPixelAlpha(image,q) != TransparentAlpha)
2629 SetPixelAlpha(draw_image,OpaqueAlpha,q);
2630 q+=GetPixelChannels(draw_image);
2632 if (SyncCacheViewAuthenticPixels(draw_view,exception) == MagickFalse)
2635 draw_view=DestroyCacheView(draw_view);
2636 (void) XParseGeometry(draw_info->geometry,&x,&y,&width,&height);
2637 if (draw_info->stencil == TransparentStencil)
2638 (void) CompositeImage(image,draw_image,CopyAlphaCompositeOp,MagickFalse,
2639 (ssize_t) x,(ssize_t) y,exception);
2643 (void) CompositeImage(image,draw_image,OverCompositeOp,MagickFalse,
2644 (ssize_t) x,(ssize_t) y,exception);
2647 draw_image=DestroyImage(draw_image);
2652 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2660 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2662 % XError() ignores BadWindow errors for XQueryTree and XGetWindowAttributes,
2663 % and ignores BadDrawable errors for XGetGeometry, and ignores BadValue errors
2664 % for XQueryColor. It returns MagickFalse in those cases. Otherwise it
2667 % The format of the XError function is:
2669 % int XError(display,error)
2671 % A description of each parameter follows:
2673 % o display: Specifies a pointer to the Display structure; returned from
2676 % o error: Specifies the error event.
2680 #if defined(__cplusplus) || defined(c_plusplus)
2684 MagickExport int XError(Display *display,XErrorEvent *error)
2686 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2687 assert(display != (Display *) NULL);
2688 assert(error != (XErrorEvent *) NULL);
2689 xerror_alert=MagickTrue;
2690 switch (error->request_code)
2694 if ((int) error->error_code == BadDrawable)
2695 return(MagickFalse);
2698 case X_GetWindowAttributes:
2701 if ((int) error->error_code == BadWindow)
2702 return(MagickFalse);
2707 if ((int) error->error_code == BadValue)
2708 return(MagickFalse);
2715 #if defined(__cplusplus) || defined(c_plusplus)
2720 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2724 % X F r e e R e s o u r c e s %
2728 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2730 % XFreeResources() frees X11 resources.
2732 % The format of the XFreeResources method is:
2734 % void XFreeResources(Display *display,XVisualInfo *visual_info,
2735 % XStandardColormap *map_info,XPixelInfo *pixel,XFontStruct *font_info,
2736 % XResourceInfo *resource_info,XWindowInfo *window_info)
2737 % resource_info,window_info)
2739 % A description of each parameter follows:
2741 % o display: Specifies a connection to an X server; returned from
2744 % o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
2745 % returned from XGetVisualInfo.
2747 % o map_info: If map_type is specified, this structure is initialized
2748 % with info from the Standard Colormap.
2750 % o pixel: Specifies a pointer to a XPixelInfo structure.
2752 % o font_info: Specifies a pointer to a XFontStruct structure.
2754 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
2756 % o window_info: Specifies a pointer to a X11 XWindowInfo structure.
2759 MagickPrivate void XFreeResources(Display *display,XVisualInfo *visual_info,
2760 XStandardColormap *map_info,XPixelInfo *pixel,XFontStruct *font_info,
2761 XResourceInfo *resource_info,XWindowInfo *window_info)
2763 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2764 assert(display != (Display *) NULL);
2765 assert(resource_info != (XResourceInfo *) NULL);
2766 if (window_info != (XWindowInfo *) NULL)
2771 if (window_info->ximage != (XImage *) NULL)
2772 XDestroyImage(window_info->ximage);
2773 if (window_info->id != (Window) NULL)
2776 Free destroy window and free cursors.
2778 if (window_info->id != XRootWindow(display,visual_info->screen))
2779 (void) XDestroyWindow(display,window_info->id);
2780 if (window_info->annotate_context != (GC) NULL)
2781 (void) XFreeGC(display,window_info->annotate_context);
2782 if (window_info->highlight_context != (GC) NULL)
2783 (void) XFreeGC(display,window_info->highlight_context);
2784 if (window_info->widget_context != (GC) NULL)
2785 (void) XFreeGC(display,window_info->widget_context);
2786 if (window_info->cursor != (Cursor) NULL)
2787 (void) XFreeCursor(display,window_info->cursor);
2788 window_info->cursor=(Cursor) NULL;
2789 if (window_info->busy_cursor != (Cursor) NULL)
2790 (void) XFreeCursor(display,window_info->busy_cursor);
2791 window_info->busy_cursor=(Cursor) NULL;
2797 if (font_info != (XFontStruct *) NULL)
2799 (void) XFreeFont(display,font_info);
2800 font_info=(XFontStruct *) NULL;
2802 if (map_info != (XStandardColormap *) NULL)
2805 Free X Standard Colormap.
2807 if (resource_info->map_type == (char *) NULL)
2808 (void) XFreeStandardColormap(display,visual_info,map_info,pixel);
2809 (void) XFree((void *) map_info);
2814 if (visual_info != (XVisualInfo *) NULL)
2815 (void) XFree((void *) visual_info);
2816 if (resource_info->close_server != MagickFalse)
2817 (void) XCloseDisplay(display);
2821 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2825 % X F r e e S t a n d a r d C o l o r m a p %
2829 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2831 % XFreeStandardColormap() frees an X11 colormap.
2833 % The format of the XFreeStandardColormap method is:
2835 % void XFreeStandardColormap(Display *display,
2836 % const XVisualInfo *visual_info,XStandardColormap *map_info,
2837 % XPixelInfo *pixel)
2839 % A description of each parameter follows:
2841 % o display: Specifies a connection to an X server; returned from
2844 % o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
2845 % returned from XGetVisualInfo.
2847 % o map_info: If map_type is specified, this structure is initialized
2848 % with info from the Standard Colormap.
2850 % o pixel: Specifies a pointer to a XPixelInfo structure.
2853 MagickPrivate void XFreeStandardColormap(Display *display,
2854 const XVisualInfo *visual_info,XStandardColormap *map_info,XPixelInfo *pixel)
2859 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2860 assert(display != (Display *) NULL);
2861 assert(visual_info != (XVisualInfo *) NULL);
2862 assert(map_info != (XStandardColormap *) NULL);
2863 (void) XFlush(display);
2864 if (map_info->colormap != (Colormap) NULL)
2866 if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
2867 (void) XFreeColormap(display,map_info->colormap);
2869 if (pixel != (XPixelInfo *) NULL)
2870 if ((visual_info->klass != TrueColor) &&
2871 (visual_info->klass != DirectColor))
2872 (void) XFreeColors(display,map_info->colormap,pixel->pixels,
2873 (int) pixel->colors,0);
2875 map_info->colormap=(Colormap) NULL;
2876 if (pixel != (XPixelInfo *) NULL)
2878 if (pixel->pixels != (unsigned long *) NULL)
2879 pixel->pixels=(unsigned long *) RelinquishMagickMemory(pixel->pixels);
2880 pixel->pixels=(unsigned long *) NULL;
2885 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2889 % X G e t A n n o t a t e I n f o %
2893 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2895 % XGetAnnotateInfo() initializes the AnnotateInfo structure.
2897 % The format of the XGetAnnotateInfo method is:
2899 % void XGetAnnotateInfo(XAnnotateInfo *annotate_info)
2901 % A description of each parameter follows:
2903 % o annotate_info: Specifies a pointer to a XAnnotateInfo structure.
2906 MagickPrivate void XGetAnnotateInfo(XAnnotateInfo *annotate_info)
2909 Initialize annotate structure.
2911 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2912 assert(annotate_info != (XAnnotateInfo *) NULL);
2915 annotate_info->width=0;
2916 annotate_info->height=0;
2917 annotate_info->stencil=ForegroundStencil;
2918 annotate_info->degrees=0.0;
2919 annotate_info->font_info=(XFontStruct *) NULL;
2920 annotate_info->text=(char *) NULL;
2921 *annotate_info->geometry='\0';
2922 annotate_info->previous=(XAnnotateInfo *) NULL;
2923 annotate_info->next=(XAnnotateInfo *) NULL;
2924 (void) XSupportsLocale();
2925 (void) XSetLocaleModifiers("");
2929 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2933 % X G e t M a p I n f o %
2937 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2939 % XGetMapInfo() initializes the XStandardColormap structure.
2941 % The format of the XStandardColormap method is:
2943 % void XGetMapInfo(const XVisualInfo *visual_info,const Colormap colormap,
2944 % XStandardColormap *map_info)
2946 % A description of each parameter follows:
2948 % o colormap: Specifies the ID of the X server colormap.
2950 % o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
2951 % returned from XGetVisualInfo.
2953 % o map_info: Specifies a pointer to a X11 XStandardColormap structure.
2956 MagickPrivate void XGetMapInfo(const XVisualInfo *visual_info,
2957 const Colormap colormap,XStandardColormap *map_info)
2960 Initialize map info.
2962 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2963 assert(visual_info != (XVisualInfo *) NULL);
2964 assert(map_info != (XStandardColormap *) NULL);
2965 map_info->colormap=colormap;
2966 map_info->red_max=visual_info->red_mask;
2967 map_info->red_mult=(size_t) (map_info->red_max != 0 ? 1 : 0);
2968 if (map_info->red_max != 0)
2969 while ((map_info->red_max & 0x01) == 0)
2971 map_info->red_max>>=1;
2972 map_info->red_mult<<=1;
2974 map_info->green_max=visual_info->green_mask;
2975 map_info->green_mult=(size_t) (map_info->green_max != 0 ? 1 : 0);
2976 if (map_info->green_max != 0)
2977 while ((map_info->green_max & 0x01) == 0)
2979 map_info->green_max>>=1;
2980 map_info->green_mult<<=1;
2982 map_info->blue_max=visual_info->blue_mask;
2983 map_info->blue_mult=(size_t) (map_info->blue_max != 0 ? 1 : 0);
2984 if (map_info->blue_max != 0)
2985 while ((map_info->blue_max & 0x01) == 0)
2987 map_info->blue_max>>=1;
2988 map_info->blue_mult<<=1;
2990 map_info->base_pixel=0;
2994 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2998 % X G e t P i x e l I n f o %
3002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3004 % XGetPixelInfo() initializes the PixelInfo structure.
3006 % The format of the XGetPixelInfo method is:
3008 % void XGetPixelInfo(Display *display,const XVisualInfo *visual_info,
3009 % const XStandardColormap *map_info,const XResourceInfo *resource_info,
3010 % Image *image,XPixelInfo *pixel)
3013 % A description of each parameter follows:
3015 % o display: Specifies a connection to an X server; returned from
3018 % o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
3019 % returned from XGetVisualInfo.
3021 % o map_info: If map_type is specified, this structure is initialized
3022 % with info from the Standard Colormap.
3024 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
3026 % o image: the image.
3028 % o pixel: Specifies a pointer to a XPixelInfo structure.
3031 MagickPrivate void XGetPixelInfo(Display *display,
3032 const XVisualInfo *visual_info,const XStandardColormap *map_info,
3033 const XResourceInfo *resource_info,Image *image,XPixelInfo *pixel)
3036 *PenColors[MaxNumberPens]=
3038 "#000000000000", /* black */
3039 "#00000000ffff", /* blue */
3040 "#0000ffffffff", /* cyan */
3041 "#0000ffff0000", /* green */
3042 "#bdbdbdbdbdbd", /* gray */
3043 "#ffff00000000", /* red */
3044 "#ffff0000ffff", /* magenta */
3045 "#ffffffff0000", /* yellow */
3046 "#ffffffffffff", /* white */
3047 "#bdbdbdbdbdbd", /* gray */
3048 "#bdbdbdbdbdbd" /* gray */
3064 Initialize pixel info.
3066 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3067 assert(display != (Display *) NULL);
3068 assert(visual_info != (XVisualInfo *) NULL);
3069 assert(map_info != (XStandardColormap *) NULL);
3070 assert(resource_info != (XResourceInfo *) NULL);
3071 assert(pixel != (XPixelInfo *) NULL);
3073 if (image != (Image *) NULL)
3074 if (image->storage_class == PseudoClass)
3075 pixel->colors=(ssize_t) image->colors;
3076 packets=(unsigned int)
3077 MagickMax((int) pixel->colors,visual_info->colormap_size)+MaxNumberPens;
3078 if (pixel->pixels != (unsigned long *) NULL)
3079 pixel->pixels=(unsigned long *) RelinquishMagickMemory(pixel->pixels);
3080 pixel->pixels=(unsigned long *) AcquireQuantumMemory(packets,
3081 sizeof(pixel->pixels));
3082 if (pixel->pixels == (unsigned long *) NULL)
3083 ThrowXWindowFatalException(ResourceLimitFatalError,"UnableToGetPixelInfo",
3086 Set foreground color.
3088 colormap=map_info->colormap;
3089 (void) XParseColor(display,colormap,(char *) ForegroundColor,
3090 &pixel->foreground_color);
3091 status=XParseColor(display,colormap,resource_info->foreground_color,
3092 &pixel->foreground_color);
3093 if (status == False)
3094 ThrowXWindowFatalException(XServerError,"ColorIsNotKnownToServer",
3095 resource_info->foreground_color);
3096 pixel->foreground_color.pixel=
3097 XStandardPixel(map_info,&pixel->foreground_color);
3098 pixel->foreground_color.flags=(char) (DoRed | DoGreen | DoBlue);
3100 Set background color.
3102 (void) XParseColor(display,colormap,"#d6d6d6d6d6d6",&pixel->background_color);
3103 status=XParseColor(display,colormap,resource_info->background_color,
3104 &pixel->background_color);
3105 if (status == False)
3106 ThrowXWindowFatalException(XServerError,"ColorIsNotKnownToServer",
3107 resource_info->background_color);
3108 pixel->background_color.pixel=
3109 XStandardPixel(map_info,&pixel->background_color);
3110 pixel->background_color.flags=(char) (DoRed | DoGreen | DoBlue);
3114 (void) XParseColor(display,colormap,(char *) BorderColor,
3115 &pixel->border_color);
3116 status=XParseColor(display,colormap,resource_info->border_color,
3117 &pixel->border_color);
3118 if (status == False)
3119 ThrowXWindowFatalException(XServerError,"ColorIsNotKnownToServer",
3120 resource_info->border_color);
3121 pixel->border_color.pixel=XStandardPixel(map_info,&pixel->border_color);
3122 pixel->border_color.flags=(char) (DoRed | DoGreen | DoBlue);
3126 pixel->matte_color=pixel->background_color;
3127 if (resource_info->matte_color != (char *) NULL)
3130 Matte color is specified as a X resource or command line argument.
3132 status=XParseColor(display,colormap,resource_info->matte_color,
3133 &pixel->matte_color);
3134 if (status == False)
3135 ThrowXWindowFatalException(XServerError,"ColorIsNotKnownToServer",
3136 resource_info->matte_color);
3137 pixel->matte_color.pixel=XStandardPixel(map_info,&pixel->matte_color);
3138 pixel->matte_color.flags=(char) (DoRed | DoGreen | DoBlue);
3141 Set highlight color.
3143 pixel->highlight_color.red=(unsigned short) ((
3144 pixel->matte_color.red*ScaleQuantumToShort(HighlightModulate))/65535L+
3145 (ScaleQuantumToShort((Quantum) (QuantumRange-HighlightModulate))));
3146 pixel->highlight_color.green=(unsigned short) ((
3147 pixel->matte_color.green*ScaleQuantumToShort(HighlightModulate))/65535L+
3148 (ScaleQuantumToShort((Quantum) (QuantumRange-HighlightModulate))));
3149 pixel->highlight_color.blue=(unsigned short) ((
3150 pixel->matte_color.blue*ScaleQuantumToShort(HighlightModulate))/65535L+
3151 (ScaleQuantumToShort((Quantum) (QuantumRange-HighlightModulate))));
3152 pixel->highlight_color.pixel=
3153 XStandardPixel(map_info,&pixel->highlight_color);
3154 pixel->highlight_color.flags=(char) (DoRed | DoGreen | DoBlue);
3158 pixel->shadow_color.red=(unsigned short) (((MagickRealType)
3159 pixel->matte_color.red*ScaleQuantumToShort(ShadowModulate))/65535L);
3160 pixel->shadow_color.green=(unsigned short) (((MagickRealType)
3161 pixel->matte_color.green*ScaleQuantumToShort(ShadowModulate))/65535L);
3162 pixel->shadow_color.blue=(unsigned short) (((MagickRealType)
3163 pixel->matte_color.blue*ScaleQuantumToShort(ShadowModulate))/65535L);
3164 pixel->shadow_color.pixel=XStandardPixel(map_info,&pixel->shadow_color);
3165 pixel->shadow_color.flags=(char) (DoRed | DoGreen | DoBlue);
3169 pixel->depth_color.red=(unsigned short) (((MagickRealType)
3170 pixel->matte_color.red*ScaleQuantumToShort(DepthModulate))/65535L);
3171 pixel->depth_color.green=(unsigned short) (((MagickRealType)
3172 pixel->matte_color.green*ScaleQuantumToShort(DepthModulate))/65535L);
3173 pixel->depth_color.blue=(unsigned short) (((MagickRealType)
3174 pixel->matte_color.blue*ScaleQuantumToShort(DepthModulate))/65535L);
3175 pixel->depth_color.pixel=XStandardPixel(map_info,&pixel->depth_color);
3176 pixel->depth_color.flags=(char) (DoRed | DoGreen | DoBlue);
3180 pixel->trough_color.red=(unsigned short) (((MagickRealType)
3181 pixel->matte_color.red*ScaleQuantumToShort(TroughModulate))/65535L);
3182 pixel->trough_color.green=(unsigned short) (((MagickRealType)
3183 pixel->matte_color.green*ScaleQuantumToShort(TroughModulate))/65535L);
3184 pixel->trough_color.blue=(unsigned short) (((MagickRealType)
3185 pixel->matte_color.blue*ScaleQuantumToShort(TroughModulate))/65535L);
3186 pixel->trough_color.pixel=XStandardPixel(map_info,&pixel->trough_color);
3187 pixel->trough_color.flags=(char) (DoRed | DoGreen | DoBlue);
3191 for (i=0; i < MaxNumberPens; i++)
3193 (void) XParseColor(display,colormap,(char *) PenColors[i],
3194 &pixel->pen_colors[i]);
3195 status=XParseColor(display,colormap,resource_info->pen_colors[i],
3196 &pixel->pen_colors[i]);
3197 if (status == False)
3198 ThrowXWindowFatalException(XServerError,"ColorIsNotKnownToServer",
3199 resource_info->pen_colors[i]);
3200 pixel->pen_colors[i].pixel=XStandardPixel(map_info,&pixel->pen_colors[i]);
3201 pixel->pen_colors[i].flags=(char) (DoRed | DoGreen | DoBlue);
3203 pixel->box_color=pixel->background_color;
3204 pixel->pen_color=pixel->foreground_color;
3207 if (image != (Image *) NULL)
3209 if ((resource_info->gamma_correct != MagickFalse) &&
3210 (image->gamma != 0.0))
3219 Initialize map relative to display and image gamma.
3221 flags=ParseGeometry(resource_info->display_gamma,&geometry_info);
3222 red_gamma=geometry_info.rho;
3223 green_gamma=geometry_info.sigma;
3224 if ((flags & SigmaValue) == 0)
3225 green_gamma=red_gamma;
3226 blue_gamma=geometry_info.xi;
3227 if ((flags & XiValue) == 0)
3228 blue_gamma=red_gamma;
3229 red_gamma*=image->gamma;
3230 green_gamma*=image->gamma;
3231 blue_gamma*=image->gamma;
3233 if (image->storage_class == PseudoClass)
3236 Initialize pixel array for images of type PseudoClass.
3238 for (i=0; i < (ssize_t) image->colors; i++)
3239 pixel->pixels[i]=XGammaPacket(map_info,image->colormap+i);
3240 for (i=0; i < MaxNumberPens; i++)
3241 pixel->pixels[image->colors+i]=pixel->pen_colors[i].pixel;
3242 pixel->colors+=MaxNumberPens;
3248 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3252 % X G e t R e s o u r c e C l a s s %
3256 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3258 % XGetResourceClass() queries the X server for the specified resource name or
3259 % class. If the resource name or class is not defined in the database, the
3260 % supplied default value is returned.
3262 % The format of the XGetResourceClass method is:
3264 % char *XGetResourceClass(XrmDatabase database,const char *client_name,
3265 % const char *keyword,char *resource_default)
3267 % A description of each parameter follows:
3269 % o database: Specifies a resource database; returned from
3270 % XrmGetStringDatabase.
3272 % o client_name: Specifies the application name used to retrieve resource
3273 % info from the X server database.
3275 % o keyword: Specifies the keyword of the value being retrieved.
3277 % o resource_default: Specifies the default value to return if the query
3278 % fails to find the specified keyword/class.
3281 MagickExport char *XGetResourceClass(XrmDatabase database,
3282 const char *client_name,const char *keyword,char *resource_default)
3285 resource_class[MaxTextExtent],
3286 resource_name[MaxTextExtent];
3297 if (database == (XrmDatabase) NULL)
3298 return(resource_default);
3299 *resource_name='\0';
3300 *resource_class='\0';
3301 if (keyword != (char *) NULL)
3308 Initialize resource keyword and class.
3310 (void) FormatLocaleString(resource_name,MaxTextExtent,"%s.%s",
3311 client_name,keyword);
3312 c=(int) (*client_name);
3313 if ((c >= XK_a) && (c <= XK_z))
3316 if ((c >= XK_agrave) && (c <= XK_odiaeresis))
3317 c-=(XK_agrave-XK_Agrave);
3319 if ((c >= XK_oslash) && (c <= XK_thorn))
3320 c-=(XK_oslash-XK_Ooblique);
3322 if ((k >= XK_a) && (k <= XK_z))
3325 if ((k >= XK_agrave) && (k <= XK_odiaeresis))
3326 k-=(XK_agrave-XK_Agrave);
3328 if ((k >= XK_oslash) && (k <= XK_thorn))
3329 k-=(XK_oslash-XK_Ooblique);
3330 (void) FormatLocaleString(resource_class,MaxTextExtent,"%c%s.%c%s",c,
3331 client_name+1,k,keyword+1);
3333 status=XrmGetResource(database,resource_name,resource_class,&resource_type,
3335 if (status == False)
3336 return(resource_default);
3337 return(resource_value.addr);
3341 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3345 % X G e t R e s o u r c e D a t a b a s e %
3349 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3351 % XGetResourceDatabase() creates a new resource database and initializes it.
3353 % The format of the XGetResourceDatabase method is:
3355 % XrmDatabase XGetResourceDatabase(Display *display,
3356 % const char *client_name)
3358 % A description of each parameter follows:
3360 % o database: XGetResourceDatabase() returns the database after it is
3363 % o display: Specifies a connection to an X server; returned from
3366 % o client_name: Specifies the application name used to retrieve resource
3367 % info from the X server database.
3370 MagickExport XrmDatabase XGetResourceDatabase(Display *display,
3371 const char *client_name)
3374 filename[MaxTextExtent];
3386 if (display == (Display *) NULL)
3387 return((XrmDatabase) NULL);
3388 assert(client_name != (char *) NULL);
3390 Initialize resource database.
3393 (void) XGetDefault(display,(char *) client_name,"dummy");
3394 resource_database=XrmGetDatabase(display);
3396 Combine application database.
3398 if (client_name != (char *) NULL)
3401 Get basename of client.
3403 p=client_name+(strlen(client_name)-1);
3404 while ((p > client_name) && (*p != '/'))
3409 c=(int) (*client_name);
3410 if ((c >= XK_a) && (c <= XK_z))
3413 if ((c >= XK_agrave) && (c <= XK_odiaeresis))
3414 c-=(XK_agrave-XK_Agrave);
3416 if ((c >= XK_oslash) && (c <= XK_thorn))
3417 c-=(XK_oslash-XK_Ooblique);
3418 #if defined(X11_APPLICATION_PATH)
3419 (void) FormatLocaleString(filename,MaxTextExtent,"%s%c%s",
3420 X11_APPLICATION_PATH,c,client_name+1);
3421 (void) XrmCombineFileDatabase(filename,&resource_database,MagickFalse);
3423 if (XResourceManagerString(display) != (char *) NULL)
3426 Combine server database.
3428 server_database=XrmGetStringDatabase(XResourceManagerString(display));
3429 XrmCombineDatabase(server_database,&resource_database,MagickFalse);
3432 Merge user preferences database.
3434 #if defined(X11_PREFERENCES_PATH)
3435 (void) FormatLocaleString(filename,MaxTextExtent,"%s%src",
3436 X11_PREFERENCES_PATH,client_name);
3437 ExpandFilename(filename);
3438 (void) XrmCombineFileDatabase(filename,&resource_database,MagickFalse);
3440 return(resource_database);
3444 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3448 % X G e t R e s o u r c e I n f o %
3452 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3454 % XGetResourceInfo(image_info,) initializes the ResourceInfo structure.
3456 % The format of the XGetResourceInfo method is:
3458 % void XGetResourceInfo(const ImageInfo *image_info,XrmDatabase database,
3459 % const char *client_name,XResourceInfo *resource_info)
3461 % A description of each parameter follows:
3463 % o image_info: the image info.
3465 % o database: Specifies a resource database; returned from
3466 % XrmGetStringDatabase.
3468 % o client_name: Specifies the application name used to retrieve
3469 % resource info from the X server database.
3471 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
3474 MagickExport void XGetResourceInfo(const ImageInfo *image_info,
3475 XrmDatabase database,const char *client_name,XResourceInfo *resource_info)
3482 Initialize resource info fields.
3484 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3485 assert(resource_info != (XResourceInfo *) NULL);
3486 (void) ResetMagickMemory(resource_info,0,sizeof(*resource_info));
3487 resource_info->resource_database=database;
3488 resource_info->image_info=(ImageInfo *) image_info;
3489 (void) SetImageInfoProgressMonitor(resource_info->image_info,
3490 XMagickProgressMonitor,(void *) NULL);
3491 resource_info->quantize_info=CloneQuantizeInfo((QuantizeInfo *) NULL);
3492 resource_info->close_server=MagickTrue;
3493 resource_info->client_name=AcquireString(client_name);
3494 resource_value=XGetResourceClass(database,client_name,"backdrop",
3496 resource_info->backdrop=IsStringTrue(resource_value);
3497 resource_info->background_color=XGetResourceInstance(database,client_name,
3498 "background",(char *) "#d6d6d6d6d6d6");
3499 resource_info->border_color=XGetResourceInstance(database,client_name,
3500 "borderColor",BorderColor);
3501 resource_value=XGetResourceClass(database,client_name,"borderWidth",
3503 resource_info->border_width=(unsigned int) StringToUnsignedLong(
3505 resource_value=XGetResourceClass(database,client_name,"colormap",
3507 resource_info->colormap=UndefinedColormap;
3508 if (LocaleCompare("private",resource_value) == 0)
3509 resource_info->colormap=PrivateColormap;
3510 if (LocaleCompare("shared",resource_value) == 0)
3511 resource_info->colormap=SharedColormap;
3512 if (resource_info->colormap == UndefinedColormap)
3513 ThrowXWindowFatalException(OptionError,"UnrecognizedColormapType",
3515 resource_value=XGetResourceClass(database,client_name,
3516 "colorRecovery",(char *) "False");
3517 resource_info->color_recovery=IsStringTrue(resource_value);
3518 resource_value=XGetResourceClass(database,client_name,"confirmExit",
3520 resource_info->confirm_exit=IsStringTrue(resource_value);
3521 resource_value=XGetResourceClass(database,client_name,"confirmEdit",
3523 resource_info->confirm_edit=IsStringTrue(resource_value);
3524 resource_value=XGetResourceClass(database,client_name,"delay",(char *) "1");
3525 resource_info->delay=(unsigned int) StringToUnsignedLong(resource_value);
3526 resource_info->display_gamma=XGetResourceClass(database,client_name,
3527 "displayGamma",(char *) "2.2");
3528 resource_value=XGetResourceClass(database,client_name,"displayWarnings",
3530 resource_info->display_warnings=IsStringTrue(resource_value);
3531 resource_info->font=XGetResourceClass(database,client_name,"font",
3533 resource_info->font=XGetResourceClass(database,client_name,"fontList",
3534 resource_info->font);
3535 resource_info->font_name[0]=XGetResourceClass(database,client_name,"font1",
3537 resource_info->font_name[1]=XGetResourceClass(database,client_name,"font2",
3538 (char *) "variable");
3539 resource_info->font_name[2]=XGetResourceClass(database,client_name,"font3",
3541 resource_info->font_name[3]=XGetResourceClass(database,client_name,"font4",
3543 resource_info->font_name[4]=XGetResourceClass(database,client_name,"font5",
3544 (char *) "7x13bold");
3545 resource_info->font_name[5]=XGetResourceClass(database,client_name,"font6",
3546 (char *) "8x13bold");
3547 resource_info->font_name[6]=XGetResourceClass(database,client_name,"font7",
3548 (char *) "9x15bold");
3549 resource_info->font_name[7]=XGetResourceClass(database,client_name,"font8",
3551 resource_info->font_name[8]=XGetResourceClass(database,client_name,"font9",
3553 resource_info->font_name[9]=XGetResourceClass(database,client_name,"font0",
3555 resource_info->font_name[10]=XGetResourceClass(database,client_name,"font0",
3557 resource_info->foreground_color=XGetResourceInstance(database,client_name,
3558 "foreground",ForegroundColor);
3559 resource_value=XGetResourceClass(database,client_name,"gammaCorrect",
3561 resource_info->gamma_correct=IsStringTrue(resource_value);
3562 resource_info->image_geometry=ConstantString(XGetResourceClass(database,
3563 client_name,"geometry",(char *) NULL));
3564 resource_value=XGetResourceClass(database,client_name,"gravity",
3566 resource_info->gravity=(GravityType) ParseCommandOption(MagickGravityOptions,
3567 MagickFalse,resource_value);
3568 directory=getcwd(resource_info->home_directory,MaxTextExtent);
3570 resource_info->icon_geometry=XGetResourceClass(database,client_name,
3571 "iconGeometry",(char *) NULL);
3572 resource_value=XGetResourceClass(database,client_name,"iconic",
3574 resource_info->iconic=IsStringTrue(resource_value);
3575 resource_value=XGetResourceClass(database,client_name,"immutable",
3576 LocaleCompare(client_name,"PerlMagick") == 0 ? (char *) "True" :
3578 resource_info->immutable=IsStringTrue(resource_value);
3579 resource_value=XGetResourceClass(database,client_name,"magnify",
3581 resource_info->magnify=(unsigned int) StringToUnsignedLong(resource_value);
3582 resource_info->map_type=XGetResourceClass(database,client_name,"map",
3584 resource_info->matte_color=XGetResourceInstance(database,client_name,
3585 "mattecolor",(char *) NULL);
3586 resource_info->name=ConstantString(XGetResourceClass(database,client_name,
3587 "name",(char *) NULL));
3588 resource_info->pen_colors[0]=XGetResourceClass(database,client_name,"pen1",
3590 resource_info->pen_colors[1]=XGetResourceClass(database,client_name,"pen2",
3592 resource_info->pen_colors[2]=XGetResourceClass(database,client_name,"pen3",
3594 resource_info->pen_colors[3]=XGetResourceClass(database,client_name,"pen4",
3596 resource_info->pen_colors[4]=XGetResourceClass(database,client_name,"pen5",
3598 resource_info->pen_colors[5]=XGetResourceClass(database,client_name,"pen6",
3600 resource_info->pen_colors[6]=XGetResourceClass(database,client_name,"pen7",
3601 (char *) "magenta");
3602 resource_info->pen_colors[7]=XGetResourceClass(database,client_name,"pen8",
3604 resource_info->pen_colors[8]=XGetResourceClass(database,client_name,"pen9",
3606 resource_info->pen_colors[9]=XGetResourceClass(database,client_name,"pen0",
3608 resource_info->pen_colors[10]=XGetResourceClass(database,client_name,"pen0",
3610 resource_value=XGetResourceClass(database,client_name,"pause",(char *) "0");
3611 resource_info->pause=(unsigned int) StringToUnsignedLong(resource_value);
3612 resource_value=XGetResourceClass(database,client_name,"quantum",(char *) "1");
3613 resource_info->quantum=StringToLong(resource_value);
3614 resource_info->text_font=XGetResourceClass(database,client_name,(char *)
3615 "font",(char *) "fixed");
3616 resource_info->text_font=XGetResourceClass(database,client_name,
3617 "textFontList",resource_info->text_font);
3618 resource_info->title=XGetResourceClass(database,client_name,"title",
3620 resource_value=XGetResourceClass(database,client_name,"undoCache",
3622 resource_info->undo_cache=(unsigned int) StringToUnsignedLong(resource_value);
3623 resource_value=XGetResourceClass(database,client_name,"update",
3625 resource_info->update=IsStringTrue(resource_value);
3626 resource_value=XGetResourceClass(database,client_name,"usePixmap",
3628 resource_info->use_pixmap=IsStringTrue(resource_value);
3629 resource_value=XGetResourceClass(database,client_name,"sharedMemory",
3631 resource_info->use_shared_memory=IsStringTrue(resource_value);
3632 resource_info->visual_type=XGetResourceClass(database,client_name,"visual",
3634 resource_info->window_group=XGetResourceClass(database,client_name,
3635 "windowGroup",(char *) NULL);
3636 resource_info->window_id=XGetResourceClass(database,client_name,"window",
3638 resource_info->write_filename=XGetResourceClass(database,client_name,
3639 "writeFilename",(char *) NULL);
3643 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3647 % X G e t R e s o u r c e I n s t a n c e %
3651 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3653 % XGetResourceInstance() queries the X server for the specified resource name.
3654 % If the resource name is not defined in the database, the supplied default
3655 % value is returned.
3657 % The format of the XGetResourceInstance method is:
3659 % char *XGetResourceInstance(XrmDatabase database,const char *client_name,
3660 % const char *keyword,const char *resource_default)
3662 % A description of each parameter follows:
3664 % o database: Specifies a resource database; returned from
3665 % XrmGetStringDatabase.
3667 % o client_name: Specifies the application name used to retrieve
3668 % resource info from the X server database.
3670 % o keyword: Specifies the keyword of the value being retrieved.
3672 % o resource_default: Specifies the default value to return if the query
3673 % fails to find the specified keyword/class.
3676 MagickExport char *XGetResourceInstance(XrmDatabase database,
3677 const char *client_name,const char *keyword,const char *resource_default)
3681 resource_name[MaxTextExtent];
3689 if (database == (XrmDatabase) NULL)
3690 return((char *) resource_default);
3691 *resource_name='\0';
3692 if (keyword != (char *) NULL)
3693 (void) FormatLocaleString(resource_name,MaxTextExtent,"%s.%s",client_name,
3695 status=XrmGetResource(database,resource_name,"ImageMagick",&resource_type,
3697 if (status == False)
3698 return((char *) resource_default);
3699 return(resource_value.addr);
3703 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3707 % X G e t S c r e e n D e n s i t y %
3711 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3713 % XGetScreenDensity() returns the density of the X server screen in
3716 % The format of the XGetScreenDensity method is:
3718 % char *XGetScreenDensity(Display *display)
3720 % A description of each parameter follows:
3722 % o density: XGetScreenDensity() returns the density of the X screen in
3725 % o display: Specifies a connection to an X server; returned from
3729 MagickExport char *XGetScreenDensity(Display *display)
3732 density[MaxTextExtent];
3739 Set density as determined by screen size.
3741 x_density=((((double) DisplayWidth(display,XDefaultScreen(display)))*25.4)/
3742 ((double) DisplayWidthMM(display,XDefaultScreen(display))));
3743 y_density=((((double) DisplayHeight(display,XDefaultScreen(display)))*25.4)/
3744 ((double) DisplayHeightMM(display,XDefaultScreen(display))));
3745 (void) FormatLocaleString(density,MaxTextExtent,"%gx%g",x_density,
3747 return(GetPageGeometry(density));
3751 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3755 + X G e t S u b w i n d o w %
3759 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3761 % XGetSubwindow() returns the subwindow of a window chosen the user with the
3762 % pointer and a button press.
3764 % The format of the XGetSubwindow method is:
3766 % Window XGetSubwindow(Display *display,Window window,int x,int y)
3768 % A description of each parameter follows:
3770 % o subwindow: XGetSubwindow() returns NULL if no subwindow is found
3771 % otherwise the subwindow is returned.
3773 % o display: Specifies a connection to an X server; returned from
3776 % o window: Specifies a pointer to a Window.
3778 % o x: the x coordinate of the pointer relative to the origin of the
3781 % o y: the y coordinate of the pointer relative to the origin of the
3785 static Window XGetSubwindow(Display *display,Window window,int x,int y)
3798 assert(display != (Display *) NULL);
3799 source_window=XRootWindow(display,XDefaultScreen(display));
3800 if (window == (Window) NULL)
3801 return(source_window);
3802 target_window=window;
3805 status=XTranslateCoordinates(display,source_window,window,x,y,
3806 &x_offset,&y_offset,&target_window);
3809 if (target_window == (Window) NULL)
3811 source_window=window;
3812 window=target_window;
3816 if (target_window == (Window) NULL)
3817 target_window=window;
3818 return(target_window);
3822 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3826 % X G e t W i n d o w C o l o r %
3830 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3832 % XGetWindowColor() returns the color of a pixel interactively chosen from the
3835 % The format of the XGetWindowColor method is:
3837 % MagickBooleanType XGetWindowColor(Display *display,XWindows *windows,
3838 % char *name,ExceptionInfo *exception)
3840 % A description of each parameter follows:
3842 % o display: Specifies a connection to an X server; returned from
3845 % o windows: Specifies a pointer to a XWindows structure.
3847 % o name: the name of the color if found in the X Color Database is
3848 % returned in this character string.
3850 % o exception: return any errors or warnings in this structure.
3853 MagickPrivate MagickBooleanType XGetWindowColor(Display *display,
3854 XWindows *windows,char *name,ExceptionInfo *exception)
3885 Choose a pixel from the X server.
3887 assert(display != (Display *) NULL);
3888 assert(name != (char *) NULL);
3889 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
3891 target_window=XSelectWindow(display,&crop_info);
3892 if (target_window == (Window) NULL)
3893 return(MagickFalse);
3894 root_window=XRootWindow(display,XDefaultScreen(display));
3895 client_window=target_window;
3896 if (target_window != root_window)
3904 status=XGetGeometry(display,target_window,&root_window,&x,&x,&d,&d,&d,&d);
3905 if (status != False)
3907 client_window=XClientWindow(display,target_window);
3908 target_window=client_window;
3912 Verify window is viewable.
3914 status=XGetWindowAttributes(display,target_window,&window_attributes);
3915 if ((status == False) || (window_attributes.map_state != IsViewable))
3916 return(MagickFalse);
3920 (void) XTranslateCoordinates(display,root_window,target_window,
3921 (int) crop_info.x,(int) crop_info.y,&x,&y,&child);
3922 ximage=XGetImage(display,target_window,x,y,1,1,AllPlanes,ZPixmap);
3923 if (ximage == (XImage *) NULL)
3924 return(MagickFalse);
3925 color.pixel=XGetPixel(ximage,0,0);
3926 XDestroyImage(ximage);
3928 Match color against the color database.
3930 (void) XQueryColor(display,window_attributes.colormap,&color);
3931 pixel.red=(double) ScaleShortToQuantum(color.red);
3932 pixel.green=(double) ScaleShortToQuantum(color.green);
3933 pixel.blue=(double) ScaleShortToQuantum(color.blue);
3934 pixel.alpha=OpaqueAlpha;
3935 (void) QueryColorname(windows->image.image,&pixel,X11Compliance,name,
3941 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3945 + X G e t W i n d o w I m a g e %
3949 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3951 % XGetWindowImage() reads an image from the target X window and returns it.
3952 % XGetWindowImage() optionally descends the window hierarchy and overlays the
3953 % target image with each child image in an optimized fashion. Any child
3954 % window that have the same visual, colormap, and are contained by its parent
3957 % The format of the XGetWindowImage method is:
3959 % Image *XGetWindowImage(Display *display,const Window window,
3960 % const unsigned int borders,const unsigned int level,
3961 % ExceptionInfo *exception)
3963 % A description of each parameter follows:
3965 % o display: Specifies a connection to an X server; returned from
3968 % o window: Specifies the window to obtain the image from.
3970 % o borders: Specifies whether borders pixels are to be saved with
3973 % o level: Specifies an unsigned integer representing the level of
3974 % decent in the window hierarchy. This value must be zero or one on
3975 % the initial call to XGetWindowImage. A value of zero returns after
3976 % one call. A value of one causes the function to descend the window
3977 % hierarchy and overlay the target image with each subwindow image.
3979 % o exception: return any errors or warnings in this structure.
3982 static Image *XGetWindowImage(Display *display,const Window window,
3983 const unsigned int borders,const unsigned int level,ExceptionInfo *exception)
3985 typedef struct _ColormapInfo
3993 struct _ColormapInfo
3997 typedef struct _WindowInfo
4033 *colormap_info = (ColormapInfo *) NULL;
4053 Verify window is viewable.
4055 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
4056 assert(display != (Display *) NULL);
4057 status=XGetWindowAttributes(display,window,&window_attributes);
4058 if ((status == False) || (window_attributes.map_state != IsViewable))
4059 return((Image *) NULL);
4061 Cropping rectangle is relative to root window.
4063 root_window=XRootWindow(display,XDefaultScreen(display));
4064 (void) XTranslateCoordinates(display,window,root_window,0,0,&x_offset,
4066 crop_info.x=(ssize_t) x_offset;
4067 crop_info.y=(ssize_t) y_offset;
4068 crop_info.width=(size_t) window_attributes.width;
4069 crop_info.height=(size_t) window_attributes.height;
4070 if (borders != MagickFalse)
4073 Include border in image.
4075 crop_info.x-=(ssize_t) window_attributes.border_width;
4076 crop_info.y-=(ssize_t) window_attributes.border_width;
4077 crop_info.width+=(size_t) (window_attributes.border_width << 1);
4078 crop_info.height+=(size_t) (window_attributes.border_width << 1);
4081 Crop to root window.
4083 if (crop_info.x < 0)
4085 crop_info.width+=crop_info.x;
4088 if (crop_info.y < 0)
4090 crop_info.height+=crop_info.y;
4093 display_width=XDisplayWidth(display,XDefaultScreen(display));
4094 if ((int) (crop_info.x+crop_info.width) > display_width)
4095 crop_info.width=(size_t) (display_width-crop_info.x);
4096 display_height=XDisplayHeight(display,XDefaultScreen(display));
4097 if ((int) (crop_info.y+crop_info.height) > display_height)
4098 crop_info.height=(size_t) (display_height-crop_info.y);
4100 Initialize window info attributes.
4102 if (number_windows >= max_windows)
4105 Allocate or resize window info buffer.
4108 if (window_info == (WindowInfo *) NULL)
4109 window_info=(WindowInfo *) AcquireQuantumMemory((size_t) max_windows,
4110 sizeof(*window_info));
4112 window_info=(WindowInfo *) ResizeQuantumMemory(window_info,(size_t)
4113 max_windows,sizeof(*window_info));
4115 if (window_info == (WindowInfo *) NULL)
4117 ThrowXWindowFatalException(ResourceLimitError,
4118 "MemoryAllocationFailed","...");
4119 return((Image *) NULL);
4121 id=number_windows++;
4122 window_info[id].window=window;
4123 window_info[id].visual=window_attributes.visual;
4124 window_info[id].colormap=window_attributes.colormap;
4125 window_info[id].bounds.x1=(short) crop_info.x;
4126 window_info[id].bounds.y1=(short) crop_info.y;
4127 window_info[id].bounds.x2=(short) (crop_info.x+(int) crop_info.width-1);
4128 window_info[id].bounds.y2=(short) (crop_info.y+(int) crop_info.height-1);
4129 crop_info.x-=x_offset;
4130 crop_info.y-=y_offset;
4131 window_info[id].crop_info=crop_info;
4141 Descend the window hierarchy.
4143 status=XQueryTree(display,window,&root_window,&window_info[id].parent,
4144 &children,&number_children);
4145 for (i=0; i < id; i++)
4146 if ((window_info[i].window == window_info[id].parent) &&
4147 (window_info[i].visual == window_info[id].visual) &&
4148 (window_info[i].colormap == window_info[id].colormap))
4150 if ((window_info[id].bounds.x1 <= window_info[i].bounds.x1) ||
4151 (window_info[id].bounds.x1 >= window_info[i].bounds.x2) ||
4152 (window_info[id].bounds.y1 <= window_info[i].bounds.y1) ||
4153 (window_info[id].bounds.y1 >= window_info[i].bounds.y2))
4156 Eliminate windows not circumscribed by their parent.
4162 if ((status == True) && (number_children != 0))
4164 for (i=0; i < (int) number_children; i++)
4165 (void) XGetWindowImage(display,children[i],MagickFalse,level+1,
4167 (void) XFree((void *) children);
4208 Get X image for each window in the list.
4210 image=NewImageList();
4211 for (id=0; id < number_windows; id++)
4214 Does target window intersect top level window?
4217 ((window_info[id].bounds.x2 >= window_info[0].bounds.x1) &&
4218 (window_info[id].bounds.x1 <= window_info[0].bounds.x2) &&
4219 (window_info[id].bounds.y2 >= window_info[0].bounds.y1) &&
4220 (window_info[id].bounds.y1 <= window_info[0].bounds.y2)) ?
4221 MagickTrue : MagickFalse;
4223 Is target window contained by another window with the same colormap?
4225 for (j=0; j < id; j++)
4226 if ((window_info[id].visual == window_info[j].visual) &&
4227 (window_info[id].colormap == window_info[j].colormap))
4229 if ((window_info[id].bounds.x1 <= window_info[j].bounds.x1) ||
4230 (window_info[id].bounds.x1 >= window_info[j].bounds.x2) ||
4231 (window_info[id].bounds.y1 <= window_info[j].bounds.y1) ||
4232 (window_info[id].bounds.y1 >= window_info[j].bounds.y2))
4236 if ((window_info[id].visual != window_info[j].visual) ||
4237 (window_info[id].colormap != window_info[j].colormap))
4239 if ((window_info[id].bounds.x2 > window_info[j].bounds.x1) &&
4240 (window_info[id].bounds.x1 < window_info[j].bounds.x2) &&
4241 (window_info[id].bounds.y2 > window_info[j].bounds.y1) &&
4242 (window_info[id].bounds.y1 < window_info[j].bounds.y2))
4245 if (import == MagickFalse)
4250 ximage=XGetImage(display,window_info[id].window,(int)
4251 window_info[id].crop_info.x,(int) window_info[id].crop_info.y,
4252 (unsigned int) window_info[id].crop_info.width,(unsigned int)
4253 window_info[id].crop_info.height,AllPlanes,ZPixmap);
4254 if (ximage == (XImage *) NULL)
4257 Initialize window colormap.
4260 colors=(XColor *) NULL;
4261 if (window_info[id].colormap != (Colormap) NULL)
4267 Search colormap list for window colormap.
4269 number_colors=(unsigned int) window_info[id].visual->map_entries;
4270 for (p=colormap_info; p != (ColormapInfo *) NULL; p=p->next)
4271 if (p->colormap == window_info[id].colormap)
4273 if (p == (ColormapInfo *) NULL)
4276 Get the window colormap.
4278 colors=(XColor *) AcquireQuantumMemory(number_colors,
4280 if (colors == (XColor *) NULL)
4282 XDestroyImage(ximage);
4283 return((Image *) NULL);
4285 if ((window_info[id].visual->klass != DirectColor) &&
4286 (window_info[id].visual->klass != TrueColor))
4287 for (i=0; i < (int) number_colors; i++)
4289 colors[i].pixel=(size_t) i;
4303 DirectColor or TrueColor visual.
4308 red_bit=window_info[id].visual->red_mask &
4309 (~(window_info[id].visual->red_mask)+1);
4310 green_bit=window_info[id].visual->green_mask &
4311 (~(window_info[id].visual->green_mask)+1);
4312 blue_bit=window_info[id].visual->blue_mask &
4313 (~(window_info[id].visual->blue_mask)+1);
4314 for (i=0; i < (int) number_colors; i++)
4316 colors[i].pixel=(unsigned long) (red | green | blue);
4319 if (red > window_info[id].visual->red_mask)
4322 if (green > window_info[id].visual->green_mask)
4325 if (blue > window_info[id].visual->blue_mask)
4329 (void) XQueryColors(display,window_info[id].colormap,colors,
4330 (int) number_colors);
4332 Append colormap to colormap list.
4334 p=(ColormapInfo *) AcquireMagickMemory(sizeof(*p));
4335 if (p == (ColormapInfo *) NULL)
4336 return((Image *) NULL);
4337 p->colormap=window_info[id].colormap;
4339 p->next=colormap_info;
4345 Allocate image structure.
4347 composite_image=AcquireImage((ImageInfo *) NULL,exception);
4348 if (composite_image == (Image *) NULL)
4350 XDestroyImage(ximage);
4351 return((Image *) NULL);
4354 Convert X image to MIFF format.
4356 if ((window_info[id].visual->klass != TrueColor) &&
4357 (window_info[id].visual->klass != DirectColor))
4358 composite_image->storage_class=PseudoClass;
4359 composite_image->columns=(size_t) ximage->width;
4360 composite_image->rows=(size_t) ximage->height;
4361 composite_view=AcquireCacheView(composite_image);
4362 switch (composite_image->storage_class)
4380 Determine shift and mask for red, green, and blue.
4382 red_mask=window_info[id].visual->red_mask;
4384 while ((red_mask != 0) && ((red_mask & 0x01) == 0))
4389 green_mask=window_info[id].visual->green_mask;
4391 while ((green_mask != 0) && ((green_mask & 0x01) == 0))
4396 blue_mask=window_info[id].visual->blue_mask;
4398 while ((blue_mask != 0) && ((blue_mask & 0x01) == 0))
4404 Convert X image to DirectClass packets.
4406 if ((number_colors != 0) &&
4407 (window_info[id].visual->klass == DirectColor))
4408 for (y=0; y < (int) composite_image->rows; y++)
4410 q=QueueCacheViewAuthenticPixels(composite_view,0,(ssize_t) y,
4411 composite_image->columns,1,exception);
4412 if (q == (Quantum *) NULL)
4414 for (x=0; x < (int) composite_image->columns; x++)
4416 pixel=XGetPixel(ximage,x,y);
4417 index=(pixel >> red_shift) & red_mask;
4418 SetPixelRed(composite_image,
4419 ScaleShortToQuantum(colors[index].red),q);
4420 index=(pixel >> green_shift) & green_mask;
4421 SetPixelGreen(composite_image,
4422 ScaleShortToQuantum(colors[index].green),q);
4423 index=(pixel >> blue_shift) & blue_mask;
4424 SetPixelBlue(composite_image,
4425 ScaleShortToQuantum(colors[index].blue),q);
4426 q+=GetPixelChannels(composite_image);
4428 status=SyncCacheViewAuthenticPixels(composite_view,exception);
4429 if (status == MagickFalse)
4433 for (y=0; y < (int) composite_image->rows; y++)
4435 q=QueueCacheViewAuthenticPixels(composite_view,0,(ssize_t) y,
4436 composite_image->columns,1,exception);
4437 if (q == (Quantum *) NULL)
4439 for (x=0; x < (int) composite_image->columns; x++)
4441 pixel=XGetPixel(ximage,x,y);
4442 color=(pixel >> red_shift) & red_mask;
4443 color=(65535UL*color)/red_mask;
4444 SetPixelRed(composite_image,
4445 ScaleShortToQuantum((unsigned short) color),q);
4446 color=(pixel >> green_shift) & green_mask;
4447 color=(65535UL*color)/green_mask;
4448 SetPixelGreen(composite_image,
4449 ScaleShortToQuantum((unsigned short) color),q);
4450 color=(pixel >> blue_shift) & blue_mask;
4451 color=(65535UL*color)/blue_mask;
4452 SetPixelBlue(composite_image,
4453 ScaleShortToQuantum((unsigned short) color),q);
4454 q+=GetPixelChannels(composite_image);
4456 status=SyncCacheViewAuthenticPixels(composite_view,exception);
4457 if (status == MagickFalse)
4467 status=AcquireImageColormap(composite_image,number_colors,
4469 if (status == MagickFalse)
4471 XDestroyImage(ximage);
4472 composite_image=DestroyImage(composite_image);
4473 return((Image *) NULL);
4475 for (i=0; i < (int) composite_image->colors; i++)
4477 composite_image->colormap[colors[i].pixel].red=(double)
4478 ScaleShortToQuantum(colors[i].red);
4479 composite_image->colormap[colors[i].pixel].green=(double)
4480 ScaleShortToQuantum(colors[i].green);
4481 composite_image->colormap[colors[i].pixel].blue=(double)
4482 ScaleShortToQuantum(colors[i].blue);
4485 Convert X image to PseudoClass packets.
4487 for (y=0; y < (int) composite_image->rows; y++)
4489 q=QueueCacheViewAuthenticPixels(composite_view,0,(ssize_t) y,
4490 composite_image->columns,1,exception);
4491 if (q == (Quantum *) NULL)
4493 for (x=0; x < (int) composite_image->columns; x++)
4495 index=(Quantum) XGetPixel(ximage,x,y);
4496 SetPixelIndex(composite_image,index,q);
4497 SetPixelInfoPixel(composite_image,
4498 composite_image->colormap+(ssize_t) index,q);
4499 q+=GetPixelChannels(composite_image);
4501 status=SyncCacheViewAuthenticPixels(composite_view,exception);
4502 if (status == MagickFalse)
4508 composite_view=DestroyCacheView(composite_view);
4509 XDestroyImage(ximage);
4510 if (image == (Image *) NULL)
4512 image=composite_image;
4516 Composite any children in back-to-front order.
4518 (void) XTranslateCoordinates(display,window_info[id].window,window,0,0,
4519 &x_offset,&y_offset,&child);
4520 x_offset-=(int) crop_info.x;
4523 y_offset-=(int) crop_info.y;
4526 (void) CompositeImage(image,composite_image,CopyCompositeOp,MagickFalse,
4527 (ssize_t) x_offset,(ssize_t) y_offset,exception);
4528 composite_image=DestroyImage(composite_image);
4531 Relinquish resources.
4533 while (colormap_info != (ColormapInfo *) NULL)
4535 next=colormap_info->next;
4536 colormap_info->colors=(XColor *) RelinquishMagickMemory(
4537 colormap_info->colors);
4538 colormap_info=(ColormapInfo *) RelinquishMagickMemory(colormap_info);
4542 Relinquish resources and restore initial state.
4544 window_info=(WindowInfo *) RelinquishMagickMemory(window_info);
4547 colormap_info=(ColormapInfo *) NULL;
4550 return((Image *) NULL);
4554 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4558 % X G e t W i n d o w I n f o %
4562 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4564 % XGetWindowInfo() initializes the XWindowInfo structure.
4566 % The format of the XGetWindowInfo method is:
4568 % void XGetWindowInfo(Display *display,XVisualInfo *visual_info,
4569 % XStandardColormap *map_info,XPixelInfo *pixel,XFontStruct *font_info,
4570 % XResourceInfo *resource_info,XWindowInfo *window)
4571 % resource_info,window)
4573 % A description of each parameter follows:
4575 % o display: Specifies a connection to an X server; returned from
4578 % o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
4579 % returned from XGetVisualInfo.
4581 % o map_info: If map_type is specified, this structure is initialized
4582 % with info from the Standard Colormap.
4584 % o pixel: Specifies a pointer to a XPixelInfo structure.
4586 % o font_info: Specifies a pointer to a XFontStruct structure.
4588 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
4591 MagickPrivate void XGetWindowInfo(Display *display,XVisualInfo *visual_info,
4592 XStandardColormap *map_info,XPixelInfo *pixel,XFontStruct *font_info,
4593 XResourceInfo *resource_info,XWindowInfo *window)
4596 Initialize window info.
4598 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
4599 assert(display != (Display *) NULL);
4600 assert(visual_info != (XVisualInfo *) NULL);
4601 assert(map_info != (XStandardColormap *) NULL);
4602 assert(pixel != (XPixelInfo *) NULL);
4603 assert(resource_info != (XResourceInfo *) NULL);
4604 assert(window != (XWindowInfo *) NULL);
4605 if (window->id != (Window) NULL)
4607 if (window->cursor != (Cursor) NULL)
4608 (void) XFreeCursor(display,window->cursor);
4609 if (window->busy_cursor != (Cursor) NULL)
4610 (void) XFreeCursor(display,window->busy_cursor);
4611 if (window->highlight_stipple != (Pixmap) NULL)
4612 (void) XFreePixmap(display,window->highlight_stipple);
4613 if (window->shadow_stipple != (Pixmap) NULL)
4614 (void) XFreePixmap(display,window->shadow_stipple);
4615 if (window->name == (char *) NULL)
4616 window->name=AcquireString("");
4617 if (window->icon_name == (char *) NULL)
4618 window->icon_name=AcquireString("");
4623 Initialize these attributes just once.
4625 window->id=(Window) NULL;
4626 if (window->name == (char *) NULL)
4627 window->name=AcquireString("");
4628 if (window->icon_name == (char *) NULL)
4629 window->icon_name=AcquireString("");
4630 window->x=XDisplayWidth(display,visual_info->screen) >> 1;
4631 window->y=XDisplayWidth(display,visual_info->screen) >> 1;
4632 window->ximage=(XImage *) NULL;
4633 window->matte_image=(XImage *) NULL;
4634 window->pixmap=(Pixmap) NULL;
4635 window->matte_pixmap=(Pixmap) NULL;
4636 window->mapped=MagickFalse;
4637 window->stasis=MagickFalse;
4638 window->shared_memory=MagickTrue;
4639 window->segment_info=(void *) NULL;
4640 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
4645 if (window->segment_info == (void *) NULL)
4646 window->segment_info=AcquireQuantumMemory(2,sizeof(*segment_info));
4647 segment_info=(XShmSegmentInfo *) window->segment_info;
4648 segment_info[0].shmid=(-1);
4649 segment_info[0].shmaddr=(char *) NULL;
4650 segment_info[1].shmid=(-1);
4651 segment_info[1].shmaddr=(char *) NULL;
4656 Initialize these attributes every time function is called.
4658 window->screen=visual_info->screen;
4659 window->root=XRootWindow(display,visual_info->screen);
4660 window->visual=visual_info->visual;
4661 window->storage_class=(unsigned int) visual_info->klass;
4662 window->depth=(unsigned int) visual_info->depth;
4663 window->visual_info=visual_info;
4664 window->map_info=map_info;
4665 window->pixel_info=pixel;
4666 window->font_info=font_info;
4667 window->cursor=XCreateFontCursor(display,XC_left_ptr);
4668 window->busy_cursor=XCreateFontCursor(display,XC_watch);
4669 window->geometry=(char *) NULL;
4670 window->icon_geometry=(char *) NULL;
4671 if (resource_info->icon_geometry != (char *) NULL)
4672 (void) CloneString(&window->icon_geometry,resource_info->icon_geometry);
4673 window->crop_geometry=(char *) NULL;
4674 window->flags=(size_t) PSize;
4677 window->min_width=1;
4678 window->min_height=1;
4679 window->width_inc=1;
4680 window->height_inc=1;
4681 window->border_width=resource_info->border_width;
4682 window->annotate_context=pixel->annotate_context;
4683 window->highlight_context=pixel->highlight_context;
4684 window->widget_context=pixel->widget_context;
4685 window->shadow_stipple=(Pixmap) NULL;
4686 window->highlight_stipple=(Pixmap) NULL;
4687 window->use_pixmap=MagickTrue;
4688 window->immutable=MagickFalse;
4689 window->shape=MagickFalse;
4691 window->mask=(int) (CWBackingStore | CWBackPixel | CWBackPixmap |
4692 CWBitGravity | CWBorderPixel | CWColormap | CWCursor | CWDontPropagate |
4693 CWEventMask | CWOverrideRedirect | CWSaveUnder | CWWinGravity);
4694 window->attributes.background_pixel=pixel->background_color.pixel;
4695 window->attributes.background_pixmap=(Pixmap) NULL;
4696 window->attributes.bit_gravity=ForgetGravity;
4697 window->attributes.backing_store=WhenMapped;
4698 window->attributes.save_under=MagickTrue;
4699 window->attributes.border_pixel=pixel->border_color.pixel;
4700 window->attributes.colormap=map_info->colormap;
4701 window->attributes.cursor=window->cursor;
4702 window->attributes.do_not_propagate_mask=NoEventMask;
4703 window->attributes.event_mask=NoEventMask;
4704 window->attributes.override_redirect=MagickFalse;
4705 window->attributes.win_gravity=NorthWestGravity;
4706 window->orphan=MagickFalse;
4710 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4714 % X H i g h l i g h t E l l i p s e %
4718 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4720 % XHighlightEllipse() puts a border on the X server around a region defined by
4723 % The format of the XHighlightEllipse method is:
4725 % void XHighlightEllipse(Display *display,Window window,
4726 % GC annotate_context,const RectangleInfo *highlight_info)
4728 % A description of each parameter follows:
4730 % o display: Specifies a connection to an X server; returned from
4733 % o window: Specifies a pointer to a Window structure.
4735 % o annotate_context: Specifies a pointer to a GC structure.
4737 % o highlight_info: Specifies a pointer to a RectangleInfo structure. It
4738 % contains the extents of any highlighting rectangle.
4741 MagickPrivate void XHighlightEllipse(Display *display,Window window,
4742 GC annotate_context,const RectangleInfo *highlight_info)
4744 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
4745 assert(display != (Display *) NULL);
4746 assert(window != (Window) NULL);
4747 assert(annotate_context != (GC) NULL);
4748 assert(highlight_info != (RectangleInfo *) NULL);
4749 if ((highlight_info->width < 4) || (highlight_info->height < 4))
4751 (void) XDrawArc(display,window,annotate_context,(int) highlight_info->x,
4752 (int) highlight_info->y,(unsigned int) highlight_info->width-1,
4753 (unsigned int) highlight_info->height-1,0,360*64);
4754 (void) XDrawArc(display,window,annotate_context,(int) highlight_info->x+1,
4755 (int) highlight_info->y+1,(unsigned int) highlight_info->width-3,
4756 (unsigned int) highlight_info->height-3,0,360*64);
4760 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4764 % X H i g h l i g h t L i n e %
4768 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4770 % XHighlightLine() puts a border on the X server around a region defined by
4773 % The format of the XHighlightLine method is:
4775 % void XHighlightLine(Display *display,Window window,GC annotate_context,
4776 % const XSegment *highlight_info)
4778 % A description of each parameter follows:
4780 % o display: Specifies a connection to an X server; returned from
4783 % o window: Specifies a pointer to a Window structure.
4785 % o annotate_context: Specifies a pointer to a GC structure.
4787 % o highlight_info: Specifies a pointer to a RectangleInfo structure. It
4788 % contains the extents of any highlighting rectangle.
4791 MagickPrivate void XHighlightLine(Display *display,Window window,
4792 GC annotate_context,const XSegment *highlight_info)
4794 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
4795 assert(display != (Display *) NULL);
4796 assert(window != (Window) NULL);
4797 assert(annotate_context != (GC) NULL);
4798 assert(highlight_info != (XSegment *) NULL);
4799 (void) XDrawLine(display,window,annotate_context,highlight_info->x1,
4800 highlight_info->y1,highlight_info->x2,highlight_info->y2);
4804 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4808 % X H i g h l i g h t R e c t a n g l e %
4812 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4814 % XHighlightRectangle() puts a border on the X server around a region defined
4815 % by highlight_info.
4817 % The format of the XHighlightRectangle method is:
4819 % void XHighlightRectangle(Display *display,Window window,
4820 % GC annotate_context,const RectangleInfo *highlight_info)
4822 % A description of each parameter follows:
4824 % o display: Specifies a connection to an X server; returned from
4827 % o window: Specifies a pointer to a Window structure.
4829 % o annotate_context: Specifies a pointer to a GC structure.
4831 % o highlight_info: Specifies a pointer to a RectangleInfo structure. It
4832 % contains the extents of any highlighting rectangle.
4835 MagickPrivate void XHighlightRectangle(Display *display,Window window,
4836 GC annotate_context,const RectangleInfo *highlight_info)
4838 assert(display != (Display *) NULL);
4839 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
4840 assert(window != (Window) NULL);
4841 assert(annotate_context != (GC) NULL);
4842 assert(highlight_info != (RectangleInfo *) NULL);
4843 if ((highlight_info->width < 4) || (highlight_info->height < 4))
4845 (void) XDrawRectangle(display,window,annotate_context,(int) highlight_info->x,
4846 (int) highlight_info->y,(unsigned int) highlight_info->width-1,
4847 (unsigned int) highlight_info->height-1);
4848 (void) XDrawRectangle(display,window,annotate_context,(int) highlight_info->x+
4849 1,(int) highlight_info->y+1,(unsigned int) highlight_info->width-3,
4850 (unsigned int) highlight_info->height-3);
4854 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4858 % X I m p o r t I m a g e %
4862 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4864 % XImportImage() reads an image from an X window.
4866 % The format of the XImportImage method is:
4868 % Image *XImportImage(const ImageInfo *image_info,XImportInfo *ximage_info,
4869 % ExceptionInfo *exception)
4871 % A description of each parameter follows:
4873 % o image_info: the image info.
4875 % o ximage_info: Specifies a pointer to an XImportInfo structure.
4877 % o exception: return any errors or warnings in this structure.
4880 MagickExport Image *XImportImage(const ImageInfo *image_info,
4881 XImportInfo *ximage_info,ExceptionInfo *exception)
4914 Open X server connection.
4916 assert(image_info != (const ImageInfo *) NULL);
4917 assert(image_info->signature == MagickSignature);
4918 if (image_info->debug != MagickFalse)
4919 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
4920 image_info->filename);
4921 assert(ximage_info != (XImportInfo *) NULL);
4922 display=XOpenDisplay(image_info->server_name);
4923 if (display == (Display *) NULL)
4925 ThrowXWindowFatalException(XServerError,"UnableToOpenXServer",
4926 XDisplayName(image_info->server_name));
4927 return((Image *) NULL);
4930 Set our forgiving exception handler.
4932 (void) XSetErrorHandler(XError);
4934 Select target window.
4940 root=XRootWindow(display,XDefaultScreen(display));
4941 target=(Window) NULL;
4942 if ((image_info->filename != (char *) NULL) &&
4943 (*image_info->filename != '\0'))
4945 if (LocaleCompare(image_info->filename,"root") == 0)
4950 Select window by ID or name.
4952 if (isdigit((unsigned char) *image_info->filename) != 0)
4953 target=XWindowByID(display,root,(Window)
4954 strtol(image_info->filename,(char **) NULL,0));
4955 if (target == (Window) NULL)
4956 target=XWindowByName(display,root,image_info->filename);
4957 if (target == (Window) NULL)
4958 ThrowXWindowFatalException(XServerError,
4959 "NoWindowWithSpecifiedIDExists",image_info->filename);
4963 If target window is not defined, interactively select one.
4965 prior_target=target;
4966 if (target == (Window) NULL)
4967 target=XSelectWindow(display,&crop_info);
4968 if (target == (Window) NULL)
4969 ThrowXWindowFatalException(XServerError,"UnableToReadXWindowImage",
4970 image_info->filename);
4971 client=target; /* obsolete */
4977 status=XGetGeometry(display,target,&root,&x,&x,&d,&d,&d,&d);
4978 if (status != False)
4986 Find window manager frame.
4988 status=XQueryTree(display,target,&root,&parent,&children,&d);
4989 if ((status != False) && (children != (Window *) NULL))
4990 (void) XFree((char *) children);
4991 if ((status == False) || (parent == (Window) NULL) ||
4999 client=XClientWindow(display,target);
5000 if (ximage_info->frame == MagickFalse)
5002 if ((ximage_info->frame == MagickFalse) &&
5003 (prior_target != MagickFalse))
5004 target=prior_target;
5007 if (ximage_info->screen)
5019 Obtain window image directly from screen.
5021 status=XGetWindowAttributes(display,target,&window_attributes);
5022 if (status == False)
5024 ThrowXWindowFatalException(XServerError,
5025 "UnableToReadXWindowAttributes",image_info->filename);
5026 (void) XCloseDisplay(display);
5027 return((Image *) NULL);
5029 (void) XTranslateCoordinates(display,target,root,0,0,&x,&y,&child);
5030 crop_info.x=(ssize_t) x;
5031 crop_info.y=(ssize_t) y;
5032 crop_info.width=(size_t) window_attributes.width;
5033 crop_info.height=(size_t) window_attributes.height;
5034 if (ximage_info->borders != 0)
5037 Include border in image.
5039 crop_info.x-=window_attributes.border_width;
5040 crop_info.y-=window_attributes.border_width;
5041 crop_info.width+=window_attributes.border_width << 1;
5042 crop_info.height+=window_attributes.border_width << 1;
5047 If WM_COLORMAP_WINDOWS property is set or multiple colormaps, descend.
5050 status=XGetWMColormapWindows(display,target,&children,&number_windows);
5051 if ((status == True) && (number_windows > 0))
5053 ximage_info->descend=MagickTrue;
5054 (void) XFree ((char *) children);
5056 colormaps=XListInstalledColormaps(display,target,&number_colormaps);
5057 if (number_colormaps > 0)
5059 if (number_colormaps > 1)
5060 ximage_info->descend=MagickTrue;
5061 (void) XFree((char *) colormaps);
5064 Alert the user not to alter the screen.
5066 if (ximage_info->silent == MagickFalse)
5067 (void) XBell(display,0);
5069 Get image by window id.
5071 (void) XGrabServer(display);
5072 image=XGetWindowImage(display,target,ximage_info->borders,
5073 ximage_info->descend ? 1U : 0U,exception);
5074 (void) XUngrabServer(display);
5075 if (image == (Image *) NULL)
5076 ThrowXWindowFatalException(XServerError,"UnableToReadXWindowImage",
5077 image_info->filename)
5080 (void) CopyMagickString(image->filename,image_info->filename,
5082 if ((crop_info.width != 0) && (crop_info.height != 0))
5089 Crop image as defined by the cropping rectangle.
5091 clone_image=CloneImage(image,0,0,MagickTrue,exception);
5092 if (clone_image != (Image *) NULL)
5094 crop_image=CropImage(clone_image,&crop_info,exception);
5095 if (crop_image != (Image *) NULL)
5097 image=DestroyImage(image);
5102 status=XGetWMName(display,target,&window_name);
5105 if ((image_info->filename != (char *) NULL) &&
5106 (*image_info->filename == '\0'))
5107 (void) CopyMagickString(image->filename,(char *) window_name.value,
5108 (size_t) window_name.nitems+1);
5109 (void) XFree((void *) window_name.value);
5112 if (ximage_info->silent == MagickFalse)
5115 Alert the user we're done.
5117 (void) XBell(display,0);
5118 (void) XBell(display,0);
5120 (void) XCloseDisplay(display);
5125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5129 % X I n i t i a l i z e W i n d o w s %
5133 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5135 % XInitializeWindows() initializes the XWindows structure.
5137 % The format of the XInitializeWindows method is:
5139 % XWindows *XInitializeWindows(Display *display,
5140 % XResourceInfo *resource_info)
5142 % A description of each parameter follows:
5144 % o windows: XInitializeWindows returns a pointer to a XWindows structure.
5146 % o display: Specifies a connection to an X server; returned from
5149 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
5152 MagickPrivate XWindows *XInitializeWindows(Display *display,
5153 XResourceInfo *resource_info)
5162 Allocate windows structure.
5164 windows=(XWindows *) AcquireMagickMemory(sizeof(*windows));
5165 if (windows == (XWindows *) NULL)
5167 ThrowXWindowFatalException(XServerFatalError,"MemoryAllocationFailed",
5169 return((XWindows *) NULL);
5171 (void) ResetMagickMemory(windows,0,sizeof(*windows));
5172 windows->pixel_info=(XPixelInfo *) AcquireMagickMemory(
5173 sizeof(*windows->pixel_info));
5174 windows->icon_pixel=(XPixelInfo *) AcquireMagickMemory(
5175 sizeof(*windows->icon_pixel));
5176 windows->icon_resources=(XResourceInfo *) AcquireMagickMemory(
5177 sizeof(*windows->icon_resources));
5178 if ((windows->pixel_info == (XPixelInfo *) NULL) ||
5179 (windows->icon_pixel == (XPixelInfo *) NULL) ||
5180 (windows->icon_resources == (XResourceInfo *) NULL))
5182 ThrowXWindowFatalException(XServerFatalError,"MemoryAllocationFailed",
5184 return((XWindows *) NULL);
5187 Initialize windows structure.
5189 windows->display=display;
5190 windows->wm_protocols=XInternAtom(display,"WM_PROTOCOLS",MagickFalse);
5191 windows->wm_delete_window=XInternAtom(display,"WM_DELETE_WINDOW",MagickFalse);
5192 windows->wm_take_focus=XInternAtom(display,"WM_TAKE_FOCUS",MagickFalse);
5193 windows->im_protocols=XInternAtom(display,"IM_PROTOCOLS",MagickFalse);
5194 windows->im_remote_command=
5195 XInternAtom(display,"IM_REMOTE_COMMAND",MagickFalse);
5196 windows->im_update_widget=XInternAtom(display,"IM_UPDATE_WIDGET",MagickFalse);
5197 windows->im_update_colormap=
5198 XInternAtom(display,"IM_UPDATE_COLORMAP",MagickFalse);
5199 windows->im_former_image=XInternAtom(display,"IM_FORMER_IMAGE",MagickFalse);
5200 windows->im_next_image=XInternAtom(display,"IM_NEXT_IMAGE",MagickFalse);
5201 windows->im_retain_colors=XInternAtom(display,"IM_RETAIN_COLORS",MagickFalse);
5202 windows->im_exit=XInternAtom(display,"IM_EXIT",MagickFalse);
5203 windows->dnd_protocols=XInternAtom(display,"DndProtocol",MagickFalse);
5204 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
5205 (void) XSynchronize(display,IsWindows95());
5207 if (IsEventLogging())
5209 (void) XSynchronize(display,MagickTrue);
5210 (void) LogMagickEvent(X11Event,GetMagickModule(),"Version: %s",
5211 GetMagickVersion((size_t *) NULL));
5212 (void) LogMagickEvent(X11Event,GetMagickModule(),"Protocols:");
5213 (void) LogMagickEvent(X11Event,GetMagickModule(),
5214 " Window Manager: 0x%lx",windows->wm_protocols);
5215 (void) LogMagickEvent(X11Event,GetMagickModule(),
5216 " delete window: 0x%lx",windows->wm_delete_window);
5217 (void) LogMagickEvent(X11Event,GetMagickModule()," take focus: 0x%lx",
5218 windows->wm_take_focus);
5219 (void) LogMagickEvent(X11Event,GetMagickModule()," ImageMagick: 0x%lx",
5220 windows->im_protocols);
5221 (void) LogMagickEvent(X11Event,GetMagickModule(),
5222 " remote command: 0x%lx",windows->im_remote_command);
5223 (void) LogMagickEvent(X11Event,GetMagickModule(),
5224 " update widget: 0x%lx",windows->im_update_widget);
5225 (void) LogMagickEvent(X11Event,GetMagickModule(),
5226 " update colormap: 0x%lx",windows->im_update_colormap);
5227 (void) LogMagickEvent(X11Event,GetMagickModule(),
5228 " former image: 0x%lx",windows->im_former_image);
5229 (void) LogMagickEvent(X11Event,GetMagickModule()," next image: 0x%lx",
5230 windows->im_next_image);
5231 (void) LogMagickEvent(X11Event,GetMagickModule(),
5232 " retain colors: 0x%lx",windows->im_retain_colors);
5233 (void) LogMagickEvent(X11Event,GetMagickModule()," exit: 0x%lx",
5235 (void) LogMagickEvent(X11Event,GetMagickModule()," Drag and Drop: 0x%lx",
5236 windows->dnd_protocols);
5239 Allocate standard colormap.
5241 windows->map_info=XAllocStandardColormap();
5242 windows->icon_map=XAllocStandardColormap();
5243 if ((windows->map_info == (XStandardColormap *) NULL) ||
5244 (windows->icon_map == (XStandardColormap *) NULL))
5245 ThrowXWindowFatalException(ResourceLimitFatalError,
5246 "MemoryAllocationFailed","...");
5247 windows->map_info->colormap=(Colormap) NULL;
5248 windows->icon_map->colormap=(Colormap) NULL;
5249 windows->pixel_info->pixels=(unsigned long *) NULL;
5250 windows->pixel_info->annotate_context=(GC) NULL;
5251 windows->pixel_info->highlight_context=(GC) NULL;
5252 windows->pixel_info->widget_context=(GC) NULL;
5253 windows->font_info=(XFontStruct *) NULL;
5254 windows->icon_pixel->annotate_context=(GC) NULL;
5255 windows->icon_pixel->pixels=(unsigned long *) NULL;
5259 *windows->icon_resources=(*resource_info);
5260 windows->icon_resources->visual_type=(char *) "default";
5261 windows->icon_resources->colormap=SharedColormap;
5262 windows->visual_info=
5263 XBestVisualInfo(display,windows->map_info,resource_info);
5264 windows->icon_visual=
5265 XBestVisualInfo(display,windows->icon_map,windows->icon_resources);
5266 if ((windows->visual_info == (XVisualInfo *) NULL) ||
5267 (windows->icon_visual == (XVisualInfo *) NULL))
5268 ThrowXWindowFatalException(XServerFatalError,"UnableToGetVisual",
5269 resource_info->visual_type);
5270 if (IsEventLogging())
5272 (void) LogMagickEvent(X11Event,GetMagickModule(),"Visual:");
5273 (void) LogMagickEvent(X11Event,GetMagickModule()," visual id: 0x%lx",
5274 windows->visual_info->visualid);
5275 (void) LogMagickEvent(X11Event,GetMagickModule()," class: %s",
5276 XVisualClassName(windows->visual_info->klass));
5277 (void) LogMagickEvent(X11Event,GetMagickModule()," depth: %d planes",
5278 windows->visual_info->depth);
5279 (void) LogMagickEvent(X11Event,GetMagickModule(),
5280 " size of colormap: %d entries",windows->visual_info->colormap_size);
5281 (void) LogMagickEvent(X11Event,GetMagickModule(),
5282 " red, green, blue masks: 0x%lx 0x%lx 0x%lx",
5283 windows->visual_info->red_mask,windows->visual_info->green_mask,
5284 windows->visual_info->blue_mask);
5285 (void) LogMagickEvent(X11Event,GetMagickModule(),
5286 " significant bits in color: %d bits",
5287 windows->visual_info->bits_per_rgb);
5290 Allocate class and manager hints.
5292 windows->class_hints=XAllocClassHint();
5293 windows->manager_hints=XAllocWMHints();
5294 if ((windows->class_hints == (XClassHint *) NULL) ||
5295 (windows->manager_hints == (XWMHints *) NULL))
5296 ThrowXWindowFatalException(ResourceLimitFatalError,
5297 "MemoryAllocationFailed","...");
5299 Determine group leader if we have one.
5301 root_window=XRootWindow(display,windows->visual_info->screen);
5302 windows->group_leader.id=(Window) NULL;
5303 if (resource_info->window_group != (char *) NULL)
5305 if (isdigit((unsigned char) *resource_info->window_group) != 0)
5306 windows->group_leader.id=XWindowByID(display,root_window,(Window)
5307 strtol((char *) resource_info->window_group,(char **) NULL,0));
5308 if (windows->group_leader.id == (Window) NULL)
5309 windows->group_leader.id=
5310 XWindowByName(display,root_window,resource_info->window_group);
5316 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5320 % X M a k e C u r s o r %
5324 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5326 % XMakeCursor() creates a crosshairs X11 cursor.
5328 % The format of the XMakeCursor method is:
5330 % Cursor XMakeCursor(Display *display,Window window,Colormap colormap,
5331 % char *background_color,char *foreground_color)
5333 % A description of each parameter follows:
5335 % o display: Specifies a connection to an X server; returned from
5338 % o window: Specifies the ID of the window for which the cursor is
5341 % o colormap: Specifies the ID of the colormap from which the background
5342 % and foreground color will be retrieved.
5344 % o background_color: Specifies the color to use for the cursor background.
5346 % o foreground_color: Specifies the color to use for the cursor foreground.
5349 MagickPrivate Cursor XMakeCursor(Display *display,Window window,
5350 Colormap colormap,char *background_color,char *foreground_color)
5352 #define scope_height 17
5353 #define scope_x_hot 8
5354 #define scope_y_hot 8
5355 #define scope_width 17
5357 static const unsigned char
5360 0x80, 0x03, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02,
5361 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x7f,
5362 0xfc, 0x01, 0x01, 0x00, 0x01, 0x7f, 0xfc, 0x01, 0x80, 0x02, 0x00,
5363 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02,
5364 0x00, 0x80, 0x02, 0x00, 0x80, 0x03, 0x00
5368 0xc0, 0x07, 0x00, 0xc0, 0x07, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06,
5369 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xff, 0xfe, 0x01, 0x7f,
5370 0xfc, 0x01, 0x03, 0x80, 0x01, 0x7f, 0xfc, 0x01, 0xff, 0xfe, 0x01,
5371 0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06,
5372 0x00, 0xc0, 0x07, 0x00, 0xc0, 0x07, 0x00
5386 assert(display != (Display *) NULL);
5387 assert(window != (Window) NULL);
5388 assert(colormap != (Colormap) NULL);
5389 assert(background_color != (char *) NULL);
5390 assert(foreground_color != (char *) NULL);
5391 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",background_color);
5392 source=XCreateBitmapFromData(display,window,(char *) scope_bits,scope_width,
5394 mask=XCreateBitmapFromData(display,window,(char *) scope_mask_bits,
5395 scope_width,scope_height);
5396 if ((source == (Pixmap) NULL) || (mask == (Pixmap) NULL))
5398 ThrowXWindowFatalException(XServerError,"UnableToCreatePixmap","...");
5399 return((Cursor) NULL);
5401 (void) XParseColor(display,colormap,background_color,&background);
5402 (void) XParseColor(display,colormap,foreground_color,&foreground);
5403 cursor=XCreatePixmapCursor(display,source,mask,&foreground,&background,
5404 scope_x_hot,scope_y_hot);
5405 (void) XFreePixmap(display,source);
5406 (void) XFreePixmap(display,mask);
5411 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5415 % X M a k e I m a g e %
5419 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5421 % XMakeImage() creates an X11 image. If the image size differs from the X11
5422 % image size, the image is first resized.
5424 % The format of the XMakeImage method is:
5426 % MagickBooleanType XMakeImage(Display *display,
5427 % const XResourceInfo *resource_info,XWindowInfo *window,Image *image,
5428 % unsigned int width,unsigned int height,ExceptionInfo *exception)
5430 % A description of each parameter follows:
5432 % o display: Specifies a connection to an X server; returned from
5435 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
5437 % o window: Specifies a pointer to a XWindowInfo structure.
5439 % o image: the image.
5441 % o width: Specifies the width in pixels of the rectangular area to
5444 % o height: Specifies the height in pixels of the rectangular area to
5447 % o exception: return any errors or warnings in this structure.
5450 MagickPrivate MagickBooleanType XMakeImage(Display *display,
5451 const XResourceInfo *resource_info,XWindowInfo *window,Image *image,
5452 unsigned int width,unsigned int height,ExceptionInfo *exception)
5454 #define CheckOverflowException(length,width,height) \
5455 (((height) != 0) && ((length)/((size_t) height) != ((size_t) width)))
5468 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
5469 assert(display != (Display *) NULL);
5470 assert(resource_info != (XResourceInfo *) NULL);
5471 assert(window != (XWindowInfo *) NULL);
5473 assert(height != 0);
5474 if ((window->width == 0) || (window->height == 0))
5475 return(MagickFalse);
5477 Apply user transforms to the image.
5479 (void) XCheckDefineCursor(display,window->id,window->busy_cursor);
5480 (void) XFlush(display);
5481 depth=(int) window->depth;
5482 if (window->destroy)
5483 window->image=DestroyImage(window->image);
5484 window->image=image;
5485 window->destroy=MagickFalse;
5486 if (window->image != (Image *) NULL)
5488 if (window->crop_geometry != (char *) NULL)
5499 window->image->page.x=0;
5500 window->image->page.y=0;
5501 (void) ParsePageGeometry(window->image,window->crop_geometry,
5502 &crop_info,exception);
5503 crop_image=CropImage(window->image,&crop_info,exception);
5504 if (crop_image != (Image *) NULL)
5506 if (window->image != image)
5507 window->image=DestroyImage(window->image);
5508 window->image=crop_image;
5509 window->destroy=MagickTrue;
5512 if ((width != (unsigned int) window->image->columns) ||
5513 (height != (unsigned int) window->image->rows))
5521 resize_image=NewImageList();
5522 if (window->pixel_info->colors != 0)
5523 resize_image=SampleImage(window->image,width,height,exception);
5525 resize_image=ThumbnailImage(window->image,width,height,exception);
5526 if (resize_image != (Image *) NULL)
5528 if (window->image != image)
5529 window->image=DestroyImage(window->image);
5530 window->image=resize_image;
5531 window->destroy=MagickTrue;
5534 width=(unsigned int) window->image->columns;
5535 assert((size_t) width == window->image->columns);
5536 height=(unsigned int) window->image->rows;
5537 assert((size_t) height == window->image->rows);
5542 ximage=(XImage *) NULL;
5543 format=(depth == 1) ? XYBitmap : ZPixmap;
5544 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
5545 if (window->shared_memory != MagickFalse)
5550 segment_info=(XShmSegmentInfo *) window->segment_info;
5551 segment_info[1].shmid=(-1);
5552 segment_info[1].shmaddr=(char *) NULL;
5553 ximage=XShmCreateImage(display,window->visual,(unsigned int) depth,format,
5554 (char *) NULL,&segment_info[1],width,height);
5555 if (ximage == (XImage *) NULL)
5556 window->shared_memory=MagickFalse;
5557 length=(size_t) ximage->bytes_per_line*ximage->height;
5558 if (CheckOverflowException(length,ximage->bytes_per_line,ximage->height))
5559 window->shared_memory=MagickFalse;
5560 if (window->shared_memory != MagickFalse)
5561 segment_info[1].shmid=shmget(IPC_PRIVATE,length,IPC_CREAT | 0777);
5562 if (window->shared_memory != MagickFalse)
5563 segment_info[1].shmaddr=(char *) shmat(segment_info[1].shmid,0,0);
5564 if (segment_info[1].shmid < 0)
5565 window->shared_memory=MagickFalse;
5566 if (window->shared_memory != MagickFalse)
5567 (void) shmctl(segment_info[1].shmid,IPC_RMID,0);
5570 if (ximage != (XImage *) NULL)
5571 XDestroyImage(ximage);
5572 ximage=(XImage *) NULL;
5573 if (segment_info[1].shmaddr)
5575 (void) shmdt(segment_info[1].shmaddr);
5576 segment_info[1].shmaddr=(char *) NULL;
5578 if (segment_info[1].shmid >= 0)
5580 (void) shmctl(segment_info[1].shmid,IPC_RMID,0);
5581 segment_info[1].shmid=(-1);
5587 Allocate X image pixel data.
5589 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
5590 if (window->shared_memory)
5598 (void) XSync(display,MagickFalse);
5599 xerror_alert=MagickFalse;
5600 segment_info=(XShmSegmentInfo *) window->segment_info;
5601 ximage->data=segment_info[1].shmaddr;
5602 segment_info[1].readOnly=MagickFalse;
5603 status=XShmAttach(display,&segment_info[1]);
5604 if (status != False)
5605 (void) XSync(display,MagickFalse);
5606 if ((status == False) || (xerror_alert != MagickFalse))
5608 window->shared_memory=MagickFalse;
5609 if (status != False)
5610 XShmDetach(display,&segment_info[1]);
5611 if (ximage != (XImage *) NULL)
5614 XDestroyImage(ximage);
5615 ximage=(XImage *) NULL;
5617 if (segment_info[1].shmid >= 0)
5619 if (segment_info[1].shmaddr != NULL)
5620 (void) shmdt(segment_info[1].shmaddr);
5621 (void) shmctl(segment_info[1].shmid,IPC_RMID,0);
5622 segment_info[1].shmid=(-1);
5623 segment_info[1].shmaddr=(char *) NULL;
5628 if (window->shared_memory == MagickFalse)
5629 ximage=XCreateImage(display,window->visual,(unsigned int) depth,format,0,
5630 (char *) NULL,width,height,XBitmapPad(display),0);
5631 if (ximage == (XImage *) NULL)
5634 Unable to create X image.
5636 (void) XCheckDefineCursor(display,window->id,window->cursor);
5637 return(MagickFalse);
5639 length=(size_t) ximage->bytes_per_line*ximage->height;
5640 if (IsEventLogging())
5642 (void) LogMagickEvent(X11Event,GetMagickModule(),"XImage:");
5643 (void) LogMagickEvent(X11Event,GetMagickModule()," width, height: %dx%d",
5644 ximage->width,ximage->height);
5645 (void) LogMagickEvent(X11Event,GetMagickModule()," format: %d",
5647 (void) LogMagickEvent(X11Event,GetMagickModule()," byte order: %d",
5648 ximage->byte_order);
5649 (void) LogMagickEvent(X11Event,GetMagickModule(),
5650 " bitmap unit, bit order, pad: %d %d %d",ximage->bitmap_unit,
5651 ximage->bitmap_bit_order,ximage->bitmap_pad);
5652 (void) LogMagickEvent(X11Event,GetMagickModule()," depth: %d",
5654 (void) LogMagickEvent(X11Event,GetMagickModule()," bytes per line: %d",
5655 ximage->bytes_per_line);
5656 (void) LogMagickEvent(X11Event,GetMagickModule()," bits per pixel: %d",
5657 ximage->bits_per_pixel);
5658 (void) LogMagickEvent(X11Event,GetMagickModule(),
5659 " red, green, blue masks: 0x%lx 0x%lx 0x%lx",ximage->red_mask,
5660 ximage->green_mask,ximage->blue_mask);
5662 if (window->shared_memory == MagickFalse)
5664 if (ximage->format != XYBitmap)
5665 ximage->data=(char *) AcquireQuantumMemory((size_t)
5666 ximage->bytes_per_line,(size_t) ximage->height);
5668 ximage->data=(char *) AcquireQuantumMemory((size_t)
5669 ximage->bytes_per_line*ximage->depth,(size_t) ximage->height);
5671 if (ximage->data == (char *) NULL)
5674 Unable to allocate pixel data.
5676 XDestroyImage(ximage);
5677 ximage=(XImage *) NULL;
5678 (void) XCheckDefineCursor(display,window->id,window->cursor);
5679 return(MagickFalse);
5681 if (window->ximage != (XImage *) NULL)
5684 Destroy previous X image.
5686 length=(size_t) window->ximage->bytes_per_line*window->ximage->height;
5687 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
5688 if (window->segment_info != (XShmSegmentInfo *) NULL)
5693 segment_info=(XShmSegmentInfo *) window->segment_info;
5694 if (segment_info[0].shmid >= 0)
5696 (void) XSync(display,MagickFalse);
5697 (void) XShmDetach(display,&segment_info[0]);
5698 (void) XSync(display,MagickFalse);
5699 if (segment_info[0].shmaddr != (char *) NULL)
5700 (void) shmdt(segment_info[0].shmaddr);
5701 (void) shmctl(segment_info[0].shmid,IPC_RMID,0);
5702 segment_info[0].shmid=(-1);
5703 segment_info[0].shmaddr=(char *) NULL;
5704 window->ximage->data=(char *) NULL;
5708 if (window->ximage->data != (char *) NULL)
5709 free(window->ximage->data);
5710 window->ximage->data=(char *) NULL;
5711 XDestroyImage(window->ximage);
5712 window->ximage=(XImage *) NULL;
5714 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
5715 if (window->segment_info != (XShmSegmentInfo *) NULL)
5720 segment_info=(XShmSegmentInfo *) window->segment_info;
5721 segment_info[0]=segment_info[1];
5724 window->ximage=ximage;
5725 matte_image=(XImage *) NULL;
5726 if ((window->shape != MagickFalse) && (window->image != (Image *) NULL))
5727 if ((window->image->matte != MagickFalse) &&
5728 ((int) width <= XDisplayWidth(display,window->screen)) &&
5729 ((int) height <= XDisplayHeight(display,window->screen)))
5734 matte_image=XCreateImage(display,window->visual,1,XYBitmap,0,
5735 (char *) NULL,width,height,XBitmapPad(display),0);
5736 if (IsEventLogging())
5738 (void) LogMagickEvent(X11Event,GetMagickModule(),"Matte Image:");
5739 (void) LogMagickEvent(X11Event,GetMagickModule(),
5740 " width, height: %dx%d",matte_image->width,matte_image->height);
5742 if (matte_image != (XImage *) NULL)
5745 Allocate matte image pixel data.
5747 matte_image->data=(char *) AcquireQuantumMemory((size_t)
5748 matte_image->bytes_per_line*matte_image->depth,
5749 (size_t) matte_image->height);
5750 if (matte_image->data == (char *) NULL)
5752 XDestroyImage(matte_image);
5753 matte_image=(XImage *) NULL;
5757 if (window->matte_image != (XImage *) NULL)
5762 if (window->matte_image->data != (char *) NULL)
5763 free(window->matte_image->data);
5764 window->matte_image->data=(char *) NULL;
5765 XDestroyImage(window->matte_image);
5766 window->matte_image=(XImage *) NULL;
5768 window->matte_image=matte_image;
5769 if (window->matte_pixmap != (Pixmap) NULL)
5771 (void) XFreePixmap(display,window->matte_pixmap);
5772 window->matte_pixmap=(Pixmap) NULL;
5773 #if defined(MAGICKCORE_HAVE_SHAPE)
5774 if (window->shape != MagickFalse)
5775 XShapeCombineMask(display,window->id,ShapeBounding,0,0,None,ShapeSet);
5778 window->stasis=MagickFalse;
5780 Convert pixels to X image data.
5782 if (window->image != (Image *) NULL)
5784 if ((ximage->byte_order == LSBFirst) || ((ximage->format == XYBitmap) &&
5785 (ximage->bitmap_bit_order == LSBFirst)))
5786 XMakeImageLSBFirst(resource_info,window,window->image,ximage,
5787 matte_image,exception);
5789 XMakeImageMSBFirst(resource_info,window,window->image,ximage,
5790 matte_image,exception);
5792 if (window->matte_image != (XImage *) NULL)
5795 Create matte pixmap.
5797 window->matte_pixmap=XCreatePixmap(display,window->id,width,height,1);
5798 if (window->matte_pixmap != (Pixmap) NULL)
5807 Copy matte image to matte pixmap.
5809 context_values.background=0;
5810 context_values.foreground=1;
5811 graphics_context=XCreateGC(display,window->matte_pixmap,
5812 (size_t) (GCBackground | GCForeground),&context_values);
5813 (void) XPutImage(display,window->matte_pixmap,graphics_context,
5814 window->matte_image,0,0,0,0,width,height);
5815 (void) XFreeGC(display,graphics_context);
5816 #if defined(MAGICKCORE_HAVE_SHAPE)
5817 if (window->shape != MagickFalse)
5818 XShapeCombineMask(display,window->id,ShapeBounding,0,0,
5819 window->matte_pixmap,ShapeSet);
5823 (void) XMakePixmap(display,resource_info,window);
5827 (void) XCheckDefineCursor(display,window->id,window->cursor);
5832 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5836 + X M a k e I m a g e L S B F i r s t %
5840 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5842 % XMakeImageLSBFirst() initializes the pixel data of an X11 Image. The X image
5843 % pixels are copied in least-significant bit and byte first order. The
5844 % server's scanline pad is respected. Rather than using one or two general
5845 % cases, many special cases are found here to help speed up the image
5848 % The format of the XMakeImageLSBFirst method is:
5850 % void XMakeImageLSBFirst(Display *display,XWindows *windows,
5851 % ExceptionInfo *exception)
5853 % A description of each parameter follows:
5855 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
5857 % o window: Specifies a pointer to a XWindowInfo structure.
5859 % o image: the image.
5861 % o ximage: Specifies a pointer to a XImage structure; returned from
5864 % o matte_image: Specifies a pointer to a XImage structure; returned from
5867 % o exception: return any errors or warnings in this structure.
5870 static void XMakeImageLSBFirst(const XResourceInfo *resource_info,
5871 const XWindowInfo *window,Image *image,XImage *ximage,XImage *matte_image,
5872 ExceptionInfo *exception)
5883 register const Quantum
5889 register unsigned char
5906 assert(resource_info != (XResourceInfo *) NULL);
5907 assert(window != (XWindowInfo *) NULL);
5908 assert(image != (Image *) NULL);
5909 if (image->debug != MagickFalse)
5910 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
5912 if ((window->immutable == MagickFalse) &&
5913 (image->storage_class == DirectClass) && (image->matte != MagickFalse))
5916 size[MaxTextExtent];
5924 image_info=AcquireImageInfo();
5925 (void) CopyMagickString(image_info->filename,
5926 resource_info->image_info->texture != (char *) NULL ?
5927 resource_info->image_info->texture : "pattern:checkerboard",
5929 (void) FormatLocaleString(size,MaxTextExtent,"%.20gx%.20g",(double)
5930 image->columns,(double) image->rows);
5931 image_info->size=ConstantString(size);
5932 pattern=ReadImage(image_info,exception);
5933 image_info=DestroyImageInfo(image_info);
5934 if (pattern != (Image *) NULL)
5936 canvas=CloneImage(image,0,0,MagickTrue,exception);
5937 if (canvas != (Image *) NULL)
5938 (void) CompositeImage(canvas,pattern,DstOverCompositeOp,MagickFalse,
5940 pattern=DestroyImage(pattern);
5943 scanline_pad=(unsigned int) (ximage->bytes_per_line-((ximage->width*
5944 ximage->bits_per_pixel) >> 3));
5945 map_info=window->map_info;
5946 pixels=window->pixel_info->pixels;
5947 q=(unsigned char *) ximage->data;
5949 canvas_view=AcquireCacheView(canvas);
5950 if (ximage->format == XYBitmap)
5952 register unsigned short
5960 Convert canvas to big-endian bitmap.
5962 background=(unsigned char)
5963 (XPixelIntensity(&window->pixel_info->foreground_color) <
5964 XPixelIntensity(&window->pixel_info->background_color) ? 0x80 : 0x00);
5965 foreground=(unsigned char)
5966 (XPixelIntensity(&window->pixel_info->background_color) <
5967 XPixelIntensity(&window->pixel_info->foreground_color) ? 0x80 : 0x00);
5968 polarity=(unsigned short) ((GetPixelInfoIntensity(
5969 &canvas->colormap[0])) < ((Quantum) QuantumRange/2) ? 1 : 0);
5970 if (canvas->colors == 2)
5971 polarity=GetPixelInfoIntensity(&canvas->colormap[0]) <
5972 GetPixelInfoIntensity(&canvas->colormap[1]);
5973 for (y=0; y < (int) canvas->rows; y++)
5975 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,canvas->columns,1,
5977 if (p == (const Quantum *) NULL)
5981 for (x=0; x < (int) canvas->columns; x++)
5984 if (GetPixelIndex(canvas,p) == (Quantum) polarity)
5995 p+=GetPixelChannels(canvas);
6003 if (window->pixel_info->colors != 0)
6004 switch (ximage->bits_per_pixel)
6008 register unsigned int
6012 Convert to 2 bit color-mapped X canvas.
6014 for (y=0; y < (int) canvas->rows; y++)
6016 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6017 canvas->columns,1,exception);
6018 if (p == (const Quantum *) NULL)
6021 for (x=0; x < (int) canvas->columns; x++)
6023 pixel=pixels[(ssize_t) GetPixelIndex(canvas,p)] & 0x0f;
6028 *q=(unsigned char) pixel;
6034 *q|=(unsigned char) (pixel << 2);
6040 *q|=(unsigned char) (pixel << 4);
6046 *q|=(unsigned char) (pixel << 6);
6052 p+=GetPixelChannels(canvas);
6060 register unsigned int
6064 Convert to 4 bit color-mapped X canvas.
6066 for (y=0; y < (int) canvas->rows; y++)
6068 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6069 canvas->columns,1,exception);
6070 if (p == (const Quantum *) NULL)
6073 for (x=0; x < (int) canvas->columns; x++)
6075 pixel=pixels[(ssize_t) GetPixelIndex(canvas,p)] & 0xf;
6080 *q=(unsigned char) pixel;
6086 *q|=(unsigned char) (pixel << 4);
6092 p+=GetPixelChannels(canvas);
6102 Convert to 8 bit color-mapped X canvas.
6104 if (resource_info->color_recovery &&
6105 resource_info->quantize_info->dither)
6107 XDitherImage(canvas,ximage,exception);
6110 for (y=0; y < (int) canvas->rows; y++)
6112 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6113 canvas->columns,1,exception);
6114 if (p == (const Quantum *) NULL)
6116 for (x=0; x < (int) canvas->columns; x++)
6118 pixel=pixels[(ssize_t) GetPixelIndex(canvas,p)];
6119 *q++=(unsigned char) pixel;
6120 p+=GetPixelChannels(canvas);
6131 register unsigned int
6135 channel[sizeof(size_t)];
6138 Convert to multi-byte color-mapped X canvas.
6140 bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3);
6141 for (y=0; y < (int) canvas->rows; y++)
6143 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6144 canvas->columns,1,exception);
6145 if (p == (const Quantum *) NULL)
6147 for (x=0; x < (int) canvas->columns; x++)
6149 pixel=pixels[(ssize_t) GetPixelIndex(canvas,p)];
6150 for (k=0; k < (int) bytes_per_pixel; k++)
6152 channel[k]=(unsigned char) pixel;
6155 for (k=0; k < (int) bytes_per_pixel; k++)
6157 p+=GetPixelChannels(canvas);
6165 switch (ximage->bits_per_pixel)
6169 register unsigned int
6173 Convert to contiguous 2 bit continuous-tone X canvas.
6175 for (y=0; y < (int) canvas->rows; y++)
6178 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6179 canvas->columns,1,exception);
6180 if (p == (const Quantum *) NULL)
6182 for (x=0; x < (int) canvas->columns; x++)
6184 pixel=XGammaPixel(canvas,map_info,p);
6190 *q=(unsigned char) pixel;
6196 *q|=(unsigned char) (pixel << 2);
6202 *q|=(unsigned char) (pixel << 4);
6208 *q|=(unsigned char) (pixel << 6);
6214 p+=GetPixelChannels(canvas);
6222 register unsigned int
6226 Convert to contiguous 4 bit continuous-tone X canvas.
6228 for (y=0; y < (int) canvas->rows; y++)
6230 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6231 canvas->columns,1,exception);
6232 if (p == (const Quantum *) NULL)
6235 for (x=0; x < (int) canvas->columns; x++)
6237 pixel=XGammaPixel(canvas,map_info,p);
6243 *q=(unsigned char) pixel;
6249 *q|=(unsigned char) (pixel << 4);
6255 p+=GetPixelChannels(canvas);
6265 Convert to contiguous 8 bit continuous-tone X canvas.
6267 if (resource_info->color_recovery &&
6268 resource_info->quantize_info->dither)
6270 XDitherImage(canvas,ximage,exception);
6273 for (y=0; y < (int) canvas->rows; y++)
6275 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6276 canvas->columns,1,exception);
6277 if (p == (const Quantum *) NULL)
6279 for (x=0; x < (int) canvas->columns; x++)
6281 pixel=XGammaPixel(canvas,map_info,p);
6282 *q++=(unsigned char) pixel;
6283 p+=GetPixelChannels(canvas);
6291 if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) &&
6292 (map_info->green_max == 255) && (map_info->blue_max == 255) &&
6293 (map_info->red_mult == 65536L) && (map_info->green_mult == 256) &&
6294 (map_info->blue_mult == 1))
6297 Convert to 32 bit continuous-tone X canvas.
6299 for (y=0; y < (int) canvas->rows; y++)
6301 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6302 canvas->columns,1,exception);
6303 if (p == (const Quantum *) NULL)
6305 if ((red_gamma != 1.0) || (green_gamma != 1.0) ||
6306 (blue_gamma != 1.0))
6309 Gamma correct canvas.
6311 for (x=(int) canvas->columns-1; x >= 0; x--)
6313 *q++=ScaleQuantumToChar(XBlueGamma(
6314 GetPixelBlue(canvas,p)));
6315 *q++=ScaleQuantumToChar(XGreenGamma(
6316 GetPixelGreen(canvas,p)));
6317 *q++=ScaleQuantumToChar(XRedGamma(
6318 GetPixelRed(canvas,p)));
6320 p+=GetPixelChannels(canvas);
6324 for (x=(int) canvas->columns-1; x >= 0; x--)
6326 *q++=ScaleQuantumToChar((Quantum)
6327 GetPixelBlue(canvas,p));
6328 *q++=ScaleQuantumToChar((Quantum)
6329 GetPixelGreen(canvas,p));
6330 *q++=ScaleQuantumToChar((Quantum)
6331 GetPixelRed(canvas,p));
6333 p+=GetPixelChannels(canvas);
6338 if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) &&
6339 (map_info->green_max == 255) && (map_info->blue_max == 255) &&
6340 (map_info->red_mult == 1) && (map_info->green_mult == 256) &&
6341 (map_info->blue_mult == 65536L))
6344 Convert to 32 bit continuous-tone X canvas.
6346 for (y=0; y < (int) canvas->rows; y++)
6348 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6349 canvas->columns,1,exception);
6350 if (p == (const Quantum *) NULL)
6352 if ((red_gamma != 1.0) || (green_gamma != 1.0) ||
6353 (blue_gamma != 1.0))
6356 Gamma correct canvas.
6358 for (x=(int) canvas->columns-1; x >= 0; x--)
6360 *q++=ScaleQuantumToChar(XRedGamma(
6361 GetPixelRed(canvas,p)));
6362 *q++=ScaleQuantumToChar(XGreenGamma(
6363 GetPixelGreen(canvas,p)));
6364 *q++=ScaleQuantumToChar(XBlueGamma(
6365 GetPixelBlue(canvas,p)));
6367 p+=GetPixelChannels(canvas);
6371 for (x=(int) canvas->columns-1; x >= 0; x--)
6373 *q++=ScaleQuantumToChar((Quantum)
6374 GetPixelRed(canvas,p));
6375 *q++=ScaleQuantumToChar((Quantum)
6376 GetPixelGreen(canvas,p));
6377 *q++=ScaleQuantumToChar((Quantum)
6378 GetPixelBlue(canvas,p));
6380 p+=GetPixelChannels(canvas);
6389 register unsigned int
6393 channel[sizeof(size_t)];
6396 Convert to multi-byte continuous-tone X canvas.
6398 bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3);
6399 for (y=0; y < (int) canvas->rows; y++)
6401 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6402 canvas->columns,1,exception);
6403 if (p == (const Quantum *) NULL)
6405 for (x=0; x < (int) canvas->columns; x++)
6407 pixel=XGammaPixel(canvas,map_info,p);
6408 for (k=0; k < (int) bytes_per_pixel; k++)
6410 channel[k]=(unsigned char) pixel;
6413 for (k=0; k < (int) bytes_per_pixel; k++)
6415 p+=GetPixelChannels(canvas);
6423 if (matte_image != (XImage *) NULL)
6426 Initialize matte canvas.
6428 scanline_pad=(unsigned int) (matte_image->bytes_per_line-
6429 ((matte_image->width*matte_image->bits_per_pixel) >> 3));
6430 q=(unsigned char *) matte_image->data;
6431 for (y=0; y < (int) canvas->rows; y++)
6433 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,canvas->columns,1,
6435 if (p == (const Quantum *) NULL)
6439 for (x=(int) canvas->columns-1; x >= 0; x--)
6442 if (GetPixelAlpha(canvas,p) > (QuantumRange/2))
6451 p+=GetPixelChannels(canvas);
6458 canvas_view=DestroyCacheView(canvas_view);
6459 if (canvas != image)
6460 canvas=DestroyImage(canvas);
6464 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6468 + X M a k e I m a g e M S B F i r s t %
6472 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6474 % XMakeImageMSBFirst() initializes the pixel data of an X11 Image. The X
6475 % image pixels are copied in most-significant bit and byte first order. The
6476 % server's scanline pad is also respected. Rather than using one or two
6477 % general cases, many special cases are found here to help speed up the image
6480 % The format of the XMakeImageMSBFirst method is:
6482 % XMakeImageMSBFirst(resource_info,window,image,ximage,matte_image,
6483 % ExceptionInfo *exception)
6485 % A description of each parameter follows:
6487 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
6489 % o window: Specifies a pointer to a XWindowInfo structure.
6491 % o image: the image.
6493 % o ximage: Specifies a pointer to a XImage structure; returned from
6496 % o matte_image: Specifies a pointer to a XImage structure; returned from
6499 % o exception: return any errors or warnings in this structure.
6502 static void XMakeImageMSBFirst(const XResourceInfo *resource_info,
6503 const XWindowInfo *window,Image *image,XImage *ximage,XImage *matte_image,
6504 ExceptionInfo *exception)
6518 register const Quantum
6521 register unsigned char
6538 assert(resource_info != (XResourceInfo *) NULL);
6539 assert(window != (XWindowInfo *) NULL);
6540 assert(image != (Image *) NULL);
6541 if (image->debug != MagickFalse)
6542 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
6544 if ((window->immutable != MagickFalse) &&
6545 (image->storage_class == DirectClass) && (image->matte != MagickFalse))
6548 size[MaxTextExtent];
6556 image_info=AcquireImageInfo();
6557 (void) CopyMagickString(image_info->filename,
6558 resource_info->image_info->texture != (char *) NULL ?
6559 resource_info->image_info->texture : "pattern:checkerboard",
6561 (void) FormatLocaleString(size,MaxTextExtent,"%.20gx%.20g",(double)
6562 image->columns,(double) image->rows);
6563 image_info->size=ConstantString(size);
6564 pattern=ReadImage(image_info,exception);
6565 image_info=DestroyImageInfo(image_info);
6566 if (pattern != (Image *) NULL)
6568 canvas=CloneImage(image,0,0,MagickTrue,exception);
6569 if (canvas != (Image *) NULL)
6570 (void) CompositeImage(canvas,pattern,DstOverCompositeOp,MagickFalse,
6572 pattern=DestroyImage(pattern);
6575 scanline_pad=(unsigned int) (ximage->bytes_per_line-((ximage->width*
6576 ximage->bits_per_pixel) >> 3));
6577 map_info=window->map_info;
6578 pixels=window->pixel_info->pixels;
6579 q=(unsigned char *) ximage->data;
6581 canvas_view=AcquireCacheView(canvas);
6582 if (ximage->format == XYBitmap)
6584 register unsigned short
6592 Convert canvas to big-endian bitmap.
6594 background=(unsigned char)
6595 (XPixelIntensity(&window->pixel_info->foreground_color) <
6596 XPixelIntensity(&window->pixel_info->background_color) ? 0x01 : 0x00);
6597 foreground=(unsigned char)
6598 (XPixelIntensity(&window->pixel_info->background_color) <
6599 XPixelIntensity(&window->pixel_info->foreground_color) ? 0x01 : 0x00);
6600 polarity=(unsigned short) ((GetPixelInfoIntensity(
6601 &canvas->colormap[0])) < ((Quantum) QuantumRange/2) ? 1 : 0);
6602 if (canvas->colors == 2)
6603 polarity=GetPixelInfoIntensity(&canvas->colormap[0]) <
6604 GetPixelInfoIntensity(&canvas->colormap[1]);
6605 for (y=0; y < (int) canvas->rows; y++)
6607 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,canvas->columns,1,
6609 if (p == (const Quantum *) NULL)
6613 for (x=(int) canvas->columns-1; x >= 0; x--)
6616 if (GetPixelIndex(canvas,p) == (Quantum) polarity)
6627 p+=GetPixelChannels(canvas);
6635 if (window->pixel_info->colors != 0)
6636 switch (ximage->bits_per_pixel)
6640 register unsigned int
6644 Convert to 2 bit color-mapped X canvas.
6646 for (y=0; y < (int) canvas->rows; y++)
6648 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6649 canvas->columns,1,exception);
6650 if (p == (const Quantum *) NULL)
6653 for (x=0; x < (int) canvas->columns; x++)
6655 pixel=pixels[(ssize_t)
6656 GetPixelIndex(canvas,p)] & 0xf;
6661 *q=(unsigned char) (pixel << 6);
6667 *q|=(unsigned char) (pixel << 4);
6673 *q|=(unsigned char) (pixel << 2);
6679 *q|=(unsigned char) pixel;
6685 p+=GetPixelChannels(canvas);
6693 register unsigned int
6697 Convert to 4 bit color-mapped X canvas.
6699 for (y=0; y < (int) canvas->rows; y++)
6701 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6702 canvas->columns,1,exception);
6703 if (p == (const Quantum *) NULL)
6706 for (x=0; x < (int) canvas->columns; x++)
6708 pixel=pixels[(ssize_t)
6709 GetPixelIndex(canvas,p)] & 0xf;
6714 *q=(unsigned char) (pixel << 4);
6720 *q|=(unsigned char) pixel;
6726 p+=GetPixelChannels(canvas);
6736 Convert to 8 bit color-mapped X canvas.
6738 if (resource_info->color_recovery &&
6739 resource_info->quantize_info->dither)
6741 XDitherImage(canvas,ximage,exception);
6744 for (y=0; y < (int) canvas->rows; y++)
6746 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6747 canvas->columns,1,exception);
6748 if (p == (const Quantum *) NULL)
6750 for (x=0; x < (int) canvas->columns; x++)
6752 pixel=pixels[(ssize_t) GetPixelIndex(canvas,p)];
6753 *q++=(unsigned char) pixel;
6754 p+=GetPixelChannels(canvas);
6765 register unsigned int
6769 channel[sizeof(size_t)];
6772 Convert to 8 bit color-mapped X canvas.
6774 bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3);
6775 for (y=0; y < (int) canvas->rows; y++)
6777 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6778 canvas->columns,1,exception);
6779 if (p == (const Quantum *) NULL)
6781 for (x=0; x < (int) canvas->columns; x++)
6783 pixel=pixels[(ssize_t)
6784 GetPixelIndex(canvas,p)];
6785 for (k=(int) bytes_per_pixel-1; k >= 0; k--)
6787 channel[k]=(unsigned char) pixel;
6790 for (k=0; k < (int) bytes_per_pixel; k++)
6792 p+=GetPixelChannels(canvas);
6800 switch (ximage->bits_per_pixel)
6804 register unsigned int
6808 Convert to 4 bit continuous-tone X canvas.
6810 for (y=0; y < (int) canvas->rows; y++)
6812 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6813 canvas->columns,1,exception);
6814 if (p == (const Quantum *) NULL)
6817 for (x=(int) canvas->columns-1; x >= 0; x--)
6819 pixel=XGammaPixel(canvas,map_info,p);
6825 *q=(unsigned char) (pixel << 6);
6831 *q|=(unsigned char) (pixel << 4);
6837 *q|=(unsigned char) (pixel << 2);
6843 *q|=(unsigned char) pixel;
6849 p+=GetPixelChannels(canvas);
6857 register unsigned int
6861 Convert to 4 bit continuous-tone X canvas.
6863 for (y=0; y < (int) canvas->rows; y++)
6865 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6866 canvas->columns,1,exception);
6867 if (p == (const Quantum *) NULL)
6870 for (x=(int) canvas->columns-1; x >= 0; x--)
6872 pixel=XGammaPixel(canvas,map_info,p);
6878 *q=(unsigned char) (pixel << 4);
6884 *q|=(unsigned char) pixel;
6890 p+=GetPixelChannels(canvas);
6900 Convert to 8 bit continuous-tone X canvas.
6902 if (resource_info->color_recovery &&
6903 resource_info->quantize_info->dither)
6905 XDitherImage(canvas,ximage,exception);
6908 for (y=0; y < (int) canvas->rows; y++)
6910 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6911 canvas->columns,1,exception);
6912 if (p == (const Quantum *) NULL)
6914 for (x=(int) canvas->columns-1; x >= 0; x--)
6916 pixel=XGammaPixel(canvas,map_info,p);
6917 *q++=(unsigned char) pixel;
6918 p+=GetPixelChannels(canvas);
6926 if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) &&
6927 (map_info->green_max == 255) && (map_info->blue_max == 255) &&
6928 (map_info->red_mult == 65536L) && (map_info->green_mult == 256) &&
6929 (map_info->blue_mult == 1))
6932 Convert to 32 bit continuous-tone X canvas.
6934 for (y=0; y < (int) canvas->rows; y++)
6936 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6937 canvas->columns,1,exception);
6938 if (p == (const Quantum *) NULL)
6940 if ((red_gamma != 1.0) || (green_gamma != 1.0) ||
6941 (blue_gamma != 1.0))
6944 Gamma correct canvas.
6946 for (x=(int) canvas->columns-1; x >= 0; x--)
6949 *q++=ScaleQuantumToChar(XRedGamma(
6950 GetPixelRed(canvas,p)));
6951 *q++=ScaleQuantumToChar(XGreenGamma(
6952 GetPixelGreen(canvas,p)));
6953 *q++=ScaleQuantumToChar(XBlueGamma(
6954 GetPixelBlue(canvas,p)));
6955 p+=GetPixelChannels(canvas);
6959 for (x=(int) canvas->columns-1; x >= 0; x--)
6962 *q++=ScaleQuantumToChar((Quantum)
6963 GetPixelRed(canvas,p));
6964 *q++=ScaleQuantumToChar((Quantum)
6965 GetPixelGreen(canvas,p));
6966 *q++=ScaleQuantumToChar((Quantum)
6967 GetPixelBlue(canvas,p));
6968 p+=GetPixelChannels(canvas);
6973 if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) &&
6974 (map_info->green_max == 255) && (map_info->blue_max == 255) &&
6975 (map_info->red_mult == 1) && (map_info->green_mult == 256) &&
6976 (map_info->blue_mult == 65536L))
6979 Convert to 32 bit continuous-tone X canvas.
6981 for (y=0; y < (int) canvas->rows; y++)
6983 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6984 canvas->columns,1,exception);
6985 if (p == (const Quantum *) NULL)
6987 if ((red_gamma != 1.0) || (green_gamma != 1.0) ||
6988 (blue_gamma != 1.0))
6991 Gamma correct canvas.
6993 for (x=(int) canvas->columns-1; x >= 0; x--)
6996 *q++=ScaleQuantumToChar(XBlueGamma(
6997 GetPixelBlue(canvas,p)));
6998 *q++=ScaleQuantumToChar(XGreenGamma(
6999 GetPixelGreen(canvas,p)));
7000 *q++=ScaleQuantumToChar(XRedGamma(
7001 GetPixelRed(canvas,p)));
7002 p+=GetPixelChannels(canvas);
7006 for (x=(int) canvas->columns-1; x >= 0; x--)
7009 *q++=ScaleQuantumToChar((Quantum)
7010 GetPixelBlue(canvas,p));
7011 *q++=ScaleQuantumToChar((Quantum)
7012 GetPixelGreen(canvas,p));
7013 *q++=ScaleQuantumToChar((Quantum)
7014 GetPixelRed(canvas,p));
7015 p+=GetPixelChannels(canvas);
7024 register unsigned int
7028 channel[sizeof(size_t)];
7031 Convert to multi-byte continuous-tone X canvas.
7033 bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3);
7034 for (y=0; y < (int) canvas->rows; y++)
7036 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
7037 canvas->columns,1,exception);
7038 if (p == (const Quantum *) NULL)
7040 for (x=(int) canvas->columns-1; x >= 0; x--)
7042 pixel=XGammaPixel(canvas,map_info,p);
7043 for (k=(int) bytes_per_pixel-1; k >= 0; k--)
7045 channel[k]=(unsigned char) pixel;
7048 for (k=0; k < (int) bytes_per_pixel; k++)
7050 p+=GetPixelChannels(canvas);
7058 if (matte_image != (XImage *) NULL)
7061 Initialize matte canvas.
7063 scanline_pad=(unsigned int) (matte_image->bytes_per_line-
7064 ((matte_image->width*matte_image->bits_per_pixel) >> 3));
7065 q=(unsigned char *) matte_image->data;
7066 for (y=0; y < (int) canvas->rows; y++)
7068 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,canvas->columns,1,
7070 if (p == (const Quantum *) NULL)
7074 for (x=(int) canvas->columns-1; x >= 0; x--)
7077 if (GetPixelAlpha(canvas,p) > (QuantumRange/2))
7086 p+=GetPixelChannels(canvas);
7093 canvas_view=DestroyCacheView(canvas_view);
7094 if (canvas != image)
7095 canvas=DestroyImage(canvas);
7099 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7103 % X M a k e M a g n i f y I m a g e %
7107 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7109 % XMakeMagnifyImage() magnifies a region of an X image and displays it.
7111 % The format of the XMakeMagnifyImage method is:
7113 % void XMakeMagnifyImage(Display *display,XWindows *windows,
7114 % ExceptionInfo *exception)
7116 % A description of each parameter follows:
7118 % o display: Specifies a connection to an X server; returned from
7121 % o windows: Specifies a pointer to a XWindows structure.
7123 % o exception: return any errors or warnings in this structure.
7126 MagickPrivate void XMakeMagnifyImage(Display *display,XWindows *windows,
7127 ExceptionInfo *exception)
7130 tuple[MaxTextExtent];
7144 register unsigned char
7152 previous_magnify = 0;
7170 Check boundary conditions.
7172 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
7173 assert(display != (Display *) NULL);
7174 assert(windows != (XWindows *) NULL);
7176 for (n=1; n < (ssize_t) windows->magnify.data; n++)
7178 while ((magnify*windows->image.ximage->width) < windows->magnify.width)
7180 while ((magnify*windows->image.ximage->height) < windows->magnify.height)
7182 while (magnify > windows->magnify.width)
7184 while (magnify > windows->magnify.height)
7186 if (magnify != previous_magnify)
7195 New magnify factor: update magnify window name.
7198 while ((1 << i) <= (int) magnify)
7200 (void) FormatLocaleString(windows->magnify.name,MaxTextExtent,
7201 "Magnify %.20gX",(double) i);
7202 status=XStringListToTextProperty(&windows->magnify.name,1,&window_name);
7203 if (status != False)
7205 XSetWMName(display,windows->magnify.id,&window_name);
7206 XSetWMIconName(display,windows->magnify.id,&window_name);
7207 (void) XFree((void *) window_name.value);
7210 previous_magnify=magnify;
7211 ximage=windows->image.ximage;
7212 width=(unsigned int) windows->magnify.ximage->width;
7213 height=(unsigned int) windows->magnify.ximage->height;
7214 if ((windows->magnify.x < 0) ||
7215 (windows->magnify.x >= windows->image.ximage->width))
7216 windows->magnify.x=windows->image.ximage->width >> 1;
7217 x=windows->magnify.x-((width/magnify) >> 1);
7221 if (x > (int) (ximage->width-(width/magnify)))
7222 x=ximage->width-width/magnify;
7223 if ((windows->magnify.y < 0) ||
7224 (windows->magnify.y >= windows->image.ximage->height))
7225 windows->magnify.y=windows->image.ximage->height >> 1;
7226 y=windows->magnify.y-((height/magnify) >> 1);
7230 if (y > (int) (ximage->height-(height/magnify)))
7231 y=ximage->height-height/magnify;
7232 q=(unsigned char *) windows->magnify.ximage->data;
7233 scanline_pad=(unsigned int) (windows->magnify.ximage->bytes_per_line-
7234 ((width*windows->magnify.ximage->bits_per_pixel) >> 3));
7235 if (ximage->bits_per_pixel < 8)
7237 register unsigned char
7244 register unsigned int
7250 pixel_info=windows->magnify.pixel_info;
7251 switch (ximage->bitmap_bit_order)
7256 Magnify little-endian bitmap.
7260 if (ximage->format == XYBitmap)
7262 background=(unsigned char)
7263 (XPixelIntensity(&pixel_info->foreground_color) <
7264 XPixelIntensity(&pixel_info->background_color) ? 0x80 : 0x00);
7265 foreground=(unsigned char)
7266 (XPixelIntensity(&pixel_info->background_color) <
7267 XPixelIntensity(&pixel_info->foreground_color) ? 0x80 : 0x00);
7268 if (windows->magnify.depth > 1)
7269 Swap(background,foreground);
7271 for (i=0; i < (ssize_t) height; i+=magnify)
7274 Propogate pixel magnify rows.
7276 for (j=0; j < magnify; j++)
7278 p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
7279 ((x*ximage->bits_per_pixel) >> 3);
7280 p_bit=(unsigned char) (x*ximage->bits_per_pixel) & 0x07;
7283 for (k=0; k < width; k+=magnify)
7286 Propogate pixel magnify columns.
7288 for (l=0; l < magnify; l++)
7291 Propogate each bit plane.
7293 for (plane=0; (int) plane < ximage->bits_per_pixel; plane++)
7296 if (*p & (0x01 << (p_bit+plane)))
7309 p_bit+=ximage->bits_per_pixel;
7316 *q=byte >> (8-q_bit);
7328 Magnify big-endian bitmap.
7332 if (ximage->format == XYBitmap)
7334 background=(unsigned char)
7335 (XPixelIntensity(&pixel_info->foreground_color) <
7336 XPixelIntensity(&pixel_info->background_color) ? 0x01 : 0x00);
7337 foreground=(unsigned char)
7338 (XPixelIntensity(&pixel_info->background_color) <
7339 XPixelIntensity(&pixel_info->foreground_color) ? 0x01 : 0x00);
7340 if (windows->magnify.depth > 1)
7341 Swap(background,foreground);
7343 for (i=0; i < (ssize_t) height; i+=magnify)
7346 Propogate pixel magnify rows.
7348 for (j=0; j < magnify; j++)
7350 p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
7351 ((x*ximage->bits_per_pixel) >> 3);
7352 p_bit=(unsigned char) (x*ximage->bits_per_pixel) & 0x07;
7355 for (k=0; k < width; k+=magnify)
7358 Propogate pixel magnify columns.
7360 for (l=0; l < magnify; l++)
7363 Propogate each bit plane.
7365 for (plane=0; (int) plane < ximage->bits_per_pixel; plane++)
7368 if (*p & (0x80 >> (p_bit+plane)))
7381 p_bit+=ximage->bits_per_pixel;
7388 *q=byte << (8-q_bit);
7399 switch (ximage->bits_per_pixel)
7405 Magnify 8 bit X image.
7407 for (i=0; i < (ssize_t) height; i+=magnify)
7410 Propogate pixel magnify rows.
7412 for (j=0; j < magnify; j++)
7414 p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
7415 ((x*ximage->bits_per_pixel) >> 3);
7416 for (k=0; k < width; k+=magnify)
7419 Propogate pixel magnify columns.
7421 for (l=0; l < magnify; l++)
7433 register unsigned int
7438 Magnify multi-byte X image.
7440 bytes_per_pixel=(unsigned int) ximage->bits_per_pixel >> 3;
7441 for (i=0; i < (ssize_t) height; i+=magnify)
7444 Propogate pixel magnify rows.
7446 for (j=0; j < magnify; j++)
7448 p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
7449 ((x*ximage->bits_per_pixel) >> 3);
7450 for (k=0; k < width; k+=magnify)
7453 Propogate pixel magnify columns.
7455 for (l=0; l < magnify; l++)
7456 for (m=0; m < bytes_per_pixel; m++)
7468 Copy X image to magnify pixmap.
7470 x=windows->magnify.x-((width/magnify) >> 1);
7472 x=(int) ((width >> 1)-windows->magnify.x*magnify);
7474 if (x > (int) (ximage->width-(width/magnify)))
7475 x=(int) ((ximage->width-windows->magnify.x)*magnify-(width >> 1));
7478 y=windows->magnify.y-((height/magnify) >> 1);
7480 y=(int) ((height >> 1)-windows->magnify.y*magnify);
7482 if (y > (int) (ximage->height-(height/magnify)))
7483 y=(int) ((ximage->height-windows->magnify.y)*magnify-(height >> 1));
7486 if ((x != 0) || (y != 0))
7487 (void) XFillRectangle(display,windows->magnify.pixmap,
7488 windows->magnify.annotate_context,0,0,width,height);
7489 (void) XPutImage(display,windows->magnify.pixmap,
7490 windows->magnify.annotate_context,windows->magnify.ximage,0,0,x,y,width-x,
7492 if ((magnify > 1) && ((magnify <= (width >> 1)) &&
7493 (magnify <= (height >> 1))))
7499 Highlight center pixel.
7501 highlight_info.x=(ssize_t) windows->magnify.width >> 1;
7502 highlight_info.y=(ssize_t) windows->magnify.height >> 1;
7503 highlight_info.width=magnify;
7504 highlight_info.height=magnify;
7505 (void) XDrawRectangle(display,windows->magnify.pixmap,
7506 windows->magnify.highlight_context,(int) highlight_info.x,
7507 (int) highlight_info.y,(unsigned int) highlight_info.width-1,
7508 (unsigned int) highlight_info.height-1);
7510 (void) XDrawRectangle(display,windows->magnify.pixmap,
7511 windows->magnify.annotate_context,(int) highlight_info.x+1,
7512 (int) highlight_info.y+1,(unsigned int) highlight_info.width-3,
7513 (unsigned int) highlight_info.height-3);
7516 Show center pixel color.
7518 (void) GetOneVirtualPixelInfo(windows->image.image,TileVirtualPixelMethod,
7519 (ssize_t) windows->magnify.x,(ssize_t) windows->magnify.y,&pixel,exception);
7520 (void) FormatLocaleString(tuple,MaxTextExtent,"%d,%d: ",
7521 windows->magnify.x,windows->magnify.y);
7522 (void) ConcatenateMagickString(tuple,"(",MaxTextExtent);
7523 ConcatenateColorComponent(&pixel,RedPixelChannel,X11Compliance,tuple);
7524 (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
7525 ConcatenateColorComponent(&pixel,GreenPixelChannel,X11Compliance,tuple);
7526 (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
7527 ConcatenateColorComponent(&pixel,BluePixelChannel,X11Compliance,tuple);
7528 if (pixel.colorspace == CMYKColorspace)
7530 (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
7531 ConcatenateColorComponent(&pixel,BlackPixelChannel,X11Compliance,tuple);
7533 if (pixel.matte != MagickFalse)
7535 (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
7536 ConcatenateColorComponent(&pixel,AlphaPixelChannel,X11Compliance,tuple);
7538 (void) ConcatenateMagickString(tuple,")",MaxTextExtent);
7539 height=(unsigned int) windows->magnify.font_info->ascent+
7540 windows->magnify.font_info->descent;
7541 x=windows->magnify.font_info->max_bounds.width >> 1;
7542 y=windows->magnify.font_info->ascent+(height >> 2);
7543 (void) XDrawImageString(display,windows->magnify.pixmap,
7544 windows->magnify.annotate_context,x,y,tuple,(int) strlen(tuple));
7545 GetColorTuple(&pixel,MagickTrue,tuple);
7547 (void) XDrawImageString(display,windows->magnify.pixmap,
7548 windows->magnify.annotate_context,x,y,tuple,(int) strlen(tuple));
7549 (void) QueryColorname(windows->image.image,&pixel,SVGCompliance,tuple,
7552 (void) XDrawImageString(display,windows->magnify.pixmap,
7553 windows->magnify.annotate_context,x,y,tuple,(int) strlen(tuple));
7555 Refresh magnify window.
7557 magnify_window=windows->magnify;
7560 XRefreshWindow(display,&magnify_window,(XEvent *) NULL);
7564 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7568 % X M a k e P i x m a p %
7572 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7574 % XMakePixmap() creates an X11 pixmap.
7576 % The format of the XMakePixmap method is:
7578 % void XMakeStandardColormap(Display *display,XVisualInfo *visual_info,
7579 % XResourceInfo *resource_info,Image *image,XStandardColormap *map_info,
7580 % XPixelInfo *pixel)
7582 % A description of each parameter follows:
7584 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
7586 % o display: Specifies a connection to an X server; returned from
7589 % o window: Specifies a pointer to a XWindowInfo structure.
7592 static MagickBooleanType XMakePixmap(Display *display,
7593 const XResourceInfo *resource_info,XWindowInfo *window)
7599 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
7600 assert(display != (Display *) NULL);
7601 assert(resource_info != (XResourceInfo *) NULL);
7602 assert(window != (XWindowInfo *) NULL);
7603 if (window->pixmap != (Pixmap) NULL)
7606 Destroy previous X pixmap.
7608 (void) XFreePixmap(display,window->pixmap);
7609 window->pixmap=(Pixmap) NULL;
7611 if (window->use_pixmap == MagickFalse)
7612 return(MagickFalse);
7613 if (window->ximage == (XImage *) NULL)
7614 return(MagickFalse);
7616 Display busy cursor.
7618 (void) XCheckDefineCursor(display,window->id,window->busy_cursor);
7619 (void) XFlush(display);
7623 width=(unsigned int) window->ximage->width;
7624 height=(unsigned int) window->ximage->height;
7625 window->pixmap=XCreatePixmap(display,window->id,width,height,window->depth);
7626 if (window->pixmap == (Pixmap) NULL)
7629 Unable to allocate pixmap.
7631 (void) XCheckDefineCursor(display,window->id,window->cursor);
7632 return(MagickFalse);
7635 Copy X image to pixmap.
7637 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
7638 if (window->shared_memory)
7639 (void) XShmPutImage(display,window->pixmap,window->annotate_context,
7640 window->ximage,0,0,0,0,width,height,MagickTrue);
7642 if (window->shared_memory == MagickFalse)
7643 (void) XPutImage(display,window->pixmap,window->annotate_context,
7644 window->ximage,0,0,0,0,width,height);
7645 if (IsEventLogging())
7647 (void) LogMagickEvent(X11Event,GetMagickModule(),"Pixmap:");
7648 (void) LogMagickEvent(X11Event,GetMagickModule()," width, height: %ux%u",
7654 (void) XCheckDefineCursor(display,window->id,window->cursor);
7659 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7663 % X M a k e S t a n d a r d C o l o r m a p %
7667 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7669 % XMakeStandardColormap() creates an X11 Standard Colormap.
7671 % The format of the XMakeStandardColormap method is:
7673 % void XMakeStandardColormap(Display *display,XVisualInfo *visual_info,
7674 % XResourceInfo *resource_info,Image *image,XStandardColormap *map_info,
7675 % XPixelInfo *pixel,ExceptionInfo *exception)
7677 % A description of each parameter follows:
7679 % o display: Specifies a connection to an X server; returned from
7682 % o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
7683 % returned from XGetVisualInfo.
7685 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
7687 % o image: the image.
7689 % o map_info: If a Standard Colormap type is specified, this structure is
7690 % initialized with info from the Standard Colormap.
7692 % o pixel: Specifies a pointer to a XPixelInfo structure.
7694 % o exception: return any errors or warnings in this structure.
7698 #if defined(__cplusplus) || defined(c_plusplus)
7702 static inline MagickRealType DiversityPixelIntensity(
7703 const DiversityPacket *pixel)
7708 intensity=0.299*pixel->red+0.587*pixel->green+0.114*pixel->blue;
7712 static int IntensityCompare(const void *x,const void *y)
7721 color_1=(DiversityPacket *) x;
7722 color_2=(DiversityPacket *) y;
7723 diversity=(int) (DiversityPixelIntensity(color_2)-
7724 DiversityPixelIntensity(color_1));
7728 static int PopularityCompare(const void *x,const void *y)
7734 color_1=(DiversityPacket *) x;
7735 color_2=(DiversityPacket *) y;
7736 return((int) color_2->count-(int) color_1->count);
7739 #if defined(__cplusplus) || defined(c_plusplus)
7743 static inline Quantum ScaleXToQuantum(const size_t x,
7746 return((Quantum) (((MagickRealType) QuantumRange*x)/scale+0.5));
7749 MagickPrivate void XMakeStandardColormap(Display *display,
7750 XVisualInfo *visual_info,XResourceInfo *resource_info,Image *image,
7751 XStandardColormap *map_info,XPixelInfo *pixel,ExceptionInfo *exception)
7774 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
7775 assert(display != (Display *) NULL);
7776 assert(visual_info != (XVisualInfo *) NULL);
7777 assert(map_info != (XStandardColormap *) NULL);
7778 assert(resource_info != (XResourceInfo *) NULL);
7779 assert(pixel != (XPixelInfo *) NULL);
7780 if (resource_info->map_type != (char *) NULL)
7783 Standard Colormap is already defined (i.e. xstdcmap).
7785 XGetPixelInfo(display,visual_info,map_info,resource_info,image,
7787 number_colors=(unsigned int) (map_info->base_pixel+
7788 (map_info->red_max+1)*(map_info->green_max+1)*(map_info->blue_max+1));
7789 if ((map_info->red_max*map_info->green_max*map_info->blue_max) != 0)
7790 if ((image->matte == MagickFalse) &&
7791 (resource_info->color_recovery == MagickFalse) &&
7792 resource_info->quantize_info->dither &&
7793 (number_colors < MaxColormapSize))
7802 Improve image appearance with error diffusion.
7804 affinity_image=AcquireImage((ImageInfo *) NULL,exception);
7805 if (affinity_image == (Image *) NULL)
7806 ThrowXWindowFatalException(ResourceLimitFatalError,
7807 "UnableToDitherImage",image->filename);
7808 affinity_image->columns=number_colors;
7809 affinity_image->rows=1;
7811 Initialize colormap image.
7813 q=QueueAuthenticPixels(affinity_image,0,0,affinity_image->columns,
7815 if (q != (Quantum *) NULL)
7817 for (i=0; i < (ssize_t) number_colors; i++)
7819 SetPixelRed(affinity_image,0,q);
7820 if (map_info->red_max != 0)
7821 SetPixelRed(affinity_image,
7822 ScaleXToQuantum((size_t) (i/map_info->red_mult),
7823 map_info->red_max),q);
7824 SetPixelGreen(affinity_image,0,q);
7825 if (map_info->green_max != 0)
7826 SetPixelGreen(affinity_image,
7827 ScaleXToQuantum((size_t) ((i/map_info->green_mult) %
7828 (map_info->green_max+1)),map_info->green_max),q);
7829 SetPixelBlue(affinity_image,0,q);
7830 if (map_info->blue_max != 0)
7831 SetPixelBlue(affinity_image,
7832 ScaleXToQuantum((size_t) (i % map_info->green_mult),
7833 map_info->blue_max),q);
7834 SetPixelAlpha(affinity_image,
7835 TransparentAlpha,q);
7836 q+=GetPixelChannels(affinity_image);
7838 (void) SyncAuthenticPixels(affinity_image,exception);
7839 (void) RemapImage(resource_info->quantize_info,image,
7840 affinity_image,exception);
7842 XGetPixelInfo(display,visual_info,map_info,resource_info,image,
7844 (void) SetImageStorageClass(image,DirectClass,exception);
7845 affinity_image=DestroyImage(affinity_image);
7847 if (IsEventLogging())
7849 (void) LogMagickEvent(X11Event,GetMagickModule(),
7850 "Standard Colormap:");
7851 (void) LogMagickEvent(X11Event,GetMagickModule(),
7852 " colormap id: 0x%lx",map_info->colormap);
7853 (void) LogMagickEvent(X11Event,GetMagickModule(),
7854 " red, green, blue max: %lu %lu %lu",map_info->red_max,
7855 map_info->green_max,map_info->blue_max);
7856 (void) LogMagickEvent(X11Event,GetMagickModule(),
7857 " red, green, blue mult: %lu %lu %lu",map_info->red_mult,
7858 map_info->green_mult,map_info->blue_mult);
7862 if ((visual_info->klass != DirectColor) &&
7863 (visual_info->klass != TrueColor))
7864 if ((image->storage_class == DirectClass) ||
7865 ((int) image->colors > visual_info->colormap_size))
7871 Image has more colors than the visual supports.
7873 quantize_info=(*resource_info->quantize_info);
7874 quantize_info.number_colors=(size_t) visual_info->colormap_size;
7875 (void) QuantizeImage(&quantize_info,image,exception);
7878 Free previous and create new colormap.
7880 (void) XFreeStandardColormap(display,visual_info,map_info,pixel);
7881 colormap=XDefaultColormap(display,visual_info->screen);
7882 if (visual_info->visual != XDefaultVisual(display,visual_info->screen))
7883 colormap=XCreateColormap(display,XRootWindow(display,visual_info->screen),
7884 visual_info->visual,visual_info->klass == DirectColor ?
7885 AllocAll : AllocNone);
7886 if (colormap == (Colormap) NULL)
7887 ThrowXWindowFatalException(ResourceLimitFatalError,"UnableToCreateColormap",
7890 Initialize the map and pixel info structures.
7892 XGetMapInfo(visual_info,colormap,map_info);
7893 XGetPixelInfo(display,visual_info,map_info,resource_info,image,pixel);
7895 Allocating colors in server colormap is based on visual class.
7897 switch (visual_info->klass)
7903 Define Standard Colormap for StaticGray or StaticColor visual.
7905 number_colors=image->colors;
7906 colors=(XColor *) AcquireQuantumMemory((size_t)
7907 visual_info->colormap_size,sizeof(*colors));
7908 if (colors == (XColor *) NULL)
7909 ThrowXWindowFatalException(ResourceLimitFatalError,
7910 "UnableToCreateColormap",image->filename);
7912 color.flags=(char) (DoRed | DoGreen | DoBlue);
7913 for (i=0; i < (ssize_t) image->colors; i++)
7915 color.red=ScaleQuantumToShort(XRedGamma(image->colormap[i].red));
7916 color.green=ScaleQuantumToShort(XGreenGamma(image->colormap[i].green));
7917 color.blue=ScaleQuantumToShort(XBlueGamma(image->colormap[i].blue));
7918 if (visual_info->klass != StaticColor)
7920 gray_value=(unsigned short) XPixelIntensity(&color);
7921 color.red=gray_value;
7922 color.green=gray_value;
7923 color.blue=gray_value;
7925 status=XAllocColor(display,colormap,&color);
7926 if (status == False)
7928 colormap=XCopyColormapAndFree(display,colormap);
7929 (void) XAllocColor(display,colormap,&color);
7931 pixel->pixels[i]=color.pixel;
7943 Define Standard Colormap for GrayScale or PseudoColor visual.
7945 number_colors=image->colors;
7946 colors=(XColor *) AcquireQuantumMemory((size_t)
7947 visual_info->colormap_size,sizeof(*colors));
7948 if (colors == (XColor *) NULL)
7949 ThrowXWindowFatalException(ResourceLimitFatalError,
7950 "UnableToCreateColormap",image->filename);
7952 Preallocate our GUI colors.
7954 (void) XAllocColor(display,colormap,&pixel->foreground_color);
7955 (void) XAllocColor(display,colormap,&pixel->background_color);
7956 (void) XAllocColor(display,colormap,&pixel->border_color);
7957 (void) XAllocColor(display,colormap,&pixel->matte_color);
7958 (void) XAllocColor(display,colormap,&pixel->highlight_color);
7959 (void) XAllocColor(display,colormap,&pixel->shadow_color);
7960 (void) XAllocColor(display,colormap,&pixel->depth_color);
7961 (void) XAllocColor(display,colormap,&pixel->trough_color);
7962 for (i=0; i < MaxNumberPens; i++)
7963 (void) XAllocColor(display,colormap,&pixel->pen_colors[i]);
7965 Determine if image colors will "fit" into X server colormap.
7967 colormap_type=resource_info->colormap;
7968 status=XAllocColorCells(display,colormap,MagickFalse,(unsigned long *)
7969 NULL,0,pixel->pixels,(unsigned int) image->colors);
7970 if (status != False)
7971 colormap_type=PrivateColormap;
7972 if (colormap_type == SharedColormap)
7993 Define Standard colormap for shared GrayScale or PseudoColor visual.
7995 diversity=(DiversityPacket *) AcquireQuantumMemory(image->colors,
7996 sizeof(*diversity));
7997 if (diversity == (DiversityPacket *) NULL)
7998 ThrowXWindowFatalException(ResourceLimitFatalError,
7999 "UnableToCreateColormap",image->filename);
8000 for (i=0; i < (ssize_t) image->colors; i++)
8002 diversity[i].red=ClampToQuantum(image->colormap[i].red);
8003 diversity[i].green=ClampToQuantum(image->colormap[i].green);
8004 diversity[i].blue=ClampToQuantum(image->colormap[i].blue);
8005 diversity[i].index=(unsigned short) i;
8006 diversity[i].count=0;
8008 image_view=AcquireCacheView(image);
8009 for (y=0; y < (int) image->rows; y++)
8014 register const Quantum
8017 p=GetCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
8018 image->columns,1,exception);
8019 if (p == (const Quantum *) NULL)
8021 for (x=(int) image->columns-1; x >= 0; x--)
8023 diversity[(ssize_t) GetPixelIndex(image,p)].count++;
8024 p+=GetPixelChannels(image);
8027 image_view=DestroyCacheView(image_view);
8029 Sort colors by decreasing intensity.
8031 qsort((void *) diversity,image->colors,sizeof(*diversity),
8033 for (i=0; i < (ssize_t) image->colors; )
8035 diversity[i].count<<=4; /* increase this colors popularity */
8036 i+=MagickMax((int) (image->colors >> 4),2);
8038 diversity[image->colors-1].count<<=4;
8039 qsort((void *) diversity,image->colors,sizeof(*diversity),
8045 color.flags=(char) (DoRed | DoGreen | DoBlue);
8046 for (i=0; i < (ssize_t) image->colors; i++)
8048 index=diversity[i].index;
8050 ScaleQuantumToShort(XRedGamma(image->colormap[index].red));
8052 ScaleQuantumToShort(XGreenGamma(image->colormap[index].green));
8054 ScaleQuantumToShort(XBlueGamma(image->colormap[index].blue));
8055 if (visual_info->klass != PseudoColor)
8057 gray_value=(unsigned short) XPixelIntensity(&color);
8058 color.red=gray_value;
8059 color.green=gray_value;
8060 color.blue=gray_value;
8062 status=XAllocColor(display,colormap,&color);
8063 if (status == False)
8065 pixel->pixels[index]=color.pixel;
8069 Read X server colormap.
8071 server_colors=(XColor *) AcquireQuantumMemory((size_t)
8072 visual_info->colormap_size,sizeof(*server_colors));
8073 if (server_colors == (XColor *) NULL)
8074 ThrowXWindowFatalException(ResourceLimitFatalError,
8075 "UnableToCreateColormap",image->filename);
8076 for (x=visual_info->colormap_size-1; x >= 0; x--)
8077 server_colors[x].pixel=(size_t) x;
8078 (void) XQueryColors(display,colormap,server_colors,
8079 (int) MagickMin((unsigned int) visual_info->colormap_size,256));
8081 Select remaining colors from X server colormap.
8083 for (; i < (ssize_t) image->colors; i++)
8085 index=diversity[i].index;
8087 ScaleQuantumToShort(XRedGamma(image->colormap[index].red));
8089 ScaleQuantumToShort(XGreenGamma(image->colormap[index].green));
8091 ScaleQuantumToShort(XBlueGamma(image->colormap[index].blue));
8092 if (visual_info->klass != PseudoColor)
8094 gray_value=(unsigned short) XPixelIntensity(&color);
8095 color.red=gray_value;
8096 color.green=gray_value;
8097 color.blue=gray_value;
8099 XBestPixel(display,colormap,server_colors,(unsigned int)
8100 visual_info->colormap_size,&color);
8101 pixel->pixels[index]=color.pixel;
8104 if ((int) image->colors < visual_info->colormap_size)
8107 Fill up colors array-- more choices for pen colors.
8109 retain_colors=MagickMin((unsigned int)
8110 (visual_info->colormap_size-image->colors),256);
8111 for (i=0; i < (ssize_t) retain_colors; i++)
8112 *p++=server_colors[i];
8113 number_colors+=retain_colors;
8115 server_colors=(XColor *) RelinquishMagickMemory(server_colors);
8116 diversity=(DiversityPacket *) RelinquishMagickMemory(diversity);
8120 Define Standard colormap for private GrayScale or PseudoColor visual.
8122 if (status == False)
8125 Not enough colormap entries in the colormap-- Create a new colormap.
8127 colormap=XCreateColormap(display,
8128 XRootWindow(display,visual_info->screen),visual_info->visual,
8130 if (colormap == (Colormap) NULL)
8131 ThrowXWindowFatalException(ResourceLimitFatalError,
8132 "UnableToCreateColormap",image->filename);
8133 map_info->colormap=colormap;
8134 if ((int) image->colors < visual_info->colormap_size)
8137 Retain colors from the default colormap to help lessens the
8138 effects of colormap flashing.
8140 retain_colors=MagickMin((unsigned int)
8141 (visual_info->colormap_size-image->colors),256);
8142 p=colors+image->colors;
8143 for (i=0; i < (ssize_t) retain_colors; i++)
8145 p->pixel=(unsigned long) i;
8148 (void) XQueryColors(display,
8149 XDefaultColormap(display,visual_info->screen),
8150 colors+image->colors,(int) retain_colors);
8152 Transfer colors from default to private colormap.
8154 (void) XAllocColorCells(display,colormap,MagickFalse,
8155 (unsigned long *) NULL,0,pixel->pixels,(unsigned int)
8157 p=colors+image->colors;
8158 for (i=0; i < (ssize_t) retain_colors; i++)
8160 p->pixel=pixel->pixels[i];
8163 (void) XStoreColors(display,colormap,colors+image->colors,
8164 (int) retain_colors);
8165 number_colors+=retain_colors;
8167 (void) XAllocColorCells(display,colormap,MagickFalse,
8168 (unsigned long *) NULL,0,pixel->pixels,(unsigned int)
8172 Store the image colormap.
8175 color.flags=(char) (DoRed | DoGreen | DoBlue);
8176 for (i=0; i < (ssize_t) image->colors; i++)
8178 color.red=ScaleQuantumToShort(XRedGamma(image->colormap[i].red));
8179 color.green=ScaleQuantumToShort(XGreenGamma(image->colormap[i].green));
8180 color.blue=ScaleQuantumToShort(XBlueGamma(image->colormap[i].blue));
8181 if (visual_info->klass != PseudoColor)
8183 gray_value=(unsigned short) XPixelIntensity(&color);
8184 color.red=gray_value;
8185 color.green=gray_value;
8186 color.blue=gray_value;
8188 color.pixel=pixel->pixels[i];
8191 (void) XStoreColors(display,colormap,colors,(int) image->colors);
8202 Define Standard Colormap for TrueColor or DirectColor visual.
8204 number_colors=(unsigned int) ((map_info->red_max*map_info->red_mult)+
8205 (map_info->green_max*map_info->green_mult)+
8206 (map_info->blue_max*map_info->blue_mult)+1);
8207 linear_colormap=(number_colors > 4096) ||
8208 (((int) (map_info->red_max+1) == visual_info->colormap_size) &&
8209 ((int) (map_info->green_max+1) == visual_info->colormap_size) &&
8210 ((int) (map_info->blue_max+1) == visual_info->colormap_size)) ?
8211 MagickTrue : MagickFalse;
8212 if (linear_colormap != MagickFalse)
8213 number_colors=(size_t) visual_info->colormap_size;
8215 Allocate color array.
8217 colors=(XColor *) AcquireQuantumMemory(number_colors,sizeof(*colors));
8218 if (colors == (XColor *) NULL)
8219 ThrowXWindowFatalException(ResourceLimitFatalError,
8220 "UnableToCreateColormap",image->filename);
8222 Initialize linear color ramp.
8225 color.flags=(char) (DoRed | DoGreen | DoBlue);
8226 if (linear_colormap != MagickFalse)
8227 for (i=0; i < (ssize_t) number_colors; i++)
8229 color.blue=(unsigned short) 0;
8230 if (map_info->blue_max != 0)
8231 color.blue=(unsigned short) ((size_t)
8232 ((65535L*(i % map_info->green_mult))/map_info->blue_max));
8233 color.green=color.blue;
8234 color.red=color.blue;
8235 color.pixel=XStandardPixel(map_info,&color);
8239 for (i=0; i < (ssize_t) number_colors; i++)
8241 color.red=(unsigned short) 0;
8242 if (map_info->red_max != 0)
8243 color.red=(unsigned short) ((size_t)
8244 ((65535L*(i/map_info->red_mult))/map_info->red_max));
8245 color.green=(unsigned int) 0;
8246 if (map_info->green_max != 0)
8247 color.green=(unsigned short) ((size_t)
8248 ((65535L*((i/map_info->green_mult) % (map_info->green_max+1)))/
8249 map_info->green_max));
8250 color.blue=(unsigned short) 0;
8251 if (map_info->blue_max != 0)
8252 color.blue=(unsigned short) ((size_t)
8253 ((65535L*(i % map_info->green_mult))/map_info->blue_max));
8254 color.pixel=XStandardPixel(map_info,&color);
8257 if ((visual_info->klass == DirectColor) &&
8258 (colormap != XDefaultColormap(display,visual_info->screen)))
8259 (void) XStoreColors(display,colormap,colors,(int) number_colors);
8261 for (i=0; i < (ssize_t) number_colors; i++)
8262 (void) XAllocColor(display,colormap,&colors[i]);
8266 if ((visual_info->klass != DirectColor) &&
8267 (visual_info->klass != TrueColor))
8270 Set foreground, background, border, etc. pixels.
8272 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8273 &pixel->foreground_color);
8274 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8275 &pixel->background_color);
8276 if (pixel->background_color.pixel == pixel->foreground_color.pixel)
8279 Foreground and background colors must differ.
8281 pixel->background_color.red=(~pixel->foreground_color.red);
8282 pixel->background_color.green=
8283 (~pixel->foreground_color.green);
8284 pixel->background_color.blue=
8285 (~pixel->foreground_color.blue);
8286 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8287 &pixel->background_color);
8289 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8290 &pixel->border_color);
8291 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8292 &pixel->matte_color);
8293 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8294 &pixel->highlight_color);
8295 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8296 &pixel->shadow_color);
8297 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8298 &pixel->depth_color);
8299 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8300 &pixel->trough_color);
8301 for (i=0; i < MaxNumberPens; i++)
8303 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8304 &pixel->pen_colors[i]);
8305 pixel->pixels[image->colors+i]=pixel->pen_colors[i].pixel;
8307 pixel->colors=(ssize_t) (image->colors+MaxNumberPens);
8309 colors=(XColor *) RelinquishMagickMemory(colors);
8310 if (IsEventLogging())
8312 (void) LogMagickEvent(X11Event,GetMagickModule(),"Standard Colormap:");
8313 (void) LogMagickEvent(X11Event,GetMagickModule()," colormap id: 0x%lx",
8314 map_info->colormap);
8315 (void) LogMagickEvent(X11Event,GetMagickModule(),
8316 " red, green, blue max: %lu %lu %lu",map_info->red_max,
8317 map_info->green_max,map_info->blue_max);
8318 (void) LogMagickEvent(X11Event,GetMagickModule(),
8319 " red, green, blue mult: %lu %lu %lu",map_info->red_mult,
8320 map_info->green_mult,map_info->blue_mult);
8325 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8329 % X M a k e W i n d o w %
8333 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8335 % XMakeWindow() creates an X11 window.
8337 % The format of the XMakeWindow method is:
8339 % void XMakeWindow(Display *display,Window parent,char **argv,int argc,
8340 % XClassHint *class_hint,XWMHints *manager_hints,
8341 % XWindowInfo *window_info)
8343 % A description of each parameter follows:
8345 % o display: Specifies a connection to an X server; returned from
8348 % o parent: Specifies the parent window_info.
8350 % o argv: Specifies the application's argument list.
8352 % o argc: Specifies the number of arguments.
8354 % o class_hint: Specifies a pointer to a X11 XClassHint structure.
8356 % o manager_hints: Specifies a pointer to a X11 XWMHints structure.
8358 % o window_info: Specifies a pointer to a X11 XWindowInfo structure.
8361 MagickPrivate void XMakeWindow(Display *display,Window parent,char **argv,
8362 int argc,XClassHint *class_hint,XWMHints *manager_hints,
8363 XWindowInfo *window_info)
8365 #define MinWindowSize 64
8373 static XTextProperty
8384 Set window info hints.
8386 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
8387 assert(display != (Display *) NULL);
8388 assert(window_info != (XWindowInfo *) NULL);
8389 size_hints=XAllocSizeHints();
8390 if (size_hints == (XSizeHints *) NULL)
8391 ThrowXWindowFatalException(XServerFatalError,"UnableToMakeXWindow",argv[0]);
8392 size_hints->flags=(int) window_info->flags;
8393 size_hints->x=window_info->x;
8394 size_hints->y=window_info->y;
8395 size_hints->width=(int) window_info->width;
8396 size_hints->height=(int) window_info->height;
8397 if (window_info->immutable != MagickFalse)
8400 Window size cannot be changed.
8402 size_hints->min_width=size_hints->width;
8403 size_hints->min_height=size_hints->height;
8404 size_hints->max_width=size_hints->width;
8405 size_hints->max_height=size_hints->height;
8406 size_hints->flags|=PMinSize;
8407 size_hints->flags|=PMaxSize;
8412 Window size can be changed.
8414 size_hints->min_width=(int) window_info->min_width;
8415 size_hints->min_height=(int) window_info->min_height;
8416 size_hints->flags|=PResizeInc;
8417 size_hints->width_inc=(int) window_info->width_inc;
8418 size_hints->height_inc=(int) window_info->height_inc;
8419 #if !defined(PRE_R4_ICCCM)
8420 size_hints->flags|=PBaseSize;
8421 size_hints->base_width=size_hints->width_inc;
8422 size_hints->base_height=size_hints->height_inc;
8425 gravity=NorthWestGravity;
8426 if (window_info->geometry != (char *) NULL)
8429 default_geometry[MaxTextExtent],
8430 geometry[MaxTextExtent];
8439 User specified geometry.
8441 (void) FormatLocaleString(default_geometry,MaxTextExtent,"%dx%d",
8442 size_hints->width,size_hints->height);
8443 (void) CopyMagickString(geometry,window_info->geometry,MaxTextExtent);
8445 while (strlen(p) != 0)
8447 if ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '%'))
8450 (void) CopyMagickString(p,p+1,MaxTextExtent);
8452 flags=XWMGeometry(display,window_info->screen,geometry,default_geometry,
8453 window_info->border_width,size_hints,&size_hints->x,&size_hints->y,
8454 &size_hints->width,&size_hints->height,&gravity);
8455 if ((flags & WidthValue) && (flags & HeightValue))
8456 size_hints->flags|=USSize;
8457 if ((flags & XValue) && (flags & YValue))
8459 size_hints->flags|=USPosition;
8460 window_info->x=size_hints->x;
8461 window_info->y=size_hints->y;
8464 #if !defined(PRE_R4_ICCCM)
8465 size_hints->win_gravity=gravity;
8466 size_hints->flags|=PWinGravity;
8468 if (window_info->id == (Window) NULL)
8469 window_info->id=XCreateWindow(display,parent,window_info->x,window_info->y,
8470 (unsigned int) size_hints->width,(unsigned int) size_hints->height,
8471 window_info->border_width,(int) window_info->depth,InputOutput,
8472 window_info->visual,(unsigned long) window_info->mask,
8473 &window_info->attributes);
8486 Window already exists; change relevant attributes.
8488 (void) XChangeWindowAttributes(display,window_info->id,(unsigned long)
8489 window_info->mask,&window_info->attributes);
8490 mask=ConfigureNotify;
8491 while (XCheckTypedWindowEvent(display,window_info->id,(int) mask,&sans_event)) ;
8492 window_changes.x=window_info->x;
8493 window_changes.y=window_info->y;
8494 window_changes.width=(int) window_info->width;
8495 window_changes.height=(int) window_info->height;
8496 mask=(MagickStatusType) (CWWidth | CWHeight);
8497 if (window_info->flags & USPosition)
8499 (void) XReconfigureWMWindow(display,window_info->id,window_info->screen,
8500 mask,&window_changes);
8502 if (window_info->id == (Window) NULL)
8503 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateWindow",
8505 status=XStringListToTextProperty(&window_info->name,1,&window_name);
8506 if (status == False)
8507 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateTextProperty",
8509 status=XStringListToTextProperty(&window_info->icon_name,1,&icon_name);
8510 if (status == False)
8511 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateTextProperty",
8512 window_info->icon_name);
8513 if (window_info->icon_geometry != (char *) NULL)
8521 User specified icon geometry.
8523 size_hints->flags|=USPosition;
8524 flags=XWMGeometry(display,window_info->screen,window_info->icon_geometry,
8525 (char *) NULL,0,size_hints,&manager_hints->icon_x,
8526 &manager_hints->icon_y,&width,&height,&gravity);
8527 if ((flags & XValue) && (flags & YValue))
8528 manager_hints->flags|=IconPositionHint;
8530 XSetWMProperties(display,window_info->id,&window_name,&icon_name,argv,argc,
8531 size_hints,manager_hints,class_hint);
8532 if (window_name.value != (void *) NULL)
8534 (void) XFree((void *) window_name.value);
8535 window_name.value=(unsigned char *) NULL;
8536 window_name.nitems=0;
8538 if (icon_name.value != (void *) NULL)
8540 (void) XFree((void *) icon_name.value);
8541 icon_name.value=(unsigned char *) NULL;
8544 atom_list[0]=XInternAtom(display,"WM_DELETE_WINDOW",MagickFalse);
8545 atom_list[1]=XInternAtom(display,"WM_TAKE_FOCUS",MagickFalse);
8546 (void) XSetWMProtocols(display,window_info->id,atom_list,2);
8547 (void) XFree((void *) size_hints);
8548 if (window_info->shape != MagickFalse)
8550 #if defined(MAGICKCORE_HAVE_SHAPE)
8556 Can we apply a non-rectangular shaping mask?
8560 if (XShapeQueryExtension(display,&error_base,&event_base) == 0)
8561 window_info->shape=MagickFalse;
8563 window_info->shape=MagickFalse;
8566 if (window_info->shared_memory)
8568 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
8570 Can we use shared memory with this window?
8572 if (XShmQueryExtension(display) == 0)
8573 window_info->shared_memory=MagickFalse;
8575 window_info->shared_memory=MagickFalse;
8578 window_info->image=NewImageList();
8579 window_info->destroy=MagickFalse;
8583 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8587 % X M a g i c k P r o g r e s s M o n i t o r %
8591 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8593 % XMagickProgressMonitor() displays the progress a task is making in
8594 % completing a task.
8596 % The format of the XMagickProgressMonitor method is:
8598 % void XMagickProgressMonitor(const char *task,
8599 % const MagickOffsetType quantum,const MagickSizeType span,
8600 % void *client_data)
8602 % A description of each parameter follows:
8604 % o task: Identifies the task in progress.
8606 % o quantum: Specifies the quantum position within the span which represents
8607 % how much progress has been made in completing a task.
8609 % o span: Specifies the span relative to completing a task.
8611 % o client_data: Pointer to any client data.
8615 static const char *GetLocaleMonitorMessage(const char *text)
8618 message[MaxTextExtent],
8627 (void) CopyMagickMemory(tag,text,MaxTextExtent);
8629 if (p != (char *) NULL)
8631 (void) FormatLocaleString(message,MaxTextExtent,"Monitor/%s",tag);
8632 locale_message=GetLocaleMessage(message);
8633 if (locale_message == message)
8635 return(locale_message);
8638 MagickPrivate MagickBooleanType XMagickProgressMonitor(const char *tag,
8639 const MagickOffsetType quantum,const MagickSizeType span,
8640 void *magick_unused(client_data))
8645 windows=XSetWindows((XWindows *) ~0);
8646 if (windows == (XWindows *) NULL)
8648 if (windows->info.mapped != MagickFalse)
8649 XProgressMonitorWidget(windows->display,windows,
8650 GetLocaleMonitorMessage(tag),quantum,span);
8655 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8659 % X Q u e r y C o l o r D a t a b a s e %
8663 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8665 % XQueryColorCompliance() looks up a RGB values for a color given in the target
8668 % The format of the XQueryColorDatabase method is:
8670 % MagickBooleanType XQueryColorCompliance(const char *target,XColor *color)
8672 % A description of each parameter follows:
8674 % o target: Specifies the color to lookup in the X color database.
8676 % o color: A pointer to an PixelInfo structure. The RGB value of the target
8677 % color is returned as this value.
8680 MagickPrivate MagickBooleanType XQueryColorCompliance(const char *target,
8687 *display = (Display *) NULL;
8696 Initialize color return value.
8698 assert(color != (XColor *) NULL);
8702 color->flags=(char) (DoRed | DoGreen | DoBlue);
8703 if ((target == (char *) NULL) || (*target == '\0'))
8704 target="#ffffffffffff";
8706 Let the X server define the color for us.
8708 if (display == (Display *) NULL)
8709 display=XOpenDisplay((char *) NULL);
8710 if (display == (Display *) NULL)
8712 ThrowXWindowFatalException(XServerError,"ColorIsNotKnownToServer",target);
8713 return(MagickFalse);
8715 colormap=XDefaultColormap(display,XDefaultScreen(display));
8716 status=XParseColor(display,colormap,(char *) target,&xcolor);
8717 if (status == False)
8718 ThrowXWindowFatalException(XServerError,"ColorIsNotKnownToServer",target)
8721 color->red=xcolor.red;
8722 color->green=xcolor.green;
8723 color->blue=xcolor.blue;
8724 color->flags=xcolor.flags;
8726 return(status != False ? MagickTrue : MagickFalse);
8730 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8734 % X Q u e r y P o s i t i o n %
8738 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8740 % XQueryPosition() gets the pointer coordinates relative to a window.
8742 % The format of the XQueryPosition method is:
8744 % void XQueryPosition(Display *display,const Window window,int *x,int *y)
8746 % A description of each parameter follows:
8748 % o display: Specifies a connection to an X server; returned from
8751 % o window: Specifies a pointer to a Window.
8753 % o x: Return the x coordinate of the pointer relative to the origin of the
8756 % o y: Return the y coordinate of the pointer relative to the origin of the
8760 MagickPrivate void XQueryPosition(Display *display,const Window window,int *x,int *y)
8772 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
8773 assert(display != (Display *) NULL);
8774 assert(window != (Window) NULL);
8775 assert(x != (int *) NULL);
8776 assert(y != (int *) NULL);
8777 (void) XQueryPointer(display,window,&root_window,&root_window,&x_root,&y_root,
8782 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8786 % X R e f r e s h W i n d o w %
8790 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8792 % XRefreshWindow() refreshes an image in a X window.
8794 % The format of the XRefreshWindow method is:
8796 % void XRefreshWindow(Display *display,const XWindowInfo *window,
8797 % const XEvent *event)
8799 % A description of each parameter follows:
8801 % o display: Specifies a connection to an X server; returned from
8804 % o window: Specifies a pointer to a XWindowInfo structure.
8806 % o event: Specifies a pointer to a XEvent structure. If it is NULL,
8807 % the entire image is refreshed.
8810 MagickPrivate void XRefreshWindow(Display *display,const XWindowInfo *window,
8811 const XEvent *event)
8821 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
8822 assert(display != (Display *) NULL);
8823 assert(window != (XWindowInfo *) NULL);
8824 if (window->ximage == (XImage *) NULL)
8826 if (event != (XEvent *) NULL)
8829 Determine geometry from expose event.
8833 width=(unsigned int) event->xexpose.width;
8834 height=(unsigned int) event->xexpose.height;
8842 Refresh entire window; discard outstanding expose events.
8846 width=window->width;
8847 height=window->height;
8848 while (XCheckTypedWindowEvent(display,window->id,Expose,&sans_event)) ;
8849 if (window->matte_pixmap != (Pixmap) NULL)
8851 #if defined(MAGICKCORE_HAVE_SHAPE)
8852 if (window->shape != MagickFalse)
8853 XShapeCombineMask(display,window->id,ShapeBounding,0,0,
8854 window->matte_pixmap,ShapeSet);
8859 Check boundary conditions.
8861 if ((window->ximage->width-(x+window->x)) < (int) width)
8862 width=(unsigned int) (window->ximage->width-(x+window->x));
8863 if ((window->ximage->height-(y+window->y)) < (int) height)
8864 height=(unsigned int) (window->ximage->height-(y+window->y));
8868 if (window->matte_pixmap != (Pixmap) NULL)
8869 (void) XSetClipMask(display,window->annotate_context,window->matte_pixmap);
8870 if (window->pixmap != (Pixmap) NULL)
8872 if (window->depth > 1)
8873 (void) XCopyArea(display,window->pixmap,window->id,
8874 window->annotate_context,x+window->x,y+window->y,width,height,x,y);
8876 (void) XCopyPlane(display,window->pixmap,window->id,
8877 window->highlight_context,x+window->x,y+window->y,width,height,x,y,
8882 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
8883 if (window->shared_memory)
8884 (void) XShmPutImage(display,window->id,window->annotate_context,
8885 window->ximage,x+window->x,y+window->y,x,y,width,height,MagickTrue);
8887 if (window->shared_memory == MagickFalse)
8888 (void) XPutImage(display,window->id,window->annotate_context,
8889 window->ximage,x+window->x,y+window->y,x,y,width,height);
8891 if (window->matte_pixmap != (Pixmap) NULL)
8892 (void) XSetClipMask(display,window->annotate_context,None);
8893 (void) XFlush(display);
8897 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8901 % X R e m o t e C o m m a n d %
8905 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8907 % XRemoteCommand() forces a remote display(1) to display the specified
8910 % The format of the XRemoteCommand method is:
8912 % MagickBooleanType XRemoteCommand(Display *display,const char *window,
8913 % const char *filename)
8915 % A description of each parameter follows:
8917 % o display: Specifies a connection to an X server; returned from
8920 % o window: Specifies the name or id of an X window.
8922 % o filename: the name of the image filename to display.
8925 MagickExport MagickBooleanType XRemoteCommand(Display *display,
8926 const char *window,const char *filename)
8935 assert(filename != (char *) NULL);
8936 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
8937 if (display == (Display *) NULL)
8938 display=XOpenDisplay((char *) NULL);
8939 if (display == (Display *) NULL)
8941 ThrowXWindowException(XServerError,"UnableToOpenXServer",filename);
8942 return(MagickFalse);
8944 remote_atom=XInternAtom(display,"IM_PROTOCOLS",MagickFalse);
8945 remote_window=(Window) NULL;
8946 root_window=XRootWindow(display,XDefaultScreen(display));
8947 if (window != (char *) NULL)
8950 Search window hierarchy and identify any clients by name or ID.
8952 if (isdigit((unsigned char) *window) != 0)
8953 remote_window=XWindowByID(display,root_window,(Window)
8954 strtol((char *) window,(char **) NULL,0));
8955 if (remote_window == (Window) NULL)
8956 remote_window=XWindowByName(display,root_window,window);
8958 if (remote_window == (Window) NULL)
8959 remote_window=XWindowByProperty(display,root_window,remote_atom);
8960 if (remote_window == (Window) NULL)
8962 ThrowXWindowException(XServerError,"UnableToConnectToRemoteDisplay",
8964 return(MagickFalse);
8967 Send remote command.
8969 remote_atom=XInternAtom(display,"IM_REMOTE_COMMAND",MagickFalse);
8970 (void) XChangeProperty(display,remote_window,remote_atom,XA_STRING,8,
8971 PropModeReplace,(unsigned char *) filename,(int) strlen(filename));
8972 (void) XSync(display,MagickFalse);
8977 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8981 % X R e t a i n W i n d o w C o l o r s %
8985 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8987 % XRetainWindowColors() sets X11 color resources on a window. This preserves
8988 % the colors associated with an image displayed on the window.
8990 % The format of the XRetainWindowColors method is:
8992 % void XRetainWindowColors(Display *display,const Window window)
8994 % A description of each parameter follows:
8996 % o display: Specifies a connection to an X server; returned from
8999 % o window: Specifies a pointer to a XWindowInfo structure.
9002 MagickExport void XRetainWindowColors(Display *display,const Window window)
9011 Put property on the window.
9013 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
9014 assert(display != (Display *) NULL);
9015 assert(window != (Window) NULL);
9016 property=XInternAtom(display,"_XSETROOT_ID",MagickFalse);
9017 if (property == (Atom) NULL)
9019 ThrowXWindowFatalException(XServerError,"UnableToCreateProperty",
9023 pixmap=XCreatePixmap(display,window,1,1,1);
9024 if (pixmap == (Pixmap) NULL)
9026 ThrowXWindowFatalException(XServerError,"UnableToCreateBitmap","");
9029 (void) XChangeProperty(display,window,property,XA_PIXMAP,32,PropModeReplace,
9030 (unsigned char *) &pixmap,1);
9031 (void) XSetCloseDownMode(display,RetainPermanent);
9035 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9039 % X S e l e c t W i n d o w %
9043 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9045 % XSelectWindow() allows a user to select a window using the mouse. If the
9046 % mouse moves, a cropping rectangle is drawn and the extents of the rectangle
9047 % is returned in the crop_info structure.
9049 % The format of the XSelectWindow function is:
9051 % target_window=XSelectWindow(display,crop_info)
9053 % A description of each parameter follows:
9055 % o window: XSelectWindow returns the window id.
9057 % o display: Specifies a pointer to the Display structure; returned from
9060 % o crop_info: Specifies a pointer to a RectangleInfo structure. It
9061 % contains the extents of any cropping rectangle.
9064 static Window XSelectWindow(Display *display,RectangleInfo *crop_info)
9066 #define MinimumCropArea (unsigned int) 9
9093 Initialize graphic context.
9095 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
9096 assert(display != (Display *) NULL);
9097 assert(crop_info != (RectangleInfo *) NULL);
9098 root_window=XRootWindow(display,XDefaultScreen(display));
9099 context_values.background=XBlackPixel(display,XDefaultScreen(display));
9100 context_values.foreground=XWhitePixel(display,XDefaultScreen(display));
9101 context_values.function=GXinvert;
9102 context_values.plane_mask=
9103 context_values.background ^ context_values.foreground;
9104 context_values.subwindow_mode=IncludeInferiors;
9105 annotate_context=XCreateGC(display,root_window,(size_t) (GCBackground |
9106 GCForeground | GCFunction | GCSubwindowMode),&context_values);
9107 if (annotate_context == (GC) NULL)
9108 return(MagickFalse);
9110 Grab the pointer using target cursor.
9112 target_cursor=XMakeCursor(display,root_window,XDefaultColormap(display,
9113 XDefaultScreen(display)),(char * ) "white",(char * ) "black");
9114 status=XGrabPointer(display,root_window,MagickFalse,(unsigned int)
9115 (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask),GrabModeSync,
9116 GrabModeAsync,root_window,target_cursor,CurrentTime);
9117 if (status != GrabSuccess)
9119 ThrowXWindowFatalException(XServerError,"UnableToGrabMouse","");
9120 return((Window) NULL);
9126 crop_info->height=0;
9128 target_window=(Window) NULL;
9133 if ((crop_info->width*crop_info->height) >= MinimumCropArea)
9134 (void) XDrawRectangle(display,root_window,annotate_context,
9135 (int) crop_info->x,(int) crop_info->y,(unsigned int) crop_info->width-1,
9136 (unsigned int) crop_info->height-1);
9138 Allow another event.
9140 (void) XAllowEvents(display,SyncPointer,CurrentTime);
9141 (void) XWindowEvent(display,root_window,ButtonPressMask |
9142 ButtonReleaseMask | ButtonMotionMask,&event);
9143 if ((crop_info->width*crop_info->height) >= MinimumCropArea)
9144 (void) XDrawRectangle(display,root_window,annotate_context,
9145 (int) crop_info->x,(int) crop_info->y,(unsigned int) crop_info->width-1,
9146 (unsigned int) crop_info->height-1);
9151 target_window=XGetSubwindow(display,event.xbutton.subwindow,
9152 event.xbutton.x,event.xbutton.y);
9153 if (target_window == (Window) NULL)
9154 target_window=root_window;
9155 x_offset=event.xbutton.x_root;
9156 y_offset=event.xbutton.y_root;
9157 crop_info->x=(ssize_t) x_offset;
9158 crop_info->y=(ssize_t) y_offset;
9160 crop_info->height=0;
9172 Discard pending button motion events.
9174 while (XCheckMaskEvent(display,ButtonMotionMask,&event)) ;
9175 crop_info->x=(ssize_t) event.xmotion.x;
9176 crop_info->y=(ssize_t) event.xmotion.y;
9178 Check boundary conditions.
9180 if ((int) crop_info->x < x_offset)
9181 crop_info->width=(size_t) (x_offset-crop_info->x);
9184 crop_info->width=(size_t) (crop_info->x-x_offset);
9185 crop_info->x=(ssize_t) x_offset;
9187 if ((int) crop_info->y < y_offset)
9188 crop_info->height=(size_t) (y_offset-crop_info->y);
9191 crop_info->height=(size_t) (crop_info->y-y_offset);
9192 crop_info->y=(ssize_t) y_offset;
9198 } while ((target_window == (Window) NULL) || (presses > 0));
9199 (void) XUngrabPointer(display,CurrentTime);
9200 (void) XFreeCursor(display,target_cursor);
9201 (void) XFreeGC(display,annotate_context);
9202 if ((crop_info->width*crop_info->height) < MinimumCropArea)
9205 crop_info->height=0;
9207 if ((crop_info->width != 0) && (crop_info->height != 0))
9208 target_window=root_window;
9209 return(target_window);
9213 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9217 % X S e t C u r s o r S t a t e %
9221 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9223 % XSetCursorState() sets the cursor state to busy, otherwise the cursor are
9224 % reset to their default.
9226 % The format of the XXSetCursorState method is:
9228 % XSetCursorState(display,windows,const MagickStatusType state)
9230 % A description of each parameter follows:
9232 % o display: Specifies a connection to an X server; returned from
9235 % o windows: Specifies a pointer to a XWindows structure.
9237 % o state: An unsigned integer greater than 0 sets the cursor state
9238 % to busy, otherwise the cursor are reset to their default.
9241 MagickPrivate void XSetCursorState(Display *display,XWindows *windows,
9242 const MagickStatusType state)
9244 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
9245 assert(display != (Display *) NULL);
9246 assert(windows != (XWindows *) NULL);
9249 (void) XCheckDefineCursor(display,windows->image.id,
9250 windows->image.busy_cursor);
9251 (void) XCheckDefineCursor(display,windows->pan.id,
9252 windows->pan.busy_cursor);
9253 (void) XCheckDefineCursor(display,windows->magnify.id,
9254 windows->magnify.busy_cursor);
9255 (void) XCheckDefineCursor(display,windows->command.id,
9256 windows->command.busy_cursor);
9260 (void) XCheckDefineCursor(display,windows->image.id,
9261 windows->image.cursor);
9262 (void) XCheckDefineCursor(display,windows->pan.id,windows->pan.cursor);
9263 (void) XCheckDefineCursor(display,windows->magnify.id,
9264 windows->magnify.cursor);
9265 (void) XCheckDefineCursor(display,windows->command.id,
9266 windows->command.cursor);
9267 (void) XCheckDefineCursor(display,windows->command.id,
9268 windows->widget.cursor);
9269 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
9271 windows->info.mapped=MagickFalse;
9275 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9279 % X S e t W i n d o w s %
9283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9285 % XSetWindows() sets the X windows structure if the windows info is specified.
9286 % Otherwise the current windows structure is returned.
9288 % The format of the XSetWindows method is:
9290 % XWindows *XSetWindows(XWindows *windows_info)
9292 % A description of each parameter follows:
9294 % o windows_info: Initialize the Windows structure with this information.
9297 MagickPrivate XWindows *XSetWindows(XWindows *windows_info)
9300 *windows = (XWindows *) NULL;
9302 if (windows_info != (XWindows *) ~0)
9304 windows=(XWindows *) RelinquishMagickMemory(windows);
9305 windows=windows_info;
9310 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9314 % X U s e r P r e f e r e n c e s %
9318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9320 % XUserPreferences() saves the preferences in a configuration file in the
9321 % users' home directory.
9323 % The format of the XUserPreferences method is:
9325 % void XUserPreferences(XResourceInfo *resource_info)
9327 % A description of each parameter follows:
9329 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
9332 MagickPrivate void XUserPreferences(XResourceInfo *resource_info)
9334 #if defined(X11_PREFERENCES_PATH)
9336 cache[MaxTextExtent],
9337 filename[MaxTextExtent],
9338 specifier[MaxTextExtent];
9345 preferences_database;
9348 Save user preferences to the client configuration file.
9350 assert(resource_info != (XResourceInfo *) NULL);
9351 client_name=GetClientName();
9352 preferences_database=XrmGetStringDatabase("");
9353 (void) FormatLocaleString(specifier,MaxTextExtent,"%s.backdrop",client_name);
9354 value=resource_info->backdrop ? "True" : "False";
9355 XrmPutStringResource(&preferences_database,specifier,(char *) value);
9356 (void) FormatLocaleString(specifier,MaxTextExtent,"%s.colormap",client_name);
9357 value=resource_info->colormap == SharedColormap ? "Shared" : "Private";
9358 XrmPutStringResource(&preferences_database,specifier,(char *) value);
9359 (void) FormatLocaleString(specifier,MaxTextExtent,"%s.confirmExit",
9361 value=resource_info->confirm_exit ? "True" : "False";
9362 XrmPutStringResource(&preferences_database,specifier,(char *) value);
9363 (void) FormatLocaleString(specifier,MaxTextExtent,"%s.confirmEdit",
9365 value=resource_info->confirm_edit ? "True" : "False";
9366 XrmPutStringResource(&preferences_database,specifier,(char *) value);
9367 (void) FormatLocaleString(specifier,MaxTextExtent,"%s.displayWarnings",
9369 value=resource_info->display_warnings ? "True" : "False";
9370 XrmPutStringResource(&preferences_database,specifier,(char *) value);
9371 (void) FormatLocaleString(specifier,MaxTextExtent,"%s.dither",client_name);
9372 value=resource_info->quantize_info->dither ? "True" : "False";
9373 XrmPutStringResource(&preferences_database,specifier,(char *) value);
9374 (void) FormatLocaleString(specifier,MaxTextExtent,"%s.gammaCorrect",
9376 value=resource_info->gamma_correct ? "True" : "False";
9377 XrmPutStringResource(&preferences_database,specifier,(char *) value);
9378 (void) FormatLocaleString(specifier,MaxTextExtent,"%s.undoCache",client_name);
9379 (void) FormatLocaleString(cache,MaxTextExtent,"%.20g",(double)
9380 resource_info->undo_cache);
9381 XrmPutStringResource(&preferences_database,specifier,cache);
9382 (void) FormatLocaleString(specifier,MaxTextExtent,"%s.usePixmap",client_name);
9383 value=resource_info->use_pixmap ? "True" : "False";
9384 XrmPutStringResource(&preferences_database,specifier,(char *) value);
9385 (void) FormatLocaleString(filename,MaxTextExtent,"%s%src",
9386 X11_PREFERENCES_PATH,client_name);
9387 ExpandFilename(filename);
9388 XrmPutFileDatabase(preferences_database,filename);
9393 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9397 % X V i s u a l C l a s s N a m e %
9401 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9403 % XVisualClassName() returns the visual class name as a character string.
9405 % The format of the XVisualClassName method is:
9407 % char *XVisualClassName(const int visual_class)
9409 % A description of each parameter follows:
9411 % o visual_type: XVisualClassName returns the visual class as a character
9414 % o class: Specifies the visual class.
9417 static const char *XVisualClassName(const int visual_class)
9419 switch (visual_class)
9421 case StaticGray: return("StaticGray");
9422 case GrayScale: return("GrayScale");
9423 case StaticColor: return("StaticColor");
9424 case PseudoColor: return("PseudoColor");
9425 case TrueColor: return("TrueColor");
9426 case DirectColor: return("DirectColor");
9428 return("unknown visual class");
9432 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9440 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9442 % XWarning() displays a warning reason in a Notice widget.
9444 % The format of the XWarning method is:
9446 % void XWarning(const unsigned int warning,const char *reason,
9447 % const char *description)
9449 % A description of each parameter follows:
9451 % o warning: Specifies the numeric warning category.
9453 % o reason: Specifies the reason to display before terminating the
9456 % o description: Specifies any description to the reason.
9459 MagickPrivate void XWarning(const ExceptionType magick_unused(warning),
9460 const char *reason,const char *description)
9463 text[MaxTextExtent];
9468 if (reason == (char *) NULL)
9470 (void) CopyMagickString(text,reason,MaxTextExtent);
9471 (void) ConcatenateMagickString(text,":",MaxTextExtent);
9472 windows=XSetWindows((XWindows *) ~0);
9473 XNoticeWidget(windows->display,windows,text,(char *) description);
9477 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9481 % X W i n d o w B y I D %
9485 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9487 % XWindowByID() locates a child window with a given ID. If not window with
9488 % the given name is found, 0 is returned. Only the window specified and its
9489 % subwindows are searched.
9491 % The format of the XWindowByID function is:
9493 % child=XWindowByID(display,window,id)
9495 % A description of each parameter follows:
9497 % o child: XWindowByID returns the window with the specified
9498 % id. If no windows are found, XWindowByID returns 0.
9500 % o display: Specifies a pointer to the Display structure; returned from
9503 % o id: Specifies the id of the window to locate.
9506 MagickPrivate Window XWindowByID(Display *display,const Window root_window,
9526 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
9527 assert(display != (Display *) NULL);
9528 assert(root_window != (Window) NULL);
9530 return(XSelectWindow(display,&rectangle_info));
9531 if (root_window == id)
9532 return(root_window);
9533 status=XQueryTree(display,root_window,&child,&child,&children,
9535 if (status == False)
9536 return((Window) NULL);
9537 window=(Window) NULL;
9538 for (i=0; i < (int) number_children; i++)
9541 Search each child and their children.
9543 window=XWindowByID(display,children[i],id);
9544 if (window != (Window) NULL)
9547 if (children != (Window *) NULL)
9548 (void) XFree((void *) children);
9553 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9557 % X W i n d o w B y N a m e %
9561 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9563 % XWindowByName() locates a window with a given name on a display. If no
9564 % window with the given name is found, 0 is returned. If more than one window
9565 % has the given name, the first one is returned. Only root and its children
9568 % The format of the XWindowByName function is:
9570 % window=XWindowByName(display,root_window,name)
9572 % A description of each parameter follows:
9574 % o window: XWindowByName returns the window id.
9576 % o display: Specifies a pointer to the Display structure; returned from
9579 % o root_window: Specifies the id of the root window.
9581 % o name: Specifies the name of the window to locate.
9584 MagickPrivate Window XWindowByName(Display *display,const Window root_window,
9604 assert(display != (Display *) NULL);
9605 assert(root_window != (Window) NULL);
9606 assert(name != (char *) NULL);
9607 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
9608 if (XGetWMName(display,root_window,&window_name) != 0)
9609 if (LocaleCompare((char *) window_name.value,name) == 0)
9610 return(root_window);
9611 status=XQueryTree(display,root_window,&child,&child,&children,
9613 if (status == False)
9614 return((Window) NULL);
9615 window=(Window) NULL;
9616 for (i=0; i < (int) number_children; i++)
9619 Search each child and their children.
9621 window=XWindowByName(display,children[i],name);
9622 if (window != (Window) NULL)
9625 if (children != (Window *) NULL)
9626 (void) XFree((void *) children);
9631 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9635 % X W i n d o w B y P r o p e r y %
9639 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9641 % XWindowByProperty() locates a child window with a given property. If not
9642 % window with the given name is found, 0 is returned. If more than one window
9643 % has the given property, the first one is returned. Only the window
9644 % specified and its subwindows are searched.
9646 % The format of the XWindowByProperty function is:
9648 % child=XWindowByProperty(display,window,property)
9650 % A description of each parameter follows:
9652 % o child: XWindowByProperty returns the window id with the specified
9653 % property. If no windows are found, XWindowByProperty returns 0.
9655 % o display: Specifies a pointer to the Display structure; returned from
9658 % o property: Specifies the property of the window to locate.
9661 MagickPrivate Window XWindowByProperty(Display *display,const Window window,
9662 const Atom property)
9690 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
9691 assert(display != (Display *) NULL);
9692 assert(window != (Window) NULL);
9693 assert(property != (Atom) NULL);
9694 status=XQueryTree(display,window,&root,&parent,&children,&number_children);
9695 if (status == False)
9696 return((Window) NULL);
9698 child=(Window) NULL;
9699 for (i=0; (i < number_children) && (child == (Window) NULL); i++)
9701 status=XGetWindowProperty(display,children[i],property,0L,0L,MagickFalse,
9702 (Atom) AnyPropertyType,&type,&format,&number_items,&after,&data);
9704 (void) XFree((void *) data);
9705 if ((status == Success) && (type != (Atom) NULL))
9708 for (i=0; (i < number_children) && (child == (Window) NULL); i++)
9709 child=XWindowByProperty(display,children[i],property);
9710 if (children != (Window *) NULL)
9711 (void) XFree((void *) children);
9717 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9721 % X I m p o r t I m a g e %
9725 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9727 % XImportImage() reads an image from an X window.
9729 % The format of the XImportImage method is:
9731 % Image *XImportImage(const ImageInfo *image_info,XImportInfo *ximage_info,
9732 % ExceptionInfo *exception)
9734 % A description of each parameter follows:
9736 % o image_info: the image info..
9738 % o ximage_info: Specifies a pointer to an XImportInfo structure.
9740 % o exception: return any errors or warnings in this structure.
9743 MagickPrivate Image *XImportImage(const ImageInfo *image_info,
9744 XImportInfo *ximage_info,ExceptionInfo *exception)
9746 assert(image_info != (const ImageInfo *) NULL);
9747 assert(image_info->signature == MagickSignature);
9748 if (image_info->debug != MagickFalse)
9749 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
9750 image_info->filename);
9751 assert(ximage_info != (XImportInfo *) NULL);
9752 assert(exception != (ExceptionInfo *) NULL);
9753 assert(exception->signature == MagickSignature);
9754 return((Image *) NULL);
9759 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9763 + X C o m p o n e n t G e n e s i s %
9767 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9769 % XComponentGenesis() instantiates the X component.
9771 % The format of the XComponentGenesis method is:
9773 % MagickBooleanType XComponentGenesis(void)
9776 MagickPrivate MagickBooleanType XComponentGenesis(void)
9782 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9786 % X G e t I m p o r t I n f o %
9790 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9792 % XGetImportInfo() initializes the XImportInfo structure.
9794 % The format of the XGetImportInfo method is:
9796 % void XGetImportInfo(XImportInfo *ximage_info)
9798 % A description of each parameter follows:
9800 % o ximage_info: Specifies a pointer to an ImageInfo structure.
9803 MagickExport void XGetImportInfo(XImportInfo *ximage_info)
9805 assert(ximage_info != (XImportInfo *) NULL);
9806 ximage_info->frame=MagickFalse;
9807 ximage_info->borders=MagickFalse;
9808 ximage_info->screen=MagickFalse;
9809 ximage_info->descend=MagickTrue;
9810 ximage_info->silent=MagickFalse;