/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X X W W IIIII N N DDDD OOO W W % % X X W W I NN N D D O O W W % % X W W I N N N D D O O W W % % X X W W W I N NN D D O O W W W % % X X W W IIIII N N DDDD OOO W W % % % % % % X11 Utility Methods for ImageMagick % % % % Software Design % % John Cristy % % July 1992 % % % % % % Copyright 1999-2007 ImageMagick Studio LLC, a non-profit organization % % dedicated to making software imaging solutions freely available. % % % % You may not use this file except in compliance with the License. You may % % obtain a copy of the License at % % % % http://www.imagemagick.org/script/license.php % % % % Unless required by applicable law or agreed to in writing, software % % distributed under the License is distributed on an "AS IS" BASIS, % % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % % See the License for the specific language governing permissions and % % limitations under the License. % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % */ /* Include declarations. */ #include "magick/studio.h" #include "magick/animate.h" #include "magick/blob.h" #include "magick/client.h" #include "magick/color.h" #include "magick/color-private.h" #include "magick/composite.h" #include "magick/display.h" #include "magick/exception.h" #include "magick/exception-private.h" #include "magick/geometry.h" #include "magick/identify.h" #include "magick/image.h" #include "magick/image-private.h" #include "magick/list.h" #include "magick/locale_.h" #include "magick/log.h" #include "magick/magick.h" #include "magick/memory_.h" #include "magick/monitor.h" #include "magick/option.h" #include "magick/PreRvIcccm.h" #include "magick/quantize.h" #include "magick/quantum.h" #include "magick/quantum-private.h" #include "magick/resource_.h" #include "magick/resize.h" #include "magick/shear.h" #include "magick/statistic.h" #include "magick/string_.h" #include "magick/transform.h" #include "magick/utility.h" #include "magick/widget.h" #include "magick/xwindow.h" #include "magick/xwindow-private.h" #include "magick/version.h" #if defined(__BEOS__) #include #endif #if defined(HasX11) #include #include #if defined(HAVE_POLL) # include #endif #if defined(HasSharedMemory) #if defined(HAVE_MACHINE_PARAM_H) # include #endif #include #include #include #endif #if defined(HasShape) #include #endif /* X defines. */ #define XBlueGamma(color) RoundToQuantum(blue_gamma == 1.0 ? (double) \ (color) : ((pow(((double) QuantumScale*(color)),1.0/(double) blue_gamma)* \ QuantumRange))) #define XGammaPixel(map,color) (unsigned long) (map->base_pixel+ \ ((ScaleQuantumToShort(XRedGamma((color)->red))*map->red_max/65535L)* \ map->red_mult)+ \ ((ScaleQuantumToShort(XGreenGamma((color)->green))*map->green_max/65535L)* \ map->green_mult)+ \ ((ScaleQuantumToShort(XBlueGamma((color)->blue))*map->blue_max/65535L)* \ map->blue_mult)) #define XGreenGamma(color) RoundToQuantum(green_gamma == 1.0 ? (double) \ (color) : ((pow(((double) QuantumScale*(color)),1.0/(double) green_gamma)* \ QuantumRange))) #define XRedGamma(color) RoundToQuantum(red_gamma == 1.0 ? (double) \ (color) : ((pow(((double) QuantumScale*(color)),1.0/(double) red_gamma)* \ QuantumRange))) #define XStandardPixel(map,color) (unsigned long) (map->base_pixel+ \ (((color)->red*map->red_max/65535L)*map->red_mult)+ \ (((color)->green*map->green_max/65535L)*map->green_mult)+ \ (((color)->blue*map->blue_max/65535L)*map->blue_mult)) #define AccentuateModulate ScaleCharToQuantum(80) #define HighlightModulate ScaleCharToQuantum(125) #define ShadowModulate ScaleCharToQuantum(135) #define DepthModulate ScaleCharToQuantum(185) #define TroughModulate ScaleCharToQuantum(110) #define XLIB_ILLEGAL_ACCESS 1 #undef ForgetGravity #undef NorthWestGravity #undef NorthGravity #undef NorthEastGravity #undef WestGravity #undef CenterGravity #undef EastGravity #undef SouthWestGravity #undef SouthGravity #undef SouthEastGravity #undef StaticGravity #undef index #if defined(hpux9) #define XFD_SET int #else #define XFD_SET fd_set #endif /* Enumeration declarations. */ typedef enum { #undef DoRed DoRed = 0x0001, #undef DoGreen DoGreen = 0x0002, #undef DoBlue DoBlue = 0x0004, DoMatte = 0x0008 } XColorFlags; /* Typedef declarations. */ typedef struct _DiversityPacket { Quantum red, green, blue; unsigned short index; unsigned long count; } DiversityPacket; /* Constant declaractions. */ static MagickBooleanType xerror_alert = MagickFalse; /* Method prototypes. */ static const char *XVisualClassName(const int); static MagickRealType blue_gamma = 1.0, green_gamma = 1.0, red_gamma = 1.0; static MagickBooleanType XMakePixmap(Display *,const XResourceInfo *,XWindowInfo *); static void XMakeImageLSBFirst(const XResourceInfo *,const XWindowInfo *,Image *, XImage *,XImage *), XMakeImageMSBFirst(const XResourceInfo *,const XWindowInfo *,Image *, XImage *,XImage *); static Window XSelectWindow(Display *,RectangleInfo *); /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % D e s t r o y X R e s o u r c e s % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % DestroyXResources() destroys any X resources. % % The format of the DestroyXResources method is: % % void DestroyXResources() % % A description of each parameter follows: % */ MagickExport void DestroyXResources(void) { register int i; unsigned int number_windows; XWindowInfo *magick_windows[MaxXWindows]; XWindows *windows; DestroyXWidget(); windows=XSetWindows((XWindows *) ~0); if ((windows == (XWindows *) NULL) || (windows->display == (Display *) NULL)) return; number_windows=0; magick_windows[number_windows++]=(&windows->context); magick_windows[number_windows++]=(&windows->group_leader); magick_windows[number_windows++]=(&windows->backdrop); magick_windows[number_windows++]=(&windows->icon); magick_windows[number_windows++]=(&windows->image); magick_windows[number_windows++]=(&windows->info); magick_windows[number_windows++]=(&windows->magnify); magick_windows[number_windows++]=(&windows->pan); magick_windows[number_windows++]=(&windows->command); magick_windows[number_windows++]=(&windows->widget); magick_windows[number_windows++]=(&windows->popup); magick_windows[number_windows++]=(&windows->context); for (i=0; i < (int) number_windows; i++) { if (magick_windows[i]->mapped != MagickFalse) { (void) XWithdrawWindow(windows->display,magick_windows[i]->id, magick_windows[i]->screen); magick_windows[i]->mapped=MagickFalse; } if (magick_windows[i]->name != (char *) NULL) magick_windows[i]->name=(char *) RelinquishMagickMemory(magick_windows[i]->name); if (magick_windows[i]->icon_name != (char *) NULL) magick_windows[i]->icon_name=(char *) RelinquishMagickMemory(magick_windows[i]->icon_name); if (magick_windows[i]->cursor != (Cursor) NULL) { (void) XFreeCursor(windows->display,magick_windows[i]->cursor); magick_windows[i]->cursor=(Cursor) NULL; } if (magick_windows[i]->busy_cursor != (Cursor) NULL) { (void) XFreeCursor(windows->display,magick_windows[i]->busy_cursor); magick_windows[i]->busy_cursor=(Cursor) NULL; } if (magick_windows[i]->highlight_stipple != (Pixmap) NULL) { (void) XFreePixmap(windows->display, magick_windows[i]->highlight_stipple); magick_windows[i]->highlight_stipple=(Pixmap) NULL; } if (magick_windows[i]->shadow_stipple != (Pixmap) NULL) { (void) XFreePixmap(windows->display,magick_windows[i]->shadow_stipple); magick_windows[i]->shadow_stipple=(Pixmap) NULL; } if (magick_windows[i]->ximage != (XImage *) NULL) { XDestroyImage(magick_windows[i]->ximage); magick_windows[i]->ximage=(XImage *) NULL; } if (magick_windows[i]->pixmap != (Pixmap) NULL) { (void) XFreePixmap(windows->display,magick_windows[i]->pixmap); magick_windows[i]->pixmap=(Pixmap) NULL; } if (magick_windows[i]->id != (Window) NULL) { (void) XDestroyWindow(windows->display,magick_windows[i]->id); magick_windows[i]->id=(Window) NULL; } if (magick_windows[i]->destroy != MagickFalse) { if (magick_windows[i]->image != (Image *) NULL) { magick_windows[i]->image=DestroyImage(magick_windows[i]->image); magick_windows[i]->image=NewImageList(); } if (magick_windows[i]->matte_pixmap != (Pixmap) NULL) { (void) XFreePixmap(windows->display, magick_windows[i]->matte_pixmap); magick_windows[i]->matte_pixmap=(Pixmap) NULL; } } if (magick_windows[i]->segment_info != (void *) NULL) { #if defined(HasSharedMemory) XShmSegmentInfo *segment_info; segment_info=(XShmSegmentInfo *) magick_windows[i]->segment_info; if (segment_info != (XShmSegmentInfo *) NULL) if (segment_info[0].shmid >= 0) { if (segment_info[0].shmaddr != NULL) (void) shmdt(segment_info[0].shmaddr); (void) shmctl(segment_info[0].shmid,IPC_RMID,0); segment_info[0].shmaddr=NULL; segment_info[0].shmid=(-1); } #endif magick_windows[i]->segment_info=(void *) RelinquishMagickMemory(magick_windows[i]->segment_info); } } windows->icon_resources=(XResourceInfo *) RelinquishMagickMemory(windows->icon_resources); if (windows->icon_pixel != (XPixelInfo *) NULL) { if (windows->icon_pixel->pixels != (unsigned long *) NULL) windows->icon_pixel->pixels=(unsigned long *) RelinquishMagickMemory(windows->icon_pixel->pixels); if (windows->icon_pixel->annotate_context != (GC) NULL) XFreeGC(windows->display,windows->icon_pixel->annotate_context); windows->icon_pixel=(XPixelInfo *) RelinquishMagickMemory(windows->icon_pixel); } if (windows->pixel_info != (XPixelInfo *) NULL) { if (windows->pixel_info->pixels != (unsigned long *) NULL) windows->pixel_info->pixels=(unsigned long *) RelinquishMagickMemory(windows->pixel_info->pixels); if (windows->pixel_info->annotate_context != (GC) NULL) XFreeGC(windows->display,windows->pixel_info->annotate_context); if (windows->pixel_info->widget_context != (GC) NULL) XFreeGC(windows->display,windows->pixel_info->widget_context); if (windows->pixel_info->highlight_context != (GC) NULL) XFreeGC(windows->display,windows->pixel_info->highlight_context); windows->pixel_info=(XPixelInfo *) RelinquishMagickMemory(windows->pixel_info); } if (windows->font_info != (XFontStruct *) NULL) { XFreeFont(windows->display,windows->font_info); windows->font_info=(XFontStruct *) NULL; } if (windows->class_hints != (XClassHint *) NULL) { XFree(windows->class_hints); windows->class_hints=(XClassHint *) NULL; } if (windows->manager_hints != (XWMHints *) NULL) { XFree(windows->manager_hints); windows->manager_hints=(XWMHints *) NULL; } if (windows->map_info != (XStandardColormap *) NULL) { XFree(windows->map_info); windows->map_info=(XStandardColormap *) NULL; } if (windows->icon_map != (XStandardColormap *) NULL) { XFree(windows->icon_map); windows->icon_map=(XStandardColormap *) NULL; } if (windows->visual_info != (XVisualInfo *) NULL) { XFree(windows->visual_info); windows->visual_info=(XVisualInfo *) NULL; } if (windows->icon_visual != (XVisualInfo *) NULL) { XFree(windows->icon_visual); windows->icon_visual=(XVisualInfo *) NULL; } (void) XSetWindows((XWindows *) NULL); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X A n n o t a t e I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XAnnotateImage() annotates the image with text. % % The format of the XAnnotateImage method is: % % MagickBooleanType XAnnotateImage(Display *display, % const XPixelInfo *pixel,XAnnotateInfo *annotate_info,Image *image) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o pixel: Specifies a pointer to a XPixelInfo structure. % % o annotate_info: Specifies a pointer to a XAnnotateInfo structure. % % o image: The image. % */ MagickExport MagickBooleanType XAnnotateImage(Display *display, const XPixelInfo *pixel,XAnnotateInfo *annotate_info,Image *image) { GC annotate_context; Image *annotate_image; int x, y; MagickBooleanType matte; Pixmap annotate_pixmap; register PixelPacket *q; unsigned int depth, height, width; Window root_window; XGCValues context_values; XImage *annotate_ximage; /* Initialize annotated image. */ (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(display != (Display *) NULL); assert(pixel != (XPixelInfo *) NULL); assert(annotate_info != (XAnnotateInfo *) NULL); assert(image != (Image *) NULL); /* Initialize annotated pixmap. */ root_window=XRootWindow(display,XDefaultScreen(display)); depth=(unsigned int) XDefaultDepth(display,XDefaultScreen(display)); annotate_pixmap=XCreatePixmap(display,root_window,annotate_info->width, annotate_info->height,depth); if (annotate_pixmap == (Pixmap) NULL) return(MagickFalse); /* Initialize graphics info. */ context_values.background=0; context_values.foreground=(unsigned long) (~0); context_values.font=annotate_info->font_info->fid; annotate_context=XCreateGC(display,root_window,(unsigned long) GCBackground | GCFont | GCForeground,&context_values); if (annotate_context == (GC) NULL) return(MagickFalse); /* Draw text to pixmap. */ (void) XDrawImageString(display,annotate_pixmap,annotate_context,0, (int) annotate_info->font_info->ascent,annotate_info->text, (int) strlen(annotate_info->text)); (void) XFreeGC(display,annotate_context); /* Initialize annotated X image. */ annotate_ximage=XGetImage(display,annotate_pixmap,0,0,annotate_info->width, annotate_info->height,AllPlanes,ZPixmap); if (annotate_ximage == (XImage *) NULL) return(MagickFalse); (void) XFreePixmap(display,annotate_pixmap); /* Initialize annotated image. */ annotate_image=AllocateImage((ImageInfo *) NULL); if (annotate_image == (Image *) NULL) return(MagickFalse); annotate_image->columns=annotate_info->width; annotate_image->rows=annotate_info->height; /* Transfer annotated X image to image. */ width=(unsigned int) image->columns; height=(unsigned int) image->rows; x=0; y=0; (void) XParseGeometry(annotate_info->geometry,&x,&y,&width,&height); annotate_image->background_color=GetOnePixel(image,x,y); if (annotate_info->stencil == ForegroundStencil) annotate_image->matte=MagickTrue; for (y=0; y < (int) annotate_image->rows; y++) { q=GetImagePixels(annotate_image,0,y,annotate_image->columns,1); if (q == (PixelPacket *) NULL) break; for (x=0; x < (int) annotate_image->columns; x++) { q->opacity=OpaqueOpacity; if (XGetPixel(annotate_ximage,x,y) == 0) { /* Set this pixel to the background color. */ q->red=ScaleShortToQuantum(pixel->box_color.red); q->green=ScaleShortToQuantum(pixel->box_color.green); q->blue=ScaleShortToQuantum(pixel->box_color.blue); if ((annotate_info->stencil == ForegroundStencil) || (annotate_info->stencil == OpaqueStencil)) q->opacity=(Quantum) TransparentOpacity; } else { /* Set this pixel to the pen color. */ q->red=ScaleShortToQuantum(pixel->pen_color.red); q->green=ScaleShortToQuantum(pixel->pen_color.green); q->blue=ScaleShortToQuantum(pixel->pen_color.blue); if (annotate_info->stencil == BackgroundStencil) q->opacity=(Quantum) TransparentOpacity; } q++; } if (SyncImagePixels(annotate_image) == MagickFalse) break; } XDestroyImage(annotate_ximage); /* Determine annotate geometry. */ (void) XParseGeometry(annotate_info->geometry,&x,&y,&width,&height); if ((width != (unsigned int) annotate_image->columns) || (height != (unsigned int) annotate_image->rows)) { char image_geometry[MaxTextExtent]; /* Scale image. */ (void) FormatMagickString(image_geometry,MaxTextExtent,"%ux%u", width,height); (void) TransformImage(&annotate_image,(char *) NULL,image_geometry); } if (annotate_info->degrees != 0.0) { Image *rotate_image; int rotations; MagickRealType normalized_degrees; /* Rotate image. */ rotate_image= RotateImage(annotate_image,annotate_info->degrees,&image->exception); if (rotate_image == (Image *) NULL) return(MagickFalse); annotate_image=DestroyImage(annotate_image); annotate_image=rotate_image; /* Annotation is relative to the degree of rotation. */ normalized_degrees=annotate_info->degrees; while (normalized_degrees < -45.0) normalized_degrees+=360.0; for (rotations=0; normalized_degrees > 45.0; rotations++) normalized_degrees-=90.0; switch (rotations % 4) { default: case 0: break; case 1: { /* Rotate 90 degrees. */ x-=(int) annotate_image->columns/2; y+=(int) annotate_image->columns/2; break; } case 2: { /* Rotate 180 degrees. */ x=x-(int) annotate_image->columns; break; } case 3: { /* Rotate 270 degrees. */ x=x-(int) annotate_image->columns/2; y=y-(int) (annotate_image->rows-(annotate_image->columns/2)); break; } } } /* Composite text onto the image. */ (void) XParseGeometry(annotate_info->geometry,&x,&y,&width,&height); matte=image->matte; (void) CompositeImage(image,annotate_image->matte != MagickFalse ? OverCompositeOp : CopyCompositeOp,annotate_image,x,y); image->matte=matte; annotate_image=DestroyImage(annotate_image); return(MagickTrue); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X B e s t F o n t % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XBestFont() returns the "best" font. "Best" is defined as a font specified % in the X resource database or a font such that the text width displayed % with the font does not exceed the specified maximum width. % % The format of the XBestFont method is: % % XFontStruct *XBestFont(Display *display, % const XResourceInfo *resource_info,const MagickBooleanType text_font) % % A description of each parameter follows: % % o font: XBestFont returns a pointer to a XFontStruct structure. % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o resource_info: Specifies a pointer to a X11 XResourceInfo structure. % % o text_font: True is font should be mono-spaced (typewriter style). % % */ static char **FontToList(char *font) { char **fontlist; register char *p, *q; register int i; unsigned int fonts; if (font == (char *) NULL) return((char **) NULL); /* Convert string to an ASCII list. */ fonts=1U; for (p=font; *p != '\0'; p++) if ((*p == ':') || (*p == ';') || (*p == ',')) fonts++; fontlist=(char **) AcquireQuantumMemory((size_t) fonts+1UL,sizeof(*fontlist)); if (fontlist == (char **) NULL) { ThrowXWindowFatalException(ResourceLimitError,"MemoryAllocationFailed", font); return((char **) NULL); } p=font; for (i=0; i < (int) fonts; i++) { for (q=p; *q != '\0'; q++) if ((*q == ':') || (*q == ';') || (*q == ',')) break; fontlist[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+1UL, sizeof(*fontlist[i])); if (fontlist[i] == (char *) NULL) { ThrowXWindowFatalException(ResourceLimitError,"MemoryAllocationFailed", font); return((char **) NULL); } (void) CopyMagickString(fontlist[i],p,(size_t) (q-p+1)); p=q+1; } fontlist[i]=(char *) NULL; return(fontlist); } MagickExport XFontStruct *XBestFont(Display *display, const XResourceInfo *resource_info,const MagickBooleanType text_font) { static const char *Fonts[]= { "-*-helvetica-medium-r-normal--12-*-*-*-*-*-iso8859-1", "-*-arial-medium-r-normal--12-*-*-*-*-*-iso8859-1", "-*-helvetica-medium-r-normal--12-*-*-*-*-*-iso8859-15", "-*-arial-medium-r-normal--12-*-*-*-*-*-iso8859-15", "-*-helvetica-medium-r-normal--12-*-*-*-*-*-*-*", "-*-arial-medium-r-normal--12-*-*-*-*-*-*-*", "variable", "fixed", (char *) NULL }, *TextFonts[]= { "-*-courier-medium-r-normal-*-12-*-*-*-*-*-iso8859-1", "-*-courier-medium-r-normal-*-12-*-*-*-*-*-iso8859-15", "-*-fixed-medium-r-normal-*-12-*-*-*-*-*-*-*", "fixed", (char *) NULL }; char *font_name; register const char **p; XFontStruct *font_info; font_info=(XFontStruct *) NULL; font_name=resource_info->font; if (text_font != MagickFalse) font_name=resource_info->text_font; if ((font_name != (char *) NULL) && (*font_name != '\0')) { char **fontlist; register int i; /* Load preferred font specified in the X resource database. */ fontlist=FontToList(font_name); if (fontlist != (char **) NULL) { for (i=0; fontlist[i] != (char *) NULL; i++) { if (font_info == (XFontStruct *) NULL) font_info=XLoadQueryFont(display,fontlist[i]); fontlist[i]=DestroyString(fontlist[i]); } fontlist=(char **) RelinquishMagickMemory(fontlist); } if (font_info == (XFontStruct *) NULL) ThrowXWindowFatalException(XServerError,"UnableToLoadFont",font_name); } /* Load fonts from list of fonts until one is found. */ p=Fonts; if (text_font != MagickFalse) p=TextFonts; if (XDisplayHeight(display,XDefaultScreen(display)) >= 748) p++; while (*p != (char *) NULL) { if (font_info != (XFontStruct *) NULL) break; font_info=XLoadQueryFont(display,(char *) *p); p++; } return(font_info); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X B e s t I c o n S i z e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XBestIconSize() returns the "best" icon size. "Best" is defined as an icon % size that maintains the aspect ratio of the image. If the window manager % has preferred icon sizes, one of the preferred sizes is used. % % The format of the XBestIconSize method is: % % void XBestIconSize(Display *display,XWindowInfo *window,Image *image) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o image: The image. % */ MagickExport void XBestIconSize(Display *display,XWindowInfo *window, Image *image) { int i, number_sizes; MagickRealType scale_factor; unsigned int height, icon_height, icon_width, width; Window root_window; XIconSize *icon_size, *size_list; /* Determine if the window manager has specified preferred icon sizes. */ (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(display != (Display *) NULL); assert(window != (XWindowInfo *) NULL); assert(image != (Image *) NULL); window->width=MaxIconSize; window->height=MaxIconSize; icon_size=(XIconSize *) NULL; number_sizes=0; root_window=XRootWindow(display,window->screen); if (XGetIconSizes(display,root_window,&size_list,&number_sizes) != 0) if ((number_sizes > 0) && (size_list != (XIconSize *) NULL)) icon_size=size_list; if (icon_size == (XIconSize *) NULL) { /* Window manager does not restrict icon size. */ icon_size=XAllocIconSize(); if (icon_size == (XIconSize *) NULL) { ThrowXWindowFatalException(ResourceLimitError, "MemoryAllocationFailed",image->filename); return; } icon_size->min_width=1; icon_size->max_width=MaxIconSize; icon_size->min_height=1; icon_size->max_height=MaxIconSize; icon_size->width_inc=1; icon_size->height_inc=1; } /* Determine aspect ratio of image. */ width=(unsigned int) image->columns; height=(unsigned int) image->rows; i=0; if (window->crop_geometry) (void) XParseGeometry(window->crop_geometry,&i,&i,&width,&height); /* Look for an icon size that maintains the aspect ratio of image. */ scale_factor=(MagickRealType) icon_size->max_width/width; if (scale_factor > ((MagickRealType) icon_size->max_height/height)) scale_factor=(MagickRealType) icon_size->max_height/height; icon_width=(unsigned int) icon_size->min_width; while ((int) icon_width < icon_size->max_width) { if (icon_width >= (unsigned int) (scale_factor*width+0.5)) break; icon_width+=icon_size->width_inc; } icon_height=(unsigned int) icon_size->min_height; while ((int) icon_height < icon_size->max_height) { if (icon_height >= (unsigned int) (scale_factor*height+0.5)) break; icon_height+=icon_size->height_inc; } (void) XFree((void *) icon_size); window->width=icon_width; window->height=icon_height; } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X B e s t P i x e l % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XBestPixel() returns a pixel from an array of pixels that is closest to the % requested color. If the color array is NULL, the colors are obtained from % the X server. % % The format of the XBestPixel method is: % % void XBestPixel(Display *display,const Colormap colormap,XColor *colors, % unsigned int number_colors,XColor *color) % % A description of each parameter follows: % % o pixel: XBestPixel returns the pixel value closest to the requested % color. % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o colormap: Specifies the ID of the X server colormap. % % o colors: Specifies an array of XColor structures. % % o number_colors: Specifies the number of XColor structures in the % color definition array. % % o color: Specifies the desired RGB value to find in the colors array. % */ MagickExport void XBestPixel(Display *display,const Colormap colormap, XColor *colors,unsigned int number_colors,XColor *color) { MagickBooleanType query_server; MagickPixelPacket pixel; MagickRealType min_distance; register MagickRealType distance; register int i, j; Status status; /* Find closest representation for the requested RGB color. */ (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(display != (Display *) NULL); assert(color != (XColor *) NULL); status=XAllocColor(display,colormap,color); if (status != False) return; query_server=colors == (XColor *) NULL ? MagickTrue : MagickFalse; if (query_server != MagickFalse) { /* Read X server colormap. */ colors=(XColor *) AcquireQuantumMemory(number_colors,sizeof(*colors)); if (colors == (XColor *) NULL) { ThrowXWindowFatalException(ResourceLimitError, "MemoryAllocationFailed","..."); return; } for (i=0; i < (int) number_colors; i++) colors[i].pixel=(unsigned long) i; if (number_colors > 256) number_colors=256; (void) XQueryColors(display,colormap,colors,(int) number_colors); } min_distance=3.0*((MagickRealType) QuantumRange+1.0)*((MagickRealType) QuantumRange+1.0); j=0; for (i=0; i < (int) number_colors; i++) { pixel.red=colors[i].red-(MagickRealType) color->red; distance=pixel.red*pixel.red; if (distance > min_distance) continue; pixel.green=colors[i].green-(MagickRealType) color->green; distance+=pixel.green*pixel.green; if (distance > min_distance) continue; pixel.blue=colors[i].blue-(MagickRealType) color->blue; distance+=pixel.blue*pixel.blue; if (distance > min_distance) continue; min_distance=distance; color->pixel=colors[i].pixel; j=i; } (void) XAllocColor(display,colormap,&colors[j]); if (query_server != MagickFalse) colors=(XColor *) RelinquishMagickMemory(colors); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X B e s t V i s u a l I n f o % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XBestVisualInfo() returns visual information for a visual that is the "best" % the server supports. "Best" is defined as: % % 1. Restrict the visual list to those supported by the default screen. % % 2. If a visual type is specified, restrict the visual list to those of % that type. % % 3. If a map type is specified, choose the visual that matches the id % specified by the Standard Colormap. % % 4 From the list of visuals, choose one that can display the most % simultaneous colors. If more than one visual can display the same % number of simultaneous colors, one is chosen based on a rank. % % The format of the XBestVisualInfo method is: % % XVisualInfo *XBestVisualInfo(Display *display, % XStandardColormap *map_info,XResourceInfo *resource_info) % % A description of each parameter follows: % % o visual_info: XBestVisualInfo returns a pointer to a X11 XVisualInfo % structure. % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o map_info: If map_type is specified, this structure is initialized % with info from the Standard Colormap. % % o resource_info: Specifies a pointer to a X11 XResourceInfo structure. % */ static inline int MagickMax(const int x,const int y) { if (x > y) return(x); return(y); } static inline unsigned long MagickMin(const unsigned int x, const unsigned int y) { if (x < y) return(x); return(y); } MagickExport XVisualInfo *XBestVisualInfo(Display *display, XStandardColormap *map_info,XResourceInfo *resource_info) { #define MaxStandardColormaps 7 #define XVisualColormapSize(visual_info) MagickMin((unsigned int) (\ (visual_info->klass == TrueColor) || (visual_info->klass == DirectColor) ? \ visual_info->red_mask | visual_info->green_mask | visual_info->blue_mask : \ (unsigned int) visual_info->colormap_size),1U << visual_info->depth) char *map_type, *visual_type; long visual_mask; register int i; static int number_visuals; static XVisualInfo visual_template; XVisualInfo *visual_info, *visual_list; /* Restrict visual search by screen number. */ (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(display != (Display *) NULL); assert(map_info != (XStandardColormap *) NULL); assert(resource_info != (XResourceInfo *) NULL); map_type=resource_info->map_type; visual_type=resource_info->visual_type; visual_mask=VisualScreenMask; visual_template.screen=XDefaultScreen(display); visual_template.depth=XDefaultDepth(display,XDefaultScreen(display)); if ((resource_info->immutable != MagickFalse) && (resource_info->colors != 0)) if (resource_info->colors <= (1UL << (unsigned long) visual_template.depth)) visual_mask|=VisualDepthMask; if (visual_type != (char *) NULL) { /* Restrict visual search by class or visual id. */ if (LocaleCompare("staticgray",visual_type) == 0) { visual_mask|=VisualClassMask; visual_template.klass=StaticGray; } else if (LocaleCompare("grayscale",visual_type) == 0) { visual_mask|=VisualClassMask; visual_template.klass=GrayScale; } else if (LocaleCompare("staticcolor",visual_type) == 0) { visual_mask|=VisualClassMask; visual_template.klass=StaticColor; } else if (LocaleCompare("pseudocolor",visual_type) == 0) { visual_mask|=VisualClassMask; visual_template.klass=PseudoColor; } else if (LocaleCompare("truecolor",visual_type) == 0) { visual_mask|=VisualClassMask; visual_template.klass=TrueColor; } else if (LocaleCompare("directcolor",visual_type) == 0) { visual_mask|=VisualClassMask; visual_template.klass=DirectColor; } else if (LocaleCompare("default",visual_type) == 0) { visual_mask|=VisualIDMask; visual_template.visualid=XVisualIDFromVisual( XDefaultVisual(display,XDefaultScreen(display))); } else if (isdigit((int) ((unsigned char) *visual_type)) != 0) { visual_mask|=VisualIDMask; visual_template.visualid= strtol(visual_type,(char **) NULL,0); } else ThrowXWindowFatalException(XServerError, "UnrecognizedVisualSpecifier",visual_type); } /* Get all visuals that meet our criteria so far. */ number_visuals=0; visual_list=XGetVisualInfo(display,visual_mask,&visual_template, &number_visuals); visual_mask=VisualScreenMask | VisualIDMask; if ((number_visuals == 0) || (visual_list == (XVisualInfo *) NULL)) { /* Failed to get visual; try using the default visual. */ ThrowXWindowFatalException(XServerWarning,"UnableToGetVisual", visual_type); visual_template.visualid=XVisualIDFromVisual(XDefaultVisual(display, XDefaultScreen(display))); visual_list=XGetVisualInfo(display,visual_mask,&visual_template, &number_visuals); if ((number_visuals == 0) || (visual_list == (XVisualInfo *) NULL)) return((XVisualInfo *) NULL); ThrowXWindowFatalException(XServerWarning,"UsingDefaultVisual", XVisualClassName(visual_list->klass)); } resource_info->color_recovery=MagickFalse; if ((map_info != (XStandardColormap *) NULL) && (map_type != (char *) NULL)) { Atom map_property; char map_name[MaxTextExtent]; int j, number_maps; Status status; Window root_window; XStandardColormap *map_list; /* Choose a visual associated with a standard colormap. */ root_window=XRootWindow(display,XDefaultScreen(display)); status=False; if (LocaleCompare(map_type,"list") != 0) { /* User specified Standard Colormap. */ (void) FormatMagickString((char *) map_name,MaxTextExtent, "RGB_%s_MAP",map_type); LocaleUpper(map_name); map_property=XInternAtom(display,(char *) map_name,MagickTrue); if (map_property != (Atom) NULL) status=XGetRGBColormaps(display,root_window,&map_list,&number_maps, map_property); } else { static const char *colormap[MaxStandardColormaps]= { "_HP_RGB_SMOOTH_MAP_LIST", "RGB_BEST_MAP", "RGB_DEFAULT_MAP", "RGB_GRAY_MAP", "RGB_RED_MAP", "RGB_GREEN_MAP", "RGB_BLUE_MAP", }; /* Choose a standard colormap from a list. */ for (i=0; i < MaxStandardColormaps; i++) { map_property=XInternAtom(display,(char *) colormap[i],MagickTrue); if (map_property == (Atom) NULL) continue; status=XGetRGBColormaps(display,root_window,&map_list,&number_maps, map_property); if (status != False) break; } resource_info->color_recovery=i == 0 ? MagickTrue : MagickFalse; } if (status == False) { ThrowXWindowFatalException(XServerError,"UnableToGetStandardColormap", map_type); return((XVisualInfo *) NULL); } /* Search all Standard Colormaps and visuals for ids that match. */ *map_info=map_list[0]; #if !defined(PRE_R4_ICCCM) visual_template.visualid=XVisualIDFromVisual(visual_list[0].visual); for (i=0; i < number_maps; i++) for (j=0; j < number_visuals; j++) if (map_list[i].visualid == XVisualIDFromVisual(visual_list[j].visual)) { *map_info=map_list[i]; visual_template.visualid=XVisualIDFromVisual( visual_list[j].visual); break; } if (map_info->visualid != visual_template.visualid) { ThrowXWindowFatalException(XServerError, "UnableToMatchVisualToStandardColormap",map_type); return((XVisualInfo *) NULL); } #endif if (map_info->colormap == (Colormap) NULL) { ThrowXWindowFatalException(XServerError, "StandardColormapIsNotInitialized",map_type); return((XVisualInfo *) NULL); } (void) XFree((void *) map_list); } else { static const unsigned int rank[]= { StaticGray, GrayScale, StaticColor, DirectColor, TrueColor, PseudoColor }; XVisualInfo *p; /* Pick one visual that displays the most simultaneous colors. */ visual_info=visual_list; p=visual_list; for (i=1; i < number_visuals; i++) { p++; if (XVisualColormapSize(p) > XVisualColormapSize(visual_info)) visual_info=p; else if (XVisualColormapSize(p) == XVisualColormapSize(visual_info)) if (rank[p->klass] > rank[visual_info->klass]) visual_info=p; } visual_template.visualid=XVisualIDFromVisual(visual_info->visual); } (void) XFree((void *) visual_list); /* Retrieve only one visual by its screen & id number. */ visual_info=XGetVisualInfo(display,visual_mask,&visual_template, &number_visuals); if ((number_visuals == 0) || (visual_info == (XVisualInfo *) NULL)) return((XVisualInfo *) NULL); return(visual_info); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X C h e c k D e f i n e C u r s o r % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XCheckDefineCursor() prevents cursor changes on the root window. % % The format of the XXCheckDefineCursor method is: % % XCheckDefineCursor(display,window,cursor) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o window: The window. % % o cursor: The cursor. % */ MagickExport int XCheckDefineCursor(Display *display,Window window, Cursor cursor) { (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(display != (Display *) NULL); if (window == XRootWindow(display,XDefaultScreen(display))) return(0); return(XDefineCursor(display,window,cursor)); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X C h e c k R e f r e s h W i n d o w s % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XCheckRefreshWindows() checks the X server for exposure events for a % particular window and updates the area associated with the exposure event. % % The format of the XCheckRefreshWindows method is: % % void XCheckRefreshWindows(Display *display,XWindows *windows) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o windows: Specifies a pointer to a XWindows structure. % */ MagickExport void XCheckRefreshWindows(Display *display,XWindows *windows) { Window id; XEvent event; (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(display != (Display *) NULL); assert(windows != (XWindows *) NULL); XDelay(display,SuspendTime); id=windows->command.id; while (XCheckTypedWindowEvent(display,id,Expose,&event) != MagickFalse) (void) XCommandWidget(display,windows,(char const **) NULL,&event); id=windows->image.id; while (XCheckTypedWindowEvent(display,id,Expose,&event) != MagickFalse) XRefreshWindow(display,&windows->image,&event); XDelay(display,SuspendTime << 1); id=windows->command.id; while (XCheckTypedWindowEvent(display,id,Expose,&event) != MagickFalse) (void) XCommandWidget(display,windows,(char const **) NULL,&event); id=windows->image.id; while (XCheckTypedWindowEvent(display,id,Expose,&event) != MagickFalse) XRefreshWindow(display,&windows->image,&event); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X C l i e n t M e s s a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XClientMessage() sends a reason to a window with XSendEvent. The reason is % initialized with a particular protocol type and atom. % % The format of the XClientMessage function is: % % XClientMessage(display,window,protocol,reason,timestamp) % % A description of each parameter follows: % % o display: Specifies a pointer to the Display structure; returned from % XOpenDisplay. % % o window: Specifies a pointer to a Window structure. % % o protocol: Specifies an atom value. % % o reason: Specifies an atom value which is the reason to send. % % o timestamp: Specifies a value of type Time. % */ MagickExport void XClientMessage(Display *display,const Window window, const Atom protocol,const Atom reason,const Time timestamp) { XClientMessageEvent client_event; assert(display != (Display *) NULL); client_event.type=ClientMessage; client_event.window=window; client_event.message_type=protocol; client_event.format=32; client_event.data.l[0]=(long) reason; client_event.data.l[1]=(long) timestamp; (void) XSendEvent(display,window,MagickFalse,NoEventMask,(XEvent *) &client_event); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + X C l i e n t W i n d o w % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XClientWindow() finds a window, at or below the specified window, which has % a WM_STATE property. If such a window is found, it is returned, otherwise % the argument window is returned. % % The format of the XClientWindow function is: % % client_window=XClientWindow(display,target_window) % % A description of each parameter follows: % % o client_window: XClientWindow returns a window, at or below the specified % window, which has a WM_STATE property otherwise the argument % target_window is returned. % % o display: Specifies a pointer to the Display structure; returned from % XOpenDisplay. % % o target_window: Specifies the window to find a WM_STATE property. % % */ static Window XClientWindow(Display *display,Window target_window) { Atom state, type; int format; Status status; unsigned char *data; unsigned long after, number_items; Window client_window; (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(display != (Display *) NULL); state=XInternAtom(display,"WM_STATE",MagickTrue); if (state == (Atom) NULL) return(target_window); type=(Atom) NULL; status=XGetWindowProperty(display,target_window,state,0L,0L,MagickFalse, (Atom) AnyPropertyType,&type,&format,&number_items,&after,&data); if ((status == Success) && (type != (Atom) NULL)) return(target_window); client_window=XWindowByProperty(display,target_window,state); if (client_window == (Window) NULL) return(target_window); return(client_window); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X C o n f i g u r e I m a g e C o l o r m a p % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XConfigureImageColormap() creates a new X colormap. % % The format of the XConfigureImageColormap method is: % % void XConfigureImageColormap(Display *display, % XResourceInfo *resource_info,XWindows *windows,Image *image) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o resource_info: Specifies a pointer to a X11 XResourceInfo structure. % % o windows: Specifies a pointer to a XWindows structure. % % o image: The image. % */ MagickExport void XConfigureImageColormap(Display *display, XResourceInfo *resource_info,XWindows *windows,Image *image) { Colormap colormap; /* Make standard colormap. */ XSetCursorState(display,windows,MagickTrue); XCheckRefreshWindows(display,windows); XMakeStandardColormap(display,windows->visual_info,resource_info,image, windows->map_info,windows->pixel_info); colormap=windows->map_info->colormap; (void) XSetWindowColormap(display,windows->image.id,colormap); (void) XSetWindowColormap(display,windows->command.id,colormap); (void) XSetWindowColormap(display,windows->widget.id,colormap); if (windows->magnify.mapped != MagickFalse) (void) XSetWindowColormap(display,windows->magnify.id,colormap); if (windows->pan.mapped != MagickFalse) (void) XSetWindowColormap(display,windows->pan.id,colormap); XSetCursorState(display,windows,MagickFalse); XClientMessage(display,windows->image.id,windows->im_protocols, windows->im_update_colormap,CurrentTime); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X C o n s t r a i n W i n d o w P o s i t i o n % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XConstrainWindowPosition() assures a window is positioned within the X % server boundaries. % % The format of the XConstrainWindowPosition method is: % % void XConstrainWindowPosition(Display *display,XWindowInfo *window_info) % % A description of each parameter follows: % % o display: Specifies a pointer to the Display structure; returned from % XOpenDisplay. % % o window_info: Specifies a pointer to a XWindowInfo structure. % */ MagickExport void XConstrainWindowPosition(Display *display, XWindowInfo *window_info) { int limit; (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(display != (Display *) NULL); assert(window_info != (XWindowInfo *) NULL); limit=XDisplayWidth(display,window_info->screen)-window_info->width; if (window_info->x < 0) window_info->x=0; else if (window_info->x > (int) limit) window_info->x=(int) limit; limit=XDisplayHeight(display,window_info->screen)-window_info->height; if (window_info->y < 0) window_info->y=0; else if (window_info->y > limit) window_info->y=limit; } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X D e l a y % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XDelay() suspends program execution for the number of milliseconds % specified. % % The format of the Delay method is: % % void XDelay(Display *display,const unsigned long milliseconds) % % A description of each parameter follows: % % o display: Specifies a pointer to the Display structure; returned from % XOpenDisplay. % % o milliseconds: Specifies the number of milliseconds to delay before % returning. % */ MagickExport void XDelay(Display *display,const unsigned long milliseconds) { assert(display != (Display *) NULL); (void) XFlush(display); if (milliseconds == 0) return; #if defined(__WINDOWS__) Sleep(milliseconds); #elif defined(vms) { float timer; timer=milliseconds/1000.0; lib$wait(&timer); } #elif defined(HAVE_USLEEP) usleep(1000*milliseconds); #elif defined(HAVE_SELECT) { struct timeval timer; timer.tv_sec=(long) milliseconds/1000; timer.tv_usec=(long) (milliseconds % 1000)*1000; (void) select(0,(XFD_SET *) NULL,(XFD_SET *) NULL,(XFD_SET *) NULL,&timer); } #elif defined(HAVE_POLL) (void) poll((struct pollfd *) NULL,0,(int) milliseconds); #elif defined(__BEOS__) snooze(1000*milliseconds); #else # error "Time delay method not defined." #endif } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X D e s t r o y R e s o u r c e I n f o % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XDestroyResourceInfo() frees memory associated with the XResourceInfo % structure. % % The format of the XDestroyResourceInfo method is: % % void XDestroyResourceInfo(XResourceInfo *resource_info) % % A description of each parameter follows: % % o resource_info: Specifies a pointer to a X11 XResourceInfo structure. % */ MagickExport void XDestroyResourceInfo(XResourceInfo *resource_info) { if (resource_info->image_geometry != (char *) NULL) resource_info->image_geometry=(char *) RelinquishMagickMemory(resource_info->image_geometry); if (resource_info->image_info != (ImageInfo *) NULL) resource_info->image_info=DestroyImageInfo(resource_info->image_info); if (resource_info->quantize_info != (QuantizeInfo *) NULL) resource_info->quantize_info=DestroyQuantizeInfo( resource_info->quantize_info); if (resource_info->client_name != (char *) NULL) resource_info->client_name=(char *) RelinquishMagickMemory(resource_info->client_name); if (resource_info->name != (char *) NULL) resource_info->name=DestroyString(resource_info->name); (void) ResetMagickMemory(resource_info,0,sizeof(*resource_info)); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X D e s t r o y W i n d o w C o l o r s % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XDestroyWindowColors() frees X11 color resources previously saved on a % window by XRetainWindowColors or programs like xsetroot. % % The format of the XDestroyWindowColors method is: % % void XDestroyWindowColors(Display *display,Window window) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o window: Specifies a pointer to a Window structure. % */ MagickExport void XDestroyWindowColors(Display *display,Window window) { Atom property, type; int format; Status status; unsigned char *data; unsigned long after, length; /* If there are previous resources on the root window, destroy them. */ (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(display != (Display *) NULL); property=XInternAtom(display,"_XSETROOT_ID",MagickFalse); if (property == (Atom) NULL) { ThrowXWindowFatalException(XServerError,"UnableToCreateProperty", "_XSETROOT_ID"); return; } status=XGetWindowProperty(display,window,property,0L,1L,MagickTrue, (Atom) AnyPropertyType,&type,&format,&length,&after,&data); if (status != Success) return; if ((type == XA_PIXMAP) && (format == 32) && (length == 1) && (after == 0)) { (void) XKillClient(display,(XID) (*((Pixmap *) data))); (void) XDeleteProperty(display,window,property); } if (type != None) (void) XFree((void *) data); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X D i s p l a y I m a g e I n f o % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XDisplayImageInfo() displays information about an X image. % % The format of the XDisplayImageInfo method is: % % void XDisplayImageInfo(Display *display, % const XResourceInfo *resource_info,XWindows *windows,Image *undo_image, % Image *image) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o resource_info: Specifies a pointer to a X11 XResourceInfo structure. % % o windows: Specifies a pointer to a XWindows structure. % % o undo_image: The undo image. % % o image: The image. % */ MagickExport void XDisplayImageInfo(Display *display, const XResourceInfo *resource_info,XWindows *windows,Image *undo_image, Image *image) { char filename[MaxTextExtent], *text, **textlist; FILE *file; int unique_file; long bytes; register long i; unsigned int levels; unsigned long number_pixels; /* Write info about the X server to a file. */ assert(display != (Display *) NULL); assert(resource_info != (XResourceInfo *) NULL); assert(windows != (XWindows *) NULL); assert(image != (Image *) NULL); if (image->debug) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); file=(FILE *) NULL; unique_file=AcquireUniqueFileResource(filename); if (unique_file != -1) file=fdopen(unique_file,"w"); if ((unique_file == -1) || (file == (FILE *) NULL)) { XNoticeWidget(display,windows,"Unable to display image info",filename); return; } if (resource_info->gamma_correct != MagickFalse) if (resource_info->display_gamma != (char *) NULL) (void) fprintf(file,"Display\n gamma: %s\n\n", resource_info->display_gamma); /* Write info about the X image to a file. */ (void) fprintf(file,"X\n visual: %s\n", XVisualClassName((int) windows->image.storage_class)); (void) fprintf(file," depth: %d\n",windows->image.ximage->depth); if (windows->visual_info->colormap_size != 0) (void) fprintf(file," colormap size: %d\n", windows->visual_info->colormap_size); if (resource_info->colormap== SharedColormap) (void) fprintf(file," colormap type: Shared\n"); else (void) fprintf(file," colormap type: Private\n"); (void) fprintf(file," geometry: %dx%d\n",windows->image.ximage->width, windows->image.ximage->height); if (windows->image.crop_geometry != (char *) NULL) (void) fprintf(file," crop geometry: %s\n",windows->image.crop_geometry); if (windows->image.pixmap == (Pixmap) NULL) (void) fprintf(file," type: X Image\n"); else (void) fprintf(file," type: Pixmap\n"); if (windows->image.shape != MagickFalse) (void) fprintf(file," non-rectangular shape: True\n"); else (void) fprintf(file," non-rectangular shape: False\n"); if (windows->image.shared_memory != MagickFalse) (void) fprintf(file," shared memory: True\n"); else (void) fprintf(file," shared memory: False\n"); (void) fprintf(file,"\n"); if (resource_info->font != (char *) NULL) (void) fprintf(file,"Font: %s\n\n",resource_info->font); if (resource_info->text_font != (char *) NULL) (void) fprintf(file,"Text font: %s\n\n",resource_info->text_font); /* Write info about the undo cache to a file. */ bytes=0; for (levels=0; undo_image != (Image *) NULL; levels++) { number_pixels=undo_image->list->columns*undo_image->list->rows; bytes+=number_pixels*sizeof(PixelPacket); undo_image=GetPreviousImageInList(undo_image); } (void) fprintf(file,"Undo Edit Cache\n levels: %u\n",levels); (void) fprintf(file," bytes: %lumb\n",(unsigned long) (bytes+(1 << 19)) >> 20); (void) fprintf(file," limit: %lumb\n\n",resource_info->undo_cache); /* Write info about the image to a file. */ (void) IdentifyImage(image,file,MagickTrue); (void) fclose(file); text=FileToString(filename,~0,&image->exception); (void) RelinquishUniqueFileResource(filename); if (text == (char *) NULL) { XNoticeWidget(display,windows,"MemoryAllocationFailed", "UnableToDisplayImageInfo"); return; } textlist=StringToList(text); if (textlist != (char **) NULL) { char title[MaxTextExtent]; /* Display information about the image in the Text View widget. */ (void) XWithdrawWindow(display,windows->info.id,windows->info.screen); (void) FormatMagickString(title,MaxTextExtent,"Image Info: %s", image->filename); XTextViewWidget(display,resource_info,windows,MagickTrue,title, (char const **) textlist); for (i=0; textlist[i] != (char *) NULL; i++) textlist[i]=DestroyString(textlist[i]); textlist=(char **) RelinquishMagickMemory(textlist); } text=DestroyString(text); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + X D i t h e r I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XDitherImage() dithers the reference image as required by the HP Color % Recovery algorithm. The color values are quantized to 3 bits of red and % green, and 2 bits of blue (3/3/2) and can be used as indices into a 8-bit X % standard colormap. % % The format of the XDitherImage method is: % % void XDitherImage(Image *image,XImage *ximage) % % A description of each parameter follows: % % o image: The image. % % o ximage: Specifies a pointer to a XImage structure; returned from % XCreateImage. % % */ static void XDitherImage(Image *image,XImage *ximage) { static const short int dither_red[2][16]= { {-16, 4, -1, 11,-14, 6, -3, 9,-15, 5, -2, 10,-13, 7, -4, 8}, { 15, -5, 0,-12, 13, -7, 2,-10, 14, -6, 1,-11, 12, -8, 3, -9} }, dither_green[2][16]= { { 11,-15, 7, -3, 8,-14, 4, -2, 10,-16, 6, -4, 9,-13, 5, -1}, {-12, 14, -8, 2, -9, 13, -5, 1,-11, 15, -7, 3,-10, 12, -6, 0} }, dither_blue[2][16]= { { -3, 9,-13, 7, -1, 11,-15, 5, -4, 8,-14, 6, -2, 10,-16, 4}, { 2,-10, 12, -8, 0,-12, 14, -6, 3, -9, 13, -7, 1,-11, 15, -5} }; PixelPacket color; int y; long value; register char *q; register const PixelPacket *p; register int i, j, x; unsigned int scanline_pad; register unsigned long pixel; unsigned char *blue_map[2][16], *green_map[2][16], *red_map[2][16]; /* Allocate and initialize dither maps. */ for (i=0; i < 2; i++) for (j=0; j < 16; j++) { red_map[i][j]=(unsigned char *) AcquireQuantumMemory(256UL, sizeof(*red_map)); green_map[i][j]=(unsigned char *) AcquireQuantumMemory(256UL, sizeof(*green_map)); blue_map[i][j]=(unsigned char *) AcquireQuantumMemory(256UL, sizeof(*blue_map)); if ((red_map[i][j] == (unsigned char *) NULL) || (green_map[i][j] == (unsigned char *) NULL) || (blue_map[i][j] == (unsigned char *) NULL)) { ThrowXWindowFatalException(ResourceLimitError, "MemoryAllocationFailed",image->filename); return; } } /* Initialize dither tables. */ for (i=0; i < 2; i++) for (j=0; j < 16; j++) for (x=0; x < 256; x++) { value=x-16; if (x < 48) value=x/2+8; value+=dither_red[i][j]; red_map[i][j][x]=(unsigned char) ((value < 0) ? 0 : (value > 255) ? 255 : value); value=x-16; if (x < 48) value=x/2+8; value+=dither_green[i][j]; green_map[i][j][x]=(unsigned char) ((value < 0) ? 0 : (value > 255) ? 255 : value); value=x-32; if (x < 112) value=x/2+24; value+=((unsigned long) dither_blue[i][j] << 1); blue_map[i][j][x]=(unsigned char) ((value < 0) ? 0 : (value > 255) ? 255 : value); } /* Dither image. */ scanline_pad=(unsigned int) (ximage->bytes_per_line- ((unsigned long) (ximage->width*ximage->bits_per_pixel) >> 3)); i=0; j=0; q=ximage->data; for (y=0; y < (int) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; for (x=0; x < (int) image->columns; x++) { color.red=RoundToQuantum((MagickRealType) (red_map[i][j][(int) ScaleQuantumToChar(p->red)] << 8)); color.green=RoundToQuantum((MagickRealType) (green_map[i][j][(int) ScaleQuantumToChar(p->green)] << 8)); color.blue=RoundToQuantum((MagickRealType) (blue_map[i][j][(int) ScaleQuantumToChar(p->blue)] << 8)); pixel=(unsigned long) (((unsigned long) color.red & 0xe0) | (((unsigned long) color.green & 0xe0) >> 3) | (((unsigned long) color.blue & 0xc0) >> 6)); *q++=(char) pixel; p++; j++; if (j == 16) j=0; } q+=scanline_pad; i++; if (i == 2) i=0; } /* Free allocated memory. */ for (i=0; i < 2; i++) for (j=0; j < 16; j++) { green_map[i][j]=(unsigned char *) RelinquishMagickMemory(green_map[i][j]); blue_map[i][j]=(unsigned char *) RelinquishMagickMemory(blue_map[i][j]); red_map[i][j]=(unsigned char *) RelinquishMagickMemory(red_map[i][j]); } } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X D r a w I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XDrawImage() draws a line on the image. % % The format of the XDrawImage method is: % % MagickBooleanType XDrawImage(display,pixel,draw_info,image) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o pixel: Specifies a pointer to a XPixelInfo structure. % % o draw_info: Specifies a pointer to a XDrawInfo structure. % % o image: The image. % */ MagickExport MagickBooleanType XDrawImage(Display *display, const XPixelInfo *pixel,XDrawInfo *draw_info,Image *image) { GC draw_context; Image *draw_image; int x, y; MagickBooleanType matte; Pixmap draw_pixmap; register PixelPacket *q; unsigned int depth, height, width; Window root_window; XGCValues context_values; XImage *draw_ximage; /* Initialize drawd image. */ assert(display != (Display *) NULL); assert(pixel != (XPixelInfo *) NULL); assert(draw_info != (XDrawInfo *) NULL); assert(image != (Image *) NULL); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); /* Initialize drawd pixmap. */ root_window=XRootWindow(display,XDefaultScreen(display)); depth=(unsigned int) XDefaultDepth(display,XDefaultScreen(display)); draw_pixmap=XCreatePixmap(display,root_window,draw_info->width, draw_info->height,depth); if (draw_pixmap == (Pixmap) NULL) return(MagickFalse); /* Initialize graphics info. */ context_values.background=(unsigned long) (~0); context_values.foreground=0; context_values.line_width=(int) draw_info->line_width; draw_context=XCreateGC(display,root_window,(unsigned long) (GCBackground | GCForeground | GCLineWidth),&context_values); if (draw_context == (GC) NULL) return(MagickFalse); /* Clear pixmap. */ (void) XFillRectangle(display,draw_pixmap,draw_context,0,0,draw_info->width, draw_info->height); /* Draw line to pixmap. */ (void) XSetBackground(display,draw_context,0); (void) XSetForeground(display,draw_context,(unsigned long) (~0)); (void) XSetFillStyle(display,draw_context,FillOpaqueStippled); (void) XSetStipple(display,draw_context,draw_info->stipple); switch (draw_info->element) { case PointElement: default: { (void) XDrawLines(display,draw_pixmap,draw_context, draw_info->coordinate_info,(int) draw_info->number_coordinates, CoordModeOrigin); break; } case LineElement: { (void) XDrawLine(display,draw_pixmap,draw_context,draw_info->line_info.x1, draw_info->line_info.y1,draw_info->line_info.x2, draw_info->line_info.y2); break; } case RectangleElement: { (void) XDrawRectangle(display,draw_pixmap,draw_context, (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y, (unsigned int) draw_info->rectangle_info.width, (unsigned int) draw_info->rectangle_info.height); break; } case FillRectangleElement: { (void) XFillRectangle(display,draw_pixmap,draw_context, (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y, (unsigned int) draw_info->rectangle_info.width, (unsigned int) draw_info->rectangle_info.height); break; } case CircleElement: case EllipseElement: { (void) XDrawArc(display,draw_pixmap,draw_context, (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y, (unsigned int) draw_info->rectangle_info.width, (unsigned int) draw_info->rectangle_info.height,0,360*64); break; } case FillCircleElement: case FillEllipseElement: { (void) XFillArc(display,draw_pixmap,draw_context, (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y, (unsigned int) draw_info->rectangle_info.width, (unsigned int) draw_info->rectangle_info.height,0,360*64); break; } case PolygonElement: { XPoint *coordinate_info; coordinate_info=draw_info->coordinate_info; (void) XDrawLines(display,draw_pixmap,draw_context,coordinate_info, (int) draw_info->number_coordinates,CoordModeOrigin); (void) XDrawLine(display,draw_pixmap,draw_context, coordinate_info[draw_info->number_coordinates-1].x, coordinate_info[draw_info->number_coordinates-1].y, coordinate_info[0].x,coordinate_info[0].y); break; } case FillPolygonElement: { (void) XFillPolygon(display,draw_pixmap,draw_context, draw_info->coordinate_info,(int) draw_info->number_coordinates,Complex, CoordModeOrigin); break; } } (void) XFreeGC(display,draw_context); /* Initialize X image. */ draw_ximage=XGetImage(display,draw_pixmap,0,0,draw_info->width, draw_info->height,AllPlanes,ZPixmap); if (draw_ximage == (XImage *) NULL) return(MagickFalse); (void) XFreePixmap(display,draw_pixmap); /* Initialize draw image. */ draw_image=AllocateImage((ImageInfo *) NULL); if (draw_image == (Image *) NULL) return(MagickFalse); draw_image->columns=draw_info->width; draw_image->rows=draw_info->height; /* Transfer drawn X image to image. */ width=(unsigned int) image->columns; height=(unsigned int) image->rows; x=0; y=0; (void) XParseGeometry(draw_info->geometry,&x,&y,&width,&height); draw_image->background_color=GetOnePixel(image,x,y); if (SetImageStorageClass(draw_image,DirectClass) == MagickFalse) return(MagickFalse); draw_image->matte=MagickTrue; for (y=0; y < (int) draw_image->rows; y++) { q=SetImagePixels(draw_image,0,y,draw_image->columns,1); if (q == (PixelPacket *) NULL) break; for (x=0; x < (int) draw_image->columns; x++) { if (XGetPixel(draw_ximage,x,y) == 0) { /* Set this pixel to the background color. */ *q=draw_image->background_color; q->opacity=(Quantum) (draw_info->stencil == OpaqueStencil ? TransparentOpacity : OpaqueOpacity); } else { /* Set this pixel to the pen color. */ q->red=ScaleShortToQuantum(pixel->pen_color.red); q->green=ScaleShortToQuantum(pixel->pen_color.green); q->blue=ScaleShortToQuantum(pixel->pen_color.blue); q->opacity=(Quantum) (draw_info->stencil == OpaqueStencil ? OpaqueOpacity : TransparentOpacity); } q++; } if (SyncImagePixels(draw_image) == MagickFalse) break; } XDestroyImage(draw_ximage); /* Determine draw geometry. */ (void) XParseGeometry(draw_info->geometry,&x,&y,&width,&height); if ((width != (unsigned int) draw_image->columns) || (height != (unsigned int) draw_image->rows)) { char image_geometry[MaxTextExtent]; /* Scale image. */ (void) FormatMagickString(image_geometry,MaxTextExtent,"%ux%u", width,height); (void) TransformImage(&draw_image,(char *) NULL,image_geometry); } if (draw_info->degrees != 0.0) { Image *rotate_image; int rotations; MagickRealType normalized_degrees; /* Rotate image. */ rotate_image=RotateImage(draw_image,draw_info->degrees,&image->exception); if (rotate_image == (Image *) NULL) return(MagickFalse); draw_image=DestroyImage(draw_image); draw_image=rotate_image; /* Annotation is relative to the degree of rotation. */ normalized_degrees=draw_info->degrees; while (normalized_degrees < -45.0) normalized_degrees+=360.0; for (rotations=0; normalized_degrees > 45.0; rotations++) normalized_degrees-=90.0; switch (rotations % 4) { default: case 0: break; case 1: { /* Rotate 90 degrees. */ x=x-(int) draw_image->columns/2; y=y+(int) draw_image->columns/2; break; } case 2: { /* Rotate 180 degrees. */ x=x-(int) draw_image->columns; break; } case 3: { /* Rotate 270 degrees. */ x=x-(int) draw_image->columns/2; y=y-(int) (draw_image->rows-(draw_image->columns/2)); break; } } } /* Composite text onto the image. */ for (y=0; y < (int) draw_image->rows; y++) { q=GetImagePixels(draw_image,0,y,draw_image->columns,1); if (q == (PixelPacket *) NULL) break; for (x=0; x < (int) draw_image->columns; x++) { if (q->opacity != (Quantum) TransparentOpacity) q->opacity=OpaqueOpacity; q++; } if (SyncImagePixels(draw_image) == MagickFalse) break; } (void) XParseGeometry(draw_info->geometry,&x,&y,&width,&height); if (draw_info->stencil == TransparentStencil) (void) CompositeImage(image,CopyOpacityCompositeOp,draw_image,x,y); else { matte=image->matte; (void) CompositeImage(image,OverCompositeOp,draw_image,x,y); image->matte=matte; } draw_image=DestroyImage(draw_image); return(MagickTrue); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X E r r o r % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XError() ignores BadWindow errors for XQueryTree and XGetWindowAttributes, % and ignores BadDrawable errors for XGetGeometry, and ignores BadValue errors % for XQueryColor. It returns MagickFalse in those cases. Otherwise it returns % True. % % The format of the XError function is: % % XError(display,error) % % A description of each parameter follows: % % o display: Specifies a pointer to the Display structure; returned from % XOpenDisplay. % % o error: Specifies the error event. % */ #if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif MagickExport int XError(Display *display,XErrorEvent *error) { (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(display != (Display *) NULL); assert(error != (XErrorEvent *) NULL); xerror_alert=MagickTrue; switch (error->request_code) { case X_GetGeometry: { if ((int) error->error_code == BadDrawable) return(MagickFalse); break; } case X_GetWindowAttributes: case X_QueryTree: { if ((int) error->error_code == BadWindow) return(MagickFalse); break; } case X_QueryColors: { if ((int) error->error_code == BadValue) return(MagickFalse); break; } } return(MagickTrue); } #if defined(__cplusplus) || defined(c_plusplus) } #endif /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X F r e e R e s o u r c e s % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XFreeResources() frees X11 resources. % % The format of the XFreeResources method is: % % void XFreeResources(Display *display,XVisualInfo *visual_info, % XStandardColormap *map_info,XPixelInfo *pixel,XFontStruct *font_info, % XResourceInfo *resource_info,XWindowInfo *window_info) % resource_info,window_info) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o visual_info: Specifies a pointer to a X11 XVisualInfo structure; % returned from XGetVisualInfo. % % o map_info: If map_type is specified, this structure is initialized % with info from the Standard Colormap. % % o pixel: Specifies a pointer to a XPixelInfo structure. % % o font_info: Specifies a pointer to a XFontStruct structure. % % o resource_info: Specifies a pointer to a X11 XResourceInfo structure. % % o window_info: Specifies a pointer to a X11 XWindowInfo structure. % */ MagickExport void XFreeResources(Display *display,XVisualInfo *visual_info, XStandardColormap *map_info,XPixelInfo *pixel,XFontStruct *font_info, XResourceInfo *resource_info,XWindowInfo *window_info) { (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(display != (Display *) NULL); assert(resource_info != (XResourceInfo *) NULL); if (window_info != (XWindowInfo *) NULL) { /* Free X image. */ if (window_info->ximage != (XImage *) NULL) XDestroyImage(window_info->ximage); if (window_info->id != (Window) NULL) { /* Free destroy window and free cursors. */ if (window_info->id != XRootWindow(display,visual_info->screen)) (void) XDestroyWindow(display,window_info->id); if (window_info->annotate_context != (GC) NULL) (void) XFreeGC(display,window_info->annotate_context); if (window_info->highlight_context != (GC) NULL) (void) XFreeGC(display,window_info->highlight_context); if (window_info->widget_context != (GC) NULL) (void) XFreeGC(display,window_info->widget_context); if (window_info->cursor != (Cursor) NULL) (void) XFreeCursor(display,window_info->cursor); window_info->cursor=(Cursor) NULL; if (window_info->busy_cursor != (Cursor) NULL) (void) XFreeCursor(display,window_info->busy_cursor); window_info->busy_cursor=(Cursor) NULL; } } /* Free font. */ if (font_info != (XFontStruct *) NULL) (void) XFreeFont(display,font_info); if (map_info != (XStandardColormap *) NULL) { /* Free X Standard Colormap. */ if (resource_info->map_type == (char *) NULL) (void) XFreeStandardColormap(display,visual_info,map_info,pixel); (void) XFree((void *) map_info); } /* Free X visual info. */ if (visual_info != (XVisualInfo *) NULL) (void) XFree((void *) visual_info); if (resource_info->close_server != MagickFalse) (void) XCloseDisplay(display); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X F r e e S t a n d a r d C o l o r m a p % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XFreeStandardColormap() frees an X11 colormap. % % The format of the XFreeStandardColormap method is: % % void XFreeStandardColormap(Display *display, % const XVisualInfo *visual_info,XStandardColormap *map_info, % XPixelInfo *pixel) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o visual_info: Specifies a pointer to a X11 XVisualInfo structure; % returned from XGetVisualInfo. % % o map_info: If map_type is specified, this structure is initialized % with info from the Standard Colormap. % % o pixel: Specifies a pointer to a XPixelInfo structure. % */ MagickExport void XFreeStandardColormap(Display *display, const XVisualInfo *visual_info,XStandardColormap *map_info,XPixelInfo *pixel) { /* Free colormap. */ (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(display != (Display *) NULL); assert(visual_info != (XVisualInfo *) NULL); assert(map_info != (XStandardColormap *) NULL); (void) XFlush(display); if (map_info->colormap != (Colormap) NULL) { if (map_info->colormap != XDefaultColormap(display,visual_info->screen)) (void) XFreeColormap(display,map_info->colormap); else if (pixel != (XPixelInfo *) NULL) if ((visual_info->klass != TrueColor) && (visual_info->klass != DirectColor)) (void) XFreeColors(display,map_info->colormap,pixel->pixels, (int) pixel->colors,0); } map_info->colormap=(Colormap) NULL; if (pixel != (XPixelInfo *) NULL) { if (pixel->pixels != (unsigned long *) NULL) pixel->pixels=(unsigned long *) RelinquishMagickMemory(pixel->pixels); pixel->pixels=(unsigned long *) NULL; } } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X G e t A n n o t a t e I n f o % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XGetAnnotateInfo() initializes the AnnotateInfo structure. % % The format of the XGetAnnotateInfo method is: % % void XGetAnnotateInfo(XAnnotateInfo *annotate_info) % % A description of each parameter follows: % % o annotate_info: Specifies a pointer to a XAnnotateInfo structure. % */ MagickExport void XGetAnnotateInfo(XAnnotateInfo *annotate_info) { /* Initialize annotate structure. */ (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(annotate_info != (XAnnotateInfo *) NULL); annotate_info->x=0; annotate_info->y=0; annotate_info->width=0; annotate_info->height=0; annotate_info->stencil=ForegroundStencil; annotate_info->degrees=0.0; annotate_info->font_info=(XFontStruct *) NULL; annotate_info->text=(char *) NULL; *annotate_info->geometry='\0'; annotate_info->previous=(XAnnotateInfo *) NULL; annotate_info->next=(XAnnotateInfo *) NULL; (void) XSupportsLocale(); (void) XSetLocaleModifiers(""); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X G e t M a p I n f o % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XGetMapInfo() initializes the XStandardColormap structure. % % The format of the XStandardColormap method is: % % void XGetMapInfo(const XVisualInfo *visual_info,const Colormap colormap, % XStandardColormap *map_info) % % A description of each parameter follows: % % o colormap: Specifies the ID of the X server colormap. % % o visual_info: Specifies a pointer to a X11 XVisualInfo structure; % returned from XGetVisualInfo. % % o map_info: Specifies a pointer to a X11 XStandardColormap structure. % */ MagickExport void XGetMapInfo(const XVisualInfo *visual_info, const Colormap colormap,XStandardColormap *map_info) { /* Initialize map info. */ (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(visual_info != (XVisualInfo *) NULL); assert(map_info != (XStandardColormap *) NULL); map_info->colormap=colormap; map_info->red_max=visual_info->red_mask; map_info->red_mult=(unsigned long) (map_info->red_max != 0 ? 1 : 0); if (map_info->red_max != 0) while ((map_info->red_max & 0x01) == 0) { map_info->red_max>>=1; map_info->red_mult<<=1; } map_info->green_max=visual_info->green_mask; map_info->green_mult=(unsigned long) (map_info->green_max != 0 ? 1 : 0); if (map_info->green_max != 0) while ((map_info->green_max & 0x01) == 0) { map_info->green_max>>=1; map_info->green_mult<<=1; } map_info->blue_max=visual_info->blue_mask; map_info->blue_mult=(unsigned long) (map_info->blue_max != 0 ? 1 : 0); if (map_info->blue_max != 0) while ((map_info->blue_max & 0x01) == 0) { map_info->blue_max>>=1; map_info->blue_mult<<=1; } map_info->base_pixel=0; } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X G e t P i x e l I n f o % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XGetPixelPacket() initializes the PixelPacket structure. % % The format of the XGetPixelPacket method is: % % void XGetPixelPacket(Display *display,const XVisualInfo *visual_info, % const XStandardColormap *map_info,const XResourceInfo *resource_info, % Image *image,XPixelInfo *pixel) % pixel) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o visual_info: Specifies a pointer to a X11 XVisualInfo structure; % returned from XGetVisualInfo. % % o map_info: If map_type is specified, this structure is initialized % with info from the Standard Colormap. % % o resource_info: Specifies a pointer to a X11 XResourceInfo structure. % % o image: The image. % % o pixel: Specifies a pointer to a XPixelInfo structure. % */ MagickExport void XGetPixelPacket(Display *display, const XVisualInfo *visual_info,const XStandardColormap *map_info, const XResourceInfo *resource_info,Image *image,XPixelInfo *pixel) { static const char *PenColors[MaxNumberPens]= { "#000000000000", /* black */ "#00000000ffff", /* blue */ "#0000ffffffff", /* cyan */ "#0000ffff0000", /* green */ "#bdbdbdbdbdbd", /* gray */ "#ffff00000000", /* red */ "#ffff0000ffff", /* magenta */ "#ffffffff0000", /* yellow */ "#ffffffffffff", /* white */ "#bdbdbdbdbdbd", /* gray */ "#bdbdbdbdbdbd" /* gray */ }; Colormap colormap; register long i; Status status; unsigned int packets; /* Initialize pixel info. */ (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(display != (Display *) NULL); assert(visual_info != (XVisualInfo *) NULL); assert(map_info != (XStandardColormap *) NULL); assert(resource_info != (XResourceInfo *) NULL); assert(pixel != (XPixelInfo *) NULL); pixel->colors=0; if (image != (Image *) NULL) if (image->storage_class == PseudoClass) pixel->colors=image->colors; packets=(unsigned int) MagickMax((int) pixel->colors,visual_info->colormap_size)+MaxNumberPens; if (pixel->pixels != (unsigned long *) NULL) pixel->pixels=(unsigned long *) RelinquishMagickMemory(pixel->pixels); pixel->pixels=(unsigned long *) AcquireQuantumMemory(packets, sizeof(pixel->pixels)); if (pixel->pixels == (unsigned long *) NULL) ThrowXWindowFatalException(ResourceLimitFatalError,"UnableToGetPixelInfo", image->filename); /* Set foreground color. */ colormap=map_info->colormap; (void) XParseColor(display,colormap,(char *) ForegroundColor, &pixel->foreground_color); status=XParseColor(display,colormap,resource_info->foreground_color, &pixel->foreground_color); if (status == False) ThrowXWindowFatalException(XServerError,"ColorIsNotKnownToServer", resource_info->foreground_color); pixel->foreground_color.pixel= XStandardPixel(map_info,&pixel->foreground_color); pixel->foreground_color.flags=(char) (DoRed | DoGreen | DoBlue); /* Set background color. */ (void) XParseColor(display,colormap,"#d6d6d6d6d6d6",&pixel->background_color); status=XParseColor(display,colormap,resource_info->background_color, &pixel->background_color); if (status == False) ThrowXWindowFatalException(XServerError,"ColorIsNotKnownToServer", resource_info->background_color); pixel->background_color.pixel= XStandardPixel(map_info,&pixel->background_color); pixel->background_color.flags=(char) (DoRed | DoGreen | DoBlue); /* Set border color. */ (void) XParseColor(display,colormap,(char *) BorderColor, &pixel->border_color); status=XParseColor(display,colormap,resource_info->border_color, &pixel->border_color); if (status == False) ThrowXWindowFatalException(XServerError,"ColorIsNotKnownToServer", resource_info->border_color); pixel->border_color.pixel=XStandardPixel(map_info,&pixel->border_color); pixel->border_color.flags=(char) (DoRed | DoGreen | DoBlue); /* Set matte color. */ pixel->matte_color=pixel->background_color; if (resource_info->matte_color != (char *) NULL) { /* Matte color is specified as a X resource or command line argument. */ status=XParseColor(display,colormap,resource_info->matte_color, &pixel->matte_color); if (status == False) ThrowXWindowFatalException(XServerError,"ColorIsNotKnownToServer", resource_info->matte_color); pixel->matte_color.pixel=XStandardPixel(map_info,&pixel->matte_color); pixel->matte_color.flags=(char) (DoRed | DoGreen | DoBlue); } /* Set highlight color. */ pixel->highlight_color.red=(unsigned short) (( pixel->matte_color.red*ScaleQuantumToShort(HighlightModulate))/65535L+ (ScaleQuantumToShort((Quantum) (QuantumRange-HighlightModulate)))); pixel->highlight_color.green=(unsigned short) (( pixel->matte_color.green*ScaleQuantumToShort(HighlightModulate))/65535L+ (ScaleQuantumToShort((Quantum) (QuantumRange-HighlightModulate)))); pixel->highlight_color.blue=(unsigned short) (( pixel->matte_color.blue*ScaleQuantumToShort(HighlightModulate))/65535L+ (ScaleQuantumToShort((Quantum) (QuantumRange-HighlightModulate)))); pixel->highlight_color.pixel= XStandardPixel(map_info,&pixel->highlight_color); pixel->highlight_color.flags=(char) (DoRed | DoGreen | DoBlue); /* Set shadow color. */ pixel->shadow_color.red=(unsigned short) (((MagickRealType) pixel->matte_color.red*ScaleQuantumToShort(ShadowModulate))/65535L); pixel->shadow_color.green=(unsigned short) (((MagickRealType) pixel->matte_color.green*ScaleQuantumToShort(ShadowModulate))/65535L); pixel->shadow_color.blue=(unsigned short) (((MagickRealType) pixel->matte_color.blue*ScaleQuantumToShort(ShadowModulate))/65535L); pixel->shadow_color.pixel=XStandardPixel(map_info,&pixel->shadow_color); pixel->shadow_color.flags=(char) (DoRed | DoGreen | DoBlue); /* Set depth color. */ pixel->depth_color.red=(unsigned short) (((MagickRealType) pixel->matte_color.red*ScaleQuantumToShort(DepthModulate))/65535L); pixel->depth_color.green=(unsigned short) (((MagickRealType) pixel->matte_color.green*ScaleQuantumToShort(DepthModulate))/65535L); pixel->depth_color.blue=(unsigned short) (((MagickRealType) pixel->matte_color.blue*ScaleQuantumToShort(DepthModulate))/65535L); pixel->depth_color.pixel=XStandardPixel(map_info,&pixel->depth_color); pixel->depth_color.flags=(char) (DoRed | DoGreen | DoBlue); /* Set trough color. */ pixel->trough_color.red=(unsigned short) (((MagickRealType) pixel->matte_color.red*ScaleQuantumToShort(TroughModulate))/65535L); pixel->trough_color.green=(unsigned short) (((MagickRealType) pixel->matte_color.green*ScaleQuantumToShort(TroughModulate))/65535L); pixel->trough_color.blue=(unsigned short) (((MagickRealType) pixel->matte_color.blue*ScaleQuantumToShort(TroughModulate))/65535L); pixel->trough_color.pixel=XStandardPixel(map_info,&pixel->trough_color); pixel->trough_color.flags=(char) (DoRed | DoGreen | DoBlue); /* Set pen color. */ for (i=0; i < MaxNumberPens; i++) { (void) XParseColor(display,colormap,(char *) PenColors[i], &pixel->pen_colors[i]); status=XParseColor(display,colormap,resource_info->pen_colors[i], &pixel->pen_colors[i]); if (status == False) ThrowXWindowFatalException(XServerError,"ColorIsNotKnownToServer", resource_info->pen_colors[i]); pixel->pen_colors[i].pixel=XStandardPixel(map_info,&pixel->pen_colors[i]); pixel->pen_colors[i].flags=(char) (DoRed | DoGreen | DoBlue); } pixel->box_color=pixel->background_color; pixel->pen_color=pixel->foreground_color; pixel->box_index=0; pixel->pen_index=1; if (image != (Image *) NULL) { if ((resource_info->gamma_correct != MagickFalse) && (image->gamma != 0.0)) { GeometryInfo geometry_info; MagickStatusType flags; /* Initialize map relative to display and image gamma. */ flags=ParseGeometry(resource_info->display_gamma,&geometry_info); red_gamma=geometry_info.rho; green_gamma=geometry_info.sigma; if ((flags & SigmaValue) == 0) green_gamma=red_gamma; blue_gamma=geometry_info.xi; if ((flags & XiValue) == 0) blue_gamma=red_gamma; red_gamma*=image->gamma; green_gamma*=image->gamma; blue_gamma*=image->gamma; } if (image->storage_class == PseudoClass) { /* Initialize pixel array for images of type PseudoClass. */ for (i=0; i < (long) image->colors; i++) pixel->pixels[i]= XGammaPixel(map_info,image->colormap+i); for (i=0; i < MaxNumberPens; i++) pixel->pixels[image->colors+i]=pixel->pen_colors[i].pixel; pixel->colors+=MaxNumberPens; } } } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X G e t R e s o u r c e C l a s s % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XGetResourceClass() queries the X server for the specified resource name or % class. If the resource name or class is not defined in the database, the % supplied default value is returned. % % The format of the XGetResourceClass method is: % % char *XGetResourceClass(XrmDatabase database,const char *client_name, % const char *keyword,char *resource_default) % % A description of each parameter follows: % % o database: Specifies a resource database; returned from % XrmGetStringDatabase. % % o client_name: Specifies the application name used to retrieve resource % info from the X server database. % % o keyword: Specifies the keyword of the value being retrieved. % % o resource_default: Specifies the default value to return if the query % fails to find the specified keyword/class. % */ MagickExport char *XGetResourceClass(XrmDatabase database, const char *client_name,const char *keyword,char *resource_default) { char resource_class[MaxTextExtent], resource_name[MaxTextExtent]; static char *resource_type; Status status; XrmValue resource_value; if (database == (XrmDatabase) NULL) return(resource_default); *resource_name='\0'; *resource_class='\0'; if (keyword != (char *) NULL) { int c, k; /* Initialize resource keyword and class. */ (void) FormatMagickString(resource_name,MaxTextExtent,"%s.%s",client_name, keyword); c=(int) (*client_name); if ((c >= XK_a) && (c <= XK_z)) c-=(XK_a-XK_A); else if ((c >= XK_agrave) && (c <= XK_odiaeresis)) c-=(XK_agrave-XK_Agrave); else if ((c >= XK_oslash) && (c <= XK_thorn)) c-=(XK_oslash-XK_Ooblique); k=(int) (*keyword); if ((k >= XK_a) && (k <= XK_z)) k-=(XK_a-XK_A); else if ((k >= XK_agrave) && (k <= XK_odiaeresis)) k-=(XK_agrave-XK_Agrave); else if ((k >= XK_oslash) && (k <= XK_thorn)) k-=(XK_oslash-XK_Ooblique); (void) FormatMagickString(resource_class,MaxTextExtent,"%c%s.%c%s",c, client_name+1,k,keyword+1); } status=XrmGetResource(database,resource_name,resource_class,&resource_type, &resource_value); if (status == False) return(resource_default); return(resource_value.addr); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X G e t R e s o u r c e D a t a b a s e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XGetResourceDatabase() creates a new resource database and initializes it. % % The format of the XGetResourceDatabase method is: % % XrmDatabase XGetResourceDatabase(Display *display, % const char *client_name) % % A description of each parameter follows: % % o database: XGetResourceDatabase() returns the database after it is % initialized. % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o client_name: Specifies the application name used to retrieve resource % info from the X server database. % */ MagickExport XrmDatabase XGetResourceDatabase(Display *display, const char *client_name) { char filename[MaxTextExtent]; int c; register const char *p; XrmDatabase resource_database, server_database; if (display == (Display *) NULL) return((XrmDatabase) NULL); assert(client_name != (char *) NULL); /* Initialize resource database. */ XrmInitialize(); (void) XGetDefault(display,(char *) client_name,"dummy"); resource_database=XrmGetDatabase(display); /* Combine application database. */ if (client_name != (char *) NULL) { /* Get basename of client. */ p=client_name+(strlen(client_name)-1); while ((p > client_name) && (*p != '/')) p--; if (*p == '/') client_name=p+1; } c=(int) (*client_name); if ((c >= XK_a) && (c <= XK_z)) c-=(XK_a-XK_A); else if ((c >= XK_agrave) && (c <= XK_odiaeresis)) c-=(XK_agrave-XK_Agrave); else if ((c >= XK_oslash) && (c <= XK_thorn)) c-=(XK_oslash-XK_Ooblique); #if defined(ApplicationDefaults) (void) FormatMagickString(filename,MaxTextExtent,"%s%c%s",ApplicationDefaults, c,client_name+1); (void) XrmCombineFileDatabase(filename,&resource_database,MagickFalse); #endif if (XResourceManagerString(display) != (char *) NULL) { /* Combine server database. */ server_database=XrmGetStringDatabase(XResourceManagerString(display)); XrmCombineDatabase(server_database,&resource_database,MagickFalse); } /* Merge user preferences database. */ #if defined(PreferencesDefaults) (void) FormatMagickString(filename,MaxTextExtent,"%s%src",PreferencesDefaults, client_name); ExpandFilename(filename); (void) XrmCombineFileDatabase(filename,&resource_database,MagickFalse); #endif return(resource_database); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X G e t R e s o u r c e I n f o % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XGetResourceInfo() initializes the ResourceInfo structure. % % The format of the XGetResourceInfo method is: % % void XGetResourceInfo(XrmDatabase database,const char *client_name, % XResourceInfo *resource_info) % % A description of each parameter follows: % % o database: Specifies a resource database; returned from % XrmGetStringDatabase. % % o client_name: Specifies the application name used to retrieve % resource info from the X server database. % % o resource_info: Specifies a pointer to a X11 XResourceInfo structure. % */ MagickExport void XGetResourceInfo(XrmDatabase database,const char *client_name, XResourceInfo *resource_info) { char *resource_value; /* Initialize resource info fields. */ (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(resource_info != (XResourceInfo *) NULL); (void) ResetMagickMemory(resource_info,0,sizeof(*resource_info)); resource_info->resource_database=database; resource_info->image_info=AcquireImageInfo(); (void) SetImageInfoProgressMonitor(resource_info->image_info, XMagickProgressMonitor,(void *) NULL); resource_info->quantize_info=CloneQuantizeInfo((QuantizeInfo *) NULL); resource_info->close_server=MagickTrue; resource_info->client_name=AcquireString(client_name); resource_value=XGetResourceClass(database,client_name,"backdrop", (char *) "False"); resource_info->backdrop=IsMagickTrue(resource_value); resource_info->background_color=XGetResourceInstance(database,client_name, "background",(char *) "#d6d6d6d6d6d6"); resource_info->border_color=XGetResourceInstance(database,client_name, "borderColor",BorderColor); resource_value=XGetResourceClass(database,client_name,"borderWidth", (char *) "2"); resource_info->border_width=(unsigned int) atoi(resource_value); resource_value=XGetResourceClass(database,client_name,"colormap", (char *) "shared"); resource_info->colormap=UndefinedColormap; if (LocaleCompare("private",resource_value) == 0) resource_info->colormap=PrivateColormap; if (LocaleCompare("shared",resource_value) == 0) resource_info->colormap=SharedColormap; if (resource_info->colormap == UndefinedColormap) ThrowXWindowFatalException(OptionError,"UnrecognizedColormapType", resource_value); resource_value=XGetResourceClass(database,client_name, "colorRecovery",(char *) "False"); resource_info->color_recovery=IsMagickTrue(resource_value); resource_value=XGetResourceClass(database,client_name,"confirmExit", (char *) "False"); resource_info->confirm_exit=IsMagickTrue(resource_value); resource_value=XGetResourceClass(database,client_name,"confirmEdit", (char *) "False"); resource_info->confirm_edit=IsMagickTrue(resource_value); resource_value=XGetResourceClass(database,client_name,"delay",(char *) "1"); resource_info->delay=(unsigned int) atoi(resource_value); resource_info->display_gamma=XGetResourceClass(database,client_name, "displayGamma",(char *) "2.2"); resource_value=XGetResourceClass(database,client_name,"displayWarnings", (char *) "True"); resource_info->display_warnings=IsMagickTrue(resource_value); resource_info->font=XGetResourceClass(database,client_name,"font", (char *) NULL); resource_info->font=XGetResourceClass(database,client_name,"fontList", resource_info->font); resource_info->font_name[0]=XGetResourceClass(database,client_name,"font1", (char *) "fixed"); resource_info->font_name[1]=XGetResourceClass(database,client_name,"font2", (char *) "variable"); resource_info->font_name[2]=XGetResourceClass(database,client_name,"font3", (char *) "5x8"); resource_info->font_name[3]=XGetResourceClass(database,client_name,"font4", (char *) "6x10"); resource_info->font_name[4]=XGetResourceClass(database,client_name,"font5", (char *) "7x13bold"); resource_info->font_name[5]=XGetResourceClass(database,client_name,"font6", (char *) "8x13bold"); resource_info->font_name[6]=XGetResourceClass(database,client_name,"font7", (char *) "9x15bold"); resource_info->font_name[7]=XGetResourceClass(database,client_name,"font8", (char *) "10x20"); resource_info->font_name[8]=XGetResourceClass(database,client_name,"font9", (char *) "12x24"); resource_info->font_name[9]=XGetResourceClass(database,client_name,"font0", (char *) "fixed"); resource_info->font_name[10]=XGetResourceClass(database,client_name,"font0", (char *) "fixed"); resource_info->foreground_color=XGetResourceInstance(database,client_name, "foreground",ForegroundColor); resource_value=XGetResourceClass(database,client_name,"gammaCorrect", (char *) "True"); resource_info->gamma_correct=IsMagickTrue(resource_value); resource_info->image_geometry=XGetResourceClass(database,client_name, "geometry",(char *) NULL); resource_value=XGetResourceClass(database,client_name,"gravity", (char *) "Center"); resource_info->gravity=(GravityType) ParseMagickOption(MagickGravityOptions, MagickFalse,resource_value); (void) getcwd(resource_info->home_directory,MaxTextExtent); resource_info->icon_geometry=XGetResourceClass(database,client_name, "iconGeometry",(char *) NULL); resource_value=XGetResourceClass(database,client_name,"iconic", (char *) "False"); resource_info->iconic=IsMagickTrue(resource_value); resource_value=XGetResourceClass(database,client_name,"immutable", LocaleCompare(client_name,"PerlMagick") == 0 ? (char *) "True" : (char *) "False"); resource_info->immutable=IsMagickTrue(resource_value); resource_value=XGetResourceClass(database,client_name,"magnify",(char *) "3"); resource_info->magnify=(unsigned int) atoi(resource_value); resource_info->map_type=XGetResourceClass(database,client_name,"map", (char *) NULL); resource_info->matte_color=XGetResourceInstance(database,client_name, "mattecolor",(char *) NULL); resource_info->name=XGetResourceClass(database,client_name,"name", (char *) NULL); resource_info->pen_colors[0]=XGetResourceClass(database,client_name,"pen1", (char *) "black"); resource_info->pen_colors[1]=XGetResourceClass(database,client_name,"pen2", (char *) "blue"); resource_info->pen_colors[2]=XGetResourceClass(database,client_name,"pen3", (char *) "cyan"); resource_info->pen_colors[3]=XGetResourceClass(database,client_name,"pen4", (char *) "green"); resource_info->pen_colors[4]=XGetResourceClass(database,client_name,"pen5", (char *) "gray"); resource_info->pen_colors[5]=XGetResourceClass(database,client_name,"pen6", (char *) "red"); resource_info->pen_colors[6]=XGetResourceClass(database,client_name,"pen7", (char *) "magenta"); resource_info->pen_colors[7]=XGetResourceClass(database,client_name,"pen8", (char *) "yellow"); resource_info->pen_colors[8]=XGetResourceClass(database,client_name,"pen9", (char *) "white"); resource_info->pen_colors[9]=XGetResourceClass(database,client_name,"pen0", (char *) "gray"); resource_info->pen_colors[10]=XGetResourceClass(database,client_name,"pen0", (char *) "gray"); resource_value=XGetResourceClass(database,client_name,"pause",(char *) "0"); resource_info->pause=(unsigned int) atoi(resource_value); resource_value=XGetResourceClass(database,client_name,"quantum",(char *) "1"); resource_info->quantum=atoi(resource_value); resource_info->text_font=XGetResourceClass(database,client_name,(char *) "font",(char *) "fixed"); resource_info->text_font=XGetResourceClass(database,client_name, "textFontList",resource_info->text_font); resource_info->title=XGetResourceClass(database,client_name,"title", (char *) NULL); resource_value=XGetResourceClass(database,client_name,"undoCache", (char *) "16"); resource_info->undo_cache=(unsigned int) atol(resource_value); resource_value=XGetResourceClass(database,client_name,"update", (char *) "False"); resource_info->update=IsMagickTrue(resource_value); resource_value=XGetResourceClass(database,client_name,"usePixmap", (char *) "True"); resource_info->use_pixmap=IsMagickTrue(resource_value); resource_value=XGetResourceClass(database,client_name,"sharedMemory", (char *) "True"); resource_info->use_shared_memory=IsMagickTrue(resource_value); resource_info->visual_type=XGetResourceClass(database,client_name,"visual", (char *) NULL); resource_info->window_group=XGetResourceClass(database,client_name, "windowGroup",(char *) NULL); resource_info->window_id=XGetResourceClass(database,client_name,"window", (char *) NULL); resource_info->write_filename=XGetResourceClass(database,client_name, "writeFilename",(char *) NULL); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X G e t R e s o u r c e I n s t a n c e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XGetResourceInstance() queries the X server for the specified resource name. % If the resource name is not defined in the database, the supplied default % value is returned. % % The format of the XGetResourceInstance method is: % % char *XGetResourceInstance(XrmDatabase database,const char *client_name, % const char *keyword,const char *resource_default) % % A description of each parameter follows: % % o database: Specifies a resource database; returned from % XrmGetStringDatabase. % % o client_name: Specifies the application name used to retrieve % resource info from the X server database. % % o keyword: Specifies the keyword of the value being retrieved. % % o resource_default: Specifies the default value to return if the query % fails to find the specified keyword/class. % */ MagickExport char *XGetResourceInstance(XrmDatabase database, const char *client_name,const char *keyword,const char *resource_default) { char *resource_type, resource_name[MaxTextExtent]; Status status; XrmValue resource_value; if (database == (XrmDatabase) NULL) return((char *) resource_default); *resource_name='\0'; if (keyword != (char *) NULL) (void) FormatMagickString(resource_name,MaxTextExtent,"%s.%s",client_name, keyword); status=XrmGetResource(database,resource_name,"ImageMagick",&resource_type, &resource_value); if (status == False) return((char *) resource_default); return(resource_value.addr); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X G e t S c r e e n D e n s i t y % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XGetScreenDensity() returns the density of the X server screen in % dots-per-inch. % % The format of the XGetScreenDensity method is: % % char *XGetScreenDensity(Display *display) % % A description of each parameter follows: % % o density: XGetScreenDensity() returns the density of the X screen in % dots-per-inch. % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % */ MagickExport char *XGetScreenDensity(Display *display) { char density[MaxTextExtent]; double x_density, y_density; /* Set density as determined by screen size. */ x_density=((((double) DisplayWidth(display,XDefaultScreen(display)))*25.4)/ ((double) DisplayWidthMM(display,XDefaultScreen(display)))); y_density=((((double) DisplayHeight(display,XDefaultScreen(display)))*25.4)/ ((double) DisplayHeightMM(display,XDefaultScreen(display)))); (void) FormatMagickString(density,MaxTextExtent,"%gx%g",x_density,y_density); return(GetPageGeometry(density)); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + X G e t S u b w i n d o w % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XGetSubwindow() returns the subwindow of a window chosen the user with the % pointer and a button press. % % The format of the XGetSubwindow method is: % % Window XGetSubwindow(Display *display,Window window,int x,int y) % % A description of each parameter follows: % % o subwindow: XGetSubwindow() returns NULL if no subwindow is found % otherwise the subwindow is returned. % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o window: Specifies a pointer to a Window. % % o x: the x coordinate of the pointer relative to the origin of the % window. % % o y: the y coordinate of the pointer relative to the origin of the % window. % % */ static Window XGetSubwindow(Display *display,Window window,int x,int y) { int x_offset, y_offset; Status status; Window source_window, target_window; assert(display != (Display *) NULL); source_window=XRootWindow(display,XDefaultScreen(display)); if (window == (Window) NULL) return(source_window); target_window=window; for ( ; ; ) { status=XTranslateCoordinates(display,source_window,window,x,y, &x_offset,&y_offset,&target_window); if (status != True) break; if (target_window == (Window) NULL) break; source_window=window; window=target_window; x=x_offset; y=y_offset; } if (target_window == (Window) NULL) target_window=window; return(target_window); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X G e t W i n d o w C o l o r % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XGetWindowColor() returns the color of a pixel interactively chosen from the % X server. % % The format of the XGetWindowColor method is: % % MagickBooleanType XGetWindowColor(Display *display,XWindows *windows, % char *name) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o windows: Specifies a pointer to a XWindows structure. % % o name: The name of of the color if found in the X Color Database is % returned in this character string. % */ MagickExport MagickBooleanType XGetWindowColor(Display *display, XWindows *windows,char *name) { int x, y; PixelPacket pixel; RectangleInfo crop_info; Status status; Window child, client_window, root_window, target_window; XColor color; XImage *ximage; XWindowAttributes window_attributes; /* Choose a pixel from the X server. */ assert(display != (Display *) NULL); assert(name != (char *) NULL); (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name); *name='\0'; target_window=XSelectWindow(display,&crop_info); if (target_window == (Window) NULL) return(MagickFalse); root_window=XRootWindow(display,XDefaultScreen(display)); client_window=target_window; if (target_window != root_window) { unsigned int d; /* Get client window. */ status=XGetGeometry(display,target_window,&root_window,&x,&x,&d,&d,&d,&d); if (status != False) { client_window=XClientWindow(display,target_window); target_window=client_window; } } /* Verify window is viewable. */ status=XGetWindowAttributes(display,target_window,&window_attributes); if ((status == False) || (window_attributes.map_state != IsViewable)) return(MagickFalse); /* Get window X image. */ (void) XTranslateCoordinates(display,root_window,target_window, (int) crop_info.x,(int) crop_info.y,&x,&y,&child); ximage=XGetImage(display,target_window,x,y,1,1,AllPlanes,ZPixmap); if (ximage == (XImage *) NULL) return(MagickFalse); color.pixel=XGetPixel(ximage,0,0); XDestroyImage(ximage); /* Match color against the color database. */ (void) XQueryColor(display,window_attributes.colormap,&color); pixel.red=ScaleShortToQuantum(color.red); pixel.green=ScaleShortToQuantum(color.green); pixel.blue=ScaleShortToQuantum(color.blue); pixel.opacity=OpaqueOpacity; (void) QueryColorname(windows->image.image,&pixel,X11Compliance,name, &windows->image.image->exception); return(MagickTrue); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + X G e t W i n d o w I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XGetWindowImage() reads an image from the target X window and returns it. % XGetWindowImage() optionally descends the window hierarchy and overlays the % target image with each child image in an optimized fashion. Any child % window that have the same visual, colormap, and are contained by its parent % are exempted. % % The format of the XGetWindowImage method is: % % Image *XGetWindowImage(Display *display,const Window window, % const unsigned int borders,const unsigned int level) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o window: Specifies the window to obtain the image from. % % o borders: Specifies whether borders pixels are to be saved with % the image. % % o level: Specifies an unsigned integer representing the level of % decent in the window hierarchy. This value must be zero or one on % the initial call to XGetWindowImage. A value of zero returns after % one call. A value of one causes the function to descend the window % hierarchy and overlay the target image with each subwindow image. % % */ static Image *XGetWindowImage(Display *display,const Window window, const unsigned int borders,const unsigned int level) { typedef struct _ColormapInfo { Colormap colormap; XColor *colors; struct _ColormapInfo *next; } ColormapInfo; typedef struct _WindowInfo { Window window, parent; Visual *visual; Colormap colormap; XSegment bounds; RectangleInfo crop_info; } WindowInfo; IndexPacket index; int display_height, display_width, id, x_offset, y_offset; RectangleInfo crop_info; register IndexPacket *indexes; register int i; static ColormapInfo *colormap_info = (ColormapInfo *) NULL; static int max_windows = 0, number_windows = 0; static WindowInfo *window_info; Status status; Window child, root_window; XWindowAttributes window_attributes; /* Verify window is viewable. */ (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(display != (Display *) NULL); status=XGetWindowAttributes(display,window,&window_attributes); if ((status == False) || (window_attributes.map_state != IsViewable)) return((Image *) NULL); /* Cropping rectangle is relative to root window. */ root_window=XRootWindow(display,XDefaultScreen(display)); (void) XTranslateCoordinates(display,window,root_window,0,0,&x_offset, &y_offset,&child); crop_info.x=(long) x_offset; crop_info.y=(long) y_offset; crop_info.width=(unsigned long) window_attributes.width; crop_info.height=(unsigned long) window_attributes.height; if (borders != MagickFalse) { /* Include border in image. */ crop_info.x-=(long) window_attributes.border_width; crop_info.y-=(long) window_attributes.border_width; crop_info.width+=(unsigned long) (window_attributes.border_width << 1); crop_info.height+=(unsigned long) (window_attributes.border_width << 1); } /* Crop to root window. */ if (crop_info.x < 0) { crop_info.width+=crop_info.x; crop_info.x=0; } if (crop_info.y < 0) { crop_info.height+=crop_info.y; crop_info.y=0; } display_width=XDisplayWidth(display,XDefaultScreen(display)); if ((int) (crop_info.x+crop_info.width) > display_width) crop_info.width=(unsigned long) (display_width-crop_info.x); display_height=XDisplayHeight(display,XDefaultScreen(display)); if ((int) (crop_info.y+crop_info.height) > display_height) crop_info.height=(unsigned long) (display_height-crop_info.y); /* Initialize window info attributes. */ if (number_windows >= max_windows) { /* Allocate or resize window info buffer. */ max_windows+=1024; if (window_info == (WindowInfo *) NULL) window_info=(WindowInfo *) AcquireQuantumMemory((size_t) max_windows, sizeof(*window_info)); else window_info=(WindowInfo *) ResizeQuantumMemory(window_info,(size_t) max_windows,sizeof(*window_info)); } if (window_info == (WindowInfo *) NULL) { ThrowXWindowFatalException(ResourceLimitError, "MemoryAllocationFailed","..."); return((Image *) NULL); } id=number_windows++; window_info[id].window=window; window_info[id].visual=window_attributes.visual; window_info[id].colormap=window_attributes.colormap; window_info[id].bounds.x1=(short) crop_info.x; window_info[id].bounds.y1=(short) crop_info.y; window_info[id].bounds.x2=(short) (crop_info.x+(int) crop_info.width-1); window_info[id].bounds.y2=(short) (crop_info.y+(int) crop_info.height-1); crop_info.x-=x_offset; crop_info.y-=y_offset; window_info[id].crop_info=crop_info; if (level != 0) { unsigned int number_children; Window *children; /* Descend the window hierarchy. */ status=XQueryTree(display,window,&root_window,&window_info[id].parent, &children,&number_children); for (i=0; i < id; i++) if ((window_info[i].window == window_info[id].parent) && (window_info[i].visual == window_info[id].visual) && (window_info[i].colormap == window_info[id].colormap)) if ((window_info[id].bounds.x1 <= window_info[i].bounds.x1) || (window_info[id].bounds.x1 >= window_info[i].bounds.x2) || (window_info[id].bounds.y1 <= window_info[i].bounds.y1) || (window_info[id].bounds.y1 >= window_info[i].bounds.y2)) { /* Eliminate windows not circumscribed by their parent. */ number_windows--; break; } if ((status == True) && (number_children != 0)) { for (i=0; i < (int) number_children; i++) (void) XGetWindowImage(display,children[i],MagickFalse,level+1); (void) XFree((void *) children); } } if (level <= 1) { ColormapInfo *next; Image *composite_image, *image; int y; MagickBooleanType import; register int j, x; register PixelPacket *q; register unsigned long pixel; unsigned int number_colors; XColor *colors; XImage *ximage; /* Get X image for each window in the list. */ image=NewImageList(); for (id=0; id < number_windows; id++) { /* Does target window intersect top level window? */ import= ((window_info[id].bounds.x2 >= window_info[0].bounds.x1) && (window_info[id].bounds.x1 <= window_info[0].bounds.x2) && (window_info[id].bounds.y2 >= window_info[0].bounds.y1) && (window_info[id].bounds.y1 <= window_info[0].bounds.y2)) ? MagickTrue : MagickFalse; /* Is target window contained by another window with the same colormap? */ for (j=0; j < id; j++) if ((window_info[id].visual == window_info[j].visual) && (window_info[id].colormap == window_info[j].colormap) && (window_info[id].bounds.x1 >= window_info[j].bounds.x1) && (window_info[id].bounds.y1 >= window_info[j].bounds.y1) && (window_info[id].bounds.x2 <= window_info[j].bounds.x2) && (window_info[id].bounds.y2 <= window_info[j].bounds.y2)) import=MagickFalse; else if ((window_info[id].visual != window_info[j].visual) || (window_info[id].colormap != window_info[j].colormap)) if ((window_info[id].bounds.x2 > window_info[j].bounds.x1) && (window_info[id].bounds.x1 < window_info[j].bounds.x2) && (window_info[id].bounds.y2 > window_info[j].bounds.y1) && (window_info[id].bounds.y1 < window_info[j].bounds.y2)) import=MagickTrue; if (import == MagickFalse) continue; /* Get X image. */ ximage=XGetImage(display,window_info[id].window,(int) window_info[id].crop_info.x,(int) window_info[id].crop_info.y, (unsigned int) window_info[id].crop_info.width,(unsigned int) window_info[id].crop_info.height,AllPlanes,ZPixmap); if (ximage == (XImage *) NULL) continue; /* Initialize window colormap. */ number_colors=0; colors=(XColor *) NULL; if (window_info[id].colormap != (Colormap) NULL) { ColormapInfo *p; /* Search colormap list for window colormap. */ number_colors=(unsigned int) window_info[id].visual->map_entries; for (p=colormap_info; p != (ColormapInfo *) NULL; p=p->next) if (p->colormap == window_info[id].colormap) break; if (p == (ColormapInfo *) NULL) { /* Get the window colormap. */ colors=(XColor *) AcquireQuantumMemory(number_colors, sizeof(*colors)); if (colors == (XColor *) NULL) { XDestroyImage(ximage); return((Image *) NULL); } if ((window_info[id].visual->klass != DirectColor) && (window_info[id].visual->klass != TrueColor)) for (i=0; i < (int) number_colors; i++) { colors[i].pixel=(unsigned long) i; colors[i].pad='\0'; } else { unsigned long blue, blue_bit, green, green_bit, red, red_bit; /* DirectColor or TrueColor visual. */ red=0; green=0; blue=0; red_bit=window_info[id].visual->red_mask & (~(window_info[id].visual->red_mask)+1); green_bit=window_info[id].visual->green_mask & (~(window_info[id].visual->green_mask)+1); blue_bit=window_info[id].visual->blue_mask & (~(window_info[id].visual->blue_mask)+1); for (i=0; i < (int) number_colors; i++) { colors[i].pixel=red | green | blue; colors[i].pad='\0'; red+=red_bit; if (red > window_info[id].visual->red_mask) red=0; green+=green_bit; if (green > window_info[id].visual->green_mask) green=0; blue+=blue_bit; if (blue > window_info[id].visual->blue_mask) blue=0; } } (void) XQueryColors(display,window_info[id].colormap,colors, (int) number_colors); /* Append colormap to colormap list. */ p=(ColormapInfo *) AcquireMagickMemory(sizeof(*p)); if (p == (ColormapInfo *) NULL) return((Image *) NULL); p->colormap=window_info[id].colormap; p->colors=colors; p->next=colormap_info; colormap_info=p; } colors=p->colors; } /* Allocate image structure. */ composite_image=AllocateImage((ImageInfo *) NULL); if (composite_image == (Image *) NULL) { XDestroyImage(ximage); return((Image *) NULL); } /* Convert X image to MIFF format. */ if ((window_info[id].visual->klass != TrueColor) && (window_info[id].visual->klass != DirectColor)) composite_image->storage_class=PseudoClass; composite_image->columns=(unsigned long) ximage->width; composite_image->rows=(unsigned long) ximage->height; switch (composite_image->storage_class) { case DirectClass: default: { register unsigned long color, index; unsigned long blue_mask, blue_shift, green_mask, green_shift, red_mask, red_shift; /* Determine shift and mask for red, green, and blue. */ red_mask=window_info[id].visual->red_mask; red_shift=0; while ((red_mask != 0) && ((red_mask & 0x01) == 0)) { red_mask>>=1; red_shift++; } green_mask=window_info[id].visual->green_mask; green_shift=0; while ((green_mask != 0) && ((green_mask & 0x01) == 0)) { green_mask>>=1; green_shift++; } blue_mask=window_info[id].visual->blue_mask; blue_shift=0; while ((blue_mask != 0) && ((blue_mask & 0x01) == 0)) { blue_mask>>=1; blue_shift++; } /* Convert X image to DirectClass packets. */ if ((number_colors != 0) && (window_info[id].visual->klass == DirectColor)) for (y=0; y < (int) composite_image->rows; y++) { q=SetImagePixels(composite_image,0,y, composite_image->columns,1); if (q == (PixelPacket *) NULL) break; for (x=0; x < (int) composite_image->columns; x++) { pixel=XGetPixel(ximage,x,y); index=(pixel >> red_shift) & red_mask; q->red=ScaleShortToQuantum(colors[index].red); index=(pixel >> green_shift) & green_mask; q->green=ScaleShortToQuantum(colors[index].green); index=(pixel >> blue_shift) & blue_mask; q->blue=ScaleShortToQuantum(colors[index].blue); q++; } if (SyncImagePixels(composite_image) == MagickFalse) break; } else for (y=0; y < (int) composite_image->rows; y++) { q=SetImagePixels(composite_image,0,y, composite_image->columns,1); if (q == (PixelPacket *) NULL) break; for (x=0; x < (int) composite_image->columns; x++) { pixel=XGetPixel(ximage,x,y); color=(pixel >> red_shift) & red_mask; color=(65535UL*color)/red_mask; q->red=ScaleShortToQuantum((unsigned short) color); color=(pixel >> green_shift) & green_mask; color=(65535UL*color)/green_mask; q->green=ScaleShortToQuantum((unsigned short) color); color=(pixel >> blue_shift) & blue_mask; color=(65535UL*color)/blue_mask; q->blue=ScaleShortToQuantum((unsigned short) color); q++; } if (SyncImagePixels(composite_image) == MagickFalse) break; } break; } case PseudoClass: { /* Create colormap. */ if (AllocateImageColormap(composite_image,number_colors) == MagickFalse) { XDestroyImage(ximage); composite_image=DestroyImage(composite_image); return((Image *) NULL); } for (i=0; i < (int) composite_image->colors; i++) { composite_image->colormap[colors[i].pixel].red= ScaleShortToQuantum(colors[i].red); composite_image->colormap[colors[i].pixel].green= ScaleShortToQuantum(colors[i].green); composite_image->colormap[colors[i].pixel].blue= ScaleShortToQuantum(colors[i].blue); } /* Convert X image to PseudoClass packets. */ for (y=0; y < (int) composite_image->rows; y++) { q=SetImagePixels(composite_image,0,y,composite_image->columns,1); if (q == (PixelPacket *) NULL) break; indexes=GetIndexes(composite_image); for (x=0; x < (int) composite_image->columns; x++) { index=(IndexPacket) XGetPixel(ximage,x,y); indexes[x]=index; *q++=composite_image->colormap[(long) index]; } if (SyncImagePixels(composite_image) == MagickFalse) break; } break; } } XDestroyImage(ximage); composite_image->depth=GetImageDepth(composite_image, &composite_image->exception); if (image == (Image *) NULL) { image=composite_image; continue; } /* Composite any children in back-to-front order. */ (void) XTranslateCoordinates(display,window_info[id].window,window,0,0, &x_offset,&y_offset,&child); x_offset-=(int) crop_info.x; if (x_offset < 0) x_offset=0; y_offset-=(int) crop_info.y; if (y_offset < 0) y_offset=0; (void) CompositeImage(image,CopyCompositeOp,composite_image, x_offset,y_offset); } /* Free resources. */ while (colormap_info != (ColormapInfo *) NULL) { next=colormap_info->next; colormap_info->colors=(XColor *) RelinquishMagickMemory(colormap_info->colors); colormap_info=(ColormapInfo *) RelinquishMagickMemory(colormap_info); colormap_info=next; } /* Free resources and restore initial state. */ window_info=(WindowInfo *) RelinquishMagickMemory(window_info); max_windows=0; number_windows=0; colormap_info=(ColormapInfo *) NULL; return(image); } return((Image *) NULL); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X G e t W i n d o w I n f o % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XGetWindowInfo() initializes the XWindowInfo structure. % % The format of the XGetWindowInfo method is: % % void XGetWindowInfo(Display *display,XVisualInfo *visual_info, % XStandardColormap *map_info,XPixelInfo *pixel,XFontStruct *font_info, % XResourceInfo *resource_info,XWindowInfo *window) % resource_info,window) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o visual_info: Specifies a pointer to a X11 XVisualInfo structure; % returned from XGetVisualInfo. % % o map_info: If map_type is specified, this structure is initialized % with info from the Standard Colormap. % % o pixel: Specifies a pointer to a XPixelInfo structure. % % o font_info: Specifies a pointer to a XFontStruct structure. % % o resource_info: Specifies a pointer to a X11 XResourceInfo structure. % */ MagickExport void XGetWindowInfo(Display *display,XVisualInfo *visual_info, XStandardColormap *map_info,XPixelInfo *pixel,XFontStruct *font_info, XResourceInfo *resource_info,XWindowInfo *window) { /* Initialize window info. */ (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(display != (Display *) NULL); assert(visual_info != (XVisualInfo *) NULL); assert(map_info != (XStandardColormap *) NULL); assert(pixel != (XPixelInfo *) NULL); assert(resource_info != (XResourceInfo *) NULL); assert(window != (XWindowInfo *) NULL); if (window->id != (Window) NULL) { if (window->cursor != (Cursor) NULL) (void) XFreeCursor(display,window->cursor); if (window->busy_cursor != (Cursor) NULL) (void) XFreeCursor(display,window->busy_cursor); if (window->highlight_stipple != (Pixmap) NULL) (void) XFreePixmap(display,window->highlight_stipple); if (window->shadow_stipple != (Pixmap) NULL) (void) XFreePixmap(display,window->shadow_stipple); *window->name='\0'; *window->icon_name='\0'; } else { /* Initialize these attributes just once. */ window->id=(Window) NULL; if (window->name == (char *) NULL) window->name=AcquireString("\0"); if (window->icon_name == (char *) NULL) window->icon_name=AcquireString("\0"); window->x=XDisplayWidth(display,visual_info->screen) >> 1; window->y=XDisplayWidth(display,visual_info->screen) >> 1; window->ximage=(XImage *) NULL; window->matte_image=(XImage *) NULL; window->pixmap=(Pixmap) NULL; window->matte_pixmap=(Pixmap) NULL; window->mapped=MagickFalse; window->stasis=MagickFalse; window->shared_memory=MagickTrue; window->segment_info=(void *) NULL; #if defined(HasSharedMemory) { XShmSegmentInfo *segment_info; if (window->segment_info == (void *) NULL) window->segment_info=AcquireQuantumMemory(2,sizeof(*segment_info)); segment_info=(XShmSegmentInfo *) window->segment_info; segment_info[0].shmid=(-1); segment_info[0].shmaddr=(char *) NULL; segment_info[1].shmid=(-1); segment_info[1].shmaddr=(char *) NULL; } #endif } /* Initialize these attributes every time function is called. */ window->screen=visual_info->screen; window->root=XRootWindow(display,visual_info->screen); window->visual=visual_info->visual; window->storage_class=(unsigned int) visual_info->klass; window->depth=(unsigned int) visual_info->depth; window->visual_info=visual_info; window->map_info=map_info; window->pixel_info=pixel; window->font_info=font_info; window->cursor=XCreateFontCursor(display,XC_left_ptr); window->busy_cursor=XCreateFontCursor(display,XC_watch); window->geometry=(char *) NULL; window->icon_geometry=(char *) NULL; if (resource_info->icon_geometry != (char *) NULL) (void) CloneString(&window->icon_geometry,resource_info->icon_geometry); window->crop_geometry=(char *) NULL; window->flags=(unsigned long) PSize; window->width=1; window->height=1; window->min_width=1; window->min_height=1; window->width_inc=1; window->height_inc=1; window->border_width=resource_info->border_width; window->annotate_context=pixel->annotate_context; window->highlight_context=pixel->highlight_context; window->widget_context=pixel->widget_context; window->shadow_stipple=(Pixmap) NULL; window->highlight_stipple=(Pixmap) NULL; window->use_pixmap=MagickTrue; window->immutable=MagickFalse; window->shape=MagickFalse; window->data=0; window->mask=(unsigned long) (CWBackingStore | CWBackPixel | CWBackPixmap | CWBitGravity | CWBorderPixel | CWColormap | CWCursor | CWDontPropagate | CWEventMask | CWOverrideRedirect | CWSaveUnder | CWWinGravity); window->attributes.background_pixel=pixel->background_color.pixel; window->attributes.background_pixmap=(Pixmap) NULL; window->attributes.bit_gravity=ForgetGravity; window->attributes.backing_store=WhenMapped; window->attributes.save_under=MagickTrue; window->attributes.border_pixel=pixel->border_color.pixel; window->attributes.colormap=map_info->colormap; window->attributes.cursor=window->cursor; window->attributes.do_not_propagate_mask=NoEventMask; window->attributes.event_mask=NoEventMask; window->attributes.override_redirect=MagickFalse; window->attributes.win_gravity=NorthWestGravity; window->orphan=MagickFalse; } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X H i g h l i g h t E l l i p s e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XHighlightEllipse() puts a border on the X server around a region defined by % highlight_info. % % The format of the XHighlightEllipse method is: % % void XHighlightEllipse(Display *display,Window window, % GC annotate_context,const RectangleInfo *highlight_info) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o window: Specifies a pointer to a Window structure. % % o annotate_context: Specifies a pointer to a GC structure. % % o highlight_info: Specifies a pointer to a RectangleInfo structure. It % contains the extents of any highlighting rectangle. % */ MagickExport void XHighlightEllipse(Display *display,Window window, GC annotate_context,const RectangleInfo *highlight_info) { (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(display != (Display *) NULL); assert(window != (Window) NULL); assert(annotate_context != (GC) NULL); assert(highlight_info != (RectangleInfo *) NULL); if ((highlight_info->width < 4) || (highlight_info->height < 4)) return; (void) XDrawArc(display,window,annotate_context,(int) highlight_info->x, (int) highlight_info->y,(unsigned int) highlight_info->width-1, (unsigned int) highlight_info->height-1,0,360*64); (void) XDrawArc(display,window,annotate_context,(int) highlight_info->x+1, (int) highlight_info->y+1,(unsigned int) highlight_info->width-3, (unsigned int) highlight_info->height-3,0,360*64); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X H i g h l i g h t L i n e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XHighlightLine() puts a border on the X server around a region defined by % highlight_info. % % The format of the XHighlightLine method is: % % void XHighlightLine(Display *display,Window window,GC annotate_context, % const XSegment *highlight_info) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o window: Specifies a pointer to a Window structure. % % o annotate_context: Specifies a pointer to a GC structure. % % o highlight_info: Specifies a pointer to a RectangleInfo structure. It % contains the extents of any highlighting rectangle. % */ MagickExport void XHighlightLine(Display *display,Window window, GC annotate_context,const XSegment *highlight_info) { (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(display != (Display *) NULL); assert(window != (Window) NULL); assert(annotate_context != (GC) NULL); assert(highlight_info != (XSegment *) NULL); (void) XDrawLine(display,window,annotate_context,highlight_info->x1, highlight_info->y1,highlight_info->x2,highlight_info->y2); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X H i g h l i g h t R e c t a n g l e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XHighlightRectangle() puts a border on the X server around a region defined % by highlight_info. % % The format of the XHighlightRectangle method is: % % void XHighlightRectangle(Display *display,Window window, % GC annotate_context,const RectangleInfo *highlight_info) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o window: Specifies a pointer to a Window structure. % % o annotate_context: Specifies a pointer to a GC structure. % % o highlight_info: Specifies a pointer to a RectangleInfo structure. It % contains the extents of any highlighting rectangle. % */ MagickExport void XHighlightRectangle(Display *display,Window window, GC annotate_context,const RectangleInfo *highlight_info) { assert(display != (Display *) NULL); (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(window != (Window) NULL); assert(annotate_context != (GC) NULL); assert(highlight_info != (RectangleInfo *) NULL); if ((highlight_info->width < 4) || (highlight_info->height < 4)) return; (void) XDrawRectangle(display,window,annotate_context,(int) highlight_info->x, (int) highlight_info->y,(unsigned int) highlight_info->width-1, (unsigned int) highlight_info->height-1); (void) XDrawRectangle(display,window,annotate_context,(int) highlight_info->x+ 1,(int) highlight_info->y+1,(unsigned int) highlight_info->width-3, (unsigned int) highlight_info->height-3); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X I m p o r t I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XImportImage() reads an image from an X window. % % The format of the XImportImage method is: % % Image *XImportImage(const ImageInfo *image_info,XImportInfo *ximage_info) % % A description of each parameter follows: % % o image_info: The image info.. % % o ximage_info: Specifies a pointer to an XImportInfo structure. % */ MagickExport Image *XImportImage(const ImageInfo *image_info, XImportInfo *ximage_info) { Colormap *colormaps; Display *display; Image *image; int number_colormaps, number_windows, x; RectangleInfo crop_info; Status status; Window *children, client, prior_target, root, target; XTextProperty window_name; /* Open X server connection. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(ximage_info != (XImportInfo *) NULL); display=XOpenDisplay(image_info->server_name); if (display == (Display *) NULL) { ThrowXWindowFatalException(XServerError,"UnableToOpenXServer", XDisplayName(image_info->server_name)); return((Image *) NULL); } /* Set our forgiving exception handler. */ (void) XSetErrorHandler(XError); /* Select target window. */ crop_info.x=0; crop_info.y=0; crop_info.width=0; crop_info.height=0; root=XRootWindow(display,XDefaultScreen(display)); target=(Window) NULL; if ((image_info->filename != (char *) NULL) && (*image_info->filename != '\0')) { if (LocaleCompare(image_info->filename,"root") == 0) target=root; else { /* Select window by ID or name. */ if (isdigit((unsigned char) *image_info->filename) != 0) target=XWindowByID(display,root,(Window) strtol(image_info->filename,(char **) NULL,0)); if (target == (Window) NULL) target=XWindowByName(display,root,image_info->filename); if (target == (Window) NULL) ThrowXWindowFatalException(XServerError, "NoWindowWithSpecifiedIDExists",image_info->filename); } } /* If target window is not defined, interactively select one. */ prior_target=target; if (target == (Window) NULL) target=XSelectWindow(display,&crop_info); if (target == (Window) NULL) ThrowXWindowFatalException(XServerError,"UnableToReadXWindowImage", image_info->filename); client=target; /* obsolete */ if (target != root) { unsigned int d; status=XGetGeometry(display,target,&root,&x,&x,&d,&d,&d,&d); if (status != False) { for ( ; ; ) { Window parent; /* Find window manager frame. */ status=XQueryTree(display,target,&root,&parent,&children,&d); if ((status != False) && (children != (Window *) NULL)) (void) XFree((char *) children); if ((status == False) || (parent == (Window) NULL) || (parent == root)) break; target=parent; } /* Get client window. */ client=XClientWindow(display,target); if (ximage_info->frame == MagickFalse) target=client; if ((ximage_info->frame == MagickFalse) && (prior_target != MagickFalse)) target=prior_target; XDelay(display,SuspendTime << 4); } } if (ximage_info->screen) { int y; Window child; XWindowAttributes window_attributes; /* Obtain window image directly from screen. */ status=XGetWindowAttributes(display,target,&window_attributes); if (status == False) { ThrowXWindowFatalException(XServerError, "UnableToReadXWindowAttributes",image_info->filename); (void) XCloseDisplay(display); return((Image *) NULL); } (void) XTranslateCoordinates(display,target,root,0,0,&x,&y,&child); crop_info.x=x; crop_info.y=y; crop_info.width=(unsigned long) window_attributes.width; crop_info.height=(unsigned long) window_attributes.height; if (ximage_info->borders) { /* Include border in image. */ crop_info.x-=window_attributes.border_width; crop_info.y-=window_attributes.border_width; crop_info.width+=window_attributes.border_width << 1; crop_info.height+=window_attributes.border_width << 1; } target=root; } /* If WM_COLORMAP_WINDOWS property is set or multiple colormaps, descend. */ number_windows=0; status=XGetWMColormapWindows(display,target,&children,&number_windows); if ((status == True) && (number_windows > 0)) { ximage_info->descend=MagickTrue; (void) XFree ((char *) children); } colormaps=XListInstalledColormaps(display,target,&number_colormaps); if (number_colormaps > 0) { if (number_colormaps > 1) ximage_info->descend=MagickTrue; (void) XFree((char *) colormaps); } /* Alert the user not to alter the screen. */ if (ximage_info->silent == MagickFalse) (void) XBell(display,0); /* Get image by window id. */ (void) XGrabServer(display); image=XGetWindowImage(display,target,ximage_info->borders, ximage_info->descend ? 1U : 0U); (void) XUngrabServer(display); if (image == (Image *) NULL) ThrowXWindowFatalException(XServerError,"UnableToReadXWindowImage", image_info->filename) else { (void) CopyMagickString(image->filename,image_info->filename, MaxTextExtent); if ((crop_info.width != 0) && (crop_info.height != 0)) { Image *clone_image, *crop_image; /* Crop image as defined by the cropping rectangle. */ clone_image=CloneImage(image,0,0,MagickTrue,&image->exception); if (clone_image != (Image *) NULL) { crop_image=CropImage(clone_image,&crop_info,&image->exception); if (crop_image != (Image *) NULL) { image=DestroyImage(image); image=crop_image; } } } status=XGetWMName(display,target,&window_name); if (status == True) { if ((image_info->filename != (char *) NULL) && (*image_info->filename == '\0')) (void) CopyMagickString(image->filename,(char *) window_name.value, (size_t) window_name.nitems+1); (void) XFree((void *) window_name.value); } } if (ximage_info->silent == MagickFalse) { /* Alert the user we're done. */ (void) XBell(display,0); (void) XBell(display,0); } (void) XCloseDisplay(display); return(image); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X I n i t i a l i z e W i n d o w s % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XInitializeWindows() initializes the XWindows structure. % % The format of the XInitializeWindows method is: % % XWindows *XInitializeWindows(Display *display, % XResourceInfo *resource_info) % % A description of each parameter follows: % % o windows: XInitializeWindows returns a pointer to a XWindows structure. % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o resource_info: Specifies a pointer to a X11 XResourceInfo structure. % */ MagickExport XWindows *XInitializeWindows(Display *display, XResourceInfo *resource_info) { Window root_window; XWindows *windows; /* Allocate windows structure. */ windows=(XWindows *) AcquireMagickMemory(sizeof(*windows)); if (windows == (XWindows *) NULL) { ThrowXWindowFatalException(XServerFatalError,"MemoryAllocationFailed", "..."); return((XWindows *) NULL); } (void) ResetMagickMemory(windows,0,sizeof(*windows)); windows->pixel_info=(XPixelInfo *) AcquireMagickMemory( sizeof(*windows->pixel_info)); windows->icon_pixel=(XPixelInfo *) AcquireMagickMemory( sizeof(*windows->icon_pixel)); windows->icon_resources=(XResourceInfo *) AcquireMagickMemory( sizeof(*windows->icon_resources)); if ((windows->pixel_info == (XPixelInfo *) NULL) || (windows->icon_pixel == (XPixelInfo *) NULL) || (windows->icon_resources == (XResourceInfo *) NULL)) { ThrowXWindowFatalException(XServerFatalError,"MemoryAllocationFailed", "..."); return((XWindows *) NULL); } /* Initialize windows structure. */ windows->display=display; windows->wm_protocols=XInternAtom(display,"WM_PROTOCOLS",MagickFalse); windows->wm_delete_window=XInternAtom(display,"WM_DELETE_WINDOW",MagickFalse); windows->wm_take_focus=XInternAtom(display,"WM_TAKE_FOCUS",MagickFalse); windows->im_protocols=XInternAtom(display,"IM_PROTOCOLS",MagickFalse); windows->im_remote_command= XInternAtom(display,"IM_REMOTE_COMMAND",MagickFalse); windows->im_update_widget=XInternAtom(display,"IM_UPDATE_WIDGET",MagickFalse); windows->im_update_colormap= XInternAtom(display,"IM_UPDATE_COLORMAP",MagickFalse); windows->im_former_image=XInternAtom(display,"IM_FORMER_IMAGE",MagickFalse); windows->im_next_image=XInternAtom(display,"IM_NEXT_IMAGE",MagickFalse); windows->im_retain_colors=XInternAtom(display,"IM_RETAIN_COLORS",MagickFalse); windows->im_exit=XInternAtom(display,"IM_EXIT",MagickFalse); windows->dnd_protocols=XInternAtom(display,"DndProtocol",MagickFalse); #if defined(__WINDOWS__) (void) XSynchronize(display,IsWindows95()); #endif if (IsEventLogging()) { (void) XSynchronize(display,MagickTrue); (void) LogMagickEvent(X11Event,GetMagickModule(),"Version: %s", GetMagickVersion((unsigned long *) NULL)); (void) LogMagickEvent(X11Event,GetMagickModule(),"Protocols:"); (void) LogMagickEvent(X11Event,GetMagickModule(), " Window Manager: 0x%lx",windows->wm_protocols); (void) LogMagickEvent(X11Event,GetMagickModule(), " delete window: 0x%lx",windows->wm_delete_window); (void) LogMagickEvent(X11Event,GetMagickModule()," take focus: 0x%lx", windows->wm_take_focus); (void) LogMagickEvent(X11Event,GetMagickModule()," ImageMagick: 0x%lx", windows->im_protocols); (void) LogMagickEvent(X11Event,GetMagickModule(), " remote command: 0x%lx",windows->im_remote_command); (void) LogMagickEvent(X11Event,GetMagickModule(), " update widget: 0x%lx",windows->im_update_widget); (void) LogMagickEvent(X11Event,GetMagickModule(), " update colormap: 0x%lx",windows->im_update_colormap); (void) LogMagickEvent(X11Event,GetMagickModule(), " former image: 0x%lx",windows->im_former_image); (void) LogMagickEvent(X11Event,GetMagickModule()," next image: 0x%lx", windows->im_next_image); (void) LogMagickEvent(X11Event,GetMagickModule(), " retain colors: 0x%lx",windows->im_retain_colors); (void) LogMagickEvent(X11Event,GetMagickModule()," exit: 0x%lx", windows->im_exit); (void) LogMagickEvent(X11Event,GetMagickModule()," Drag and Drop: 0x%lx", windows->dnd_protocols); } /* Allocate standard colormap. */ windows->map_info=XAllocStandardColormap(); windows->icon_map=XAllocStandardColormap(); if ((windows->map_info == (XStandardColormap *) NULL) || (windows->icon_map == (XStandardColormap *) NULL)) ThrowXWindowFatalException(ResourceLimitFatalError, "MemoryAllocationFailed","..."); windows->map_info->colormap=(Colormap) NULL; windows->icon_map->colormap=(Colormap) NULL; windows->pixel_info->pixels=(unsigned long *) NULL; windows->pixel_info->annotate_context=(GC) NULL; windows->pixel_info->highlight_context=(GC) NULL; windows->pixel_info->widget_context=(GC) NULL; windows->font_info=(XFontStruct *) NULL; windows->icon_pixel->annotate_context=(GC) NULL; windows->icon_pixel->pixels=(unsigned long *) NULL; /* Allocate visual. */ *windows->icon_resources=(*resource_info); windows->icon_resources->visual_type=(char *) "default"; windows->icon_resources->colormap=SharedColormap; windows->visual_info= XBestVisualInfo(display,windows->map_info,resource_info); windows->icon_visual= XBestVisualInfo(display,windows->icon_map,windows->icon_resources); if ((windows->visual_info == (XVisualInfo *) NULL) || (windows->icon_visual == (XVisualInfo *) NULL)) ThrowXWindowFatalException(XServerFatalError,"UnableToGetVisual", resource_info->visual_type); if (IsEventLogging()) { (void) LogMagickEvent(X11Event,GetMagickModule(),"Visual:"); (void) LogMagickEvent(X11Event,GetMagickModule()," visual id: 0x%lx", windows->visual_info->visualid); (void) LogMagickEvent(X11Event,GetMagickModule()," class: %s", XVisualClassName(windows->visual_info->klass)); (void) LogMagickEvent(X11Event,GetMagickModule()," depth: %d planes", windows->visual_info->depth); (void) LogMagickEvent(X11Event,GetMagickModule(), " size of colormap: %d entries",windows->visual_info->colormap_size); (void) LogMagickEvent(X11Event,GetMagickModule(), " red, green, blue masks: 0x%lx 0x%lx 0x%lx", windows->visual_info->red_mask,windows->visual_info->green_mask, windows->visual_info->blue_mask); (void) LogMagickEvent(X11Event,GetMagickModule(), " significant bits in color: %d bits", windows->visual_info->bits_per_rgb); } /* Allocate class and manager hints. */ windows->class_hints=XAllocClassHint(); windows->manager_hints=XAllocWMHints(); if ((windows->class_hints == (XClassHint *) NULL) || (windows->manager_hints == (XWMHints *) NULL)) ThrowXWindowFatalException(ResourceLimitFatalError, "MemoryAllocationFailed","..."); /* Determine group leader if we have one. */ root_window=XRootWindow(display,windows->visual_info->screen); windows->group_leader.id=(Window) NULL; if (resource_info->window_group != (char *) NULL) { if (isdigit((unsigned char) *resource_info->window_group) != 0) windows->group_leader.id=XWindowByID(display,root_window,(Window) strtol((char *) resource_info->window_group,(char **) NULL,0)); if (windows->group_leader.id == (Window) NULL) windows->group_leader.id= XWindowByName(display,root_window,resource_info->window_group); } return(windows); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X M a k e C u r s o r % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XMakeCursor() creates a crosshairs X11 cursor. % % The format of the XMakeCursor method is: % % Cursor XMakeCursor(Display *display,Window window,Colormap colormap, % char *background_color,char *foreground_color) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o window: Specifies the ID of the window for which the cursor is % assigned. % % o colormap: Specifies the ID of the colormap from which the background % and foreground color will be retrieved. % % o background_color: Specifies the color to use for the cursor background. % % o foreground_color: Specifies the color to use for the cursor foreground. % */ MagickExport Cursor XMakeCursor(Display *display,Window window, Colormap colormap,char *background_color,char *foreground_color) { #define scope_height 17 #define scope_x_hot 8 #define scope_y_hot 8 #define scope_width 17 static const unsigned char scope_bits[] = { 0x80, 0x03, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x7f, 0xfc, 0x01, 0x01, 0x00, 0x01, 0x7f, 0xfc, 0x01, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x03, 0x00 }, scope_mask_bits[] = { 0xc0, 0x07, 0x00, 0xc0, 0x07, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xff, 0xfe, 0x01, 0x7f, 0xfc, 0x01, 0x03, 0x80, 0x01, 0x7f, 0xfc, 0x01, 0xff, 0xfe, 0x01, 0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x07, 0x00, 0xc0, 0x07, 0x00 }; Cursor cursor; Pixmap mask, source; XColor background, foreground; assert(display != (Display *) NULL); assert(window != (Window) NULL); assert(colormap != (Colormap) NULL); assert(background_color != (char *) NULL); assert(foreground_color != (char *) NULL); (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",background_color); source=XCreateBitmapFromData(display,window,(char *) scope_bits,scope_width, scope_height); mask=XCreateBitmapFromData(display,window,(char *) scope_mask_bits, scope_width,scope_height); if ((source == (Pixmap) NULL) || (mask == (Pixmap) NULL)) { ThrowXWindowFatalException(XServerError,"UnableToCreatePixmap","..."); return((Cursor) NULL); } (void) XParseColor(display,colormap,background_color,&background); (void) XParseColor(display,colormap,foreground_color,&foreground); cursor=XCreatePixmapCursor(display,source,mask,&foreground,&background, scope_x_hot,scope_y_hot); (void) XFreePixmap(display,source); (void) XFreePixmap(display,mask); return(cursor); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X M a k e I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XMakeImage() creates an X11 image. If the image size differs from the X11 % image size, the image is first resized. % % The format of the XMakeImage method is: % % MagickBooleanType XMakeImage(Display *display, % const XResourceInfo *resource_info,XWindowInfo *window,Image *image, % unsigned int width,unsigned int height) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o resource_info: Specifies a pointer to a X11 XResourceInfo structure. % % o window: Specifies a pointer to a XWindowInfo structure. % % o image: The image. % % o width: Specifies the width in pixels of the rectangular area to % display. % % o height: Specifies the height in pixels of the rectangular area to % display. % */ MagickExport MagickBooleanType XMakeImage(Display *display, const XResourceInfo *resource_info,XWindowInfo *window,Image *image, unsigned int width,unsigned int height) { int depth, format; size_t length; XImage *matte_image, *ximage; (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(display != (Display *) NULL); assert(resource_info != (XResourceInfo *) NULL); assert(window != (XWindowInfo *) NULL); assert(width != 0); assert(height != 0); if ((window->width == 0) || (window->height == 0)) return(MagickFalse); /* Apply user transforms to the image. */ (void) XCheckDefineCursor(display,window->id,window->busy_cursor); (void) XFlush(display); depth=(int) window->depth; if (window->destroy) window->image=DestroyImage(window->image); window->image=image; window->destroy=MagickFalse; if (window->image != (Image *) NULL) { if (window->crop_geometry != (char *) NULL) { Image *crop_image; RectangleInfo crop_info; /* Crop image. */ (void) ParsePageGeometry(window->image,window->crop_geometry, &crop_info); crop_image=CropImage(window->image,&crop_info,&image->exception); if (crop_image != (Image *) NULL) { if (window->image != image) window->image=DestroyImage(window->image); window->image=crop_image; window->destroy=MagickTrue; } } if ((width != (unsigned int) window->image->columns) || (height != (unsigned int) window->image->rows)) { Image *resize_image; /* Resize image. */ resize_image=NewImageList(); if (window->pixel_info->colors != 0) resize_image=SampleImage(window->image,width,height, &image->exception); else resize_image=ThumbnailImage(window->image,width,height, &image->exception); if (resize_image != (Image *) NULL) { if (window->image != image) window->image=DestroyImage(window->image); window->image=resize_image; window->destroy=MagickTrue; } } if ((window->immutable == MagickFalse) && (window->image->matte != MagickFalse) && (window->pixel_info->colors == 0)) { Image *pattern; ImageInfo *image_info; image_info=AcquireImageInfo(); (void) CopyMagickString(image_info->filename, resource_info->image_info->texture != (char *) NULL ? resource_info->image_info->texture : "pattern:checkerboard", MaxTextExtent); pattern=ReadImage(image_info,&window->image->exception); image_info=DestroyImageInfo(image_info); if (pattern != (Image *) NULL) { Image *canvas; /* Composite transparent image on canvas. */ canvas=CloneImage(window->image,window->image->columns, window->image->rows,MagickTrue,&window->image->exception); if (canvas != (Image *) NULL) { (void) TextureImage(canvas,pattern); (void) CompositeImage(canvas,AtopCompositeOp,window->image, 0,0); if (window->image != image) window->image=DestroyImage(window->image); window->image=canvas; window->destroy=MagickTrue; } pattern=DestroyImage(pattern); } } width=(unsigned int) window->image->columns; height=(unsigned int) window->image->rows; } /* Create X image. */ ximage=(XImage *) NULL; format=(depth == 1) ? XYBitmap : ZPixmap; #if defined(HasSharedMemory) if (window->shared_memory != MagickFalse) { XShmSegmentInfo *segment_info; segment_info=(XShmSegmentInfo *) window->segment_info; segment_info[1].shmid=(-1); segment_info[1].shmaddr=(char *) NULL; ximage=XShmCreateImage(display,window->visual,(unsigned int) depth,format, (char *) NULL,&segment_info[1],width,height); if (ximage == (XImage *) NULL) window->shared_memory=MagickFalse; if (window->shared_memory != MagickFalse) segment_info[1].shmid=shmget(IPC_PRIVATE,(unsigned int) (ximage->bytes_per_line*ximage->height),IPC_CREAT | 0777); if (window->shared_memory != MagickFalse) segment_info[1].shmaddr=(char *) shmat(segment_info[1].shmid,0,0); if (segment_info[1].shmid < 0) window->shared_memory=MagickFalse; if (window->shared_memory != MagickFalse) (void) shmctl(segment_info[1].shmid,IPC_RMID,0); else { if (ximage != (XImage *) NULL) XDestroyImage(ximage); ximage=(XImage *) NULL; if (segment_info[1].shmaddr) { (void) shmdt(segment_info[1].shmaddr); segment_info[1].shmaddr=(char *) NULL; } if (segment_info[1].shmid >= 0) { (void) shmctl(segment_info[1].shmid,IPC_RMID,0); segment_info[1].shmid=(-1); } } } #endif /* Allocate X image pixel data. */ #if defined(HasSharedMemory) if (window->shared_memory) { Status status; XShmSegmentInfo *segment_info; (void) XSync(display,MagickFalse); xerror_alert=MagickFalse; segment_info=(XShmSegmentInfo *) window->segment_info; ximage->data=segment_info[1].shmaddr; segment_info[1].readOnly=MagickFalse; status=XShmAttach(display,&segment_info[1]); if (status != False) (void) XSync(display,MagickFalse); if ((status == False) || (xerror_alert != MagickFalse)) { window->shared_memory=MagickFalse; if (status != False) XShmDetach(display,&segment_info[1]); if (ximage != (XImage *) NULL) { ximage->data=NULL; XDestroyImage(ximage); ximage=(XImage *) NULL; } if (segment_info[1].shmid >= 0) { if (segment_info[1].shmaddr != NULL) (void) shmdt(segment_info[1].shmaddr); (void) shmctl(segment_info[1].shmid,IPC_RMID,0); segment_info[1].shmid=(-1); segment_info[1].shmaddr=(char *) NULL; } } } #endif if (window->shared_memory == MagickFalse) ximage=XCreateImage(display,window->visual,(unsigned int) depth,format,0, (char *) NULL,width,height,XBitmapPad(display),0); if (ximage == (XImage *) NULL) { /* Unable to create X image. */ (void) XCheckDefineCursor(display,window->id,window->cursor); return(MagickFalse); } length=(size_t) ximage->bytes_per_line*ximage->height; if (IsEventLogging()) { (void) LogMagickEvent(X11Event,GetMagickModule(),"XImage:"); (void) LogMagickEvent(X11Event,GetMagickModule()," width, height: %dx%d", ximage->width,ximage->height); (void) LogMagickEvent(X11Event,GetMagickModule()," format: %d", ximage->format); (void) LogMagickEvent(X11Event,GetMagickModule()," byte order: %d", ximage->byte_order); (void) LogMagickEvent(X11Event,GetMagickModule(), " bitmap unit, bit order, pad: %d %d %d",ximage->bitmap_unit, ximage->bitmap_bit_order,ximage->bitmap_pad); (void) LogMagickEvent(X11Event,GetMagickModule()," depth: %d", ximage->depth); (void) LogMagickEvent(X11Event,GetMagickModule()," bytes per line: %d", ximage->bytes_per_line); (void) LogMagickEvent(X11Event,GetMagickModule()," bits per pixel: %d", ximage->bits_per_pixel); (void) LogMagickEvent(X11Event,GetMagickModule(), " red, green, blue masks: 0x%lx 0x%lx 0x%lx",ximage->red_mask, ximage->green_mask,ximage->blue_mask); } if (window->shared_memory == MagickFalse) { if (ximage->format == XYBitmap) length=(size_t) ximage->bytes_per_line*ximage->height*ximage->depth; else length=(size_t) ximage->bytes_per_line*ximage->height; ximage->data=(char *) malloc(length); } if (ximage->data == (char *) NULL) { /* Unable to allocate pixel data. */ XDestroyImage(ximage); ximage=(XImage *) NULL; (void) XCheckDefineCursor(display,window->id,window->cursor); return(MagickFalse); } if (window->ximage != (XImage *) NULL) { /* Destroy previous X image. */ length=(size_t) window->ximage->bytes_per_line*window->ximage->height; #if defined(HasSharedMemory) if (window->segment_info != (XShmSegmentInfo *) NULL) { XShmSegmentInfo *segment_info; segment_info=(XShmSegmentInfo *) window->segment_info; if (segment_info[0].shmid >= 0) { (void) XSync(display,MagickFalse); (void) XShmDetach(display,&segment_info[0]); (void) XSync(display,MagickFalse); if (segment_info[0].shmaddr != (char *) NULL) (void) shmdt(segment_info[0].shmaddr); (void) shmctl(segment_info[0].shmid,IPC_RMID,0); segment_info[0].shmid=(-1); segment_info[0].shmaddr=(char *) NULL; window->ximage->data=(char *) NULL; } } #endif if (window->ximage->data != (char *) NULL) free(window->ximage->data); window->ximage->data=(char *) NULL; XDestroyImage(window->ximage); window->ximage=(XImage *) NULL; } #if defined(HasSharedMemory) if (window->segment_info != (XShmSegmentInfo *) NULL) { XShmSegmentInfo *segment_info; segment_info=(XShmSegmentInfo *) window->segment_info; segment_info[0]=segment_info[1]; } #endif window->ximage=ximage; matte_image=(XImage *) NULL; if ((window->shape != MagickFalse) && (window->image != (Image *) NULL)) if (window->image->matte && ((long) width <= XDisplayWidth(display,window->screen)) && ((long) height <= XDisplayHeight(display,window->screen))) { /* Create matte image. */ matte_image=XCreateImage(display,window->visual,1,XYBitmap,0, (char *) NULL,width,height,XBitmapPad(display),0); if (IsEventLogging()) { (void) LogMagickEvent(X11Event,GetMagickModule(),"Matte Image:"); (void) LogMagickEvent(X11Event,GetMagickModule(), " width, height: %dx%d",matte_image->width,matte_image->height); } if (matte_image != (XImage *) NULL) { /* Allocate matte image pixel data. */ length=(size_t) matte_image->bytes_per_line* matte_image->height*matte_image->depth; matte_image->data=(char *) malloc(length); if (matte_image->data == (char *) NULL) { XDestroyImage(matte_image); matte_image=(XImage *) NULL; } } } if (window->matte_image != (XImage *) NULL) { /* Free matte image. */ if (window->matte_image->data != (char *) NULL) free(window->matte_image->data); window->matte_image->data=(char *) NULL; XDestroyImage(window->matte_image); window->matte_image=(XImage *) NULL; } window->matte_image=matte_image; if (window->matte_pixmap != (Pixmap) NULL) { (void) XFreePixmap(display,window->matte_pixmap); window->matte_pixmap=(Pixmap) NULL; #if defined(HasShape) if (window->shape != MagickFalse) XShapeCombineMask(display,window->id,ShapeBounding,0,0,None,ShapeSet); #endif } window->stasis=MagickFalse; /* Convert pixels to X image data. */ if (window->image != (Image *) NULL) { if ((ximage->byte_order == LSBFirst) || ((ximage->format == XYBitmap) && (ximage->bitmap_bit_order == LSBFirst))) XMakeImageLSBFirst(resource_info,window,window->image,ximage, matte_image); else XMakeImageMSBFirst(resource_info,window,window->image,ximage, matte_image); } if (window->matte_image != (XImage *) NULL) { /* Create matte pixmap. */ window->matte_pixmap=XCreatePixmap(display,window->id,width,height,1); if (window->matte_pixmap != (Pixmap) NULL) { GC graphics_context; XGCValues context_values; /* Copy matte image to matte pixmap. */ context_values.background=1; context_values.foreground=0; graphics_context=XCreateGC(display,window->matte_pixmap, (unsigned long) (GCBackground | GCForeground),&context_values); (void) XPutImage(display,window->matte_pixmap,graphics_context, window->matte_image,0,0,0,0,width,height); (void) XFreeGC(display,graphics_context); #if defined(HasShape) if (window->shape != MagickFalse) XShapeCombineMask(display,window->id,ShapeBounding,0,0, window->matte_pixmap,ShapeSet); #endif } } (void) XMakePixmap(display,resource_info,window); /* Restore cursor. */ (void) XCheckDefineCursor(display,window->id,window->cursor); return(MagickTrue); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + X M a k e I m a g e L S B F i r s t % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XMakeImageLSBFirst() initializes the pixel data of an X11 Image. The X image % pixels are copied in least-significant bit and byte first order. The % server's scanline pad is respected. Rather than using one or two general % cases, many special cases are found here to help speed up the image % conversion. % % The format of the XMakeImageLSBFirst method is: % % void XMakeImageLSBFirst(Display *display,XWindows *windows) % % A description of each parameter follows: % % o resource_info: Specifies a pointer to a X11 XResourceInfo structure. % % o window: Specifies a pointer to a XWindowInfo structure. % % o image: The image. % % o ximage: Specifies a pointer to a XImage structure; returned from % XCreateImage. % % o matte_image: Specifies a pointer to a XImage structure; returned from % XCreateImage. % */ static void XMakeImageLSBFirst(const XResourceInfo *resource_info, const XWindowInfo *window,Image *image,XImage *ximage,XImage *matte_image) { int y; register IndexPacket *indexes; register int x; register const PixelPacket *p; register unsigned char *q; unsigned char bit, byte; unsigned int scanline_pad; unsigned long pixel, *pixels; XStandardColormap *map_info; assert(resource_info != (XResourceInfo *) NULL); assert(window != (XWindowInfo *) NULL); assert(image != (Image *) NULL); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); scanline_pad=(unsigned int) (ximage->bytes_per_line-((ximage->width* ximage->bits_per_pixel) >> 3)); map_info=window->map_info; pixels=window->pixel_info->pixels; q=(unsigned char *) ximage->data; x=0; if (ximage->format == XYBitmap) { register unsigned short polarity; unsigned char background, foreground; /* Convert image to big-endian bitmap. */ background=(unsigned char) (XPixelIntensity(&window->pixel_info->foreground_color) < XPixelIntensity(&window->pixel_info->background_color) ? 0x80 : 0x00); foreground=(unsigned char) (XPixelIntensity(&window->pixel_info->background_color) < XPixelIntensity(&window->pixel_info->foreground_color) ? 0x80 : 0x00); polarity=(unsigned short) ((PixelIntensityToQuantum( &image->colormap[0])) < ((Quantum) QuantumRange/2) ? 1 : 0); if (image->colors == 2) polarity=PixelIntensity(&image->colormap[0]) < PixelIntensity(&image->colormap[1]); for (y=0; y < (int) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetIndexes(image); bit=0; byte=0; for (x=0; x < (int) image->columns; x++) { byte>>=1; if (indexes[x] == (IndexPacket) polarity) byte|=foreground; else byte|=background; bit++; if (bit == 8) { *q++=byte; bit=0; byte=0; } } if (bit != 0) *q=byte >> (8-bit); q+=scanline_pad; } } else if (window->pixel_info->colors != 0) switch (ximage->bits_per_pixel) { case 2: { register unsigned int nibble; /* Convert to 2 bit color-mapped X image. */ for (y=0; y < (int) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetIndexes(image); nibble=0; for (x=0; x < (int) image->columns; x++) { pixel=pixels[(long) indexes[x]] & 0x0f; switch (nibble) { case 0: { *q=(unsigned char) pixel; nibble++; break; } case 1: { *q|=(unsigned char) (pixel << 2); nibble++; break; } case 2: { *q|=(unsigned char) (pixel << 4); nibble++; break; } case 3: { *q|=(unsigned char) (pixel << 6); q++; nibble=0; break; } } } q+=scanline_pad; } break; } case 4: { register unsigned int nibble; /* Convert to 4 bit color-mapped X image. */ for (y=0; y < (int) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetIndexes(image); nibble=0; for (x=0; x < (int) image->columns; x++) { pixel=pixels[(long) indexes[x]] & 0xf; switch (nibble) { case 0: { *q=(unsigned char) pixel; nibble++; break; } case 1: { *q|=(unsigned char) (pixel << 4); q++; nibble=0; break; } } } q+=scanline_pad; } break; } case 6: case 8: { /* Convert to 8 bit color-mapped X image. */ if (resource_info->color_recovery && resource_info->quantize_info->dither) { XDitherImage(image,ximage); break; } for (y=0; y < (int) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetIndexes(image); for (x=0; x < (int) image->columns; x++) { pixel=pixels[(long) indexes[x]]; *q++=(unsigned char) pixel; } q+=scanline_pad; } break; } default: { register int k; register unsigned int bytes_per_pixel; unsigned char channel[sizeof(unsigned long)]; /* Convert to multi-byte color-mapped X image. */ bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3); for (y=0; y < (int) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetIndexes(image); for (x=0; x < (int) image->columns; x++) { pixel=pixels[(long) indexes[x]]; for (k=0; k < (int) bytes_per_pixel; k++) { channel[k]=(unsigned char) pixel; pixel>>=8; } for (k=0; k < (int) bytes_per_pixel; k++) *q++=channel[k]; } q+=scanline_pad; } break; } } else switch (ximage->bits_per_pixel) { case 2: { register unsigned int nibble; /* Convert to contiguous 2 bit continuous-tone X image. */ for (y=0; y < (int) image->rows; y++) { nibble=0; p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; for (x=0; x < (int) image->columns; x++) { pixel=XGammaPixel(map_info,p); pixel&=0xf; switch (nibble) { case 0: { *q=(unsigned char) pixel; nibble++; break; } case 1: { *q|=(unsigned char) (pixel << 2); nibble++; break; } case 2: { *q|=(unsigned char) (pixel << 4); nibble++; break; } case 3: { *q|=(unsigned char) (pixel << 6); q++; nibble=0; break; } } p++; } q+=scanline_pad; } break; } case 4: { register unsigned int nibble; /* Convert to contiguous 4 bit continuous-tone X image. */ for (y=0; y < (int) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; nibble=0; for (x=0; x < (int) image->columns; x++) { pixel=XGammaPixel(map_info,p); pixel&=0xf; switch (nibble) { case 0: { *q=(unsigned char) pixel; nibble++; break; } case 1: { *q|=(unsigned char) (pixel << 4); q++; nibble=0; break; } } p++; } q+=scanline_pad; } break; } case 6: case 8: { /* Convert to contiguous 8 bit continuous-tone X image. */ if (resource_info->color_recovery && resource_info->quantize_info->dither) { XDitherImage(image,ximage); break; } for (y=0; y < (int) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; for (x=0; x < (int) image->columns; x++) { pixel=XGammaPixel(map_info,p); *q++=(unsigned char) pixel; p++; } q+=scanline_pad; } break; } default: { if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) && (map_info->green_max == 255) && (map_info->blue_max == 255) && (map_info->red_mult == 65536L) && (map_info->green_mult == 256) && (map_info->blue_mult == 1)) { /* Convert to 32 bit continuous-tone X image. */ for (y=0; y < (int) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1, &image->exception); if (p == (const PixelPacket *) NULL) break; if ((red_gamma != 1.0) || (green_gamma != 1.0) || (blue_gamma != 1.0)) { /* Gamma correct image. */ for (x=(int) image->columns-1; x >= 0; x--) { *q++=ScaleQuantumToChar(XBlueGamma(p->blue)); *q++=ScaleQuantumToChar(XGreenGamma(p->green)); *q++=ScaleQuantumToChar(XRedGamma(p->red)); *q++=0; p++; } continue; } for (x=(int) image->columns-1; x >= 0; x--) { *q++=ScaleQuantumToChar((Quantum) p->blue); *q++=ScaleQuantumToChar((Quantum) p->green); *q++=ScaleQuantumToChar((Quantum) p->red); *q++=0; p++; } } } else if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) && (map_info->green_max == 255) && (map_info->blue_max == 255) && (map_info->red_mult == 1) && (map_info->green_mult == 256) && (map_info->blue_mult == 65536L)) { /* Convert to 32 bit continuous-tone X image. */ for (y=0; y < (int) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1, &image->exception); if (p == (const PixelPacket *) NULL) break; if ((red_gamma != 1.0) || (green_gamma != 1.0) || (blue_gamma != 1.0)) { /* Gamma correct image. */ for (x=(int) image->columns-1; x >= 0; x--) { *q++=ScaleQuantumToChar(XRedGamma(p->red)); *q++=ScaleQuantumToChar(XGreenGamma(p->green)); *q++=ScaleQuantumToChar(XBlueGamma(p->blue)); *q++=0; p++; } continue; } for (x=(int) image->columns-1; x >= 0; x--) { *q++=ScaleQuantumToChar((Quantum) p->red); *q++=ScaleQuantumToChar((Quantum) p->green); *q++=ScaleQuantumToChar((Quantum) p->blue); *q++=0; p++; } } } else { register int k; register unsigned int bytes_per_pixel; unsigned char channel[sizeof(unsigned long)]; /* Convert to multi-byte continuous-tone X image. */ bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3); for (y=0; y < (int) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1, &image->exception); if (p == (PixelPacket *) NULL) break; for (x=0; x < (long) image->columns; x++) { pixel=XGammaPixel(map_info,p); for (k=0; k < (int) bytes_per_pixel; k++) { channel[k]=(unsigned char) pixel; pixel>>=8; } for (k=0; k < (int) bytes_per_pixel; k++) *q++=channel[k]; p++; } q+=scanline_pad; } } break; } } if (matte_image != (XImage *) NULL) { /* Initialize matte image. */ scanline_pad=(unsigned int) (matte_image->bytes_per_line- ((matte_image->width*matte_image->bits_per_pixel) >> 3)); q=(unsigned char *) matte_image->data; for (y=0; y < (int) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; bit=0; byte=0; for (x=(int) image->columns-1; x >= 0; x--) { byte>>=1; if (p->opacity == (Quantum) TransparentOpacity) byte|=0x80; bit++; if (bit == 8) { *q++=byte; bit=0; byte=0; } p++; } if (bit != 0) *q=byte >> (8-bit); q+=scanline_pad; } } } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + X M a k e I m a g e M S B F i r s t % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XMakeImageMSBFirst() initializes the pixel data of an X11 Image. The X % image pixels are copied in most-significant bit and byte first order. The % server's scanline pad is also respected. Rather than using one or two % general cases, many special cases are found here to help speed up the image % conversion. % % The format of the XMakeImageMSBFirst method is: % % XMakeImageMSBFirst(resource_info,window,image,ximage,matte_image) % % A description of each parameter follows: % % o resource_info: Specifies a pointer to a X11 XResourceInfo structure. % % o window: Specifies a pointer to a XWindowInfo structure. % % o image: The image. % % o ximage: Specifies a pointer to a XImage structure; returned from % XCreateImage. % % o matte_image: Specifies a pointer to a XImage structure; returned from % XCreateImage. % % */ static void XMakeImageMSBFirst(const XResourceInfo *resource_info, const XWindowInfo *window,Image *image,XImage *ximage,XImage *matte_image) { int y; register IndexPacket *indexes; register int x; register const PixelPacket *p; register unsigned char *q; unsigned char bit, byte; unsigned int scanline_pad; unsigned long pixel, *pixels; XStandardColormap *map_info; assert(resource_info != (XResourceInfo *) NULL); assert(window != (XWindowInfo *) NULL); assert(image != (Image *) NULL); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); scanline_pad=(unsigned int) (ximage->bytes_per_line- ((ximage->width*ximage->bits_per_pixel) >> 3)); map_info=window->map_info; pixels=window->pixel_info->pixels; q=(unsigned char *) ximage->data; x=0; if (ximage->format == XYBitmap) { register unsigned short polarity; unsigned char background, foreground; /* Convert image to big-endian bitmap. */ background=(unsigned char) (XPixelIntensity(&window->pixel_info->foreground_color) < XPixelIntensity(&window->pixel_info->background_color) ? 0x01 : 0x00); foreground=(unsigned char) (XPixelIntensity(&window->pixel_info->background_color) < XPixelIntensity(&window->pixel_info->foreground_color) ? 0x01 : 0x00); polarity=(unsigned short) ((PixelIntensityToQuantum( &image->colormap[0])) < ((Quantum) QuantumRange/2) ? 1 : 0); if (image->colors == 2) polarity=PixelIntensity(&image->colormap[0]) < PixelIntensity(&image->colormap[1]); for (y=0; y < (int) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetIndexes(image); bit=0; byte=0; for (x=(int) image->columns-1; x >= 0; x--) { byte<<=1; if (indexes[x] == (IndexPacket) polarity) byte|=foreground; else byte|=background; bit++; if (bit == 8) { *q++=byte; bit=0; byte=0; } } if (bit != 0) *q=byte << (8-bit); q+=scanline_pad; } } else if (window->pixel_info->colors != 0) switch (ximage->bits_per_pixel) { case 2: { register unsigned int nibble; /* Convert to 2 bit color-mapped X image. */ for (y=0; y < (int) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetIndexes(image); nibble=0; for (x=0; x < (int) image->columns; x++) { pixel=pixels[(long) indexes[x]] & 0xf; switch (nibble) { case 0: { *q=(unsigned char) (pixel << 6); nibble++; break; } case 1: { *q|=(unsigned char) (pixel << 4); nibble++; break; } case 2: { *q|=(unsigned char) (pixel << 2); nibble++; break; } case 3: { *q|=(unsigned char) pixel; q++; nibble=0; break; } } } q+=scanline_pad; } break; } case 4: { register unsigned int nibble; /* Convert to 4 bit color-mapped X image. */ for (y=0; y < (int) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetIndexes(image); nibble=0; for (x=0; x < (int) image->columns; x++) { pixel=pixels[(long) indexes[x]] & 0xf; switch (nibble) { case 0: { *q=(unsigned char) (pixel << 4); nibble++; break; } case 1: { *q|=(unsigned char) pixel; q++; nibble=0; break; } } } q+=scanline_pad; } break; } case 6: case 8: { /* Convert to 8 bit color-mapped X image. */ if (resource_info->color_recovery && resource_info->quantize_info->dither) { XDitherImage(image,ximage); break; } for (y=0; y < (int) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetIndexes(image); for (x=0; x < (int) image->columns; x++) { pixel=pixels[(long) indexes[x]]; *q++=(unsigned char) pixel; } q+=scanline_pad; } break; } default: { register int k; register unsigned int bytes_per_pixel; unsigned char channel[sizeof(unsigned long)]; /* Convert to 8 bit color-mapped X image. */ bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3); for (y=0; y < (int) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetIndexes(image); for (x=0; x < (int) image->columns; x++) { pixel=pixels[(long) indexes[x]]; for (k=(int) bytes_per_pixel-1; k >= 0; k--) { channel[k]=(unsigned char) pixel; pixel>>=8; } for (k=0; k < (int) bytes_per_pixel; k++) *q++=channel[k]; } q+=scanline_pad; } break; } } else switch (ximage->bits_per_pixel) { case 2: { register unsigned int nibble; /* Convert to 4 bit continuous-tone X image. */ for (y=0; y < (int) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; nibble=0; for (x=(int) image->columns-1; x >= 0; x--) { pixel=XGammaPixel(map_info,p); pixel&=0xf; switch (nibble) { case 0: { *q=(unsigned char) (pixel << 6); nibble++; break; } case 1: { *q|=(unsigned char) (pixel << 4); nibble++; break; } case 2: { *q|=(unsigned char) (pixel << 2); nibble++; break; } case 3: { *q|=(unsigned char) pixel; q++; nibble=0; break; } } p++; } q+=scanline_pad; } break; } case 4: { register unsigned int nibble; /* Convert to 4 bit continuous-tone X image. */ for (y=0; y < (int) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; nibble=0; for (x=(int) image->columns-1; x >= 0; x--) { pixel=XGammaPixel(map_info,p); pixel&=0xf; switch (nibble) { case 0: { *q=(unsigned char) (pixel << 4); nibble++; break; } case 1: { *q|=(unsigned char) pixel; q++; nibble=0; break; } } p++; } q+=scanline_pad; } break; } case 6: case 8: { /* Convert to 8 bit continuous-tone X image. */ if (resource_info->color_recovery && resource_info->quantize_info->dither) { XDitherImage(image,ximage); break; } for (y=0; y < (int) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; for (x=(int) image->columns-1; x >= 0; x--) { pixel=XGammaPixel(map_info,p); *q++=(unsigned char) pixel; p++; } q+=scanline_pad; } break; } default: { if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) && (map_info->green_max == 255) && (map_info->blue_max == 255) && (map_info->red_mult == 65536L) && (map_info->green_mult == 256) && (map_info->blue_mult == 1)) { /* Convert to 32 bit continuous-tone X image. */ for (y=0; y < (int) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1, &image->exception); if (p == (const PixelPacket *) NULL) break; if ((red_gamma != 1.0) || (green_gamma != 1.0) || (blue_gamma != 1.0)) { /* Gamma correct image. */ for (x=(int) image->columns-1; x >= 0; x--) { *q++=0; *q++=ScaleQuantumToChar(XRedGamma(p->red)); *q++=ScaleQuantumToChar(XGreenGamma(p->green)); *q++=ScaleQuantumToChar(XBlueGamma(p->blue)); p++; } continue; } for (x=(int) image->columns-1; x >= 0; x--) { *q++=0; *q++=ScaleQuantumToChar((Quantum) p->red); *q++=ScaleQuantumToChar((Quantum) p->green); *q++=ScaleQuantumToChar((Quantum) p->blue); p++; } } } else if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) && (map_info->green_max == 255) && (map_info->blue_max == 255) && (map_info->red_mult == 1) && (map_info->green_mult == 256) && (map_info->blue_mult == 65536L)) { /* Convert to 32 bit continuous-tone X image. */ for (y=0; y < (int) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1, &image->exception); if (p == (const PixelPacket *) NULL) break; if ((red_gamma != 1.0) || (green_gamma != 1.0) || (blue_gamma != 1.0)) { /* Gamma correct image. */ for (x=(int) image->columns-1; x >= 0; x--) { *q++=0; *q++=ScaleQuantumToChar(XBlueGamma(p->blue)); *q++=ScaleQuantumToChar(XGreenGamma(p->green)); *q++=ScaleQuantumToChar(XRedGamma(p->red)); p++; } continue; } for (x=(int) image->columns-1; x >= 0; x--) { *q++=0; *q++=ScaleQuantumToChar((Quantum) p->blue); *q++=ScaleQuantumToChar((Quantum) p->green); *q++=ScaleQuantumToChar((Quantum) p->red); p++; } } } else { register int k; register unsigned int bytes_per_pixel; unsigned char channel[sizeof(unsigned long)]; /* Convert to multi-byte continuous-tone X image. */ bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3); for (y=0; y < (int) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1, &image->exception); if (p == (const PixelPacket *) NULL) break; for (x=(int) image->columns-1; x >= 0; x--) { pixel=XGammaPixel(map_info,p); for (k=(int) bytes_per_pixel-1; k >= 0; k--) { channel[k]=(unsigned char) pixel; pixel>>=8; } for (k=0; k < (int) bytes_per_pixel; k++) *q++=channel[k]; p++; } q+=scanline_pad; } } break; } } if (matte_image != (XImage *) NULL) { /* Initialize matte image. */ scanline_pad=(unsigned int) (matte_image->bytes_per_line- ((matte_image->width*matte_image->bits_per_pixel) >> 3)); q=(unsigned char *) matte_image->data; for (y=0; y < (int) image->rows; y++) { p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; bit=0; byte=0; for (x=(int) image->columns-1; x >= 0; x--) { byte<<=1; if (p->opacity == (Quantum) TransparentOpacity) byte|=0x01; bit++; if (bit == 8) { *q++=byte; bit=0; byte=0; } p++; } if (bit != 0) *q=byte << (8-bit); q+=scanline_pad; } } } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X M a k e M a g n i f y I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XMakeMagnifyImage() magnifies a region of an X image and displays it. % % The format of the XMakeMagnifyImage method is: % % void XMakeMagnifyImage(display,windows) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o windows: Specifies a pointer to a XWindows structure. % */ MagickExport void XMakeMagnifyImage(Display *display,XWindows *windows) { char tuple[MaxTextExtent]; int y; long n; MagickPixelPacket pixel; register int x; register long i; register unsigned char *p, *q; static unsigned int previous_magnify = 0; static XWindowInfo magnify_window; unsigned int height, j, k, l, magnify, scanline_pad, width; XImage *ximage; /* Check boundary conditions. */ (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(display != (Display *) NULL); assert(windows != (XWindows *) NULL); magnify=1; for (n=1; n < (long) windows->magnify.data; n++) magnify<<=1; while ((magnify*windows->image.ximage->width) < windows->magnify.width) magnify<<=1; while ((magnify*windows->image.ximage->height) < windows->magnify.height) magnify<<=1; while (magnify > windows->magnify.width) magnify>>=1; while (magnify > windows->magnify.height) magnify>>=1; if (magnify != previous_magnify) { Status status; XTextProperty window_name; /* New magnify factor: update magnify window name. */ i=0; while ((1 << i) <= (int) magnify) i++; (void) FormatMagickString(windows->magnify.name,MaxTextExtent, "Magnify %luX",i); status=XStringListToTextProperty(&windows->magnify.name,1,&window_name); if (status != False) { XSetWMName(display,windows->magnify.id,&window_name); XSetWMIconName(display,windows->magnify.id,&window_name); (void) XFree((void *) window_name.value); } } previous_magnify=magnify; ximage=windows->image.ximage; width=(unsigned int) windows->magnify.ximage->width; height=(unsigned int) windows->magnify.ximage->height; if ((windows->magnify.x < 0) || (windows->magnify.x >= windows->image.ximage->width)) windows->magnify.x=windows->image.ximage->width >> 1; x=windows->magnify.x-((width/magnify) >> 1); if (x < 0) x=0; else if (x > (int) (ximage->width-(width/magnify))) x=ximage->width-width/magnify; if ((windows->magnify.y < 0) || (windows->magnify.y >= windows->image.ximage->height)) windows->magnify.y=windows->image.ximage->height >> 1; y=windows->magnify.y-((height/magnify) >> 1); if (y < 0) y=0; else if (y > (int) (ximage->height-(height/magnify))) y=ximage->height-height/magnify; q=(unsigned char *) windows->magnify.ximage->data; scanline_pad=(unsigned int) (windows->magnify.ximage->bytes_per_line- ((width*windows->magnify.ximage->bits_per_pixel) >> 3)); if (ximage->bits_per_pixel < 8) { register unsigned char background, byte, foreground, p_bit, q_bit; register unsigned int plane; XPixelInfo *pixel_info; pixel_info=windows->magnify.pixel_info; switch (ximage->bitmap_bit_order) { case LSBFirst: { /* Magnify little-endian bitmap. */ background=0x00; foreground=0x80; if (ximage->format == XYBitmap) { background=(unsigned char) (XPixelIntensity(&pixel_info->foreground_color) < XPixelIntensity(&pixel_info->background_color) ? 0x80 : 0x00); foreground=(unsigned char) (XPixelIntensity(&pixel_info->background_color) < XPixelIntensity(&pixel_info->foreground_color) ? 0x80 : 0x00); if (windows->magnify.depth > 1) Swap(background,foreground); } for (i=0; i < (long) height; i+=magnify) { /* Propogate pixel magnify rows. */ for (j=0; j < magnify; j++) { p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+ ((x*ximage->bits_per_pixel) >> 3); p_bit=(unsigned char) (x*ximage->bits_per_pixel) & 0x07; q_bit=0; byte=0; for (k=0; k < width; k+=magnify) { /* Propogate pixel magnify columns. */ for (l=0; l < magnify; l++) { /* Propogate each bit plane. */ for (plane=0; (int) plane < ximage->bits_per_pixel; plane++) { byte>>=1; if (*p & (0x01 << (p_bit+plane))) byte|=foreground; else byte|=background; q_bit++; if (q_bit == 8) { *q++=byte; q_bit=0; byte=0; } } } p_bit+=ximage->bits_per_pixel; if (p_bit == 8) { p++; p_bit=0; } if (q_bit != 0) *q=byte >> (8-q_bit); q+=scanline_pad; } } y++; } break; } case MSBFirst: default: { /* Magnify big-endian bitmap. */ background=0x00; foreground=0x01; if (ximage->format == XYBitmap) { background=(unsigned char) (XPixelIntensity(&pixel_info->foreground_color) < XPixelIntensity(&pixel_info->background_color) ? 0x01 : 0x00); foreground=(unsigned char) (XPixelIntensity(&pixel_info->background_color) < XPixelIntensity(&pixel_info->foreground_color) ? 0x01 : 0x00); if (windows->magnify.depth > 1) Swap(background,foreground); } for (i=0; i < (long) height; i+=magnify) { /* Propogate pixel magnify rows. */ for (j=0; j < magnify; j++) { p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+ ((x*ximage->bits_per_pixel) >> 3); p_bit=(unsigned char) (x*ximage->bits_per_pixel) & 0x07; q_bit=0; byte=0; for (k=0; k < width; k+=magnify) { /* Propogate pixel magnify columns. */ for (l=0; l < magnify; l++) { /* Propogate each bit plane. */ for (plane=0; (int) plane < ximage->bits_per_pixel; plane++) { byte<<=1; if (*p & (0x80 >> (p_bit+plane))) byte|=foreground; else byte|=background; q_bit++; if (q_bit == 8) { *q++=byte; q_bit=0; byte=0; } } } p_bit+=ximage->bits_per_pixel; if (p_bit == 8) { p++; p_bit=0; } if (q_bit != 0) *q=byte << (8-q_bit); q+=scanline_pad; } } y++; } break; } } } else switch (ximage->bits_per_pixel) { case 6: case 8: { /* Magnify 8 bit X image. */ for (i=0; i < (long) height; i+=magnify) { /* Propogate pixel magnify rows. */ for (j=0; j < magnify; j++) { p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+ ((x*ximage->bits_per_pixel) >> 3); for (k=0; k < width; k+=magnify) { /* Propogate pixel magnify columns. */ for (l=0; l < magnify; l++) *q++=(*p); p++; } q+=scanline_pad; } y++; } break; } default: { register unsigned int bytes_per_pixel, m; /* Magnify multi-byte X image. */ bytes_per_pixel=(unsigned int) ximage->bits_per_pixel >> 3; for (i=0; i < (long) height; i+=magnify) { /* Propogate pixel magnify rows. */ for (j=0; j < magnify; j++) { p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+ ((x*ximage->bits_per_pixel) >> 3); for (k=0; k < width; k+=magnify) { /* Propogate pixel magnify columns. */ for (l=0; l < magnify; l++) for (m=0; m < bytes_per_pixel; m++) *q++=(*(p+m)); p+=bytes_per_pixel; } q+=scanline_pad; } y++; } break; } } /* Copy X image to magnify pixmap. */ x=windows->magnify.x-((width/magnify) >> 1); if (x < 0) x=(int) ((width >> 1)-windows->magnify.x*magnify); else if (x > (int) (ximage->width-(width/magnify))) x=(int) ((ximage->width-windows->magnify.x)*magnify-(width >> 1)); else x=0; y=windows->magnify.y-((height/magnify) >> 1); if (y < 0) y=(int) ((height >> 1)-windows->magnify.y*magnify); else if (y > (int) (ximage->height-(height/magnify))) y=(int) ((ximage->height-windows->magnify.y)*magnify-(height >> 1)); else y=0; if ((x != 0) || (y != 0)) (void) XFillRectangle(display,windows->magnify.pixmap, windows->magnify.annotate_context,0,0,width,height); (void) XPutImage(display,windows->magnify.pixmap, windows->magnify.annotate_context,windows->magnify.ximage,0,0,x,y,width-x, height-y); if ((magnify > 1) && ((magnify <= (width >> 1)) && (magnify <= (height >> 1)))) { RectangleInfo highlight_info; /* Highlight center pixel. */ highlight_info.x=(long) windows->magnify.width >> 1; highlight_info.y=(long) windows->magnify.height >> 1; highlight_info.width=magnify; highlight_info.height=magnify; (void) XDrawRectangle(display,windows->magnify.pixmap, windows->magnify.highlight_context,(int) highlight_info.x, (int) highlight_info.y,(unsigned int) highlight_info.width-1, (unsigned int) highlight_info.height-1); if (magnify > 2) (void) XDrawRectangle(display,windows->magnify.pixmap, windows->magnify.annotate_context,(int) highlight_info.x+1, (int) highlight_info.y+1,(unsigned int) highlight_info.width-3, (unsigned int) highlight_info.height-3); } /* Show center pixel color. */ pixel=AcquireOneMagickPixel(windows->image.image,windows->magnify.x, windows->magnify.y,&windows->image.image->exception); (void) FormatMagickString(tuple,MaxTextExtent,"%d,%d: ", windows->magnify.x,windows->magnify.y); (void) ConcatenateMagickString(tuple,"(",MaxTextExtent); ConcatenateColorComponent(&pixel,RedChannel,X11Compliance,tuple); (void) ConcatenateMagickString(tuple,",",MaxTextExtent); ConcatenateColorComponent(&pixel,GreenChannel,X11Compliance,tuple); (void) ConcatenateMagickString(tuple,",",MaxTextExtent); ConcatenateColorComponent(&pixel,BlueChannel,X11Compliance,tuple); if (pixel.colorspace == CMYKColorspace) { (void) ConcatenateMagickString(tuple,",",MaxTextExtent); ConcatenateColorComponent(&pixel,IndexChannel,X11Compliance,tuple); } if (pixel.matte != MagickFalse) { (void) ConcatenateMagickString(tuple,",",MaxTextExtent); ConcatenateColorComponent(&pixel,OpacityChannel,X11Compliance,tuple); } (void) ConcatenateMagickString(tuple,")",MaxTextExtent); height=(unsigned int) windows->magnify.font_info->ascent+ windows->magnify.font_info->descent; x=windows->magnify.font_info->max_bounds.width >> 1; y=windows->magnify.font_info->ascent+(height >> 2); (void) XDrawImageString(display,windows->magnify.pixmap, windows->magnify.annotate_context,x,y,tuple,(int) strlen(tuple)); (void) QueryMagickColorname(windows->image.image,&pixel,SVGCompliance, MagickTrue,tuple,&windows->image.image->exception); y+=height; (void) XDrawImageString(display,windows->magnify.pixmap, windows->magnify.annotate_context,x,y,tuple,(int) strlen(tuple)); (void) QueryMagickColorname(windows->image.image,&pixel,SVGCompliance, MagickFalse,tuple,&windows->image.image->exception); y+=height; (void) XDrawImageString(display,windows->magnify.pixmap, windows->magnify.annotate_context,x,y,tuple,(int) strlen(tuple)); /* Refresh magnify window. */ magnify_window=windows->magnify; magnify_window.x=0; magnify_window.y=0; XRefreshWindow(display,&magnify_window,(XEvent *) NULL); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X M a k e P i x m a p % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XMakePixmap() creates an X11 pixmap. % % The format of the XMakePixmap method is: % % void XMakeStandardColormap(Display *display,XVisualInfo *visual_info, % XResourceInfo *resource_info,Image *image,XStandardColormap *map_info, % XPixelInfo *pixel) % % A description of each parameter follows: % % o resource_info: Specifies a pointer to a X11 XResourceInfo structure. % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o window: Specifies a pointer to a XWindowInfo structure. % % */ static MagickBooleanType XMakePixmap(Display *display, const XResourceInfo *resource_info,XWindowInfo *window) { unsigned int height, width; (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(display != (Display *) NULL); assert(resource_info != (XResourceInfo *) NULL); assert(window != (XWindowInfo *) NULL); if (window->pixmap != (Pixmap) NULL) { /* Destroy previous X pixmap. */ (void) XFreePixmap(display,window->pixmap); window->pixmap=(Pixmap) NULL; } if (window->use_pixmap == MagickFalse) return(MagickFalse); if (window->ximage == (XImage *) NULL) return(MagickFalse); /* Display busy cursor. */ (void) XCheckDefineCursor(display,window->id,window->busy_cursor); (void) XFlush(display); /* Create pixmap. */ width=(unsigned int) window->ximage->width; height=(unsigned int) window->ximage->height; window->pixmap=XCreatePixmap(display,window->id,width,height,window->depth); if (window->pixmap == (Pixmap) NULL) { /* Unable to allocate pixmap. */ (void) XCheckDefineCursor(display,window->id,window->cursor); return(MagickFalse); } /* Copy X image to pixmap. */ #if defined(HasSharedMemory) if (window->shared_memory) (void) XShmPutImage(display,window->pixmap,window->annotate_context, window->ximage,0,0,0,0,width,height,MagickTrue); #endif if (window->shared_memory == MagickFalse) (void) XPutImage(display,window->pixmap,window->annotate_context, window->ximage,0,0,0,0,width,height); if (IsEventLogging()) { (void) LogMagickEvent(X11Event,GetMagickModule(),"Pixmap:"); (void) LogMagickEvent(X11Event,GetMagickModule()," width, height: %ux%u", width,height); } /* Restore cursor. */ (void) XCheckDefineCursor(display,window->id,window->cursor); return(MagickTrue); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X M a k e S t a n d a r d C o l o r m a p % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XMakeStandardColormap() creates an X11 Standard Colormap. % % The format of the XMakeStandardColormap method is: % % XMakeStandardColormap(display,visual_info,resource_info,image, % map_info,pixel) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o visual_info: Specifies a pointer to a X11 XVisualInfo structure; % returned from XGetVisualInfo. % % o resource_info: Specifies a pointer to a X11 XResourceInfo structure. % % o image: The image. % % o map_info: If a Standard Colormap type is specified, this structure is % initialized with info from the Standard Colormap. % % o pixel: Specifies a pointer to a XPixelInfo structure. % % */ #if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif static inline MagickRealType DiversityPixelIntensity( const DiversityPacket *pixel) { MagickRealType intensity; intensity=0.299*pixel->red+0.587*pixel->green+0.114*pixel->blue; return(intensity); } static int IntensityCompare(const void *x,const void *y) { DiversityPacket *color_1, *color_2; int diversity; color_1=(DiversityPacket *) x; color_2=(DiversityPacket *) y; diversity=(int) (DiversityPixelIntensity(color_2)- DiversityPixelIntensity(color_1)); return(diversity); } static int PopularityCompare(const void *x,const void *y) { DiversityPacket *color_1, *color_2; color_1=(DiversityPacket *) x; color_2=(DiversityPacket *) y; return((int) color_2->count-(int) color_1->count); } #if defined(__cplusplus) || defined(c_plusplus) } #endif static inline Quantum ScaleXToQuantum(const unsigned long x, const unsigned long scale) { return((Quantum) (((MagickRealType) QuantumRange*x)/scale+0.5)); } MagickExport void XMakeStandardColormap(Display *display, XVisualInfo *visual_info,XResourceInfo *resource_info,Image *image, XStandardColormap *map_info,XPixelInfo *pixel) { Colormap colormap; register IndexPacket *indexes; register PixelPacket *q; register long i; Status status; unsigned long number_colors, retain_colors; unsigned short gray_value; XColor color, *colors, *p; (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(display != (Display *) NULL); assert(visual_info != (XVisualInfo *) NULL); assert(map_info != (XStandardColormap *) NULL); assert(resource_info != (XResourceInfo *) NULL); assert(pixel != (XPixelInfo *) NULL); if (resource_info->map_type != (char *) NULL) { /* Standard Colormap is already defined (i.e. xstdcmap). */ XGetPixelPacket(display,visual_info,map_info,resource_info,image, pixel); number_colors=(unsigned int) (map_info->base_pixel+ (map_info->red_max+1)*(map_info->green_max+1)*(map_info->blue_max+1)); if ((map_info->red_max*map_info->green_max*map_info->blue_max) != 0) if ((image->matte == MagickFalse) && (resource_info->color_recovery == MagickFalse) && resource_info->quantize_info->dither && (number_colors < MaxColormapSize)) { Image *map_image; /* Improve image appearance with error diffusion. */ map_image=AllocateImage((ImageInfo *) NULL); if (map_image == (Image *) NULL) ThrowXWindowFatalException(ResourceLimitFatalError, "UnableToDitherImage",image->filename); map_image->columns=number_colors; map_image->rows=1; /* Initialize colormap image. */ q=SetImagePixels(map_image,0,0,map_image->columns,1); if (q != (PixelPacket *) NULL) { for (i=0; i < (long) number_colors; i++) { q->red=(Quantum) 0; if (map_info->red_max != 0) q->red=ScaleXToQuantum(1UL*i/map_info->red_mult, map_info->red_max); q->green=(Quantum) 0; if (map_info->green_max != 0) q->green=ScaleXToQuantum((1UL*i/map_info->green_mult) % (map_info->green_max+1),map_info->green_max); q->blue=(Quantum) 0; if (map_info->blue_max != 0) q->blue=ScaleXToQuantum(1UL*i % map_info->green_mult, map_info->blue_max); q->opacity=(Quantum) TransparentOpacity; q++; } (void) SyncImagePixels(map_image); (void) MapImage(image,map_image,MagickTrue); } XGetPixelPacket(display,visual_info,map_info,resource_info,image, pixel); (void) SetImageStorageClass(image,DirectClass); map_image=DestroyImage(map_image); } if (IsEventLogging()) { (void) LogMagickEvent(X11Event,GetMagickModule(), "Standard Colormap:"); (void) LogMagickEvent(X11Event,GetMagickModule(), " colormap id: 0x%lx",map_info->colormap); (void) LogMagickEvent(X11Event,GetMagickModule(), " red, green, blue max: %lu %lu %lu",map_info->red_max, map_info->green_max,map_info->blue_max); (void) LogMagickEvent(X11Event,GetMagickModule(), " red, green, blue mult: %lu %lu %lu",map_info->red_mult, map_info->green_mult,map_info->blue_mult); } return; } if ((visual_info->klass != DirectColor) && (visual_info->klass != TrueColor)) if ((image->storage_class == DirectClass) || ((int) image->colors > visual_info->colormap_size)) { QuantizeInfo quantize_info; /* Image has more colors than the visual supports. */ quantize_info=(*resource_info->quantize_info); quantize_info.number_colors=(unsigned long) visual_info->colormap_size; (void) QuantizeImage(&quantize_info,image); } /* Free previous and create new colormap. */ (void) XFreeStandardColormap(display,visual_info,map_info,pixel); colormap=XDefaultColormap(display,visual_info->screen); if (visual_info->visual != XDefaultVisual(display,visual_info->screen)) colormap=XCreateColormap(display,XRootWindow(display,visual_info->screen), visual_info->visual,visual_info->klass == DirectColor ? AllocAll : AllocNone); if (colormap == (Colormap) NULL) ThrowXWindowFatalException(ResourceLimitFatalError,"UnableToCreateColormap", image->filename); /* Initialize the map and pixel info structures. */ XGetMapInfo(visual_info,colormap,map_info); XGetPixelPacket(display,visual_info,map_info,resource_info,image,pixel); /* Allocating colors in server colormap is based on visual class. */ switch (visual_info->klass) { case StaticGray: case StaticColor: { /* Define Standard Colormap for StaticGray or StaticColor visual. */ number_colors=image->colors; colors=(XColor *) AcquireQuantumMemory((size_t) visual_info->colormap_size,sizeof(*colors)); if (colors == (XColor *) NULL) ThrowXWindowFatalException(ResourceLimitFatalError, "UnableToCreateColormap",image->filename); p=colors; color.flags=(char) (DoRed | DoGreen | DoBlue); for (i=0; i < (long) image->colors; i++) { color.red=ScaleQuantumToShort(XRedGamma(image->colormap[i].red)); color.green=ScaleQuantumToShort(XGreenGamma(image->colormap[i].green)); color.blue=ScaleQuantumToShort(XBlueGamma(image->colormap[i].blue)); if (visual_info->klass != StaticColor) { gray_value=(unsigned short) XPixelIntensity(&color); color.red=gray_value; color.green=gray_value; color.blue=gray_value; } status=XAllocColor(display,colormap,&color); if (status == False) { colormap=XCopyColormapAndFree(display,colormap); (void) XAllocColor(display,colormap,&color); } pixel->pixels[i]=color.pixel; *p++=color; } break; } case GrayScale: case PseudoColor: { unsigned int colormap_type; /* Define Standard Colormap for GrayScale or PseudoColor visual. */ number_colors=image->colors; colors=(XColor *) AcquireQuantumMemory((size_t) visual_info->colormap_size,sizeof(*colors)); if (colors == (XColor *) NULL) ThrowXWindowFatalException(ResourceLimitFatalError, "UnableToCreateColormap",image->filename); /* Preallocate our GUI colors. */ (void) XAllocColor(display,colormap,&pixel->foreground_color); (void) XAllocColor(display,colormap,&pixel->background_color); (void) XAllocColor(display,colormap,&pixel->border_color); (void) XAllocColor(display,colormap,&pixel->matte_color); (void) XAllocColor(display,colormap,&pixel->highlight_color); (void) XAllocColor(display,colormap,&pixel->shadow_color); (void) XAllocColor(display,colormap,&pixel->depth_color); (void) XAllocColor(display,colormap,&pixel->trough_color); for (i=0; i < MaxNumberPens; i++) (void) XAllocColor(display,colormap,&pixel->pen_colors[i]); /* Determine if image colors will "fit" into X server colormap. */ colormap_type=resource_info->colormap; status=XAllocColorCells(display,colormap,MagickFalse,(unsigned long *) NULL,0,pixel->pixels,(unsigned int) image->colors); if (status != False) colormap_type=PrivateColormap; if (colormap_type == SharedColormap) { DiversityPacket *diversity; int y; register int x; unsigned short index; XColor *server_colors; /* Define Standard colormap for shared GrayScale or PseudoColor visual. */ diversity=(DiversityPacket *) AcquireQuantumMemory(image->colors, sizeof(*diversity)); if (diversity == (DiversityPacket *) NULL) ThrowXWindowFatalException(ResourceLimitFatalError, "UnableToCreateColormap",image->filename); for (i=0; i < (long) image->colors; i++) { diversity[i].red=image->colormap[i].red; diversity[i].green=image->colormap[i].green; diversity[i].blue=image->colormap[i].blue; diversity[i].index=(unsigned short) i; diversity[i].count=0; } for (y=0; y < (int) image->rows; y++) { q=GetImagePixels(image,0,y,image->columns,1); if (q == (PixelPacket *) NULL) break; indexes=GetIndexes(image); for (x=(int) image->columns-1; x >= 0; x--) diversity[(long) indexes[x]].count++; } /* Sort colors by decreasing intensity. */ qsort((void *) diversity,image->colors,sizeof(*diversity), IntensityCompare); for (i=0; i < (long) image->colors; ) { diversity[i].count<<=4; /* increase this colors popularity */ i+=MagickMax((long) (image->colors >> 4),2); } diversity[image->colors-1].count<<=4; qsort((void *) diversity,image->colors,sizeof(*diversity), PopularityCompare); /* Allocate colors. */ p=colors; color.flags=(char) (DoRed | DoGreen | DoBlue); for (i=0; i < (long) image->colors; i++) { index=diversity[i].index; color.red= ScaleQuantumToShort(XRedGamma(image->colormap[index].red)); color.green= ScaleQuantumToShort(XGreenGamma(image->colormap[index].green)); color.blue= ScaleQuantumToShort(XBlueGamma(image->colormap[index].blue)); if (visual_info->klass != PseudoColor) { gray_value=(unsigned short) XPixelIntensity(&color); color.red=gray_value; color.green=gray_value; color.blue=gray_value; } status=XAllocColor(display,colormap,&color); if (status == False) break; pixel->pixels[index]=color.pixel; *p++=color; } /* Read X server colormap. */ server_colors=(XColor *) AcquireQuantumMemory((size_t) visual_info->colormap_size,sizeof(*server_colors)); if (server_colors == (XColor *) NULL) ThrowXWindowFatalException(ResourceLimitFatalError, "UnableToCreateColormap",image->filename); for (x=visual_info->colormap_size-1; x >= 0; x--) server_colors[x].pixel=(unsigned long) x; (void) XQueryColors(display,colormap,server_colors, (int) MagickMin((unsigned int) visual_info->colormap_size,256)); /* Select remaining colors from X server colormap. */ for (; i < (long) image->colors; i++) { index=diversity[i].index; color.red= ScaleQuantumToShort(XRedGamma(image->colormap[index].red)); color.green= ScaleQuantumToShort(XGreenGamma(image->colormap[index].green)); color.blue= ScaleQuantumToShort(XBlueGamma(image->colormap[index].blue)); if (visual_info->klass != PseudoColor) { gray_value=(unsigned short) XPixelIntensity(&color); color.red=gray_value; color.green=gray_value; color.blue=gray_value; } XBestPixel(display,colormap,server_colors,(unsigned int) visual_info->colormap_size,&color); pixel->pixels[index]=color.pixel; *p++=color; } if ((int) image->colors < visual_info->colormap_size) { /* Fill up colors array-- more choices for pen colors. */ retain_colors=MagickMin((unsigned int) (visual_info->colormap_size-image->colors),256); for (i=0; i < (long) retain_colors; i++) *p++=server_colors[i]; number_colors+=retain_colors; } server_colors=(XColor *) RelinquishMagickMemory(server_colors); diversity=(DiversityPacket *) RelinquishMagickMemory(diversity); break; } /* Define Standard colormap for private GrayScale or PseudoColor visual. */ if (status == False) { /* Not enough colormap entries in the colormap-- Create a new colormap. */ colormap=XCreateColormap(display, XRootWindow(display,visual_info->screen),visual_info->visual, AllocNone); if (colormap == (Colormap) NULL) ThrowXWindowFatalException(ResourceLimitFatalError, "UnableToCreateColormap",image->filename); map_info->colormap=colormap; if ((int) image->colors < visual_info->colormap_size) { /* Retain colors from the default colormap to help lessens the effects of colormap flashing. */ retain_colors=MagickMin((unsigned int) (visual_info->colormap_size-image->colors),256); p=colors+image->colors; for (i=0; i < (long) retain_colors; i++) { p->pixel=(unsigned long) i; p++; } (void) XQueryColors(display, XDefaultColormap(display,visual_info->screen), colors+image->colors,(int) retain_colors); /* Transfer colors from default to private colormap. */ (void) XAllocColorCells(display,colormap,MagickFalse, (unsigned long *) NULL,0,pixel->pixels,(unsigned int) retain_colors); p=colors+image->colors; for (i=0; i < (long) retain_colors; i++) { p->pixel=pixel->pixels[i]; p++; } (void) XStoreColors(display,colormap,colors+image->colors, (int) retain_colors); number_colors+=retain_colors; } (void) XAllocColorCells(display,colormap,MagickFalse, (unsigned long *) NULL,0,pixel->pixels,(unsigned int) image->colors); } /* Store the image colormap. */ p=colors; color.flags=(char) (DoRed | DoGreen | DoBlue); for (i=0; i < (long) image->colors; i++) { color.red=ScaleQuantumToShort(XRedGamma(image->colormap[i].red)); color.green=ScaleQuantumToShort(XGreenGamma(image->colormap[i].green)); color.blue=ScaleQuantumToShort(XBlueGamma(image->colormap[i].blue)); if (visual_info->klass != PseudoColor) { gray_value=(unsigned short) XPixelIntensity(&color); color.red=gray_value; color.green=gray_value; color.blue=gray_value; } color.pixel=pixel->pixels[i]; *p++=color; } (void) XStoreColors(display,colormap,colors,(int) image->colors); break; } case TrueColor: case DirectColor: default: { MagickBooleanType linear_colormap; /* Define Standard Colormap for TrueColor or DirectColor visual. */ number_colors=(unsigned int) ((map_info->red_max*map_info->red_mult)+ (map_info->green_max*map_info->green_mult)+ (map_info->blue_max*map_info->blue_mult)+1); linear_colormap=(number_colors > 4096) || (((int) (map_info->red_max+1) == visual_info->colormap_size) && ((int) (map_info->green_max+1) == visual_info->colormap_size) && ((int) (map_info->blue_max+1) == visual_info->colormap_size)) ? MagickTrue : MagickFalse; if (linear_colormap != MagickFalse) number_colors=(unsigned long) visual_info->colormap_size; /* Allocate color array. */ colors=(XColor *) AcquireQuantumMemory(number_colors,sizeof(*colors)); if (colors == (XColor *) NULL) ThrowXWindowFatalException(ResourceLimitFatalError, "UnableToCreateColormap",image->filename); /* Initialize linear color ramp. */ p=colors; color.flags=(char) (DoRed | DoGreen | DoBlue); if (linear_colormap != MagickFalse) for (i=0; i < (long) number_colors; i++) { color.blue=(unsigned short) 0; if (map_info->blue_max != 0) color.blue=(unsigned short) ((unsigned long) ((65535L*(i % map_info->green_mult))/map_info->blue_max)); color.green=color.blue; color.red=color.blue; color.pixel=XStandardPixel(map_info,&color); *p++=color; } else for (i=0; i < (long) number_colors; i++) { color.red=(unsigned short) 0; if (map_info->red_max != 0) color.red=(unsigned short) ((unsigned long) ((65535L*(i/map_info->red_mult))/map_info->red_max)); color.green=(unsigned int) 0; if (map_info->green_max != 0) color.green=(unsigned short) ((unsigned long) ((65535L*((i/map_info->green_mult) % (map_info->green_max+1)))/ map_info->green_max)); color.blue=(unsigned short) 0; if (map_info->blue_max != 0) color.blue=(unsigned short) ((unsigned long) ((65535L*(i % map_info->green_mult))/map_info->blue_max)); color.pixel=XStandardPixel(map_info,&color); *p++=color; } if ((visual_info->klass == DirectColor) && (colormap != XDefaultColormap(display,visual_info->screen))) (void) XStoreColors(display,colormap,colors,(int) number_colors); else for (i=0; i < (long) number_colors; i++) (void) XAllocColor(display,colormap,&colors[i]); break; } } if ((visual_info->klass != DirectColor) && (visual_info->klass != TrueColor)) { /* Set foreground, background, border, etc. pixels. */ XBestPixel(display,colormap,colors,(unsigned int) number_colors, &pixel->foreground_color); XBestPixel(display,colormap,colors,(unsigned int) number_colors, &pixel->background_color); if (pixel->background_color.pixel == pixel->foreground_color.pixel) { /* Foreground and background colors must differ. */ pixel->background_color.red=(~pixel->foreground_color.red); pixel->background_color.green= (~pixel->foreground_color.green); pixel->background_color.blue= (~pixel->foreground_color.blue); XBestPixel(display,colormap,colors,(unsigned int) number_colors, &pixel->background_color); } XBestPixel(display,colormap,colors,(unsigned int) number_colors, &pixel->border_color); XBestPixel(display,colormap,colors,(unsigned int) number_colors, &pixel->matte_color); XBestPixel(display,colormap,colors,(unsigned int) number_colors, &pixel->highlight_color); XBestPixel(display,colormap,colors,(unsigned int) number_colors, &pixel->shadow_color); XBestPixel(display,colormap,colors,(unsigned int) number_colors, &pixel->depth_color); XBestPixel(display,colormap,colors,(unsigned int) number_colors, &pixel->trough_color); for (i=0; i < MaxNumberPens; i++) { XBestPixel(display,colormap,colors,(unsigned int) number_colors, &pixel->pen_colors[i]); pixel->pixels[image->colors+i]=pixel->pen_colors[i].pixel; } pixel->colors=image->colors+MaxNumberPens; } colors=(XColor *) RelinquishMagickMemory(colors); if (IsEventLogging()) { (void) LogMagickEvent(X11Event,GetMagickModule(),"Standard Colormap:"); (void) LogMagickEvent(X11Event,GetMagickModule()," colormap id: 0x%lx", map_info->colormap); (void) LogMagickEvent(X11Event,GetMagickModule(), " red, green, blue max: %lu %lu %lu",map_info->red_max, map_info->green_max,map_info->blue_max); (void) LogMagickEvent(X11Event,GetMagickModule(), " red, green, blue mult: %lu %lu %lu",map_info->red_mult, map_info->green_mult,map_info->blue_mult); } } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X M a k e W i n d o w % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XMakeWindow() creates an X11 window. % % The format of the XMakeWindow method is: % % void XMakeWindow(Display *display,Window parent,char **argv,int argc, % XClassHint *class_hint,XWMHints *manager_hints, % XWindowInfo *window_info) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o parent: Specifies the parent window_info. % % o argv: Specifies the application's argument list. % % o argc: Specifies the number of arguments. % % o class_hint: Specifies a pointer to a X11 XClassHint structure. % % o manager_hints: Specifies a pointer to a X11 XWMHints structure. % % o window_info: Specifies a pointer to a X11 XWindowInfo structure. % */ MagickExport void XMakeWindow(Display *display,Window parent,char **argv, int argc,XClassHint *class_hint,XWMHints *manager_hints, XWindowInfo *window_info) { #define MinWindowSize 64 Atom atom_list[2]; int gravity; static XTextProperty icon_name, window_name; Status status; XSizeHints *size_hints; /* Set window info hints. */ (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(display != (Display *) NULL); assert(window_info != (XWindowInfo *) NULL); size_hints=XAllocSizeHints(); if (size_hints == (XSizeHints *) NULL) ThrowXWindowFatalException(XServerFatalError,"UnableToMakeXWindow",argv[0]); size_hints->flags=(long) window_info->flags; size_hints->x=window_info->x; size_hints->y=window_info->y; size_hints->width=(int) window_info->width; size_hints->height=(int) window_info->height; if (window_info->immutable != MagickFalse) { /* Window size cannot be changed. */ size_hints->min_width=size_hints->width; size_hints->min_height=size_hints->height; size_hints->max_width=size_hints->width; size_hints->max_height=size_hints->height; size_hints->flags|=PMinSize; size_hints->flags|=PMaxSize; } else { /* Window size can be changed. */ size_hints->min_width=(int) window_info->min_width; size_hints->min_height=(int) window_info->min_height; size_hints->flags|=PResizeInc; size_hints->width_inc=(int) window_info->width_inc; size_hints->height_inc=(int) window_info->height_inc; #if !defined(PRE_R4_ICCCM) size_hints->flags|=PBaseSize; size_hints->base_width=size_hints->width_inc; size_hints->base_height=size_hints->height_inc; #endif } gravity=NorthWestGravity; if (window_info->geometry != (char *) NULL) { char default_geometry[MaxTextExtent], geometry[MaxTextExtent]; int flags; register char *p; /* User specified geometry. */ (void) FormatMagickString(default_geometry,MaxTextExtent,"%dx%d", size_hints->width,size_hints->height); (void) CopyMagickString(geometry,window_info->geometry,MaxTextExtent); p=geometry; while (strlen(p) != 0) { if ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '%')) p++; else (void) CopyMagickString(p,p+1,MaxTextExtent); } flags=XWMGeometry(display,window_info->screen,geometry,default_geometry, window_info->border_width,size_hints,&size_hints->x,&size_hints->y, &size_hints->width,&size_hints->height,&gravity); if ((flags & WidthValue) && (flags & HeightValue)) size_hints->flags|=USSize; if ((flags & XValue) && (flags & YValue)) { size_hints->flags|=USPosition; window_info->x=size_hints->x; window_info->y=size_hints->y; } } #if !defined(PRE_R4_ICCCM) size_hints->win_gravity=gravity; size_hints->flags|=PWinGravity; #endif if (window_info->id == (Window) NULL) window_info->id=XCreateWindow(display,parent,window_info->x,window_info->y, (unsigned int) size_hints->width,(unsigned int) size_hints->height, window_info->border_width,(int) window_info->depth,InputOutput, window_info->visual,window_info->mask,&window_info->attributes); else { MagickStatusType mask; XEvent sans_event; XWindowChanges window_changes; /* Window already exists; change relevant attributes. */ (void) XChangeWindowAttributes(display,window_info->id,window_info->mask, &window_info->attributes); mask=ConfigureNotify; while (XCheckTypedWindowEvent(display,window_info->id,(int) mask,&sans_event)); window_changes.x=window_info->x; window_changes.y=window_info->y; window_changes.width=(int) window_info->width; window_changes.height=(int) window_info->height; mask=(MagickStatusType) (CWWidth | CWHeight); if (window_info->flags & USPosition) mask|=CWX | CWY; (void) XReconfigureWMWindow(display,window_info->id,window_info->screen, mask,&window_changes); } if (window_info->id == (Window) NULL) ThrowXWindowFatalException(XServerFatalError,"UnableToCreateWindow", window_info->name); status=XStringListToTextProperty(&window_info->name,1,&window_name); if (status == False) ThrowXWindowFatalException(XServerFatalError,"UnableToCreateTextProperty", window_info->name); status=XStringListToTextProperty(&window_info->icon_name,1,&icon_name); if (status == False) ThrowXWindowFatalException(XServerFatalError,"UnableToCreateTextProperty", window_info->icon_name); if (window_info->icon_geometry != (char *) NULL) { int flags, height, width; /* User specified icon geometry. */ size_hints->flags|=USPosition; flags=XWMGeometry(display,window_info->screen,window_info->icon_geometry, (char *) NULL,0,size_hints,&manager_hints->icon_x, &manager_hints->icon_y,&width,&height,&gravity); if ((flags & XValue) && (flags & YValue)) manager_hints->flags|=IconPositionHint; } XSetWMProperties(display,window_info->id,&window_name,&icon_name,argv,argc, size_hints,manager_hints,class_hint); if (window_name.value != (void *) NULL) { (void) XFree((void *) window_name.value); window_name.value=(unsigned char *) NULL; window_name.nitems=0; } if (icon_name.value != (void *) NULL) { (void) XFree((void *) icon_name.value); icon_name.value=(unsigned char *) NULL; icon_name.nitems=0; } atom_list[0]=XInternAtom(display,"WM_DELETE_WINDOW",MagickFalse); atom_list[1]=XInternAtom(display,"WM_TAKE_FOCUS",MagickFalse); (void) XSetWMProtocols(display,window_info->id,atom_list,2); (void) XFree((void *) size_hints); if (window_info->shape != MagickFalse) { #if defined(HasShape) int error_base, event_base; /* Can we apply a non-rectangular shaping mask? */ error_base=0; event_base=0; if (XShapeQueryExtension(display,&error_base,&event_base) == 0) window_info->shape=MagickFalse; if (window_info->immutable == MagickFalse) window_info->shape=MagickFalse; #else window_info->shape=MagickFalse; #endif } if (window_info->shared_memory) { #if defined(HasSharedMemory) /* Can we we use shared memory with this window? */ if (XShmQueryExtension(display) == 0) window_info->shared_memory=MagickFalse; #else window_info->shared_memory=MagickFalse; #endif } window_info->image=NewImageList(); window_info->destroy=MagickFalse; } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X M a g i c k P r o g r e s s M o n i t o r % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XMagickProgressMonitor() displays the progress a task is making in % completing a task. % % The format of the XMagickProgressMonitor method is: % % void XMagickProgressMonitor(const char *task, % const MagickOffsetType quantum,const MagickSizeType span, % void *client_data) % % A description of each parameter follows: % % o task: Identifies the task in progress. % % o quantum: Specifies the quantum position within the span which represents % how much progress has been made in completing a task. % % o span: Specifies the span relative to completing a task. % % o client_data: Pointer to any client data. % */ static const char *GetLocaleMonitorMessage(const char *tag) { char message[MaxTextExtent]; const char *locale_message; (void) FormatMagickString(message,MaxTextExtent,"Monitor/%s",tag); locale_message=GetLocaleMessage(message); if (locale_message == message) return(tag); return(locale_message); } MagickExport MagickBooleanType XMagickProgressMonitor(const char *tag, const MagickOffsetType quantum,const MagickSizeType span, void *magick_unused(client_data)) { XWindows *windows; windows=XSetWindows((XWindows *) ~0); if (windows == (XWindows *) NULL) return(MagickTrue); if (windows->info.mapped != MagickFalse) XProgressMonitorWidget(windows->display,windows, GetLocaleMonitorMessage(tag),quantum,span); return(MagickTrue); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X Q u e r y C o l o r D a t a b a s e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XQueryColorDatabase() looks up a RGB values for a color given in the target % string. % % The format of the XQueryColorDatabase method is: % % MagickBooleanType XQueryColorDatabase(const char *target,XColor *color) % % A description of each parameter follows: % % o target: Specifies the color to lookup in the X color database. % % o color: A pointer to an PixelPacket structure. The RGB value of the target % color is returned as this value. % */ MagickExport MagickBooleanType XQueryColorDatabase(const char *target, XColor *color) { Colormap colormap; static Display *display = (Display *) NULL; Status status; XColor xcolor; /* Initialize color return value. */ assert(color != (XColor *) NULL); color->red=0; color->green=0; color->blue=0; color->flags=(char) (DoRed | DoGreen | DoBlue); if ((target == (char *) NULL) || (*target == '\0')) target="#ffffffffffff"; /* Let the X server define the color for us. */ if (display == (Display *) NULL) display=XOpenDisplay((char *) NULL); if (display == (Display *) NULL) { ThrowXWindowFatalException(XServerError,"ColorIsNotKnownToServer",target); return(MagickFalse); } colormap=XDefaultColormap(display,XDefaultScreen(display)); status=XParseColor(display,colormap,(char *) target,&xcolor); if (status == False) ThrowXWindowFatalException(XServerError,"ColorIsNotKnownToServer",target) else { color->red=xcolor.red; color->green=xcolor.green; color->blue=xcolor.blue; color->flags=xcolor.flags; } return(status != False ? MagickTrue : MagickFalse); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X Q u e r y P o s i t i o n % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XQueryPosition() gets the pointer coordinates relative to a window. % % The format of the XQueryPosition method is: % % void XQueryPosition(Display *display,const Window window,int *x,int *y) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o window: Specifies a pointer to a Window. % % o x: Return the x coordinate of the pointer relative to the origin of the % window. % % o y: Return the y coordinate of the pointer relative to the origin of the % window. % */ MagickExport void XQueryPosition(Display *display,const Window window,int *x,int *y) { int x_root, y_root; unsigned int mask; Window root_window; (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(display != (Display *) NULL); assert(window != (Window) NULL); assert(x != (int *) NULL); assert(y != (int *) NULL); (void) XQueryPointer(display,window,&root_window,&root_window,&x_root,&y_root, x,y,&mask); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X R e f r e s h W i n d o w % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XRefreshWindow() refreshes an image in a X window. % % The format of the XRefreshWindow method is: % % void XRefreshWindow(Display *display,const XWindowInfo *window, % const XEvent *event) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o window: Specifies a pointer to a XWindowInfo structure. % % o event: Specifies a pointer to a XEvent structure. If it is NULL, % the entire image is refreshed. % */ MagickExport void XRefreshWindow(Display *display,const XWindowInfo *window, const XEvent *event) { int x, y; unsigned int height, width; (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(display != (Display *) NULL); assert(window != (XWindowInfo *) NULL); if (window->ximage == (XImage *) NULL) return; if (event != (XEvent *) NULL) { /* Determine geometry from expose event. */ x=event->xexpose.x; y=event->xexpose.y; width=(unsigned int) event->xexpose.width; height=(unsigned int) event->xexpose.height; } else { XEvent sans_event; /* Refresh entire window; discard outstanding expose events. */ x=0; y=0; width=window->width; height=window->height; while (XCheckTypedWindowEvent(display,window->id,Expose,&sans_event)); } /* Check boundary conditions. */ if ((window->ximage->width-(x+window->x)) < (int) width) width=(unsigned int) (window->ximage->width-(x+window->x)); if ((window->ximage->height-(y+window->y)) < (int) height) height=(unsigned int) (window->ximage->height-(y+window->y)); /* Refresh image. */ if (window->matte_pixmap != (Pixmap) NULL) (void) XSetClipMask(display,window->annotate_context,window->matte_pixmap); if (window->pixmap != (Pixmap) NULL) { if (window->depth > 1) (void) XCopyArea(display,window->pixmap,window->id, window->annotate_context,x+window->x,y+window->y,width,height,x,y); else (void) XCopyPlane(display,window->pixmap,window->id, window->highlight_context,x+window->x,y+window->y,width,height,x,y, 1L); } else { #if defined(HasSharedMemory) if (window->shared_memory) (void) XShmPutImage(display,window->id,window->annotate_context, window->ximage,x+window->x,y+window->y,x,y,width,height,MagickTrue); #endif if (window->shared_memory == MagickFalse) (void) XPutImage(display,window->id,window->annotate_context, window->ximage,x+window->x,y+window->y,x,y,width,height); } if (window->matte_pixmap != (Pixmap) NULL) (void) XSetClipMask(display,window->annotate_context,None); (void) XFlush(display); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X R e m o t e C o m m a n d % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XRemoteCommand() forces a remote display(1) to display the specified % image filename. % % The format of the XRemoteCommand method is: % % MagickBooleanType XRemoteCommand(Display *display,const char *window, % const char *filename) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o window: Specifies the name or id of an X window. % % o filename: The name of the image filename to display. % */ MagickExport MagickBooleanType XRemoteCommand(Display *display, const char *window,const char *filename) { Atom remote_atom; Window remote_window, root_window; assert(filename != (char *) NULL); (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename); if (display == (Display *) NULL) display=XOpenDisplay((char *) NULL); if (display == (Display *) NULL) { ThrowXWindowException(XServerError,"UnableToOpenXServer",filename); return(MagickFalse); } remote_atom=XInternAtom(display,"IM_PROTOCOLS",MagickFalse); remote_window=(Window) NULL; root_window=XRootWindow(display,XDefaultScreen(display)); if (window != (char *) NULL) { /* Search window hierarchy and identify any clients by name or ID. */ if (isdigit((unsigned char) *window) != 0) remote_window=XWindowByID(display,root_window,(Window) strtol((char *) window,(char **) NULL,0)); if (remote_window == (Window) NULL) remote_window=XWindowByName(display,root_window,window); } if (remote_window == (Window) NULL) remote_window=XWindowByProperty(display,root_window,remote_atom); if (remote_window == (Window) NULL) { ThrowXWindowException(XServerError,"UnableToConnectToRemoteDisplay", filename); return(MagickFalse); } /* Send remote command. */ remote_atom=XInternAtom(display,"IM_REMOTE_COMMAND",MagickFalse); (void) XChangeProperty(display,remote_window,remote_atom,XA_STRING,8, PropModeReplace,(unsigned char *) filename,(int) strlen(filename)); (void) XSync(display,MagickFalse); return(MagickTrue); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X R e t a i n W i n d o w C o l o r s % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XRetainWindowColors() sets X11 color resources on a window. This preserves % the colors associated with an image displayed on the window. % % The format of the XRetainWindowColors method is: % % void XRetainWindowColors(Display *display,const Window window) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o window: Specifies a pointer to a XWindowInfo structure. % */ MagickExport void XRetainWindowColors(Display *display,const Window window) { Atom property; Pixmap pixmap; /* Put property on the window. */ (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(display != (Display *) NULL); assert(window != (Window) NULL); property=XInternAtom(display,"_XSETROOT_ID",MagickFalse); if (property == (Atom) NULL) { ThrowXWindowFatalException(XServerError,"UnableToCreateProperty", "_XSETROOT_ID"); return; } pixmap=XCreatePixmap(display,window,1,1,1); if (pixmap == (Pixmap) NULL) { ThrowXWindowFatalException(XServerError,"UnableToCreateBitmap",""); return; } (void) XChangeProperty(display,window,property,XA_PIXMAP,32,PropModeReplace, (unsigned char *) &pixmap,1); (void) XSetCloseDownMode(display,RetainPermanent); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X S e l e c t W i n d o w % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XSelectWindow() allows a user to select a window using the mouse. If the % mouse moves, a cropping rectangle is drawn and the extents of the rectangle % is returned in the crop_info structure. % % The format of the XSelectWindow function is: % % target_window=XSelectWindow(display,crop_info) % % A description of each parameter follows: % % o window: XSelectWindow returns the window id. % % o display: Specifies a pointer to the Display structure; returned from % XOpenDisplay. % % o crop_info: Specifies a pointer to a RectangleInfo structure. It % contains the extents of any cropping rectangle. % % */ static Window XSelectWindow(Display *display,RectangleInfo *crop_info) { #define MinimumCropArea (unsigned int) 9 Cursor target_cursor; GC annotate_context; int presses, x_offset, y_offset; Status status; Window root_window, target_window; XEvent event; XGCValues context_values; /* Initialize graphic context. */ (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(display != (Display *) NULL); assert(crop_info != (RectangleInfo *) NULL); root_window=XRootWindow(display,XDefaultScreen(display)); context_values.background=XBlackPixel(display,XDefaultScreen(display)); context_values.foreground=XWhitePixel(display,XDefaultScreen(display)); context_values.function=GXinvert; context_values.plane_mask= context_values.background ^ context_values.foreground; context_values.subwindow_mode=IncludeInferiors; annotate_context=XCreateGC(display,root_window,(unsigned long) (GCBackground | GCForeground | GCFunction | GCSubwindowMode),&context_values); if (annotate_context == (GC) NULL) return(MagickFalse); /* Grab the pointer using target cursor. */ target_cursor=XMakeCursor(display,root_window,XDefaultColormap(display, XDefaultScreen(display)),(char * ) "white",(char * ) "black"); status=XGrabPointer(display,root_window,MagickFalse,(unsigned int) (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask),GrabModeSync, GrabModeAsync,root_window,target_cursor,CurrentTime); if (status != GrabSuccess) { ThrowXWindowFatalException(XServerError,"UnableToGrabMouse",""); return((Window) NULL); } /* Select a window. */ crop_info->width=0; crop_info->height=0; presses=0; target_window=(Window) NULL; x_offset=0; y_offset=0; do { if ((crop_info->width*crop_info->height) >= MinimumCropArea) (void) XDrawRectangle(display,root_window,annotate_context, (int) crop_info->x,(int) crop_info->y,(unsigned int) crop_info->width-1, (unsigned int) crop_info->height-1); /* Allow another event. */ (void) XAllowEvents(display,SyncPointer,CurrentTime); (void) XWindowEvent(display,root_window,ButtonPressMask | ButtonReleaseMask | ButtonMotionMask,&event); if ((crop_info->width*crop_info->height) >= MinimumCropArea) (void) XDrawRectangle(display,root_window,annotate_context, (int) crop_info->x,(int) crop_info->y,(unsigned int) crop_info->width-1, (unsigned int) crop_info->height-1); switch (event.type) { case ButtonPress: { target_window=XGetSubwindow(display,event.xbutton.subwindow, event.xbutton.x,event.xbutton.y); if (target_window == (Window) NULL) target_window=root_window; x_offset=event.xbutton.x_root; y_offset=event.xbutton.y_root; crop_info->x=x_offset; crop_info->y=y_offset; crop_info->width=0; crop_info->height=0; presses++; break; } case ButtonRelease: { presses--; break; } case MotionNotify: { /* Discard pending button motion events. */ while (XCheckMaskEvent(display,ButtonMotionMask,&event)); crop_info->x=event.xmotion.x; crop_info->y=event.xmotion.y; /* Check boundary conditions. */ if ((int) crop_info->x < x_offset) crop_info->width=(unsigned int) (x_offset-crop_info->x); else { crop_info->width=(unsigned int) (crop_info->x-x_offset); crop_info->x=x_offset; } if ((int) crop_info->y < y_offset) crop_info->height=(unsigned int) (y_offset-crop_info->y); else { crop_info->height=(unsigned int) (crop_info->y-y_offset); crop_info->y=y_offset; } } default: break; } } while ((target_window == (Window) NULL) || (presses > 0)); (void) XUngrabPointer(display,CurrentTime); (void) XFreeCursor(display,target_cursor); (void) XFreeGC(display,annotate_context); if ((crop_info->width*crop_info->height) < MinimumCropArea) { crop_info->width=0; crop_info->height=0; } if ((crop_info->width != 0) && (crop_info->height != 0)) target_window=root_window; return(target_window); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X S e t C u r s o r S t a t e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XSetCursorState() sets the cursor state to busy, otherwise the cursor are % reset to their default. % % The format of the XXSetCursorState method is: % % XSetCursorState(display,windows,const MagickStatusType state) % % A description of each parameter follows: % % o display: Specifies a connection to an X server; returned from % XOpenDisplay. % % o windows: Specifies a pointer to a XWindows structure. % % o state: An unsigned integer greater than 0 sets the cursor state % to busy, otherwise the cursor are reset to their default. % */ MagickExport void XSetCursorState(Display *display,XWindows *windows, const MagickStatusType state) { (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(display != (Display *) NULL); assert(windows != (XWindows *) NULL); if (state) { (void) XCheckDefineCursor(display,windows->image.id, windows->image.busy_cursor); (void) XCheckDefineCursor(display,windows->pan.id, windows->pan.busy_cursor); (void) XCheckDefineCursor(display,windows->magnify.id, windows->magnify.busy_cursor); (void) XCheckDefineCursor(display,windows->command.id, windows->command.busy_cursor); } else { (void) XCheckDefineCursor(display,windows->image.id, windows->image.cursor); (void) XCheckDefineCursor(display,windows->pan.id,windows->pan.cursor); (void) XCheckDefineCursor(display,windows->magnify.id, windows->magnify.cursor); (void) XCheckDefineCursor(display,windows->command.id, windows->command.cursor); (void) XCheckDefineCursor(display,windows->command.id, windows->widget.cursor); (void) XWithdrawWindow(display,windows->info.id,windows->info.screen); } windows->info.mapped=MagickFalse; } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X S e t W i n d o w s % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XSetWindows() sets the X windows structure if the windows info is specified. % Otherwise the current windows structure is returned. % % The format of the XSetWindows method is: % % XWindows *XSetWindows(XWindows *windows_info) % % A description of each parameter follows: % % o windows_info: Initialize the Windows structure with this information. % */ MagickExport XWindows *XSetWindows(XWindows *windows_info) { static XWindows *windows = (XWindows *) NULL; if (windows_info != (XWindows *) ~0) { windows=(XWindows *) RelinquishMagickMemory(windows); windows=windows_info; } return(windows); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X U s e r P r e f e r e n c e s % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XUserPreferences() saves the preferences in a configuration file in the % users' home directory. % % The format of the XUserPreferences method is: % % void XUserPreferences(XResourceInfo *resource_info) % % A description of each parameter follows: % % o resource_info: Specifies a pointer to a X11 XResourceInfo structure. % */ MagickExport void XUserPreferences(XResourceInfo *resource_info) { #if defined(PreferencesDefaults) char cache[MaxTextExtent], filename[MaxTextExtent], specifier[MaxTextExtent]; const char *value; XrmDatabase preferences_database; /* Save user preferences to the client configuration file. */ assert(resource_info != (XResourceInfo *) NULL); preferences_database=XrmGetStringDatabase(""); (void) FormatMagickString(specifier,MaxTextExtent,"%s.backdrop", GetClientName()); value=resource_info->backdrop ? "True" : "False"; XrmPutStringResource(&preferences_database,specifier,(char *) value); (void) FormatMagickString(specifier,MaxTextExtent,"%s.colormap", GetClientName()); value=resource_info->colormap == SharedColormap ? "Shared" : "Private"; XrmPutStringResource(&preferences_database,specifier,(char *) value); (void) FormatMagickString(specifier,MaxTextExtent,"%s.confirmExit", GetClientName()); value=resource_info->confirm_exit ? "True" : "False"; XrmPutStringResource(&preferences_database,specifier,(char *) value); (void) FormatMagickString(specifier,MaxTextExtent,"%s.confirmEdit", GetClientName()); value=resource_info->confirm_edit ? "True" : "False"; XrmPutStringResource(&preferences_database,specifier,(char *) value); (void) FormatMagickString(specifier,MaxTextExtent,"%s.displayWarnings", GetClientName()); value=resource_info->display_warnings ? "True" : "False"; XrmPutStringResource(&preferences_database,specifier,(char *) value); (void) FormatMagickString(specifier,MaxTextExtent,"%s.dither", GetClientName()); value=resource_info->quantize_info->dither ? "True" : "False"; XrmPutStringResource(&preferences_database,specifier,(char *) value); (void) FormatMagickString(specifier,MaxTextExtent,"%s.gammaCorrect", GetClientName()); value=resource_info->gamma_correct ? "True" : "False"; XrmPutStringResource(&preferences_database,specifier,(char *) value); (void) FormatMagickString(specifier,MaxTextExtent,"%s.undoCache", GetClientName()); (void) FormatMagickString(cache,MaxTextExtent,"%lu", resource_info->undo_cache); XrmPutStringResource(&preferences_database,specifier,cache); (void) FormatMagickString(specifier,MaxTextExtent,"%s.usePixmap", GetClientName()); value=resource_info->use_pixmap ? "True" : "False"; XrmPutStringResource(&preferences_database,specifier,(char *) value); (void) FormatMagickString(filename,MaxTextExtent,"%s%src", PreferencesDefaults,GetClientName()); ExpandFilename(filename); XrmPutFileDatabase(preferences_database,filename); #endif } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X V i s u a l C l a s s N a m e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XVisualClassName() returns the visual class name as a character string. % % The format of the XVisualClassName method is: % % char *XVisualClassName(const int visual_class) % % A description of each parameter follows: % % o visual_type: XVisualClassName returns the visual class as a character % string. % % o class: Specifies the visual class. % % */ static const char *XVisualClassName(const int visual_class) { switch (visual_class) { case StaticGray: return("StaticGray"); case GrayScale: return("GrayScale"); case StaticColor: return("StaticColor"); case PseudoColor: return("PseudoColor"); case TrueColor: return("TrueColor"); case DirectColor: return("DirectColor"); } return("unknown visual class"); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X W a r n i n g % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XWarning() displays a warning reason in a Notice widget. % % The format of the XWarning method is: % % void XWarning(const unsigned int warning,const char *reason, % const char *description) % % A description of each parameter follows: % % o warning: Specifies the numeric warning category. % % o reason: Specifies the reason to display before terminating the % program. % % o description: Specifies any description to the reason. % */ MagickExport void XWarning(const ExceptionType magick_unused(warning), const char *reason,const char *description) { char text[MaxTextExtent]; XWindows *windows; if (reason == (char *) NULL) return; (void) CopyMagickString(text,reason,MaxTextExtent); (void) ConcatenateMagickString(text,":",MaxTextExtent); windows=XSetWindows((XWindows *) ~0); XNoticeWidget(windows->display,windows,text,(char *) description); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X W i n d o w B y I D % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XWindowByID() locates a child window with a given ID. If not window with % the given name is found, 0 is returned. Only the window specified and its % subwindows are searched. % % The format of the XWindowByID function is: % % child=XWindowByID(display,window,id) % % A description of each parameter follows: % % o child: XWindowByID returns the window with the specified % id. If no windows are found, XWindowByID returns 0. % % o display: Specifies a pointer to the Display structure; returned from % XOpenDisplay. % % o id: Specifies the id of the window to locate. % */ MagickExport Window XWindowByID(Display *display,const Window root_window, const unsigned long id) { RectangleInfo rectangle_info; register int i; Status status; unsigned int number_children; Window child, *children, window; (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(display != (Display *) NULL); assert(root_window != (Window) NULL); if (id == 0) return(XSelectWindow(display,&rectangle_info)); if (root_window == id) return(id); status=XQueryTree(display,root_window,&child,&child,&children, &number_children); if (status == False) return((Window) NULL); window=(Window) NULL; for (i=0; i < (int) number_children; i++) { /* Search each child and their children. */ window=XWindowByID(display,children[i],id); if (window != (Window) NULL) break; } if (children != (Window *) NULL) (void) XFree((void *) children); return(window); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X W i n d o w B y N a m e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XWindowByName() locates a window with a given name on a display. If no % window with the given name is found, 0 is returned. If more than one window % has the given name, the first one is returned. Only root and its children % are searched. % % The format of the XWindowByName function is: % % window=XWindowByName(display,root_window,name) % % A description of each parameter follows: % % o window: XWindowByName returns the window id. % % o display: Specifies a pointer to the Display structure; returned from % XOpenDisplay. % % o root_window: Specifies the id of the root window. % % o name: Specifies the name of the window to locate. % */ MagickExport Window XWindowByName(Display *display,const Window root_window, const char *name) { register int i; Status status; unsigned int number_children; Window *children, child, window; XTextProperty window_name; assert(display != (Display *) NULL); assert(root_window != (Window) NULL); assert(name != (char *) NULL); (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name); if (XGetWMName(display,root_window,&window_name) != 0) if (LocaleCompare((char *) window_name.value,name) == 0) return(root_window); status=XQueryTree(display,root_window,&child,&child,&children, &number_children); if (status == False) return((Window) NULL); window=(Window) NULL; for (i=0; i < (int) number_children; i++) { /* Search each child and their children. */ window=XWindowByName(display,children[i],name); if (window != (Window) NULL) break; } if (children != (Window *) NULL) (void) XFree((void *) children); return(window); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X W i n d o w B y P r o p e r y % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XWindowByProperty() locates a child window with a given property. If not % window with the given name is found, 0 is returned. If more than one window % has the given property, the first one is returned. Only the window % specified and its subwindows are searched. % % The format of the XWindowByProperty function is: % % child=XWindowByProperty(display,window,property) % % A description of each parameter follows: % % o child: XWindowByProperty returns the window id with the specified % property. If no windows are found, XWindowByProperty returns 0. % % o display: Specifies a pointer to the Display structure; returned from % XOpenDisplay. % % o property: Specifies the property of the window to locate. % */ MagickExport Window XWindowByProperty(Display *display,const Window window, const Atom property) { Atom type; int format; Status status; unsigned char *data; unsigned int i, number_children; unsigned long after, number_items; Window child, *children, parent, root; (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(display != (Display *) NULL); assert(window != (Window) NULL); assert(property != (Atom) NULL); status=XQueryTree(display,window,&root,&parent,&children,&number_children); if (status == False) return((Window) NULL); type=(Atom) NULL; child=(Window) NULL; for (i=0; (i < number_children) && (child == (Window) NULL); i++) { status=XGetWindowProperty(display,children[i],property,0L,0L,MagickFalse, (Atom) AnyPropertyType,&type,&format,&number_items,&after,&data); if (data != NULL) (void) XFree((void *) data); if ((status == Success) && (type != (Atom) NULL)) child=children[i]; } for (i=0; (i < number_children) && (child == (Window) NULL); i++) child=XWindowByProperty(display,children[i],property); if (children != (Window *) NULL) (void) XFree((void *) children); return(child); } #else /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X I m p o r t I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XImportImage() reads an image from an X window. % % The format of the XImportImage method is: % % Image *XImportImage(const ImageInfo *image_info,XImportInfo *ximage_info) % % A description of each parameter follows: % % o image_info: The image info.. % % o ximage_info: Specifies a pointer to an XImportInfo structure. % */ MagickExport Image *XImportImage(const ImageInfo *image_info, XImportInfo *ximage_info) { assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(ximage_info != (XImportInfo *) NULL); return((Image *) NULL); } #endif /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % X G e t I m p o r t I n f o % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % XGetImportInfo() initializes the XImportInfo structure. % % The format of the XGetImportInfo method is: % % void XGetImportInfo(XImportInfo *ximage_info) % % A description of each parameter follows: % % o ximage_info: Specifies a pointer to an ImageInfo structure. % */ MagickExport void XGetImportInfo(XImportInfo *ximage_info) { assert(ximage_info != (XImportInfo *) NULL); ximage_info->frame=MagickFalse; ximage_info->borders=MagickFalse; ximage_info->screen=MagickFalse; ximage_info->descend=MagickTrue; ximage_info->silent=MagickFalse; }