forked from openkylin/imagemagick
9917 lines
332 KiB
C
9917 lines
332 KiB
C
/*
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
% %
|
||
% %
|
||
% %
|
||
% 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 %
|
||
% %
|
||
% %
|
||
% MagickCore X11 Utility Methods %
|
||
% %
|
||
% Software Design %
|
||
% Cristy %
|
||
% July 1992 %
|
||
% %
|
||
% %
|
||
% Copyright 1999-2021 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 %
|
||
% %
|
||
% https://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/artifact.h"
|
||
#include "magick/blob.h"
|
||
#include "magick/cache.h"
|
||
#include "magick/client.h"
|
||
#include "magick/color.h"
|
||
#include "magick/color-private.h"
|
||
#include "magick/colormap.h"
|
||
#include "magick/composite.h"
|
||
#include "magick/display.h"
|
||
#include "magick/distort.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/memory-private.h"
|
||
#include "magick/monitor.h"
|
||
#include "magick/nt-base-private.h"
|
||
#include "magick/option.h"
|
||
#include "magick/quantize.h"
|
||
#include "magick/quantum.h"
|
||
#include "magick/quantum-private.h"
|
||
#include "magick/resource_.h"
|
||
#include "magick/resize.h"
|
||
#include "magick/statistic.h"
|
||
#include "magick/string_.h"
|
||
#include "magick/string-private.h"
|
||
#include "magick/token.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 <OS.h>
|
||
#endif
|
||
#if defined(MAGICKCORE_X11_DELEGATE)
|
||
#include <X11/Xproto.h>
|
||
#include <X11/Xlocale.h>
|
||
#if defined(MAGICK_HAVE_POLL)
|
||
# include <sys/poll.h>
|
||
#endif
|
||
#if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
|
||
#if defined(MAGICKCORE_HAVE_MACHINE_PARAM_H)
|
||
# include <machine/param.h>
|
||
#endif
|
||
#include <sys/ipc.h>
|
||
#include <sys/shm.h>
|
||
#include <X11/extensions/XShm.h>
|
||
#endif
|
||
#if defined(MAGICKCORE_HAVE_SHAPE)
|
||
#include <X11/extensions/shape.h>
|
||
#endif
|
||
|
||
/*
|
||
X defines.
|
||
*/
|
||
#define XBlueGamma(color) ClampToQuantum(blue_gamma == 1.0 ? (double) \
|
||
(color) : ((pow(((double) QuantumScale*(color)),1.0/(double) blue_gamma)* \
|
||
QuantumRange)))
|
||
#define XGammaPixel(map,color) (size_t) (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) ClampToQuantum(green_gamma == 1.0 ? (double) \
|
||
(color) : ((pow(((double) QuantumScale*(color)),1.0/(double) green_gamma)* \
|
||
QuantumRange)))
|
||
#define XRedGamma(color) ClampToQuantum(red_gamma == 1.0 ? (double) \
|
||
(color) : ((pow(((double) QuantumScale*(color)),1.0/(double) red_gamma)* \
|
||
QuantumRange)))
|
||
#define XStandardPixel(map,color) (size_t) (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;
|
||
|
||
size_t
|
||
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)
|
||
{
|
||
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);
|
||
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]->matte_image != (XImage *) NULL)
|
||
{
|
||
XDestroyImage(magick_windows[i]->matte_image);
|
||
magick_windows[i]->matte_image=(XImage *) 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(MAGICKCORE_HAVE_SHARED_MEMORY)
|
||
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)
|
||
{
|
||
if (windows->class_hints->res_name != (char *) NULL)
|
||
windows->class_hints->res_name=DestroyString(
|
||
windows->class_hints->res_name);
|
||
if (windows->class_hints->res_class != (char *) NULL)
|
||
windows->class_hints->res_class=DestroyString(
|
||
windows->class_hints->res_class);
|
||
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)
|
||
{
|
||
CacheView
|
||
*annotate_view;
|
||
|
||
GC
|
||
annotate_context;
|
||
|
||
ExceptionInfo
|
||
*exception;
|
||
|
||
Image
|
||
*annotate_image;
|
||
|
||
int
|
||
x,
|
||
y;
|
||
|
||
MagickBooleanType
|
||
matte;
|
||
|
||
Pixmap
|
||
annotate_pixmap;
|
||
|
||
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=(size_t) (~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=AcquireImage((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);
|
||
(void) GetOneVirtualPixel(image,(ssize_t) x,(ssize_t) y,
|
||
&annotate_image->background_color,&image->exception);
|
||
if (annotate_info->stencil == ForegroundStencil)
|
||
annotate_image->matte=MagickTrue;
|
||
exception=(&image->exception);
|
||
annotate_view=AcquireAuthenticCacheView(annotate_image,exception);
|
||
for (y=0; y < (int) annotate_image->rows; y++)
|
||
{
|
||
int
|
||
x;
|
||
|
||
PixelPacket
|
||
*magick_restrict q;
|
||
|
||
q=GetCacheViewAuthenticPixels(annotate_view,0,(ssize_t) y,
|
||
annotate_image->columns,1,exception);
|
||
if (q == (PixelPacket *) NULL)
|
||
break;
|
||
for (x=0; x < (int) annotate_image->columns; x++)
|
||
{
|
||
SetPixelOpacity(q,OpaqueOpacity);
|
||
if (XGetPixel(annotate_ximage,x,y) == 0)
|
||
{
|
||
/*
|
||
Set this pixel to the background color.
|
||
*/
|
||
SetPixelRed(q,ScaleShortToQuantum(pixel->box_color.red));
|
||
SetPixelGreen(q,ScaleShortToQuantum(pixel->box_color.green));
|
||
SetPixelBlue(q,ScaleShortToQuantum(pixel->box_color.blue));
|
||
if ((annotate_info->stencil == ForegroundStencil) ||
|
||
(annotate_info->stencil == OpaqueStencil))
|
||
SetPixelOpacity(q,TransparentOpacity);
|
||
}
|
||
else
|
||
{
|
||
/*
|
||
Set this pixel to the pen color.
|
||
*/
|
||
SetPixelRed(q,ScaleShortToQuantum(pixel->pen_color.red));
|
||
SetPixelGreen(q,ScaleShortToQuantum(pixel->pen_color.green));
|
||
SetPixelBlue(q,ScaleShortToQuantum(pixel->pen_color.blue));
|
||
if (annotate_info->stencil == BackgroundStencil)
|
||
SetPixelOpacity(q,TransparentOpacity);
|
||
}
|
||
q++;
|
||
}
|
||
if (SyncCacheViewAuthenticPixels(annotate_view,exception) == MagickFalse)
|
||
break;
|
||
}
|
||
annotate_view=DestroyCacheView(annotate_view);
|
||
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) FormatLocaleString(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,(ssize_t) x,(ssize_t) 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;
|
||
|
||
char
|
||
*p,
|
||
*q;
|
||
|
||
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);
|
||
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);
|
||
(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;
|
||
|
||
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;
|
||
|
||
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)
|
||
ThrowXWindowException(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);
|
||
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;
|
||
|
||
MagickRealType
|
||
distance;
|
||
|
||
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","...");
|
||
for (i=0; i < (int) number_colors; i++)
|
||
colors[i].pixel=(size_t) 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.
|
||
%
|
||
*/
|
||
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 long) visual_info->colormap_size),1UL << visual_info->depth)
|
||
|
||
char
|
||
*map_type,
|
||
*visual_type;
|
||
|
||
int
|
||
visual_mask;
|
||
|
||
int
|
||
i;
|
||
|
||
size_t
|
||
one;
|
||
|
||
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));
|
||
one=1;
|
||
if ((resource_info->immutable != MagickFalse) && (resource_info->colors != 0))
|
||
if (resource_info->colors <= (one << (size_t) 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
|
||
ThrowXWindowException(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.
|
||
*/
|
||
ThrowXWindowException(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);
|
||
ThrowXWindowException(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.
|
||
*/
|
||
map_list=(XStandardColormap *) NULL;
|
||
root_window=XRootWindow(display,XDefaultScreen(display));
|
||
status=False;
|
||
number_maps=0;
|
||
if (LocaleCompare(map_type,"list") != 0)
|
||
{
|
||
/*
|
||
User specified Standard Colormap.
|
||
*/
|
||
(void) FormatLocaleString((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);
|
||
/*
|
||
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);
|
||
#endif
|
||
if (map_info->colormap == (Colormap) NULL)
|
||
ThrowXWindowFatalException(XServerError,
|
||
"StandardColormapIsNotInitialized",map_type);
|
||
(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 areassociated 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);
|
||
(void) memset(&client_event,0,sizeof(client_event));
|
||
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 m p o n e n t T e r m i n u s %
|
||
% %
|
||
% %
|
||
% %
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
%
|
||
% XComponentTerminus() destroys the module component.
|
||
%
|
||
% The format of the XComponentTerminus method is:
|
||
%
|
||
% XComponentTerminus(void)
|
||
%
|
||
*/
|
||
MagickExport void XComponentTerminus(void)
|
||
{
|
||
DestroyXResources();
|
||
}
|
||
|
||
/*
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
% %
|
||
% %
|
||
% %
|
||
% 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 size_t 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 size_t milliseconds)
|
||
{
|
||
assert(display != (Display *) NULL);
|
||
(void) XFlush(display);
|
||
MagickDelay(milliseconds);
|
||
}
|
||
|
||
/*
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
% %
|
||
% %
|
||
% %
|
||
% 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->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) memset(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");
|
||
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;
|
||
|
||
ssize_t
|
||
i;
|
||
|
||
size_t
|
||
number_pixels;
|
||
|
||
ssize_t
|
||
bytes;
|
||
|
||
unsigned int
|
||
levels;
|
||
|
||
/*
|
||
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) FormatLocaleFile(file,"Display\n gamma: %s\n\n",
|
||
resource_info->display_gamma);
|
||
/*
|
||
Write info about the X image to a file.
|
||
*/
|
||
(void) FormatLocaleFile(file,"X\n visual: %s\n",
|
||
XVisualClassName((int) windows->image.storage_class));
|
||
(void) FormatLocaleFile(file," depth: %d\n",windows->image.ximage->depth);
|
||
if (windows->visual_info->colormap_size != 0)
|
||
(void) FormatLocaleFile(file," colormap size: %d\n",
|
||
windows->visual_info->colormap_size);
|
||
if (resource_info->colormap== SharedColormap)
|
||
(void) FormatLocaleFile(file," colormap type: Shared\n");
|
||
else
|
||
(void) FormatLocaleFile(file," colormap type: Private\n");
|
||
(void) FormatLocaleFile(file," geometry: %dx%d\n",
|
||
windows->image.ximage->width,windows->image.ximage->height);
|
||
if (windows->image.crop_geometry != (char *) NULL)
|
||
(void) FormatLocaleFile(file," crop geometry: %s\n",
|
||
windows->image.crop_geometry);
|
||
if (windows->image.pixmap == (Pixmap) NULL)
|
||
(void) FormatLocaleFile(file," type: X Image\n");
|
||
else
|
||
(void) FormatLocaleFile(file," type: Pixmap\n");
|
||
if (windows->image.shape != MagickFalse)
|
||
(void) FormatLocaleFile(file," non-rectangular shape: True\n");
|
||
else
|
||
(void) FormatLocaleFile(file," non-rectangular shape: False\n");
|
||
if (windows->image.shared_memory != MagickFalse)
|
||
(void) FormatLocaleFile(file," shared memory: True\n");
|
||
else
|
||
(void) FormatLocaleFile(file," shared memory: False\n");
|
||
(void) FormatLocaleFile(file,"\n");
|
||
if (resource_info->font != (char *) NULL)
|
||
(void) FormatLocaleFile(file,"Font: %s\n\n",resource_info->font);
|
||
if (resource_info->text_font != (char *) NULL)
|
||
(void) FormatLocaleFile(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) FormatLocaleFile(file,"Undo Edit Cache\n levels: %u\n",levels);
|
||
(void) FormatLocaleFile(file," bytes: %.20gmb\n",(double)
|
||
((bytes+(1 << 19)) >> 20));
|
||
(void) FormatLocaleFile(file," limit: %.20gmb\n\n",(double)
|
||
resource_info->undo_cache);
|
||
/*
|
||
Write info about the image to a file.
|
||
*/
|
||
(void) IdentifyImage(image,file,MagickTrue);
|
||
(void) fclose(file);
|
||
text=FileToString(filename,~0UL,&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) FormatLocaleString(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}
|
||
};
|
||
|
||
CacheView
|
||
*image_view;
|
||
|
||
int
|
||
value,
|
||
y;
|
||
|
||
PixelPacket
|
||
color;
|
||
|
||
char
|
||
*q;
|
||
|
||
const PixelPacket
|
||
*p;
|
||
|
||
int
|
||
i,
|
||
j,
|
||
x;
|
||
|
||
unsigned int
|
||
scanline_pad;
|
||
|
||
size_t
|
||
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 *) AcquireCriticalMemory(256UL*
|
||
sizeof(*red_map));
|
||
green_map[i][j]=(unsigned char *) AcquireCriticalMemory(256UL*
|
||
sizeof(*green_map));
|
||
blue_map[i][j]=(unsigned char *) AcquireCriticalMemory(256UL*
|
||
sizeof(*blue_map));
|
||
}
|
||
/*
|
||
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+=((size_t) 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-
|
||
((size_t) (ximage->width*ximage->bits_per_pixel) >> 3));
|
||
i=0;
|
||
j=0;
|
||
q=ximage->data;
|
||
image_view=AcquireVirtualCacheView(image,&image->exception);
|
||
for (y=0; y < (int) image->rows; y++)
|
||
{
|
||
p=GetCacheViewVirtualPixels(image_view,0,(ssize_t) y,image->columns,1,
|
||
&image->exception);
|
||
if (p == (const PixelPacket *) NULL)
|
||
break;
|
||
for (x=0; x < (int) image->columns; x++)
|
||
{
|
||
color.red=ClampToQuantum((MagickRealType) (red_map[i][j][(int)
|
||
ScaleQuantumToChar(GetPixelRed(p))] << 8));
|
||
color.green=ClampToQuantum((MagickRealType) (green_map[i][j][(int)
|
||
ScaleQuantumToChar(GetPixelGreen(p))] << 8));
|
||
color.blue=ClampToQuantum((MagickRealType) (blue_map[i][j][(int)
|
||
ScaleQuantumToChar(GetPixelBlue(p))] << 8));
|
||
pixel=(size_t) (((size_t) color.red & 0xe0) |
|
||
(((size_t) color.green & 0xe0) >> 3) |
|
||
(((size_t) color.blue & 0xc0) >> 6));
|
||
*q++=(char) pixel;
|
||
p++;
|
||
j++;
|
||
if (j == 16)
|
||
j=0;
|
||
}
|
||
q+=scanline_pad;
|
||
i++;
|
||
if (i == 2)
|
||
i=0;
|
||
}
|
||
image_view=DestroyCacheView(image_view);
|
||
/*
|
||
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)
|
||
{
|
||
CacheView
|
||
*draw_view;
|
||
|
||
ExceptionInfo
|
||
*exception;
|
||
|
||
GC
|
||
draw_context;
|
||
|
||
Image
|
||
*draw_image;
|
||
|
||
int
|
||
x,
|
||
y;
|
||
|
||
MagickBooleanType
|
||
matte;
|
||
|
||
Pixmap
|
||
draw_pixmap;
|
||
|
||
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=(size_t) (~0);
|
||
context_values.foreground=0;
|
||
context_values.line_width=(int) draw_info->line_width;
|
||
draw_context=XCreateGC(display,root_window,(size_t)
|
||
(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,(size_t) (~0));
|
||
if (draw_info->stipple != (Pixmap) NULL)
|
||
{
|
||
(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=AcquireImage((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);
|
||
(void) GetOneVirtualPixel(image,(ssize_t) x,(ssize_t) y,
|
||
&draw_image->background_color,&image->exception);
|
||
if (SetImageStorageClass(draw_image,DirectClass) == MagickFalse)
|
||
return(MagickFalse);
|
||
draw_image->matte=MagickTrue;
|
||
exception=(&image->exception);
|
||
draw_view=AcquireAuthenticCacheView(draw_image,exception);
|
||
for (y=0; y < (int) draw_image->rows; y++)
|
||
{
|
||
int
|
||
x;
|
||
|
||
PixelPacket
|
||
*magick_restrict q;
|
||
|
||
q=QueueCacheViewAuthenticPixels(draw_view,0,(ssize_t) y,draw_image->columns,
|
||
1,exception);
|
||
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.
|
||
*/
|
||
SetPixelRed(q,ScaleShortToQuantum(pixel->pen_color.red));
|
||
SetPixelGreen(q,ScaleShortToQuantum(pixel->pen_color.green));
|
||
SetPixelBlue(q,ScaleShortToQuantum(pixel->pen_color.blue));
|
||
SetPixelOpacity(q,(Quantum) (draw_info->stencil ==
|
||
OpaqueStencil ? OpaqueOpacity : TransparentOpacity));
|
||
}
|
||
q++;
|
||
}
|
||
if (SyncCacheViewAuthenticPixels(draw_view,exception) == MagickFalse)
|
||
break;
|
||
}
|
||
draw_view=DestroyCacheView(draw_view);
|
||
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) FormatLocaleString(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.
|
||
*/
|
||
draw_view=AcquireAuthenticCacheView(draw_image,exception);
|
||
for (y=0; y < (int) draw_image->rows; y++)
|
||
{
|
||
int
|
||
x;
|
||
|
||
PixelPacket
|
||
*magick_restrict q;
|
||
|
||
q=GetCacheViewAuthenticPixels(draw_view,0,(ssize_t) y,draw_image->columns,1,
|
||
exception);
|
||
if (q == (PixelPacket *) NULL)
|
||
break;
|
||
for (x=0; x < (int) draw_image->columns; x++)
|
||
{
|
||
if (q->opacity != (Quantum) TransparentOpacity)
|
||
SetPixelOpacity(q,OpaqueOpacity);
|
||
q++;
|
||
}
|
||
if (SyncCacheViewAuthenticPixels(draw_view,exception) == MagickFalse)
|
||
break;
|
||
}
|
||
draw_view=DestroyCacheView(draw_view);
|
||
(void) XParseGeometry(draw_info->geometry,&x,&y,&width,&height);
|
||
if (draw_info->stencil == TransparentStencil)
|
||
(void) CompositeImage(image,CopyOpacityCompositeOp,draw_image,(ssize_t) x,
|
||
(ssize_t) y);
|
||
else
|
||
{
|
||
matte=image->matte;
|
||
(void) CompositeImage(image,OverCompositeOp,draw_image,(ssize_t) x,
|
||
(ssize_t) 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);
|
||
(void) display;
|
||
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);
|
||
font_info=(XFontStruct *) NULL;
|
||
}
|
||
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=(size_t) (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=(size_t) (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=(size_t) (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;
|
||
|
||
ssize_t
|
||
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=(ssize_t) 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)
|
||
ThrowXWindowException(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)
|
||
ThrowXWindowException(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)
|
||
ThrowXWindowException(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)
|
||
ThrowXWindowException(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) (((MagickRealType)
|
||
pixel->matte_color.red*ScaleQuantumToShort(HighlightModulate))/65535L+
|
||
(ScaleQuantumToShort((Quantum) (QuantumRange-HighlightModulate))));
|
||
pixel->highlight_color.green=(unsigned short) (((MagickRealType)
|
||
pixel->matte_color.green*ScaleQuantumToShort(HighlightModulate))/65535L+
|
||
(ScaleQuantumToShort((Quantum) (QuantumRange-HighlightModulate))));
|
||
pixel->highlight_color.blue=(unsigned short) (((MagickRealType)
|
||
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)
|
||
ThrowXWindowException(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 < (ssize_t) 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) FormatLocaleString(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) FormatLocaleString(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;
|
||
|
||
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.
|
||
*/
|
||
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(X11_APPLICATION_PATH)
|
||
(void) FormatLocaleString(filename,MaxTextExtent,"%s%c%s",
|
||
X11_APPLICATION_PATH,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(X11_PREFERENCES_PATH)
|
||
(void) FormatLocaleString(filename,MaxTextExtent,"%s%src",
|
||
X11_PREFERENCES_PATH,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(image_info,) initializes the ResourceInfo structure.
|
||
%
|
||
% The format of the XGetResourceInfo method is:
|
||
%
|
||
% void XGetResourceInfo(const ImageInfo *image_info,XrmDatabase database,
|
||
% const char *client_name,XResourceInfo *resource_info)
|
||
%
|
||
% A description of each parameter follows:
|
||
%
|
||
% o image_info: the image info.
|
||
%
|
||
% 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(const ImageInfo *image_info,
|
||
XrmDatabase database,const char *client_name,XResourceInfo *resource_info)
|
||
{
|
||
char
|
||
*directory,
|
||
*resource_value;
|
||
|
||
/*
|
||
Initialize resource info fields.
|
||
*/
|
||
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
|
||
assert(resource_info != (XResourceInfo *) NULL);
|
||
(void) memset(resource_info,0,sizeof(*resource_info));
|
||
resource_info->resource_database=database;
|
||
resource_info->image_info=(ImageInfo *) image_info;
|
||
(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) StringToUnsignedLong(
|
||
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)
|
||
ThrowXWindowException(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) StringToUnsignedLong(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 *) "False");
|
||
resource_info->gamma_correct=IsMagickTrue(resource_value);
|
||
resource_info->image_geometry=ConstantString(XGetResourceClass(database,
|
||
client_name,"geometry",(char *) NULL));
|
||
resource_value=XGetResourceClass(database,client_name,"gravity",
|
||
(char *) "Center");
|
||
resource_info->gravity=(GravityType) ParseCommandOption(MagickGravityOptions,
|
||
MagickFalse,resource_value);
|
||
directory=getcwd(resource_info->home_directory,MaxTextExtent);
|
||
(void) directory;
|
||
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) StringToUnsignedLong(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=ConstantString(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) StringToUnsignedLong(resource_value);
|
||
resource_value=XGetResourceClass(database,client_name,"quantum",(char *) "1");
|
||
resource_info->quantum=StringToLong(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 *) "256");
|
||
resource_info->undo_cache=(unsigned int) StringToUnsignedLong(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) FormatLocaleString(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) FormatLocaleString(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 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;
|
||
|
||
IndexPacket
|
||
*indexes;
|
||
|
||
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=(ssize_t) x_offset;
|
||
crop_info.y=(ssize_t) y_offset;
|
||
crop_info.width=(size_t) window_attributes.width;
|
||
crop_info.height=(size_t) window_attributes.height;
|
||
if (borders != MagickFalse)
|
||
{
|
||
/*
|
||
Include border in image.
|
||
*/
|
||
crop_info.x-=(ssize_t) window_attributes.border_width;
|
||
crop_info.y-=(ssize_t) window_attributes.border_width;
|
||
crop_info.width+=(size_t) (window_attributes.border_width << 1);
|
||
crop_info.height+=(size_t) (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=(size_t) (display_width-crop_info.x);
|
||
display_height=XDisplayHeight(display,XDefaultScreen(display));
|
||
if ((int) (crop_info.y+crop_info.height) > display_height)
|
||
crop_info.height=(size_t) (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","...");
|
||
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.x2 > window_info[i].bounds.x2) ||
|
||
(window_info[id].bounds.y1 < window_info[i].bounds.y1) ||
|
||
(window_info[id].bounds.y2 > 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)
|
||
{
|
||
CacheView
|
||
*composite_view;
|
||
|
||
ColormapInfo
|
||
*next;
|
||
|
||
ExceptionInfo
|
||
*exception;
|
||
|
||
Image
|
||
*composite_image,
|
||
*image;
|
||
|
||
int
|
||
y;
|
||
|
||
MagickBooleanType
|
||
import;
|
||
|
||
int
|
||
j,
|
||
x;
|
||
|
||
PixelPacket
|
||
*magick_restrict q;
|
||
|
||
size_t
|
||
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))
|
||
{
|
||
if ((window_info[id].bounds.x1 >= window_info[j].bounds.x1) &&
|
||
(window_info[id].bounds.x2 <= window_info[j].bounds.x2) &&
|
||
(window_info[id].bounds.y1 >= window_info[j].bounds.y1) &&
|
||
(window_info[id].bounds.y2 <= window_info[j].bounds.y2))
|
||
import=MagickFalse;
|
||
}
|
||
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=(size_t) i;
|
||
colors[i].pad='\0';
|
||
}
|
||
else
|
||
{
|
||
size_t
|
||
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=(unsigned long) (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=AcquireImage((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=(size_t) ximage->width;
|
||
composite_image->rows=(size_t) ximage->height;
|
||
exception=(&composite_image->exception);
|
||
composite_view=AcquireAuthenticCacheView(composite_image,exception);
|
||
switch (composite_image->storage_class)
|
||
{
|
||
case DirectClass:
|
||
default:
|
||
{
|
||
size_t
|
||
color,
|
||
index;
|
||
|
||
size_t
|
||
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=QueueCacheViewAuthenticPixels(composite_view,0,(ssize_t) y,
|
||
composite_image->columns,1,exception);
|
||
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;
|
||
SetPixelRed(q,ScaleShortToQuantum(
|
||
colors[index].red));
|
||
index=(pixel >> green_shift) & green_mask;
|
||
SetPixelGreen(q,ScaleShortToQuantum(
|
||
colors[index].green));
|
||
index=(pixel >> blue_shift) & blue_mask;
|
||
SetPixelBlue(q,ScaleShortToQuantum(
|
||
colors[index].blue));
|
||
q++;
|
||
}
|
||
if (SyncCacheViewAuthenticPixels(composite_view,exception) == MagickFalse)
|
||
break;
|
||
}
|
||
else
|
||
for (y=0; y < (int) composite_image->rows; y++)
|
||
{
|
||
q=QueueCacheViewAuthenticPixels(composite_view,0,(ssize_t) y,
|
||
composite_image->columns,1,exception);
|
||
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;
|
||
if (red_mask != 0)
|
||
color=(65535UL*color)/red_mask;
|
||
SetPixelRed(q,ScaleShortToQuantum((unsigned short)
|
||
color));
|
||
color=(pixel >> green_shift) & green_mask;
|
||
if (green_mask != 0)
|
||
color=(65535UL*color)/green_mask;
|
||
SetPixelGreen(q,ScaleShortToQuantum((unsigned short)
|
||
color));
|
||
color=(pixel >> blue_shift) & blue_mask;
|
||
if (blue_mask != 0)
|
||
color=(65535UL*color)/blue_mask;
|
||
SetPixelBlue(q,ScaleShortToQuantum((unsigned short)
|
||
color));
|
||
q++;
|
||
}
|
||
if (SyncCacheViewAuthenticPixels(composite_view,exception) == MagickFalse)
|
||
break;
|
||
}
|
||
break;
|
||
}
|
||
case PseudoClass:
|
||
{
|
||
/*
|
||
Create colormap.
|
||
*/
|
||
if (AcquireImageColormap(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=QueueCacheViewAuthenticPixels(composite_view,0,(ssize_t) y,
|
||
composite_image->columns,1,exception);
|
||
if (q == (PixelPacket *) NULL)
|
||
break;
|
||
indexes=GetCacheViewAuthenticIndexQueue(composite_view);
|
||
for (x=0; x < (int) composite_image->columns; x++)
|
||
{
|
||
index=(IndexPacket) XGetPixel(ximage,x,y);
|
||
SetPixelIndex(indexes+x,index);
|
||
SetPixelRGBO(q,composite_image->colormap+(ssize_t)
|
||
index);
|
||
q++;
|
||
}
|
||
if (SyncCacheViewAuthenticPixels(composite_view,exception) == MagickFalse)
|
||
break;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
composite_view=DestroyCacheView(composite_view);
|
||
XDestroyImage(ximage);
|
||
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,(ssize_t)
|
||
x_offset,(ssize_t) y_offset);
|
||
composite_image=DestroyImage(composite_image);
|
||
}
|
||
/*
|
||
Relinquish 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;
|
||
}
|
||
/*
|
||
Relinquish 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);
|
||
if (window->name == (char *) NULL)
|
||
window->name=AcquireString("");
|
||
if (window->icon_name == (char *) NULL)
|
||
window->icon_name=AcquireString("");
|
||
}
|
||
else
|
||
{
|
||
/*
|
||
Initialize these attributes just once.
|
||
*/
|
||
window->id=(Window) NULL;
|
||
if (window->name == (char *) NULL)
|
||
window->name=AcquireString("");
|
||
if (window->icon_name == (char *) NULL)
|
||
window->icon_name=AcquireString("");
|
||
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(MAGICKCORE_HAVE_SHARED_MEMORY)
|
||
{
|
||
XShmSegmentInfo
|
||
*segment_info;
|
||
|
||
if (window->segment_info == (void *) NULL)
|
||
window->segment_info=AcquireCriticalMemory(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=(size_t) 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=(int) (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 == MagickCoreSignature);
|
||
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));
|
||
/*
|
||
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 != '\0')
|
||
{
|
||
if (LocaleCompare(image_info->filename,"root") == 0)
|
||
target=root;
|
||
else
|
||
{
|
||
/*
|
||
Select window by ID or name.
|
||
*/
|
||
if (isdigit((int) ((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)
|
||
ThrowXWindowException(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)
|
||
ThrowXWindowException(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;
|
||
}
|
||
}
|
||
if (ximage_info->screen != MagickFalse)
|
||
{
|
||
int
|
||
y;
|
||
|
||
Window
|
||
child;
|
||
|
||
XWindowAttributes
|
||
window_attributes;
|
||
|
||
/*
|
||
Obtain window image directly from screen.
|
||
*/
|
||
status=XGetWindowAttributes(display,target,&window_attributes);
|
||
if (status == False)
|
||
{
|
||
(void) XCloseDisplay(display);
|
||
ThrowXWindowFatalException(XServerError,
|
||
"UnableToReadXWindowAttributes",image_info->filename);
|
||
}
|
||
(void) XTranslateCoordinates(display,target,root,0,0,&x,&y,&child);
|
||
crop_info.x=(ssize_t) x;
|
||
crop_info.y=(ssize_t) y;
|
||
crop_info.width=(size_t) window_attributes.width;
|
||
crop_info.height=(size_t) window_attributes.height;
|
||
if (ximage_info->borders != 0)
|
||
{
|
||
/*
|
||
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)
|
||
ThrowXWindowException(XServerError,"UnableToReadXWindowImage",
|
||
image_info->filename)
|
||
else
|
||
{
|
||
(void) CopyMagickString(image->filename,image_info->filename,
|
||
MaxTextExtent);
|
||
if ((crop_info.width != 0) && (crop_info.height != 0))
|
||
{
|
||
Image
|
||
*crop_image;
|
||
|
||
/*
|
||
Crop image as defined by the cropping rectangle.
|
||
*/
|
||
crop_image=CropImage(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 == '\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",
|
||
"...");
|
||
(void) memset(windows,0,sizeof(*windows));
|
||
windows->pixel_info=(XPixelInfo *) AcquireQuantumMemory(1,
|
||
sizeof(*windows->pixel_info));
|
||
windows->icon_pixel=(XPixelInfo *) AcquireQuantumMemory(1,
|
||
sizeof(*windows->icon_pixel));
|
||
windows->icon_resources=(XResourceInfo *) AcquireQuantumMemory(1,
|
||
sizeof(*windows->icon_resources));
|
||
if ((windows->pixel_info == (XPixelInfo *) NULL) ||
|
||
(windows->icon_pixel == (XPixelInfo *) NULL) ||
|
||
(windows->icon_resources == (XResourceInfo *) NULL))
|
||
ThrowXWindowFatalException(XServerFatalError,"MemoryAllocationFailed",
|
||
"...");
|
||
/*
|
||
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(MAGICKCORE_WINDOWS_SUPPORT)
|
||
(void) XSynchronize(display,MagickFalse);
|
||
#endif
|
||
if (IsEventLogging())
|
||
{
|
||
(void) XSynchronize(display,MagickTrue);
|
||
(void) LogMagickEvent(X11Event,GetMagickModule(),"Version: %s",
|
||
GetMagickVersion((size_t *) 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((int) ((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","...");
|
||
(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)
|
||
{
|
||
#define CheckOverflowException(length,width,height) \
|
||
(((height) != 0) && ((length)/((size_t) height) != ((size_t) width)))
|
||
|
||
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.
|
||
*/
|
||
window->image->page.x=0;
|
||
window->image->page.y=0;
|
||
(void) ParsePageGeometry(window->image,window->crop_geometry,
|
||
&crop_info,&image->exception);
|
||
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) &&
|
||
(window->image->rows > (unsigned long) XDisplayHeight(display,window->screen)) &&
|
||
(window->image->columns > (unsigned long) XDisplayWidth(display,window->screen)))
|
||
resize_image=ResizeImage(window->image,width,height,
|
||
image->filter,image->blur,&image->exception);
|
||
else
|
||
{
|
||
if (window->image->storage_class == PseudoClass)
|
||
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;
|
||
}
|
||
}
|
||
width=(unsigned int) window->image->columns;
|
||
assert((size_t) width == window->image->columns);
|
||
height=(unsigned int) window->image->rows;
|
||
assert((size_t) height == window->image->rows);
|
||
}
|
||
/*
|
||
Create X image.
|
||
*/
|
||
ximage=(XImage *) NULL;
|
||
format=(depth == 1) ? XYBitmap : ZPixmap;
|
||
#if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
|
||
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);
|
||
length=0;
|
||
if (ximage == (XImage *) NULL)
|
||
window->shared_memory=MagickFalse;
|
||
else
|
||
{
|
||
length=(size_t) ximage->bytes_per_line*ximage->height;
|
||
if (CheckOverflowException(length,ximage->bytes_per_line,ximage->height))
|
||
window->shared_memory=MagickFalse;
|
||
}
|
||
if (window->shared_memory != MagickFalse)
|
||
segment_info[1].shmid=shmget(IPC_PRIVATE,length,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(MAGICKCORE_HAVE_SHARED_MEMORY)
|
||
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]);
|
||
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)
|
||
{
|
||
ximage->data=(char *) AcquireQuantumMemory((size_t)
|
||
ximage->bytes_per_line,(size_t) ximage->depth*ximage->height);
|
||
if (ximage->data != (char *) NULL)
|
||
(void) memset(ximage->data,0,(size_t)
|
||
ximage->bytes_per_line*ximage->depth*ximage->height);
|
||
}
|
||
else
|
||
{
|
||
ximage->data=(char *) AcquireQuantumMemory((size_t)
|
||
ximage->bytes_per_line,(size_t) ximage->height);
|
||
if (ximage->data != (char *) NULL)
|
||
(void) memset(ximage->data,0,(size_t)
|
||
ximage->bytes_per_line*ximage->height);
|
||
}
|
||
}
|
||
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(MAGICKCORE_HAVE_SHARED_MEMORY)
|
||
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(MAGICKCORE_HAVE_SHARED_MEMORY)
|
||
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 != MagickFalse) &&
|
||
((int) width <= XDisplayWidth(display,window->screen)) &&
|
||
((int) 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.
|
||
*/
|
||
matte_image->data=(char *) malloc((size_t)
|
||
matte_image->bytes_per_line*matte_image->depth*
|
||
matte_image->height);
|
||
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(MAGICKCORE_HAVE_SHAPE)
|
||
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,
|
||
(size_t) (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(MAGICKCORE_HAVE_SHAPE)
|
||
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)
|
||
{
|
||
CacheView
|
||
*canvas_view;
|
||
|
||
Image
|
||
*canvas;
|
||
|
||
int
|
||
y;
|
||
|
||
const IndexPacket
|
||
*indexes;
|
||
|
||
const PixelPacket
|
||
*p;
|
||
|
||
int
|
||
x;
|
||
|
||
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);
|
||
canvas=image;
|
||
if ((window->immutable == MagickFalse) &&
|
||
(image->storage_class == DirectClass) && (image->matte != MagickFalse))
|
||
{
|
||
char
|
||
size[MaxTextExtent];
|
||
|
||
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);
|
||
(void) FormatLocaleString(size,MaxTextExtent,"%.20gx%.20g",(double)
|
||
image->columns,(double) image->rows);
|
||
image_info->size=ConstantString(size);
|
||
pattern=ReadImage(image_info,&image->exception);
|
||
image_info=DestroyImageInfo(image_info);
|
||
if (pattern != (Image *) NULL)
|
||
{
|
||
canvas=CloneImage(image,0,0,MagickTrue,&image->exception);
|
||
if (canvas != (Image *) NULL)
|
||
(void) CompositeImage(canvas,DstOverCompositeOp,pattern,0,0);
|
||
pattern=DestroyImage(pattern);
|
||
}
|
||
}
|
||
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;
|
||
canvas_view=AcquireVirtualCacheView(canvas,&canvas->exception);
|
||
if (ximage->format == XYBitmap)
|
||
{
|
||
unsigned short
|
||
polarity;
|
||
|
||
unsigned char
|
||
background,
|
||
foreground;
|
||
|
||
/*
|
||
Convert canvas 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) ((GetPixelIntensity(image,
|
||
&canvas->colormap[0])) < (QuantumRange/2.0) ? 1 : 0);
|
||
if (canvas->colors == 2)
|
||
polarity=GetPixelIntensity(canvas,&canvas->colormap[0]) <
|
||
GetPixelIntensity(canvas,&canvas->colormap[1]);
|
||
for (y=0; y < (int) canvas->rows; y++)
|
||
{
|
||
p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,canvas->columns,1,
|
||
&canvas->exception);
|
||
if (p == (const PixelPacket *) NULL)
|
||
break;
|
||
indexes=GetCacheViewVirtualIndexQueue(canvas_view);
|
||
bit=0;
|
||
byte=0;
|
||
for (x=0; x < (int) canvas->columns; x++)
|
||
{
|
||
byte>>=1;
|
||
if (GetPixelIndex(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:
|
||
{
|
||
unsigned int
|
||
nibble;
|
||
|
||
/*
|
||
Convert to 2 bit color-mapped X canvas.
|
||
*/
|
||
for (y=0; y < (int) canvas->rows; y++)
|
||
{
|
||
p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
|
||
canvas->columns,1,&canvas->exception);
|
||
if (p == (const PixelPacket *) NULL)
|
||
break;
|
||
indexes=GetCacheViewVirtualIndexQueue(canvas_view);
|
||
nibble=0;
|
||
for (x=0; x < (int) canvas->columns; x++)
|
||
{
|
||
pixel=pixels[(ssize_t) GetPixelIndex(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:
|
||
{
|
||
unsigned int
|
||
nibble;
|
||
|
||
/*
|
||
Convert to 4 bit color-mapped X canvas.
|
||
*/
|
||
for (y=0; y < (int) canvas->rows; y++)
|
||
{
|
||
p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
|
||
canvas->columns,1,&canvas->exception);
|
||
if (p == (const PixelPacket *) NULL)
|
||
break;
|
||
indexes=GetCacheViewVirtualIndexQueue(canvas_view);
|
||
nibble=0;
|
||
for (x=0; x < (int) canvas->columns; x++)
|
||
{
|
||
pixel=pixels[(ssize_t) GetPixelIndex(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 canvas.
|
||
*/
|
||
if ((resource_info->color_recovery != MagickFalse) &&
|
||
(resource_info->quantize_info->dither != MagickFalse))
|
||
{
|
||
XDitherImage(canvas,ximage);
|
||
break;
|
||
}
|
||
for (y=0; y < (int) canvas->rows; y++)
|
||
{
|
||
p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
|
||
canvas->columns,1,&canvas->exception);
|
||
if (p == (const PixelPacket *) NULL)
|
||
break;
|
||
indexes=GetCacheViewVirtualIndexQueue(canvas_view);
|
||
for (x=0; x < (int) canvas->columns; x++)
|
||
{
|
||
pixel=pixels[(ssize_t) GetPixelIndex(indexes+x)];
|
||
*q++=(unsigned char) pixel;
|
||
}
|
||
q+=scanline_pad;
|
||
}
|
||
break;
|
||
}
|
||
default:
|
||
{
|
||
int
|
||
k;
|
||
|
||
unsigned int
|
||
bytes_per_pixel;
|
||
|
||
/*
|
||
Convert to multi-byte color-mapped X canvas.
|
||
*/
|
||
bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3);
|
||
for (y=0; y < (int) canvas->rows; y++)
|
||
{
|
||
p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
|
||
canvas->columns,1,&canvas->exception);
|
||
if (p == (const PixelPacket *) NULL)
|
||
break;
|
||
indexes=GetCacheViewVirtualIndexQueue(canvas_view);
|
||
for (x=0; x < (int) canvas->columns; x++)
|
||
{
|
||
pixel=pixels[(ssize_t) GetPixelIndex(indexes+x)];
|
||
for (k=0; k < (int) bytes_per_pixel; k++)
|
||
{
|
||
*q++=(unsigned char) (pixel & 0xff);
|
||
pixel>>=8;
|
||
}
|
||
}
|
||
q+=scanline_pad;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
switch (ximage->bits_per_pixel)
|
||
{
|
||
case 2:
|
||
{
|
||
unsigned int
|
||
nibble;
|
||
|
||
/*
|
||
Convert to contiguous 2 bit continuous-tone X canvas.
|
||
*/
|
||
for (y=0; y < (int) canvas->rows; y++)
|
||
{
|
||
nibble=0;
|
||
p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
|
||
canvas->columns,1,&canvas->exception);
|
||
if (p == (const PixelPacket *) NULL)
|
||
break;
|
||
for (x=0; x < (int) canvas->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:
|
||
{
|
||
unsigned int
|
||
nibble;
|
||
|
||
/*
|
||
Convert to contiguous 4 bit continuous-tone X canvas.
|
||
*/
|
||
for (y=0; y < (int) canvas->rows; y++)
|
||
{
|
||
p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
|
||
canvas->columns,1,&canvas->exception);
|
||
if (p == (const PixelPacket *) NULL)
|
||
break;
|
||
nibble=0;
|
||
for (x=0; x < (int) canvas->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 canvas.
|
||
*/
|
||
if ((resource_info->color_recovery != MagickFalse) &&
|
||
(resource_info->quantize_info->dither != MagickFalse))
|
||
{
|
||
XDitherImage(canvas,ximage);
|
||
break;
|
||
}
|
||
for (y=0; y < (int) canvas->rows; y++)
|
||
{
|
||
p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
|
||
canvas->columns,1,&canvas->exception);
|
||
if (p == (const PixelPacket *) NULL)
|
||
break;
|
||
for (x=0; x < (int) canvas->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 canvas.
|
||
*/
|
||
for (y=0; y < (int) canvas->rows; y++)
|
||
{
|
||
p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
|
||
canvas->columns,1,&canvas->exception);
|
||
if (p == (const PixelPacket *) NULL)
|
||
break;
|
||
if ((red_gamma != 1.0) || (green_gamma != 1.0) ||
|
||
(blue_gamma != 1.0))
|
||
{
|
||
/*
|
||
Gamma correct canvas.
|
||
*/
|
||
for (x=(int) canvas->columns-1; x >= 0; x--)
|
||
{
|
||
*q++=ScaleQuantumToChar(XBlueGamma(GetPixelBlue(p)));
|
||
*q++=ScaleQuantumToChar(XGreenGamma(GetPixelGreen(p)));
|
||
*q++=ScaleQuantumToChar(XRedGamma(GetPixelRed(p)));
|
||
*q++=0;
|
||
p++;
|
||
}
|
||
continue;
|
||
}
|
||
for (x=(int) canvas->columns-1; x >= 0; x--)
|
||
{
|
||
*q++=ScaleQuantumToChar((Quantum) GetPixelBlue(p));
|
||
*q++=ScaleQuantumToChar((Quantum) GetPixelGreen(p));
|
||
*q++=ScaleQuantumToChar((Quantum) GetPixelRed(p));
|
||
*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 canvas.
|
||
*/
|
||
for (y=0; y < (int) canvas->rows; y++)
|
||
{
|
||
p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
|
||
canvas->columns,1,&canvas->exception);
|
||
if (p == (const PixelPacket *) NULL)
|
||
break;
|
||
if ((red_gamma != 1.0) || (green_gamma != 1.0) ||
|
||
(blue_gamma != 1.0))
|
||
{
|
||
/*
|
||
Gamma correct canvas.
|
||
*/
|
||
for (x=(int) canvas->columns-1; x >= 0; x--)
|
||
{
|
||
*q++=ScaleQuantumToChar(XRedGamma(GetPixelRed(p)));
|
||
*q++=ScaleQuantumToChar(XGreenGamma(GetPixelGreen(p)));
|
||
*q++=ScaleQuantumToChar(XBlueGamma(GetPixelBlue(p)));
|
||
*q++=0;
|
||
p++;
|
||
}
|
||
continue;
|
||
}
|
||
for (x=(int) canvas->columns-1; x >= 0; x--)
|
||
{
|
||
*q++=ScaleQuantumToChar((Quantum) GetPixelRed(p));
|
||
*q++=ScaleQuantumToChar((Quantum) GetPixelGreen(p));
|
||
*q++=ScaleQuantumToChar((Quantum) GetPixelBlue(p));
|
||
*q++=0;
|
||
p++;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
int
|
||
k;
|
||
|
||
unsigned int
|
||
bytes_per_pixel;
|
||
|
||
/*
|
||
Convert to multi-byte continuous-tone X canvas.
|
||
*/
|
||
bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3);
|
||
for (y=0; y < (int) canvas->rows; y++)
|
||
{
|
||
p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
|
||
canvas->columns,1,&canvas->exception);
|
||
if (p == (PixelPacket *) NULL)
|
||
break;
|
||
for (x=0; x < (int) canvas->columns; x++)
|
||
{
|
||
pixel=XGammaPixel(map_info,p);
|
||
for (k=0; k < (int) bytes_per_pixel; k++)
|
||
{
|
||
*q++=(unsigned char) (pixel & 0xff);
|
||
pixel>>=8;
|
||
}
|
||
p++;
|
||
}
|
||
q+=scanline_pad;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
if (matte_image != (XImage *) NULL)
|
||
{
|
||
/*
|
||
Initialize matte canvas.
|
||
*/
|
||
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) canvas->rows; y++)
|
||
{
|
||
p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,canvas->columns,1,
|
||
&canvas->exception);
|
||
if (p == (const PixelPacket *) NULL)
|
||
break;
|
||
bit=0;
|
||
byte=0;
|
||
for (x=(int) canvas->columns-1; x >= 0; x--)
|
||
{
|
||
byte>>=1;
|
||
if (GetPixelOpacity(p) > (QuantumRange/2))
|
||
byte|=0x80;
|
||
bit++;
|
||
if (bit == 8)
|
||
{
|
||
*q++=byte;
|
||
bit=0;
|
||
byte=0;
|
||
}
|
||
p++;
|
||
}
|
||
if (bit != 0)
|
||
*q=byte >> (8-bit);
|
||
q+=scanline_pad;
|
||
}
|
||
}
|
||
canvas_view=DestroyCacheView(canvas_view);
|
||
if (canvas != image)
|
||
canvas=DestroyImage(canvas);
|
||
}
|
||
|
||
/*
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
% %
|
||
% %
|
||
% %
|
||
+ 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)
|
||
{
|
||
CacheView
|
||
*canvas_view;
|
||
|
||
Image
|
||
*canvas;
|
||
|
||
int
|
||
y;
|
||
|
||
int
|
||
x;
|
||
|
||
const IndexPacket
|
||
*indexes;
|
||
|
||
const PixelPacket
|
||
*p;
|
||
|
||
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);
|
||
canvas=image;
|
||
if ((window->immutable != MagickFalse) &&
|
||
(image->storage_class == DirectClass) && (image->matte != MagickFalse))
|
||
{
|
||
char
|
||
size[MaxTextExtent];
|
||
|
||
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);
|
||
(void) FormatLocaleString(size,MaxTextExtent,"%.20gx%.20g",(double)
|
||
image->columns,(double) image->rows);
|
||
image_info->size=ConstantString(size);
|
||
pattern=ReadImage(image_info,&image->exception);
|
||
image_info=DestroyImageInfo(image_info);
|
||
if (pattern != (Image *) NULL)
|
||
{
|
||
canvas=CloneImage(image,0,0,MagickTrue,&image->exception);
|
||
if (canvas != (Image *) NULL)
|
||
(void) CompositeImage(canvas,DstOverCompositeOp,pattern,0,0);
|
||
pattern=DestroyImage(pattern);
|
||
}
|
||
}
|
||
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;
|
||
canvas_view=AcquireVirtualCacheView(canvas,&canvas->exception);
|
||
if (ximage->format == XYBitmap)
|
||
{
|
||
unsigned short
|
||
polarity;
|
||
|
||
unsigned char
|
||
background,
|
||
foreground;
|
||
|
||
/*
|
||
Convert canvas 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) ((GetPixelIntensity(image,
|
||
&canvas->colormap[0])) < (QuantumRange/2.0) ? 1 : 0);
|
||
if (canvas->colors == 2)
|
||
polarity=GetPixelIntensity(canvas,&canvas->colormap[0]) <
|
||
GetPixelIntensity(canvas,&canvas->colormap[1]);
|
||
for (y=0; y < (int) canvas->rows; y++)
|
||
{
|
||
p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,canvas->columns,1,
|
||
&canvas->exception);
|
||
if (p == (const PixelPacket *) NULL)
|
||
break;
|
||
indexes=GetCacheViewVirtualIndexQueue(canvas_view);
|
||
bit=0;
|
||
byte=0;
|
||
for (x=(int) canvas->columns-1; x >= 0; x--)
|
||
{
|
||
byte<<=1;
|
||
if (GetPixelIndex(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:
|
||
{
|
||
unsigned int
|
||
nibble;
|
||
|
||
/*
|
||
Convert to 2 bit color-mapped X canvas.
|
||
*/
|
||
for (y=0; y < (int) canvas->rows; y++)
|
||
{
|
||
p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
|
||
canvas->columns,1,&canvas->exception);
|
||
if (p == (const PixelPacket *) NULL)
|
||
break;
|
||
indexes=GetCacheViewVirtualIndexQueue(canvas_view);
|
||
nibble=0;
|
||
for (x=0; x < (int) canvas->columns; x++)
|
||
{
|
||
pixel=pixels[(ssize_t) GetPixelIndex(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:
|
||
{
|
||
unsigned int
|
||
nibble;
|
||
|
||
/*
|
||
Convert to 4 bit color-mapped X canvas.
|
||
*/
|
||
for (y=0; y < (int) canvas->rows; y++)
|
||
{
|
||
p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
|
||
canvas->columns,1,&canvas->exception);
|
||
if (p == (const PixelPacket *) NULL)
|
||
break;
|
||
indexes=GetCacheViewVirtualIndexQueue(canvas_view);
|
||
nibble=0;
|
||
for (x=0; x < (int) canvas->columns; x++)
|
||
{
|
||
pixel=pixels[(ssize_t) GetPixelIndex(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 canvas.
|
||
*/
|
||
if (resource_info->color_recovery &&
|
||
resource_info->quantize_info->dither)
|
||
{
|
||
XDitherImage(canvas,ximage);
|
||
break;
|
||
}
|
||
for (y=0; y < (int) canvas->rows; y++)
|
||
{
|
||
p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
|
||
canvas->columns,1,&canvas->exception);
|
||
if (p == (const PixelPacket *) NULL)
|
||
break;
|
||
indexes=GetCacheViewVirtualIndexQueue(canvas_view);
|
||
for (x=0; x < (int) canvas->columns; x++)
|
||
{
|
||
pixel=pixels[(ssize_t) GetPixelIndex(indexes+x)];
|
||
*q++=(unsigned char) pixel;
|
||
}
|
||
q+=scanline_pad;
|
||
}
|
||
break;
|
||
}
|
||
default:
|
||
{
|
||
int
|
||
k;
|
||
|
||
unsigned int
|
||
bytes_per_pixel;
|
||
|
||
unsigned char
|
||
channel[sizeof(size_t)];
|
||
|
||
/*
|
||
Convert to 8 bit color-mapped X canvas.
|
||
*/
|
||
bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3);
|
||
for (y=0; y < (int) canvas->rows; y++)
|
||
{
|
||
p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
|
||
canvas->columns,1,&canvas->exception);
|
||
if (p == (const PixelPacket *) NULL)
|
||
break;
|
||
indexes=GetCacheViewVirtualIndexQueue(canvas_view);
|
||
for (x=0; x < (int) canvas->columns; x++)
|
||
{
|
||
pixel=pixels[(ssize_t) GetPixelIndex(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:
|
||
{
|
||
unsigned int
|
||
nibble;
|
||
|
||
/*
|
||
Convert to 4 bit continuous-tone X canvas.
|
||
*/
|
||
for (y=0; y < (int) canvas->rows; y++)
|
||
{
|
||
p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
|
||
canvas->columns,1,&canvas->exception);
|
||
if (p == (const PixelPacket *) NULL)
|
||
break;
|
||
nibble=0;
|
||
for (x=(int) canvas->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:
|
||
{
|
||
unsigned int
|
||
nibble;
|
||
|
||
/*
|
||
Convert to 4 bit continuous-tone X canvas.
|
||
*/
|
||
for (y=0; y < (int) canvas->rows; y++)
|
||
{
|
||
p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
|
||
canvas->columns,1,&canvas->exception);
|
||
if (p == (const PixelPacket *) NULL)
|
||
break;
|
||
nibble=0;
|
||
for (x=(int) canvas->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 canvas.
|
||
*/
|
||
if (resource_info->color_recovery &&
|
||
resource_info->quantize_info->dither)
|
||
{
|
||
XDitherImage(canvas,ximage);
|
||
break;
|
||
}
|
||
for (y=0; y < (int) canvas->rows; y++)
|
||
{
|
||
p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
|
||
canvas->columns,1,&canvas->exception);
|
||
if (p == (const PixelPacket *) NULL)
|
||
break;
|
||
for (x=(int) canvas->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 canvas.
|
||
*/
|
||
for (y=0; y < (int) canvas->rows; y++)
|
||
{
|
||
p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
|
||
canvas->columns,1,&canvas->exception);
|
||
if (p == (const PixelPacket *) NULL)
|
||
break;
|
||
if ((red_gamma != 1.0) || (green_gamma != 1.0) ||
|
||
(blue_gamma != 1.0))
|
||
{
|
||
/*
|
||
Gamma correct canvas.
|
||
*/
|
||
for (x=(int) canvas->columns-1; x >= 0; x--)
|
||
{
|
||
*q++=0;
|
||
*q++=ScaleQuantumToChar(XRedGamma(GetPixelRed(p)));
|
||
*q++=ScaleQuantumToChar(XGreenGamma(GetPixelGreen(p)));
|
||
*q++=ScaleQuantumToChar(XBlueGamma(GetPixelBlue(p)));
|
||
p++;
|
||
}
|
||
continue;
|
||
}
|
||
for (x=(int) canvas->columns-1; x >= 0; x--)
|
||
{
|
||
*q++=0;
|
||
*q++=ScaleQuantumToChar((Quantum) GetPixelRed(p));
|
||
*q++=ScaleQuantumToChar((Quantum) GetPixelGreen(p));
|
||
*q++=ScaleQuantumToChar((Quantum) GetPixelBlue(p));
|
||
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 canvas.
|
||
*/
|
||
for (y=0; y < (int) canvas->rows; y++)
|
||
{
|
||
p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
|
||
canvas->columns,1,&canvas->exception);
|
||
if (p == (const PixelPacket *) NULL)
|
||
break;
|
||
if ((red_gamma != 1.0) || (green_gamma != 1.0) ||
|
||
(blue_gamma != 1.0))
|
||
{
|
||
/*
|
||
Gamma correct canvas.
|
||
*/
|
||
for (x=(int) canvas->columns-1; x >= 0; x--)
|
||
{
|
||
*q++=0;
|
||
*q++=ScaleQuantumToChar(XBlueGamma(GetPixelBlue(p)));
|
||
*q++=ScaleQuantumToChar(XGreenGamma(GetPixelGreen(p)));
|
||
*q++=ScaleQuantumToChar(XRedGamma(GetPixelRed(p)));
|
||
p++;
|
||
}
|
||
continue;
|
||
}
|
||
for (x=(int) canvas->columns-1; x >= 0; x--)
|
||
{
|
||
*q++=0;
|
||
*q++=ScaleQuantumToChar((Quantum) GetPixelBlue(p));
|
||
*q++=ScaleQuantumToChar((Quantum) GetPixelGreen(p));
|
||
*q++=ScaleQuantumToChar((Quantum) GetPixelRed(p));
|
||
p++;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
int
|
||
k;
|
||
|
||
unsigned int
|
||
bytes_per_pixel;
|
||
|
||
/*
|
||
Convert to multi-byte continuous-tone X canvas.
|
||
*/
|
||
bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3);
|
||
for (y=0; y < (int) canvas->rows; y++)
|
||
{
|
||
p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,
|
||
canvas->columns,1,&canvas->exception);
|
||
if (p == (const PixelPacket *) NULL)
|
||
break;
|
||
for (x=(int) canvas->columns-1; x >= 0; x--)
|
||
{
|
||
pixel=XGammaPixel(map_info,p);
|
||
for (k=(int) bytes_per_pixel-1; k >= 0; k--)
|
||
{
|
||
*q++=(unsigned char) (pixel & 0xff);
|
||
pixel>>=8;
|
||
}
|
||
p++;
|
||
}
|
||
q+=scanline_pad;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
if (matte_image != (XImage *) NULL)
|
||
{
|
||
/*
|
||
Initialize matte canvas.
|
||
*/
|
||
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) canvas->rows; y++)
|
||
{
|
||
p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,canvas->columns,1,
|
||
&canvas->exception);
|
||
if (p == (const PixelPacket *) NULL)
|
||
break;
|
||
bit=0;
|
||
byte=0;
|
||
for (x=(int) canvas->columns-1; x >= 0; x--)
|
||
{
|
||
byte<<=1;
|
||
if (GetPixelOpacity(p) > (QuantumRange/2))
|
||
byte|=0x01;
|
||
bit++;
|
||
if (bit == 8)
|
||
{
|
||
*q++=byte;
|
||
bit=0;
|
||
byte=0;
|
||
}
|
||
p++;
|
||
}
|
||
if (bit != 0)
|
||
*q=byte << (8-bit);
|
||
q+=scanline_pad;
|
||
}
|
||
}
|
||
canvas_view=DestroyCacheView(canvas_view);
|
||
if (canvas != image)
|
||
canvas=DestroyImage(canvas);
|
||
}
|
||
|
||
/*
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
% %
|
||
% %
|
||
% %
|
||
% 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;
|
||
|
||
MagickPixelPacket
|
||
pixel;
|
||
|
||
int
|
||
x;
|
||
|
||
ssize_t
|
||
i;
|
||
|
||
unsigned char
|
||
*p,
|
||
*q;
|
||
|
||
ssize_t
|
||
n;
|
||
|
||
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 < (ssize_t) 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 == 0)
|
||
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) FormatLocaleString(windows->magnify.name,MaxTextExtent,
|
||
"Magnify %.20gX",(double) 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)
|
||
{
|
||
unsigned char
|
||
background,
|
||
byte,
|
||
foreground,
|
||
p_bit,
|
||
q_bit;
|
||
|
||
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 < (ssize_t) 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 < (ssize_t) 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 < (ssize_t) 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:
|
||
{
|
||
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 < (ssize_t) 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=(ssize_t) windows->magnify.width >> 1;
|
||
highlight_info.y=(ssize_t) 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.
|
||
*/
|
||
(void) GetOneVirtualMagickPixel(windows->image.image,(ssize_t)
|
||
windows->magnify.x,(ssize_t) windows->magnify.y,&pixel,
|
||
&windows->image.image->exception);
|
||
(void) FormatLocaleString(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));
|
||
GetColorTuple(&pixel,MagickTrue,tuple);
|
||
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,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);
|
||
(void) resource_info;
|
||
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(MAGICKCORE_HAVE_SHARED_MEMORY)
|
||
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.298839*pixel->red+0.586811*pixel->green+0.114350*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 size_t x,
|
||
const size_t 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;
|
||
|
||
ExceptionInfo
|
||
*exception;
|
||
|
||
IndexPacket
|
||
*indexes;
|
||
|
||
ssize_t
|
||
i;
|
||
|
||
Status
|
||
status;
|
||
|
||
size_t
|
||
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);
|
||
exception=(&image->exception);
|
||
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
|
||
*affinity_image;
|
||
|
||
PixelPacket
|
||
*magick_restrict q;
|
||
|
||
/*
|
||
Improve image appearance with error diffusion.
|
||
*/
|
||
affinity_image=AcquireImage((ImageInfo *) NULL);
|
||
if (affinity_image == (Image *) NULL)
|
||
ThrowXWindowFatalException(ResourceLimitFatalError,
|
||
"UnableToDitherImage",image->filename);
|
||
affinity_image->columns=number_colors;
|
||
affinity_image->rows=1;
|
||
/*
|
||
Initialize colormap image.
|
||
*/
|
||
q=QueueAuthenticPixels(affinity_image,0,0,affinity_image->columns,
|
||
1,exception);
|
||
if (q != (PixelPacket *) NULL)
|
||
{
|
||
for (i=0; i < (ssize_t) number_colors; i++)
|
||
{
|
||
SetPixelRed(q,0);
|
||
if (map_info->red_max != 0)
|
||
SetPixelRed(q,ScaleXToQuantum((size_t) (i/
|
||
map_info->red_mult),map_info->red_max));
|
||
SetPixelGreen(q,0);
|
||
if (map_info->green_max != 0)
|
||
SetPixelGreen(q,ScaleXToQuantum((size_t) ((i/
|
||
map_info->green_mult) % (map_info->green_max+1)),
|
||
map_info->green_max));
|
||
SetPixelBlue(q,0);
|
||
if (map_info->blue_max != 0)
|
||
SetPixelBlue(q,ScaleXToQuantum((size_t) (i %
|
||
map_info->green_mult),map_info->blue_max));
|
||
SetPixelOpacity(q,TransparentOpacity);
|
||
q++;
|
||
}
|
||
(void) SyncAuthenticPixels(affinity_image,exception);
|
||
(void) RemapImage(resource_info->quantize_info,image,
|
||
affinity_image);
|
||
}
|
||
XGetPixelPacket(display,visual_info,map_info,resource_info,image,
|
||
pixel);
|
||
(void) SetImageStorageClass(image,DirectClass);
|
||
affinity_image=DestroyImage(affinity_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=(size_t) 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 < (ssize_t) 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)
|
||
{
|
||
CacheView
|
||
*image_view;
|
||
|
||
DiversityPacket
|
||
*diversity;
|
||
|
||
int
|
||
y;
|
||
|
||
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 < (ssize_t) 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;
|
||
}
|
||
image_view=AcquireAuthenticCacheView(image,exception);
|
||
for (y=0; y < (int) image->rows; y++)
|
||
{
|
||
int
|
||
x;
|
||
|
||
const PixelPacket
|
||
*magick_restrict p;
|
||
|
||
p=GetCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
|
||
image->columns,1,exception);
|
||
if (p == (const PixelPacket *) NULL)
|
||
break;
|
||
indexes=GetCacheViewAuthenticIndexQueue(image_view);
|
||
for (x=(int) image->columns-1; x >= 0; x--)
|
||
diversity[(ssize_t) GetPixelIndex(indexes+x)].count++;
|
||
}
|
||
image_view=DestroyCacheView(image_view);
|
||
/*
|
||
Sort colors by decreasing intensity.
|
||
*/
|
||
qsort((void *) diversity,image->colors,sizeof(*diversity),
|
||
IntensityCompare);
|
||
for (i=0; i < (ssize_t) image->colors; )
|
||
{
|
||
diversity[i].count<<=4; /* increase this colors popularity */
|
||
i+=MagickMax((int) (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 < (ssize_t) 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=(size_t) 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 < (ssize_t) 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 < (ssize_t) 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 < (ssize_t) 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 < (ssize_t) 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 < (ssize_t) 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=(size_t) 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 < (ssize_t) number_colors; i++)
|
||
{
|
||
color.blue=(unsigned short) 0;
|
||
if (map_info->blue_max != 0)
|
||
color.blue=(unsigned short) ((size_t)
|
||
((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 < (ssize_t) number_colors; i++)
|
||
{
|
||
color.red=(unsigned short) 0;
|
||
if (map_info->red_max != 0)
|
||
color.red=(unsigned short) ((size_t)
|
||
((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) ((size_t)
|
||
((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) ((size_t)
|
||
((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 < (ssize_t) 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=(ssize_t) (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=(int) 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;
|
||
|
||
char
|
||
*p;
|
||
|
||
/*
|
||
User specified geometry.
|
||
*/
|
||
(void) FormatLocaleString(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) memmove(p,p+1,MaxTextExtent-(p-geometry));
|
||
}
|
||
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,(unsigned long) 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,(unsigned long)
|
||
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(MAGICKCORE_HAVE_SHAPE)
|
||
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;
|
||
#else
|
||
window_info->shape=MagickFalse;
|
||
#endif
|
||
}
|
||
window_info->shape=MagickFalse; /* Fedora 30 has a broken shape extention */
|
||
if (window_info->shared_memory != MagickFalse)
|
||
{
|
||
#if defined(MAGICKCORE_HAVE_SHARED_MEMORY)
|
||
/*
|
||
Can 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 *text)
|
||
{
|
||
char
|
||
message[MaxTextExtent],
|
||
tag[MaxTextExtent];
|
||
|
||
const char
|
||
*locale_message;
|
||
|
||
char
|
||
*p;
|
||
|
||
(void) CopyMagickString(tag,text,MaxTextExtent);
|
||
p=strrchr(tag,'/');
|
||
if (p != (char *) NULL)
|
||
*p='\0';
|
||
(void) FormatLocaleString(message,MaxTextExtent,"Monitor/%s",tag);
|
||
locale_message=GetLocaleMessage(message);
|
||
if (locale_message == message)
|
||
return(text);
|
||
return(locale_message);
|
||
}
|
||
|
||
MagickExport MagickBooleanType XMagickProgressMonitor(const char *tag,
|
||
const MagickOffsetType quantum,const MagickSizeType span,
|
||
void *magick_unused(client_data))
|
||
{
|
||
XWindows
|
||
*windows;
|
||
|
||
magick_unreferenced(client_data);
|
||
|
||
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);
|
||
colormap=XDefaultColormap(display,XDefaultScreen(display));
|
||
status=XParseColor(display,colormap,(char *) target,&xcolor);
|
||
if (status == False)
|
||
ThrowXWindowException(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)) ;
|
||
if (window->matte_pixmap != (Pixmap) NULL)
|
||
{
|
||
#if defined(MAGICKCORE_HAVE_SHAPE)
|
||
if (window->shape != MagickFalse)
|
||
XShapeCombineMask(display,window->id,ShapeBounding,0,0,
|
||
window->matte_pixmap,ShapeSet);
|
||
#endif
|
||
}
|
||
}
|
||
/*
|
||
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(MAGICKCORE_HAVE_SHARED_MEMORY)
|
||
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((int) ((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 n d e r I m a g e %
|
||
% %
|
||
% %
|
||
% %
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
%
|
||
% XRenderImage() renders text on the image with an X11 font. It also returns
|
||
% the bounding box of the text relative to the image.
|
||
%
|
||
% The format of the XRenderImage method is:
|
||
%
|
||
% MagickBooleanType XRenderImage(Image *image,DrawInfo *draw_info,
|
||
% const PointInfo *offset,TypeMetric *metrics)
|
||
%
|
||
% A description of each parameter follows:
|
||
%
|
||
% o image: the image.
|
||
%
|
||
% o draw_info: the draw info.
|
||
%
|
||
% o offset: (x,y) location of text relative to image.
|
||
%
|
||
% o metrics: bounding box of text.
|
||
%
|
||
*/
|
||
MagickPrivate MagickBooleanType XRenderImage(Image *image,
|
||
const DrawInfo *draw_info,const PointInfo *offset,TypeMetric *metrics)
|
||
{
|
||
const char
|
||
*client_name;
|
||
|
||
DrawInfo
|
||
cache_info;
|
||
|
||
Display
|
||
*display = (Display *) NULL;
|
||
|
||
ImageInfo
|
||
*image_info;
|
||
|
||
MagickBooleanType
|
||
status;
|
||
|
||
size_t
|
||
height,
|
||
width;
|
||
|
||
XAnnotateInfo
|
||
annotate_info;
|
||
|
||
XFontStruct
|
||
*font_info;
|
||
|
||
XPixelInfo
|
||
pixel;
|
||
|
||
XResourceInfo
|
||
resource_info;
|
||
|
||
XrmDatabase
|
||
resource_database;
|
||
|
||
XStandardColormap
|
||
*map_info;
|
||
|
||
XVisualInfo
|
||
*visual_info;
|
||
|
||
/*
|
||
Open X server connection.
|
||
*/
|
||
display=XOpenDisplay(draw_info->server_name);
|
||
if (display == (Display *) NULL)
|
||
{
|
||
ThrowXWindowException(XServerError,"UnableToOpenXServer",
|
||
draw_info->server_name);
|
||
return(MagickFalse);
|
||
}
|
||
/*
|
||
Get user defaults from X resource database.
|
||
*/
|
||
(void) XSetErrorHandler(XError);
|
||
image_info=AcquireImageInfo();
|
||
client_name=GetClientName();
|
||
resource_database=XGetResourceDatabase(display,client_name);
|
||
XGetResourceInfo(image_info,resource_database,client_name,&resource_info);
|
||
resource_info.close_server=MagickFalse;
|
||
resource_info.colormap=PrivateColormap;
|
||
resource_info.font=AcquireString(draw_info->font);
|
||
resource_info.background_color=AcquireString("#ffffffffffff");
|
||
resource_info.foreground_color=AcquireString("#000000000000");
|
||
map_info=XAllocStandardColormap();
|
||
visual_info=(XVisualInfo *) NULL;
|
||
font_info=(XFontStruct *) NULL;
|
||
pixel.pixels=(unsigned long *) NULL;
|
||
if (map_info == (XStandardColormap *) NULL)
|
||
{
|
||
ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed",
|
||
image->filename);
|
||
return(MagickFalse);
|
||
}
|
||
/*
|
||
Initialize visual info.
|
||
*/
|
||
visual_info=XBestVisualInfo(display,map_info,&resource_info);
|
||
if (visual_info == (XVisualInfo *) NULL)
|
||
{
|
||
XFreeResources(display,visual_info,map_info,&pixel,font_info,
|
||
&resource_info,(XWindowInfo *) NULL);
|
||
ThrowXWindowException(XServerError,"UnableToGetVisual",image->filename);
|
||
return(MagickFalse);
|
||
}
|
||
map_info->colormap=(Colormap) NULL;
|
||
/*
|
||
Initialize Standard Colormap info.
|
||
*/
|
||
XGetMapInfo(visual_info,XDefaultColormap(display,visual_info->screen),
|
||
map_info);
|
||
XGetPixelPacket(display,visual_info,map_info,&resource_info,(Image *) NULL,
|
||
&pixel);
|
||
pixel.annotate_context=XDefaultGC(display,visual_info->screen);
|
||
/*
|
||
Initialize font info.
|
||
*/
|
||
font_info=XBestFont(display,&resource_info,MagickFalse);
|
||
if (font_info == (XFontStruct *) NULL)
|
||
{
|
||
XFreeResources(display,visual_info,map_info,&pixel,font_info,
|
||
&resource_info,(XWindowInfo *) NULL);
|
||
ThrowXWindowException(XServerError,"UnableToLoadFont",draw_info->font);
|
||
return(MagickFalse);
|
||
}
|
||
cache_info=(*draw_info);
|
||
/*
|
||
Initialize annotate info.
|
||
*/
|
||
XGetAnnotateInfo(&annotate_info);
|
||
annotate_info.stencil=ForegroundStencil;
|
||
if (cache_info.font != draw_info->font)
|
||
{
|
||
/*
|
||
Type name has changed.
|
||
*/
|
||
(void) XFreeFont(display,font_info);
|
||
(void) CloneString(&resource_info.font,draw_info->font);
|
||
font_info=XBestFont(display,&resource_info,MagickFalse);
|
||
if (font_info == (XFontStruct *) NULL)
|
||
{
|
||
ThrowXWindowException(XServerError,"UnableToLoadFont",
|
||
draw_info->font);
|
||
return(MagickFalse);
|
||
}
|
||
}
|
||
if (image->debug != MagickFalse)
|
||
(void) LogMagickEvent(AnnotateEvent,GetMagickModule(),
|
||
"Font %s; pointsize %g",draw_info->font != (char *) NULL ?
|
||
draw_info->font : "none",draw_info->pointsize);
|
||
cache_info=(*draw_info);
|
||
annotate_info.font_info=font_info;
|
||
annotate_info.text=(char *) draw_info->text;
|
||
annotate_info.width=(unsigned int) XTextWidth(font_info,draw_info->text,(int)
|
||
strlen(draw_info->text));
|
||
annotate_info.height=(unsigned int) font_info->ascent+font_info->descent;
|
||
metrics->pixels_per_em.x=(double) font_info->max_bounds.width;
|
||
metrics->pixels_per_em.y=(double) font_info->ascent+font_info->descent;
|
||
metrics->ascent=(double) font_info->ascent+4;
|
||
metrics->descent=(double) (-font_info->descent);
|
||
metrics->width=annotate_info.width/ExpandAffine(&draw_info->affine);
|
||
metrics->height=font_info->ascent+font_info->descent;
|
||
metrics->max_advance=(double) font_info->max_bounds.width;
|
||
metrics->bounds.x1=0.0;
|
||
metrics->bounds.y1=metrics->descent;
|
||
metrics->bounds.x2=metrics->ascent+metrics->descent;
|
||
metrics->bounds.y2=metrics->ascent+metrics->descent;
|
||
metrics->underline_position=(-2.0);
|
||
metrics->underline_thickness=1.0;
|
||
if (draw_info->render == MagickFalse)
|
||
return(MagickTrue);
|
||
if (draw_info->fill.opacity == TransparentOpacity)
|
||
return(MagickTrue);
|
||
/*
|
||
Render fill color.
|
||
*/
|
||
width=annotate_info.width;
|
||
height=annotate_info.height;
|
||
if ((draw_info->affine.rx != 0.0) || (draw_info->affine.ry != 0.0))
|
||
{
|
||
if (((draw_info->affine.sx-draw_info->affine.sy) == 0.0) &&
|
||
((draw_info->affine.rx+draw_info->affine.ry) == 0.0))
|
||
annotate_info.degrees=(180.0/MagickPI)*
|
||
atan2(draw_info->affine.rx,draw_info->affine.sx);
|
||
}
|
||
(void) FormatLocaleString(annotate_info.geometry,MaxTextExtent,
|
||
"%.20gx%.20g%+.20g%+.20g",(double) width,(double) height,
|
||
ceil(offset->x-0.5),ceil(offset->y-metrics->ascent-metrics->descent+
|
||
draw_info->interline_spacing-0.5));
|
||
pixel.pen_color.red=ScaleQuantumToShort(draw_info->fill.red);
|
||
pixel.pen_color.green=ScaleQuantumToShort(draw_info->fill.green);
|
||
pixel.pen_color.blue=ScaleQuantumToShort(draw_info->fill.blue);
|
||
status=XAnnotateImage(display,&pixel,&annotate_info,image);
|
||
if (status == 0)
|
||
{
|
||
ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed",
|
||
image->filename);
|
||
return(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");
|
||
pixmap=XCreatePixmap(display,window,1,1,1);
|
||
if (pixmap == (Pixmap) NULL)
|
||
ThrowXWindowFatalException(XServerError,"UnableToCreateBitmap","");
|
||
(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,(size_t) (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","");
|
||
/*
|
||
Select a window.
|
||
*/
|
||
crop_info->width=0;
|
||
crop_info->height=0;
|
||
presses=0;
|
||
target_window=(Window) NULL;
|
||
x_offset=0;
|
||
y_offset=0;
|
||
(void) XGrabServer(display);
|
||
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=(ssize_t) x_offset;
|
||
crop_info->y=(ssize_t) 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=(ssize_t) event.xmotion.x;
|
||
crop_info->y=(ssize_t) event.xmotion.y;
|
||
/*
|
||
Check boundary conditions.
|
||
*/
|
||
if ((int) crop_info->x < x_offset)
|
||
crop_info->width=(size_t) (x_offset-crop_info->x);
|
||
else
|
||
{
|
||
crop_info->width=(size_t) (crop_info->x-x_offset);
|
||
crop_info->x=(ssize_t) x_offset;
|
||
}
|
||
if ((int) crop_info->y < y_offset)
|
||
crop_info->height=(size_t) (y_offset-crop_info->y);
|
||
else
|
||
{
|
||
crop_info->height=(size_t) (crop_info->y-y_offset);
|
||
crop_info->y=(ssize_t) y_offset;
|
||
}
|
||
}
|
||
default:
|
||
break;
|
||
}
|
||
} while ((target_window == (Window) NULL) || (presses > 0));
|
||
(void) XUngrabServer(display);
|
||
(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(X11_PREFERENCES_PATH)
|
||
char
|
||
cache[MaxTextExtent],
|
||
filename[MaxTextExtent],
|
||
specifier[MaxTextExtent];
|
||
|
||
const char
|
||
*client_name,
|
||
*value;
|
||
|
||
XrmDatabase
|
||
preferences_database;
|
||
|
||
/*
|
||
Save user preferences to the client configuration file.
|
||
*/
|
||
assert(resource_info != (XResourceInfo *) NULL);
|
||
client_name=GetClientName();
|
||
preferences_database=XrmGetStringDatabase("");
|
||
(void) FormatLocaleString(specifier,MaxTextExtent,"%s.backdrop",client_name);
|
||
value=resource_info->backdrop ? "True" : "False";
|
||
XrmPutStringResource(&preferences_database,specifier,(char *) value);
|
||
(void) FormatLocaleString(specifier,MaxTextExtent,"%s.colormap",client_name);
|
||
value=resource_info->colormap == SharedColormap ? "Shared" : "Private";
|
||
XrmPutStringResource(&preferences_database,specifier,(char *) value);
|
||
(void) FormatLocaleString(specifier,MaxTextExtent,"%s.confirmExit",
|
||
client_name);
|
||
value=resource_info->confirm_exit ? "True" : "False";
|
||
XrmPutStringResource(&preferences_database,specifier,(char *) value);
|
||
(void) FormatLocaleString(specifier,MaxTextExtent,"%s.confirmEdit",
|
||
client_name);
|
||
value=resource_info->confirm_edit ? "True" : "False";
|
||
XrmPutStringResource(&preferences_database,specifier,(char *) value);
|
||
(void) FormatLocaleString(specifier,MaxTextExtent,"%s.displayWarnings",
|
||
client_name);
|
||
value=resource_info->display_warnings ? "True" : "False";
|
||
XrmPutStringResource(&preferences_database,specifier,(char *) value);
|
||
(void) FormatLocaleString(specifier,MaxTextExtent,"%s.dither",client_name);
|
||
value=resource_info->quantize_info->dither ? "True" : "False";
|
||
XrmPutStringResource(&preferences_database,specifier,(char *) value);
|
||
(void) FormatLocaleString(specifier,MaxTextExtent,"%s.gammaCorrect",
|
||
client_name);
|
||
value=resource_info->gamma_correct ? "True" : "False";
|
||
XrmPutStringResource(&preferences_database,specifier,(char *) value);
|
||
(void) FormatLocaleString(specifier,MaxTextExtent,"%s.undoCache",client_name);
|
||
(void) FormatLocaleString(cache,MaxTextExtent,"%.20g",(double)
|
||
resource_info->undo_cache);
|
||
XrmPutStringResource(&preferences_database,specifier,cache);
|
||
(void) FormatLocaleString(specifier,MaxTextExtent,"%s.usePixmap",client_name);
|
||
value=resource_info->use_pixmap ? "True" : "False";
|
||
XrmPutStringResource(&preferences_database,specifier,(char *) value);
|
||
(void) FormatLocaleString(filename,MaxTextExtent,"%s%src",
|
||
X11_PREFERENCES_PATH,client_name);
|
||
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;
|
||
|
||
magick_unreferenced(warning);
|
||
|
||
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 size_t id)
|
||
{
|
||
RectangleInfo
|
||
rectangle_info;
|
||
|
||
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(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=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)
|
||
{
|
||
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 == MagickCoreSignature);
|
||
if (image_info->debug != MagickFalse)
|
||
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
|
||
image_info->filename);
|
||
assert(ximage_info != (XImportInfo *) NULL);
|
||
(void) ximage_info;
|
||
return((Image *) NULL);
|
||
}
|
||
|
||
/*
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
% %
|
||
% %
|
||
% %
|
||
+ X R e n d e r I m a g e %
|
||
% %
|
||
% %
|
||
% %
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
%
|
||
% XRenderImage() renders text on the image with an X11 font. It also returns
|
||
% the bounding box of the text relative to the image.
|
||
%
|
||
% The format of the XRenderImage method is:
|
||
%
|
||
% MagickBooleanType XRenderImage(Image *image,DrawInfo *draw_info,
|
||
% const PointInfo *offset,TypeMetric *metrics)
|
||
%
|
||
% A description of each parameter follows:
|
||
%
|
||
% o image: the image.
|
||
%
|
||
% o draw_info: the draw info.
|
||
%
|
||
% o offset: (x,y) location of text relative to image.
|
||
%
|
||
% o metrics: bounding box of text.
|
||
%
|
||
*/
|
||
MagickPrivate MagickBooleanType XRenderImage(Image *image,
|
||
const DrawInfo *draw_info,const PointInfo *offset,TypeMetric *metrics)
|
||
{
|
||
(void) draw_info;
|
||
(void) offset;
|
||
(void) metrics;
|
||
(void) ThrowMagickException(&image->exception,GetMagickModule(),
|
||
MissingDelegateError,"DelegateLibrarySupportNotBuiltIn","`%s' (X11)",
|
||
image->filename);
|
||
return(MagickFalse);
|
||
}
|
||
#endif
|
||
|
||
/*
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
% %
|
||
% %
|
||
% %
|
||
+ X C o m p o n e n t G e n e s i s %
|
||
% %
|
||
% %
|
||
% %
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
%
|
||
% XComponentGenesis() instantiates the X component.
|
||
%
|
||
% The format of the XComponentGenesis method is:
|
||
%
|
||
% MagickBooleanType XComponentGenesis(void)
|
||
%
|
||
*/
|
||
MagickExport MagickBooleanType XComponentGenesis(void)
|
||
{
|
||
return(MagickTrue);
|
||
}
|
||
|
||
/*
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||
% %
|
||
% %
|
||
% %
|
||
% 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;
|
||
}
|