2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 % X X W W IIIII N N DDDD OOO W W %
7 % X X W W I NN N D D O O W W %
8 % X W W I N N N D D O O W W %
9 % X X W W W I N NN D D O O W W W %
10 % X X W W IIIII N N DDDD OOO W W %
13 % MagickCore X11 Utility Methods %
20 % Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42 #include "MagickCore/studio.h"
43 #include "MagickCore/animate.h"
44 #include "MagickCore/artifact.h"
45 #include "MagickCore/blob.h"
46 #include "MagickCore/cache.h"
47 #include "MagickCore/client.h"
48 #include "MagickCore/color.h"
49 #include "MagickCore/color-private.h"
50 #include "MagickCore/colormap.h"
51 #include "MagickCore/composite.h"
52 #include "MagickCore/display.h"
53 #include "MagickCore/exception.h"
54 #include "MagickCore/exception-private.h"
55 #include "MagickCore/geometry.h"
56 #include "MagickCore/identify.h"
57 #include "MagickCore/image.h"
58 #include "MagickCore/image-private.h"
59 #include "MagickCore/list.h"
60 #include "MagickCore/locale_.h"
61 #include "MagickCore/log.h"
62 #include "MagickCore/magick.h"
63 #include "MagickCore/memory_.h"
64 #include "MagickCore/monitor.h"
65 #include "MagickCore/option.h"
66 #include "MagickCore/pixel-accessor.h"
67 #include "MagickCore/PreRvIcccm.h"
68 #include "MagickCore/quantize.h"
69 #include "MagickCore/quantum.h"
70 #include "MagickCore/quantum-private.h"
71 #include "MagickCore/resource_.h"
72 #include "MagickCore/resize.h"
73 #include "MagickCore/shear.h"
74 #include "MagickCore/statistic.h"
75 #include "MagickCore/string_.h"
76 #include "MagickCore/string-private.h"
77 #include "MagickCore/transform.h"
78 #include "MagickCore/utility.h"
79 #include "MagickCore/widget.h"
80 #include "MagickCore/xwindow.h"
81 #include "MagickCore/xwindow-private.h"
82 #include "MagickCore/version.h"
86 #if defined(MAGICKCORE_X11_DELEGATE)
87 #include <X11/Xproto.h>
88 #include <X11/Xlocale.h>
89 #if defined(MAGICK_HAVE_POLL)
90 # include <sys/poll.h>
92 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
93 #if defined(MAGICKCORE_HAVE_MACHINE_PARAM_H)
94 # include <machine/param.h>
98 #include <X11/extensions/XShm.h>
100 #if defined(MAGICKCORE_HAVE_SHAPE)
101 #include <X11/extensions/shape.h>
107 #define XBlueGamma(color) ClampToQuantum(blue_gamma == 1.0 ? (double) \
108 (color) : ((pow(((double) QuantumScale*(color)),1.0/(double) blue_gamma)* \
110 #define XGammaPacket(map,color) (size_t) (map->base_pixel+ \
111 ((ScaleQuantumToShort(XRedGamma((color)->red))*map->red_max/65535L)* \
113 ((ScaleQuantumToShort(XGreenGamma((color)->green))*map->green_max/65535L)* \
115 ((ScaleQuantumToShort(XBlueGamma((color)->blue))*map->blue_max/65535L)* \
117 #define XGammaPixel(image,map,color) (size_t) (map->base_pixel+ \
118 ((ScaleQuantumToShort(XRedGamma(GetPixelRed(image,color)))*map->red_max/65535L)* \
120 ((ScaleQuantumToShort(XGreenGamma(GetPixelGreen(image,color)))*map->green_max/65535L)* \
122 ((ScaleQuantumToShort(XBlueGamma(GetPixelBlue(image,color)))*map->blue_max/65535L)* \
124 #define XGreenGamma(color) ClampToQuantum(green_gamma == 1.0 ? (double) \
125 (color) : ((pow(((double) QuantumScale*(color)),1.0/(double) green_gamma)* \
127 #define XRedGamma(color) ClampToQuantum(red_gamma == 1.0 ? (double) \
128 (color) : ((pow(((double) QuantumScale*(color)),1.0/(double) red_gamma)* \
130 #define XStandardPixel(map,color) (size_t) (map->base_pixel+ \
131 (((color)->red*map->red_max/65535L)*map->red_mult)+ \
132 (((color)->green*map->green_max/65535L)*map->green_mult)+ \
133 (((color)->blue*map->blue_max/65535L)*map->blue_mult))
135 #define AccentuateModulate ScaleCharToQuantum(80)
136 #define HighlightModulate ScaleCharToQuantum(125)
137 #define ShadowModulate ScaleCharToQuantum(135)
138 #define DepthModulate ScaleCharToQuantum(185)
139 #define TroughModulate ScaleCharToQuantum(110)
141 #define XLIB_ILLEGAL_ACCESS 1
143 #undef NorthWestGravity
145 #undef NorthEastGravity
149 #undef SouthWestGravity
151 #undef SouthEastGravity
158 #define XFD_SET fd_set
162 Enumeration declarations.
176 Typedef declarations.
178 typedef struct _DiversityPacket
193 Constant declaractions.
195 static MagickBooleanType
196 xerror_alert = MagickFalse;
202 *XVisualClassName(const int);
204 static MagickRealType
209 static MagickBooleanType
210 XMakePixmap(Display *,const XResourceInfo *,XWindowInfo *);
213 XMakeImageLSBFirst(const XResourceInfo *,const XWindowInfo *,Image *,
215 XMakeImageMSBFirst(const XResourceInfo *,const XWindowInfo *,Image *,
219 XSelectWindow(Display *,RectangleInfo *);
222 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
226 % D e s t r o y X R e s o u r c e s %
230 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
232 % DestroyXResources() destroys any X resources.
234 % The format of the DestroyXResources method is:
236 % void DestroyXResources()
238 % A description of each parameter follows:
241 MagickExport void DestroyXResources(void)
250 *magick_windows[MaxXWindows];
256 windows=XSetWindows((XWindows *) ~0);
257 if ((windows == (XWindows *) NULL) || (windows->display == (Display *) NULL))
260 magick_windows[number_windows++]=(&windows->context);
261 magick_windows[number_windows++]=(&windows->group_leader);
262 magick_windows[number_windows++]=(&windows->backdrop);
263 magick_windows[number_windows++]=(&windows->icon);
264 magick_windows[number_windows++]=(&windows->image);
265 magick_windows[number_windows++]=(&windows->info);
266 magick_windows[number_windows++]=(&windows->magnify);
267 magick_windows[number_windows++]=(&windows->pan);
268 magick_windows[number_windows++]=(&windows->command);
269 magick_windows[number_windows++]=(&windows->widget);
270 magick_windows[number_windows++]=(&windows->popup);
271 magick_windows[number_windows++]=(&windows->context);
272 for (i=0; i < (int) number_windows; i++)
274 if (magick_windows[i]->mapped != MagickFalse)
276 (void) XWithdrawWindow(windows->display,magick_windows[i]->id,
277 magick_windows[i]->screen);
278 magick_windows[i]->mapped=MagickFalse;
280 if (magick_windows[i]->name != (char *) NULL)
281 magick_windows[i]->name=(char *)
282 RelinquishMagickMemory(magick_windows[i]->name);
283 if (magick_windows[i]->icon_name != (char *) NULL)
284 magick_windows[i]->icon_name=(char *)
285 RelinquishMagickMemory(magick_windows[i]->icon_name);
286 if (magick_windows[i]->cursor != (Cursor) NULL)
288 (void) XFreeCursor(windows->display,magick_windows[i]->cursor);
289 magick_windows[i]->cursor=(Cursor) NULL;
291 if (magick_windows[i]->busy_cursor != (Cursor) NULL)
293 (void) XFreeCursor(windows->display,magick_windows[i]->busy_cursor);
294 magick_windows[i]->busy_cursor=(Cursor) NULL;
296 if (magick_windows[i]->highlight_stipple != (Pixmap) NULL)
298 (void) XFreePixmap(windows->display,
299 magick_windows[i]->highlight_stipple);
300 magick_windows[i]->highlight_stipple=(Pixmap) NULL;
302 if (magick_windows[i]->shadow_stipple != (Pixmap) NULL)
304 (void) XFreePixmap(windows->display,magick_windows[i]->shadow_stipple);
305 magick_windows[i]->shadow_stipple=(Pixmap) NULL;
307 if (magick_windows[i]->ximage != (XImage *) NULL)
309 XDestroyImage(magick_windows[i]->ximage);
310 magick_windows[i]->ximage=(XImage *) NULL;
312 if (magick_windows[i]->pixmap != (Pixmap) NULL)
314 (void) XFreePixmap(windows->display,magick_windows[i]->pixmap);
315 magick_windows[i]->pixmap=(Pixmap) NULL;
317 if (magick_windows[i]->id != (Window) NULL)
319 (void) XDestroyWindow(windows->display,magick_windows[i]->id);
320 magick_windows[i]->id=(Window) NULL;
322 if (magick_windows[i]->destroy != MagickFalse)
324 if (magick_windows[i]->image != (Image *) NULL)
326 magick_windows[i]->image=DestroyImage(magick_windows[i]->image);
327 magick_windows[i]->image=NewImageList();
329 if (magick_windows[i]->matte_pixmap != (Pixmap) NULL)
331 (void) XFreePixmap(windows->display,
332 magick_windows[i]->matte_pixmap);
333 magick_windows[i]->matte_pixmap=(Pixmap) NULL;
336 if (magick_windows[i]->segment_info != (void *) NULL)
338 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
342 segment_info=(XShmSegmentInfo *) magick_windows[i]->segment_info;
343 if (segment_info != (XShmSegmentInfo *) NULL)
344 if (segment_info[0].shmid >= 0)
346 if (segment_info[0].shmaddr != NULL)
347 (void) shmdt(segment_info[0].shmaddr);
348 (void) shmctl(segment_info[0].shmid,IPC_RMID,0);
349 segment_info[0].shmaddr=NULL;
350 segment_info[0].shmid=(-1);
353 magick_windows[i]->segment_info=(void *)
354 RelinquishMagickMemory(magick_windows[i]->segment_info);
357 windows->icon_resources=(XResourceInfo *)
358 RelinquishMagickMemory(windows->icon_resources);
359 if (windows->icon_pixel != (XPixelInfo *) NULL)
361 if (windows->icon_pixel->pixels != (unsigned long *) NULL)
362 windows->icon_pixel->pixels=(unsigned long *)
363 RelinquishMagickMemory(windows->icon_pixel->pixels);
364 if (windows->icon_pixel->annotate_context != (GC) NULL)
365 XFreeGC(windows->display,windows->icon_pixel->annotate_context);
366 windows->icon_pixel=(XPixelInfo *)
367 RelinquishMagickMemory(windows->icon_pixel);
369 if (windows->pixel_info != (XPixelInfo *) NULL)
371 if (windows->pixel_info->pixels != (unsigned long *) NULL)
372 windows->pixel_info->pixels=(unsigned long *)
373 RelinquishMagickMemory(windows->pixel_info->pixels);
374 if (windows->pixel_info->annotate_context != (GC) NULL)
375 XFreeGC(windows->display,windows->pixel_info->annotate_context);
376 if (windows->pixel_info->widget_context != (GC) NULL)
377 XFreeGC(windows->display,windows->pixel_info->widget_context);
378 if (windows->pixel_info->highlight_context != (GC) NULL)
379 XFreeGC(windows->display,windows->pixel_info->highlight_context);
380 windows->pixel_info=(XPixelInfo *)
381 RelinquishMagickMemory(windows->pixel_info);
383 if (windows->font_info != (XFontStruct *) NULL)
385 XFreeFont(windows->display,windows->font_info);
386 windows->font_info=(XFontStruct *) NULL;
388 if (windows->class_hints != (XClassHint *) NULL)
390 if (windows->class_hints->res_name != (char *) NULL)
391 XFree(windows->class_hints->res_name);
392 if (windows->class_hints->res_class != (char *) NULL)
393 XFree(windows->class_hints->res_class);
394 XFree(windows->class_hints);
395 windows->class_hints=(XClassHint *) NULL;
397 if (windows->manager_hints != (XWMHints *) NULL)
399 XFree(windows->manager_hints);
400 windows->manager_hints=(XWMHints *) NULL;
402 if (windows->map_info != (XStandardColormap *) NULL)
404 XFree(windows->map_info);
405 windows->map_info=(XStandardColormap *) NULL;
407 if (windows->icon_map != (XStandardColormap *) NULL)
409 XFree(windows->icon_map);
410 windows->icon_map=(XStandardColormap *) NULL;
412 if (windows->visual_info != (XVisualInfo *) NULL)
414 XFree(windows->visual_info);
415 windows->visual_info=(XVisualInfo *) NULL;
417 if (windows->icon_visual != (XVisualInfo *) NULL)
419 XFree(windows->icon_visual);
420 windows->icon_visual=(XVisualInfo *) NULL;
422 (void) XSetWindows((XWindows *) NULL);
426 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
430 % X A n n o t a t e I m a g e %
434 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
436 % XAnnotateImage() annotates the image with text.
438 % The format of the XAnnotateImage method is:
440 % MagickBooleanType XAnnotateImage(Display *display,
441 % const XPixelInfo *pixel,XAnnotateInfo *annotate_info,Image *image)
443 % A description of each parameter follows:
445 % o display: Specifies a connection to an X server; returned from
448 % o pixel: Specifies a pointer to a XPixelInfo structure.
450 % o annotate_info: Specifies a pointer to a XAnnotateInfo structure.
452 % o image: the image.
455 MagickExport MagickBooleanType XAnnotateImage(Display *display,
456 const XPixelInfo *pixel,XAnnotateInfo *annotate_info,Image *image)
495 Initialize annotated image.
497 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
498 assert(display != (Display *) NULL);
499 assert(pixel != (XPixelInfo *) NULL);
500 assert(annotate_info != (XAnnotateInfo *) NULL);
501 assert(image != (Image *) NULL);
503 Initialize annotated pixmap.
505 root_window=XRootWindow(display,XDefaultScreen(display));
506 depth=(unsigned int) XDefaultDepth(display,XDefaultScreen(display));
507 annotate_pixmap=XCreatePixmap(display,root_window,annotate_info->width,
508 annotate_info->height,depth);
509 if (annotate_pixmap == (Pixmap) NULL)
512 Initialize graphics info.
514 context_values.background=0;
515 context_values.foreground=(size_t) (~0);
516 context_values.font=annotate_info->font_info->fid;
517 annotate_context=XCreateGC(display,root_window,(unsigned long)
518 (GCBackground | GCFont | GCForeground),&context_values);
519 if (annotate_context == (GC) NULL)
524 (void) XDrawImageString(display,annotate_pixmap,annotate_context,0,
525 (int) annotate_info->font_info->ascent,annotate_info->text,
526 (int) strlen(annotate_info->text));
527 (void) XFreeGC(display,annotate_context);
529 Initialize annotated X image.
531 annotate_ximage=XGetImage(display,annotate_pixmap,0,0,annotate_info->width,
532 annotate_info->height,AllPlanes,ZPixmap);
533 if (annotate_ximage == (XImage *) NULL)
535 (void) XFreePixmap(display,annotate_pixmap);
537 Initialize annotated image.
539 annotate_image=AcquireImage((ImageInfo *) NULL);
540 if (annotate_image == (Image *) NULL)
542 annotate_image->columns=annotate_info->width;
543 annotate_image->rows=annotate_info->height;
545 Transfer annotated X image to image.
547 width=(unsigned int) image->columns;
548 height=(unsigned int) image->rows;
551 (void) XParseGeometry(annotate_info->geometry,&x,&y,&width,&height);
552 (void) GetOneVirtualPixel(image,(ssize_t) x,(ssize_t) y,
553 &annotate_image->background_color,&image->exception);
554 if (annotate_info->stencil == ForegroundStencil)
555 annotate_image->matte=MagickTrue;
556 exception=(&image->exception);
557 annotate_view=AcquireCacheView(annotate_image);
558 for (y=0; y < (int) annotate_image->rows; y++)
566 q=GetCacheViewAuthenticPixels(annotate_view,0,(ssize_t) y,
567 annotate_image->columns,1,exception);
568 if (q == (const Quantum *) NULL)
570 for (x=0; x < (int) annotate_image->columns; x++)
572 SetPixelAlpha(annotate_image,OpaqueAlpha,q);
573 if (XGetPixel(annotate_ximage,x,y) == 0)
576 Set this pixel to the background color.
578 SetPixelRed(annotate_image,ScaleShortToQuantum(
579 pixel->box_color.red),q);
580 SetPixelGreen(annotate_image,ScaleShortToQuantum(
581 pixel->box_color.green),q);
582 SetPixelBlue(annotate_image,ScaleShortToQuantum(
583 pixel->box_color.blue),q);
584 if ((annotate_info->stencil == ForegroundStencil) ||
585 (annotate_info->stencil == OpaqueStencil))
586 SetPixelAlpha(annotate_image,TransparentAlpha,q);
591 Set this pixel to the pen color.
593 SetPixelRed(annotate_image,ScaleShortToQuantum(
594 pixel->pen_color.red),q);
595 SetPixelGreen(annotate_image,ScaleShortToQuantum(
596 pixel->pen_color.green),q);
597 SetPixelBlue(annotate_image,ScaleShortToQuantum(
598 pixel->pen_color.blue),q);
599 if (annotate_info->stencil == BackgroundStencil)
600 SetPixelAlpha(annotate_image,TransparentAlpha,q);
602 q+=GetPixelChannels(annotate_image);
604 if (SyncCacheViewAuthenticPixels(annotate_view,exception) == MagickFalse)
607 annotate_view=DestroyCacheView(annotate_view);
608 XDestroyImage(annotate_ximage);
610 Determine annotate geometry.
612 (void) XParseGeometry(annotate_info->geometry,&x,&y,&width,&height);
613 if ((width != (unsigned int) annotate_image->columns) ||
614 (height != (unsigned int) annotate_image->rows))
617 image_geometry[MaxTextExtent];
622 (void) FormatLocaleString(image_geometry,MaxTextExtent,"%ux%u",
624 (void) TransformImage(&annotate_image,(char *) NULL,image_geometry);
626 if (annotate_info->degrees != 0.0)
641 RotateImage(annotate_image,annotate_info->degrees,&image->exception);
642 if (rotate_image == (Image *) NULL)
644 annotate_image=DestroyImage(annotate_image);
645 annotate_image=rotate_image;
647 Annotation is relative to the degree of rotation.
649 normalized_degrees=annotate_info->degrees;
650 while (normalized_degrees < -45.0)
651 normalized_degrees+=360.0;
652 for (rotations=0; normalized_degrees > 45.0; rotations++)
653 normalized_degrees-=90.0;
654 switch (rotations % 4)
664 x-=(int) annotate_image->columns/2;
665 y+=(int) annotate_image->columns/2;
673 x=x-(int) annotate_image->columns;
681 x=x-(int) annotate_image->columns/2;
682 y=y-(int) (annotate_image->rows-(annotate_image->columns/2));
688 Composite text onto the image.
690 (void) XParseGeometry(annotate_info->geometry,&x,&y,&width,&height);
692 (void) CompositeImage(image,annotate_image->matte != MagickFalse ?
693 OverCompositeOp : CopyCompositeOp,annotate_image,(ssize_t) x,(ssize_t) y);
695 annotate_image=DestroyImage(annotate_image);
700 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
704 % X B e s t F o n t %
708 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
710 % XBestFont() returns the "best" font. "Best" is defined as a font specified
711 % in the X resource database or a font such that the text width displayed
712 % with the font does not exceed the specified maximum width.
714 % The format of the XBestFont method is:
716 % XFontStruct *XBestFont(Display *display,
717 % const XResourceInfo *resource_info,const MagickBooleanType text_font)
719 % A description of each parameter follows:
721 % o font: XBestFont returns a pointer to a XFontStruct structure.
723 % o display: Specifies a connection to an X server; returned from
726 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
728 % o text_font: True is font should be mono-spaced (typewriter style).
732 static char **FontToList(char *font)
747 if (font == (char *) NULL)
748 return((char **) NULL);
750 Convert string to an ASCII list.
753 for (p=font; *p != '\0'; p++)
754 if ((*p == ':') || (*p == ';') || (*p == ','))
756 fontlist=(char **) AcquireQuantumMemory((size_t) fonts+1UL,sizeof(*fontlist));
757 if (fontlist == (char **) NULL)
759 ThrowXWindowFatalException(ResourceLimitError,"MemoryAllocationFailed",
761 return((char **) NULL);
764 for (i=0; i < (int) fonts; i++)
766 for (q=p; *q != '\0'; q++)
767 if ((*q == ':') || (*q == ';') || (*q == ','))
769 fontlist[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+1UL,
770 sizeof(*fontlist[i]));
771 if (fontlist[i] == (char *) NULL)
773 ThrowXWindowFatalException(ResourceLimitError,"MemoryAllocationFailed",
775 return((char **) NULL);
777 (void) CopyMagickString(fontlist[i],p,(size_t) (q-p+1));
780 fontlist[i]=(char *) NULL;
784 MagickExport XFontStruct *XBestFont(Display *display,
785 const XResourceInfo *resource_info,const MagickBooleanType text_font)
790 "-*-helvetica-medium-r-normal--12-*-*-*-*-*-iso8859-1",
791 "-*-arial-medium-r-normal--12-*-*-*-*-*-iso8859-1",
792 "-*-helvetica-medium-r-normal--12-*-*-*-*-*-iso8859-15",
793 "-*-arial-medium-r-normal--12-*-*-*-*-*-iso8859-15",
794 "-*-helvetica-medium-r-normal--12-*-*-*-*-*-*-*",
795 "-*-arial-medium-r-normal--12-*-*-*-*-*-*-*",
802 "-*-courier-medium-r-normal-*-12-*-*-*-*-*-iso8859-1",
803 "-*-courier-medium-r-normal-*-12-*-*-*-*-*-iso8859-15",
804 "-*-fixed-medium-r-normal-*-12-*-*-*-*-*-*-*",
818 font_info=(XFontStruct *) NULL;
819 font_name=resource_info->font;
820 if (text_font != MagickFalse)
821 font_name=resource_info->text_font;
822 if ((font_name != (char *) NULL) && (*font_name != '\0'))
831 Load preferred font specified in the X resource database.
833 fontlist=FontToList(font_name);
834 if (fontlist != (char **) NULL)
836 for (i=0; fontlist[i] != (char *) NULL; i++)
838 if (font_info == (XFontStruct *) NULL)
839 font_info=XLoadQueryFont(display,fontlist[i]);
840 fontlist[i]=DestroyString(fontlist[i]);
842 fontlist=(char **) RelinquishMagickMemory(fontlist);
844 if (font_info == (XFontStruct *) NULL)
845 ThrowXWindowFatalException(XServerError,"UnableToLoadFont",font_name);
848 Load fonts from list of fonts until one is found.
851 if (text_font != MagickFalse)
853 if (XDisplayHeight(display,XDefaultScreen(display)) >= 748)
855 while (*p != (char *) NULL)
857 if (font_info != (XFontStruct *) NULL)
859 font_info=XLoadQueryFont(display,(char *) *p);
866 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
870 % X B e s t I c o n S i z e %
874 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
876 % XBestIconSize() returns the "best" icon size. "Best" is defined as an icon
877 % size that maintains the aspect ratio of the image. If the window manager
878 % has preferred icon sizes, one of the preferred sizes is used.
880 % The format of the XBestIconSize method is:
882 % void XBestIconSize(Display *display,XWindowInfo *window,Image *image)
884 % A description of each parameter follows:
886 % o display: Specifies a connection to an X server; returned from
889 % o image: the image.
892 MagickExport void XBestIconSize(Display *display,XWindowInfo *window,
916 Determine if the window manager has specified preferred icon sizes.
918 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
919 assert(display != (Display *) NULL);
920 assert(window != (XWindowInfo *) NULL);
921 assert(image != (Image *) NULL);
922 window->width=MaxIconSize;
923 window->height=MaxIconSize;
924 icon_size=(XIconSize *) NULL;
926 root_window=XRootWindow(display,window->screen);
927 if (XGetIconSizes(display,root_window,&size_list,&number_sizes) != 0)
928 if ((number_sizes > 0) && (size_list != (XIconSize *) NULL))
930 if (icon_size == (XIconSize *) NULL)
933 Window manager does not restrict icon size.
935 icon_size=XAllocIconSize();
936 if (icon_size == (XIconSize *) NULL)
938 ThrowXWindowFatalException(ResourceLimitError,
939 "MemoryAllocationFailed",image->filename);
942 icon_size->min_width=1;
943 icon_size->max_width=MaxIconSize;
944 icon_size->min_height=1;
945 icon_size->max_height=MaxIconSize;
946 icon_size->width_inc=1;
947 icon_size->height_inc=1;
950 Determine aspect ratio of image.
952 width=(unsigned int) image->columns;
953 height=(unsigned int) image->rows;
955 if (window->crop_geometry)
956 (void) XParseGeometry(window->crop_geometry,&i,&i,&width,&height);
958 Look for an icon size that maintains the aspect ratio of image.
960 scale_factor=(MagickRealType) icon_size->max_width/width;
961 if (scale_factor > ((MagickRealType) icon_size->max_height/height))
962 scale_factor=(MagickRealType) icon_size->max_height/height;
963 icon_width=(unsigned int) icon_size->min_width;
964 while ((int) icon_width < icon_size->max_width)
966 if (icon_width >= (unsigned int) (scale_factor*width+0.5))
968 icon_width+=icon_size->width_inc;
970 icon_height=(unsigned int) icon_size->min_height;
971 while ((int) icon_height < icon_size->max_height)
973 if (icon_height >= (unsigned int) (scale_factor*height+0.5))
975 icon_height+=icon_size->height_inc;
977 (void) XFree((void *) icon_size);
978 window->width=icon_width;
979 window->height=icon_height;
983 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
987 % X B e s t P i x e l %
991 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
993 % XBestPixel() returns a pixel from an array of pixels that is closest to the
994 % requested color. If the color array is NULL, the colors are obtained from
997 % The format of the XBestPixel method is:
999 % void XBestPixel(Display *display,const Colormap colormap,XColor *colors,
1000 % unsigned int number_colors,XColor *color)
1002 % A description of each parameter follows:
1004 % o pixel: XBestPixel returns the pixel value closest to the requested
1007 % o display: Specifies a connection to an X server; returned from
1010 % o colormap: Specifies the ID of the X server colormap.
1012 % o colors: Specifies an array of XColor structures.
1014 % o number_colors: Specifies the number of XColor structures in the
1015 % color definition array.
1017 % o color: Specifies the desired RGB value to find in the colors array.
1020 MagickExport void XBestPixel(Display *display,const Colormap colormap,
1021 XColor *colors,unsigned int number_colors,XColor *color)
1032 register MagickRealType
1043 Find closest representation for the requested RGB color.
1045 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1046 assert(display != (Display *) NULL);
1047 assert(color != (XColor *) NULL);
1048 status=XAllocColor(display,colormap,color);
1049 if (status != False)
1051 query_server=colors == (XColor *) NULL ? MagickTrue : MagickFalse;
1052 if (query_server != MagickFalse)
1055 Read X server colormap.
1057 colors=(XColor *) AcquireQuantumMemory(number_colors,sizeof(*colors));
1058 if (colors == (XColor *) NULL)
1060 ThrowXWindowFatalException(ResourceLimitError,
1061 "MemoryAllocationFailed","...");
1064 for (i=0; i < (int) number_colors; i++)
1065 colors[i].pixel=(size_t) i;
1066 if (number_colors > 256)
1068 (void) XQueryColors(display,colormap,colors,(int) number_colors);
1070 min_distance=3.0*((MagickRealType) QuantumRange+1.0)*((MagickRealType)
1073 for (i=0; i < (int) number_colors; i++)
1075 pixel.red=colors[i].red-(MagickRealType) color->red;
1076 distance=pixel.red*pixel.red;
1077 if (distance > min_distance)
1079 pixel.green=colors[i].green-(MagickRealType) color->green;
1080 distance+=pixel.green*pixel.green;
1081 if (distance > min_distance)
1083 pixel.blue=colors[i].blue-(MagickRealType) color->blue;
1084 distance+=pixel.blue*pixel.blue;
1085 if (distance > min_distance)
1087 min_distance=distance;
1088 color->pixel=colors[i].pixel;
1091 (void) XAllocColor(display,colormap,&colors[j]);
1092 if (query_server != MagickFalse)
1093 colors=(XColor *) RelinquishMagickMemory(colors);
1097 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1101 % X B e s t V i s u a l I n f o %
1105 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1107 % XBestVisualInfo() returns visual information for a visual that is the "best"
1108 % the server supports. "Best" is defined as:
1110 % 1. Restrict the visual list to those supported by the default screen.
1112 % 2. If a visual type is specified, restrict the visual list to those of
1115 % 3. If a map type is specified, choose the visual that matches the id
1116 % specified by the Standard Colormap.
1118 % 4 From the list of visuals, choose one that can display the most
1119 % simultaneous colors. If more than one visual can display the same
1120 % number of simultaneous colors, one is chosen based on a rank.
1122 % The format of the XBestVisualInfo method is:
1124 % XVisualInfo *XBestVisualInfo(Display *display,
1125 % XStandardColormap *map_info,XResourceInfo *resource_info)
1127 % A description of each parameter follows:
1129 % o visual_info: XBestVisualInfo returns a pointer to a X11 XVisualInfo
1132 % o display: Specifies a connection to an X server; returned from
1135 % o map_info: If map_type is specified, this structure is initialized
1136 % with info from the Standard Colormap.
1138 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
1142 static inline int MagickMax(const int x,const int y)
1149 static inline size_t MagickMin(const unsigned int x,
1150 const unsigned int y)
1157 MagickExport XVisualInfo *XBestVisualInfo(Display *display,
1158 XStandardColormap *map_info,XResourceInfo *resource_info)
1160 #define MaxStandardColormaps 7
1161 #define XVisualColormapSize(visual_info) MagickMin((unsigned int) (\
1162 (visual_info->klass == TrueColor) || (visual_info->klass == DirectColor) ? \
1163 visual_info->red_mask | visual_info->green_mask | visual_info->blue_mask : \
1164 (unsigned int) visual_info->colormap_size),1U << visual_info->depth)
1190 Restrict visual search by screen number.
1192 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1193 assert(display != (Display *) NULL);
1194 assert(map_info != (XStandardColormap *) NULL);
1195 assert(resource_info != (XResourceInfo *) NULL);
1196 map_type=resource_info->map_type;
1197 visual_type=resource_info->visual_type;
1198 visual_mask=VisualScreenMask;
1199 visual_template.screen=XDefaultScreen(display);
1200 visual_template.depth=XDefaultDepth(display,XDefaultScreen(display));
1202 if ((resource_info->immutable != MagickFalse) && (resource_info->colors != 0))
1203 if (resource_info->colors <= (one << (size_t) visual_template.depth))
1204 visual_mask|=VisualDepthMask;
1205 if (visual_type != (char *) NULL)
1208 Restrict visual search by class or visual id.
1210 if (LocaleCompare("staticgray",visual_type) == 0)
1212 visual_mask|=VisualClassMask;
1213 visual_template.klass=StaticGray;
1216 if (LocaleCompare("grayscale",visual_type) == 0)
1218 visual_mask|=VisualClassMask;
1219 visual_template.klass=GrayScale;
1222 if (LocaleCompare("staticcolor",visual_type) == 0)
1224 visual_mask|=VisualClassMask;
1225 visual_template.klass=StaticColor;
1228 if (LocaleCompare("pseudocolor",visual_type) == 0)
1230 visual_mask|=VisualClassMask;
1231 visual_template.klass=PseudoColor;
1234 if (LocaleCompare("truecolor",visual_type) == 0)
1236 visual_mask|=VisualClassMask;
1237 visual_template.klass=TrueColor;
1240 if (LocaleCompare("directcolor",visual_type) == 0)
1242 visual_mask|=VisualClassMask;
1243 visual_template.klass=DirectColor;
1246 if (LocaleCompare("default",visual_type) == 0)
1248 visual_mask|=VisualIDMask;
1249 visual_template.visualid=XVisualIDFromVisual(
1250 XDefaultVisual(display,XDefaultScreen(display)));
1253 if (isdigit((int) ((unsigned char) *visual_type)) != 0)
1255 visual_mask|=VisualIDMask;
1256 visual_template.visualid=
1257 strtol(visual_type,(char **) NULL,0);
1260 ThrowXWindowFatalException(XServerError,
1261 "UnrecognizedVisualSpecifier",visual_type);
1264 Get all visuals that meet our criteria so far.
1267 visual_list=XGetVisualInfo(display,visual_mask,&visual_template,
1269 visual_mask=VisualScreenMask | VisualIDMask;
1270 if ((number_visuals == 0) || (visual_list == (XVisualInfo *) NULL))
1273 Failed to get visual; try using the default visual.
1275 ThrowXWindowFatalException(XServerWarning,"UnableToGetVisual",
1277 visual_template.visualid=XVisualIDFromVisual(XDefaultVisual(display,
1278 XDefaultScreen(display)));
1279 visual_list=XGetVisualInfo(display,visual_mask,&visual_template,
1281 if ((number_visuals == 0) || (visual_list == (XVisualInfo *) NULL))
1282 return((XVisualInfo *) NULL);
1283 ThrowXWindowFatalException(XServerWarning,"UsingDefaultVisual",
1284 XVisualClassName(visual_list->klass));
1286 resource_info->color_recovery=MagickFalse;
1287 if ((map_info != (XStandardColormap *) NULL) && (map_type != (char *) NULL))
1293 map_name[MaxTextExtent];
1309 Choose a visual associated with a standard colormap.
1311 root_window=XRootWindow(display,XDefaultScreen(display));
1313 if (LocaleCompare(map_type,"list") != 0)
1316 User specified Standard Colormap.
1318 (void) FormatLocaleString((char *) map_name,MaxTextExtent,
1319 "RGB_%s_MAP",map_type);
1320 LocaleUpper(map_name);
1321 map_property=XInternAtom(display,(char *) map_name,MagickTrue);
1322 if (map_property != (Atom) NULL)
1323 status=XGetRGBColormaps(display,root_window,&map_list,&number_maps,
1329 *colormap[MaxStandardColormaps]=
1331 "_HP_RGB_SMOOTH_MAP_LIST",
1341 Choose a standard colormap from a list.
1343 for (i=0; i < MaxStandardColormaps; i++)
1345 map_property=XInternAtom(display,(char *) colormap[i],MagickTrue);
1346 if (map_property == (Atom) NULL)
1348 status=XGetRGBColormaps(display,root_window,&map_list,&number_maps,
1350 if (status != False)
1353 resource_info->color_recovery=i == 0 ? MagickTrue : MagickFalse;
1355 if (status == False)
1357 ThrowXWindowFatalException(XServerError,"UnableToGetStandardColormap",
1359 return((XVisualInfo *) NULL);
1362 Search all Standard Colormaps and visuals for ids that match.
1364 *map_info=map_list[0];
1365 #if !defined(PRE_R4_ICCCM)
1366 visual_template.visualid=XVisualIDFromVisual(visual_list[0].visual);
1367 for (i=0; i < number_maps; i++)
1368 for (j=0; j < number_visuals; j++)
1369 if (map_list[i].visualid ==
1370 XVisualIDFromVisual(visual_list[j].visual))
1372 *map_info=map_list[i];
1373 visual_template.visualid=XVisualIDFromVisual(
1374 visual_list[j].visual);
1377 if (map_info->visualid != visual_template.visualid)
1379 ThrowXWindowFatalException(XServerError,
1380 "UnableToMatchVisualToStandardColormap",map_type);
1381 return((XVisualInfo *) NULL);
1384 if (map_info->colormap == (Colormap) NULL)
1386 ThrowXWindowFatalException(XServerError,
1387 "StandardColormapIsNotInitialized",map_type);
1388 return((XVisualInfo *) NULL);
1390 (void) XFree((void *) map_list);
1394 static const unsigned int
1409 Pick one visual that displays the most simultaneous colors.
1411 visual_info=visual_list;
1413 for (i=1; i < number_visuals; i++)
1416 if (XVisualColormapSize(p) > XVisualColormapSize(visual_info))
1419 if (XVisualColormapSize(p) == XVisualColormapSize(visual_info))
1420 if (rank[p->klass] > rank[visual_info->klass])
1423 visual_template.visualid=XVisualIDFromVisual(visual_info->visual);
1425 (void) XFree((void *) visual_list);
1427 Retrieve only one visual by its screen & id number.
1429 visual_info=XGetVisualInfo(display,visual_mask,&visual_template,
1431 if ((number_visuals == 0) || (visual_info == (XVisualInfo *) NULL))
1432 return((XVisualInfo *) NULL);
1433 return(visual_info);
1437 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1441 % X C h e c k D e f i n e C u r s o r %
1445 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1447 % XCheckDefineCursor() prevents cursor changes on the root window.
1449 % The format of the XXCheckDefineCursor method is:
1451 % XCheckDefineCursor(display,window,cursor)
1453 % A description of each parameter follows:
1455 % o display: Specifies a connection to an X server; returned from
1458 % o window: the window.
1460 % o cursor: the cursor.
1463 MagickExport int XCheckDefineCursor(Display *display,Window window,
1466 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1467 assert(display != (Display *) NULL);
1468 if (window == XRootWindow(display,XDefaultScreen(display)))
1470 return(XDefineCursor(display,window,cursor));
1474 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1478 % X C h e c k R e f r e s h W i n d o w s %
1482 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1484 % XCheckRefreshWindows() checks the X server for exposure events for a
1485 % particular window and updates the areassociated with the exposure event.
1487 % The format of the XCheckRefreshWindows method is:
1489 % void XCheckRefreshWindows(Display *display,XWindows *windows)
1491 % A description of each parameter follows:
1493 % o display: Specifies a connection to an X server; returned from
1496 % o windows: Specifies a pointer to a XWindows structure.
1499 MagickExport void XCheckRefreshWindows(Display *display,XWindows *windows)
1507 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1508 assert(display != (Display *) NULL);
1509 assert(windows != (XWindows *) NULL);
1510 XDelay(display,SuspendTime);
1511 id=windows->command.id;
1512 while (XCheckTypedWindowEvent(display,id,Expose,&event) != MagickFalse)
1513 (void) XCommandWidget(display,windows,(char const **) NULL,&event);
1514 id=windows->image.id;
1515 while (XCheckTypedWindowEvent(display,id,Expose,&event) != MagickFalse)
1516 XRefreshWindow(display,&windows->image,&event);
1517 XDelay(display,SuspendTime << 1);
1518 id=windows->command.id;
1519 while (XCheckTypedWindowEvent(display,id,Expose,&event) != MagickFalse)
1520 (void) XCommandWidget(display,windows,(char const **) NULL,&event);
1521 id=windows->image.id;
1522 while (XCheckTypedWindowEvent(display,id,Expose,&event) != MagickFalse)
1523 XRefreshWindow(display,&windows->image,&event);
1527 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1531 % X C l i e n t M e s s a g e %
1535 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1537 % XClientMessage() sends a reason to a window with XSendEvent. The reason is
1538 % initialized with a particular protocol type and atom.
1540 % The format of the XClientMessage function is:
1542 % XClientMessage(display,window,protocol,reason,timestamp)
1544 % A description of each parameter follows:
1546 % o display: Specifies a pointer to the Display structure; returned from
1549 % o window: Specifies a pointer to a Window structure.
1551 % o protocol: Specifies an atom value.
1553 % o reason: Specifies an atom value which is the reason to send.
1555 % o timestamp: Specifies a value of type Time.
1558 MagickExport void XClientMessage(Display *display,const Window window,
1559 const Atom protocol,const Atom reason,const Time timestamp)
1564 assert(display != (Display *) NULL);
1565 client_event.type=ClientMessage;
1566 client_event.window=window;
1567 client_event.message_type=protocol;
1568 client_event.format=32;
1569 client_event.data.l[0]=(long) reason;
1570 client_event.data.l[1]=(long) timestamp;
1571 (void) XSendEvent(display,window,MagickFalse,NoEventMask,(XEvent *) &client_event);
1575 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1579 + X C l i e n t W i n d o w %
1583 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1585 % XClientWindow() finds a window, at or below the specified window, which has
1586 % a WM_STATE property. If such a window is found, it is returned, otherwise
1587 % the argument window is returned.
1589 % The format of the XClientWindow function is:
1591 % client_window=XClientWindow(display,target_window)
1593 % A description of each parameter follows:
1595 % o client_window: XClientWindow returns a window, at or below the specified
1596 % window, which has a WM_STATE property otherwise the argument
1597 % target_window is returned.
1599 % o display: Specifies a pointer to the Display structure; returned from
1602 % o target_window: Specifies the window to find a WM_STATE property.
1605 static Window XClientWindow(Display *display,Window target_window)
1627 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1628 assert(display != (Display *) NULL);
1629 state=XInternAtom(display,"WM_STATE",MagickTrue);
1630 if (state == (Atom) NULL)
1631 return(target_window);
1633 status=XGetWindowProperty(display,target_window,state,0L,0L,MagickFalse,
1634 (Atom) AnyPropertyType,&type,&format,&number_items,&after,&data);
1635 if ((status == Success) && (type != (Atom) NULL))
1636 return(target_window);
1637 client_window=XWindowByProperty(display,target_window,state);
1638 if (client_window == (Window) NULL)
1639 return(target_window);
1640 return(client_window);
1644 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1648 + X C o m p o n e n t T e r m i n u s %
1652 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1654 % XComponentTerminus() destroys the module component.
1656 % The format of the XComponentTerminus method is:
1658 % XComponentTerminus(void)
1661 MagickExport void XComponentTerminus(void)
1663 DestroyXResources();
1667 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1671 % X C o n f i g u r e I m a g e C o l o r m a p %
1675 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1677 % XConfigureImageColormap() creates a new X colormap.
1679 % The format of the XConfigureImageColormap method is:
1681 % void XConfigureImageColormap(Display *display,
1682 % XResourceInfo *resource_info,XWindows *windows,Image *image)
1684 % A description of each parameter follows:
1686 % o display: Specifies a connection to an X server; returned from
1689 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
1691 % o windows: Specifies a pointer to a XWindows structure.
1693 % o image: the image.
1696 MagickExport void XConfigureImageColormap(Display *display,
1697 XResourceInfo *resource_info,XWindows *windows,Image *image)
1703 Make standard colormap.
1705 XSetCursorState(display,windows,MagickTrue);
1706 XCheckRefreshWindows(display,windows);
1707 XMakeStandardColormap(display,windows->visual_info,resource_info,image,
1708 windows->map_info,windows->pixel_info);
1709 colormap=windows->map_info->colormap;
1710 (void) XSetWindowColormap(display,windows->image.id,colormap);
1711 (void) XSetWindowColormap(display,windows->command.id,colormap);
1712 (void) XSetWindowColormap(display,windows->widget.id,colormap);
1713 if (windows->magnify.mapped != MagickFalse)
1714 (void) XSetWindowColormap(display,windows->magnify.id,colormap);
1715 if (windows->pan.mapped != MagickFalse)
1716 (void) XSetWindowColormap(display,windows->pan.id,colormap);
1717 XSetCursorState(display,windows,MagickFalse);
1718 XClientMessage(display,windows->image.id,windows->im_protocols,
1719 windows->im_update_colormap,CurrentTime);
1723 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1727 % X C o n s t r a i n W i n d o w P o s i t i o n %
1731 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1733 % XConstrainWindowPosition() assures a window is positioned within the X
1734 % server boundaries.
1736 % The format of the XConstrainWindowPosition method is:
1738 % void XConstrainWindowPosition(Display *display,XWindowInfo *window_info)
1740 % A description of each parameter follows:
1742 % o display: Specifies a pointer to the Display structure; returned from
1745 % o window_info: Specifies a pointer to a XWindowInfo structure.
1748 MagickExport void XConstrainWindowPosition(Display *display,
1749 XWindowInfo *window_info)
1754 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1755 assert(display != (Display *) NULL);
1756 assert(window_info != (XWindowInfo *) NULL);
1757 limit=XDisplayWidth(display,window_info->screen)-window_info->width;
1758 if (window_info->x < 0)
1761 if (window_info->x > (int) limit)
1762 window_info->x=(int) limit;
1763 limit=XDisplayHeight(display,window_info->screen)-window_info->height;
1764 if (window_info->y < 0)
1767 if (window_info->y > limit)
1768 window_info->y=limit;
1772 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1780 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1782 % XDelay() suspends program execution for the number of milliseconds
1785 % The format of the Delay method is:
1787 % void XDelay(Display *display,const size_t milliseconds)
1789 % A description of each parameter follows:
1791 % o display: Specifies a pointer to the Display structure; returned from
1794 % o milliseconds: Specifies the number of milliseconds to delay before
1798 MagickExport void XDelay(Display *display,const size_t milliseconds)
1800 assert(display != (Display *) NULL);
1801 (void) XFlush(display);
1802 MagickDelay(milliseconds);
1806 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1810 % X D e s t r o y R e s o u r c e I n f o %
1814 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1816 % XDestroyResourceInfo() frees memory associated with the XResourceInfo
1819 % The format of the XDestroyResourceInfo method is:
1821 % void XDestroyResourceInfo(XResourceInfo *resource_info)
1823 % A description of each parameter follows:
1825 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
1828 MagickExport void XDestroyResourceInfo(XResourceInfo *resource_info)
1830 if (resource_info->image_geometry != (char *) NULL)
1831 resource_info->image_geometry=(char *)
1832 RelinquishMagickMemory(resource_info->image_geometry);
1833 if (resource_info->quantize_info != (QuantizeInfo *) NULL)
1834 resource_info->quantize_info=DestroyQuantizeInfo(
1835 resource_info->quantize_info);
1836 if (resource_info->client_name != (char *) NULL)
1837 resource_info->client_name=(char *)
1838 RelinquishMagickMemory(resource_info->client_name);
1839 if (resource_info->name != (char *) NULL)
1840 resource_info->name=DestroyString(resource_info->name);
1841 (void) ResetMagickMemory(resource_info,0,sizeof(*resource_info));
1845 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1849 % X D e s t r o y W i n d o w C o l o r s %
1853 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1855 % XDestroyWindowColors() frees X11 color resources previously saved on a
1856 % window by XRetainWindowColors or programs like xsetroot.
1858 % The format of the XDestroyWindowColors method is:
1860 % void XDestroyWindowColors(Display *display,Window window)
1862 % A description of each parameter follows:
1864 % o display: Specifies a connection to an X server; returned from
1867 % o window: Specifies a pointer to a Window structure.
1870 MagickExport void XDestroyWindowColors(Display *display,Window window)
1890 If there are previous resources on the root window, destroy them.
1892 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1893 assert(display != (Display *) NULL);
1894 property=XInternAtom(display,"_XSETROOT_ID",MagickFalse);
1895 if (property == (Atom) NULL)
1897 ThrowXWindowFatalException(XServerError,"UnableToCreateProperty",
1901 status=XGetWindowProperty(display,window,property,0L,1L,MagickTrue,
1902 (Atom) AnyPropertyType,&type,&format,&length,&after,&data);
1903 if (status != Success)
1905 if ((type == XA_PIXMAP) && (format == 32) && (length == 1) && (after == 0))
1907 (void) XKillClient(display,(XID) (*((Pixmap *) data)));
1908 (void) XDeleteProperty(display,window,property);
1911 (void) XFree((void *) data);
1915 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1919 % X D i s p l a y I m a g e I n f o %
1923 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1925 % XDisplayImageInfo() displays information about an X image.
1927 % The format of the XDisplayImageInfo method is:
1929 % void XDisplayImageInfo(Display *display,
1930 % const XResourceInfo *resource_info,XWindows *windows,Image *undo_image,
1933 % A description of each parameter follows:
1935 % o display: Specifies a connection to an X server; returned from
1938 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
1940 % o windows: Specifies a pointer to a XWindows structure.
1942 % o undo_image: the undo image.
1944 % o image: the image.
1947 MagickExport void XDisplayImageInfo(Display *display,
1948 const XResourceInfo *resource_info,XWindows *windows,Image *undo_image,
1952 filename[MaxTextExtent],
1975 Write info about the X server to a file.
1977 assert(display != (Display *) NULL);
1978 assert(resource_info != (XResourceInfo *) NULL);
1979 assert(windows != (XWindows *) NULL);
1980 assert(image != (Image *) NULL);
1982 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1984 unique_file=AcquireUniqueFileResource(filename);
1985 if (unique_file != -1)
1986 file=fdopen(unique_file,"w");
1987 if ((unique_file == -1) || (file == (FILE *) NULL))
1989 XNoticeWidget(display,windows,"Unable to display image info",filename);
1992 if (resource_info->gamma_correct != MagickFalse)
1993 if (resource_info->display_gamma != (char *) NULL)
1994 (void) FormatLocaleFile(file,"Display\n gamma: %s\n\n",
1995 resource_info->display_gamma);
1997 Write info about the X image to a file.
1999 (void) FormatLocaleFile(file,"X\n visual: %s\n",
2000 XVisualClassName((int) windows->image.storage_class));
2001 (void) FormatLocaleFile(file," depth: %d\n",windows->image.ximage->depth);
2002 if (windows->visual_info->colormap_size != 0)
2003 (void) FormatLocaleFile(file," colormap size: %d\n",
2004 windows->visual_info->colormap_size);
2005 if (resource_info->colormap== SharedColormap)
2006 (void) FormatLocaleFile(file," colormap type: Shared\n");
2008 (void) FormatLocaleFile(file," colormap type: Private\n");
2009 (void) FormatLocaleFile(file," geometry: %dx%d\n",
2010 windows->image.ximage->width,windows->image.ximage->height);
2011 if (windows->image.crop_geometry != (char *) NULL)
2012 (void) FormatLocaleFile(file," crop geometry: %s\n",
2013 windows->image.crop_geometry);
2014 if (windows->image.pixmap == (Pixmap) NULL)
2015 (void) FormatLocaleFile(file," type: X Image\n");
2017 (void) FormatLocaleFile(file," type: Pixmap\n");
2018 if (windows->image.shape != MagickFalse)
2019 (void) FormatLocaleFile(file," non-rectangular shape: True\n");
2021 (void) FormatLocaleFile(file," non-rectangular shape: False\n");
2022 if (windows->image.shared_memory != MagickFalse)
2023 (void) FormatLocaleFile(file," shared memory: True\n");
2025 (void) FormatLocaleFile(file," shared memory: False\n");
2026 (void) FormatLocaleFile(file,"\n");
2027 if (resource_info->font != (char *) NULL)
2028 (void) FormatLocaleFile(file,"Font: %s\n\n",resource_info->font);
2029 if (resource_info->text_font != (char *) NULL)
2030 (void) FormatLocaleFile(file,"Text font: %s\n\n",resource_info->text_font);
2032 Write info about the undo cache to a file.
2035 for (levels=0; undo_image != (Image *) NULL; levels++)
2037 number_pixels=undo_image->list->columns*undo_image->list->rows;
2038 bytes+=number_pixels*sizeof(PixelPacket);
2039 undo_image=GetPreviousImageInList(undo_image);
2041 (void) FormatLocaleFile(file,"Undo Edit Cache\n levels: %u\n",levels);
2042 (void) FormatLocaleFile(file," bytes: %.20gmb\n",(double)
2043 ((bytes+(1 << 19)) >> 20));
2044 (void) FormatLocaleFile(file," limit: %.20gmb\n\n",(double)
2045 resource_info->undo_cache);
2047 Write info about the image to a file.
2049 (void) IdentifyImage(image,file,MagickTrue,&image->exception);
2050 (void) fclose(file);
2051 text=FileToString(filename,~0,&image->exception);
2052 (void) RelinquishUniqueFileResource(filename);
2053 if (text == (char *) NULL)
2055 XNoticeWidget(display,windows,"MemoryAllocationFailed",
2056 "UnableToDisplayImageInfo");
2059 textlist=StringToList(text);
2060 if (textlist != (char **) NULL)
2063 title[MaxTextExtent];
2066 Display information about the image in the Text View widget.
2068 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
2069 (void) FormatLocaleString(title,MaxTextExtent,"Image Info: %s",
2071 XTextViewWidget(display,resource_info,windows,MagickTrue,title,
2072 (char const **) textlist);
2073 for (i=0; textlist[i] != (char *) NULL; i++)
2074 textlist[i]=DestroyString(textlist[i]);
2075 textlist=(char **) RelinquishMagickMemory(textlist);
2077 text=DestroyString(text);
2081 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2085 + X D i t h e r I m a g e %
2089 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2091 % XDitherImage() dithers the reference image as required by the HP Color
2092 % Recovery algorithm. The color values are quantized to 3 bits of red and
2093 % green, and 2 bits of blue (3/3/2) and can be used as indices into a 8-bit X
2094 % standard colormap.
2096 % The format of the XDitherImage method is:
2098 % void XDitherImage(Image *image,XImage *ximage)
2100 % A description of each parameter follows:
2102 % o image: the image.
2104 % o ximage: Specifies a pointer to a XImage structure; returned from
2108 static void XDitherImage(Image *image,XImage *ximage)
2110 static const short int
2113 {-16, 4, -1, 11,-14, 6, -3, 9,-15, 5, -2, 10,-13, 7, -4, 8},
2114 { 15, -5, 0,-12, 13, -7, 2,-10, 14, -6, 1,-11, 12, -8, 3, -9}
2116 dither_green[2][16]=
2118 { 11,-15, 7, -3, 8,-14, 4, -2, 10,-16, 6, -4, 9,-13, 5, -1},
2119 {-12, 14, -8, 2, -9, 13, -5, 1,-11, 15, -7, 3,-10, 12, -6, 0}
2123 { -3, 9,-13, 7, -1, 11,-15, 5, -4, 8,-14, 6, -2, 10,-16, 4},
2124 { 2,-10, 12, -8, 0,-12, 14, -6, 3, -9, 13, -7, 1,-11, 15, -5}
2140 register const Quantum
2160 Allocate and initialize dither maps.
2162 for (i=0; i < 2; i++)
2163 for (j=0; j < 16; j++)
2165 red_map[i][j]=(unsigned char *) AcquireQuantumMemory(256UL,
2167 green_map[i][j]=(unsigned char *) AcquireQuantumMemory(256UL,
2168 sizeof(*green_map));
2169 blue_map[i][j]=(unsigned char *) AcquireQuantumMemory(256UL,
2171 if ((red_map[i][j] == (unsigned char *) NULL) ||
2172 (green_map[i][j] == (unsigned char *) NULL) ||
2173 (blue_map[i][j] == (unsigned char *) NULL))
2175 ThrowXWindowFatalException(ResourceLimitError,
2176 "MemoryAllocationFailed",image->filename);
2181 Initialize dither tables.
2183 for (i=0; i < 2; i++)
2184 for (j=0; j < 16; j++)
2185 for (x=0; x < 256; x++)
2190 value+=dither_red[i][j];
2191 red_map[i][j][x]=(unsigned char)
2192 ((value < 0) ? 0 : (value > 255) ? 255 : value);
2196 value+=dither_green[i][j];
2197 green_map[i][j][x]=(unsigned char)
2198 ((value < 0) ? 0 : (value > 255) ? 255 : value);
2202 value+=((size_t) dither_blue[i][j] << 1);
2203 blue_map[i][j][x]=(unsigned char)
2204 ((value < 0) ? 0 : (value > 255) ? 255 : value);
2209 scanline_pad=(unsigned int) (ximage->bytes_per_line-
2210 ((size_t) (ximage->width*ximage->bits_per_pixel) >> 3));
2214 image_view=AcquireCacheView(image);
2215 for (y=0; y < (int) image->rows; y++)
2217 p=GetCacheViewVirtualPixels(image_view,0,(ssize_t) y,image->columns,1,
2219 if (p == (const Quantum *) NULL)
2221 for (x=0; x < (int) image->columns; x++)
2223 color.red=ClampToQuantum((MagickRealType) (red_map[i][j][(int)
2224 ScaleQuantumToChar(GetPixelRed(image,p))] << 8));
2225 color.green=ClampToQuantum((MagickRealType) (green_map[i][j][(int)
2226 ScaleQuantumToChar(GetPixelGreen(image,p))] << 8));
2227 color.blue=ClampToQuantum((MagickRealType) (blue_map[i][j][(int)
2228 ScaleQuantumToChar(GetPixelBlue(image,p))] << 8));
2229 pixel=(size_t) (((size_t) color.red & 0xe0) |
2230 (((size_t) color.green & 0xe0) >> 3) |
2231 (((size_t) color.blue & 0xc0) >> 6));
2233 p+=GetPixelChannels(image);
2243 image_view=DestroyCacheView(image_view);
2245 Free allocated memory.
2247 for (i=0; i < 2; i++)
2248 for (j=0; j < 16; j++)
2250 green_map[i][j]=(unsigned char *) RelinquishMagickMemory(green_map[i][j]);
2251 blue_map[i][j]=(unsigned char *) RelinquishMagickMemory(blue_map[i][j]);
2252 red_map[i][j]=(unsigned char *) RelinquishMagickMemory(red_map[i][j]);
2257 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2261 % X D r a w I m a g e %
2265 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2267 % XDrawImage() draws a line on the image.
2269 % The format of the XDrawImage method is:
2271 % MagickBooleanType XDrawImage(display,pixel,draw_info,image)
2273 % A description of each parameter follows:
2275 % o display: Specifies a connection to an X server; returned from
2278 % o pixel: Specifies a pointer to a XPixelInfo structure.
2280 % o draw_info: Specifies a pointer to a XDrawInfo structure.
2282 % o image: the image.
2285 MagickExport MagickBooleanType XDrawImage(Display *display,
2286 const XPixelInfo *pixel,XDrawInfo *draw_info,Image *image)
2325 Initialize drawd image.
2327 assert(display != (Display *) NULL);
2328 assert(pixel != (XPixelInfo *) NULL);
2329 assert(draw_info != (XDrawInfo *) NULL);
2330 assert(image != (Image *) NULL);
2331 if (image->debug != MagickFalse)
2332 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2334 Initialize drawd pixmap.
2336 root_window=XRootWindow(display,XDefaultScreen(display));
2337 depth=(unsigned int) XDefaultDepth(display,XDefaultScreen(display));
2338 draw_pixmap=XCreatePixmap(display,root_window,draw_info->width,
2339 draw_info->height,depth);
2340 if (draw_pixmap == (Pixmap) NULL)
2341 return(MagickFalse);
2343 Initialize graphics info.
2345 context_values.background=(size_t) (~0);
2346 context_values.foreground=0;
2347 context_values.line_width=(int) draw_info->line_width;
2348 draw_context=XCreateGC(display,root_window,(size_t)
2349 (GCBackground | GCForeground | GCLineWidth),&context_values);
2350 if (draw_context == (GC) NULL)
2351 return(MagickFalse);
2355 (void) XFillRectangle(display,draw_pixmap,draw_context,0,0,draw_info->width,
2358 Draw line to pixmap.
2360 (void) XSetBackground(display,draw_context,0);
2361 (void) XSetForeground(display,draw_context,(size_t) (~0));
2362 if (draw_info->stipple != (Pixmap) NULL)
2364 (void) XSetFillStyle(display,draw_context,FillOpaqueStippled);
2365 (void) XSetStipple(display,draw_context,draw_info->stipple);
2367 switch (draw_info->element)
2372 (void) XDrawLines(display,draw_pixmap,draw_context,
2373 draw_info->coordinate_info,(int) draw_info->number_coordinates,
2379 (void) XDrawLine(display,draw_pixmap,draw_context,draw_info->line_info.x1,
2380 draw_info->line_info.y1,draw_info->line_info.x2,
2381 draw_info->line_info.y2);
2384 case RectangleElement:
2386 (void) XDrawRectangle(display,draw_pixmap,draw_context,
2387 (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y,
2388 (unsigned int) draw_info->rectangle_info.width,
2389 (unsigned int) draw_info->rectangle_info.height);
2392 case FillRectangleElement:
2394 (void) XFillRectangle(display,draw_pixmap,draw_context,
2395 (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y,
2396 (unsigned int) draw_info->rectangle_info.width,
2397 (unsigned int) draw_info->rectangle_info.height);
2401 case EllipseElement:
2403 (void) XDrawArc(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,0,360*64);
2409 case FillCircleElement:
2410 case FillEllipseElement:
2412 (void) XFillArc(display,draw_pixmap,draw_context,
2413 (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y,
2414 (unsigned int) draw_info->rectangle_info.width,
2415 (unsigned int) draw_info->rectangle_info.height,0,360*64);
2418 case PolygonElement:
2423 coordinate_info=draw_info->coordinate_info;
2424 (void) XDrawLines(display,draw_pixmap,draw_context,coordinate_info,
2425 (int) draw_info->number_coordinates,CoordModeOrigin);
2426 (void) XDrawLine(display,draw_pixmap,draw_context,
2427 coordinate_info[draw_info->number_coordinates-1].x,
2428 coordinate_info[draw_info->number_coordinates-1].y,
2429 coordinate_info[0].x,coordinate_info[0].y);
2432 case FillPolygonElement:
2434 (void) XFillPolygon(display,draw_pixmap,draw_context,
2435 draw_info->coordinate_info,(int) draw_info->number_coordinates,Complex,
2440 (void) XFreeGC(display,draw_context);
2444 draw_ximage=XGetImage(display,draw_pixmap,0,0,draw_info->width,
2445 draw_info->height,AllPlanes,ZPixmap);
2446 if (draw_ximage == (XImage *) NULL)
2447 return(MagickFalse);
2448 (void) XFreePixmap(display,draw_pixmap);
2450 Initialize draw image.
2452 draw_image=AcquireImage((ImageInfo *) NULL);
2453 if (draw_image == (Image *) NULL)
2454 return(MagickFalse);
2455 draw_image->columns=draw_info->width;
2456 draw_image->rows=draw_info->height;
2458 Transfer drawn X image to image.
2460 width=(unsigned int) image->columns;
2461 height=(unsigned int) image->rows;
2464 (void) XParseGeometry(draw_info->geometry,&x,&y,&width,&height);
2465 (void) GetOneVirtualPixel(image,(ssize_t) x,(ssize_t) y,
2466 &draw_image->background_color,&image->exception);
2467 if (SetImageStorageClass(draw_image,DirectClass,&image->exception) == MagickFalse)
2468 return(MagickFalse);
2469 draw_image->matte=MagickTrue;
2470 exception=(&image->exception);
2471 draw_view=AcquireCacheView(draw_image);
2472 for (y=0; y < (int) draw_image->rows; y++)
2480 q=QueueCacheViewAuthenticPixels(draw_view,0,(ssize_t) y,draw_image->columns,
2482 if (q == (const Quantum *) NULL)
2484 for (x=0; x < (int) draw_image->columns; x++)
2486 if (XGetPixel(draw_ximage,x,y) == 0)
2489 Set this pixel to the background color.
2491 SetPixelPacket(draw_image,&draw_image->background_color,q);
2492 SetPixelAlpha(draw_image,(Quantum) (draw_info->stencil ==
2493 OpaqueStencil ? TransparentAlpha : OpaqueAlpha),q);
2498 Set this pixel to the pen color.
2500 SetPixelRed(draw_image,ScaleShortToQuantum(
2501 pixel->pen_color.red),q);
2502 SetPixelGreen(draw_image,ScaleShortToQuantum(
2503 pixel->pen_color.green),q);
2504 SetPixelBlue(draw_image,ScaleShortToQuantum(
2505 pixel->pen_color.blue),q);
2506 SetPixelAlpha(draw_image,(Quantum) (draw_info->stencil ==
2507 OpaqueStencil ? OpaqueAlpha : TransparentAlpha),q);
2509 q+=GetPixelChannels(draw_image);
2511 if (SyncCacheViewAuthenticPixels(draw_view,exception) == MagickFalse)
2514 draw_view=DestroyCacheView(draw_view);
2515 XDestroyImage(draw_ximage);
2517 Determine draw geometry.
2519 (void) XParseGeometry(draw_info->geometry,&x,&y,&width,&height);
2520 if ((width != (unsigned int) draw_image->columns) ||
2521 (height != (unsigned int) draw_image->rows))
2524 image_geometry[MaxTextExtent];
2529 (void) FormatLocaleString(image_geometry,MaxTextExtent,"%ux%u",
2531 (void) TransformImage(&draw_image,(char *) NULL,image_geometry);
2533 if (draw_info->degrees != 0.0)
2547 rotate_image=RotateImage(draw_image,draw_info->degrees,&image->exception);
2548 if (rotate_image == (Image *) NULL)
2549 return(MagickFalse);
2550 draw_image=DestroyImage(draw_image);
2551 draw_image=rotate_image;
2553 Annotation is relative to the degree of rotation.
2555 normalized_degrees=draw_info->degrees;
2556 while (normalized_degrees < -45.0)
2557 normalized_degrees+=360.0;
2558 for (rotations=0; normalized_degrees > 45.0; rotations++)
2559 normalized_degrees-=90.0;
2560 switch (rotations % 4)
2570 x=x-(int) draw_image->columns/2;
2571 y=y+(int) draw_image->columns/2;
2579 x=x-(int) draw_image->columns;
2587 x=x-(int) draw_image->columns/2;
2588 y=y-(int) (draw_image->rows-(draw_image->columns/2));
2594 Composite text onto the image.
2596 draw_view=AcquireCacheView(draw_image);
2597 for (y=0; y < (int) draw_image->rows; y++)
2605 q=GetCacheViewAuthenticPixels(draw_view,0,(ssize_t) y,draw_image->columns,1,
2607 if (q == (const Quantum *) NULL)
2609 for (x=0; x < (int) draw_image->columns; x++)
2611 if (GetPixelAlpha(image,q) != TransparentAlpha)
2612 SetPixelAlpha(draw_image,OpaqueAlpha,q);
2613 q+=GetPixelChannels(draw_image);
2615 if (SyncCacheViewAuthenticPixels(draw_view,exception) == MagickFalse)
2618 draw_view=DestroyCacheView(draw_view);
2619 (void) XParseGeometry(draw_info->geometry,&x,&y,&width,&height);
2620 if (draw_info->stencil == TransparentStencil)
2621 (void) CompositeImage(image,CopyOpacityCompositeOp,draw_image,(ssize_t) x,
2626 (void) CompositeImage(image,OverCompositeOp,draw_image,(ssize_t) x,
2630 draw_image=DestroyImage(draw_image);
2635 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2643 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2645 % XError() ignores BadWindow errors for XQueryTree and XGetWindowAttributes,
2646 % and ignores BadDrawable errors for XGetGeometry, and ignores BadValue errors
2647 % for XQueryColor. It returns MagickFalse in those cases. Otherwise it returns
2650 % The format of the XError function is:
2652 % XError(display,error)
2654 % A description of each parameter follows:
2656 % o display: Specifies a pointer to the Display structure; returned from
2659 % o error: Specifies the error event.
2663 #if defined(__cplusplus) || defined(c_plusplus)
2667 MagickExport int XError(Display *display,XErrorEvent *error)
2669 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2670 assert(display != (Display *) NULL);
2671 assert(error != (XErrorEvent *) NULL);
2672 xerror_alert=MagickTrue;
2673 switch (error->request_code)
2677 if ((int) error->error_code == BadDrawable)
2678 return(MagickFalse);
2681 case X_GetWindowAttributes:
2684 if ((int) error->error_code == BadWindow)
2685 return(MagickFalse);
2690 if ((int) error->error_code == BadValue)
2691 return(MagickFalse);
2698 #if defined(__cplusplus) || defined(c_plusplus)
2703 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2707 % X F r e e R e s o u r c e s %
2711 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2713 % XFreeResources() frees X11 resources.
2715 % The format of the XFreeResources method is:
2717 % void XFreeResources(Display *display,XVisualInfo *visual_info,
2718 % XStandardColormap *map_info,XPixelInfo *pixel,XFontStruct *font_info,
2719 % XResourceInfo *resource_info,XWindowInfo *window_info)
2720 % resource_info,window_info)
2722 % A description of each parameter follows:
2724 % o display: Specifies a connection to an X server; returned from
2727 % o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
2728 % returned from XGetVisualInfo.
2730 % o map_info: If map_type is specified, this structure is initialized
2731 % with info from the Standard Colormap.
2733 % o pixel: Specifies a pointer to a XPixelInfo structure.
2735 % o font_info: Specifies a pointer to a XFontStruct structure.
2737 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
2739 % o window_info: Specifies a pointer to a X11 XWindowInfo structure.
2742 MagickExport void XFreeResources(Display *display,XVisualInfo *visual_info,
2743 XStandardColormap *map_info,XPixelInfo *pixel,XFontStruct *font_info,
2744 XResourceInfo *resource_info,XWindowInfo *window_info)
2746 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2747 assert(display != (Display *) NULL);
2748 assert(resource_info != (XResourceInfo *) NULL);
2749 if (window_info != (XWindowInfo *) NULL)
2754 if (window_info->ximage != (XImage *) NULL)
2755 XDestroyImage(window_info->ximage);
2756 if (window_info->id != (Window) NULL)
2759 Free destroy window and free cursors.
2761 if (window_info->id != XRootWindow(display,visual_info->screen))
2762 (void) XDestroyWindow(display,window_info->id);
2763 if (window_info->annotate_context != (GC) NULL)
2764 (void) XFreeGC(display,window_info->annotate_context);
2765 if (window_info->highlight_context != (GC) NULL)
2766 (void) XFreeGC(display,window_info->highlight_context);
2767 if (window_info->widget_context != (GC) NULL)
2768 (void) XFreeGC(display,window_info->widget_context);
2769 if (window_info->cursor != (Cursor) NULL)
2770 (void) XFreeCursor(display,window_info->cursor);
2771 window_info->cursor=(Cursor) NULL;
2772 if (window_info->busy_cursor != (Cursor) NULL)
2773 (void) XFreeCursor(display,window_info->busy_cursor);
2774 window_info->busy_cursor=(Cursor) NULL;
2780 if (font_info != (XFontStruct *) NULL)
2782 (void) XFreeFont(display,font_info);
2783 font_info=(XFontStruct *) NULL;
2785 if (map_info != (XStandardColormap *) NULL)
2788 Free X Standard Colormap.
2790 if (resource_info->map_type == (char *) NULL)
2791 (void) XFreeStandardColormap(display,visual_info,map_info,pixel);
2792 (void) XFree((void *) map_info);
2797 if (visual_info != (XVisualInfo *) NULL)
2798 (void) XFree((void *) visual_info);
2799 if (resource_info->close_server != MagickFalse)
2800 (void) XCloseDisplay(display);
2804 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2808 % X F r e e S t a n d a r d C o l o r m a p %
2812 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2814 % XFreeStandardColormap() frees an X11 colormap.
2816 % The format of the XFreeStandardColormap method is:
2818 % void XFreeStandardColormap(Display *display,
2819 % const XVisualInfo *visual_info,XStandardColormap *map_info,
2820 % XPixelInfo *pixel)
2822 % A description of each parameter follows:
2824 % o display: Specifies a connection to an X server; returned from
2827 % o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
2828 % returned from XGetVisualInfo.
2830 % o map_info: If map_type is specified, this structure is initialized
2831 % with info from the Standard Colormap.
2833 % o pixel: Specifies a pointer to a XPixelInfo structure.
2836 MagickExport void XFreeStandardColormap(Display *display,
2837 const XVisualInfo *visual_info,XStandardColormap *map_info,XPixelInfo *pixel)
2842 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2843 assert(display != (Display *) NULL);
2844 assert(visual_info != (XVisualInfo *) NULL);
2845 assert(map_info != (XStandardColormap *) NULL);
2846 (void) XFlush(display);
2847 if (map_info->colormap != (Colormap) NULL)
2849 if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
2850 (void) XFreeColormap(display,map_info->colormap);
2852 if (pixel != (XPixelInfo *) NULL)
2853 if ((visual_info->klass != TrueColor) &&
2854 (visual_info->klass != DirectColor))
2855 (void) XFreeColors(display,map_info->colormap,pixel->pixels,
2856 (int) pixel->colors,0);
2858 map_info->colormap=(Colormap) NULL;
2859 if (pixel != (XPixelInfo *) NULL)
2861 if (pixel->pixels != (unsigned long *) NULL)
2862 pixel->pixels=(unsigned long *) RelinquishMagickMemory(pixel->pixels);
2863 pixel->pixels=(unsigned long *) NULL;
2868 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2872 % X G e t A n n o t a t e I n f o %
2876 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2878 % XGetAnnotateInfo() initializes the AnnotateInfo structure.
2880 % The format of the XGetAnnotateInfo method is:
2882 % void XGetAnnotateInfo(XAnnotateInfo *annotate_info)
2884 % A description of each parameter follows:
2886 % o annotate_info: Specifies a pointer to a XAnnotateInfo structure.
2889 MagickExport void XGetAnnotateInfo(XAnnotateInfo *annotate_info)
2892 Initialize annotate structure.
2894 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2895 assert(annotate_info != (XAnnotateInfo *) NULL);
2898 annotate_info->width=0;
2899 annotate_info->height=0;
2900 annotate_info->stencil=ForegroundStencil;
2901 annotate_info->degrees=0.0;
2902 annotate_info->font_info=(XFontStruct *) NULL;
2903 annotate_info->text=(char *) NULL;
2904 *annotate_info->geometry='\0';
2905 annotate_info->previous=(XAnnotateInfo *) NULL;
2906 annotate_info->next=(XAnnotateInfo *) NULL;
2907 (void) XSupportsLocale();
2908 (void) XSetLocaleModifiers("");
2912 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2916 % X G e t M a p I n f o %
2920 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2922 % XGetMapInfo() initializes the XStandardColormap structure.
2924 % The format of the XStandardColormap method is:
2926 % void XGetMapInfo(const XVisualInfo *visual_info,const Colormap colormap,
2927 % XStandardColormap *map_info)
2929 % A description of each parameter follows:
2931 % o colormap: Specifies the ID of the X server colormap.
2933 % o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
2934 % returned from XGetVisualInfo.
2936 % o map_info: Specifies a pointer to a X11 XStandardColormap structure.
2939 MagickExport void XGetMapInfo(const XVisualInfo *visual_info,
2940 const Colormap colormap,XStandardColormap *map_info)
2943 Initialize map info.
2945 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2946 assert(visual_info != (XVisualInfo *) NULL);
2947 assert(map_info != (XStandardColormap *) NULL);
2948 map_info->colormap=colormap;
2949 map_info->red_max=visual_info->red_mask;
2950 map_info->red_mult=(size_t) (map_info->red_max != 0 ? 1 : 0);
2951 if (map_info->red_max != 0)
2952 while ((map_info->red_max & 0x01) == 0)
2954 map_info->red_max>>=1;
2955 map_info->red_mult<<=1;
2957 map_info->green_max=visual_info->green_mask;
2958 map_info->green_mult=(size_t) (map_info->green_max != 0 ? 1 : 0);
2959 if (map_info->green_max != 0)
2960 while ((map_info->green_max & 0x01) == 0)
2962 map_info->green_max>>=1;
2963 map_info->green_mult<<=1;
2965 map_info->blue_max=visual_info->blue_mask;
2966 map_info->blue_mult=(size_t) (map_info->blue_max != 0 ? 1 : 0);
2967 if (map_info->blue_max != 0)
2968 while ((map_info->blue_max & 0x01) == 0)
2970 map_info->blue_max>>=1;
2971 map_info->blue_mult<<=1;
2973 map_info->base_pixel=0;
2977 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2981 % X G e t P i x e l I n f o %
2985 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2987 % XGetPixelInfo() initializes the PixelPacket structure.
2989 % The format of the XGetPixelInfo method is:
2991 % void XGetPixelInfo(Display *display,const XVisualInfo *visual_info,
2992 % const XStandardColormap *map_info,const XResourceInfo *resource_info,
2993 % Image *image,XPixelInfo *pixel)
2996 % A description of each parameter follows:
2998 % o display: Specifies a connection to an X server; returned from
3001 % o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
3002 % returned from XGetVisualInfo.
3004 % o map_info: If map_type is specified, this structure is initialized
3005 % with info from the Standard Colormap.
3007 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
3009 % o image: the image.
3011 % o pixel: Specifies a pointer to a XPixelInfo structure.
3014 MagickExport void XGetPixelInfo(Display *display,
3015 const XVisualInfo *visual_info,const XStandardColormap *map_info,
3016 const XResourceInfo *resource_info,Image *image,XPixelInfo *pixel)
3019 *PenColors[MaxNumberPens]=
3021 "#000000000000", /* black */
3022 "#00000000ffff", /* blue */
3023 "#0000ffffffff", /* cyan */
3024 "#0000ffff0000", /* green */
3025 "#bdbdbdbdbdbd", /* gray */
3026 "#ffff00000000", /* red */
3027 "#ffff0000ffff", /* magenta */
3028 "#ffffffff0000", /* yellow */
3029 "#ffffffffffff", /* white */
3030 "#bdbdbdbdbdbd", /* gray */
3031 "#bdbdbdbdbdbd" /* gray */
3047 Initialize pixel info.
3049 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3050 assert(display != (Display *) NULL);
3051 assert(visual_info != (XVisualInfo *) NULL);
3052 assert(map_info != (XStandardColormap *) NULL);
3053 assert(resource_info != (XResourceInfo *) NULL);
3054 assert(pixel != (XPixelInfo *) NULL);
3056 if (image != (Image *) NULL)
3057 if (image->storage_class == PseudoClass)
3058 pixel->colors=(ssize_t) image->colors;
3059 packets=(unsigned int)
3060 MagickMax((int) pixel->colors,visual_info->colormap_size)+MaxNumberPens;
3061 if (pixel->pixels != (unsigned long *) NULL)
3062 pixel->pixels=(unsigned long *) RelinquishMagickMemory(pixel->pixels);
3063 pixel->pixels=(unsigned long *) AcquireQuantumMemory(packets,
3064 sizeof(pixel->pixels));
3065 if (pixel->pixels == (unsigned long *) NULL)
3066 ThrowXWindowFatalException(ResourceLimitFatalError,"UnableToGetPixelInfo",
3069 Set foreground color.
3071 colormap=map_info->colormap;
3072 (void) XParseColor(display,colormap,(char *) ForegroundColor,
3073 &pixel->foreground_color);
3074 status=XParseColor(display,colormap,resource_info->foreground_color,
3075 &pixel->foreground_color);
3076 if (status == False)
3077 ThrowXWindowFatalException(XServerError,"ColorIsNotKnownToServer",
3078 resource_info->foreground_color);
3079 pixel->foreground_color.pixel=
3080 XStandardPixel(map_info,&pixel->foreground_color);
3081 pixel->foreground_color.flags=(char) (DoRed | DoGreen | DoBlue);
3083 Set background color.
3085 (void) XParseColor(display,colormap,"#d6d6d6d6d6d6",&pixel->background_color);
3086 status=XParseColor(display,colormap,resource_info->background_color,
3087 &pixel->background_color);
3088 if (status == False)
3089 ThrowXWindowFatalException(XServerError,"ColorIsNotKnownToServer",
3090 resource_info->background_color);
3091 pixel->background_color.pixel=
3092 XStandardPixel(map_info,&pixel->background_color);
3093 pixel->background_color.flags=(char) (DoRed | DoGreen | DoBlue);
3097 (void) XParseColor(display,colormap,(char *) BorderColor,
3098 &pixel->border_color);
3099 status=XParseColor(display,colormap,resource_info->border_color,
3100 &pixel->border_color);
3101 if (status == False)
3102 ThrowXWindowFatalException(XServerError,"ColorIsNotKnownToServer",
3103 resource_info->border_color);
3104 pixel->border_color.pixel=XStandardPixel(map_info,&pixel->border_color);
3105 pixel->border_color.flags=(char) (DoRed | DoGreen | DoBlue);
3109 pixel->matte_color=pixel->background_color;
3110 if (resource_info->matte_color != (char *) NULL)
3113 Matte color is specified as a X resource or command line argument.
3115 status=XParseColor(display,colormap,resource_info->matte_color,
3116 &pixel->matte_color);
3117 if (status == False)
3118 ThrowXWindowFatalException(XServerError,"ColorIsNotKnownToServer",
3119 resource_info->matte_color);
3120 pixel->matte_color.pixel=XStandardPixel(map_info,&pixel->matte_color);
3121 pixel->matte_color.flags=(char) (DoRed | DoGreen | DoBlue);
3124 Set highlight color.
3126 pixel->highlight_color.red=(unsigned short) ((
3127 pixel->matte_color.red*ScaleQuantumToShort(HighlightModulate))/65535L+
3128 (ScaleQuantumToShort((Quantum) (QuantumRange-HighlightModulate))));
3129 pixel->highlight_color.green=(unsigned short) ((
3130 pixel->matte_color.green*ScaleQuantumToShort(HighlightModulate))/65535L+
3131 (ScaleQuantumToShort((Quantum) (QuantumRange-HighlightModulate))));
3132 pixel->highlight_color.blue=(unsigned short) ((
3133 pixel->matte_color.blue*ScaleQuantumToShort(HighlightModulate))/65535L+
3134 (ScaleQuantumToShort((Quantum) (QuantumRange-HighlightModulate))));
3135 pixel->highlight_color.pixel=
3136 XStandardPixel(map_info,&pixel->highlight_color);
3137 pixel->highlight_color.flags=(char) (DoRed | DoGreen | DoBlue);
3141 pixel->shadow_color.red=(unsigned short) (((MagickRealType)
3142 pixel->matte_color.red*ScaleQuantumToShort(ShadowModulate))/65535L);
3143 pixel->shadow_color.green=(unsigned short) (((MagickRealType)
3144 pixel->matte_color.green*ScaleQuantumToShort(ShadowModulate))/65535L);
3145 pixel->shadow_color.blue=(unsigned short) (((MagickRealType)
3146 pixel->matte_color.blue*ScaleQuantumToShort(ShadowModulate))/65535L);
3147 pixel->shadow_color.pixel=XStandardPixel(map_info,&pixel->shadow_color);
3148 pixel->shadow_color.flags=(char) (DoRed | DoGreen | DoBlue);
3152 pixel->depth_color.red=(unsigned short) (((MagickRealType)
3153 pixel->matte_color.red*ScaleQuantumToShort(DepthModulate))/65535L);
3154 pixel->depth_color.green=(unsigned short) (((MagickRealType)
3155 pixel->matte_color.green*ScaleQuantumToShort(DepthModulate))/65535L);
3156 pixel->depth_color.blue=(unsigned short) (((MagickRealType)
3157 pixel->matte_color.blue*ScaleQuantumToShort(DepthModulate))/65535L);
3158 pixel->depth_color.pixel=XStandardPixel(map_info,&pixel->depth_color);
3159 pixel->depth_color.flags=(char) (DoRed | DoGreen | DoBlue);
3163 pixel->trough_color.red=(unsigned short) (((MagickRealType)
3164 pixel->matte_color.red*ScaleQuantumToShort(TroughModulate))/65535L);
3165 pixel->trough_color.green=(unsigned short) (((MagickRealType)
3166 pixel->matte_color.green*ScaleQuantumToShort(TroughModulate))/65535L);
3167 pixel->trough_color.blue=(unsigned short) (((MagickRealType)
3168 pixel->matte_color.blue*ScaleQuantumToShort(TroughModulate))/65535L);
3169 pixel->trough_color.pixel=XStandardPixel(map_info,&pixel->trough_color);
3170 pixel->trough_color.flags=(char) (DoRed | DoGreen | DoBlue);
3174 for (i=0; i < MaxNumberPens; i++)
3176 (void) XParseColor(display,colormap,(char *) PenColors[i],
3177 &pixel->pen_colors[i]);
3178 status=XParseColor(display,colormap,resource_info->pen_colors[i],
3179 &pixel->pen_colors[i]);
3180 if (status == False)
3181 ThrowXWindowFatalException(XServerError,"ColorIsNotKnownToServer",
3182 resource_info->pen_colors[i]);
3183 pixel->pen_colors[i].pixel=XStandardPixel(map_info,&pixel->pen_colors[i]);
3184 pixel->pen_colors[i].flags=(char) (DoRed | DoGreen | DoBlue);
3186 pixel->box_color=pixel->background_color;
3187 pixel->pen_color=pixel->foreground_color;
3190 if (image != (Image *) NULL)
3192 if ((resource_info->gamma_correct != MagickFalse) &&
3193 (image->gamma != 0.0))
3202 Initialize map relative to display and image gamma.
3204 flags=ParseGeometry(resource_info->display_gamma,&geometry_info);
3205 red_gamma=geometry_info.rho;
3206 green_gamma=geometry_info.sigma;
3207 if ((flags & SigmaValue) == 0)
3208 green_gamma=red_gamma;
3209 blue_gamma=geometry_info.xi;
3210 if ((flags & XiValue) == 0)
3211 blue_gamma=red_gamma;
3212 red_gamma*=image->gamma;
3213 green_gamma*=image->gamma;
3214 blue_gamma*=image->gamma;
3216 if (image->storage_class == PseudoClass)
3219 Initialize pixel array for images of type PseudoClass.
3221 for (i=0; i < (ssize_t) image->colors; i++)
3222 pixel->pixels[i]=XGammaPacket(map_info,image->colormap+i);
3223 for (i=0; i < MaxNumberPens; i++)
3224 pixel->pixels[image->colors+i]=pixel->pen_colors[i].pixel;
3225 pixel->colors+=MaxNumberPens;
3231 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3235 % X G e t R e s o u r c e C l a s s %
3239 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3241 % XGetResourceClass() queries the X server for the specified resource name or
3242 % class. If the resource name or class is not defined in the database, the
3243 % supplied default value is returned.
3245 % The format of the XGetResourceClass method is:
3247 % char *XGetResourceClass(XrmDatabase database,const char *client_name,
3248 % const char *keyword,char *resource_default)
3250 % A description of each parameter follows:
3252 % o database: Specifies a resource database; returned from
3253 % XrmGetStringDatabase.
3255 % o client_name: Specifies the application name used to retrieve resource
3256 % info from the X server database.
3258 % o keyword: Specifies the keyword of the value being retrieved.
3260 % o resource_default: Specifies the default value to return if the query
3261 % fails to find the specified keyword/class.
3264 MagickExport char *XGetResourceClass(XrmDatabase database,
3265 const char *client_name,const char *keyword,char *resource_default)
3268 resource_class[MaxTextExtent],
3269 resource_name[MaxTextExtent];
3280 if (database == (XrmDatabase) NULL)
3281 return(resource_default);
3282 *resource_name='\0';
3283 *resource_class='\0';
3284 if (keyword != (char *) NULL)
3291 Initialize resource keyword and class.
3293 (void) FormatLocaleString(resource_name,MaxTextExtent,"%s.%s",
3294 client_name,keyword);
3295 c=(int) (*client_name);
3296 if ((c >= XK_a) && (c <= XK_z))
3299 if ((c >= XK_agrave) && (c <= XK_odiaeresis))
3300 c-=(XK_agrave-XK_Agrave);
3302 if ((c >= XK_oslash) && (c <= XK_thorn))
3303 c-=(XK_oslash-XK_Ooblique);
3305 if ((k >= XK_a) && (k <= XK_z))
3308 if ((k >= XK_agrave) && (k <= XK_odiaeresis))
3309 k-=(XK_agrave-XK_Agrave);
3311 if ((k >= XK_oslash) && (k <= XK_thorn))
3312 k-=(XK_oslash-XK_Ooblique);
3313 (void) FormatLocaleString(resource_class,MaxTextExtent,"%c%s.%c%s",c,
3314 client_name+1,k,keyword+1);
3316 status=XrmGetResource(database,resource_name,resource_class,&resource_type,
3318 if (status == False)
3319 return(resource_default);
3320 return(resource_value.addr);
3324 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3328 % X G e t R e s o u r c e D a t a b a s e %
3332 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3334 % XGetResourceDatabase() creates a new resource database and initializes it.
3336 % The format of the XGetResourceDatabase method is:
3338 % XrmDatabase XGetResourceDatabase(Display *display,
3339 % const char *client_name)
3341 % A description of each parameter follows:
3343 % o database: XGetResourceDatabase() returns the database after it is
3346 % o display: Specifies a connection to an X server; returned from
3349 % o client_name: Specifies the application name used to retrieve resource
3350 % info from the X server database.
3353 MagickExport XrmDatabase XGetResourceDatabase(Display *display,
3354 const char *client_name)
3357 filename[MaxTextExtent];
3369 if (display == (Display *) NULL)
3370 return((XrmDatabase) NULL);
3371 assert(client_name != (char *) NULL);
3373 Initialize resource database.
3376 (void) XGetDefault(display,(char *) client_name,"dummy");
3377 resource_database=XrmGetDatabase(display);
3379 Combine application database.
3381 if (client_name != (char *) NULL)
3384 Get basename of client.
3386 p=client_name+(strlen(client_name)-1);
3387 while ((p > client_name) && (*p != '/'))
3392 c=(int) (*client_name);
3393 if ((c >= XK_a) && (c <= XK_z))
3396 if ((c >= XK_agrave) && (c <= XK_odiaeresis))
3397 c-=(XK_agrave-XK_Agrave);
3399 if ((c >= XK_oslash) && (c <= XK_thorn))
3400 c-=(XK_oslash-XK_Ooblique);
3401 #if defined(X11_APPLICATION_PATH)
3402 (void) FormatLocaleString(filename,MaxTextExtent,"%s%c%s",
3403 X11_APPLICATION_PATH,c,client_name+1);
3404 (void) XrmCombineFileDatabase(filename,&resource_database,MagickFalse);
3406 if (XResourceManagerString(display) != (char *) NULL)
3409 Combine server database.
3411 server_database=XrmGetStringDatabase(XResourceManagerString(display));
3412 XrmCombineDatabase(server_database,&resource_database,MagickFalse);
3415 Merge user preferences database.
3417 #if defined(X11_PREFERENCES_PATH)
3418 (void) FormatLocaleString(filename,MaxTextExtent,"%s%src",
3419 X11_PREFERENCES_PATH,client_name);
3420 ExpandFilename(filename);
3421 (void) XrmCombineFileDatabase(filename,&resource_database,MagickFalse);
3423 return(resource_database);
3427 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3431 % X G e t R e s o u r c e I n f o %
3435 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3437 % XGetResourceInfo(image_info,) initializes the ResourceInfo structure.
3439 % The format of the XGetResourceInfo method is:
3441 % void XGetResourceInfo(const ImageInfo *image_info,XrmDatabase database,
3442 % const char *client_name,XResourceInfo *resource_info)
3444 % A description of each parameter follows:
3446 % o image_info: the image info.
3448 % o database: Specifies a resource database; returned from
3449 % XrmGetStringDatabase.
3451 % o client_name: Specifies the application name used to retrieve
3452 % resource info from the X server database.
3454 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
3457 MagickExport void XGetResourceInfo(const ImageInfo *image_info,
3458 XrmDatabase database,const char *client_name,XResourceInfo *resource_info)
3465 Initialize resource info fields.
3467 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3468 assert(resource_info != (XResourceInfo *) NULL);
3469 (void) ResetMagickMemory(resource_info,0,sizeof(*resource_info));
3470 resource_info->resource_database=database;
3471 resource_info->image_info=(ImageInfo *) image_info;
3472 (void) SetImageInfoProgressMonitor(resource_info->image_info,
3473 XMagickProgressMonitor,(void *) NULL);
3474 resource_info->quantize_info=CloneQuantizeInfo((QuantizeInfo *) NULL);
3475 resource_info->close_server=MagickTrue;
3476 resource_info->client_name=AcquireString(client_name);
3477 resource_value=XGetResourceClass(database,client_name,"backdrop",
3479 resource_info->backdrop=IsMagickTrue(resource_value);
3480 resource_info->background_color=XGetResourceInstance(database,client_name,
3481 "background",(char *) "#d6d6d6d6d6d6");
3482 resource_info->border_color=XGetResourceInstance(database,client_name,
3483 "borderColor",BorderColor);
3484 resource_value=XGetResourceClass(database,client_name,"borderWidth",
3486 resource_info->border_width=(unsigned int) StringToUnsignedLong(
3488 resource_value=XGetResourceClass(database,client_name,"colormap",
3490 resource_info->colormap=UndefinedColormap;
3491 if (LocaleCompare("private",resource_value) == 0)
3492 resource_info->colormap=PrivateColormap;
3493 if (LocaleCompare("shared",resource_value) == 0)
3494 resource_info->colormap=SharedColormap;
3495 if (resource_info->colormap == UndefinedColormap)
3496 ThrowXWindowFatalException(OptionError,"UnrecognizedColormapType",
3498 resource_value=XGetResourceClass(database,client_name,
3499 "colorRecovery",(char *) "False");
3500 resource_info->color_recovery=IsMagickTrue(resource_value);
3501 resource_value=XGetResourceClass(database,client_name,"confirmExit",
3503 resource_info->confirm_exit=IsMagickTrue(resource_value);
3504 resource_value=XGetResourceClass(database,client_name,"confirmEdit",
3506 resource_info->confirm_edit=IsMagickTrue(resource_value);
3507 resource_value=XGetResourceClass(database,client_name,"delay",(char *) "1");
3508 resource_info->delay=(unsigned int) StringToUnsignedLong(resource_value);
3509 resource_info->display_gamma=XGetResourceClass(database,client_name,
3510 "displayGamma",(char *) "2.2");
3511 resource_value=XGetResourceClass(database,client_name,"displayWarnings",
3513 resource_info->display_warnings=IsMagickTrue(resource_value);
3514 resource_info->font=XGetResourceClass(database,client_name,"font",
3516 resource_info->font=XGetResourceClass(database,client_name,"fontList",
3517 resource_info->font);
3518 resource_info->font_name[0]=XGetResourceClass(database,client_name,"font1",
3520 resource_info->font_name[1]=XGetResourceClass(database,client_name,"font2",
3521 (char *) "variable");
3522 resource_info->font_name[2]=XGetResourceClass(database,client_name,"font3",
3524 resource_info->font_name[3]=XGetResourceClass(database,client_name,"font4",
3526 resource_info->font_name[4]=XGetResourceClass(database,client_name,"font5",
3527 (char *) "7x13bold");
3528 resource_info->font_name[5]=XGetResourceClass(database,client_name,"font6",
3529 (char *) "8x13bold");
3530 resource_info->font_name[6]=XGetResourceClass(database,client_name,"font7",
3531 (char *) "9x15bold");
3532 resource_info->font_name[7]=XGetResourceClass(database,client_name,"font8",
3534 resource_info->font_name[8]=XGetResourceClass(database,client_name,"font9",
3536 resource_info->font_name[9]=XGetResourceClass(database,client_name,"font0",
3538 resource_info->font_name[10]=XGetResourceClass(database,client_name,"font0",
3540 resource_info->foreground_color=XGetResourceInstance(database,client_name,
3541 "foreground",ForegroundColor);
3542 resource_value=XGetResourceClass(database,client_name,"gammaCorrect",
3544 resource_info->gamma_correct=IsMagickTrue(resource_value);
3545 resource_info->image_geometry=ConstantString(XGetResourceClass(database,
3546 client_name,"geometry",(char *) NULL));
3547 resource_value=XGetResourceClass(database,client_name,"gravity",
3549 resource_info->gravity=(GravityType) ParseCommandOption(MagickGravityOptions,
3550 MagickFalse,resource_value);
3551 directory=getcwd(resource_info->home_directory,MaxTextExtent);
3553 resource_info->icon_geometry=XGetResourceClass(database,client_name,
3554 "iconGeometry",(char *) NULL);
3555 resource_value=XGetResourceClass(database,client_name,"iconic",
3557 resource_info->iconic=IsMagickTrue(resource_value);
3558 resource_value=XGetResourceClass(database,client_name,"immutable",
3559 LocaleCompare(client_name,"PerlMagick") == 0 ? (char *) "True" :
3561 resource_info->immutable=IsMagickTrue(resource_value);
3562 resource_value=XGetResourceClass(database,client_name,"magnify",
3564 resource_info->magnify=(unsigned int) StringToUnsignedLong(resource_value);
3565 resource_info->map_type=XGetResourceClass(database,client_name,"map",
3567 resource_info->matte_color=XGetResourceInstance(database,client_name,
3568 "mattecolor",(char *) NULL);
3569 resource_info->name=ConstantString(XGetResourceClass(database,client_name,
3570 "name",(char *) NULL));
3571 resource_info->pen_colors[0]=XGetResourceClass(database,client_name,"pen1",
3573 resource_info->pen_colors[1]=XGetResourceClass(database,client_name,"pen2",
3575 resource_info->pen_colors[2]=XGetResourceClass(database,client_name,"pen3",
3577 resource_info->pen_colors[3]=XGetResourceClass(database,client_name,"pen4",
3579 resource_info->pen_colors[4]=XGetResourceClass(database,client_name,"pen5",
3581 resource_info->pen_colors[5]=XGetResourceClass(database,client_name,"pen6",
3583 resource_info->pen_colors[6]=XGetResourceClass(database,client_name,"pen7",
3584 (char *) "magenta");
3585 resource_info->pen_colors[7]=XGetResourceClass(database,client_name,"pen8",
3587 resource_info->pen_colors[8]=XGetResourceClass(database,client_name,"pen9",
3589 resource_info->pen_colors[9]=XGetResourceClass(database,client_name,"pen0",
3591 resource_info->pen_colors[10]=XGetResourceClass(database,client_name,"pen0",
3593 resource_value=XGetResourceClass(database,client_name,"pause",(char *) "0");
3594 resource_info->pause=(unsigned int) StringToUnsignedLong(resource_value);
3595 resource_value=XGetResourceClass(database,client_name,"quantum",(char *) "1");
3596 resource_info->quantum=StringToLong(resource_value);
3597 resource_info->text_font=XGetResourceClass(database,client_name,(char *)
3598 "font",(char *) "fixed");
3599 resource_info->text_font=XGetResourceClass(database,client_name,
3600 "textFontList",resource_info->text_font);
3601 resource_info->title=XGetResourceClass(database,client_name,"title",
3603 resource_value=XGetResourceClass(database,client_name,"undoCache",
3605 resource_info->undo_cache=(unsigned int) StringToUnsignedLong(resource_value);
3606 resource_value=XGetResourceClass(database,client_name,"update",
3608 resource_info->update=IsMagickTrue(resource_value);
3609 resource_value=XGetResourceClass(database,client_name,"usePixmap",
3611 resource_info->use_pixmap=IsMagickTrue(resource_value);
3612 resource_value=XGetResourceClass(database,client_name,"sharedMemory",
3614 resource_info->use_shared_memory=IsMagickTrue(resource_value);
3615 resource_info->visual_type=XGetResourceClass(database,client_name,"visual",
3617 resource_info->window_group=XGetResourceClass(database,client_name,
3618 "windowGroup",(char *) NULL);
3619 resource_info->window_id=XGetResourceClass(database,client_name,"window",
3621 resource_info->write_filename=XGetResourceClass(database,client_name,
3622 "writeFilename",(char *) NULL);
3626 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3630 % X G e t R e s o u r c e I n s t a n c e %
3634 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3636 % XGetResourceInstance() queries the X server for the specified resource name.
3637 % If the resource name is not defined in the database, the supplied default
3638 % value is returned.
3640 % The format of the XGetResourceInstance method is:
3642 % char *XGetResourceInstance(XrmDatabase database,const char *client_name,
3643 % const char *keyword,const char *resource_default)
3645 % A description of each parameter follows:
3647 % o database: Specifies a resource database; returned from
3648 % XrmGetStringDatabase.
3650 % o client_name: Specifies the application name used to retrieve
3651 % resource info from the X server database.
3653 % o keyword: Specifies the keyword of the value being retrieved.
3655 % o resource_default: Specifies the default value to return if the query
3656 % fails to find the specified keyword/class.
3659 MagickExport char *XGetResourceInstance(XrmDatabase database,
3660 const char *client_name,const char *keyword,const char *resource_default)
3664 resource_name[MaxTextExtent];
3672 if (database == (XrmDatabase) NULL)
3673 return((char *) resource_default);
3674 *resource_name='\0';
3675 if (keyword != (char *) NULL)
3676 (void) FormatLocaleString(resource_name,MaxTextExtent,"%s.%s",client_name,
3678 status=XrmGetResource(database,resource_name,"ImageMagick",&resource_type,
3680 if (status == False)
3681 return((char *) resource_default);
3682 return(resource_value.addr);
3686 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3690 % X G e t S c r e e n D e n s i t y %
3694 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3696 % XGetScreenDensity() returns the density of the X server screen in
3699 % The format of the XGetScreenDensity method is:
3701 % char *XGetScreenDensity(Display *display)
3703 % A description of each parameter follows:
3705 % o density: XGetScreenDensity() returns the density of the X screen in
3708 % o display: Specifies a connection to an X server; returned from
3712 MagickExport char *XGetScreenDensity(Display *display)
3715 density[MaxTextExtent];
3722 Set density as determined by screen size.
3724 x_density=((((double) DisplayWidth(display,XDefaultScreen(display)))*25.4)/
3725 ((double) DisplayWidthMM(display,XDefaultScreen(display))));
3726 y_density=((((double) DisplayHeight(display,XDefaultScreen(display)))*25.4)/
3727 ((double) DisplayHeightMM(display,XDefaultScreen(display))));
3728 (void) FormatLocaleString(density,MaxTextExtent,"%gx%g",x_density,
3730 return(GetPageGeometry(density));
3734 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3738 + X G e t S u b w i n d o w %
3742 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3744 % XGetSubwindow() returns the subwindow of a window chosen the user with the
3745 % pointer and a button press.
3747 % The format of the XGetSubwindow method is:
3749 % Window XGetSubwindow(Display *display,Window window,int x,int y)
3751 % A description of each parameter follows:
3753 % o subwindow: XGetSubwindow() returns NULL if no subwindow is found
3754 % otherwise the subwindow is returned.
3756 % o display: Specifies a connection to an X server; returned from
3759 % o window: Specifies a pointer to a Window.
3761 % o x: the x coordinate of the pointer relative to the origin of the
3764 % o y: the y coordinate of the pointer relative to the origin of the
3768 static Window XGetSubwindow(Display *display,Window window,int x,int y)
3781 assert(display != (Display *) NULL);
3782 source_window=XRootWindow(display,XDefaultScreen(display));
3783 if (window == (Window) NULL)
3784 return(source_window);
3785 target_window=window;
3788 status=XTranslateCoordinates(display,source_window,window,x,y,
3789 &x_offset,&y_offset,&target_window);
3792 if (target_window == (Window) NULL)
3794 source_window=window;
3795 window=target_window;
3799 if (target_window == (Window) NULL)
3800 target_window=window;
3801 return(target_window);
3805 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3809 % X G e t W i n d o w C o l o r %
3813 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3815 % XGetWindowColor() returns the color of a pixel interactively chosen from the
3818 % The format of the XGetWindowColor method is:
3820 % MagickBooleanType XGetWindowColor(Display *display,XWindows *windows,
3823 % A description of each parameter follows:
3825 % o display: Specifies a connection to an X server; returned from
3828 % o windows: Specifies a pointer to a XWindows structure.
3830 % o name: the name of the color if found in the X Color Database is
3831 % returned in this character string.
3834 MagickExport MagickBooleanType XGetWindowColor(Display *display,
3835 XWindows *windows,char *name)
3866 Choose a pixel from the X server.
3868 assert(display != (Display *) NULL);
3869 assert(name != (char *) NULL);
3870 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
3872 target_window=XSelectWindow(display,&crop_info);
3873 if (target_window == (Window) NULL)
3874 return(MagickFalse);
3875 root_window=XRootWindow(display,XDefaultScreen(display));
3876 client_window=target_window;
3877 if (target_window != root_window)
3885 status=XGetGeometry(display,target_window,&root_window,&x,&x,&d,&d,&d,&d);
3886 if (status != False)
3888 client_window=XClientWindow(display,target_window);
3889 target_window=client_window;
3893 Verify window is viewable.
3895 status=XGetWindowAttributes(display,target_window,&window_attributes);
3896 if ((status == False) || (window_attributes.map_state != IsViewable))
3897 return(MagickFalse);
3901 (void) XTranslateCoordinates(display,root_window,target_window,
3902 (int) crop_info.x,(int) crop_info.y,&x,&y,&child);
3903 ximage=XGetImage(display,target_window,x,y,1,1,AllPlanes,ZPixmap);
3904 if (ximage == (XImage *) NULL)
3905 return(MagickFalse);
3906 color.pixel=XGetPixel(ximage,0,0);
3907 XDestroyImage(ximage);
3909 Match color against the color database.
3911 (void) XQueryColor(display,window_attributes.colormap,&color);
3912 pixel.red=ScaleShortToQuantum(color.red);
3913 pixel.green=ScaleShortToQuantum(color.green);
3914 pixel.blue=ScaleShortToQuantum(color.blue);
3915 pixel.alpha=OpaqueAlpha;
3916 (void) QueryColorname(windows->image.image,&pixel,X11Compliance,name,
3917 &windows->image.image->exception);
3922 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3926 + X G e t W i n d o w I m a g e %
3930 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3932 % XGetWindowImage() reads an image from the target X window and returns it.
3933 % XGetWindowImage() optionally descends the window hierarchy and overlays the
3934 % target image with each child image in an optimized fashion. Any child
3935 % window that have the same visual, colormap, and are contained by its parent
3938 % The format of the XGetWindowImage method is:
3940 % Image *XGetWindowImage(Display *display,const Window window,
3941 % const unsigned int borders,const unsigned int level)
3943 % A description of each parameter follows:
3945 % o display: Specifies a connection to an X server; returned from
3948 % o window: Specifies the window to obtain the image from.
3950 % o borders: Specifies whether borders pixels are to be saved with
3953 % o level: Specifies an unsigned integer representing the level of
3954 % decent in the window hierarchy. This value must be zero or one on
3955 % the initial call to XGetWindowImage. A value of zero returns after
3956 % one call. A value of one causes the function to descend the window
3957 % hierarchy and overlay the target image with each subwindow image.
3960 static Image *XGetWindowImage(Display *display,const Window window,
3961 const unsigned int borders,const unsigned int level)
3963 typedef struct _ColormapInfo
3971 struct _ColormapInfo
3975 typedef struct _WindowInfo
4011 *colormap_info = (ColormapInfo *) NULL;
4031 Verify window is viewable.
4033 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
4034 assert(display != (Display *) NULL);
4035 status=XGetWindowAttributes(display,window,&window_attributes);
4036 if ((status == False) || (window_attributes.map_state != IsViewable))
4037 return((Image *) NULL);
4039 Cropping rectangle is relative to root window.
4041 root_window=XRootWindow(display,XDefaultScreen(display));
4042 (void) XTranslateCoordinates(display,window,root_window,0,0,&x_offset,
4044 crop_info.x=(ssize_t) x_offset;
4045 crop_info.y=(ssize_t) y_offset;
4046 crop_info.width=(size_t) window_attributes.width;
4047 crop_info.height=(size_t) window_attributes.height;
4048 if (borders != MagickFalse)
4051 Include border in image.
4053 crop_info.x-=(ssize_t) window_attributes.border_width;
4054 crop_info.y-=(ssize_t) window_attributes.border_width;
4055 crop_info.width+=(size_t) (window_attributes.border_width << 1);
4056 crop_info.height+=(size_t) (window_attributes.border_width << 1);
4059 Crop to root window.
4061 if (crop_info.x < 0)
4063 crop_info.width+=crop_info.x;
4066 if (crop_info.y < 0)
4068 crop_info.height+=crop_info.y;
4071 display_width=XDisplayWidth(display,XDefaultScreen(display));
4072 if ((int) (crop_info.x+crop_info.width) > display_width)
4073 crop_info.width=(size_t) (display_width-crop_info.x);
4074 display_height=XDisplayHeight(display,XDefaultScreen(display));
4075 if ((int) (crop_info.y+crop_info.height) > display_height)
4076 crop_info.height=(size_t) (display_height-crop_info.y);
4078 Initialize window info attributes.
4080 if (number_windows >= max_windows)
4083 Allocate or resize window info buffer.
4086 if (window_info == (WindowInfo *) NULL)
4087 window_info=(WindowInfo *) AcquireQuantumMemory((size_t) max_windows,
4088 sizeof(*window_info));
4090 window_info=(WindowInfo *) ResizeQuantumMemory(window_info,(size_t)
4091 max_windows,sizeof(*window_info));
4093 if (window_info == (WindowInfo *) NULL)
4095 ThrowXWindowFatalException(ResourceLimitError,
4096 "MemoryAllocationFailed","...");
4097 return((Image *) NULL);
4099 id=number_windows++;
4100 window_info[id].window=window;
4101 window_info[id].visual=window_attributes.visual;
4102 window_info[id].colormap=window_attributes.colormap;
4103 window_info[id].bounds.x1=(short) crop_info.x;
4104 window_info[id].bounds.y1=(short) crop_info.y;
4105 window_info[id].bounds.x2=(short) (crop_info.x+(int) crop_info.width-1);
4106 window_info[id].bounds.y2=(short) (crop_info.y+(int) crop_info.height-1);
4107 crop_info.x-=x_offset;
4108 crop_info.y-=y_offset;
4109 window_info[id].crop_info=crop_info;
4119 Descend the window hierarchy.
4121 status=XQueryTree(display,window,&root_window,&window_info[id].parent,
4122 &children,&number_children);
4123 for (i=0; i < id; i++)
4124 if ((window_info[i].window == window_info[id].parent) &&
4125 (window_info[i].visual == window_info[id].visual) &&
4126 (window_info[i].colormap == window_info[id].colormap))
4128 if ((window_info[id].bounds.x1 <= window_info[i].bounds.x1) ||
4129 (window_info[id].bounds.x1 >= window_info[i].bounds.x2) ||
4130 (window_info[id].bounds.y1 <= window_info[i].bounds.y1) ||
4131 (window_info[id].bounds.y1 >= window_info[i].bounds.y2))
4134 Eliminate windows not circumscribed by their parent.
4140 if ((status == True) && (number_children != 0))
4142 for (i=0; i < (int) number_children; i++)
4143 (void) XGetWindowImage(display,children[i],MagickFalse,level+1);
4144 (void) XFree((void *) children);
4188 Get X image for each window in the list.
4190 image=NewImageList();
4191 for (id=0; id < number_windows; id++)
4194 Does target window intersect top level window?
4197 ((window_info[id].bounds.x2 >= window_info[0].bounds.x1) &&
4198 (window_info[id].bounds.x1 <= window_info[0].bounds.x2) &&
4199 (window_info[id].bounds.y2 >= window_info[0].bounds.y1) &&
4200 (window_info[id].bounds.y1 <= window_info[0].bounds.y2)) ?
4201 MagickTrue : MagickFalse;
4203 Is target window contained by another window with the same colormap?
4205 for (j=0; j < id; j++)
4206 if ((window_info[id].visual == window_info[j].visual) &&
4207 (window_info[id].colormap == window_info[j].colormap))
4209 if ((window_info[id].bounds.x1 <= window_info[j].bounds.x1) ||
4210 (window_info[id].bounds.x1 >= window_info[j].bounds.x2) ||
4211 (window_info[id].bounds.y1 <= window_info[j].bounds.y1) ||
4212 (window_info[id].bounds.y1 >= window_info[j].bounds.y2))
4216 if ((window_info[id].visual != window_info[j].visual) ||
4217 (window_info[id].colormap != window_info[j].colormap))
4219 if ((window_info[id].bounds.x2 > window_info[j].bounds.x1) &&
4220 (window_info[id].bounds.x1 < window_info[j].bounds.x2) &&
4221 (window_info[id].bounds.y2 > window_info[j].bounds.y1) &&
4222 (window_info[id].bounds.y1 < window_info[j].bounds.y2))
4225 if (import == MagickFalse)
4230 ximage=XGetImage(display,window_info[id].window,(int)
4231 window_info[id].crop_info.x,(int) window_info[id].crop_info.y,
4232 (unsigned int) window_info[id].crop_info.width,(unsigned int)
4233 window_info[id].crop_info.height,AllPlanes,ZPixmap);
4234 if (ximage == (XImage *) NULL)
4237 Initialize window colormap.
4240 colors=(XColor *) NULL;
4241 if (window_info[id].colormap != (Colormap) NULL)
4247 Search colormap list for window colormap.
4249 number_colors=(unsigned int) window_info[id].visual->map_entries;
4250 for (p=colormap_info; p != (ColormapInfo *) NULL; p=p->next)
4251 if (p->colormap == window_info[id].colormap)
4253 if (p == (ColormapInfo *) NULL)
4256 Get the window colormap.
4258 colors=(XColor *) AcquireQuantumMemory(number_colors,
4260 if (colors == (XColor *) NULL)
4262 XDestroyImage(ximage);
4263 return((Image *) NULL);
4265 if ((window_info[id].visual->klass != DirectColor) &&
4266 (window_info[id].visual->klass != TrueColor))
4267 for (i=0; i < (int) number_colors; i++)
4269 colors[i].pixel=(size_t) i;
4283 DirectColor or TrueColor visual.
4288 red_bit=window_info[id].visual->red_mask &
4289 (~(window_info[id].visual->red_mask)+1);
4290 green_bit=window_info[id].visual->green_mask &
4291 (~(window_info[id].visual->green_mask)+1);
4292 blue_bit=window_info[id].visual->blue_mask &
4293 (~(window_info[id].visual->blue_mask)+1);
4294 for (i=0; i < (int) number_colors; i++)
4296 colors[i].pixel=(unsigned long) (red | green | blue);
4299 if (red > window_info[id].visual->red_mask)
4302 if (green > window_info[id].visual->green_mask)
4305 if (blue > window_info[id].visual->blue_mask)
4309 (void) XQueryColors(display,window_info[id].colormap,colors,
4310 (int) number_colors);
4312 Append colormap to colormap list.
4314 p=(ColormapInfo *) AcquireMagickMemory(sizeof(*p));
4315 if (p == (ColormapInfo *) NULL)
4316 return((Image *) NULL);
4317 p->colormap=window_info[id].colormap;
4319 p->next=colormap_info;
4325 Allocate image structure.
4327 composite_image=AcquireImage((ImageInfo *) NULL);
4328 if (composite_image == (Image *) NULL)
4330 XDestroyImage(ximage);
4331 return((Image *) NULL);
4334 Convert X image to MIFF format.
4336 if ((window_info[id].visual->klass != TrueColor) &&
4337 (window_info[id].visual->klass != DirectColor))
4338 composite_image->storage_class=PseudoClass;
4339 composite_image->columns=(size_t) ximage->width;
4340 composite_image->rows=(size_t) ximage->height;
4341 exception=(&composite_image->exception);
4342 composite_view=AcquireCacheView(composite_image);
4343 switch (composite_image->storage_class)
4361 Determine shift and mask for red, green, and blue.
4363 red_mask=window_info[id].visual->red_mask;
4365 while ((red_mask != 0) && ((red_mask & 0x01) == 0))
4370 green_mask=window_info[id].visual->green_mask;
4372 while ((green_mask != 0) && ((green_mask & 0x01) == 0))
4377 blue_mask=window_info[id].visual->blue_mask;
4379 while ((blue_mask != 0) && ((blue_mask & 0x01) == 0))
4385 Convert X image to DirectClass packets.
4387 if ((number_colors != 0) &&
4388 (window_info[id].visual->klass == DirectColor))
4389 for (y=0; y < (int) composite_image->rows; y++)
4391 q=QueueCacheViewAuthenticPixels(composite_view,0,(ssize_t) y,
4392 composite_image->columns,1,exception);
4393 if (q == (const Quantum *) NULL)
4395 for (x=0; x < (int) composite_image->columns; x++)
4397 pixel=XGetPixel(ximage,x,y);
4398 index=(pixel >> red_shift) & red_mask;
4399 SetPixelRed(composite_image,
4400 ScaleShortToQuantum(colors[index].red),q);
4401 index=(pixel >> green_shift) & green_mask;
4402 SetPixelGreen(composite_image,
4403 ScaleShortToQuantum(colors[index].green),q);
4404 index=(pixel >> blue_shift) & blue_mask;
4405 SetPixelBlue(composite_image,
4406 ScaleShortToQuantum(colors[index].blue),q);
4407 q+=GetPixelChannels(composite_image);
4409 if (SyncCacheViewAuthenticPixels(composite_view,exception) == MagickFalse)
4413 for (y=0; y < (int) composite_image->rows; y++)
4415 q=QueueCacheViewAuthenticPixels(composite_view,0,(ssize_t) y,
4416 composite_image->columns,1,exception);
4417 if (q == (const Quantum *) NULL)
4419 for (x=0; x < (int) composite_image->columns; x++)
4421 pixel=XGetPixel(ximage,x,y);
4422 color=(pixel >> red_shift) & red_mask;
4423 color=(65535UL*color)/red_mask;
4424 SetPixelRed(composite_image,
4425 ScaleShortToQuantum((unsigned short) color),q);
4426 color=(pixel >> green_shift) & green_mask;
4427 color=(65535UL*color)/green_mask;
4428 SetPixelGreen(composite_image,
4429 ScaleShortToQuantum((unsigned short) color),q);
4430 color=(pixel >> blue_shift) & blue_mask;
4431 color=(65535UL*color)/blue_mask;
4432 SetPixelBlue(composite_image,
4433 ScaleShortToQuantum((unsigned short) color),q);
4434 q+=GetPixelChannels(composite_image);
4436 if (SyncCacheViewAuthenticPixels(composite_view,exception) == MagickFalse)
4446 if (AcquireImageColormap(composite_image,number_colors) == MagickFalse)
4448 XDestroyImage(ximage);
4449 composite_image=DestroyImage(composite_image);
4450 return((Image *) NULL);
4452 for (i=0; i < (int) composite_image->colors; i++)
4454 composite_image->colormap[colors[i].pixel].red=
4455 ScaleShortToQuantum(colors[i].red);
4456 composite_image->colormap[colors[i].pixel].green=
4457 ScaleShortToQuantum(colors[i].green);
4458 composite_image->colormap[colors[i].pixel].blue=
4459 ScaleShortToQuantum(colors[i].blue);
4462 Convert X image to PseudoClass packets.
4464 for (y=0; y < (int) composite_image->rows; y++)
4466 q=QueueCacheViewAuthenticPixels(composite_view,0,(ssize_t) y,
4467 composite_image->columns,1,exception);
4468 if (q == (const Quantum *) NULL)
4470 for (x=0; x < (int) composite_image->columns; x++)
4472 index=(Quantum) XGetPixel(ximage,x,y);
4473 SetPixelIndex(composite_image,index,q);
4474 SetPixelPacket(composite_image,
4475 composite_image->colormap+(ssize_t) index,q);
4476 q+=GetPixelChannels(composite_image);
4478 if (SyncCacheViewAuthenticPixels(composite_view,exception) == MagickFalse)
4484 composite_view=DestroyCacheView(composite_view);
4485 XDestroyImage(ximage);
4486 if (image == (Image *) NULL)
4488 image=composite_image;
4492 Composite any children in back-to-front order.
4494 (void) XTranslateCoordinates(display,window_info[id].window,window,0,0,
4495 &x_offset,&y_offset,&child);
4496 x_offset-=(int) crop_info.x;
4499 y_offset-=(int) crop_info.y;
4502 (void) CompositeImage(image,CopyCompositeOp,composite_image,(ssize_t)
4503 x_offset,(ssize_t) y_offset);
4506 Relinquish resources.
4508 while (colormap_info != (ColormapInfo *) NULL)
4510 next=colormap_info->next;
4511 colormap_info->colors=(XColor *)
4512 RelinquishMagickMemory(colormap_info->colors);
4513 colormap_info=(ColormapInfo *) RelinquishMagickMemory(colormap_info);
4517 Relinquish resources and restore initial state.
4519 window_info=(WindowInfo *) RelinquishMagickMemory(window_info);
4522 colormap_info=(ColormapInfo *) NULL;
4525 return((Image *) NULL);
4529 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4533 % X G e t W i n d o w I n f o %
4537 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4539 % XGetWindowInfo() initializes the XWindowInfo structure.
4541 % The format of the XGetWindowInfo method is:
4543 % void XGetWindowInfo(Display *display,XVisualInfo *visual_info,
4544 % XStandardColormap *map_info,XPixelInfo *pixel,XFontStruct *font_info,
4545 % XResourceInfo *resource_info,XWindowInfo *window)
4546 % resource_info,window)
4548 % A description of each parameter follows:
4550 % o display: Specifies a connection to an X server; returned from
4553 % o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
4554 % returned from XGetVisualInfo.
4556 % o map_info: If map_type is specified, this structure is initialized
4557 % with info from the Standard Colormap.
4559 % o pixel: Specifies a pointer to a XPixelInfo structure.
4561 % o font_info: Specifies a pointer to a XFontStruct structure.
4563 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
4566 MagickExport void XGetWindowInfo(Display *display,XVisualInfo *visual_info,
4567 XStandardColormap *map_info,XPixelInfo *pixel,XFontStruct *font_info,
4568 XResourceInfo *resource_info,XWindowInfo *window)
4571 Initialize window info.
4573 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
4574 assert(display != (Display *) NULL);
4575 assert(visual_info != (XVisualInfo *) NULL);
4576 assert(map_info != (XStandardColormap *) NULL);
4577 assert(pixel != (XPixelInfo *) NULL);
4578 assert(resource_info != (XResourceInfo *) NULL);
4579 assert(window != (XWindowInfo *) NULL);
4580 if (window->id != (Window) NULL)
4582 if (window->cursor != (Cursor) NULL)
4583 (void) XFreeCursor(display,window->cursor);
4584 if (window->busy_cursor != (Cursor) NULL)
4585 (void) XFreeCursor(display,window->busy_cursor);
4586 if (window->highlight_stipple != (Pixmap) NULL)
4587 (void) XFreePixmap(display,window->highlight_stipple);
4588 if (window->shadow_stipple != (Pixmap) NULL)
4589 (void) XFreePixmap(display,window->shadow_stipple);
4590 if (window->name == (char *) NULL)
4591 window->name=AcquireString("");
4592 if (window->icon_name == (char *) NULL)
4593 window->icon_name=AcquireString("");
4598 Initialize these attributes just once.
4600 window->id=(Window) NULL;
4601 if (window->name == (char *) NULL)
4602 window->name=AcquireString("");
4603 if (window->icon_name == (char *) NULL)
4604 window->icon_name=AcquireString("");
4605 window->x=XDisplayWidth(display,visual_info->screen) >> 1;
4606 window->y=XDisplayWidth(display,visual_info->screen) >> 1;
4607 window->ximage=(XImage *) NULL;
4608 window->matte_image=(XImage *) NULL;
4609 window->pixmap=(Pixmap) NULL;
4610 window->matte_pixmap=(Pixmap) NULL;
4611 window->mapped=MagickFalse;
4612 window->stasis=MagickFalse;
4613 window->shared_memory=MagickTrue;
4614 window->segment_info=(void *) NULL;
4615 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
4620 if (window->segment_info == (void *) NULL)
4621 window->segment_info=AcquireQuantumMemory(2,sizeof(*segment_info));
4622 segment_info=(XShmSegmentInfo *) window->segment_info;
4623 segment_info[0].shmid=(-1);
4624 segment_info[0].shmaddr=(char *) NULL;
4625 segment_info[1].shmid=(-1);
4626 segment_info[1].shmaddr=(char *) NULL;
4631 Initialize these attributes every time function is called.
4633 window->screen=visual_info->screen;
4634 window->root=XRootWindow(display,visual_info->screen);
4635 window->visual=visual_info->visual;
4636 window->storage_class=(unsigned int) visual_info->klass;
4637 window->depth=(unsigned int) visual_info->depth;
4638 window->visual_info=visual_info;
4639 window->map_info=map_info;
4640 window->pixel_info=pixel;
4641 window->font_info=font_info;
4642 window->cursor=XCreateFontCursor(display,XC_left_ptr);
4643 window->busy_cursor=XCreateFontCursor(display,XC_watch);
4644 window->geometry=(char *) NULL;
4645 window->icon_geometry=(char *) NULL;
4646 if (resource_info->icon_geometry != (char *) NULL)
4647 (void) CloneString(&window->icon_geometry,resource_info->icon_geometry);
4648 window->crop_geometry=(char *) NULL;
4649 window->flags=(size_t) PSize;
4652 window->min_width=1;
4653 window->min_height=1;
4654 window->width_inc=1;
4655 window->height_inc=1;
4656 window->border_width=resource_info->border_width;
4657 window->annotate_context=pixel->annotate_context;
4658 window->highlight_context=pixel->highlight_context;
4659 window->widget_context=pixel->widget_context;
4660 window->shadow_stipple=(Pixmap) NULL;
4661 window->highlight_stipple=(Pixmap) NULL;
4662 window->use_pixmap=MagickTrue;
4663 window->immutable=MagickFalse;
4664 window->shape=MagickFalse;
4666 window->mask=(int) (CWBackingStore | CWBackPixel | CWBackPixmap |
4667 CWBitGravity | CWBorderPixel | CWColormap | CWCursor | CWDontPropagate |
4668 CWEventMask | CWOverrideRedirect | CWSaveUnder | CWWinGravity);
4669 window->attributes.background_pixel=pixel->background_color.pixel;
4670 window->attributes.background_pixmap=(Pixmap) NULL;
4671 window->attributes.bit_gravity=ForgetGravity;
4672 window->attributes.backing_store=WhenMapped;
4673 window->attributes.save_under=MagickTrue;
4674 window->attributes.border_pixel=pixel->border_color.pixel;
4675 window->attributes.colormap=map_info->colormap;
4676 window->attributes.cursor=window->cursor;
4677 window->attributes.do_not_propagate_mask=NoEventMask;
4678 window->attributes.event_mask=NoEventMask;
4679 window->attributes.override_redirect=MagickFalse;
4680 window->attributes.win_gravity=NorthWestGravity;
4681 window->orphan=MagickFalse;
4685 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4689 % X H i g h l i g h t E l l i p s e %
4693 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4695 % XHighlightEllipse() puts a border on the X server around a region defined by
4698 % The format of the XHighlightEllipse method is:
4700 % void XHighlightEllipse(Display *display,Window window,
4701 % GC annotate_context,const RectangleInfo *highlight_info)
4703 % A description of each parameter follows:
4705 % o display: Specifies a connection to an X server; returned from
4708 % o window: Specifies a pointer to a Window structure.
4710 % o annotate_context: Specifies a pointer to a GC structure.
4712 % o highlight_info: Specifies a pointer to a RectangleInfo structure. It
4713 % contains the extents of any highlighting rectangle.
4716 MagickExport void XHighlightEllipse(Display *display,Window window,
4717 GC annotate_context,const RectangleInfo *highlight_info)
4719 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
4720 assert(display != (Display *) NULL);
4721 assert(window != (Window) NULL);
4722 assert(annotate_context != (GC) NULL);
4723 assert(highlight_info != (RectangleInfo *) NULL);
4724 if ((highlight_info->width < 4) || (highlight_info->height < 4))
4726 (void) XDrawArc(display,window,annotate_context,(int) highlight_info->x,
4727 (int) highlight_info->y,(unsigned int) highlight_info->width-1,
4728 (unsigned int) highlight_info->height-1,0,360*64);
4729 (void) XDrawArc(display,window,annotate_context,(int) highlight_info->x+1,
4730 (int) highlight_info->y+1,(unsigned int) highlight_info->width-3,
4731 (unsigned int) highlight_info->height-3,0,360*64);
4735 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4739 % X H i g h l i g h t L i n e %
4743 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4745 % XHighlightLine() puts a border on the X server around a region defined by
4748 % The format of the XHighlightLine method is:
4750 % void XHighlightLine(Display *display,Window window,GC annotate_context,
4751 % const XSegment *highlight_info)
4753 % A description of each parameter follows:
4755 % o display: Specifies a connection to an X server; returned from
4758 % o window: Specifies a pointer to a Window structure.
4760 % o annotate_context: Specifies a pointer to a GC structure.
4762 % o highlight_info: Specifies a pointer to a RectangleInfo structure. It
4763 % contains the extents of any highlighting rectangle.
4766 MagickExport void XHighlightLine(Display *display,Window window,
4767 GC annotate_context,const XSegment *highlight_info)
4769 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
4770 assert(display != (Display *) NULL);
4771 assert(window != (Window) NULL);
4772 assert(annotate_context != (GC) NULL);
4773 assert(highlight_info != (XSegment *) NULL);
4774 (void) XDrawLine(display,window,annotate_context,highlight_info->x1,
4775 highlight_info->y1,highlight_info->x2,highlight_info->y2);
4779 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4783 % X H i g h l i g h t R e c t a n g l e %
4787 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4789 % XHighlightRectangle() puts a border on the X server around a region defined
4790 % by highlight_info.
4792 % The format of the XHighlightRectangle method is:
4794 % void XHighlightRectangle(Display *display,Window window,
4795 % GC annotate_context,const RectangleInfo *highlight_info)
4797 % A description of each parameter follows:
4799 % o display: Specifies a connection to an X server; returned from
4802 % o window: Specifies a pointer to a Window structure.
4804 % o annotate_context: Specifies a pointer to a GC structure.
4806 % o highlight_info: Specifies a pointer to a RectangleInfo structure. It
4807 % contains the extents of any highlighting rectangle.
4810 MagickExport void XHighlightRectangle(Display *display,Window window,
4811 GC annotate_context,const RectangleInfo *highlight_info)
4813 assert(display != (Display *) NULL);
4814 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
4815 assert(window != (Window) NULL);
4816 assert(annotate_context != (GC) NULL);
4817 assert(highlight_info != (RectangleInfo *) NULL);
4818 if ((highlight_info->width < 4) || (highlight_info->height < 4))
4820 (void) XDrawRectangle(display,window,annotate_context,(int) highlight_info->x,
4821 (int) highlight_info->y,(unsigned int) highlight_info->width-1,
4822 (unsigned int) highlight_info->height-1);
4823 (void) XDrawRectangle(display,window,annotate_context,(int) highlight_info->x+
4824 1,(int) highlight_info->y+1,(unsigned int) highlight_info->width-3,
4825 (unsigned int) highlight_info->height-3);
4829 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4833 % X I m p o r t I m a g e %
4837 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4839 % XImportImage() reads an image from an X window.
4841 % The format of the XImportImage method is:
4843 % Image *XImportImage(const ImageInfo *image_info,XImportInfo *ximage_info)
4845 % A description of each parameter follows:
4847 % o image_info: the image info.
4849 % o ximage_info: Specifies a pointer to an XImportInfo structure.
4852 MagickExport Image *XImportImage(const ImageInfo *image_info,
4853 XImportInfo *ximage_info)
4886 Open X server connection.
4888 assert(image_info != (const ImageInfo *) NULL);
4889 assert(image_info->signature == MagickSignature);
4890 if (image_info->debug != MagickFalse)
4891 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
4892 image_info->filename);
4893 assert(ximage_info != (XImportInfo *) NULL);
4894 display=XOpenDisplay(image_info->server_name);
4895 if (display == (Display *) NULL)
4897 ThrowXWindowFatalException(XServerError,"UnableToOpenXServer",
4898 XDisplayName(image_info->server_name));
4899 return((Image *) NULL);
4902 Set our forgiving exception handler.
4904 (void) XSetErrorHandler(XError);
4906 Select target window.
4912 root=XRootWindow(display,XDefaultScreen(display));
4913 target=(Window) NULL;
4914 if ((image_info->filename != (char *) NULL) &&
4915 (*image_info->filename != '\0'))
4917 if (LocaleCompare(image_info->filename,"root") == 0)
4922 Select window by ID or name.
4924 if (isdigit((unsigned char) *image_info->filename) != 0)
4925 target=XWindowByID(display,root,(Window)
4926 strtol(image_info->filename,(char **) NULL,0));
4927 if (target == (Window) NULL)
4928 target=XWindowByName(display,root,image_info->filename);
4929 if (target == (Window) NULL)
4930 ThrowXWindowFatalException(XServerError,
4931 "NoWindowWithSpecifiedIDExists",image_info->filename);
4935 If target window is not defined, interactively select one.
4937 prior_target=target;
4938 if (target == (Window) NULL)
4939 target=XSelectWindow(display,&crop_info);
4940 if (target == (Window) NULL)
4941 ThrowXWindowFatalException(XServerError,"UnableToReadXWindowImage",
4942 image_info->filename);
4943 client=target; /* obsolete */
4949 status=XGetGeometry(display,target,&root,&x,&x,&d,&d,&d,&d);
4950 if (status != False)
4958 Find window manager frame.
4960 status=XQueryTree(display,target,&root,&parent,&children,&d);
4961 if ((status != False) && (children != (Window *) NULL))
4962 (void) XFree((char *) children);
4963 if ((status == False) || (parent == (Window) NULL) ||
4971 client=XClientWindow(display,target);
4972 if (ximage_info->frame == MagickFalse)
4974 if ((ximage_info->frame == MagickFalse) &&
4975 (prior_target != MagickFalse))
4976 target=prior_target;
4977 XDelay(display,SuspendTime << 4);
4980 if (ximage_info->screen)
4992 Obtain window image directly from screen.
4994 status=XGetWindowAttributes(display,target,&window_attributes);
4995 if (status == False)
4997 ThrowXWindowFatalException(XServerError,
4998 "UnableToReadXWindowAttributes",image_info->filename);
4999 (void) XCloseDisplay(display);
5000 return((Image *) NULL);
5002 (void) XTranslateCoordinates(display,target,root,0,0,&x,&y,&child);
5003 crop_info.x=(ssize_t) x;
5004 crop_info.y=(ssize_t) y;
5005 crop_info.width=(size_t) window_attributes.width;
5006 crop_info.height=(size_t) window_attributes.height;
5007 if (ximage_info->borders != 0)
5010 Include border in image.
5012 crop_info.x-=window_attributes.border_width;
5013 crop_info.y-=window_attributes.border_width;
5014 crop_info.width+=window_attributes.border_width << 1;
5015 crop_info.height+=window_attributes.border_width << 1;
5020 If WM_COLORMAP_WINDOWS property is set or multiple colormaps, descend.
5023 status=XGetWMColormapWindows(display,target,&children,&number_windows);
5024 if ((status == True) && (number_windows > 0))
5026 ximage_info->descend=MagickTrue;
5027 (void) XFree ((char *) children);
5029 colormaps=XListInstalledColormaps(display,target,&number_colormaps);
5030 if (number_colormaps > 0)
5032 if (number_colormaps > 1)
5033 ximage_info->descend=MagickTrue;
5034 (void) XFree((char *) colormaps);
5037 Alert the user not to alter the screen.
5039 if (ximage_info->silent == MagickFalse)
5040 (void) XBell(display,0);
5042 Get image by window id.
5044 (void) XGrabServer(display);
5045 image=XGetWindowImage(display,target,ximage_info->borders,
5046 ximage_info->descend ? 1U : 0U);
5047 (void) XUngrabServer(display);
5048 if (image == (Image *) NULL)
5049 ThrowXWindowFatalException(XServerError,"UnableToReadXWindowImage",
5050 image_info->filename)
5053 (void) CopyMagickString(image->filename,image_info->filename,
5055 if ((crop_info.width != 0) && (crop_info.height != 0))
5062 Crop image as defined by the cropping rectangle.
5064 clone_image=CloneImage(image,0,0,MagickTrue,&image->exception);
5065 if (clone_image != (Image *) NULL)
5067 crop_image=CropImage(clone_image,&crop_info,&image->exception);
5068 if (crop_image != (Image *) NULL)
5070 image=DestroyImage(image);
5075 status=XGetWMName(display,target,&window_name);
5078 if ((image_info->filename != (char *) NULL) &&
5079 (*image_info->filename == '\0'))
5080 (void) CopyMagickString(image->filename,(char *) window_name.value,
5081 (size_t) window_name.nitems+1);
5082 (void) XFree((void *) window_name.value);
5085 if (ximage_info->silent == MagickFalse)
5088 Alert the user we're done.
5090 (void) XBell(display,0);
5091 (void) XBell(display,0);
5093 (void) XCloseDisplay(display);
5098 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5102 % X I n i t i a l i z e W i n d o w s %
5106 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5108 % XInitializeWindows() initializes the XWindows structure.
5110 % The format of the XInitializeWindows method is:
5112 % XWindows *XInitializeWindows(Display *display,
5113 % XResourceInfo *resource_info)
5115 % A description of each parameter follows:
5117 % o windows: XInitializeWindows returns a pointer to a XWindows structure.
5119 % o display: Specifies a connection to an X server; returned from
5122 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
5125 MagickExport XWindows *XInitializeWindows(Display *display,
5126 XResourceInfo *resource_info)
5135 Allocate windows structure.
5137 windows=(XWindows *) AcquireMagickMemory(sizeof(*windows));
5138 if (windows == (XWindows *) NULL)
5140 ThrowXWindowFatalException(XServerFatalError,"MemoryAllocationFailed",
5142 return((XWindows *) NULL);
5144 (void) ResetMagickMemory(windows,0,sizeof(*windows));
5145 windows->pixel_info=(XPixelInfo *) AcquireMagickMemory(
5146 sizeof(*windows->pixel_info));
5147 windows->icon_pixel=(XPixelInfo *) AcquireMagickMemory(
5148 sizeof(*windows->icon_pixel));
5149 windows->icon_resources=(XResourceInfo *) AcquireMagickMemory(
5150 sizeof(*windows->icon_resources));
5151 if ((windows->pixel_info == (XPixelInfo *) NULL) ||
5152 (windows->icon_pixel == (XPixelInfo *) NULL) ||
5153 (windows->icon_resources == (XResourceInfo *) NULL))
5155 ThrowXWindowFatalException(XServerFatalError,"MemoryAllocationFailed",
5157 return((XWindows *) NULL);
5160 Initialize windows structure.
5162 windows->display=display;
5163 windows->wm_protocols=XInternAtom(display,"WM_PROTOCOLS",MagickFalse);
5164 windows->wm_delete_window=XInternAtom(display,"WM_DELETE_WINDOW",MagickFalse);
5165 windows->wm_take_focus=XInternAtom(display,"WM_TAKE_FOCUS",MagickFalse);
5166 windows->im_protocols=XInternAtom(display,"IM_PROTOCOLS",MagickFalse);
5167 windows->im_remote_command=
5168 XInternAtom(display,"IM_REMOTE_COMMAND",MagickFalse);
5169 windows->im_update_widget=XInternAtom(display,"IM_UPDATE_WIDGET",MagickFalse);
5170 windows->im_update_colormap=
5171 XInternAtom(display,"IM_UPDATE_COLORMAP",MagickFalse);
5172 windows->im_former_image=XInternAtom(display,"IM_FORMER_IMAGE",MagickFalse);
5173 windows->im_next_image=XInternAtom(display,"IM_NEXT_IMAGE",MagickFalse);
5174 windows->im_retain_colors=XInternAtom(display,"IM_RETAIN_COLORS",MagickFalse);
5175 windows->im_exit=XInternAtom(display,"IM_EXIT",MagickFalse);
5176 windows->dnd_protocols=XInternAtom(display,"DndProtocol",MagickFalse);
5177 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
5178 (void) XSynchronize(display,IsWindows95());
5180 if (IsEventLogging())
5182 (void) XSynchronize(display,MagickTrue);
5183 (void) LogMagickEvent(X11Event,GetMagickModule(),"Version: %s",
5184 GetMagickVersion((size_t *) NULL));
5185 (void) LogMagickEvent(X11Event,GetMagickModule(),"Protocols:");
5186 (void) LogMagickEvent(X11Event,GetMagickModule(),
5187 " Window Manager: 0x%lx",windows->wm_protocols);
5188 (void) LogMagickEvent(X11Event,GetMagickModule(),
5189 " delete window: 0x%lx",windows->wm_delete_window);
5190 (void) LogMagickEvent(X11Event,GetMagickModule()," take focus: 0x%lx",
5191 windows->wm_take_focus);
5192 (void) LogMagickEvent(X11Event,GetMagickModule()," ImageMagick: 0x%lx",
5193 windows->im_protocols);
5194 (void) LogMagickEvent(X11Event,GetMagickModule(),
5195 " remote command: 0x%lx",windows->im_remote_command);
5196 (void) LogMagickEvent(X11Event,GetMagickModule(),
5197 " update widget: 0x%lx",windows->im_update_widget);
5198 (void) LogMagickEvent(X11Event,GetMagickModule(),
5199 " update colormap: 0x%lx",windows->im_update_colormap);
5200 (void) LogMagickEvent(X11Event,GetMagickModule(),
5201 " former image: 0x%lx",windows->im_former_image);
5202 (void) LogMagickEvent(X11Event,GetMagickModule()," next image: 0x%lx",
5203 windows->im_next_image);
5204 (void) LogMagickEvent(X11Event,GetMagickModule(),
5205 " retain colors: 0x%lx",windows->im_retain_colors);
5206 (void) LogMagickEvent(X11Event,GetMagickModule()," exit: 0x%lx",
5208 (void) LogMagickEvent(X11Event,GetMagickModule()," Drag and Drop: 0x%lx",
5209 windows->dnd_protocols);
5212 Allocate standard colormap.
5214 windows->map_info=XAllocStandardColormap();
5215 windows->icon_map=XAllocStandardColormap();
5216 if ((windows->map_info == (XStandardColormap *) NULL) ||
5217 (windows->icon_map == (XStandardColormap *) NULL))
5218 ThrowXWindowFatalException(ResourceLimitFatalError,
5219 "MemoryAllocationFailed","...");
5220 windows->map_info->colormap=(Colormap) NULL;
5221 windows->icon_map->colormap=(Colormap) NULL;
5222 windows->pixel_info->pixels=(unsigned long *) NULL;
5223 windows->pixel_info->annotate_context=(GC) NULL;
5224 windows->pixel_info->highlight_context=(GC) NULL;
5225 windows->pixel_info->widget_context=(GC) NULL;
5226 windows->font_info=(XFontStruct *) NULL;
5227 windows->icon_pixel->annotate_context=(GC) NULL;
5228 windows->icon_pixel->pixels=(unsigned long *) NULL;
5232 *windows->icon_resources=(*resource_info);
5233 windows->icon_resources->visual_type=(char *) "default";
5234 windows->icon_resources->colormap=SharedColormap;
5235 windows->visual_info=
5236 XBestVisualInfo(display,windows->map_info,resource_info);
5237 windows->icon_visual=
5238 XBestVisualInfo(display,windows->icon_map,windows->icon_resources);
5239 if ((windows->visual_info == (XVisualInfo *) NULL) ||
5240 (windows->icon_visual == (XVisualInfo *) NULL))
5241 ThrowXWindowFatalException(XServerFatalError,"UnableToGetVisual",
5242 resource_info->visual_type);
5243 if (IsEventLogging())
5245 (void) LogMagickEvent(X11Event,GetMagickModule(),"Visual:");
5246 (void) LogMagickEvent(X11Event,GetMagickModule()," visual id: 0x%lx",
5247 windows->visual_info->visualid);
5248 (void) LogMagickEvent(X11Event,GetMagickModule()," class: %s",
5249 XVisualClassName(windows->visual_info->klass));
5250 (void) LogMagickEvent(X11Event,GetMagickModule()," depth: %d planes",
5251 windows->visual_info->depth);
5252 (void) LogMagickEvent(X11Event,GetMagickModule(),
5253 " size of colormap: %d entries",windows->visual_info->colormap_size);
5254 (void) LogMagickEvent(X11Event,GetMagickModule(),
5255 " red, green, blue masks: 0x%lx 0x%lx 0x%lx",
5256 windows->visual_info->red_mask,windows->visual_info->green_mask,
5257 windows->visual_info->blue_mask);
5258 (void) LogMagickEvent(X11Event,GetMagickModule(),
5259 " significant bits in color: %d bits",
5260 windows->visual_info->bits_per_rgb);
5263 Allocate class and manager hints.
5265 windows->class_hints=XAllocClassHint();
5266 windows->manager_hints=XAllocWMHints();
5267 if ((windows->class_hints == (XClassHint *) NULL) ||
5268 (windows->manager_hints == (XWMHints *) NULL))
5269 ThrowXWindowFatalException(ResourceLimitFatalError,
5270 "MemoryAllocationFailed","...");
5272 Determine group leader if we have one.
5274 root_window=XRootWindow(display,windows->visual_info->screen);
5275 windows->group_leader.id=(Window) NULL;
5276 if (resource_info->window_group != (char *) NULL)
5278 if (isdigit((unsigned char) *resource_info->window_group) != 0)
5279 windows->group_leader.id=XWindowByID(display,root_window,(Window)
5280 strtol((char *) resource_info->window_group,(char **) NULL,0));
5281 if (windows->group_leader.id == (Window) NULL)
5282 windows->group_leader.id=
5283 XWindowByName(display,root_window,resource_info->window_group);
5289 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5293 % X M a k e C u r s o r %
5297 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5299 % XMakeCursor() creates a crosshairs X11 cursor.
5301 % The format of the XMakeCursor method is:
5303 % Cursor XMakeCursor(Display *display,Window window,Colormap colormap,
5304 % char *background_color,char *foreground_color)
5306 % A description of each parameter follows:
5308 % o display: Specifies a connection to an X server; returned from
5311 % o window: Specifies the ID of the window for which the cursor is
5314 % o colormap: Specifies the ID of the colormap from which the background
5315 % and foreground color will be retrieved.
5317 % o background_color: Specifies the color to use for the cursor background.
5319 % o foreground_color: Specifies the color to use for the cursor foreground.
5322 MagickExport Cursor XMakeCursor(Display *display,Window window,
5323 Colormap colormap,char *background_color,char *foreground_color)
5325 #define scope_height 17
5326 #define scope_x_hot 8
5327 #define scope_y_hot 8
5328 #define scope_width 17
5330 static const unsigned char
5333 0x80, 0x03, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02,
5334 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x7f,
5335 0xfc, 0x01, 0x01, 0x00, 0x01, 0x7f, 0xfc, 0x01, 0x80, 0x02, 0x00,
5336 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02,
5337 0x00, 0x80, 0x02, 0x00, 0x80, 0x03, 0x00
5341 0xc0, 0x07, 0x00, 0xc0, 0x07, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06,
5342 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xff, 0xfe, 0x01, 0x7f,
5343 0xfc, 0x01, 0x03, 0x80, 0x01, 0x7f, 0xfc, 0x01, 0xff, 0xfe, 0x01,
5344 0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06,
5345 0x00, 0xc0, 0x07, 0x00, 0xc0, 0x07, 0x00
5359 assert(display != (Display *) NULL);
5360 assert(window != (Window) NULL);
5361 assert(colormap != (Colormap) NULL);
5362 assert(background_color != (char *) NULL);
5363 assert(foreground_color != (char *) NULL);
5364 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",background_color);
5365 source=XCreateBitmapFromData(display,window,(char *) scope_bits,scope_width,
5367 mask=XCreateBitmapFromData(display,window,(char *) scope_mask_bits,
5368 scope_width,scope_height);
5369 if ((source == (Pixmap) NULL) || (mask == (Pixmap) NULL))
5371 ThrowXWindowFatalException(XServerError,"UnableToCreatePixmap","...");
5372 return((Cursor) NULL);
5374 (void) XParseColor(display,colormap,background_color,&background);
5375 (void) XParseColor(display,colormap,foreground_color,&foreground);
5376 cursor=XCreatePixmapCursor(display,source,mask,&foreground,&background,
5377 scope_x_hot,scope_y_hot);
5378 (void) XFreePixmap(display,source);
5379 (void) XFreePixmap(display,mask);
5384 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5388 % X M a k e I m a g e %
5392 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5394 % XMakeImage() creates an X11 image. If the image size differs from the X11
5395 % image size, the image is first resized.
5397 % The format of the XMakeImage method is:
5399 % MagickBooleanType XMakeImage(Display *display,
5400 % const XResourceInfo *resource_info,XWindowInfo *window,Image *image,
5401 % unsigned int width,unsigned int height)
5403 % A description of each parameter follows:
5405 % o display: Specifies a connection to an X server; returned from
5408 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
5410 % o window: Specifies a pointer to a XWindowInfo structure.
5412 % o image: the image.
5414 % o width: Specifies the width in pixels of the rectangular area to
5417 % o height: Specifies the height in pixels of the rectangular area to
5421 MagickExport MagickBooleanType XMakeImage(Display *display,
5422 const XResourceInfo *resource_info,XWindowInfo *window,Image *image,
5423 unsigned int width,unsigned int height)
5425 #define CheckOverflowException(length,width,height) \
5426 (((height) != 0) && ((length)/((size_t) height) != ((size_t) width)))
5439 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
5440 assert(display != (Display *) NULL);
5441 assert(resource_info != (XResourceInfo *) NULL);
5442 assert(window != (XWindowInfo *) NULL);
5444 assert(height != 0);
5445 if ((window->width == 0) || (window->height == 0))
5446 return(MagickFalse);
5448 Apply user transforms to the image.
5450 (void) XCheckDefineCursor(display,window->id,window->busy_cursor);
5451 (void) XFlush(display);
5452 depth=(int) window->depth;
5453 if (window->destroy)
5454 window->image=DestroyImage(window->image);
5455 window->image=image;
5456 window->destroy=MagickFalse;
5457 if (window->image != (Image *) NULL)
5459 if (window->crop_geometry != (char *) NULL)
5470 window->image->page.x=0;
5471 window->image->page.y=0;
5472 (void) ParsePageGeometry(window->image,window->crop_geometry,
5473 &crop_info,&image->exception);
5474 crop_image=CropImage(window->image,&crop_info,&image->exception);
5475 if (crop_image != (Image *) NULL)
5477 if (window->image != image)
5478 window->image=DestroyImage(window->image);
5479 window->image=crop_image;
5480 window->destroy=MagickTrue;
5483 if ((width != (unsigned int) window->image->columns) ||
5484 (height != (unsigned int) window->image->rows))
5492 resize_image=NewImageList();
5493 if (window->pixel_info->colors != 0)
5494 resize_image=SampleImage(window->image,width,height,
5497 resize_image=ThumbnailImage(window->image,width,height,
5499 if (resize_image != (Image *) NULL)
5501 if (window->image != image)
5502 window->image=DestroyImage(window->image);
5503 window->image=resize_image;
5504 window->destroy=MagickTrue;
5507 width=(unsigned int) window->image->columns;
5508 assert((size_t) width == window->image->columns);
5509 height=(unsigned int) window->image->rows;
5510 assert((size_t) height == window->image->rows);
5515 ximage=(XImage *) NULL;
5516 format=(depth == 1) ? XYBitmap : ZPixmap;
5517 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
5518 if (window->shared_memory != MagickFalse)
5523 segment_info=(XShmSegmentInfo *) window->segment_info;
5524 segment_info[1].shmid=(-1);
5525 segment_info[1].shmaddr=(char *) NULL;
5526 ximage=XShmCreateImage(display,window->visual,(unsigned int) depth,format,
5527 (char *) NULL,&segment_info[1],width,height);
5528 if (ximage == (XImage *) NULL)
5529 window->shared_memory=MagickFalse;
5530 length=(size_t) ximage->bytes_per_line*ximage->height;
5531 if (CheckOverflowException(length,ximage->bytes_per_line,ximage->height))
5532 window->shared_memory=MagickFalse;
5533 if (window->shared_memory != MagickFalse)
5534 segment_info[1].shmid=shmget(IPC_PRIVATE,length,IPC_CREAT | 0777);
5535 if (window->shared_memory != MagickFalse)
5536 segment_info[1].shmaddr=(char *) shmat(segment_info[1].shmid,0,0);
5537 if (segment_info[1].shmid < 0)
5538 window->shared_memory=MagickFalse;
5539 if (window->shared_memory != MagickFalse)
5540 (void) shmctl(segment_info[1].shmid,IPC_RMID,0);
5543 if (ximage != (XImage *) NULL)
5544 XDestroyImage(ximage);
5545 ximage=(XImage *) NULL;
5546 if (segment_info[1].shmaddr)
5548 (void) shmdt(segment_info[1].shmaddr);
5549 segment_info[1].shmaddr=(char *) NULL;
5551 if (segment_info[1].shmid >= 0)
5553 (void) shmctl(segment_info[1].shmid,IPC_RMID,0);
5554 segment_info[1].shmid=(-1);
5560 Allocate X image pixel data.
5562 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
5563 if (window->shared_memory)
5571 (void) XSync(display,MagickFalse);
5572 xerror_alert=MagickFalse;
5573 segment_info=(XShmSegmentInfo *) window->segment_info;
5574 ximage->data=segment_info[1].shmaddr;
5575 segment_info[1].readOnly=MagickFalse;
5576 status=XShmAttach(display,&segment_info[1]);
5577 if (status != False)
5578 (void) XSync(display,MagickFalse);
5579 if ((status == False) || (xerror_alert != MagickFalse))
5581 window->shared_memory=MagickFalse;
5582 if (status != False)
5583 XShmDetach(display,&segment_info[1]);
5584 if (ximage != (XImage *) NULL)
5587 XDestroyImage(ximage);
5588 ximage=(XImage *) NULL;
5590 if (segment_info[1].shmid >= 0)
5592 if (segment_info[1].shmaddr != NULL)
5593 (void) shmdt(segment_info[1].shmaddr);
5594 (void) shmctl(segment_info[1].shmid,IPC_RMID,0);
5595 segment_info[1].shmid=(-1);
5596 segment_info[1].shmaddr=(char *) NULL;
5601 if (window->shared_memory == MagickFalse)
5602 ximage=XCreateImage(display,window->visual,(unsigned int) depth,format,0,
5603 (char *) NULL,width,height,XBitmapPad(display),0);
5604 if (ximage == (XImage *) NULL)
5607 Unable to create X image.
5609 (void) XCheckDefineCursor(display,window->id,window->cursor);
5610 return(MagickFalse);
5612 length=(size_t) ximage->bytes_per_line*ximage->height;
5613 if (IsEventLogging())
5615 (void) LogMagickEvent(X11Event,GetMagickModule(),"XImage:");
5616 (void) LogMagickEvent(X11Event,GetMagickModule()," width, height: %dx%d",
5617 ximage->width,ximage->height);
5618 (void) LogMagickEvent(X11Event,GetMagickModule()," format: %d",
5620 (void) LogMagickEvent(X11Event,GetMagickModule()," byte order: %d",
5621 ximage->byte_order);
5622 (void) LogMagickEvent(X11Event,GetMagickModule(),
5623 " bitmap unit, bit order, pad: %d %d %d",ximage->bitmap_unit,
5624 ximage->bitmap_bit_order,ximage->bitmap_pad);
5625 (void) LogMagickEvent(X11Event,GetMagickModule()," depth: %d",
5627 (void) LogMagickEvent(X11Event,GetMagickModule()," bytes per line: %d",
5628 ximage->bytes_per_line);
5629 (void) LogMagickEvent(X11Event,GetMagickModule()," bits per pixel: %d",
5630 ximage->bits_per_pixel);
5631 (void) LogMagickEvent(X11Event,GetMagickModule(),
5632 " red, green, blue masks: 0x%lx 0x%lx 0x%lx",ximage->red_mask,
5633 ximage->green_mask,ximage->blue_mask);
5635 if (window->shared_memory == MagickFalse)
5637 if (ximage->format != XYBitmap)
5638 ximage->data=(char *) AcquireQuantumMemory((size_t)
5639 ximage->bytes_per_line,(size_t) ximage->height);
5641 ximage->data=(char *) AcquireQuantumMemory((size_t)
5642 ximage->bytes_per_line*ximage->depth,(size_t) ximage->height);
5644 if (ximage->data == (char *) NULL)
5647 Unable to allocate pixel data.
5649 XDestroyImage(ximage);
5650 ximage=(XImage *) NULL;
5651 (void) XCheckDefineCursor(display,window->id,window->cursor);
5652 return(MagickFalse);
5654 if (window->ximage != (XImage *) NULL)
5657 Destroy previous X image.
5659 length=(size_t) window->ximage->bytes_per_line*window->ximage->height;
5660 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
5661 if (window->segment_info != (XShmSegmentInfo *) NULL)
5666 segment_info=(XShmSegmentInfo *) window->segment_info;
5667 if (segment_info[0].shmid >= 0)
5669 (void) XSync(display,MagickFalse);
5670 (void) XShmDetach(display,&segment_info[0]);
5671 (void) XSync(display,MagickFalse);
5672 if (segment_info[0].shmaddr != (char *) NULL)
5673 (void) shmdt(segment_info[0].shmaddr);
5674 (void) shmctl(segment_info[0].shmid,IPC_RMID,0);
5675 segment_info[0].shmid=(-1);
5676 segment_info[0].shmaddr=(char *) NULL;
5677 window->ximage->data=(char *) NULL;
5681 if (window->ximage->data != (char *) NULL)
5682 free(window->ximage->data);
5683 window->ximage->data=(char *) NULL;
5684 XDestroyImage(window->ximage);
5685 window->ximage=(XImage *) NULL;
5687 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
5688 if (window->segment_info != (XShmSegmentInfo *) NULL)
5693 segment_info=(XShmSegmentInfo *) window->segment_info;
5694 segment_info[0]=segment_info[1];
5697 window->ximage=ximage;
5698 matte_image=(XImage *) NULL;
5699 if ((window->shape != MagickFalse) && (window->image != (Image *) NULL))
5700 if ((window->image->matte != MagickFalse) &&
5701 ((int) width <= XDisplayWidth(display,window->screen)) &&
5702 ((int) height <= XDisplayHeight(display,window->screen)))
5707 matte_image=XCreateImage(display,window->visual,1,XYBitmap,0,
5708 (char *) NULL,width,height,XBitmapPad(display),0);
5709 if (IsEventLogging())
5711 (void) LogMagickEvent(X11Event,GetMagickModule(),"Matte Image:");
5712 (void) LogMagickEvent(X11Event,GetMagickModule(),
5713 " width, height: %dx%d",matte_image->width,matte_image->height);
5715 if (matte_image != (XImage *) NULL)
5718 Allocate matte image pixel data.
5720 matte_image->data=(char *) AcquireQuantumMemory((size_t)
5721 matte_image->bytes_per_line*matte_image->depth,
5722 (size_t) matte_image->height);
5723 if (matte_image->data == (char *) NULL)
5725 XDestroyImage(matte_image);
5726 matte_image=(XImage *) NULL;
5730 if (window->matte_image != (XImage *) NULL)
5735 if (window->matte_image->data != (char *) NULL)
5736 free(window->matte_image->data);
5737 window->matte_image->data=(char *) NULL;
5738 XDestroyImage(window->matte_image);
5739 window->matte_image=(XImage *) NULL;
5741 window->matte_image=matte_image;
5742 if (window->matte_pixmap != (Pixmap) NULL)
5744 (void) XFreePixmap(display,window->matte_pixmap);
5745 window->matte_pixmap=(Pixmap) NULL;
5746 #if defined(MAGICKCORE_HAVE_SHAPE)
5747 if (window->shape != MagickFalse)
5748 XShapeCombineMask(display,window->id,ShapeBounding,0,0,None,ShapeSet);
5751 window->stasis=MagickFalse;
5753 Convert pixels to X image data.
5755 if (window->image != (Image *) NULL)
5757 if ((ximage->byte_order == LSBFirst) || ((ximage->format == XYBitmap) &&
5758 (ximage->bitmap_bit_order == LSBFirst)))
5759 XMakeImageLSBFirst(resource_info,window,window->image,ximage,
5762 XMakeImageMSBFirst(resource_info,window,window->image,ximage,
5765 if (window->matte_image != (XImage *) NULL)
5768 Create matte pixmap.
5770 window->matte_pixmap=XCreatePixmap(display,window->id,width,height,1);
5771 if (window->matte_pixmap != (Pixmap) NULL)
5780 Copy matte image to matte pixmap.
5782 context_values.background=0;
5783 context_values.foreground=1;
5784 graphics_context=XCreateGC(display,window->matte_pixmap,
5785 (size_t) (GCBackground | GCForeground),&context_values);
5786 (void) XPutImage(display,window->matte_pixmap,graphics_context,
5787 window->matte_image,0,0,0,0,width,height);
5788 (void) XFreeGC(display,graphics_context);
5789 #if defined(MAGICKCORE_HAVE_SHAPE)
5790 if (window->shape != MagickFalse)
5791 XShapeCombineMask(display,window->id,ShapeBounding,0,0,
5792 window->matte_pixmap,ShapeSet);
5796 (void) XMakePixmap(display,resource_info,window);
5800 (void) XCheckDefineCursor(display,window->id,window->cursor);
5805 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5809 + X M a k e I m a g e L S B F i r s t %
5813 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5815 % XMakeImageLSBFirst() initializes the pixel data of an X11 Image. The X image
5816 % pixels are copied in least-significant bit and byte first order. The
5817 % server's scanline pad is respected. Rather than using one or two general
5818 % cases, many special cases are found here to help speed up the image
5821 % The format of the XMakeImageLSBFirst method is:
5823 % void XMakeImageLSBFirst(Display *display,XWindows *windows)
5825 % A description of each parameter follows:
5827 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
5829 % o window: Specifies a pointer to a XWindowInfo structure.
5831 % o image: the image.
5833 % o ximage: Specifies a pointer to a XImage structure; returned from
5836 % o matte_image: Specifies a pointer to a XImage structure; returned from
5840 static void XMakeImageLSBFirst(const XResourceInfo *resource_info,
5841 const XWindowInfo *window,Image *image,XImage *ximage,XImage *matte_image)
5852 register const Quantum
5858 register unsigned char
5875 assert(resource_info != (XResourceInfo *) NULL);
5876 assert(window != (XWindowInfo *) NULL);
5877 assert(image != (Image *) NULL);
5878 if (image->debug != MagickFalse)
5879 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
5881 if ((window->immutable == MagickFalse) &&
5882 (image->storage_class == DirectClass) && (image->matte != MagickFalse))
5885 size[MaxTextExtent];
5893 image_info=AcquireImageInfo();
5894 (void) CopyMagickString(image_info->filename,
5895 resource_info->image_info->texture != (char *) NULL ?
5896 resource_info->image_info->texture : "pattern:checkerboard",
5898 (void) FormatLocaleString(size,MaxTextExtent,"%.20gx%.20g",(double)
5899 image->columns,(double) image->rows);
5900 image_info->size=ConstantString(size);
5901 pattern=ReadImage(image_info,&image->exception);
5902 image_info=DestroyImageInfo(image_info);
5903 if (pattern != (Image *) NULL)
5905 canvas=CloneImage(image,0,0,MagickTrue,&image->exception);
5906 if (canvas != (Image *) NULL)
5907 (void) CompositeImage(canvas,DstOverCompositeOp,pattern,0,0);
5908 pattern=DestroyImage(pattern);
5911 scanline_pad=(unsigned int) (ximage->bytes_per_line-((ximage->width*
5912 ximage->bits_per_pixel) >> 3));
5913 map_info=window->map_info;
5914 pixels=window->pixel_info->pixels;
5915 q=(unsigned char *) ximage->data;
5917 canvas_view=AcquireCacheView(canvas);
5918 if (ximage->format == XYBitmap)
5920 register unsigned short
5928 Convert canvas to big-endian bitmap.
5930 background=(unsigned char)
5931 (XPixelIntensity(&window->pixel_info->foreground_color) <
5932 XPixelIntensity(&window->pixel_info->background_color) ? 0x80 : 0x00);
5933 foreground=(unsigned char)
5934 (XPixelIntensity(&window->pixel_info->background_color) <
5935 XPixelIntensity(&window->pixel_info->foreground_color) ? 0x80 : 0x00);
5936 polarity=(unsigned short) ((GetPixelPacketIntensity(
5937 &canvas->colormap[0])) < ((Quantum) QuantumRange/2) ? 1 : 0);
5938 if (canvas->colors == 2)
5939 polarity=GetPixelPacketIntensity(&canvas->colormap[0]) <
5940 GetPixelPacketIntensity(&canvas->colormap[1]);
5941 for (y=0; y < (int) canvas->rows; y++)
5943 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,canvas->columns,1,
5944 &canvas->exception);
5945 if (p == (const Quantum *) NULL)
5949 for (x=0; x < (int) canvas->columns; x++)
5952 if (GetPixelIndex(canvas,p) == (Quantum) polarity)
5963 p+=GetPixelChannels(canvas);
5971 if (window->pixel_info->colors != 0)
5972 switch (ximage->bits_per_pixel)
5976 register unsigned int
5980 Convert to 2 bit color-mapped X canvas.
5982 for (y=0; y < (int) canvas->rows; y++)
5984 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
5985 canvas->columns,1,&canvas->exception);
5986 if (p == (const Quantum *) NULL)
5989 for (x=0; x < (int) canvas->columns; x++)
5991 pixel=pixels[(ssize_t) GetPixelIndex(canvas,p)] & 0x0f;
5996 *q=(unsigned char) pixel;
6002 *q|=(unsigned char) (pixel << 2);
6008 *q|=(unsigned char) (pixel << 4);
6014 *q|=(unsigned char) (pixel << 6);
6020 p+=GetPixelChannels(canvas);
6028 register unsigned int
6032 Convert to 4 bit color-mapped X canvas.
6034 for (y=0; y < (int) canvas->rows; y++)
6036 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6037 canvas->columns,1,&canvas->exception);
6038 if (p == (const Quantum *) NULL)
6041 for (x=0; x < (int) canvas->columns; x++)
6043 pixel=pixels[(ssize_t) GetPixelIndex(canvas,p)] & 0xf;
6048 *q=(unsigned char) pixel;
6054 *q|=(unsigned char) (pixel << 4);
6060 p+=GetPixelChannels(canvas);
6070 Convert to 8 bit color-mapped X canvas.
6072 if (resource_info->color_recovery &&
6073 resource_info->quantize_info->dither)
6075 XDitherImage(canvas,ximage);
6078 for (y=0; y < (int) canvas->rows; y++)
6080 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6081 canvas->columns,1,&canvas->exception);
6082 if (p == (const Quantum *) NULL)
6084 for (x=0; x < (int) canvas->columns; x++)
6086 pixel=pixels[(ssize_t) GetPixelIndex(canvas,p)];
6087 *q++=(unsigned char) pixel;
6088 p+=GetPixelChannels(canvas);
6099 register unsigned int
6103 channel[sizeof(size_t)];
6106 Convert to multi-byte color-mapped X canvas.
6108 bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3);
6109 for (y=0; y < (int) canvas->rows; y++)
6111 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6112 canvas->columns,1,&canvas->exception);
6113 if (p == (const Quantum *) NULL)
6115 for (x=0; x < (int) canvas->columns; x++)
6117 pixel=pixels[(ssize_t) GetPixelIndex(canvas,p)];
6118 for (k=0; k < (int) bytes_per_pixel; k++)
6120 channel[k]=(unsigned char) pixel;
6123 for (k=0; k < (int) bytes_per_pixel; k++)
6125 p+=GetPixelChannels(canvas);
6133 switch (ximage->bits_per_pixel)
6137 register unsigned int
6141 Convert to contiguous 2 bit continuous-tone X canvas.
6143 for (y=0; y < (int) canvas->rows; y++)
6146 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6147 canvas->columns,1,&canvas->exception);
6148 if (p == (const Quantum *) NULL)
6150 for (x=0; x < (int) canvas->columns; x++)
6152 pixel=XGammaPixel(canvas,map_info,p);
6158 *q=(unsigned char) pixel;
6164 *q|=(unsigned char) (pixel << 2);
6170 *q|=(unsigned char) (pixel << 4);
6176 *q|=(unsigned char) (pixel << 6);
6182 p+=GetPixelChannels(canvas);
6190 register unsigned int
6194 Convert to contiguous 4 bit continuous-tone X canvas.
6196 for (y=0; y < (int) canvas->rows; y++)
6198 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6199 canvas->columns,1,&canvas->exception);
6200 if (p == (const Quantum *) NULL)
6203 for (x=0; x < (int) canvas->columns; x++)
6205 pixel=XGammaPixel(canvas,map_info,p);
6211 *q=(unsigned char) pixel;
6217 *q|=(unsigned char) (pixel << 4);
6223 p+=GetPixelChannels(canvas);
6233 Convert to contiguous 8 bit continuous-tone X canvas.
6235 if (resource_info->color_recovery &&
6236 resource_info->quantize_info->dither)
6238 XDitherImage(canvas,ximage);
6241 for (y=0; y < (int) canvas->rows; y++)
6243 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6244 canvas->columns,1,&canvas->exception);
6245 if (p == (const Quantum *) NULL)
6247 for (x=0; x < (int) canvas->columns; x++)
6249 pixel=XGammaPixel(canvas,map_info,p);
6250 *q++=(unsigned char) pixel;
6251 p+=GetPixelChannels(canvas);
6259 if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) &&
6260 (map_info->green_max == 255) && (map_info->blue_max == 255) &&
6261 (map_info->red_mult == 65536L) && (map_info->green_mult == 256) &&
6262 (map_info->blue_mult == 1))
6265 Convert to 32 bit continuous-tone X canvas.
6267 for (y=0; y < (int) canvas->rows; y++)
6269 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6270 canvas->columns,1,&canvas->exception);
6271 if (p == (const Quantum *) NULL)
6273 if ((red_gamma != 1.0) || (green_gamma != 1.0) ||
6274 (blue_gamma != 1.0))
6277 Gamma correct canvas.
6279 for (x=(int) canvas->columns-1; x >= 0; x--)
6281 *q++=ScaleQuantumToChar(XBlueGamma(
6282 GetPixelBlue(canvas,p)));
6283 *q++=ScaleQuantumToChar(XGreenGamma(
6284 GetPixelGreen(canvas,p)));
6285 *q++=ScaleQuantumToChar(XRedGamma(
6286 GetPixelRed(canvas,p)));
6288 p+=GetPixelChannels(canvas);
6292 for (x=(int) canvas->columns-1; x >= 0; x--)
6294 *q++=ScaleQuantumToChar((Quantum)
6295 GetPixelBlue(canvas,p));
6296 *q++=ScaleQuantumToChar((Quantum)
6297 GetPixelGreen(canvas,p));
6298 *q++=ScaleQuantumToChar((Quantum)
6299 GetPixelRed(canvas,p));
6301 p+=GetPixelChannels(canvas);
6306 if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) &&
6307 (map_info->green_max == 255) && (map_info->blue_max == 255) &&
6308 (map_info->red_mult == 1) && (map_info->green_mult == 256) &&
6309 (map_info->blue_mult == 65536L))
6312 Convert to 32 bit continuous-tone X canvas.
6314 for (y=0; y < (int) canvas->rows; y++)
6316 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6317 canvas->columns,1,&canvas->exception);
6318 if (p == (const Quantum *) NULL)
6320 if ((red_gamma != 1.0) || (green_gamma != 1.0) ||
6321 (blue_gamma != 1.0))
6324 Gamma correct canvas.
6326 for (x=(int) canvas->columns-1; x >= 0; x--)
6328 *q++=ScaleQuantumToChar(XRedGamma(
6329 GetPixelRed(canvas,p)));
6330 *q++=ScaleQuantumToChar(XGreenGamma(
6331 GetPixelGreen(canvas,p)));
6332 *q++=ScaleQuantumToChar(XBlueGamma(
6333 GetPixelBlue(canvas,p)));
6335 p+=GetPixelChannels(canvas);
6339 for (x=(int) canvas->columns-1; x >= 0; x--)
6341 *q++=ScaleQuantumToChar((Quantum)
6342 GetPixelRed(canvas,p));
6343 *q++=ScaleQuantumToChar((Quantum)
6344 GetPixelGreen(canvas,p));
6345 *q++=ScaleQuantumToChar((Quantum)
6346 GetPixelBlue(canvas,p));
6348 p+=GetPixelChannels(canvas);
6357 register unsigned int
6361 channel[sizeof(size_t)];
6364 Convert to multi-byte continuous-tone X canvas.
6366 bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3);
6367 for (y=0; y < (int) canvas->rows; y++)
6369 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6370 canvas->columns,1,&canvas->exception);
6371 if (p == (const Quantum *) NULL)
6373 for (x=0; x < (int) canvas->columns; x++)
6375 pixel=XGammaPixel(canvas,map_info,p);
6376 for (k=0; k < (int) bytes_per_pixel; k++)
6378 channel[k]=(unsigned char) pixel;
6381 for (k=0; k < (int) bytes_per_pixel; k++)
6383 p+=GetPixelChannels(canvas);
6391 if (matte_image != (XImage *) NULL)
6394 Initialize matte canvas.
6396 scanline_pad=(unsigned int) (matte_image->bytes_per_line-
6397 ((matte_image->width*matte_image->bits_per_pixel) >> 3));
6398 q=(unsigned char *) matte_image->data;
6399 for (y=0; y < (int) canvas->rows; y++)
6401 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,canvas->columns,1,
6402 &canvas->exception);
6403 if (p == (const Quantum *) NULL)
6407 for (x=(int) canvas->columns-1; x >= 0; x--)
6410 if (GetPixelAlpha(canvas,p) > (QuantumRange/2))
6419 p+=GetPixelChannels(canvas);
6426 canvas_view=DestroyCacheView(canvas_view);
6427 if (canvas != image)
6428 canvas=DestroyImage(canvas);
6432 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6436 + X M a k e I m a g e M S B F i r s t %
6440 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6442 % XMakeImageMSBFirst() initializes the pixel data of an X11 Image. The X
6443 % image pixels are copied in most-significant bit and byte first order. The
6444 % server's scanline pad is also respected. Rather than using one or two
6445 % general cases, many special cases are found here to help speed up the image
6448 % The format of the XMakeImageMSBFirst method is:
6450 % XMakeImageMSBFirst(resource_info,window,image,ximage,matte_image)
6452 % A description of each parameter follows:
6454 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
6456 % o window: Specifies a pointer to a XWindowInfo structure.
6458 % o image: the image.
6460 % o ximage: Specifies a pointer to a XImage structure; returned from
6463 % o matte_image: Specifies a pointer to a XImage structure; returned from
6467 static void XMakeImageMSBFirst(const XResourceInfo *resource_info,
6468 const XWindowInfo *window,Image *image,XImage *ximage,XImage *matte_image)
6482 register const Quantum
6485 register unsigned char
6502 assert(resource_info != (XResourceInfo *) NULL);
6503 assert(window != (XWindowInfo *) NULL);
6504 assert(image != (Image *) NULL);
6505 if (image->debug != MagickFalse)
6506 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
6508 if ((window->immutable != MagickFalse) &&
6509 (image->storage_class == DirectClass) && (image->matte != MagickFalse))
6512 size[MaxTextExtent];
6520 image_info=AcquireImageInfo();
6521 (void) CopyMagickString(image_info->filename,
6522 resource_info->image_info->texture != (char *) NULL ?
6523 resource_info->image_info->texture : "pattern:checkerboard",
6525 (void) FormatLocaleString(size,MaxTextExtent,"%.20gx%.20g",(double)
6526 image->columns,(double) image->rows);
6527 image_info->size=ConstantString(size);
6528 pattern=ReadImage(image_info,&image->exception);
6529 image_info=DestroyImageInfo(image_info);
6530 if (pattern != (Image *) NULL)
6532 canvas=CloneImage(image,0,0,MagickTrue,&image->exception);
6533 if (canvas != (Image *) NULL)
6534 (void) CompositeImage(canvas,DstOverCompositeOp,pattern,0,0);
6535 pattern=DestroyImage(pattern);
6538 scanline_pad=(unsigned int) (ximage->bytes_per_line-((ximage->width*
6539 ximage->bits_per_pixel) >> 3));
6540 map_info=window->map_info;
6541 pixels=window->pixel_info->pixels;
6542 q=(unsigned char *) ximage->data;
6544 canvas_view=AcquireCacheView(canvas);
6545 if (ximage->format == XYBitmap)
6547 register unsigned short
6555 Convert canvas to big-endian bitmap.
6557 background=(unsigned char)
6558 (XPixelIntensity(&window->pixel_info->foreground_color) <
6559 XPixelIntensity(&window->pixel_info->background_color) ? 0x01 : 0x00);
6560 foreground=(unsigned char)
6561 (XPixelIntensity(&window->pixel_info->background_color) <
6562 XPixelIntensity(&window->pixel_info->foreground_color) ? 0x01 : 0x00);
6563 polarity=(unsigned short) ((GetPixelPacketIntensity(
6564 &canvas->colormap[0])) < ((Quantum) QuantumRange/2) ? 1 : 0);
6565 if (canvas->colors == 2)
6566 polarity=GetPixelPacketIntensity(&canvas->colormap[0]) <
6567 GetPixelPacketIntensity(&canvas->colormap[1]);
6568 for (y=0; y < (int) canvas->rows; y++)
6570 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,canvas->columns,1,
6571 &canvas->exception);
6572 if (p == (const Quantum *) NULL)
6576 for (x=(int) canvas->columns-1; x >= 0; x--)
6579 if (GetPixelIndex(canvas,p) == (Quantum) polarity)
6590 p+=GetPixelChannels(canvas);
6598 if (window->pixel_info->colors != 0)
6599 switch (ximage->bits_per_pixel)
6603 register unsigned int
6607 Convert to 2 bit color-mapped X canvas.
6609 for (y=0; y < (int) canvas->rows; y++)
6611 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6612 canvas->columns,1,&canvas->exception);
6613 if (p == (const Quantum *) NULL)
6616 for (x=0; x < (int) canvas->columns; x++)
6618 pixel=pixels[(ssize_t)
6619 GetPixelIndex(canvas,p)] & 0xf;
6624 *q=(unsigned char) (pixel << 6);
6630 *q|=(unsigned char) (pixel << 4);
6636 *q|=(unsigned char) (pixel << 2);
6642 *q|=(unsigned char) pixel;
6648 p+=GetPixelChannels(canvas);
6656 register unsigned int
6660 Convert to 4 bit color-mapped X canvas.
6662 for (y=0; y < (int) canvas->rows; y++)
6664 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6665 canvas->columns,1,&canvas->exception);
6666 if (p == (const Quantum *) NULL)
6669 for (x=0; x < (int) canvas->columns; x++)
6671 pixel=pixels[(ssize_t)
6672 GetPixelIndex(canvas,p)] & 0xf;
6677 *q=(unsigned char) (pixel << 4);
6683 *q|=(unsigned char) pixel;
6689 p+=GetPixelChannels(canvas);
6699 Convert to 8 bit color-mapped X canvas.
6701 if (resource_info->color_recovery &&
6702 resource_info->quantize_info->dither)
6704 XDitherImage(canvas,ximage);
6707 for (y=0; y < (int) canvas->rows; y++)
6709 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6710 canvas->columns,1,&canvas->exception);
6711 if (p == (const Quantum *) NULL)
6713 for (x=0; x < (int) canvas->columns; x++)
6715 pixel=pixels[(ssize_t)
6716 GetPixelIndex(canvas,p)];
6717 *q++=(unsigned char) pixel;
6718 p+=GetPixelChannels(canvas);
6729 register unsigned int
6733 channel[sizeof(size_t)];
6736 Convert to 8 bit color-mapped X canvas.
6738 bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3);
6739 for (y=0; y < (int) canvas->rows; y++)
6741 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6742 canvas->columns,1,&canvas->exception);
6743 if (p == (const Quantum *) NULL)
6745 for (x=0; x < (int) canvas->columns; x++)
6747 pixel=pixels[(ssize_t)
6748 GetPixelIndex(canvas,p)];
6749 for (k=(int) bytes_per_pixel-1; k >= 0; k--)
6751 channel[k]=(unsigned char) pixel;
6754 for (k=0; k < (int) bytes_per_pixel; k++)
6756 p+=GetPixelChannels(canvas);
6764 switch (ximage->bits_per_pixel)
6768 register unsigned int
6772 Convert to 4 bit continuous-tone X canvas.
6774 for (y=0; y < (int) canvas->rows; y++)
6776 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6777 canvas->columns,1,&canvas->exception);
6778 if (p == (const Quantum *) NULL)
6781 for (x=(int) canvas->columns-1; x >= 0; x--)
6783 pixel=XGammaPixel(canvas,map_info,p);
6789 *q=(unsigned char) (pixel << 6);
6795 *q|=(unsigned char) (pixel << 4);
6801 *q|=(unsigned char) (pixel << 2);
6807 *q|=(unsigned char) pixel;
6813 p+=GetPixelChannels(canvas);
6821 register unsigned int
6825 Convert to 4 bit continuous-tone X canvas.
6827 for (y=0; y < (int) canvas->rows; y++)
6829 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6830 canvas->columns,1,&canvas->exception);
6831 if (p == (const Quantum *) NULL)
6834 for (x=(int) canvas->columns-1; x >= 0; x--)
6836 pixel=XGammaPixel(canvas,map_info,p);
6842 *q=(unsigned char) (pixel << 4);
6848 *q|=(unsigned char) pixel;
6854 p+=GetPixelChannels(canvas);
6864 Convert to 8 bit continuous-tone X canvas.
6866 if (resource_info->color_recovery &&
6867 resource_info->quantize_info->dither)
6869 XDitherImage(canvas,ximage);
6872 for (y=0; y < (int) canvas->rows; y++)
6874 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6875 canvas->columns,1,&canvas->exception);
6876 if (p == (const Quantum *) NULL)
6878 for (x=(int) canvas->columns-1; x >= 0; x--)
6880 pixel=XGammaPixel(canvas,map_info,p);
6881 *q++=(unsigned char) pixel;
6882 p+=GetPixelChannels(canvas);
6890 if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) &&
6891 (map_info->green_max == 255) && (map_info->blue_max == 255) &&
6892 (map_info->red_mult == 65536L) && (map_info->green_mult == 256) &&
6893 (map_info->blue_mult == 1))
6896 Convert to 32 bit continuous-tone X canvas.
6898 for (y=0; y < (int) canvas->rows; y++)
6900 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6901 canvas->columns,1,&canvas->exception);
6902 if (p == (const Quantum *) NULL)
6904 if ((red_gamma != 1.0) || (green_gamma != 1.0) ||
6905 (blue_gamma != 1.0))
6908 Gamma correct canvas.
6910 for (x=(int) canvas->columns-1; x >= 0; x--)
6913 *q++=ScaleQuantumToChar(XRedGamma(
6914 GetPixelRed(canvas,p)));
6915 *q++=ScaleQuantumToChar(XGreenGamma(
6916 GetPixelGreen(canvas,p)));
6917 *q++=ScaleQuantumToChar(XBlueGamma(
6918 GetPixelBlue(canvas,p)));
6919 p+=GetPixelChannels(canvas);
6923 for (x=(int) canvas->columns-1; x >= 0; x--)
6926 *q++=ScaleQuantumToChar((Quantum)
6927 GetPixelRed(canvas,p));
6928 *q++=ScaleQuantumToChar((Quantum)
6929 GetPixelGreen(canvas,p));
6930 *q++=ScaleQuantumToChar((Quantum)
6931 GetPixelBlue(canvas,p));
6932 p+=GetPixelChannels(canvas);
6937 if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) &&
6938 (map_info->green_max == 255) && (map_info->blue_max == 255) &&
6939 (map_info->red_mult == 1) && (map_info->green_mult == 256) &&
6940 (map_info->blue_mult == 65536L))
6943 Convert to 32 bit continuous-tone X canvas.
6945 for (y=0; y < (int) canvas->rows; y++)
6947 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
6948 canvas->columns,1,&canvas->exception);
6949 if (p == (const Quantum *) NULL)
6951 if ((red_gamma != 1.0) || (green_gamma != 1.0) ||
6952 (blue_gamma != 1.0))
6955 Gamma correct canvas.
6957 for (x=(int) canvas->columns-1; x >= 0; x--)
6960 *q++=ScaleQuantumToChar(XBlueGamma(
6961 GetPixelBlue(canvas,p)));
6962 *q++=ScaleQuantumToChar(XGreenGamma(
6963 GetPixelGreen(canvas,p)));
6964 *q++=ScaleQuantumToChar(XRedGamma(
6965 GetPixelRed(canvas,p)));
6966 p+=GetPixelChannels(canvas);
6970 for (x=(int) canvas->columns-1; x >= 0; x--)
6973 *q++=ScaleQuantumToChar((Quantum)
6974 GetPixelBlue(canvas,p));
6975 *q++=ScaleQuantumToChar((Quantum)
6976 GetPixelGreen(canvas,p));
6977 *q++=ScaleQuantumToChar((Quantum)
6978 GetPixelRed(canvas,p));
6979 p+=GetPixelChannels(canvas);
6988 register unsigned int
6992 channel[sizeof(size_t)];
6995 Convert to multi-byte continuous-tone X canvas.
6997 bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3);
6998 for (y=0; y < (int) canvas->rows; y++)
7000 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
7001 canvas->columns,1,&canvas->exception);
7002 if (p == (const Quantum *) NULL)
7004 for (x=(int) canvas->columns-1; x >= 0; x--)
7006 pixel=XGammaPixel(canvas,map_info,p);
7007 for (k=(int) bytes_per_pixel-1; k >= 0; k--)
7009 channel[k]=(unsigned char) pixel;
7012 for (k=0; k < (int) bytes_per_pixel; k++)
7014 p+=GetPixelChannels(canvas);
7022 if (matte_image != (XImage *) NULL)
7025 Initialize matte canvas.
7027 scanline_pad=(unsigned int) (matte_image->bytes_per_line-
7028 ((matte_image->width*matte_image->bits_per_pixel) >> 3));
7029 q=(unsigned char *) matte_image->data;
7030 for (y=0; y < (int) canvas->rows; y++)
7032 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,canvas->columns,1,
7033 &canvas->exception);
7034 if (p == (const Quantum *) NULL)
7038 for (x=(int) canvas->columns-1; x >= 0; x--)
7041 if (GetPixelAlpha(canvas,p) > (QuantumRange/2))
7050 p+=GetPixelChannels(canvas);
7057 canvas_view=DestroyCacheView(canvas_view);
7058 if (canvas != image)
7059 canvas=DestroyImage(canvas);
7063 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7067 % X M a k e M a g n i f y I m a g e %
7071 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7073 % XMakeMagnifyImage() magnifies a region of an X image and displays it.
7075 % The format of the XMakeMagnifyImage method is:
7077 % void XMakeMagnifyImage(display,windows)
7079 % A description of each parameter follows:
7081 % o display: Specifies a connection to an X server; returned from
7084 % o windows: Specifies a pointer to a XWindows structure.
7087 MagickExport void XMakeMagnifyImage(Display *display,XWindows *windows)
7090 tuple[MaxTextExtent];
7104 register unsigned char
7112 previous_magnify = 0;
7130 Check boundary conditions.
7132 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
7133 assert(display != (Display *) NULL);
7134 assert(windows != (XWindows *) NULL);
7136 for (n=1; n < (ssize_t) windows->magnify.data; n++)
7138 while ((magnify*windows->image.ximage->width) < windows->magnify.width)
7140 while ((magnify*windows->image.ximage->height) < windows->magnify.height)
7142 while (magnify > windows->magnify.width)
7144 while (magnify > windows->magnify.height)
7146 if (magnify != previous_magnify)
7155 New magnify factor: update magnify window name.
7158 while ((1 << i) <= (int) magnify)
7160 (void) FormatLocaleString(windows->magnify.name,MaxTextExtent,
7161 "Magnify %.20gX",(double) i);
7162 status=XStringListToTextProperty(&windows->magnify.name,1,&window_name);
7163 if (status != False)
7165 XSetWMName(display,windows->magnify.id,&window_name);
7166 XSetWMIconName(display,windows->magnify.id,&window_name);
7167 (void) XFree((void *) window_name.value);
7170 previous_magnify=magnify;
7171 ximage=windows->image.ximage;
7172 width=(unsigned int) windows->magnify.ximage->width;
7173 height=(unsigned int) windows->magnify.ximage->height;
7174 if ((windows->magnify.x < 0) ||
7175 (windows->magnify.x >= windows->image.ximage->width))
7176 windows->magnify.x=windows->image.ximage->width >> 1;
7177 x=windows->magnify.x-((width/magnify) >> 1);
7181 if (x > (int) (ximage->width-(width/magnify)))
7182 x=ximage->width-width/magnify;
7183 if ((windows->magnify.y < 0) ||
7184 (windows->magnify.y >= windows->image.ximage->height))
7185 windows->magnify.y=windows->image.ximage->height >> 1;
7186 y=windows->magnify.y-((height/magnify) >> 1);
7190 if (y > (int) (ximage->height-(height/magnify)))
7191 y=ximage->height-height/magnify;
7192 q=(unsigned char *) windows->magnify.ximage->data;
7193 scanline_pad=(unsigned int) (windows->magnify.ximage->bytes_per_line-
7194 ((width*windows->magnify.ximage->bits_per_pixel) >> 3));
7195 if (ximage->bits_per_pixel < 8)
7197 register unsigned char
7204 register unsigned int
7210 pixel_info=windows->magnify.pixel_info;
7211 switch (ximage->bitmap_bit_order)
7216 Magnify little-endian bitmap.
7220 if (ximage->format == XYBitmap)
7222 background=(unsigned char)
7223 (XPixelIntensity(&pixel_info->foreground_color) <
7224 XPixelIntensity(&pixel_info->background_color) ? 0x80 : 0x00);
7225 foreground=(unsigned char)
7226 (XPixelIntensity(&pixel_info->background_color) <
7227 XPixelIntensity(&pixel_info->foreground_color) ? 0x80 : 0x00);
7228 if (windows->magnify.depth > 1)
7229 Swap(background,foreground);
7231 for (i=0; i < (ssize_t) height; i+=magnify)
7234 Propogate pixel magnify rows.
7236 for (j=0; j < magnify; j++)
7238 p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
7239 ((x*ximage->bits_per_pixel) >> 3);
7240 p_bit=(unsigned char) (x*ximage->bits_per_pixel) & 0x07;
7243 for (k=0; k < width; k+=magnify)
7246 Propogate pixel magnify columns.
7248 for (l=0; l < magnify; l++)
7251 Propogate each bit plane.
7253 for (plane=0; (int) plane < ximage->bits_per_pixel; plane++)
7256 if (*p & (0x01 << (p_bit+plane)))
7269 p_bit+=ximage->bits_per_pixel;
7276 *q=byte >> (8-q_bit);
7288 Magnify big-endian bitmap.
7292 if (ximage->format == XYBitmap)
7294 background=(unsigned char)
7295 (XPixelIntensity(&pixel_info->foreground_color) <
7296 XPixelIntensity(&pixel_info->background_color) ? 0x01 : 0x00);
7297 foreground=(unsigned char)
7298 (XPixelIntensity(&pixel_info->background_color) <
7299 XPixelIntensity(&pixel_info->foreground_color) ? 0x01 : 0x00);
7300 if (windows->magnify.depth > 1)
7301 Swap(background,foreground);
7303 for (i=0; i < (ssize_t) height; i+=magnify)
7306 Propogate pixel magnify rows.
7308 for (j=0; j < magnify; j++)
7310 p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
7311 ((x*ximage->bits_per_pixel) >> 3);
7312 p_bit=(unsigned char) (x*ximage->bits_per_pixel) & 0x07;
7315 for (k=0; k < width; k+=magnify)
7318 Propogate pixel magnify columns.
7320 for (l=0; l < magnify; l++)
7323 Propogate each bit plane.
7325 for (plane=0; (int) plane < ximage->bits_per_pixel; plane++)
7328 if (*p & (0x80 >> (p_bit+plane)))
7341 p_bit+=ximage->bits_per_pixel;
7348 *q=byte << (8-q_bit);
7359 switch (ximage->bits_per_pixel)
7365 Magnify 8 bit X image.
7367 for (i=0; i < (ssize_t) height; i+=magnify)
7370 Propogate pixel magnify rows.
7372 for (j=0; j < magnify; j++)
7374 p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
7375 ((x*ximage->bits_per_pixel) >> 3);
7376 for (k=0; k < width; k+=magnify)
7379 Propogate pixel magnify columns.
7381 for (l=0; l < magnify; l++)
7393 register unsigned int
7398 Magnify multi-byte X image.
7400 bytes_per_pixel=(unsigned int) ximage->bits_per_pixel >> 3;
7401 for (i=0; i < (ssize_t) height; i+=magnify)
7404 Propogate pixel magnify rows.
7406 for (j=0; j < magnify; j++)
7408 p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
7409 ((x*ximage->bits_per_pixel) >> 3);
7410 for (k=0; k < width; k+=magnify)
7413 Propogate pixel magnify columns.
7415 for (l=0; l < magnify; l++)
7416 for (m=0; m < bytes_per_pixel; m++)
7428 Copy X image to magnify pixmap.
7430 x=windows->magnify.x-((width/magnify) >> 1);
7432 x=(int) ((width >> 1)-windows->magnify.x*magnify);
7434 if (x > (int) (ximage->width-(width/magnify)))
7435 x=(int) ((ximage->width-windows->magnify.x)*magnify-(width >> 1));
7438 y=windows->magnify.y-((height/magnify) >> 1);
7440 y=(int) ((height >> 1)-windows->magnify.y*magnify);
7442 if (y > (int) (ximage->height-(height/magnify)))
7443 y=(int) ((ximage->height-windows->magnify.y)*magnify-(height >> 1));
7446 if ((x != 0) || (y != 0))
7447 (void) XFillRectangle(display,windows->magnify.pixmap,
7448 windows->magnify.annotate_context,0,0,width,height);
7449 (void) XPutImage(display,windows->magnify.pixmap,
7450 windows->magnify.annotate_context,windows->magnify.ximage,0,0,x,y,width-x,
7452 if ((magnify > 1) && ((magnify <= (width >> 1)) &&
7453 (magnify <= (height >> 1))))
7459 Highlight center pixel.
7461 highlight_info.x=(ssize_t) windows->magnify.width >> 1;
7462 highlight_info.y=(ssize_t) windows->magnify.height >> 1;
7463 highlight_info.width=magnify;
7464 highlight_info.height=magnify;
7465 (void) XDrawRectangle(display,windows->magnify.pixmap,
7466 windows->magnify.highlight_context,(int) highlight_info.x,
7467 (int) highlight_info.y,(unsigned int) highlight_info.width-1,
7468 (unsigned int) highlight_info.height-1);
7470 (void) XDrawRectangle(display,windows->magnify.pixmap,
7471 windows->magnify.annotate_context,(int) highlight_info.x+1,
7472 (int) highlight_info.y+1,(unsigned int) highlight_info.width-3,
7473 (unsigned int) highlight_info.height-3);
7476 Show center pixel color.
7478 (void) GetOneVirtualMagickPixel(windows->image.image,(ssize_t)
7479 windows->magnify.x,(ssize_t) windows->magnify.y,&pixel,
7480 &windows->image.image->exception);
7481 (void) FormatLocaleString(tuple,MaxTextExtent,"%d,%d: ",
7482 windows->magnify.x,windows->magnify.y);
7483 (void) ConcatenateMagickString(tuple,"(",MaxTextExtent);
7484 ConcatenateColorComponent(&pixel,RedPixelChannel,X11Compliance,tuple);
7485 (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
7486 ConcatenateColorComponent(&pixel,GreenPixelChannel,X11Compliance,tuple);
7487 (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
7488 ConcatenateColorComponent(&pixel,BluePixelChannel,X11Compliance,tuple);
7489 if (pixel.colorspace == CMYKColorspace)
7491 (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
7492 ConcatenateColorComponent(&pixel,BlackPixelChannel,X11Compliance,tuple);
7494 if (pixel.matte != MagickFalse)
7496 (void) ConcatenateMagickString(tuple,",",MaxTextExtent);
7497 ConcatenateColorComponent(&pixel,AlphaPixelChannel,X11Compliance,tuple);
7499 (void) ConcatenateMagickString(tuple,")",MaxTextExtent);
7500 height=(unsigned int) windows->magnify.font_info->ascent+
7501 windows->magnify.font_info->descent;
7502 x=windows->magnify.font_info->max_bounds.width >> 1;
7503 y=windows->magnify.font_info->ascent+(height >> 2);
7504 (void) XDrawImageString(display,windows->magnify.pixmap,
7505 windows->magnify.annotate_context,x,y,tuple,(int) strlen(tuple));
7506 GetColorTuple(&pixel,MagickTrue,tuple);
7508 (void) XDrawImageString(display,windows->magnify.pixmap,
7509 windows->magnify.annotate_context,x,y,tuple,(int) strlen(tuple));
7510 (void) QueryMagickColorname(windows->image.image,&pixel,SVGCompliance,tuple,
7511 &windows->image.image->exception);
7513 (void) XDrawImageString(display,windows->magnify.pixmap,
7514 windows->magnify.annotate_context,x,y,tuple,(int) strlen(tuple));
7516 Refresh magnify window.
7518 magnify_window=windows->magnify;
7521 XRefreshWindow(display,&magnify_window,(XEvent *) NULL);
7525 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7529 % X M a k e P i x m a p %
7533 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7535 % XMakePixmap() creates an X11 pixmap.
7537 % The format of the XMakePixmap method is:
7539 % void XMakeStandardColormap(Display *display,XVisualInfo *visual_info,
7540 % XResourceInfo *resource_info,Image *image,XStandardColormap *map_info,
7541 % XPixelInfo *pixel)
7543 % A description of each parameter follows:
7545 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
7547 % o display: Specifies a connection to an X server; returned from
7550 % o window: Specifies a pointer to a XWindowInfo structure.
7553 static MagickBooleanType XMakePixmap(Display *display,
7554 const XResourceInfo *resource_info,XWindowInfo *window)
7560 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
7561 assert(display != (Display *) NULL);
7562 assert(resource_info != (XResourceInfo *) NULL);
7563 assert(window != (XWindowInfo *) NULL);
7564 if (window->pixmap != (Pixmap) NULL)
7567 Destroy previous X pixmap.
7569 (void) XFreePixmap(display,window->pixmap);
7570 window->pixmap=(Pixmap) NULL;
7572 if (window->use_pixmap == MagickFalse)
7573 return(MagickFalse);
7574 if (window->ximage == (XImage *) NULL)
7575 return(MagickFalse);
7577 Display busy cursor.
7579 (void) XCheckDefineCursor(display,window->id,window->busy_cursor);
7580 (void) XFlush(display);
7584 width=(unsigned int) window->ximage->width;
7585 height=(unsigned int) window->ximage->height;
7586 window->pixmap=XCreatePixmap(display,window->id,width,height,window->depth);
7587 if (window->pixmap == (Pixmap) NULL)
7590 Unable to allocate pixmap.
7592 (void) XCheckDefineCursor(display,window->id,window->cursor);
7593 return(MagickFalse);
7596 Copy X image to pixmap.
7598 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
7599 if (window->shared_memory)
7600 (void) XShmPutImage(display,window->pixmap,window->annotate_context,
7601 window->ximage,0,0,0,0,width,height,MagickTrue);
7603 if (window->shared_memory == MagickFalse)
7604 (void) XPutImage(display,window->pixmap,window->annotate_context,
7605 window->ximage,0,0,0,0,width,height);
7606 if (IsEventLogging())
7608 (void) LogMagickEvent(X11Event,GetMagickModule(),"Pixmap:");
7609 (void) LogMagickEvent(X11Event,GetMagickModule()," width, height: %ux%u",
7615 (void) XCheckDefineCursor(display,window->id,window->cursor);
7620 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7624 % X M a k e S t a n d a r d C o l o r m a p %
7628 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7630 % XMakeStandardColormap() creates an X11 Standard Colormap.
7632 % The format of the XMakeStandardColormap method is:
7634 % XMakeStandardColormap(display,visual_info,resource_info,image,
7637 % A description of each parameter follows:
7639 % o display: Specifies a connection to an X server; returned from
7642 % o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
7643 % returned from XGetVisualInfo.
7645 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
7647 % o image: the image.
7649 % o map_info: If a Standard Colormap type is specified, this structure is
7650 % initialized with info from the Standard Colormap.
7652 % o pixel: Specifies a pointer to a XPixelInfo structure.
7656 #if defined(__cplusplus) || defined(c_plusplus)
7660 static inline MagickRealType DiversityPixelIntensity(
7661 const DiversityPacket *pixel)
7666 intensity=0.299*pixel->red+0.587*pixel->green+0.114*pixel->blue;
7670 static int IntensityCompare(const void *x,const void *y)
7679 color_1=(DiversityPacket *) x;
7680 color_2=(DiversityPacket *) y;
7681 diversity=(int) (DiversityPixelIntensity(color_2)-
7682 DiversityPixelIntensity(color_1));
7686 static int PopularityCompare(const void *x,const void *y)
7692 color_1=(DiversityPacket *) x;
7693 color_2=(DiversityPacket *) y;
7694 return((int) color_2->count-(int) color_1->count);
7697 #if defined(__cplusplus) || defined(c_plusplus)
7701 static inline Quantum ScaleXToQuantum(const size_t x,
7704 return((Quantum) (((MagickRealType) QuantumRange*x)/scale+0.5));
7707 MagickExport void XMakeStandardColormap(Display *display,
7708 XVisualInfo *visual_info,XResourceInfo *resource_info,Image *image,
7709 XStandardColormap *map_info,XPixelInfo *pixel)
7735 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
7736 assert(display != (Display *) NULL);
7737 assert(visual_info != (XVisualInfo *) NULL);
7738 assert(map_info != (XStandardColormap *) NULL);
7739 assert(resource_info != (XResourceInfo *) NULL);
7740 assert(pixel != (XPixelInfo *) NULL);
7741 exception=(&image->exception);
7742 if (resource_info->map_type != (char *) NULL)
7745 Standard Colormap is already defined (i.e. xstdcmap).
7747 XGetPixelInfo(display,visual_info,map_info,resource_info,image,
7749 number_colors=(unsigned int) (map_info->base_pixel+
7750 (map_info->red_max+1)*(map_info->green_max+1)*(map_info->blue_max+1));
7751 if ((map_info->red_max*map_info->green_max*map_info->blue_max) != 0)
7752 if ((image->matte == MagickFalse) &&
7753 (resource_info->color_recovery == MagickFalse) &&
7754 resource_info->quantize_info->dither &&
7755 (number_colors < MaxColormapSize))
7764 Improve image appearance with error diffusion.
7766 affinity_image=AcquireImage((ImageInfo *) NULL);
7767 if (affinity_image == (Image *) NULL)
7768 ThrowXWindowFatalException(ResourceLimitFatalError,
7769 "UnableToDitherImage",image->filename);
7770 affinity_image->columns=number_colors;
7771 affinity_image->rows=1;
7773 Initialize colormap image.
7775 q=QueueAuthenticPixels(affinity_image,0,0,affinity_image->columns,
7777 if (q != (Quantum *) NULL)
7779 for (i=0; i < (ssize_t) number_colors; i++)
7781 SetPixelRed(affinity_image,0,q);
7782 if (map_info->red_max != 0)
7783 SetPixelRed(affinity_image,
7784 ScaleXToQuantum((size_t) (i/map_info->red_mult),
7785 map_info->red_max),q);
7786 SetPixelGreen(affinity_image,0,q);
7787 if (map_info->green_max != 0)
7788 SetPixelGreen(affinity_image,
7789 ScaleXToQuantum((size_t) ((i/map_info->green_mult) %
7790 (map_info->green_max+1)),map_info->green_max),q);
7791 SetPixelBlue(affinity_image,0,q);
7792 if (map_info->blue_max != 0)
7793 SetPixelBlue(affinity_image,
7794 ScaleXToQuantum((size_t) (i % map_info->green_mult),
7795 map_info->blue_max),q);
7796 SetPixelAlpha(affinity_image,
7797 TransparentAlpha,q);
7798 q+=GetPixelChannels(affinity_image);
7800 (void) SyncAuthenticPixels(affinity_image,exception);
7801 (void) RemapImage(resource_info->quantize_info,image,
7804 XGetPixelInfo(display,visual_info,map_info,resource_info,image,
7806 (void) SetImageStorageClass(image,DirectClass,exception);
7807 affinity_image=DestroyImage(affinity_image);
7809 if (IsEventLogging())
7811 (void) LogMagickEvent(X11Event,GetMagickModule(),
7812 "Standard Colormap:");
7813 (void) LogMagickEvent(X11Event,GetMagickModule(),
7814 " colormap id: 0x%lx",map_info->colormap);
7815 (void) LogMagickEvent(X11Event,GetMagickModule(),
7816 " red, green, blue max: %lu %lu %lu",map_info->red_max,
7817 map_info->green_max,map_info->blue_max);
7818 (void) LogMagickEvent(X11Event,GetMagickModule(),
7819 " red, green, blue mult: %lu %lu %lu",map_info->red_mult,
7820 map_info->green_mult,map_info->blue_mult);
7824 if ((visual_info->klass != DirectColor) &&
7825 (visual_info->klass != TrueColor))
7826 if ((image->storage_class == DirectClass) ||
7827 ((int) image->colors > visual_info->colormap_size))
7833 Image has more colors than the visual supports.
7835 quantize_info=(*resource_info->quantize_info);
7836 quantize_info.number_colors=(size_t) visual_info->colormap_size;
7837 (void) QuantizeImage(&quantize_info,image);
7840 Free previous and create new colormap.
7842 (void) XFreeStandardColormap(display,visual_info,map_info,pixel);
7843 colormap=XDefaultColormap(display,visual_info->screen);
7844 if (visual_info->visual != XDefaultVisual(display,visual_info->screen))
7845 colormap=XCreateColormap(display,XRootWindow(display,visual_info->screen),
7846 visual_info->visual,visual_info->klass == DirectColor ?
7847 AllocAll : AllocNone);
7848 if (colormap == (Colormap) NULL)
7849 ThrowXWindowFatalException(ResourceLimitFatalError,"UnableToCreateColormap",
7852 Initialize the map and pixel info structures.
7854 XGetMapInfo(visual_info,colormap,map_info);
7855 XGetPixelInfo(display,visual_info,map_info,resource_info,image,pixel);
7857 Allocating colors in server colormap is based on visual class.
7859 switch (visual_info->klass)
7865 Define Standard Colormap for StaticGray or StaticColor visual.
7867 number_colors=image->colors;
7868 colors=(XColor *) AcquireQuantumMemory((size_t)
7869 visual_info->colormap_size,sizeof(*colors));
7870 if (colors == (XColor *) NULL)
7871 ThrowXWindowFatalException(ResourceLimitFatalError,
7872 "UnableToCreateColormap",image->filename);
7874 color.flags=(char) (DoRed | DoGreen | DoBlue);
7875 for (i=0; i < (ssize_t) image->colors; i++)
7877 color.red=ScaleQuantumToShort(XRedGamma(image->colormap[i].red));
7878 color.green=ScaleQuantumToShort(XGreenGamma(image->colormap[i].green));
7879 color.blue=ScaleQuantumToShort(XBlueGamma(image->colormap[i].blue));
7880 if (visual_info->klass != StaticColor)
7882 gray_value=(unsigned short) XPixelIntensity(&color);
7883 color.red=gray_value;
7884 color.green=gray_value;
7885 color.blue=gray_value;
7887 status=XAllocColor(display,colormap,&color);
7888 if (status == False)
7890 colormap=XCopyColormapAndFree(display,colormap);
7891 (void) XAllocColor(display,colormap,&color);
7893 pixel->pixels[i]=color.pixel;
7905 Define Standard Colormap for GrayScale or PseudoColor visual.
7907 number_colors=image->colors;
7908 colors=(XColor *) AcquireQuantumMemory((size_t)
7909 visual_info->colormap_size,sizeof(*colors));
7910 if (colors == (XColor *) NULL)
7911 ThrowXWindowFatalException(ResourceLimitFatalError,
7912 "UnableToCreateColormap",image->filename);
7914 Preallocate our GUI colors.
7916 (void) XAllocColor(display,colormap,&pixel->foreground_color);
7917 (void) XAllocColor(display,colormap,&pixel->background_color);
7918 (void) XAllocColor(display,colormap,&pixel->border_color);
7919 (void) XAllocColor(display,colormap,&pixel->matte_color);
7920 (void) XAllocColor(display,colormap,&pixel->highlight_color);
7921 (void) XAllocColor(display,colormap,&pixel->shadow_color);
7922 (void) XAllocColor(display,colormap,&pixel->depth_color);
7923 (void) XAllocColor(display,colormap,&pixel->trough_color);
7924 for (i=0; i < MaxNumberPens; i++)
7925 (void) XAllocColor(display,colormap,&pixel->pen_colors[i]);
7927 Determine if image colors will "fit" into X server colormap.
7929 colormap_type=resource_info->colormap;
7930 status=XAllocColorCells(display,colormap,MagickFalse,(unsigned long *)
7931 NULL,0,pixel->pixels,(unsigned int) image->colors);
7932 if (status != False)
7933 colormap_type=PrivateColormap;
7934 if (colormap_type == SharedColormap)
7955 Define Standard colormap for shared GrayScale or PseudoColor visual.
7957 diversity=(DiversityPacket *) AcquireQuantumMemory(image->colors,
7958 sizeof(*diversity));
7959 if (diversity == (DiversityPacket *) NULL)
7960 ThrowXWindowFatalException(ResourceLimitFatalError,
7961 "UnableToCreateColormap",image->filename);
7962 for (i=0; i < (ssize_t) image->colors; i++)
7964 diversity[i].red=image->colormap[i].red;
7965 diversity[i].green=image->colormap[i].green;
7966 diversity[i].blue=image->colormap[i].blue;
7967 diversity[i].index=(unsigned short) i;
7968 diversity[i].count=0;
7970 image_view=AcquireCacheView(image);
7971 for (y=0; y < (int) image->rows; y++)
7976 register const Quantum
7979 p=GetCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
7980 image->columns,1,exception);
7981 if (p == (const Quantum *) NULL)
7983 for (x=(int) image->columns-1; x >= 0; x--)
7985 diversity[(ssize_t) GetPixelIndex(image,p)].count++;
7986 p+=GetPixelChannels(image);
7989 image_view=DestroyCacheView(image_view);
7991 Sort colors by decreasing intensity.
7993 qsort((void *) diversity,image->colors,sizeof(*diversity),
7995 for (i=0; i < (ssize_t) image->colors; )
7997 diversity[i].count<<=4; /* increase this colors popularity */
7998 i+=MagickMax((int) (image->colors >> 4),2);
8000 diversity[image->colors-1].count<<=4;
8001 qsort((void *) diversity,image->colors,sizeof(*diversity),
8007 color.flags=(char) (DoRed | DoGreen | DoBlue);
8008 for (i=0; i < (ssize_t) image->colors; i++)
8010 index=diversity[i].index;
8012 ScaleQuantumToShort(XRedGamma(image->colormap[index].red));
8014 ScaleQuantumToShort(XGreenGamma(image->colormap[index].green));
8016 ScaleQuantumToShort(XBlueGamma(image->colormap[index].blue));
8017 if (visual_info->klass != PseudoColor)
8019 gray_value=(unsigned short) XPixelIntensity(&color);
8020 color.red=gray_value;
8021 color.green=gray_value;
8022 color.blue=gray_value;
8024 status=XAllocColor(display,colormap,&color);
8025 if (status == False)
8027 pixel->pixels[index]=color.pixel;
8031 Read X server colormap.
8033 server_colors=(XColor *) AcquireQuantumMemory((size_t)
8034 visual_info->colormap_size,sizeof(*server_colors));
8035 if (server_colors == (XColor *) NULL)
8036 ThrowXWindowFatalException(ResourceLimitFatalError,
8037 "UnableToCreateColormap",image->filename);
8038 for (x=visual_info->colormap_size-1; x >= 0; x--)
8039 server_colors[x].pixel=(size_t) x;
8040 (void) XQueryColors(display,colormap,server_colors,
8041 (int) MagickMin((unsigned int) visual_info->colormap_size,256));
8043 Select remaining colors from X server colormap.
8045 for (; i < (ssize_t) image->colors; i++)
8047 index=diversity[i].index;
8049 ScaleQuantumToShort(XRedGamma(image->colormap[index].red));
8051 ScaleQuantumToShort(XGreenGamma(image->colormap[index].green));
8053 ScaleQuantumToShort(XBlueGamma(image->colormap[index].blue));
8054 if (visual_info->klass != PseudoColor)
8056 gray_value=(unsigned short) XPixelIntensity(&color);
8057 color.red=gray_value;
8058 color.green=gray_value;
8059 color.blue=gray_value;
8061 XBestPixel(display,colormap,server_colors,(unsigned int)
8062 visual_info->colormap_size,&color);
8063 pixel->pixels[index]=color.pixel;
8066 if ((int) image->colors < visual_info->colormap_size)
8069 Fill up colors array-- more choices for pen colors.
8071 retain_colors=MagickMin((unsigned int)
8072 (visual_info->colormap_size-image->colors),256);
8073 for (i=0; i < (ssize_t) retain_colors; i++)
8074 *p++=server_colors[i];
8075 number_colors+=retain_colors;
8077 server_colors=(XColor *) RelinquishMagickMemory(server_colors);
8078 diversity=(DiversityPacket *) RelinquishMagickMemory(diversity);
8082 Define Standard colormap for private GrayScale or PseudoColor visual.
8084 if (status == False)
8087 Not enough colormap entries in the colormap-- Create a new colormap.
8089 colormap=XCreateColormap(display,
8090 XRootWindow(display,visual_info->screen),visual_info->visual,
8092 if (colormap == (Colormap) NULL)
8093 ThrowXWindowFatalException(ResourceLimitFatalError,
8094 "UnableToCreateColormap",image->filename);
8095 map_info->colormap=colormap;
8096 if ((int) image->colors < visual_info->colormap_size)
8099 Retain colors from the default colormap to help lessens the
8100 effects of colormap flashing.
8102 retain_colors=MagickMin((unsigned int)
8103 (visual_info->colormap_size-image->colors),256);
8104 p=colors+image->colors;
8105 for (i=0; i < (ssize_t) retain_colors; i++)
8107 p->pixel=(unsigned long) i;
8110 (void) XQueryColors(display,
8111 XDefaultColormap(display,visual_info->screen),
8112 colors+image->colors,(int) retain_colors);
8114 Transfer colors from default to private colormap.
8116 (void) XAllocColorCells(display,colormap,MagickFalse,
8117 (unsigned long *) NULL,0,pixel->pixels,(unsigned int)
8119 p=colors+image->colors;
8120 for (i=0; i < (ssize_t) retain_colors; i++)
8122 p->pixel=pixel->pixels[i];
8125 (void) XStoreColors(display,colormap,colors+image->colors,
8126 (int) retain_colors);
8127 number_colors+=retain_colors;
8129 (void) XAllocColorCells(display,colormap,MagickFalse,
8130 (unsigned long *) NULL,0,pixel->pixels,(unsigned int)
8134 Store the image colormap.
8137 color.flags=(char) (DoRed | DoGreen | DoBlue);
8138 for (i=0; i < (ssize_t) image->colors; i++)
8140 color.red=ScaleQuantumToShort(XRedGamma(image->colormap[i].red));
8141 color.green=ScaleQuantumToShort(XGreenGamma(image->colormap[i].green));
8142 color.blue=ScaleQuantumToShort(XBlueGamma(image->colormap[i].blue));
8143 if (visual_info->klass != PseudoColor)
8145 gray_value=(unsigned short) XPixelIntensity(&color);
8146 color.red=gray_value;
8147 color.green=gray_value;
8148 color.blue=gray_value;
8150 color.pixel=pixel->pixels[i];
8153 (void) XStoreColors(display,colormap,colors,(int) image->colors);
8164 Define Standard Colormap for TrueColor or DirectColor visual.
8166 number_colors=(unsigned int) ((map_info->red_max*map_info->red_mult)+
8167 (map_info->green_max*map_info->green_mult)+
8168 (map_info->blue_max*map_info->blue_mult)+1);
8169 linear_colormap=(number_colors > 4096) ||
8170 (((int) (map_info->red_max+1) == visual_info->colormap_size) &&
8171 ((int) (map_info->green_max+1) == visual_info->colormap_size) &&
8172 ((int) (map_info->blue_max+1) == visual_info->colormap_size)) ?
8173 MagickTrue : MagickFalse;
8174 if (linear_colormap != MagickFalse)
8175 number_colors=(size_t) visual_info->colormap_size;
8177 Allocate color array.
8179 colors=(XColor *) AcquireQuantumMemory(number_colors,sizeof(*colors));
8180 if (colors == (XColor *) NULL)
8181 ThrowXWindowFatalException(ResourceLimitFatalError,
8182 "UnableToCreateColormap",image->filename);
8184 Initialize linear color ramp.
8187 color.flags=(char) (DoRed | DoGreen | DoBlue);
8188 if (linear_colormap != MagickFalse)
8189 for (i=0; i < (ssize_t) number_colors; i++)
8191 color.blue=(unsigned short) 0;
8192 if (map_info->blue_max != 0)
8193 color.blue=(unsigned short) ((size_t)
8194 ((65535L*(i % map_info->green_mult))/map_info->blue_max));
8195 color.green=color.blue;
8196 color.red=color.blue;
8197 color.pixel=XStandardPixel(map_info,&color);
8201 for (i=0; i < (ssize_t) number_colors; i++)
8203 color.red=(unsigned short) 0;
8204 if (map_info->red_max != 0)
8205 color.red=(unsigned short) ((size_t)
8206 ((65535L*(i/map_info->red_mult))/map_info->red_max));
8207 color.green=(unsigned int) 0;
8208 if (map_info->green_max != 0)
8209 color.green=(unsigned short) ((size_t)
8210 ((65535L*((i/map_info->green_mult) % (map_info->green_max+1)))/
8211 map_info->green_max));
8212 color.blue=(unsigned short) 0;
8213 if (map_info->blue_max != 0)
8214 color.blue=(unsigned short) ((size_t)
8215 ((65535L*(i % map_info->green_mult))/map_info->blue_max));
8216 color.pixel=XStandardPixel(map_info,&color);
8219 if ((visual_info->klass == DirectColor) &&
8220 (colormap != XDefaultColormap(display,visual_info->screen)))
8221 (void) XStoreColors(display,colormap,colors,(int) number_colors);
8223 for (i=0; i < (ssize_t) number_colors; i++)
8224 (void) XAllocColor(display,colormap,&colors[i]);
8228 if ((visual_info->klass != DirectColor) &&
8229 (visual_info->klass != TrueColor))
8232 Set foreground, background, border, etc. pixels.
8234 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8235 &pixel->foreground_color);
8236 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8237 &pixel->background_color);
8238 if (pixel->background_color.pixel == pixel->foreground_color.pixel)
8241 Foreground and background colors must differ.
8243 pixel->background_color.red=(~pixel->foreground_color.red);
8244 pixel->background_color.green=
8245 (~pixel->foreground_color.green);
8246 pixel->background_color.blue=
8247 (~pixel->foreground_color.blue);
8248 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8249 &pixel->background_color);
8251 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8252 &pixel->border_color);
8253 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8254 &pixel->matte_color);
8255 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8256 &pixel->highlight_color);
8257 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8258 &pixel->shadow_color);
8259 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8260 &pixel->depth_color);
8261 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8262 &pixel->trough_color);
8263 for (i=0; i < MaxNumberPens; i++)
8265 XBestPixel(display,colormap,colors,(unsigned int) number_colors,
8266 &pixel->pen_colors[i]);
8267 pixel->pixels[image->colors+i]=pixel->pen_colors[i].pixel;
8269 pixel->colors=(ssize_t) (image->colors+MaxNumberPens);
8271 colors=(XColor *) RelinquishMagickMemory(colors);
8272 if (IsEventLogging())
8274 (void) LogMagickEvent(X11Event,GetMagickModule(),"Standard Colormap:");
8275 (void) LogMagickEvent(X11Event,GetMagickModule()," colormap id: 0x%lx",
8276 map_info->colormap);
8277 (void) LogMagickEvent(X11Event,GetMagickModule(),
8278 " red, green, blue max: %lu %lu %lu",map_info->red_max,
8279 map_info->green_max,map_info->blue_max);
8280 (void) LogMagickEvent(X11Event,GetMagickModule(),
8281 " red, green, blue mult: %lu %lu %lu",map_info->red_mult,
8282 map_info->green_mult,map_info->blue_mult);
8287 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8291 % X M a k e W i n d o w %
8295 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8297 % XMakeWindow() creates an X11 window.
8299 % The format of the XMakeWindow method is:
8301 % void XMakeWindow(Display *display,Window parent,char **argv,int argc,
8302 % XClassHint *class_hint,XWMHints *manager_hints,
8303 % XWindowInfo *window_info)
8305 % A description of each parameter follows:
8307 % o display: Specifies a connection to an X server; returned from
8310 % o parent: Specifies the parent window_info.
8312 % o argv: Specifies the application's argument list.
8314 % o argc: Specifies the number of arguments.
8316 % o class_hint: Specifies a pointer to a X11 XClassHint structure.
8318 % o manager_hints: Specifies a pointer to a X11 XWMHints structure.
8320 % o window_info: Specifies a pointer to a X11 XWindowInfo structure.
8323 MagickExport void XMakeWindow(Display *display,Window parent,char **argv,
8324 int argc,XClassHint *class_hint,XWMHints *manager_hints,
8325 XWindowInfo *window_info)
8327 #define MinWindowSize 64
8335 static XTextProperty
8346 Set window info hints.
8348 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
8349 assert(display != (Display *) NULL);
8350 assert(window_info != (XWindowInfo *) NULL);
8351 size_hints=XAllocSizeHints();
8352 if (size_hints == (XSizeHints *) NULL)
8353 ThrowXWindowFatalException(XServerFatalError,"UnableToMakeXWindow",argv[0]);
8354 size_hints->flags=(int) window_info->flags;
8355 size_hints->x=window_info->x;
8356 size_hints->y=window_info->y;
8357 size_hints->width=(int) window_info->width;
8358 size_hints->height=(int) window_info->height;
8359 if (window_info->immutable != MagickFalse)
8362 Window size cannot be changed.
8364 size_hints->min_width=size_hints->width;
8365 size_hints->min_height=size_hints->height;
8366 size_hints->max_width=size_hints->width;
8367 size_hints->max_height=size_hints->height;
8368 size_hints->flags|=PMinSize;
8369 size_hints->flags|=PMaxSize;
8374 Window size can be changed.
8376 size_hints->min_width=(int) window_info->min_width;
8377 size_hints->min_height=(int) window_info->min_height;
8378 size_hints->flags|=PResizeInc;
8379 size_hints->width_inc=(int) window_info->width_inc;
8380 size_hints->height_inc=(int) window_info->height_inc;
8381 #if !defined(PRE_R4_ICCCM)
8382 size_hints->flags|=PBaseSize;
8383 size_hints->base_width=size_hints->width_inc;
8384 size_hints->base_height=size_hints->height_inc;
8387 gravity=NorthWestGravity;
8388 if (window_info->geometry != (char *) NULL)
8391 default_geometry[MaxTextExtent],
8392 geometry[MaxTextExtent];
8401 User specified geometry.
8403 (void) FormatLocaleString(default_geometry,MaxTextExtent,"%dx%d",
8404 size_hints->width,size_hints->height);
8405 (void) CopyMagickString(geometry,window_info->geometry,MaxTextExtent);
8407 while (strlen(p) != 0)
8409 if ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '%'))
8412 (void) CopyMagickString(p,p+1,MaxTextExtent);
8414 flags=XWMGeometry(display,window_info->screen,geometry,default_geometry,
8415 window_info->border_width,size_hints,&size_hints->x,&size_hints->y,
8416 &size_hints->width,&size_hints->height,&gravity);
8417 if ((flags & WidthValue) && (flags & HeightValue))
8418 size_hints->flags|=USSize;
8419 if ((flags & XValue) && (flags & YValue))
8421 size_hints->flags|=USPosition;
8422 window_info->x=size_hints->x;
8423 window_info->y=size_hints->y;
8426 #if !defined(PRE_R4_ICCCM)
8427 size_hints->win_gravity=gravity;
8428 size_hints->flags|=PWinGravity;
8430 if (window_info->id == (Window) NULL)
8431 window_info->id=XCreateWindow(display,parent,window_info->x,window_info->y,
8432 (unsigned int) size_hints->width,(unsigned int) size_hints->height,
8433 window_info->border_width,(int) window_info->depth,InputOutput,
8434 window_info->visual,(unsigned long) window_info->mask,
8435 &window_info->attributes);
8448 Window already exists; change relevant attributes.
8450 (void) XChangeWindowAttributes(display,window_info->id,(unsigned long)
8451 window_info->mask,&window_info->attributes);
8452 mask=ConfigureNotify;
8453 while (XCheckTypedWindowEvent(display,window_info->id,(int) mask,&sans_event)) ;
8454 window_changes.x=window_info->x;
8455 window_changes.y=window_info->y;
8456 window_changes.width=(int) window_info->width;
8457 window_changes.height=(int) window_info->height;
8458 mask=(MagickStatusType) (CWWidth | CWHeight);
8459 if (window_info->flags & USPosition)
8461 (void) XReconfigureWMWindow(display,window_info->id,window_info->screen,
8462 mask,&window_changes);
8464 if (window_info->id == (Window) NULL)
8465 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateWindow",
8467 status=XStringListToTextProperty(&window_info->name,1,&window_name);
8468 if (status == False)
8469 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateTextProperty",
8471 status=XStringListToTextProperty(&window_info->icon_name,1,&icon_name);
8472 if (status == False)
8473 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateTextProperty",
8474 window_info->icon_name);
8475 if (window_info->icon_geometry != (char *) NULL)
8483 User specified icon geometry.
8485 size_hints->flags|=USPosition;
8486 flags=XWMGeometry(display,window_info->screen,window_info->icon_geometry,
8487 (char *) NULL,0,size_hints,&manager_hints->icon_x,
8488 &manager_hints->icon_y,&width,&height,&gravity);
8489 if ((flags & XValue) && (flags & YValue))
8490 manager_hints->flags|=IconPositionHint;
8492 XSetWMProperties(display,window_info->id,&window_name,&icon_name,argv,argc,
8493 size_hints,manager_hints,class_hint);
8494 if (window_name.value != (void *) NULL)
8496 (void) XFree((void *) window_name.value);
8497 window_name.value=(unsigned char *) NULL;
8498 window_name.nitems=0;
8500 if (icon_name.value != (void *) NULL)
8502 (void) XFree((void *) icon_name.value);
8503 icon_name.value=(unsigned char *) NULL;
8506 atom_list[0]=XInternAtom(display,"WM_DELETE_WINDOW",MagickFalse);
8507 atom_list[1]=XInternAtom(display,"WM_TAKE_FOCUS",MagickFalse);
8508 (void) XSetWMProtocols(display,window_info->id,atom_list,2);
8509 (void) XFree((void *) size_hints);
8510 if (window_info->shape != MagickFalse)
8512 #if defined(MAGICKCORE_HAVE_SHAPE)
8518 Can we apply a non-rectangular shaping mask?
8522 if (XShapeQueryExtension(display,&error_base,&event_base) == 0)
8523 window_info->shape=MagickFalse;
8525 window_info->shape=MagickFalse;
8528 if (window_info->shared_memory)
8530 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
8532 Can we use shared memory with this window?
8534 if (XShmQueryExtension(display) == 0)
8535 window_info->shared_memory=MagickFalse;
8537 window_info->shared_memory=MagickFalse;
8540 window_info->image=NewImageList();
8541 window_info->destroy=MagickFalse;
8545 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8549 % X M a g i c k P r o g r e s s M o n i t o r %
8553 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8555 % XMagickProgressMonitor() displays the progress a task is making in
8556 % completing a task.
8558 % The format of the XMagickProgressMonitor method is:
8560 % void XMagickProgressMonitor(const char *task,
8561 % const MagickOffsetType quantum,const MagickSizeType span,
8562 % void *client_data)
8564 % A description of each parameter follows:
8566 % o task: Identifies the task in progress.
8568 % o quantum: Specifies the quantum position within the span which represents
8569 % how much progress has been made in completing a task.
8571 % o span: Specifies the span relative to completing a task.
8573 % o client_data: Pointer to any client data.
8577 static const char *GetLocaleMonitorMessage(const char *text)
8580 message[MaxTextExtent],
8589 (void) CopyMagickMemory(tag,text,MaxTextExtent);
8591 if (p != (char *) NULL)
8593 (void) FormatLocaleString(message,MaxTextExtent,"Monitor/%s",tag);
8594 locale_message=GetLocaleMessage(message);
8595 if (locale_message == message)
8597 return(locale_message);
8600 MagickExport MagickBooleanType XMagickProgressMonitor(const char *tag,
8601 const MagickOffsetType quantum,const MagickSizeType span,
8602 void *magick_unused(client_data))
8607 windows=XSetWindows((XWindows *) ~0);
8608 if (windows == (XWindows *) NULL)
8610 if (windows->info.mapped != MagickFalse)
8611 XProgressMonitorWidget(windows->display,windows,
8612 GetLocaleMonitorMessage(tag),quantum,span);
8617 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8621 % X Q u e r y C o l o r D a t a b a s e %
8625 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8627 % XQueryColorDatabase() looks up a RGB values for a color given in the target
8630 % The format of the XQueryColorDatabase method is:
8632 % MagickBooleanType XQueryColorDatabase(const char *target,XColor *color)
8634 % A description of each parameter follows:
8636 % o target: Specifies the color to lookup in the X color database.
8638 % o color: A pointer to an PixelPacket structure. The RGB value of the target
8639 % color is returned as this value.
8642 MagickExport MagickBooleanType XQueryColorDatabase(const char *target,
8649 *display = (Display *) NULL;
8658 Initialize color return value.
8660 assert(color != (XColor *) NULL);
8664 color->flags=(char) (DoRed | DoGreen | DoBlue);
8665 if ((target == (char *) NULL) || (*target == '\0'))
8666 target="#ffffffffffff";
8668 Let the X server define the color for us.
8670 if (display == (Display *) NULL)
8671 display=XOpenDisplay((char *) NULL);
8672 if (display == (Display *) NULL)
8674 ThrowXWindowFatalException(XServerError,"ColorIsNotKnownToServer",target);
8675 return(MagickFalse);
8677 colormap=XDefaultColormap(display,XDefaultScreen(display));
8678 status=XParseColor(display,colormap,(char *) target,&xcolor);
8679 if (status == False)
8680 ThrowXWindowFatalException(XServerError,"ColorIsNotKnownToServer",target)
8683 color->red=xcolor.red;
8684 color->green=xcolor.green;
8685 color->blue=xcolor.blue;
8686 color->flags=xcolor.flags;
8688 return(status != False ? MagickTrue : MagickFalse);
8692 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8696 % X Q u e r y P o s i t i o n %
8700 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8702 % XQueryPosition() gets the pointer coordinates relative to a window.
8704 % The format of the XQueryPosition method is:
8706 % void XQueryPosition(Display *display,const Window window,int *x,int *y)
8708 % A description of each parameter follows:
8710 % o display: Specifies a connection to an X server; returned from
8713 % o window: Specifies a pointer to a Window.
8715 % o x: Return the x coordinate of the pointer relative to the origin of the
8718 % o y: Return the y coordinate of the pointer relative to the origin of the
8722 MagickExport void XQueryPosition(Display *display,const Window window,int *x,int *y)
8734 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
8735 assert(display != (Display *) NULL);
8736 assert(window != (Window) NULL);
8737 assert(x != (int *) NULL);
8738 assert(y != (int *) NULL);
8739 (void) XQueryPointer(display,window,&root_window,&root_window,&x_root,&y_root,
8744 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8748 % X R e f r e s h W i n d o w %
8752 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8754 % XRefreshWindow() refreshes an image in a X window.
8756 % The format of the XRefreshWindow method is:
8758 % void XRefreshWindow(Display *display,const XWindowInfo *window,
8759 % const XEvent *event)
8761 % A description of each parameter follows:
8763 % o display: Specifies a connection to an X server; returned from
8766 % o window: Specifies a pointer to a XWindowInfo structure.
8768 % o event: Specifies a pointer to a XEvent structure. If it is NULL,
8769 % the entire image is refreshed.
8772 MagickExport void XRefreshWindow(Display *display,const XWindowInfo *window,
8773 const XEvent *event)
8783 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
8784 assert(display != (Display *) NULL);
8785 assert(window != (XWindowInfo *) NULL);
8786 if (window->ximage == (XImage *) NULL)
8788 if (event != (XEvent *) NULL)
8791 Determine geometry from expose event.
8795 width=(unsigned int) event->xexpose.width;
8796 height=(unsigned int) event->xexpose.height;
8804 Refresh entire window; discard outstanding expose events.
8808 width=window->width;
8809 height=window->height;
8810 while (XCheckTypedWindowEvent(display,window->id,Expose,&sans_event)) ;
8811 if (window->matte_pixmap != (Pixmap) NULL)
8813 #if defined(MAGICKCORE_HAVE_SHAPE)
8814 if (window->shape != MagickFalse)
8815 XShapeCombineMask(display,window->id,ShapeBounding,0,0,
8816 window->matte_pixmap,ShapeSet);
8821 Check boundary conditions.
8823 if ((window->ximage->width-(x+window->x)) < (int) width)
8824 width=(unsigned int) (window->ximage->width-(x+window->x));
8825 if ((window->ximage->height-(y+window->y)) < (int) height)
8826 height=(unsigned int) (window->ximage->height-(y+window->y));
8830 if (window->matte_pixmap != (Pixmap) NULL)
8831 (void) XSetClipMask(display,window->annotate_context,window->matte_pixmap);
8832 if (window->pixmap != (Pixmap) NULL)
8834 if (window->depth > 1)
8835 (void) XCopyArea(display,window->pixmap,window->id,
8836 window->annotate_context,x+window->x,y+window->y,width,height,x,y);
8838 (void) XCopyPlane(display,window->pixmap,window->id,
8839 window->highlight_context,x+window->x,y+window->y,width,height,x,y,
8844 #if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
8845 if (window->shared_memory)
8846 (void) XShmPutImage(display,window->id,window->annotate_context,
8847 window->ximage,x+window->x,y+window->y,x,y,width,height,MagickTrue);
8849 if (window->shared_memory == MagickFalse)
8850 (void) XPutImage(display,window->id,window->annotate_context,
8851 window->ximage,x+window->x,y+window->y,x,y,width,height);
8853 if (window->matte_pixmap != (Pixmap) NULL)
8854 (void) XSetClipMask(display,window->annotate_context,None);
8855 (void) XFlush(display);
8859 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8863 % X R e m o t e C o m m a n d %
8867 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8869 % XRemoteCommand() forces a remote display(1) to display the specified
8872 % The format of the XRemoteCommand method is:
8874 % MagickBooleanType XRemoteCommand(Display *display,const char *window,
8875 % const char *filename)
8877 % A description of each parameter follows:
8879 % o display: Specifies a connection to an X server; returned from
8882 % o window: Specifies the name or id of an X window.
8884 % o filename: the name of the image filename to display.
8887 MagickExport MagickBooleanType XRemoteCommand(Display *display,
8888 const char *window,const char *filename)
8897 assert(filename != (char *) NULL);
8898 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
8899 if (display == (Display *) NULL)
8900 display=XOpenDisplay((char *) NULL);
8901 if (display == (Display *) NULL)
8903 ThrowXWindowException(XServerError,"UnableToOpenXServer",filename);
8904 return(MagickFalse);
8906 remote_atom=XInternAtom(display,"IM_PROTOCOLS",MagickFalse);
8907 remote_window=(Window) NULL;
8908 root_window=XRootWindow(display,XDefaultScreen(display));
8909 if (window != (char *) NULL)
8912 Search window hierarchy and identify any clients by name or ID.
8914 if (isdigit((unsigned char) *window) != 0)
8915 remote_window=XWindowByID(display,root_window,(Window)
8916 strtol((char *) window,(char **) NULL,0));
8917 if (remote_window == (Window) NULL)
8918 remote_window=XWindowByName(display,root_window,window);
8920 if (remote_window == (Window) NULL)
8921 remote_window=XWindowByProperty(display,root_window,remote_atom);
8922 if (remote_window == (Window) NULL)
8924 ThrowXWindowException(XServerError,"UnableToConnectToRemoteDisplay",
8926 return(MagickFalse);
8929 Send remote command.
8931 remote_atom=XInternAtom(display,"IM_REMOTE_COMMAND",MagickFalse);
8932 (void) XChangeProperty(display,remote_window,remote_atom,XA_STRING,8,
8933 PropModeReplace,(unsigned char *) filename,(int) strlen(filename));
8934 (void) XSync(display,MagickFalse);
8939 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8943 % X R e t a i n W i n d o w C o l o r s %
8947 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8949 % XRetainWindowColors() sets X11 color resources on a window. This preserves
8950 % the colors associated with an image displayed on the window.
8952 % The format of the XRetainWindowColors method is:
8954 % void XRetainWindowColors(Display *display,const Window window)
8956 % A description of each parameter follows:
8958 % o display: Specifies a connection to an X server; returned from
8961 % o window: Specifies a pointer to a XWindowInfo structure.
8964 MagickExport void XRetainWindowColors(Display *display,const Window window)
8973 Put property on the window.
8975 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
8976 assert(display != (Display *) NULL);
8977 assert(window != (Window) NULL);
8978 property=XInternAtom(display,"_XSETROOT_ID",MagickFalse);
8979 if (property == (Atom) NULL)
8981 ThrowXWindowFatalException(XServerError,"UnableToCreateProperty",
8985 pixmap=XCreatePixmap(display,window,1,1,1);
8986 if (pixmap == (Pixmap) NULL)
8988 ThrowXWindowFatalException(XServerError,"UnableToCreateBitmap","");
8991 (void) XChangeProperty(display,window,property,XA_PIXMAP,32,PropModeReplace,
8992 (unsigned char *) &pixmap,1);
8993 (void) XSetCloseDownMode(display,RetainPermanent);
8997 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9001 % X S e l e c t W i n d o w %
9005 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9007 % XSelectWindow() allows a user to select a window using the mouse. If the
9008 % mouse moves, a cropping rectangle is drawn and the extents of the rectangle
9009 % is returned in the crop_info structure.
9011 % The format of the XSelectWindow function is:
9013 % target_window=XSelectWindow(display,crop_info)
9015 % A description of each parameter follows:
9017 % o window: XSelectWindow returns the window id.
9019 % o display: Specifies a pointer to the Display structure; returned from
9022 % o crop_info: Specifies a pointer to a RectangleInfo structure. It
9023 % contains the extents of any cropping rectangle.
9026 static Window XSelectWindow(Display *display,RectangleInfo *crop_info)
9028 #define MinimumCropArea (unsigned int) 9
9055 Initialize graphic context.
9057 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
9058 assert(display != (Display *) NULL);
9059 assert(crop_info != (RectangleInfo *) NULL);
9060 root_window=XRootWindow(display,XDefaultScreen(display));
9061 context_values.background=XBlackPixel(display,XDefaultScreen(display));
9062 context_values.foreground=XWhitePixel(display,XDefaultScreen(display));
9063 context_values.function=GXinvert;
9064 context_values.plane_mask=
9065 context_values.background ^ context_values.foreground;
9066 context_values.subwindow_mode=IncludeInferiors;
9067 annotate_context=XCreateGC(display,root_window,(size_t) (GCBackground |
9068 GCForeground | GCFunction | GCSubwindowMode),&context_values);
9069 if (annotate_context == (GC) NULL)
9070 return(MagickFalse);
9072 Grab the pointer using target cursor.
9074 target_cursor=XMakeCursor(display,root_window,XDefaultColormap(display,
9075 XDefaultScreen(display)),(char * ) "white",(char * ) "black");
9076 status=XGrabPointer(display,root_window,MagickFalse,(unsigned int)
9077 (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask),GrabModeSync,
9078 GrabModeAsync,root_window,target_cursor,CurrentTime);
9079 if (status != GrabSuccess)
9081 ThrowXWindowFatalException(XServerError,"UnableToGrabMouse","");
9082 return((Window) NULL);
9088 crop_info->height=0;
9090 target_window=(Window) NULL;
9095 if ((crop_info->width*crop_info->height) >= MinimumCropArea)
9096 (void) XDrawRectangle(display,root_window,annotate_context,
9097 (int) crop_info->x,(int) crop_info->y,(unsigned int) crop_info->width-1,
9098 (unsigned int) crop_info->height-1);
9100 Allow another event.
9102 (void) XAllowEvents(display,SyncPointer,CurrentTime);
9103 (void) XWindowEvent(display,root_window,ButtonPressMask |
9104 ButtonReleaseMask | ButtonMotionMask,&event);
9105 if ((crop_info->width*crop_info->height) >= MinimumCropArea)
9106 (void) XDrawRectangle(display,root_window,annotate_context,
9107 (int) crop_info->x,(int) crop_info->y,(unsigned int) crop_info->width-1,
9108 (unsigned int) crop_info->height-1);
9113 target_window=XGetSubwindow(display,event.xbutton.subwindow,
9114 event.xbutton.x,event.xbutton.y);
9115 if (target_window == (Window) NULL)
9116 target_window=root_window;
9117 x_offset=event.xbutton.x_root;
9118 y_offset=event.xbutton.y_root;
9119 crop_info->x=(ssize_t) x_offset;
9120 crop_info->y=(ssize_t) y_offset;
9122 crop_info->height=0;
9134 Discard pending button motion events.
9136 while (XCheckMaskEvent(display,ButtonMotionMask,&event)) ;
9137 crop_info->x=(ssize_t) event.xmotion.x;
9138 crop_info->y=(ssize_t) event.xmotion.y;
9140 Check boundary conditions.
9142 if ((int) crop_info->x < x_offset)
9143 crop_info->width=(size_t) (x_offset-crop_info->x);
9146 crop_info->width=(size_t) (crop_info->x-x_offset);
9147 crop_info->x=(ssize_t) x_offset;
9149 if ((int) crop_info->y < y_offset)
9150 crop_info->height=(size_t) (y_offset-crop_info->y);
9153 crop_info->height=(size_t) (crop_info->y-y_offset);
9154 crop_info->y=(ssize_t) y_offset;
9160 } while ((target_window == (Window) NULL) || (presses > 0));
9161 (void) XUngrabPointer(display,CurrentTime);
9162 (void) XFreeCursor(display,target_cursor);
9163 (void) XFreeGC(display,annotate_context);
9164 if ((crop_info->width*crop_info->height) < MinimumCropArea)
9167 crop_info->height=0;
9169 if ((crop_info->width != 0) && (crop_info->height != 0))
9170 target_window=root_window;
9171 return(target_window);
9175 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9179 % X S e t C u r s o r S t a t e %
9183 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9185 % XSetCursorState() sets the cursor state to busy, otherwise the cursor are
9186 % reset to their default.
9188 % The format of the XXSetCursorState method is:
9190 % XSetCursorState(display,windows,const MagickStatusType state)
9192 % A description of each parameter follows:
9194 % o display: Specifies a connection to an X server; returned from
9197 % o windows: Specifies a pointer to a XWindows structure.
9199 % o state: An unsigned integer greater than 0 sets the cursor state
9200 % to busy, otherwise the cursor are reset to their default.
9203 MagickExport void XSetCursorState(Display *display,XWindows *windows,
9204 const MagickStatusType state)
9206 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
9207 assert(display != (Display *) NULL);
9208 assert(windows != (XWindows *) NULL);
9211 (void) XCheckDefineCursor(display,windows->image.id,
9212 windows->image.busy_cursor);
9213 (void) XCheckDefineCursor(display,windows->pan.id,
9214 windows->pan.busy_cursor);
9215 (void) XCheckDefineCursor(display,windows->magnify.id,
9216 windows->magnify.busy_cursor);
9217 (void) XCheckDefineCursor(display,windows->command.id,
9218 windows->command.busy_cursor);
9222 (void) XCheckDefineCursor(display,windows->image.id,
9223 windows->image.cursor);
9224 (void) XCheckDefineCursor(display,windows->pan.id,windows->pan.cursor);
9225 (void) XCheckDefineCursor(display,windows->magnify.id,
9226 windows->magnify.cursor);
9227 (void) XCheckDefineCursor(display,windows->command.id,
9228 windows->command.cursor);
9229 (void) XCheckDefineCursor(display,windows->command.id,
9230 windows->widget.cursor);
9231 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
9233 windows->info.mapped=MagickFalse;
9237 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9241 % X S e t W i n d o w s %
9245 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9247 % XSetWindows() sets the X windows structure if the windows info is specified.
9248 % Otherwise the current windows structure is returned.
9250 % The format of the XSetWindows method is:
9252 % XWindows *XSetWindows(XWindows *windows_info)
9254 % A description of each parameter follows:
9256 % o windows_info: Initialize the Windows structure with this information.
9259 MagickExport XWindows *XSetWindows(XWindows *windows_info)
9262 *windows = (XWindows *) NULL;
9264 if (windows_info != (XWindows *) ~0)
9266 windows=(XWindows *) RelinquishMagickMemory(windows);
9267 windows=windows_info;
9272 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9276 % X U s e r P r e f e r e n c e s %
9280 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9282 % XUserPreferences() saves the preferences in a configuration file in the
9283 % users' home directory.
9285 % The format of the XUserPreferences method is:
9287 % void XUserPreferences(XResourceInfo *resource_info)
9289 % A description of each parameter follows:
9291 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
9294 MagickExport void XUserPreferences(XResourceInfo *resource_info)
9296 #if defined(X11_PREFERENCES_PATH)
9298 cache[MaxTextExtent],
9299 filename[MaxTextExtent],
9300 specifier[MaxTextExtent];
9307 preferences_database;
9310 Save user preferences to the client configuration file.
9312 assert(resource_info != (XResourceInfo *) NULL);
9313 client_name=GetClientName();
9314 preferences_database=XrmGetStringDatabase("");
9315 (void) FormatLocaleString(specifier,MaxTextExtent,"%s.backdrop",client_name);
9316 value=resource_info->backdrop ? "True" : "False";
9317 XrmPutStringResource(&preferences_database,specifier,(char *) value);
9318 (void) FormatLocaleString(specifier,MaxTextExtent,"%s.colormap",client_name);
9319 value=resource_info->colormap == SharedColormap ? "Shared" : "Private";
9320 XrmPutStringResource(&preferences_database,specifier,(char *) value);
9321 (void) FormatLocaleString(specifier,MaxTextExtent,"%s.confirmExit",
9323 value=resource_info->confirm_exit ? "True" : "False";
9324 XrmPutStringResource(&preferences_database,specifier,(char *) value);
9325 (void) FormatLocaleString(specifier,MaxTextExtent,"%s.confirmEdit",
9327 value=resource_info->confirm_edit ? "True" : "False";
9328 XrmPutStringResource(&preferences_database,specifier,(char *) value);
9329 (void) FormatLocaleString(specifier,MaxTextExtent,"%s.displayWarnings",
9331 value=resource_info->display_warnings ? "True" : "False";
9332 XrmPutStringResource(&preferences_database,specifier,(char *) value);
9333 (void) FormatLocaleString(specifier,MaxTextExtent,"%s.dither",client_name);
9334 value=resource_info->quantize_info->dither ? "True" : "False";
9335 XrmPutStringResource(&preferences_database,specifier,(char *) value);
9336 (void) FormatLocaleString(specifier,MaxTextExtent,"%s.gammaCorrect",
9338 value=resource_info->gamma_correct ? "True" : "False";
9339 XrmPutStringResource(&preferences_database,specifier,(char *) value);
9340 (void) FormatLocaleString(specifier,MaxTextExtent,"%s.undoCache",client_name);
9341 (void) FormatLocaleString(cache,MaxTextExtent,"%.20g",(double)
9342 resource_info->undo_cache);
9343 XrmPutStringResource(&preferences_database,specifier,cache);
9344 (void) FormatLocaleString(specifier,MaxTextExtent,"%s.usePixmap",client_name);
9345 value=resource_info->use_pixmap ? "True" : "False";
9346 XrmPutStringResource(&preferences_database,specifier,(char *) value);
9347 (void) FormatLocaleString(filename,MaxTextExtent,"%s%src",
9348 X11_PREFERENCES_PATH,client_name);
9349 ExpandFilename(filename);
9350 XrmPutFileDatabase(preferences_database,filename);
9355 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9359 % X V i s u a l C l a s s N a m e %
9363 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9365 % XVisualClassName() returns the visual class name as a character string.
9367 % The format of the XVisualClassName method is:
9369 % char *XVisualClassName(const int visual_class)
9371 % A description of each parameter follows:
9373 % o visual_type: XVisualClassName returns the visual class as a character
9376 % o class: Specifies the visual class.
9379 static const char *XVisualClassName(const int visual_class)
9381 switch (visual_class)
9383 case StaticGray: return("StaticGray");
9384 case GrayScale: return("GrayScale");
9385 case StaticColor: return("StaticColor");
9386 case PseudoColor: return("PseudoColor");
9387 case TrueColor: return("TrueColor");
9388 case DirectColor: return("DirectColor");
9390 return("unknown visual class");
9394 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9402 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9404 % XWarning() displays a warning reason in a Notice widget.
9406 % The format of the XWarning method is:
9408 % void XWarning(const unsigned int warning,const char *reason,
9409 % const char *description)
9411 % A description of each parameter follows:
9413 % o warning: Specifies the numeric warning category.
9415 % o reason: Specifies the reason to display before terminating the
9418 % o description: Specifies any description to the reason.
9421 MagickExport void XWarning(const ExceptionType magick_unused(warning),
9422 const char *reason,const char *description)
9425 text[MaxTextExtent];
9430 if (reason == (char *) NULL)
9432 (void) CopyMagickString(text,reason,MaxTextExtent);
9433 (void) ConcatenateMagickString(text,":",MaxTextExtent);
9434 windows=XSetWindows((XWindows *) ~0);
9435 XNoticeWidget(windows->display,windows,text,(char *) description);
9439 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9443 % X W i n d o w B y I D %
9447 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9449 % XWindowByID() locates a child window with a given ID. If not window with
9450 % the given name is found, 0 is returned. Only the window specified and its
9451 % subwindows are searched.
9453 % The format of the XWindowByID function is:
9455 % child=XWindowByID(display,window,id)
9457 % A description of each parameter follows:
9459 % o child: XWindowByID returns the window with the specified
9460 % id. If no windows are found, XWindowByID returns 0.
9462 % o display: Specifies a pointer to the Display structure; returned from
9465 % o id: Specifies the id of the window to locate.
9468 MagickExport Window XWindowByID(Display *display,const Window root_window,
9488 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
9489 assert(display != (Display *) NULL);
9490 assert(root_window != (Window) NULL);
9492 return(XSelectWindow(display,&rectangle_info));
9493 if (root_window == id)
9494 return(root_window);
9495 status=XQueryTree(display,root_window,&child,&child,&children,
9497 if (status == False)
9498 return((Window) NULL);
9499 window=(Window) NULL;
9500 for (i=0; i < (int) number_children; i++)
9503 Search each child and their children.
9505 window=XWindowByID(display,children[i],id);
9506 if (window != (Window) NULL)
9509 if (children != (Window *) NULL)
9510 (void) XFree((void *) children);
9515 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9519 % X W i n d o w B y N a m e %
9523 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9525 % XWindowByName() locates a window with a given name on a display. If no
9526 % window with the given name is found, 0 is returned. If more than one window
9527 % has the given name, the first one is returned. Only root and its children
9530 % The format of the XWindowByName function is:
9532 % window=XWindowByName(display,root_window,name)
9534 % A description of each parameter follows:
9536 % o window: XWindowByName returns the window id.
9538 % o display: Specifies a pointer to the Display structure; returned from
9541 % o root_window: Specifies the id of the root window.
9543 % o name: Specifies the name of the window to locate.
9546 MagickExport Window XWindowByName(Display *display,const Window root_window,
9566 assert(display != (Display *) NULL);
9567 assert(root_window != (Window) NULL);
9568 assert(name != (char *) NULL);
9569 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
9570 if (XGetWMName(display,root_window,&window_name) != 0)
9571 if (LocaleCompare((char *) window_name.value,name) == 0)
9572 return(root_window);
9573 status=XQueryTree(display,root_window,&child,&child,&children,
9575 if (status == False)
9576 return((Window) NULL);
9577 window=(Window) NULL;
9578 for (i=0; i < (int) number_children; i++)
9581 Search each child and their children.
9583 window=XWindowByName(display,children[i],name);
9584 if (window != (Window) NULL)
9587 if (children != (Window *) NULL)
9588 (void) XFree((void *) children);
9593 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9597 % X W i n d o w B y P r o p e r y %
9601 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9603 % XWindowByProperty() locates a child window with a given property. If not
9604 % window with the given name is found, 0 is returned. If more than one window
9605 % has the given property, the first one is returned. Only the window
9606 % specified and its subwindows are searched.
9608 % The format of the XWindowByProperty function is:
9610 % child=XWindowByProperty(display,window,property)
9612 % A description of each parameter follows:
9614 % o child: XWindowByProperty returns the window id with the specified
9615 % property. If no windows are found, XWindowByProperty returns 0.
9617 % o display: Specifies a pointer to the Display structure; returned from
9620 % o property: Specifies the property of the window to locate.
9623 MagickExport Window XWindowByProperty(Display *display,const Window window,
9624 const Atom property)
9652 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
9653 assert(display != (Display *) NULL);
9654 assert(window != (Window) NULL);
9655 assert(property != (Atom) NULL);
9656 status=XQueryTree(display,window,&root,&parent,&children,&number_children);
9657 if (status == False)
9658 return((Window) NULL);
9660 child=(Window) NULL;
9661 for (i=0; (i < number_children) && (child == (Window) NULL); i++)
9663 status=XGetWindowProperty(display,children[i],property,0L,0L,MagickFalse,
9664 (Atom) AnyPropertyType,&type,&format,&number_items,&after,&data);
9666 (void) XFree((void *) data);
9667 if ((status == Success) && (type != (Atom) NULL))
9670 for (i=0; (i < number_children) && (child == (Window) NULL); i++)
9671 child=XWindowByProperty(display,children[i],property);
9672 if (children != (Window *) NULL)
9673 (void) XFree((void *) children);
9679 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9683 % X I m p o r t I m a g e %
9687 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9689 % XImportImage() reads an image from an X window.
9691 % The format of the XImportImage method is:
9693 % Image *XImportImage(const ImageInfo *image_info,XImportInfo *ximage_info)
9695 % A description of each parameter follows:
9697 % o image_info: the image info..
9699 % o ximage_info: Specifies a pointer to an XImportInfo structure.
9702 MagickExport Image *XImportImage(const ImageInfo *image_info,
9703 XImportInfo *ximage_info)
9705 assert(image_info != (const ImageInfo *) NULL);
9706 assert(image_info->signature == MagickSignature);
9707 if (image_info->debug != MagickFalse)
9708 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
9709 image_info->filename);
9710 assert(ximage_info != (XImportInfo *) NULL);
9711 return((Image *) NULL);
9716 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9720 + X C o m p o n e n t G e n e s i s %
9724 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9726 % XComponentGenesis() instantiates the X component.
9728 % The format of the XComponentGenesis method is:
9730 % MagickBooleanType XComponentGenesis(void)
9733 MagickExport MagickBooleanType XComponentGenesis(void)
9739 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9743 % X G e t I m p o r t I n f o %
9747 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9749 % XGetImportInfo() initializes the XImportInfo structure.
9751 % The format of the XGetImportInfo method is:
9753 % void XGetImportInfo(XImportInfo *ximage_info)
9755 % A description of each parameter follows:
9757 % o ximage_info: Specifies a pointer to an ImageInfo structure.
9760 MagickExport void XGetImportInfo(XImportInfo *ximage_info)
9762 assert(ximage_info != (XImportInfo *) NULL);
9763 ximage_info->frame=MagickFalse;
9764 ximage_info->borders=MagickFalse;
9765 ximage_info->screen=MagickFalse;
9766 ximage_info->descend=MagickTrue;
9767 ximage_info->silent=MagickFalse;