1/* 2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3% % 4% % 5% % 6% X X W W IIIII N N DDDD OOO W W % 7% X X W W I NN N D D O O W W % 8% X W W I N N N D D O O W W % 9% X X W W W I N NN D D O O W W W % 10% X X W W IIIII N N DDDD OOO W W % 11% % 12% % 13% MagickCore X11 Utility Methods % 14% % 15% Software Design % 16% Cristy % 17% July 1992 % 18% % 19% % 20% Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization % 21% dedicated to making software imaging solutions freely available. % 22% % 23% You may not use this file except in compliance with the License. You may % 24% obtain a copy of the License at % 25% % 26% http://www.imagemagick.org/script/license.php % 27% % 28% Unless required by applicable law or agreed to in writing, software % 29% distributed under the License is distributed on an "AS IS" BASIS, % 30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 31% See the License for the specific language governing permissions and % 32% limitations under the License. % 33% % 34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 35% 36% 37*/ 38 39/* 40 Include declarations. 41*/ 42#include "MagickCore/studio.h" 43#include "MagickCore/animate.h" 44#include "MagickCore/artifact.h" 45#include "MagickCore/blob.h" 46#include "MagickCore/cache.h" 47#include "MagickCore/client.h" 48#include "MagickCore/color.h" 49#include "MagickCore/color-private.h" 50#include "MagickCore/colormap.h" 51#include "MagickCore/composite.h" 52#include "MagickCore/constitute.h" 53#include "MagickCore/display.h" 54#include "MagickCore/distort.h" 55#include "MagickCore/exception.h" 56#include "MagickCore/exception-private.h" 57#include "MagickCore/geometry.h" 58#include "MagickCore/identify.h" 59#include "MagickCore/image.h" 60#include "MagickCore/image-private.h" 61#include "MagickCore/list.h" 62#include "MagickCore/locale_.h" 63#include "MagickCore/log.h" 64#include "MagickCore/magick.h" 65#include "MagickCore/memory_.h" 66#include "MagickCore/monitor.h" 67#include "MagickCore/nt-base-private.h" 68#include "MagickCore/option.h" 69#include "MagickCore/pixel-accessor.h" 70#include "MagickCore/quantize.h" 71#include "MagickCore/quantum.h" 72#include "MagickCore/quantum-private.h" 73#include "MagickCore/resource_.h" 74#include "MagickCore/resize.h" 75#include "MagickCore/statistic.h" 76#include "MagickCore/string_.h" 77#include "MagickCore/string-private.h" 78#include "MagickCore/transform.h" 79#include "MagickCore/transform-private.h" 80#include "MagickCore/token.h" 81#include "MagickCore/utility.h" 82#include "MagickCore/utility-private.h" 83#include "MagickCore/widget.h" 84#include "MagickCore/widget-private.h" 85#include "MagickCore/xwindow.h" 86#include "MagickCore/xwindow-private.h" 87#include "MagickCore/version.h" 88#if defined(__BEOS__) 89#include <OS.h> 90#endif 91#if defined(MAGICKCORE_X11_DELEGATE) 92#include <X11/Xproto.h> 93#include <X11/Xlocale.h> 94#if defined(MAGICK_HAVE_POLL) 95# include <sys/poll.h> 96#endif 97#if defined(MAGICKCORE_HAVE_SHARED_MEMORY) 98#if defined(MAGICKCORE_HAVE_MACHINE_PARAM_H) 99# include <machine/param.h> 100#endif 101#include <sys/ipc.h> 102#include <sys/shm.h> 103#include <X11/extensions/XShm.h> 104#endif 105#if defined(MAGICKCORE_HAVE_SHAPE) 106#include <X11/extensions/shape.h> 107#endif 108 109/* 110 X defines. 111*/ 112#define XBlueGamma(color) ClampToQuantum(blue_gamma == 1.0 ? (double) \ 113 (color) : ((pow(((double) QuantumScale*(color)),1.0/(double) blue_gamma)* \ 114 QuantumRange))) 115#define XGammaPacket(map,color) (size_t) (map->base_pixel+ \ 116 ((ScaleQuantumToShort(XRedGamma((color)->red))*map->red_max/65535L)* \ 117 map->red_mult)+ \ 118 ((ScaleQuantumToShort(XGreenGamma((color)->green))*map->green_max/65535L)* \ 119 map->green_mult)+ \ 120 ((ScaleQuantumToShort(XBlueGamma((color)->blue))*map->blue_max/65535L)* \ 121 map->blue_mult)) 122#define XGammaPixel(image,map,color) (size_t) (map->base_pixel+ \ 123 ((ScaleQuantumToShort(XRedGamma(GetPixelRed(image,color)))*map->red_max/65535L)* \ 124 map->red_mult)+ \ 125 ((ScaleQuantumToShort(XGreenGamma(GetPixelGreen(image,color)))*map->green_max/65535L)* \ 126 map->green_mult)+ \ 127 ((ScaleQuantumToShort(XBlueGamma(GetPixelBlue(image,color)))*map->blue_max/65535L)* \ 128 map->blue_mult)) 129#define XGreenGamma(color) ClampToQuantum(green_gamma == 1.0 ? (double) \ 130 (color) : ((pow(((double) QuantumScale*(color)),1.0/(double) green_gamma)* \ 131 QuantumRange))) 132#define XRedGamma(color) ClampToQuantum(red_gamma == 1.0 ? (double) \ 133 (color) : ((pow(((double) QuantumScale*(color)),1.0/(double) red_gamma)* \ 134 QuantumRange))) 135#define XStandardPixel(map,color) (size_t) (map->base_pixel+ \ 136 (((color)->red*map->red_max/65535L)*map->red_mult)+ \ 137 (((color)->green*map->green_max/65535L)*map->green_mult)+ \ 138 (((color)->blue*map->blue_max/65535L)*map->blue_mult)) 139 140#define AccentuateModulate ScaleCharToQuantum(80) 141#define HighlightModulate ScaleCharToQuantum(125) 142#define ShadowModulate ScaleCharToQuantum(135) 143#define DepthModulate ScaleCharToQuantum(185) 144#define TroughModulate ScaleCharToQuantum(110) 145 146#define XLIB_ILLEGAL_ACCESS 1 147#undef ForgetGravity 148#undef NorthWestGravity 149#undef NorthGravity 150#undef NorthEastGravity 151#undef WestGravity 152#undef CenterGravity 153#undef EastGravity 154#undef SouthWestGravity 155#undef SouthGravity 156#undef SouthEastGravity 157#undef StaticGravity 158 159#undef index 160#if defined(hpux9) 161#define XFD_SET int 162#else 163#define XFD_SET fd_set 164#endif 165 166/* 167 Enumeration declarations. 168*/ 169typedef enum 170{ 171#undef DoRed 172 DoRed = 0x0001, 173#undef DoGreen 174 DoGreen = 0x0002, 175#undef DoBlue 176 DoBlue = 0x0004, 177 DoMatte = 0x0008 178} XColorFlags; 179 180/* 181 Typedef declarations. 182*/ 183typedef struct _DiversityPacket 184{ 185 Quantum 186 red, 187 green, 188 blue; 189 190 unsigned short 191 index; 192 193 size_t 194 count; 195} DiversityPacket; 196 197/* 198 Constant declaractions. 199*/ 200static MagickBooleanType 201 xerror_alert = MagickFalse; 202 203/* 204 Method prototypes. 205*/ 206static const char 207 *XVisualClassName(const int); 208 209static double 210 blue_gamma = 1.0, 211 green_gamma = 1.0, 212 red_gamma = 1.0; 213 214static MagickBooleanType 215 XMakePixmap(Display *,const XResourceInfo *,XWindowInfo *); 216 217static void 218 XMakeImageLSBFirst(const XResourceInfo *,const XWindowInfo *,Image *, 219 XImage *,XImage *,ExceptionInfo *), 220 XMakeImageMSBFirst(const XResourceInfo *,const XWindowInfo *,Image *, 221 XImage *,XImage *,ExceptionInfo *); 222 223static Window 224 XSelectWindow(Display *,RectangleInfo *); 225 226/* 227%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 228% % 229% % 230% % 231% D e s t r o y X R e s o u r c e s % 232% % 233% % 234% % 235%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 236% 237% DestroyXResources() destroys any X resources. 238% 239% The format of the DestroyXResources method is: 240% 241% void DestroyXResources() 242% 243% A description of each parameter follows: 244% 245*/ 246MagickExport void DestroyXResources(void) 247{ 248 register int 249 i; 250 251 unsigned int 252 number_windows; 253 254 XWindowInfo 255 *magick_windows[MaxXWindows]; 256 257 XWindows 258 *windows; 259 260 DestroyXWidget(); 261 windows=XSetWindows((XWindows *) ~0); 262 if ((windows == (XWindows *) NULL) || (windows->display == (Display *) NULL)) 263 return; 264 number_windows=0; 265 magick_windows[number_windows++]=(&windows->context); 266 magick_windows[number_windows++]=(&windows->group_leader); 267 magick_windows[number_windows++]=(&windows->backdrop); 268 magick_windows[number_windows++]=(&windows->icon); 269 magick_windows[number_windows++]=(&windows->image); 270 magick_windows[number_windows++]=(&windows->info); 271 magick_windows[number_windows++]=(&windows->magnify); 272 magick_windows[number_windows++]=(&windows->pan); 273 magick_windows[number_windows++]=(&windows->command); 274 magick_windows[number_windows++]=(&windows->widget); 275 magick_windows[number_windows++]=(&windows->popup); 276 magick_windows[number_windows++]=(&windows->context); 277 for (i=0; i < (int) number_windows; i++) 278 { 279 if (magick_windows[i]->mapped != MagickFalse) 280 { 281 (void) XWithdrawWindow(windows->display,magick_windows[i]->id, 282 magick_windows[i]->screen); 283 magick_windows[i]->mapped=MagickFalse; 284 } 285 if (magick_windows[i]->name != (char *) NULL) 286 magick_windows[i]->name=(char *) 287 RelinquishMagickMemory(magick_windows[i]->name); 288 if (magick_windows[i]->icon_name != (char *) NULL) 289 magick_windows[i]->icon_name=(char *) 290 RelinquishMagickMemory(magick_windows[i]->icon_name); 291 if (magick_windows[i]->cursor != (Cursor) NULL) 292 { 293 (void) XFreeCursor(windows->display,magick_windows[i]->cursor); 294 magick_windows[i]->cursor=(Cursor) NULL; 295 } 296 if (magick_windows[i]->busy_cursor != (Cursor) NULL) 297 { 298 (void) XFreeCursor(windows->display,magick_windows[i]->busy_cursor); 299 magick_windows[i]->busy_cursor=(Cursor) NULL; 300 } 301 if (magick_windows[i]->highlight_stipple != (Pixmap) NULL) 302 { 303 (void) XFreePixmap(windows->display, 304 magick_windows[i]->highlight_stipple); 305 magick_windows[i]->highlight_stipple=(Pixmap) NULL; 306 } 307 if (magick_windows[i]->shadow_stipple != (Pixmap) NULL) 308 { 309 (void) XFreePixmap(windows->display,magick_windows[i]->shadow_stipple); 310 magick_windows[i]->shadow_stipple=(Pixmap) NULL; 311 } 312 if (magick_windows[i]->ximage != (XImage *) NULL) 313 { 314 XDestroyImage(magick_windows[i]->ximage); 315 magick_windows[i]->ximage=(XImage *) NULL; 316 } 317 if (magick_windows[i]->pixmap != (Pixmap) NULL) 318 { 319 (void) XFreePixmap(windows->display,magick_windows[i]->pixmap); 320 magick_windows[i]->pixmap=(Pixmap) NULL; 321 } 322 if (magick_windows[i]->id != (Window) NULL) 323 { 324 (void) XDestroyWindow(windows->display,magick_windows[i]->id); 325 magick_windows[i]->id=(Window) NULL; 326 } 327 if (magick_windows[i]->destroy != MagickFalse) 328 { 329 if (magick_windows[i]->image != (Image *) NULL) 330 { 331 magick_windows[i]->image=DestroyImage(magick_windows[i]->image); 332 magick_windows[i]->image=NewImageList(); 333 } 334 if (magick_windows[i]->matte_pixmap != (Pixmap) NULL) 335 { 336 (void) XFreePixmap(windows->display, 337 magick_windows[i]->matte_pixmap); 338 magick_windows[i]->matte_pixmap=(Pixmap) NULL; 339 } 340 } 341 if (magick_windows[i]->segment_info != (void *) NULL) 342 { 343#if defined(MAGICKCORE_HAVE_SHARED_MEMORY) 344 XShmSegmentInfo 345 *segment_info; 346 347 segment_info=(XShmSegmentInfo *) magick_windows[i]->segment_info; 348 if (segment_info != (XShmSegmentInfo *) NULL) 349 if (segment_info[0].shmid >= 0) 350 { 351 if (segment_info[0].shmaddr != NULL) 352 (void) shmdt(segment_info[0].shmaddr); 353 (void) shmctl(segment_info[0].shmid,IPC_RMID,0); 354 segment_info[0].shmaddr=NULL; 355 segment_info[0].shmid=(-1); 356 } 357#endif 358 magick_windows[i]->segment_info=(void *) 359 RelinquishMagickMemory(magick_windows[i]->segment_info); 360 } 361 } 362 windows->icon_resources=(XResourceInfo *) 363 RelinquishMagickMemory(windows->icon_resources); 364 if (windows->icon_pixel != (XPixelInfo *) NULL) 365 { 366 if (windows->icon_pixel->pixels != (unsigned long *) NULL) 367 windows->icon_pixel->pixels=(unsigned long *) 368 RelinquishMagickMemory(windows->icon_pixel->pixels); 369 if (windows->icon_pixel->annotate_context != (GC) NULL) 370 XFreeGC(windows->display,windows->icon_pixel->annotate_context); 371 windows->icon_pixel=(XPixelInfo *) 372 RelinquishMagickMemory(windows->icon_pixel); 373 } 374 if (windows->pixel_info != (XPixelInfo *) NULL) 375 { 376 if (windows->pixel_info->pixels != (unsigned long *) NULL) 377 windows->pixel_info->pixels=(unsigned long *) 378 RelinquishMagickMemory(windows->pixel_info->pixels); 379 if (windows->pixel_info->annotate_context != (GC) NULL) 380 XFreeGC(windows->display,windows->pixel_info->annotate_context); 381 if (windows->pixel_info->widget_context != (GC) NULL) 382 XFreeGC(windows->display,windows->pixel_info->widget_context); 383 if (windows->pixel_info->highlight_context != (GC) NULL) 384 XFreeGC(windows->display,windows->pixel_info->highlight_context); 385 windows->pixel_info=(XPixelInfo *) 386 RelinquishMagickMemory(windows->pixel_info); 387 } 388 if (windows->font_info != (XFontStruct *) NULL) 389 { 390 XFreeFont(windows->display,windows->font_info); 391 windows->font_info=(XFontStruct *) NULL; 392 } 393 if (windows->class_hints != (XClassHint *) NULL) 394 { 395 if (windows->class_hints->res_name != (char *) NULL) 396 windows->class_hints->res_name=DestroyString( 397 windows->class_hints->res_name); 398 if (windows->class_hints->res_class != (char *) NULL) 399 windows->class_hints->res_class=DestroyString( 400 windows->class_hints->res_class); 401 XFree(windows->class_hints); 402 windows->class_hints=(XClassHint *) NULL; 403 } 404 if (windows->manager_hints != (XWMHints *) NULL) 405 { 406 XFree(windows->manager_hints); 407 windows->manager_hints=(XWMHints *) NULL; 408 } 409 if (windows->map_info != (XStandardColormap *) NULL) 410 { 411 XFree(windows->map_info); 412 windows->map_info=(XStandardColormap *) NULL; 413 } 414 if (windows->icon_map != (XStandardColormap *) NULL) 415 { 416 XFree(windows->icon_map); 417 windows->icon_map=(XStandardColormap *) NULL; 418 } 419 if (windows->visual_info != (XVisualInfo *) NULL) 420 { 421 XFree(windows->visual_info); 422 windows->visual_info=(XVisualInfo *) NULL; 423 } 424 if (windows->icon_visual != (XVisualInfo *) NULL) 425 { 426 XFree(windows->icon_visual); 427 windows->icon_visual=(XVisualInfo *) NULL; 428 } 429 (void) XSetWindows((XWindows *) NULL); 430} 431 432/* 433%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 434% % 435% % 436% % 437% X A n n o t a t e I m a g e % 438% % 439% % 440% % 441%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 442% 443% XAnnotateImage() annotates the image with text. 444% 445% The format of the XAnnotateImage method is: 446% 447% MagickBooleanType XAnnotateImage(Display *display, 448% const XPixelInfo *pixel,XAnnotateInfo *annotate_info,Image *image, 449% ExceptionInfo *exception) 450% 451% A description of each parameter follows: 452% 453% o display: Specifies a connection to an X server; returned from 454% XOpenDisplay. 455% 456% o pixel: Specifies a pointer to a XPixelInfo structure. 457% 458% o annotate_info: Specifies a pointer to a XAnnotateInfo structure. 459% 460% o image: the image. 461% 462% o exception: return any errors or warnings in this structure. 463% 464*/ 465MagickPrivate MagickBooleanType XAnnotateImage(Display *display, 466 const XPixelInfo *pixel,XAnnotateInfo *annotate_info,Image *image, 467 ExceptionInfo *exception) 468{ 469 CacheView 470 *annotate_view; 471 472 GC 473 annotate_context; 474 475 Image 476 *annotate_image; 477 478 int 479 x, 480 y; 481 482 PixelTrait 483 alpha_trait; 484 485 Pixmap 486 annotate_pixmap; 487 488 unsigned int 489 depth, 490 height, 491 width; 492 493 Window 494 root_window; 495 496 XGCValues 497 context_values; 498 499 XImage 500 *annotate_ximage; 501 502 /* 503 Initialize annotated image. 504 */ 505 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 506 assert(display != (Display *) NULL); 507 assert(pixel != (XPixelInfo *) NULL); 508 assert(annotate_info != (XAnnotateInfo *) NULL); 509 assert(image != (Image *) NULL); 510 /* 511 Initialize annotated pixmap. 512 */ 513 root_window=XRootWindow(display,XDefaultScreen(display)); 514 depth=(unsigned int) XDefaultDepth(display,XDefaultScreen(display)); 515 annotate_pixmap=XCreatePixmap(display,root_window,annotate_info->width, 516 annotate_info->height,depth); 517 if (annotate_pixmap == (Pixmap) NULL) 518 return(MagickFalse); 519 /* 520 Initialize graphics info. 521 */ 522 context_values.background=0; 523 context_values.foreground=(size_t) (~0); 524 context_values.font=annotate_info->font_info->fid; 525 annotate_context=XCreateGC(display,root_window,(unsigned long) 526 (GCBackground | GCFont | GCForeground),&context_values); 527 if (annotate_context == (GC) NULL) 528 return(MagickFalse); 529 /* 530 Draw text to pixmap. 531 */ 532 (void) XDrawImageString(display,annotate_pixmap,annotate_context,0, 533 (int) annotate_info->font_info->ascent,annotate_info->text, 534 (int) strlen(annotate_info->text)); 535 (void) XFreeGC(display,annotate_context); 536 /* 537 Initialize annotated X image. 538 */ 539 annotate_ximage=XGetImage(display,annotate_pixmap,0,0,annotate_info->width, 540 annotate_info->height,AllPlanes,ZPixmap); 541 if (annotate_ximage == (XImage *) NULL) 542 return(MagickFalse); 543 (void) XFreePixmap(display,annotate_pixmap); 544 /* 545 Initialize annotated image. 546 */ 547 annotate_image=AcquireImage((ImageInfo *) NULL,exception); 548 if (annotate_image == (Image *) NULL) 549 return(MagickFalse); 550 annotate_image->columns=annotate_info->width; 551 annotate_image->rows=annotate_info->height; 552 /* 553 Transfer annotated X image to image. 554 */ 555 width=(unsigned int) image->columns; 556 height=(unsigned int) image->rows; 557 x=0; 558 y=0; 559 (void) XParseGeometry(annotate_info->geometry,&x,&y,&width,&height); 560 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,(ssize_t) x, 561 (ssize_t) y,&annotate_image->background_color,exception); 562 if (annotate_info->stencil == ForegroundStencil) 563 annotate_image->alpha_trait=BlendPixelTrait; 564 annotate_view=AcquireAuthenticCacheView(annotate_image,exception); 565 for (y=0; y < (int) annotate_image->rows; y++) 566 { 567 register int 568 x; 569 570 register Quantum 571 *magick_restrict q; 572 573 q=GetCacheViewAuthenticPixels(annotate_view,0,(ssize_t) y, 574 annotate_image->columns,1,exception); 575 if (q == (Quantum *) NULL) 576 break; 577 for (x=0; x < (int) annotate_image->columns; x++) 578 { 579 SetPixelAlpha(annotate_image,OpaqueAlpha,q); 580 if (XGetPixel(annotate_ximage,x,y) == 0) 581 { 582 /* 583 Set this pixel to the background color. 584 */ 585 SetPixelRed(annotate_image,ScaleShortToQuantum( 586 pixel->box_color.red),q); 587 SetPixelGreen(annotate_image,ScaleShortToQuantum( 588 pixel->box_color.green),q); 589 SetPixelBlue(annotate_image,ScaleShortToQuantum( 590 pixel->box_color.blue),q); 591 if ((annotate_info->stencil == ForegroundStencil) || 592 (annotate_info->stencil == OpaqueStencil)) 593 SetPixelAlpha(annotate_image,TransparentAlpha,q); 594 } 595 else 596 { 597 /* 598 Set this pixel to the pen color. 599 */ 600 SetPixelRed(annotate_image,ScaleShortToQuantum( 601 pixel->pen_color.red),q); 602 SetPixelGreen(annotate_image,ScaleShortToQuantum( 603 pixel->pen_color.green),q); 604 SetPixelBlue(annotate_image,ScaleShortToQuantum( 605 pixel->pen_color.blue),q); 606 if (annotate_info->stencil == BackgroundStencil) 607 SetPixelAlpha(annotate_image,TransparentAlpha,q); 608 } 609 q+=GetPixelChannels(annotate_image); 610 } 611 if (SyncCacheViewAuthenticPixels(annotate_view,exception) == MagickFalse) 612 break; 613 } 614 annotate_view=DestroyCacheView(annotate_view); 615 XDestroyImage(annotate_ximage); 616 /* 617 Determine annotate geometry. 618 */ 619 (void) XParseGeometry(annotate_info->geometry,&x,&y,&width,&height); 620 if ((width != (unsigned int) annotate_image->columns) || 621 (height != (unsigned int) annotate_image->rows)) 622 { 623 char 624 image_geometry[MagickPathExtent]; 625 626 /* 627 Scale image. 628 */ 629 (void) FormatLocaleString(image_geometry,MagickPathExtent,"%ux%u", 630 width,height); 631 (void) TransformImage(&annotate_image,(char *) NULL,image_geometry, 632 exception); 633 } 634 if (annotate_info->degrees != 0.0) 635 { 636 Image 637 *rotate_image; 638 639 int 640 rotations; 641 642 double 643 normalized_degrees; 644 645 /* 646 Rotate image. 647 */ 648 rotate_image=RotateImage(annotate_image,annotate_info->degrees,exception); 649 if (rotate_image == (Image *) NULL) 650 return(MagickFalse); 651 annotate_image=DestroyImage(annotate_image); 652 annotate_image=rotate_image; 653 /* 654 Annotation is relative to the degree of rotation. 655 */ 656 normalized_degrees=annotate_info->degrees; 657 while (normalized_degrees < -45.0) 658 normalized_degrees+=360.0; 659 for (rotations=0; normalized_degrees > 45.0; rotations++) 660 normalized_degrees-=90.0; 661 switch (rotations % 4) 662 { 663 default: 664 case 0: 665 break; 666 case 1: 667 { 668 /* 669 Rotate 90 degrees. 670 */ 671 x-=(int) annotate_image->columns/2; 672 y+=(int) annotate_image->columns/2; 673 break; 674 } 675 case 2: 676 { 677 /* 678 Rotate 180 degrees. 679 */ 680 x=x-(int) annotate_image->columns; 681 break; 682 } 683 case 3: 684 { 685 /* 686 Rotate 270 degrees. 687 */ 688 x=x-(int) annotate_image->columns/2; 689 y=y-(int) (annotate_image->rows-(annotate_image->columns/2)); 690 break; 691 } 692 } 693 } 694 /* 695 Composite text onto the image. 696 */ 697 (void) XParseGeometry(annotate_info->geometry,&x,&y,&width,&height); 698 alpha_trait=image->alpha_trait; 699 (void) CompositeImage(image,annotate_image, 700 annotate_image->alpha_trait != UndefinedPixelTrait ? OverCompositeOp : 701 CopyCompositeOp,MagickTrue,(ssize_t) x,(ssize_t) y,exception); 702 image->alpha_trait=alpha_trait; 703 annotate_image=DestroyImage(annotate_image); 704 return(MagickTrue); 705} 706 707/* 708%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 709% % 710% % 711% % 712% X B e s t F o n t % 713% % 714% % 715% % 716%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 717% 718% XBestFont() returns the "best" font. "Best" is defined as a font specified 719% in the X resource database or a font such that the text width displayed 720% with the font does not exceed the specified maximum width. 721% 722% The format of the XBestFont method is: 723% 724% XFontStruct *XBestFont(Display *display, 725% const XResourceInfo *resource_info,const MagickBooleanType text_font) 726% 727% A description of each parameter follows: 728% 729% o font: XBestFont returns a pointer to a XFontStruct structure. 730% 731% o display: Specifies a connection to an X server; returned from 732% XOpenDisplay. 733% 734% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. 735% 736% o text_font: True is font should be mono-spaced (typewriter style). 737% 738*/ 739 740static char **FontToList(char *font) 741{ 742 char 743 **fontlist; 744 745 register char 746 *p, 747 *q; 748 749 register int 750 i; 751 752 unsigned int 753 fonts; 754 755 if (font == (char *) NULL) 756 return((char **) NULL); 757 /* 758 Convert string to an ASCII list. 759 */ 760 fonts=1U; 761 for (p=font; *p != '\0'; p++) 762 if ((*p == ':') || (*p == ';') || (*p == ',')) 763 fonts++; 764 fontlist=(char **) AcquireQuantumMemory((size_t) fonts+1UL,sizeof(*fontlist)); 765 if (fontlist == (char **) NULL) 766 { 767 ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed",font); 768 return((char **) NULL); 769 } 770 p=font; 771 for (i=0; i < (int) fonts; i++) 772 { 773 for (q=p; *q != '\0'; q++) 774 if ((*q == ':') || (*q == ';') || (*q == ',')) 775 break; 776 fontlist[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+1UL, 777 sizeof(*fontlist[i])); 778 if (fontlist[i] == (char *) NULL) 779 { 780 ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed",font); 781 return((char **) NULL); 782 } 783 (void) CopyMagickString(fontlist[i],p,(size_t) (q-p+1)); 784 p=q+1; 785 } 786 fontlist[i]=(char *) NULL; 787 return(fontlist); 788} 789 790MagickPrivate XFontStruct *XBestFont(Display *display, 791 const XResourceInfo *resource_info,const MagickBooleanType text_font) 792{ 793 static const char 794 *Fonts[]= 795 { 796 "-*-helvetica-medium-r-normal--12-*-*-*-*-*-iso8859-1", 797 "-*-arial-medium-r-normal--12-*-*-*-*-*-iso8859-1", 798 "-*-helvetica-medium-r-normal--12-*-*-*-*-*-iso8859-15", 799 "-*-arial-medium-r-normal--12-*-*-*-*-*-iso8859-15", 800 "-*-helvetica-medium-r-normal--12-*-*-*-*-*-*-*", 801 "-*-arial-medium-r-normal--12-*-*-*-*-*-*-*", 802 "variable", 803 "fixed", 804 (char *) NULL 805 }, 806 *TextFonts[]= 807 { 808 "-*-courier-medium-r-normal-*-12-*-*-*-*-*-iso8859-1", 809 "-*-courier-medium-r-normal-*-12-*-*-*-*-*-iso8859-15", 810 "-*-fixed-medium-r-normal-*-12-*-*-*-*-*-*-*", 811 "fixed", 812 (char *) NULL 813 }; 814 815 char 816 *font_name; 817 818 register const char 819 **p; 820 821 XFontStruct 822 *font_info; 823 824 font_info=(XFontStruct *) NULL; 825 font_name=resource_info->font; 826 if (text_font != MagickFalse) 827 font_name=resource_info->text_font; 828 if ((font_name != (char *) NULL) && (*font_name != '\0')) 829 { 830 char 831 **fontlist; 832 833 register int 834 i; 835 836 /* 837 Load preferred font specified in the X resource database. 838 */ 839 fontlist=FontToList(font_name); 840 if (fontlist != (char **) NULL) 841 { 842 for (i=0; fontlist[i] != (char *) NULL; i++) 843 { 844 if (font_info == (XFontStruct *) NULL) 845 font_info=XLoadQueryFont(display,fontlist[i]); 846 fontlist[i]=DestroyString(fontlist[i]); 847 } 848 fontlist=(char **) RelinquishMagickMemory(fontlist); 849 } 850 if (font_info == (XFontStruct *) NULL) 851 ThrowXWindowException(XServerError,"UnableToLoadFont",font_name); 852 } 853 /* 854 Load fonts from list of fonts until one is found. 855 */ 856 p=Fonts; 857 if (text_font != MagickFalse) 858 p=TextFonts; 859 if (XDisplayHeight(display,XDefaultScreen(display)) >= 748) 860 p++; 861 while (*p != (char *) NULL) 862 { 863 if (font_info != (XFontStruct *) NULL) 864 break; 865 font_info=XLoadQueryFont(display,(char *) *p); 866 p++; 867 } 868 return(font_info); 869} 870 871/* 872%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 873% % 874% % 875% % 876% X B e s t I c o n S i z e % 877% % 878% % 879% % 880%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 881% 882% XBestIconSize() returns the "best" icon size. "Best" is defined as an icon 883% size that maintains the aspect ratio of the image. If the window manager 884% has preferred icon sizes, one of the preferred sizes is used. 885% 886% The format of the XBestIconSize method is: 887% 888% void XBestIconSize(Display *display,XWindowInfo *window,Image *image) 889% 890% A description of each parameter follows: 891% 892% o display: Specifies a connection to an X server; returned from 893% XOpenDisplay. 894% 895% o image: the image. 896% 897*/ 898MagickPrivate void XBestIconSize(Display *display,XWindowInfo *window, 899 Image *image) 900{ 901 int 902 i, 903 number_sizes; 904 905 double 906 scale_factor; 907 908 unsigned int 909 height, 910 icon_height, 911 icon_width, 912 width; 913 914 Window 915 root_window; 916 917 XIconSize 918 *icon_size, 919 *size_list; 920 921 /* 922 Determine if the window manager has specified preferred icon sizes. 923 */ 924 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 925 assert(display != (Display *) NULL); 926 assert(window != (XWindowInfo *) NULL); 927 assert(image != (Image *) NULL); 928 window->width=MaxIconSize; 929 window->height=MaxIconSize; 930 icon_size=(XIconSize *) NULL; 931 number_sizes=0; 932 root_window=XRootWindow(display,window->screen); 933 if (XGetIconSizes(display,root_window,&size_list,&number_sizes) != 0) 934 if ((number_sizes > 0) && (size_list != (XIconSize *) NULL)) 935 icon_size=size_list; 936 if (icon_size == (XIconSize *) NULL) 937 { 938 /* 939 Window manager does not restrict icon size. 940 */ 941 icon_size=XAllocIconSize(); 942 if (icon_size == (XIconSize *) NULL) 943 { 944 ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed", 945 image->filename); 946 return; 947 } 948 icon_size->min_width=1; 949 icon_size->max_width=MaxIconSize; 950 icon_size->min_height=1; 951 icon_size->max_height=MaxIconSize; 952 icon_size->width_inc=1; 953 icon_size->height_inc=1; 954 } 955 /* 956 Determine aspect ratio of image. 957 */ 958 width=(unsigned int) image->columns; 959 height=(unsigned int) image->rows; 960 i=0; 961 if (window->crop_geometry) 962 (void) XParseGeometry(window->crop_geometry,&i,&i,&width,&height); 963 /* 964 Look for an icon size that maintains the aspect ratio of image. 965 */ 966 scale_factor=(double) icon_size->max_width/width; 967 if (scale_factor > ((double) icon_size->max_height/height)) 968 scale_factor=(double) icon_size->max_height/height; 969 icon_width=(unsigned int) icon_size->min_width; 970 while ((int) icon_width < icon_size->max_width) 971 { 972 if (icon_width >= (unsigned int) (scale_factor*width+0.5)) 973 break; 974 icon_width+=icon_size->width_inc; 975 } 976 icon_height=(unsigned int) icon_size->min_height; 977 while ((int) icon_height < icon_size->max_height) 978 { 979 if (icon_height >= (unsigned int) (scale_factor*height+0.5)) 980 break; 981 icon_height+=icon_size->height_inc; 982 } 983 (void) XFree((void *) icon_size); 984 window->width=icon_width; 985 window->height=icon_height; 986} 987 988/* 989%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 990% % 991% % 992% % 993% X B e s t P i x e l % 994% % 995% % 996% % 997%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 998% 999% XBestPixel() returns a pixel from an array of pixels that is closest to the 1000% requested color. If the color array is NULL, the colors are obtained from 1001% the X server. 1002% 1003% The format of the XBestPixel method is: 1004% 1005% void XBestPixel(Display *display,const Colormap colormap,XColor *colors, 1006% unsigned int number_colors,XColor *color) 1007% 1008% A description of each parameter follows: 1009% 1010% o pixel: XBestPixel returns the pixel value closest to the requested 1011% color. 1012% 1013% o display: Specifies a connection to an X server; returned from 1014% XOpenDisplay. 1015% 1016% o colormap: Specifies the ID of the X server colormap. 1017% 1018% o colors: Specifies an array of XColor structures. 1019% 1020% o number_colors: Specifies the number of XColor structures in the 1021% color definition array. 1022% 1023% o color: Specifies the desired RGB value to find in the colors array. 1024% 1025*/ 1026MagickPrivate void XBestPixel(Display *display,const Colormap colormap, 1027 XColor *colors,unsigned int number_colors,XColor *color) 1028{ 1029 MagickBooleanType 1030 query_server; 1031 1032 PixelInfo 1033 pixel; 1034 1035 double 1036 min_distance; 1037 1038 register double 1039 distance; 1040 1041 register int 1042 i, 1043 j; 1044 1045 Status 1046 status; 1047 1048 /* 1049 Find closest representation for the requested RGB color. 1050 */ 1051 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 1052 assert(display != (Display *) NULL); 1053 assert(color != (XColor *) NULL); 1054 status=XAllocColor(display,colormap,color); 1055 if (status != False) 1056 return; 1057 query_server=colors == (XColor *) NULL ? MagickTrue : MagickFalse; 1058 if (query_server != MagickFalse) 1059 { 1060 /* 1061 Read X server colormap. 1062 */ 1063 colors=(XColor *) AcquireQuantumMemory(number_colors,sizeof(*colors)); 1064 if (colors == (XColor *) NULL) 1065 { 1066 ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed", 1067 "..."); 1068 return; 1069 } 1070 for (i=0; i < (int) number_colors; i++) 1071 colors[i].pixel=(size_t) i; 1072 if (number_colors > 256) 1073 number_colors=256; 1074 (void) XQueryColors(display,colormap,colors,(int) number_colors); 1075 } 1076 min_distance=3.0*((double) QuantumRange+1.0)*((double) 1077 QuantumRange+1.0); 1078 j=0; 1079 for (i=0; i < (int) number_colors; i++) 1080 { 1081 pixel.red=colors[i].red-(double) color->red; 1082 distance=pixel.red*pixel.red; 1083 if (distance > min_distance) 1084 continue; 1085 pixel.green=colors[i].green-(double) color->green; 1086 distance+=pixel.green*pixel.green; 1087 if (distance > min_distance) 1088 continue; 1089 pixel.blue=colors[i].blue-(double) color->blue; 1090 distance+=pixel.blue*pixel.blue; 1091 if (distance > min_distance) 1092 continue; 1093 min_distance=distance; 1094 color->pixel=colors[i].pixel; 1095 j=i; 1096 } 1097 (void) XAllocColor(display,colormap,&colors[j]); 1098 if (query_server != MagickFalse) 1099 colors=(XColor *) RelinquishMagickMemory(colors); 1100} 1101 1102/* 1103%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1104% % 1105% % 1106% % 1107% X B e s t V i s u a l I n f o % 1108% % 1109% % 1110% % 1111%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1112% 1113% XBestVisualInfo() returns visual information for a visual that is the "best" 1114% the server supports. "Best" is defined as: 1115% 1116% 1. Restrict the visual list to those supported by the default screen. 1117% 1118% 2. If a visual type is specified, restrict the visual list to those of 1119% that type. 1120% 1121% 3. If a map type is specified, choose the visual that matches the id 1122% specified by the Standard Colormap. 1123% 1124% 4 From the list of visuals, choose one that can display the most 1125% simultaneous colors. If more than one visual can display the same 1126% number of simultaneous colors, one is chosen based on a rank. 1127% 1128% The format of the XBestVisualInfo method is: 1129% 1130% XVisualInfo *XBestVisualInfo(Display *display, 1131% XStandardColormap *map_info,XResourceInfo *resource_info) 1132% 1133% A description of each parameter follows: 1134% 1135% o visual_info: XBestVisualInfo returns a pointer to a X11 XVisualInfo 1136% structure. 1137% 1138% o display: Specifies a connection to an X server; returned from 1139% XOpenDisplay. 1140% 1141% o map_info: If map_type is specified, this structure is initialized 1142% with info from the Standard Colormap. 1143% 1144% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. 1145% 1146*/ 1147MagickPrivate XVisualInfo *XBestVisualInfo(Display *display, 1148 XStandardColormap *map_info,XResourceInfo *resource_info) 1149{ 1150#define MaxStandardColormaps 7 1151#define XVisualColormapSize(visual_info) MagickMin((unsigned int) (\ 1152 (visual_info->klass == TrueColor) || (visual_info->klass == DirectColor) ? \ 1153 visual_info->red_mask | visual_info->green_mask | visual_info->blue_mask : \ 1154 (unsigned long) visual_info->colormap_size),1UL << visual_info->depth) 1155 1156 char 1157 *map_type, 1158 *visual_type; 1159 1160 int 1161 visual_mask; 1162 1163 register int 1164 i; 1165 1166 size_t 1167 one; 1168 1169 static int 1170 number_visuals; 1171 1172 static XVisualInfo 1173 visual_template; 1174 1175 XVisualInfo 1176 *visual_info, 1177 *visual_list; 1178 1179 /* 1180 Restrict visual search by screen number. 1181 */ 1182 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 1183 assert(display != (Display *) NULL); 1184 assert(map_info != (XStandardColormap *) NULL); 1185 assert(resource_info != (XResourceInfo *) NULL); 1186 map_type=resource_info->map_type; 1187 visual_type=resource_info->visual_type; 1188 visual_mask=VisualScreenMask; 1189 visual_template.screen=XDefaultScreen(display); 1190 visual_template.depth=XDefaultDepth(display,XDefaultScreen(display)); 1191 one=1; 1192 if ((resource_info->immutable != MagickFalse) && (resource_info->colors != 0)) 1193 if (resource_info->colors <= (one << (size_t) visual_template.depth)) 1194 visual_mask|=VisualDepthMask; 1195 if (visual_type != (char *) NULL) 1196 { 1197 /* 1198 Restrict visual search by class or visual id. 1199 */ 1200 if (LocaleCompare("staticgray",visual_type) == 0) 1201 { 1202 visual_mask|=VisualClassMask; 1203 visual_template.klass=StaticGray; 1204 } 1205 else 1206 if (LocaleCompare("grayscale",visual_type) == 0) 1207 { 1208 visual_mask|=VisualClassMask; 1209 visual_template.klass=GrayScale; 1210 } 1211 else 1212 if (LocaleCompare("staticcolor",visual_type) == 0) 1213 { 1214 visual_mask|=VisualClassMask; 1215 visual_template.klass=StaticColor; 1216 } 1217 else 1218 if (LocaleCompare("pseudocolor",visual_type) == 0) 1219 { 1220 visual_mask|=VisualClassMask; 1221 visual_template.klass=PseudoColor; 1222 } 1223 else 1224 if (LocaleCompare("truecolor",visual_type) == 0) 1225 { 1226 visual_mask|=VisualClassMask; 1227 visual_template.klass=TrueColor; 1228 } 1229 else 1230 if (LocaleCompare("directcolor",visual_type) == 0) 1231 { 1232 visual_mask|=VisualClassMask; 1233 visual_template.klass=DirectColor; 1234 } 1235 else 1236 if (LocaleCompare("default",visual_type) == 0) 1237 { 1238 visual_mask|=VisualIDMask; 1239 visual_template.visualid=XVisualIDFromVisual( 1240 XDefaultVisual(display,XDefaultScreen(display))); 1241 } 1242 else 1243 if (isdigit((int) ((unsigned char) *visual_type)) != 0) 1244 { 1245 visual_mask|=VisualIDMask; 1246 visual_template.visualid= 1247 strtol(visual_type,(char **) NULL,0); 1248 } 1249 else 1250 ThrowXWindowException(XServerError, 1251 "UnrecognizedVisualSpecifier",visual_type); 1252 } 1253 /* 1254 Get all visuals that meet our criteria so far. 1255 */ 1256 number_visuals=0; 1257 visual_list=XGetVisualInfo(display,visual_mask,&visual_template, 1258 &number_visuals); 1259 visual_mask=VisualScreenMask | VisualIDMask; 1260 if ((number_visuals == 0) || (visual_list == (XVisualInfo *) NULL)) 1261 { 1262 /* 1263 Failed to get visual; try using the default visual. 1264 */ 1265 ThrowXWindowException(XServerWarning,"UnableToGetVisual",visual_type); 1266 visual_template.visualid=XVisualIDFromVisual(XDefaultVisual(display, 1267 XDefaultScreen(display))); 1268 visual_list=XGetVisualInfo(display,visual_mask,&visual_template, 1269 &number_visuals); 1270 if ((number_visuals == 0) || (visual_list == (XVisualInfo *) NULL)) 1271 return((XVisualInfo *) NULL); 1272 ThrowXWindowException(XServerWarning,"UsingDefaultVisual", 1273 XVisualClassName(visual_list->klass)); 1274 } 1275 resource_info->color_recovery=MagickFalse; 1276 if ((map_info != (XStandardColormap *) NULL) && (map_type != (char *) NULL)) 1277 { 1278 Atom 1279 map_property; 1280 1281 char 1282 map_name[MagickPathExtent]; 1283 1284 int 1285 j, 1286 number_maps; 1287 1288 Status 1289 status; 1290 1291 Window 1292 root_window; 1293 1294 XStandardColormap 1295 *map_list; 1296 1297 /* 1298 Choose a visual associated with a standard colormap. 1299 */ 1300 root_window=XRootWindow(display,XDefaultScreen(display)); 1301 status=False; 1302 number_maps=0; 1303 if (LocaleCompare(map_type,"list") != 0) 1304 { 1305 /* 1306 User specified Standard Colormap. 1307 */ 1308 (void) FormatLocaleString((char *) map_name,MagickPathExtent, 1309 "RGB_%s_MAP",map_type); 1310 LocaleUpper(map_name); 1311 map_property=XInternAtom(display,(char *) map_name,MagickTrue); 1312 if (map_property != (Atom) NULL) 1313 status=XGetRGBColormaps(display,root_window,&map_list,&number_maps, 1314 map_property); 1315 } 1316 else 1317 { 1318 static const char 1319 *colormap[MaxStandardColormaps]= 1320 { 1321 "_HP_RGB_SMOOTH_MAP_LIST", 1322 "RGB_BEST_MAP", 1323 "RGB_DEFAULT_MAP", 1324 "RGB_GRAY_MAP", 1325 "RGB_RED_MAP", 1326 "RGB_GREEN_MAP", 1327 "RGB_BLUE_MAP", 1328 }; 1329 1330 /* 1331 Choose a standard colormap from a list. 1332 */ 1333 for (i=0; i < MaxStandardColormaps; i++) 1334 { 1335 map_property=XInternAtom(display,(char *) colormap[i],MagickTrue); 1336 if (map_property == (Atom) NULL) 1337 continue; 1338 status=XGetRGBColormaps(display,root_window,&map_list,&number_maps, 1339 map_property); 1340 if (status != False) 1341 break; 1342 } 1343 resource_info->color_recovery=i == 0 ? MagickTrue : MagickFalse; 1344 } 1345 if (status == False) 1346 { 1347 ThrowXWindowException(XServerError,"UnableToGetStandardColormap", 1348 map_type); 1349 return((XVisualInfo *) NULL); 1350 } 1351 /* 1352 Search all Standard Colormaps and visuals for ids that match. 1353 */ 1354 *map_info=map_list[0]; 1355#if !defined(PRE_R4_ICCCM) 1356 visual_template.visualid=XVisualIDFromVisual(visual_list[0].visual); 1357 for (i=0; i < number_maps; i++) 1358 for (j=0; j < number_visuals; j++) 1359 if (map_list[i].visualid == 1360 XVisualIDFromVisual(visual_list[j].visual)) 1361 { 1362 *map_info=map_list[i]; 1363 visual_template.visualid=XVisualIDFromVisual( 1364 visual_list[j].visual); 1365 break; 1366 } 1367 if (map_info->visualid != visual_template.visualid) 1368 { 1369 ThrowXWindowException(XServerError, 1370 "UnableToMatchVisualToStandardColormap",map_type); 1371 return((XVisualInfo *) NULL); 1372 } 1373#endif 1374 if (map_info->colormap == (Colormap) NULL) 1375 { 1376 ThrowXWindowException(XServerError,"StandardColormapIsNotInitialized", 1377 map_type); 1378 return((XVisualInfo *) NULL); 1379 } 1380 (void) XFree((void *) map_list); 1381 } 1382 else 1383 { 1384 static const unsigned int 1385 rank[]= 1386 { 1387 StaticGray, 1388 GrayScale, 1389 StaticColor, 1390 DirectColor, 1391 TrueColor, 1392 PseudoColor 1393 }; 1394 1395 XVisualInfo 1396 *p; 1397 1398 /* 1399 Pick one visual that displays the most simultaneous colors. 1400 */ 1401 visual_info=visual_list; 1402 p=visual_list; 1403 for (i=1; i < number_visuals; i++) 1404 { 1405 p++; 1406 if (XVisualColormapSize(p) > XVisualColormapSize(visual_info)) 1407 visual_info=p; 1408 else 1409 if (XVisualColormapSize(p) == XVisualColormapSize(visual_info)) 1410 if (rank[p->klass] > rank[visual_info->klass]) 1411 visual_info=p; 1412 } 1413 visual_template.visualid=XVisualIDFromVisual(visual_info->visual); 1414 } 1415 (void) XFree((void *) visual_list); 1416 /* 1417 Retrieve only one visual by its screen & id number. 1418 */ 1419 visual_info=XGetVisualInfo(display,visual_mask,&visual_template, 1420 &number_visuals); 1421 if ((number_visuals == 0) || (visual_info == (XVisualInfo *) NULL)) 1422 return((XVisualInfo *) NULL); 1423 return(visual_info); 1424} 1425 1426/* 1427%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1428% % 1429% % 1430% % 1431% X C h e c k D e f i n e C u r s o r % 1432% % 1433% % 1434% % 1435%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1436% 1437% XCheckDefineCursor() prevents cursor changes on the root window. 1438% 1439% The format of the XXCheckDefineCursor method is: 1440% 1441% XCheckDefineCursor(display,window,cursor) 1442% 1443% A description of each parameter follows: 1444% 1445% o display: Specifies a connection to an X server; returned from 1446% XOpenDisplay. 1447% 1448% o window: the window. 1449% 1450% o cursor: the cursor. 1451% 1452*/ 1453MagickPrivate int XCheckDefineCursor(Display *display,Window window, 1454 Cursor cursor) 1455{ 1456 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 1457 assert(display != (Display *) NULL); 1458 if (window == XRootWindow(display,XDefaultScreen(display))) 1459 return(0); 1460 return(XDefineCursor(display,window,cursor)); 1461} 1462 1463/* 1464%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1465% % 1466% % 1467% % 1468% X C h e c k R e f r e s h W i n d o w s % 1469% % 1470% % 1471% % 1472%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1473% 1474% XCheckRefreshWindows() checks the X server for exposure events for a 1475% particular window and updates the areassociated with the exposure event. 1476% 1477% The format of the XCheckRefreshWindows method is: 1478% 1479% void XCheckRefreshWindows(Display *display,XWindows *windows) 1480% 1481% A description of each parameter follows: 1482% 1483% o display: Specifies a connection to an X server; returned from 1484% XOpenDisplay. 1485% 1486% o windows: Specifies a pointer to a XWindows structure. 1487% 1488*/ 1489MagickPrivate void XCheckRefreshWindows(Display *display,XWindows *windows) 1490{ 1491 Window 1492 id; 1493 1494 XEvent 1495 event; 1496 1497 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 1498 assert(display != (Display *) NULL); 1499 assert(windows != (XWindows *) NULL); 1500 XDelay(display,SuspendTime); 1501 id=windows->command.id; 1502 while (XCheckTypedWindowEvent(display,id,Expose,&event) != MagickFalse) 1503 (void) XCommandWidget(display,windows,(char const **) NULL,&event); 1504 id=windows->image.id; 1505 while (XCheckTypedWindowEvent(display,id,Expose,&event) != MagickFalse) 1506 XRefreshWindow(display,&windows->image,&event); 1507 XDelay(display,SuspendTime << 1); 1508 id=windows->command.id; 1509 while (XCheckTypedWindowEvent(display,id,Expose,&event) != MagickFalse) 1510 (void) XCommandWidget(display,windows,(char const **) NULL,&event); 1511 id=windows->image.id; 1512 while (XCheckTypedWindowEvent(display,id,Expose,&event) != MagickFalse) 1513 XRefreshWindow(display,&windows->image,&event); 1514} 1515 1516/* 1517%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1518% % 1519% % 1520% % 1521% X C l i e n t M e s s a g e % 1522% % 1523% % 1524% % 1525%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1526% 1527% XClientMessage() sends a reason to a window with XSendEvent. The reason is 1528% initialized with a particular protocol type and atom. 1529% 1530% The format of the XClientMessage function is: 1531% 1532% XClientMessage(display,window,protocol,reason,timestamp) 1533% 1534% A description of each parameter follows: 1535% 1536% o display: Specifies a pointer to the Display structure; returned from 1537% XOpenDisplay. 1538% 1539% o window: Specifies a pointer to a Window structure. 1540% 1541% o protocol: Specifies an atom value. 1542% 1543% o reason: Specifies an atom value which is the reason to send. 1544% 1545% o timestamp: Specifies a value of type Time. 1546% 1547*/ 1548MagickPrivate void XClientMessage(Display *display,const Window window, 1549 const Atom protocol,const Atom reason,const Time timestamp) 1550{ 1551 XClientMessageEvent 1552 client_event; 1553 1554 assert(display != (Display *) NULL); 1555 client_event.type=ClientMessage; 1556 client_event.window=window; 1557 client_event.message_type=protocol; 1558 client_event.format=32; 1559 client_event.data.l[0]=(long) reason; 1560 client_event.data.l[1]=(long) timestamp; 1561 (void) XSendEvent(display,window,MagickFalse,NoEventMask,(XEvent *) &client_event); 1562} 1563 1564/* 1565%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1566% % 1567% % 1568% % 1569+ X C l i e n t W i n d o w % 1570% % 1571% % 1572% % 1573%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1574% 1575% XClientWindow() finds a window, at or below the specified window, which has 1576% a WM_STATE property. If such a window is found, it is returned, otherwise 1577% the argument window is returned. 1578% 1579% The format of the XClientWindow function is: 1580% 1581% client_window=XClientWindow(display,target_window) 1582% 1583% A description of each parameter follows: 1584% 1585% o client_window: XClientWindow returns a window, at or below the specified 1586% window, which has a WM_STATE property otherwise the argument 1587% target_window is returned. 1588% 1589% o display: Specifies a pointer to the Display structure; returned from 1590% XOpenDisplay. 1591% 1592% o target_window: Specifies the window to find a WM_STATE property. 1593% 1594*/ 1595static Window XClientWindow(Display *display,Window target_window) 1596{ 1597 Atom 1598 state, 1599 type; 1600 1601 int 1602 format; 1603 1604 Status 1605 status; 1606 1607 unsigned char 1608 *data; 1609 1610 unsigned long 1611 after, 1612 number_items; 1613 1614 Window 1615 client_window; 1616 1617 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 1618 assert(display != (Display *) NULL); 1619 state=XInternAtom(display,"WM_STATE",MagickTrue); 1620 if (state == (Atom) NULL) 1621 return(target_window); 1622 type=(Atom) NULL; 1623 status=XGetWindowProperty(display,target_window,state,0L,0L,MagickFalse, 1624 (Atom) AnyPropertyType,&type,&format,&number_items,&after,&data); 1625 if ((status == Success) && (type != (Atom) NULL)) 1626 return(target_window); 1627 client_window=XWindowByProperty(display,target_window,state); 1628 if (client_window == (Window) NULL) 1629 return(target_window); 1630 return(client_window); 1631} 1632 1633/* 1634%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1635% % 1636% % 1637% % 1638+ X C o m p o n e n t T e r m i n u s % 1639% % 1640% % 1641% % 1642%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1643% 1644% XComponentTerminus() destroys the module component. 1645% 1646% The format of the XComponentTerminus method is: 1647% 1648% XComponentTerminus(void) 1649% 1650*/ 1651MagickPrivate void XComponentTerminus(void) 1652{ 1653 DestroyXResources(); 1654} 1655 1656/* 1657%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1658% % 1659% % 1660% % 1661% X C o n f i g u r e I m a g e C o l o r m a p % 1662% % 1663% % 1664% % 1665%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1666% 1667% XConfigureImageColormap() creates a new X colormap. 1668% 1669% The format of the XConfigureImageColormap method is: 1670% 1671% void XConfigureImageColormap(Display *display, 1672% XResourceInfo *resource_info,XWindows *windows,Image *image, 1673% ExceptionInfo *exception) 1674% 1675% A description of each parameter follows: 1676% 1677% o display: Specifies a connection to an X server; returned from 1678% XOpenDisplay. 1679% 1680% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. 1681% 1682% o windows: Specifies a pointer to a XWindows structure. 1683% 1684% o image: the image. 1685% 1686% o exception: return any errors or warnings in this structure. 1687% 1688*/ 1689MagickPrivate void XConfigureImageColormap(Display *display, 1690 XResourceInfo *resource_info,XWindows *windows,Image *image, 1691 ExceptionInfo *exception) 1692{ 1693 Colormap 1694 colormap; 1695 1696 /* 1697 Make standard colormap. 1698 */ 1699 XSetCursorState(display,windows,MagickTrue); 1700 XCheckRefreshWindows(display,windows); 1701 XMakeStandardColormap(display,windows->visual_info,resource_info,image, 1702 windows->map_info,windows->pixel_info,exception); 1703 colormap=windows->map_info->colormap; 1704 (void) XSetWindowColormap(display,windows->image.id,colormap); 1705 (void) XSetWindowColormap(display,windows->command.id,colormap); 1706 (void) XSetWindowColormap(display,windows->widget.id,colormap); 1707 if (windows->magnify.mapped != MagickFalse) 1708 (void) XSetWindowColormap(display,windows->magnify.id,colormap); 1709 if (windows->pan.mapped != MagickFalse) 1710 (void) XSetWindowColormap(display,windows->pan.id,colormap); 1711 XSetCursorState(display,windows,MagickFalse); 1712 XClientMessage(display,windows->image.id,windows->im_protocols, 1713 windows->im_update_colormap,CurrentTime); 1714} 1715 1716/* 1717%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1718% % 1719% % 1720% % 1721% X C o n s t r a i n W i n d o w P o s i t i o n % 1722% % 1723% % 1724% % 1725%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1726% 1727% XConstrainWindowPosition() assures a window is positioned within the X 1728% server boundaries. 1729% 1730% The format of the XConstrainWindowPosition method is: 1731% 1732% void XConstrainWindowPosition(Display *display,XWindowInfo *window_info) 1733% 1734% A description of each parameter follows: 1735% 1736% o display: Specifies a pointer to the Display structure; returned from 1737% XOpenDisplay. 1738% 1739% o window_info: Specifies a pointer to a XWindowInfo structure. 1740% 1741*/ 1742MagickPrivate void XConstrainWindowPosition(Display *display, 1743 XWindowInfo *window_info) 1744{ 1745 int 1746 limit; 1747 1748 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 1749 assert(display != (Display *) NULL); 1750 assert(window_info != (XWindowInfo *) NULL); 1751 limit=XDisplayWidth(display,window_info->screen)-window_info->width; 1752 if (window_info->x < 0) 1753 window_info->x=0; 1754 else 1755 if (window_info->x > (int) limit) 1756 window_info->x=(int) limit; 1757 limit=XDisplayHeight(display,window_info->screen)-window_info->height; 1758 if (window_info->y < 0) 1759 window_info->y=0; 1760 else 1761 if (window_info->y > limit) 1762 window_info->y=limit; 1763} 1764 1765/* 1766%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1767% % 1768% % 1769% % 1770% X D e l a y % 1771% % 1772% % 1773% % 1774%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1775% 1776% XDelay() suspends program execution for the number of milliseconds 1777% specified. 1778% 1779% The format of the Delay method is: 1780% 1781% void XDelay(Display *display,const size_t milliseconds) 1782% 1783% A description of each parameter follows: 1784% 1785% o display: Specifies a pointer to the Display structure; returned from 1786% XOpenDisplay. 1787% 1788% o milliseconds: Specifies the number of milliseconds to delay before 1789% returning. 1790% 1791*/ 1792MagickPrivate void XDelay(Display *display,const size_t milliseconds) 1793{ 1794 assert(display != (Display *) NULL); 1795 (void) XFlush(display); 1796 MagickDelay(milliseconds); 1797} 1798 1799/* 1800%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1801% % 1802% % 1803% % 1804% X D e s t r o y R e s o u r c e I n f o % 1805% % 1806% % 1807% % 1808%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1809% 1810% XDestroyResourceInfo() frees memory associated with the XResourceInfo 1811% structure. 1812% 1813% The format of the XDestroyResourceInfo method is: 1814% 1815% void XDestroyResourceInfo(XResourceInfo *resource_info) 1816% 1817% A description of each parameter follows: 1818% 1819% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. 1820% 1821*/ 1822MagickExport void XDestroyResourceInfo(XResourceInfo *resource_info) 1823{ 1824 if (resource_info->image_geometry != (char *) NULL) 1825 resource_info->image_geometry=(char *) 1826 RelinquishMagickMemory(resource_info->image_geometry); 1827 if (resource_info->quantize_info != (QuantizeInfo *) NULL) 1828 resource_info->quantize_info=DestroyQuantizeInfo( 1829 resource_info->quantize_info); 1830 if (resource_info->client_name != (char *) NULL) 1831 resource_info->client_name=(char *) 1832 RelinquishMagickMemory(resource_info->client_name); 1833 if (resource_info->name != (char *) NULL) 1834 resource_info->name=DestroyString(resource_info->name); 1835 (void) ResetMagickMemory(resource_info,0,sizeof(*resource_info)); 1836} 1837 1838/* 1839%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1840% % 1841% % 1842% % 1843% X D e s t r o y W i n d o w C o l o r s % 1844% % 1845% % 1846% % 1847%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1848% 1849% XDestroyWindowColors() frees X11 color resources previously saved on a 1850% window by XRetainWindowColors or programs like xsetroot. 1851% 1852% The format of the XDestroyWindowColors method is: 1853% 1854% void XDestroyWindowColors(Display *display,Window window) 1855% 1856% A description of each parameter follows: 1857% 1858% o display: Specifies a connection to an X server; returned from 1859% XOpenDisplay. 1860% 1861% o window: Specifies a pointer to a Window structure. 1862% 1863*/ 1864MagickPrivate void XDestroyWindowColors(Display *display,Window window) 1865{ 1866 Atom 1867 property, 1868 type; 1869 1870 int 1871 format; 1872 1873 Status 1874 status; 1875 1876 unsigned char 1877 *data; 1878 1879 unsigned long 1880 after, 1881 length; 1882 1883 /* 1884 If there are previous resources on the root window, destroy them. 1885 */ 1886 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 1887 assert(display != (Display *) NULL); 1888 property=XInternAtom(display,"_XSETROOT_ID",MagickFalse); 1889 if (property == (Atom) NULL) 1890 { 1891 ThrowXWindowException(XServerError,"UnableToCreateProperty", 1892 "_XSETROOT_ID"); 1893 return; 1894 } 1895 status=XGetWindowProperty(display,window,property,0L,1L,MagickTrue, 1896 (Atom) AnyPropertyType,&type,&format,&length,&after,&data); 1897 if (status != Success) 1898 return; 1899 if ((type == XA_PIXMAP) && (format == 32) && (length == 1) && (after == 0)) 1900 { 1901 (void) XKillClient(display,(XID) (*((Pixmap *) data))); 1902 (void) XDeleteProperty(display,window,property); 1903 } 1904 if (type != None) 1905 (void) XFree((void *) data); 1906} 1907 1908/* 1909%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1910% % 1911% % 1912% % 1913% X D i s p l a y I m a g e I n f o % 1914% % 1915% % 1916% % 1917%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1918% 1919% XDisplayImageInfo() displays information about an X image. 1920% 1921% The format of the XDisplayImageInfo method is: 1922% 1923% void XDisplayImageInfo(Display *display, 1924% const XResourceInfo *resource_info,XWindows *windows,Image *undo_image, 1925% Image *image,ExceptionInfo *exception) 1926% 1927% A description of each parameter follows: 1928% 1929% o display: Specifies a connection to an X server; returned from 1930% XOpenDisplay. 1931% 1932% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. 1933% 1934% o windows: Specifies a pointer to a XWindows structure. 1935% 1936% o undo_image: the undo image. 1937% 1938% o image: the image. 1939% 1940% o exception: return any errors or warnings in this structure. 1941% 1942*/ 1943MagickPrivate void XDisplayImageInfo(Display *display, 1944 const XResourceInfo *resource_info,XWindows *windows,Image *undo_image, 1945 Image *image,ExceptionInfo *exception) 1946{ 1947 char 1948 filename[MagickPathExtent], 1949 *text, 1950 **textlist; 1951 1952 FILE 1953 *file; 1954 1955 int 1956 unique_file; 1957 1958 register ssize_t 1959 i; 1960 1961 size_t 1962 number_pixels; 1963 1964 ssize_t 1965 bytes; 1966 1967 unsigned int 1968 levels; 1969 1970 /* 1971 Write info about the X server to a file. 1972 */ 1973 assert(display != (Display *) NULL); 1974 assert(resource_info != (XResourceInfo *) NULL); 1975 assert(windows != (XWindows *) NULL); 1976 assert(image != (Image *) NULL); 1977 if (image->debug) 1978 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 1979 file=(FILE *) NULL; 1980 unique_file=AcquireUniqueFileResource(filename); 1981 if (unique_file != -1) 1982 file=fdopen(unique_file,"w"); 1983 if ((unique_file == -1) || (file == (FILE *) NULL)) 1984 { 1985 XNoticeWidget(display,windows,"Unable to display image info",filename); 1986 return; 1987 } 1988 if (resource_info->gamma_correct != MagickFalse) 1989 if (resource_info->display_gamma != (char *) NULL) 1990 (void) FormatLocaleFile(file,"Display\n gamma: %s\n\n", 1991 resource_info->display_gamma); 1992 /* 1993 Write info about the X image to a file. 1994 */ 1995 (void) FormatLocaleFile(file,"X\n visual: %s\n", 1996 XVisualClassName((int) windows->image.storage_class)); 1997 (void) FormatLocaleFile(file," depth: %d\n",windows->image.ximage->depth); 1998 if (windows->visual_info->colormap_size != 0) 1999 (void) FormatLocaleFile(file," colormap size: %d\n", 2000 windows->visual_info->colormap_size); 2001 if (resource_info->colormap== SharedColormap) 2002 (void) FormatLocaleFile(file," colormap type: Shared\n"); 2003 else 2004 (void) FormatLocaleFile(file," colormap type: Private\n"); 2005 (void) FormatLocaleFile(file," geometry: %dx%d\n", 2006 windows->image.ximage->width,windows->image.ximage->height); 2007 if (windows->image.crop_geometry != (char *) NULL) 2008 (void) FormatLocaleFile(file," crop geometry: %s\n", 2009 windows->image.crop_geometry); 2010 if (windows->image.pixmap == (Pixmap) NULL) 2011 (void) FormatLocaleFile(file," type: X Image\n"); 2012 else 2013 (void) FormatLocaleFile(file," type: Pixmap\n"); 2014 if (windows->image.shape != MagickFalse) 2015 (void) FormatLocaleFile(file," non-rectangular shape: True\n"); 2016 else 2017 (void) FormatLocaleFile(file," non-rectangular shape: False\n"); 2018 if (windows->image.shared_memory != MagickFalse) 2019 (void) FormatLocaleFile(file," shared memory: True\n"); 2020 else 2021 (void) FormatLocaleFile(file," shared memory: False\n"); 2022 (void) FormatLocaleFile(file,"\n"); 2023 if (resource_info->font != (char *) NULL) 2024 (void) FormatLocaleFile(file,"Font: %s\n\n",resource_info->font); 2025 if (resource_info->text_font != (char *) NULL) 2026 (void) FormatLocaleFile(file,"Text font: %s\n\n",resource_info->text_font); 2027 /* 2028 Write info about the undo cache to a file. 2029 */ 2030 bytes=0; 2031 for (levels=0; undo_image != (Image *) NULL; levels++) 2032 { 2033 number_pixels=undo_image->list->columns*undo_image->list->rows; 2034 bytes+=number_pixels*sizeof(PixelInfo); 2035 undo_image=GetPreviousImageInList(undo_image); 2036 } 2037 (void) FormatLocaleFile(file,"Undo Edit Cache\n levels: %u\n",levels); 2038 (void) FormatLocaleFile(file," bytes: %.20gmb\n",(double) 2039 ((bytes+(1 << 19)) >> 20)); 2040 (void) FormatLocaleFile(file," limit: %.20gmb\n\n",(double) 2041 resource_info->undo_cache); 2042 /* 2043 Write info about the image to a file. 2044 */ 2045 (void) IdentifyImage(image,file,MagickTrue,exception); 2046 (void) fclose(file); 2047 text=FileToString(filename,~0UL,exception); 2048 (void) RelinquishUniqueFileResource(filename); 2049 if (text == (char *) NULL) 2050 { 2051 XNoticeWidget(display,windows,"MemoryAllocationFailed", 2052 "UnableToDisplayImageInfo"); 2053 return; 2054 } 2055 textlist=StringToList(text); 2056 if (textlist != (char **) NULL) 2057 { 2058 char 2059 title[MagickPathExtent]; 2060 2061 /* 2062 Display information about the image in the Text View widget. 2063 */ 2064 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen); 2065 (void) FormatLocaleString(title,MagickPathExtent,"Image Info: %s", 2066 image->filename); 2067 XTextViewWidget(display,resource_info,windows,MagickTrue,title, 2068 (char const **) textlist); 2069 for (i=0; textlist[i] != (char *) NULL; i++) 2070 textlist[i]=DestroyString(textlist[i]); 2071 textlist=(char **) RelinquishMagickMemory(textlist); 2072 } 2073 text=DestroyString(text); 2074} 2075 2076/* 2077%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2078% % 2079% % 2080% % 2081+ X D i t h e r I m a g e % 2082% % 2083% % 2084% % 2085%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2086% 2087% XDitherImage() dithers the reference image as required by the HP Color 2088% Recovery algorithm. The color values are quantized to 3 bits of red and 2089% green, and 2 bits of blue (3/3/2) and can be used as indices into a 8-bit X 2090% standard colormap. 2091% 2092% The format of the XDitherImage method is: 2093% 2094% void XDitherImage(Image *image,XImage *ximage,ExceptionInfo *exception) 2095% 2096% A description of each parameter follows: 2097% 2098% o image: the image. 2099% 2100% o ximage: Specifies a pointer to a XImage structure; returned from 2101% XCreateImage. 2102% 2103% o exception: return any errors or warnings in this structure. 2104% 2105*/ 2106static void XDitherImage(Image *image,XImage *ximage,ExceptionInfo *exception) 2107{ 2108 static const short int 2109 dither_red[2][16]= 2110 { 2111 {-16, 4, -1, 11,-14, 6, -3, 9,-15, 5, -2, 10,-13, 7, -4, 8}, 2112 { 15, -5, 0,-12, 13, -7, 2,-10, 14, -6, 1,-11, 12, -8, 3, -9} 2113 }, 2114 dither_green[2][16]= 2115 { 2116 { 11,-15, 7, -3, 8,-14, 4, -2, 10,-16, 6, -4, 9,-13, 5, -1}, 2117 {-12, 14, -8, 2, -9, 13, -5, 1,-11, 15, -7, 3,-10, 12, -6, 0} 2118 }, 2119 dither_blue[2][16]= 2120 { 2121 { -3, 9,-13, 7, -1, 11,-15, 5, -4, 8,-14, 6, -2, 10,-16, 4}, 2122 { 2,-10, 12, -8, 0,-12, 14, -6, 3, -9, 13, -7, 1,-11, 15, -5} 2123 }; 2124 2125 CacheView 2126 *image_view; 2127 2128 int 2129 value, 2130 y; 2131 2132 PixelInfo 2133 color; 2134 2135 register char 2136 *q; 2137 2138 register const Quantum 2139 *p; 2140 2141 register int 2142 i, 2143 j, 2144 x; 2145 2146 unsigned int 2147 scanline_pad; 2148 2149 register size_t 2150 pixel; 2151 2152 unsigned char 2153 *blue_map[2][16], 2154 *green_map[2][16], 2155 *red_map[2][16]; 2156 2157 /* 2158 Allocate and initialize dither maps. 2159 */ 2160 for (i=0; i < 2; i++) 2161 for (j=0; j < 16; j++) 2162 { 2163 red_map[i][j]=(unsigned char *) AcquireQuantumMemory(256UL, 2164 sizeof(*red_map)); 2165 green_map[i][j]=(unsigned char *) AcquireQuantumMemory(256UL, 2166 sizeof(*green_map)); 2167 blue_map[i][j]=(unsigned char *) AcquireQuantumMemory(256UL, 2168 sizeof(*blue_map)); 2169 if ((red_map[i][j] == (unsigned char *) NULL) || 2170 (green_map[i][j] == (unsigned char *) NULL) || 2171 (blue_map[i][j] == (unsigned char *) NULL)) 2172 { 2173 ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed", 2174 image->filename); 2175 return; 2176 } 2177 } 2178 /* 2179 Initialize dither tables. 2180 */ 2181 for (i=0; i < 2; i++) 2182 for (j=0; j < 16; j++) 2183 for (x=0; x < 256; x++) 2184 { 2185 value=x-16; 2186 if (x < 48) 2187 value=x/2+8; 2188 value+=dither_red[i][j]; 2189 red_map[i][j][x]=(unsigned char) 2190 ((value < 0) ? 0 : (value > 255) ? 255 : value); 2191 value=x-16; 2192 if (x < 48) 2193 value=x/2+8; 2194 value+=dither_green[i][j]; 2195 green_map[i][j][x]=(unsigned char) 2196 ((value < 0) ? 0 : (value > 255) ? 255 : value); 2197 value=x-32; 2198 if (x < 112) 2199 value=x/2+24; 2200 value+=((size_t) dither_blue[i][j] << 1); 2201 blue_map[i][j][x]=(unsigned char) 2202 ((value < 0) ? 0 : (value > 255) ? 255 : value); 2203 } 2204 /* 2205 Dither image. 2206 */ 2207 scanline_pad=(unsigned int) (ximage->bytes_per_line- 2208 ((size_t) (ximage->width*ximage->bits_per_pixel) >> 3)); 2209 i=0; 2210 j=0; 2211 q=ximage->data; 2212 image_view=AcquireVirtualCacheView(image,exception); 2213 for (y=0; y < (int) image->rows; y++) 2214 { 2215 p=GetCacheViewVirtualPixels(image_view,0,(ssize_t) y,image->columns,1, 2216 exception); 2217 if (p == (const Quantum *) NULL) 2218 break; 2219 for (x=0; x < (int) image->columns; x++) 2220 { 2221 color.red=(double) ClampToQuantum((double) (red_map[i][j][ 2222 (int) ScaleQuantumToChar(GetPixelRed(image,p))] << 8)); 2223 color.green=(double) ClampToQuantum((double) (green_map[i][j][ 2224 (int) ScaleQuantumToChar(GetPixelGreen(image,p))] << 8)); 2225 color.blue=(double) ClampToQuantum((double) (blue_map[i][j][ 2226 (int) ScaleQuantumToChar(GetPixelBlue(image,p))] << 8)); 2227 pixel=(size_t) (((size_t) color.red & 0xe0) | 2228 (((size_t) color.green & 0xe0) >> 3) | 2229 (((size_t) color.blue & 0xc0) >> 6)); 2230 *q++=(char) pixel; 2231 p+=GetPixelChannels(image); 2232 j++; 2233 if (j == 16) 2234 j=0; 2235 } 2236 q+=scanline_pad; 2237 i++; 2238 if (i == 2) 2239 i=0; 2240 } 2241 image_view=DestroyCacheView(image_view); 2242 /* 2243 Free allocated memory. 2244 */ 2245 for (i=0; i < 2; i++) 2246 for (j=0; j < 16; j++) 2247 { 2248 green_map[i][j]=(unsigned char *) RelinquishMagickMemory(green_map[i][j]); 2249 blue_map[i][j]=(unsigned char *) RelinquishMagickMemory(blue_map[i][j]); 2250 red_map[i][j]=(unsigned char *) RelinquishMagickMemory(red_map[i][j]); 2251 } 2252} 2253 2254/* 2255%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2256% % 2257% % 2258% % 2259% X D r a w I m a g e % 2260% % 2261% % 2262% % 2263%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2264% 2265% XDrawImage() draws a line on the image. 2266% 2267% The format of the XDrawImage method is: 2268% 2269% MagickBooleanType XDrawImage(Display *display,const XPixelInfo *pixel, 2270% XDrawInfo *draw_info,Image *image,ExceptionInfo *exception) 2271% 2272% A description of each parameter follows: 2273% 2274% o display: Specifies a connection to an X server; returned from 2275% XOpenDisplay. 2276% 2277% o pixel: Specifies a pointer to a XPixelInfo structure. 2278% 2279% o draw_info: Specifies a pointer to a XDrawInfo structure. 2280% 2281% o image: the image. 2282% 2283% o exception: return any errors or warnings in this structure. 2284% 2285*/ 2286MagickPrivate MagickBooleanType XDrawImage(Display *display, 2287 const XPixelInfo *pixel,XDrawInfo *draw_info,Image *image, 2288 ExceptionInfo *exception) 2289{ 2290 CacheView 2291 *draw_view; 2292 2293 GC 2294 draw_context; 2295 2296 Image 2297 *draw_image; 2298 2299 int 2300 x, 2301 y; 2302 2303 PixelTrait 2304 alpha_trait; 2305 2306 Pixmap 2307 draw_pixmap; 2308 2309 unsigned int 2310 depth, 2311 height, 2312 width; 2313 2314 Window 2315 root_window; 2316 2317 XGCValues 2318 context_values; 2319 2320 XImage 2321 *draw_ximage; 2322 2323 /* 2324 Initialize drawd image. 2325 */ 2326 assert(display != (Display *) NULL); 2327 assert(pixel != (XPixelInfo *) NULL); 2328 assert(draw_info != (XDrawInfo *) NULL); 2329 assert(image != (Image *) NULL); 2330 if (image->debug != MagickFalse) 2331 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 2332 /* 2333 Initialize drawd pixmap. 2334 */ 2335 root_window=XRootWindow(display,XDefaultScreen(display)); 2336 depth=(unsigned int) XDefaultDepth(display,XDefaultScreen(display)); 2337 draw_pixmap=XCreatePixmap(display,root_window,draw_info->width, 2338 draw_info->height,depth); 2339 if (draw_pixmap == (Pixmap) NULL) 2340 return(MagickFalse); 2341 /* 2342 Initialize graphics info. 2343 */ 2344 context_values.background=(size_t) (~0); 2345 context_values.foreground=0; 2346 context_values.line_width=(int) draw_info->line_width; 2347 draw_context=XCreateGC(display,root_window,(size_t) 2348 (GCBackground | GCForeground | GCLineWidth),&context_values); 2349 if (draw_context == (GC) NULL) 2350 return(MagickFalse); 2351 /* 2352 Clear pixmap. 2353 */ 2354 (void) XFillRectangle(display,draw_pixmap,draw_context,0,0,draw_info->width, 2355 draw_info->height); 2356 /* 2357 Draw line to pixmap. 2358 */ 2359 (void) XSetBackground(display,draw_context,0); 2360 (void) XSetForeground(display,draw_context,(size_t) (~0)); 2361 if (draw_info->stipple != (Pixmap) NULL) 2362 { 2363 (void) XSetFillStyle(display,draw_context,FillOpaqueStippled); 2364 (void) XSetStipple(display,draw_context,draw_info->stipple); 2365 } 2366 switch (draw_info->element) 2367 { 2368 case PointElement: 2369 default: 2370 { 2371 (void) XDrawLines(display,draw_pixmap,draw_context, 2372 draw_info->coordinate_info,(int) draw_info->number_coordinates, 2373 CoordModeOrigin); 2374 break; 2375 } 2376 case LineElement: 2377 { 2378 (void) XDrawLine(display,draw_pixmap,draw_context,draw_info->line_info.x1, 2379 draw_info->line_info.y1,draw_info->line_info.x2, 2380 draw_info->line_info.y2); 2381 break; 2382 } 2383 case RectangleElement: 2384 { 2385 (void) XDrawRectangle(display,draw_pixmap,draw_context, 2386 (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y, 2387 (unsigned int) draw_info->rectangle_info.width, 2388 (unsigned int) draw_info->rectangle_info.height); 2389 break; 2390 } 2391 case FillRectangleElement: 2392 { 2393 (void) XFillRectangle(display,draw_pixmap,draw_context, 2394 (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y, 2395 (unsigned int) draw_info->rectangle_info.width, 2396 (unsigned int) draw_info->rectangle_info.height); 2397 break; 2398 } 2399 case CircleElement: 2400 case EllipseElement: 2401 { 2402 (void) XDrawArc(display,draw_pixmap,draw_context, 2403 (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y, 2404 (unsigned int) draw_info->rectangle_info.width, 2405 (unsigned int) draw_info->rectangle_info.height,0,360*64); 2406 break; 2407 } 2408 case FillCircleElement: 2409 case FillEllipseElement: 2410 { 2411 (void) XFillArc(display,draw_pixmap,draw_context, 2412 (int) draw_info->rectangle_info.x,(int) draw_info->rectangle_info.y, 2413 (unsigned int) draw_info->rectangle_info.width, 2414 (unsigned int) draw_info->rectangle_info.height,0,360*64); 2415 break; 2416 } 2417 case PolygonElement: 2418 { 2419 XPoint 2420 *coordinate_info; 2421 2422 coordinate_info=draw_info->coordinate_info; 2423 (void) XDrawLines(display,draw_pixmap,draw_context,coordinate_info, 2424 (int) draw_info->number_coordinates,CoordModeOrigin); 2425 (void) XDrawLine(display,draw_pixmap,draw_context, 2426 coordinate_info[draw_info->number_coordinates-1].x, 2427 coordinate_info[draw_info->number_coordinates-1].y, 2428 coordinate_info[0].x,coordinate_info[0].y); 2429 break; 2430 } 2431 case FillPolygonElement: 2432 { 2433 (void) XFillPolygon(display,draw_pixmap,draw_context, 2434 draw_info->coordinate_info,(int) draw_info->number_coordinates,Complex, 2435 CoordModeOrigin); 2436 break; 2437 } 2438 } 2439 (void) XFreeGC(display,draw_context); 2440 /* 2441 Initialize X image. 2442 */ 2443 draw_ximage=XGetImage(display,draw_pixmap,0,0,draw_info->width, 2444 draw_info->height,AllPlanes,ZPixmap); 2445 if (draw_ximage == (XImage *) NULL) 2446 return(MagickFalse); 2447 (void) XFreePixmap(display,draw_pixmap); 2448 /* 2449 Initialize draw image. 2450 */ 2451 draw_image=AcquireImage((ImageInfo *) NULL,exception); 2452 if (draw_image == (Image *) NULL) 2453 return(MagickFalse); 2454 draw_image->columns=draw_info->width; 2455 draw_image->rows=draw_info->height; 2456 /* 2457 Transfer drawn X image to image. 2458 */ 2459 width=(unsigned int) image->columns; 2460 height=(unsigned int) image->rows; 2461 x=0; 2462 y=0; 2463 (void) XParseGeometry(draw_info->geometry,&x,&y,&width,&height); 2464 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,(ssize_t) x, 2465 (ssize_t) y,&draw_image->background_color,exception); 2466 if (SetImageStorageClass(draw_image,DirectClass,exception) == MagickFalse) 2467 return(MagickFalse); 2468 draw_image->alpha_trait=BlendPixelTrait; 2469 draw_view=AcquireAuthenticCacheView(draw_image,exception); 2470 for (y=0; y < (int) draw_image->rows; y++) 2471 { 2472 register int 2473 x; 2474 2475 register Quantum 2476 *magick_restrict q; 2477 2478 q=QueueCacheViewAuthenticPixels(draw_view,0,(ssize_t) y,draw_image->columns, 2479 1,exception); 2480 if (q == (Quantum *) NULL) 2481 break; 2482 for (x=0; x < (int) draw_image->columns; x++) 2483 { 2484 if (XGetPixel(draw_ximage,x,y) == 0) 2485 { 2486 /* 2487 Set this pixel to the background color. 2488 */ 2489 SetPixelViaPixelInfo(draw_image,&draw_image->background_color,q); 2490 SetPixelAlpha(draw_image,(Quantum) (draw_info->stencil == 2491 OpaqueStencil ? TransparentAlpha : OpaqueAlpha),q); 2492 } 2493 else 2494 { 2495 /* 2496 Set this pixel to the pen color. 2497 */ 2498 SetPixelRed(draw_image,ScaleShortToQuantum( 2499 pixel->pen_color.red),q); 2500 SetPixelGreen(draw_image,ScaleShortToQuantum( 2501 pixel->pen_color.green),q); 2502 SetPixelBlue(draw_image,ScaleShortToQuantum( 2503 pixel->pen_color.blue),q); 2504 SetPixelAlpha(draw_image,(Quantum) (draw_info->stencil == 2505 OpaqueStencil ? OpaqueAlpha : TransparentAlpha),q); 2506 } 2507 q+=GetPixelChannels(draw_image); 2508 } 2509 if (SyncCacheViewAuthenticPixels(draw_view,exception) == MagickFalse) 2510 break; 2511 } 2512 draw_view=DestroyCacheView(draw_view); 2513 XDestroyImage(draw_ximage); 2514 /* 2515 Determine draw geometry. 2516 */ 2517 (void) XParseGeometry(draw_info->geometry,&x,&y,&width,&height); 2518 if ((width != (unsigned int) draw_image->columns) || 2519 (height != (unsigned int) draw_image->rows)) 2520 { 2521 char 2522 image_geometry[MagickPathExtent]; 2523 2524 /* 2525 Scale image. 2526 */ 2527 (void) FormatLocaleString(image_geometry,MagickPathExtent,"%ux%u", 2528 width,height); 2529 (void) TransformImage(&draw_image,(char *) NULL,image_geometry, 2530 exception); 2531 } 2532 if (draw_info->degrees != 0.0) 2533 { 2534 Image 2535 *rotate_image; 2536 2537 int 2538 rotations; 2539 2540 double 2541 normalized_degrees; 2542 2543 /* 2544 Rotate image. 2545 */ 2546 rotate_image=RotateImage(draw_image,draw_info->degrees,exception); 2547 if (rotate_image == (Image *) NULL) 2548 return(MagickFalse); 2549 draw_image=DestroyImage(draw_image); 2550 draw_image=rotate_image; 2551 /* 2552 Annotation is relative to the degree of rotation. 2553 */ 2554 normalized_degrees=draw_info->degrees; 2555 while (normalized_degrees < -45.0) 2556 normalized_degrees+=360.0; 2557 for (rotations=0; normalized_degrees > 45.0; rotations++) 2558 normalized_degrees-=90.0; 2559 switch (rotations % 4) 2560 { 2561 default: 2562 case 0: 2563 break; 2564 case 1: 2565 { 2566 /* 2567 Rotate 90 degrees. 2568 */ 2569 x=x-(int) draw_image->columns/2; 2570 y=y+(int) draw_image->columns/2; 2571 break; 2572 } 2573 case 2: 2574 { 2575 /* 2576 Rotate 180 degrees. 2577 */ 2578 x=x-(int) draw_image->columns; 2579 break; 2580 } 2581 case 3: 2582 { 2583 /* 2584 Rotate 270 degrees. 2585 */ 2586 x=x-(int) draw_image->columns/2; 2587 y=y-(int) (draw_image->rows-(draw_image->columns/2)); 2588 break; 2589 } 2590 } 2591 } 2592 /* 2593 Composite text onto the image. 2594 */ 2595 draw_view=AcquireAuthenticCacheView(draw_image,exception); 2596 for (y=0; y < (int) draw_image->rows; y++) 2597 { 2598 register int 2599 x; 2600 2601 register Quantum 2602 *magick_restrict q; 2603 2604 q=GetCacheViewAuthenticPixels(draw_view,0,(ssize_t) y,draw_image->columns,1, 2605 exception); 2606 if (q == (Quantum *) NULL) 2607 break; 2608 for (x=0; x < (int) draw_image->columns; x++) 2609 { 2610 if (GetPixelAlpha(image,q) != TransparentAlpha) 2611 SetPixelAlpha(draw_image,OpaqueAlpha,q); 2612 q+=GetPixelChannels(draw_image); 2613 } 2614 if (SyncCacheViewAuthenticPixels(draw_view,exception) == MagickFalse) 2615 break; 2616 } 2617 draw_view=DestroyCacheView(draw_view); 2618 (void) XParseGeometry(draw_info->geometry,&x,&y,&width,&height); 2619 if (draw_info->stencil == TransparentStencil) 2620 (void) CompositeImage(image,draw_image,CopyAlphaCompositeOp,MagickTrue, 2621 (ssize_t) x,(ssize_t) y,exception); 2622 else 2623 { 2624 alpha_trait=image->alpha_trait; 2625 (void) CompositeImage(image,draw_image,OverCompositeOp,MagickTrue, 2626 (ssize_t) x,(ssize_t) y,exception); 2627 image->alpha_trait=alpha_trait; 2628 } 2629 draw_image=DestroyImage(draw_image); 2630 return(MagickTrue); 2631} 2632 2633/* 2634%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2635% % 2636% % 2637% % 2638% X E r r o r % 2639% % 2640% % 2641% % 2642%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2643% 2644% XError() ignores BadWindow errors for XQueryTree and XGetWindowAttributes, 2645% and ignores BadDrawable errors for XGetGeometry, and ignores BadValue errors 2646% for XQueryColor. It returns MagickFalse in those cases. Otherwise it 2647% returns True. 2648% 2649% The format of the XError function is: 2650% 2651% int XError(display,error) 2652% 2653% A description of each parameter follows: 2654% 2655% o display: Specifies a pointer to the Display structure; returned from 2656% XOpenDisplay. 2657% 2658% o error: Specifies the error event. 2659% 2660*/ 2661 2662#if defined(__cplusplus) || defined(c_plusplus) 2663extern "C" { 2664#endif 2665 2666MagickExport int XError(Display *display,XErrorEvent *error) 2667{ 2668 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 2669 assert(display != (Display *) NULL); 2670 assert(error != (XErrorEvent *) NULL); 2671 xerror_alert=MagickTrue; 2672 switch (error->request_code) 2673 { 2674 case X_GetGeometry: 2675 { 2676 if ((int) error->error_code == BadDrawable) 2677 return(MagickFalse); 2678 break; 2679 } 2680 case X_GetWindowAttributes: 2681 case X_QueryTree: 2682 { 2683 if ((int) error->error_code == BadWindow) 2684 return(MagickFalse); 2685 break; 2686 } 2687 case X_QueryColors: 2688 { 2689 if ((int) error->error_code == BadValue) 2690 return(MagickFalse); 2691 break; 2692 } 2693 } 2694 return(MagickTrue); 2695} 2696 2697#if defined(__cplusplus) || defined(c_plusplus) 2698} 2699#endif 2700 2701/* 2702%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2703% % 2704% % 2705% % 2706% X F r e e R e s o u r c e s % 2707% % 2708% % 2709% % 2710%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2711% 2712% XFreeResources() frees X11 resources. 2713% 2714% The format of the XFreeResources method is: 2715% 2716% void XFreeResources(Display *display,XVisualInfo *visual_info, 2717% XStandardColormap *map_info,XPixelInfo *pixel,XFontStruct *font_info, 2718% XResourceInfo *resource_info,XWindowInfo *window_info) 2719% resource_info,window_info) 2720% 2721% A description of each parameter follows: 2722% 2723% o display: Specifies a connection to an X server; returned from 2724% XOpenDisplay. 2725% 2726% o visual_info: Specifies a pointer to a X11 XVisualInfo structure; 2727% returned from XGetVisualInfo. 2728% 2729% o map_info: If map_type is specified, this structure is initialized 2730% with info from the Standard Colormap. 2731% 2732% o pixel: Specifies a pointer to a XPixelInfo structure. 2733% 2734% o font_info: Specifies a pointer to a XFontStruct structure. 2735% 2736% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. 2737% 2738% o window_info: Specifies a pointer to a X11 XWindowInfo structure. 2739% 2740*/ 2741MagickPrivate void XFreeResources(Display *display,XVisualInfo *visual_info, 2742 XStandardColormap *map_info,XPixelInfo *pixel,XFontStruct *font_info, 2743 XResourceInfo *resource_info,XWindowInfo *window_info) 2744{ 2745 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 2746 assert(display != (Display *) NULL); 2747 assert(resource_info != (XResourceInfo *) NULL); 2748 if (window_info != (XWindowInfo *) NULL) 2749 { 2750 /* 2751 Free X image. 2752 */ 2753 if (window_info->ximage != (XImage *) NULL) 2754 XDestroyImage(window_info->ximage); 2755 if (window_info->id != (Window) NULL) 2756 { 2757 /* 2758 Free destroy window and free cursors. 2759 */ 2760 if (window_info->id != XRootWindow(display,visual_info->screen)) 2761 (void) XDestroyWindow(display,window_info->id); 2762 if (window_info->annotate_context != (GC) NULL) 2763 (void) XFreeGC(display,window_info->annotate_context); 2764 if (window_info->highlight_context != (GC) NULL) 2765 (void) XFreeGC(display,window_info->highlight_context); 2766 if (window_info->widget_context != (GC) NULL) 2767 (void) XFreeGC(display,window_info->widget_context); 2768 if (window_info->cursor != (Cursor) NULL) 2769 (void) XFreeCursor(display,window_info->cursor); 2770 window_info->cursor=(Cursor) NULL; 2771 if (window_info->busy_cursor != (Cursor) NULL) 2772 (void) XFreeCursor(display,window_info->busy_cursor); 2773 window_info->busy_cursor=(Cursor) NULL; 2774 } 2775 } 2776 /* 2777 Free font. 2778 */ 2779 if (font_info != (XFontStruct *) NULL) 2780 { 2781 (void) XFreeFont(display,font_info); 2782 font_info=(XFontStruct *) NULL; 2783 } 2784 if (map_info != (XStandardColormap *) NULL) 2785 { 2786 /* 2787 Free X Standard Colormap. 2788 */ 2789 if (resource_info->map_type == (char *) NULL) 2790 (void) XFreeStandardColormap(display,visual_info,map_info,pixel); 2791 (void) XFree((void *) map_info); 2792 } 2793 /* 2794 Free X visual info. 2795 */ 2796 if (visual_info != (XVisualInfo *) NULL) 2797 (void) XFree((void *) visual_info); 2798 if (resource_info->close_server != MagickFalse) 2799 (void) XCloseDisplay(display); 2800} 2801 2802/* 2803%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2804% % 2805% % 2806% % 2807% X F r e e S t a n d a r d C o l o r m a p % 2808% % 2809% % 2810% % 2811%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2812% 2813% XFreeStandardColormap() frees an X11 colormap. 2814% 2815% The format of the XFreeStandardColormap method is: 2816% 2817% void XFreeStandardColormap(Display *display, 2818% const XVisualInfo *visual_info,XStandardColormap *map_info, 2819% XPixelInfo *pixel) 2820% 2821% A description of each parameter follows: 2822% 2823% o display: Specifies a connection to an X server; returned from 2824% XOpenDisplay. 2825% 2826% o visual_info: Specifies a pointer to a X11 XVisualInfo structure; 2827% returned from XGetVisualInfo. 2828% 2829% o map_info: If map_type is specified, this structure is initialized 2830% with info from the Standard Colormap. 2831% 2832% o pixel: Specifies a pointer to a XPixelInfo structure. 2833% 2834*/ 2835MagickPrivate void XFreeStandardColormap(Display *display, 2836 const XVisualInfo *visual_info,XStandardColormap *map_info,XPixelInfo *pixel) 2837{ 2838 /* 2839 Free colormap. 2840 */ 2841 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 2842 assert(display != (Display *) NULL); 2843 assert(visual_info != (XVisualInfo *) NULL); 2844 assert(map_info != (XStandardColormap *) NULL); 2845 (void) XFlush(display); 2846 if (map_info->colormap != (Colormap) NULL) 2847 { 2848 if (map_info->colormap != XDefaultColormap(display,visual_info->screen)) 2849 (void) XFreeColormap(display,map_info->colormap); 2850 else 2851 if (pixel != (XPixelInfo *) NULL) 2852 if ((visual_info->klass != TrueColor) && 2853 (visual_info->klass != DirectColor)) 2854 (void) XFreeColors(display,map_info->colormap,pixel->pixels, 2855 (int) pixel->colors,0); 2856 } 2857 map_info->colormap=(Colormap) NULL; 2858 if (pixel != (XPixelInfo *) NULL) 2859 { 2860 if (pixel->pixels != (unsigned long *) NULL) 2861 pixel->pixels=(unsigned long *) RelinquishMagickMemory(pixel->pixels); 2862 pixel->pixels=(unsigned long *) NULL; 2863 } 2864} 2865 2866/* 2867%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2868% % 2869% % 2870% % 2871% X G e t A n n o t a t e I n f o % 2872% % 2873% % 2874% % 2875%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2876% 2877% XGetAnnotateInfo() initializes the AnnotateInfo structure. 2878% 2879% The format of the XGetAnnotateInfo method is: 2880% 2881% void XGetAnnotateInfo(XAnnotateInfo *annotate_info) 2882% 2883% A description of each parameter follows: 2884% 2885% o annotate_info: Specifies a pointer to a XAnnotateInfo structure. 2886% 2887*/ 2888MagickPrivate void XGetAnnotateInfo(XAnnotateInfo *annotate_info) 2889{ 2890 /* 2891 Initialize annotate structure. 2892 */ 2893 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 2894 assert(annotate_info != (XAnnotateInfo *) NULL); 2895 annotate_info->x=0; 2896 annotate_info->y=0; 2897 annotate_info->width=0; 2898 annotate_info->height=0; 2899 annotate_info->stencil=ForegroundStencil; 2900 annotate_info->degrees=0.0; 2901 annotate_info->font_info=(XFontStruct *) NULL; 2902 annotate_info->text=(char *) NULL; 2903 *annotate_info->geometry='\0'; 2904 annotate_info->previous=(XAnnotateInfo *) NULL; 2905 annotate_info->next=(XAnnotateInfo *) NULL; 2906 (void) XSupportsLocale(); 2907 (void) XSetLocaleModifiers(""); 2908} 2909 2910/* 2911%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2912% % 2913% % 2914% % 2915% X G e t M a p I n f o % 2916% % 2917% % 2918% % 2919%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2920% 2921% XGetMapInfo() initializes the XStandardColormap structure. 2922% 2923% The format of the XStandardColormap method is: 2924% 2925% void XGetMapInfo(const XVisualInfo *visual_info,const Colormap colormap, 2926% XStandardColormap *map_info) 2927% 2928% A description of each parameter follows: 2929% 2930% o colormap: Specifies the ID of the X server colormap. 2931% 2932% o visual_info: Specifies a pointer to a X11 XVisualInfo structure; 2933% returned from XGetVisualInfo. 2934% 2935% o map_info: Specifies a pointer to a X11 XStandardColormap structure. 2936% 2937*/ 2938MagickPrivate void XGetMapInfo(const XVisualInfo *visual_info, 2939 const Colormap colormap,XStandardColormap *map_info) 2940{ 2941 /* 2942 Initialize map info. 2943 */ 2944 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 2945 assert(visual_info != (XVisualInfo *) NULL); 2946 assert(map_info != (XStandardColormap *) NULL); 2947 map_info->colormap=colormap; 2948 map_info->red_max=visual_info->red_mask; 2949 map_info->red_mult=(size_t) (map_info->red_max != 0 ? 1 : 0); 2950 if (map_info->red_max != 0) 2951 while ((map_info->red_max & 0x01) == 0) 2952 { 2953 map_info->red_max>>=1; 2954 map_info->red_mult<<=1; 2955 } 2956 map_info->green_max=visual_info->green_mask; 2957 map_info->green_mult=(size_t) (map_info->green_max != 0 ? 1 : 0); 2958 if (map_info->green_max != 0) 2959 while ((map_info->green_max & 0x01) == 0) 2960 { 2961 map_info->green_max>>=1; 2962 map_info->green_mult<<=1; 2963 } 2964 map_info->blue_max=visual_info->blue_mask; 2965 map_info->blue_mult=(size_t) (map_info->blue_max != 0 ? 1 : 0); 2966 if (map_info->blue_max != 0) 2967 while ((map_info->blue_max & 0x01) == 0) 2968 { 2969 map_info->blue_max>>=1; 2970 map_info->blue_mult<<=1; 2971 } 2972 map_info->base_pixel=0; 2973} 2974 2975/* 2976%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2977% % 2978% % 2979% % 2980% X G e t P i x e l I n f o % 2981% % 2982% % 2983% % 2984%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2985% 2986% XGetPixelInfo() initializes the PixelInfo structure. 2987% 2988% The format of the XGetPixelInfo method is: 2989% 2990% void XGetPixelInfo(Display *display,const XVisualInfo *visual_info, 2991% const XStandardColormap *map_info,const XResourceInfo *resource_info, 2992% Image *image,XPixelInfo *pixel) 2993% pixel) 2994% 2995% A description of each parameter follows: 2996% 2997% o display: Specifies a connection to an X server; returned from 2998% XOpenDisplay. 2999% 3000% o visual_info: Specifies a pointer to a X11 XVisualInfo structure; 3001% returned from XGetVisualInfo. 3002% 3003% o map_info: If map_type is specified, this structure is initialized 3004% with info from the Standard Colormap. 3005% 3006% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. 3007% 3008% o image: the image. 3009% 3010% o pixel: Specifies a pointer to a XPixelInfo structure. 3011% 3012*/ 3013MagickPrivate void XGetPixelInfo(Display *display, 3014 const XVisualInfo *visual_info,const XStandardColormap *map_info, 3015 const XResourceInfo *resource_info,Image *image,XPixelInfo *pixel) 3016{ 3017 static const char 3018 *PenColors[MaxNumberPens]= 3019 { 3020 "#000000000000", /* black */ 3021 "#00000000ffff", /* blue */ 3022 "#0000ffffffff", /* cyan */ 3023 "#0000ffff0000", /* green */ 3024 "#bdbdbdbdbdbd", /* gray */ 3025 "#ffff00000000", /* red */ 3026 "#ffff0000ffff", /* magenta */ 3027 "#ffffffff0000", /* yellow */ 3028 "#ffffffffffff", /* white */ 3029 "#bdbdbdbdbdbd", /* gray */ 3030 "#bdbdbdbdbdbd" /* gray */ 3031 }; 3032 3033 Colormap 3034 colormap; 3035 3036 extern const char 3037 BorderColor[], 3038 ForegroundColor[]; 3039 3040 register ssize_t 3041 i; 3042 3043 Status 3044 status; 3045 3046 unsigned int 3047 packets; 3048 3049 /* 3050 Initialize pixel info. 3051 */ 3052 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 3053 assert(display != (Display *) NULL); 3054 assert(visual_info != (XVisualInfo *) NULL); 3055 assert(map_info != (XStandardColormap *) NULL); 3056 assert(resource_info != (XResourceInfo *) NULL); 3057 assert(pixel != (XPixelInfo *) NULL); 3058 pixel->colors=0; 3059 if (image != (Image *) NULL) 3060 if (image->storage_class == PseudoClass) 3061 pixel->colors=(ssize_t) image->colors; 3062 packets=(unsigned int) 3063 MagickMax((int) pixel->colors,visual_info->colormap_size)+MaxNumberPens; 3064 if (pixel->pixels != (unsigned long *) NULL) 3065 pixel->pixels=(unsigned long *) RelinquishMagickMemory(pixel->pixels); 3066 pixel->pixels=(unsigned long *) AcquireQuantumMemory(packets, 3067 sizeof(*pixel->pixels)); 3068 if (pixel->pixels == (unsigned long *) NULL) 3069 ThrowXWindowFatalException(ResourceLimitFatalError,"UnableToGetPixelInfo", 3070 image->filename); 3071 /* 3072 Set foreground color. 3073 */ 3074 colormap=map_info->colormap; 3075 (void) XParseColor(display,colormap,(char *) ForegroundColor, 3076 &pixel->foreground_color); 3077 status=XParseColor(display,colormap,resource_info->foreground_color, 3078 &pixel->foreground_color); 3079 if (status == False) 3080 ThrowXWindowException(XServerError,"ColorIsNotKnownToServer", 3081 resource_info->foreground_color); 3082 pixel->foreground_color.pixel= 3083 XStandardPixel(map_info,&pixel->foreground_color); 3084 pixel->foreground_color.flags=(char) (DoRed | DoGreen | DoBlue); 3085 /* 3086 Set background color. 3087 */ 3088 (void) XParseColor(display,colormap,"#d6d6d6d6d6d6",&pixel->background_color); 3089 status=XParseColor(display,colormap,resource_info->background_color, 3090 &pixel->background_color); 3091 if (status == False) 3092 ThrowXWindowException(XServerError,"ColorIsNotKnownToServer", 3093 resource_info->background_color); 3094 pixel->background_color.pixel= 3095 XStandardPixel(map_info,&pixel->background_color); 3096 pixel->background_color.flags=(char) (DoRed | DoGreen | DoBlue); 3097 /* 3098 Set border color. 3099 */ 3100 (void) XParseColor(display,colormap,(char *) BorderColor, 3101 &pixel->border_color); 3102 status=XParseColor(display,colormap,resource_info->border_color, 3103 &pixel->border_color); 3104 if (status == False) 3105 ThrowXWindowException(XServerError,"ColorIsNotKnownToServer", 3106 resource_info->border_color); 3107 pixel->border_color.pixel=XStandardPixel(map_info,&pixel->border_color); 3108 pixel->border_color.flags=(char) (DoRed | DoGreen | DoBlue); 3109 /* 3110 Set matte color. 3111 */ 3112 pixel->alpha_color=pixel->background_color; 3113 if (resource_info->alpha_color != (char *) NULL) 3114 { 3115 /* 3116 Matte color is specified as a X resource or command line argument. 3117 */ 3118 status=XParseColor(display,colormap,resource_info->alpha_color, 3119 &pixel->alpha_color); 3120 if (status == False) 3121 ThrowXWindowException(XServerError,"ColorIsNotKnownToServer", 3122 resource_info->alpha_color); 3123 pixel->alpha_color.pixel=XStandardPixel(map_info,&pixel->alpha_color); 3124 pixel->alpha_color.flags=(char) (DoRed | DoGreen | DoBlue); 3125 } 3126 /* 3127 Set highlight color. 3128 */ 3129 pixel->highlight_color.red=(unsigned short) (((double) 3130 pixel->alpha_color.red*ScaleQuantumToShort(HighlightModulate))/65535L+ 3131 (ScaleQuantumToShort((Quantum) (QuantumRange-HighlightModulate)))); 3132 pixel->highlight_color.green=(unsigned short) (((double) 3133 pixel->alpha_color.green*ScaleQuantumToShort(HighlightModulate))/65535L+ 3134 (ScaleQuantumToShort((Quantum) (QuantumRange-HighlightModulate)))); 3135 pixel->highlight_color.blue=(unsigned short) (((double) 3136 pixel->alpha_color.blue*ScaleQuantumToShort(HighlightModulate))/65535L+ 3137 (ScaleQuantumToShort((Quantum) (QuantumRange-HighlightModulate)))); 3138 pixel->highlight_color.pixel=XStandardPixel(map_info,&pixel->highlight_color); 3139 pixel->highlight_color.flags=(char) (DoRed | DoGreen | DoBlue); 3140 /* 3141 Set shadow color. 3142 */ 3143 pixel->shadow_color.red=(unsigned short) (((double) 3144 pixel->alpha_color.red*ScaleQuantumToShort(ShadowModulate))/65535L); 3145 pixel->shadow_color.green=(unsigned short) (((double) 3146 pixel->alpha_color.green*ScaleQuantumToShort(ShadowModulate))/65535L); 3147 pixel->shadow_color.blue=(unsigned short) (((double) 3148 pixel->alpha_color.blue*ScaleQuantumToShort(ShadowModulate))/65535L); 3149 pixel->shadow_color.pixel=XStandardPixel(map_info,&pixel->shadow_color); 3150 pixel->shadow_color.flags=(char) (DoRed | DoGreen | DoBlue); 3151 /* 3152 Set depth color. 3153 */ 3154 pixel->depth_color.red=(unsigned short) (((double) 3155 pixel->alpha_color.red*ScaleQuantumToShort(DepthModulate))/65535L); 3156 pixel->depth_color.green=(unsigned short) (((double) 3157 pixel->alpha_color.green*ScaleQuantumToShort(DepthModulate))/65535L); 3158 pixel->depth_color.blue=(unsigned short) (((double) 3159 pixel->alpha_color.blue*ScaleQuantumToShort(DepthModulate))/65535L); 3160 pixel->depth_color.pixel=XStandardPixel(map_info,&pixel->depth_color); 3161 pixel->depth_color.flags=(char) (DoRed | DoGreen | DoBlue); 3162 /* 3163 Set trough color. 3164 */ 3165 pixel->trough_color.red=(unsigned short) (((double) 3166 pixel->alpha_color.red*ScaleQuantumToShort(TroughModulate))/65535L); 3167 pixel->trough_color.green=(unsigned short) (((double) 3168 pixel->alpha_color.green*ScaleQuantumToShort(TroughModulate))/65535L); 3169 pixel->trough_color.blue=(unsigned short) (((double) 3170 pixel->alpha_color.blue*ScaleQuantumToShort(TroughModulate))/65535L); 3171 pixel->trough_color.pixel=XStandardPixel(map_info,&pixel->trough_color); 3172 pixel->trough_color.flags=(char) (DoRed | DoGreen | DoBlue); 3173 /* 3174 Set pen color. 3175 */ 3176 for (i=0; i < MaxNumberPens; i++) 3177 { 3178 (void) XParseColor(display,colormap,(char *) PenColors[i], 3179 &pixel->pen_colors[i]); 3180 status=XParseColor(display,colormap,resource_info->pen_colors[i], 3181 &pixel->pen_colors[i]); 3182 if (status == False) 3183 ThrowXWindowException(XServerError,"ColorIsNotKnownToServer", 3184 resource_info->pen_colors[i]); 3185 pixel->pen_colors[i].pixel=XStandardPixel(map_info,&pixel->pen_colors[i]); 3186 pixel->pen_colors[i].flags=(char) (DoRed | DoGreen | DoBlue); 3187 } 3188 pixel->box_color=pixel->background_color; 3189 pixel->pen_color=pixel->foreground_color; 3190 pixel->box_index=0; 3191 pixel->pen_index=1; 3192 if (image != (Image *) NULL) 3193 { 3194 if ((resource_info->gamma_correct != MagickFalse) && 3195 (image->gamma != 0.0)) 3196 { 3197 GeometryInfo 3198 geometry_info; 3199 3200 MagickStatusType 3201 flags; 3202 3203 /* 3204 Initialize map relative to display and image gamma. 3205 */ 3206 flags=ParseGeometry(resource_info->display_gamma,&geometry_info); 3207 red_gamma=geometry_info.rho; 3208 green_gamma=geometry_info.sigma; 3209 if ((flags & SigmaValue) == 0) 3210 green_gamma=red_gamma; 3211 blue_gamma=geometry_info.xi; 3212 if ((flags & XiValue) == 0) 3213 blue_gamma=red_gamma; 3214 red_gamma*=image->gamma; 3215 green_gamma*=image->gamma; 3216 blue_gamma*=image->gamma; 3217 } 3218 if (image->storage_class == PseudoClass) 3219 { 3220 /* 3221 Initialize pixel array for images of type PseudoClass. 3222 */ 3223 for (i=0; i < (ssize_t) image->colors; i++) 3224 pixel->pixels[i]=XGammaPacket(map_info,image->colormap+i); 3225 for (i=0; i < MaxNumberPens; i++) 3226 pixel->pixels[image->colors+i]=pixel->pen_colors[i].pixel; 3227 pixel->colors+=MaxNumberPens; 3228 } 3229 } 3230} 3231 3232/* 3233%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3234% % 3235% % 3236% % 3237% X G e t R e s o u r c e C l a s s % 3238% % 3239% % 3240% % 3241%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3242% 3243% XGetResourceClass() queries the X server for the specified resource name or 3244% class. If the resource name or class is not defined in the database, the 3245% supplied default value is returned. 3246% 3247% The format of the XGetResourceClass method is: 3248% 3249% char *XGetResourceClass(XrmDatabase database,const char *client_name, 3250% const char *keyword,char *resource_default) 3251% 3252% A description of each parameter follows: 3253% 3254% o database: Specifies a resource database; returned from 3255% XrmGetStringDatabase. 3256% 3257% o client_name: Specifies the application name used to retrieve resource 3258% info from the X server database. 3259% 3260% o keyword: Specifies the keyword of the value being retrieved. 3261% 3262% o resource_default: Specifies the default value to return if the query 3263% fails to find the specified keyword/class. 3264% 3265*/ 3266MagickExport char *XGetResourceClass(XrmDatabase database, 3267 const char *client_name,const char *keyword,char *resource_default) 3268{ 3269 char 3270 resource_class[MagickPathExtent], 3271 resource_name[MagickPathExtent]; 3272 3273 static char 3274 *resource_type; 3275 3276 Status 3277 status; 3278 3279 XrmValue 3280 resource_value; 3281 3282 if (database == (XrmDatabase) NULL) 3283 return(resource_default); 3284 *resource_name='\0'; 3285 *resource_class='\0'; 3286 if (keyword != (char *) NULL) 3287 { 3288 int 3289 c, 3290 k; 3291 3292 /* 3293 Initialize resource keyword and class. 3294 */ 3295 (void) FormatLocaleString(resource_name,MagickPathExtent,"%s.%s", 3296 client_name,keyword); 3297 c=(int) (*client_name); 3298 if ((c >= XK_a) && (c <= XK_z)) 3299 c-=(XK_a-XK_A); 3300 else 3301 if ((c >= XK_agrave) && (c <= XK_odiaeresis)) 3302 c-=(XK_agrave-XK_Agrave); 3303 else 3304 if ((c >= XK_oslash) && (c <= XK_thorn)) 3305 c-=(XK_oslash-XK_Ooblique); 3306 k=(int) (*keyword); 3307 if ((k >= XK_a) && (k <= XK_z)) 3308 k-=(XK_a-XK_A); 3309 else 3310 if ((k >= XK_agrave) && (k <= XK_odiaeresis)) 3311 k-=(XK_agrave-XK_Agrave); 3312 else 3313 if ((k >= XK_oslash) && (k <= XK_thorn)) 3314 k-=(XK_oslash-XK_Ooblique); 3315 (void) FormatLocaleString(resource_class,MagickPathExtent,"%c%s.%c%s",c, 3316 client_name+1,k,keyword+1); 3317 } 3318 status=XrmGetResource(database,resource_name,resource_class,&resource_type, 3319 &resource_value); 3320 if (status == False) 3321 return(resource_default); 3322 return(resource_value.addr); 3323} 3324 3325/* 3326%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3327% % 3328% % 3329% % 3330% X G e t R e s o u r c e D a t a b a s e % 3331% % 3332% % 3333% % 3334%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3335% 3336% XGetResourceDatabase() creates a new resource database and initializes it. 3337% 3338% The format of the XGetResourceDatabase method is: 3339% 3340% XrmDatabase XGetResourceDatabase(Display *display, 3341% const char *client_name) 3342% 3343% A description of each parameter follows: 3344% 3345% o database: XGetResourceDatabase() returns the database after it is 3346% initialized. 3347% 3348% o display: Specifies a connection to an X server; returned from 3349% XOpenDisplay. 3350% 3351% o client_name: Specifies the application name used to retrieve resource 3352% info from the X server database. 3353% 3354*/ 3355MagickExport XrmDatabase XGetResourceDatabase(Display *display, 3356 const char *client_name) 3357{ 3358 char 3359 filename[MagickPathExtent]; 3360 3361 int 3362 c; 3363 3364 register const char 3365 *p; 3366 3367 XrmDatabase 3368 resource_database, 3369 server_database; 3370 3371 if (display == (Display *) NULL) 3372 return((XrmDatabase) NULL); 3373 assert(client_name != (char *) NULL); 3374 /* 3375 Initialize resource database. 3376 */ 3377 XrmInitialize(); 3378 (void) XGetDefault(display,(char *) client_name,"dummy"); 3379 resource_database=XrmGetDatabase(display); 3380 /* 3381 Combine application database. 3382 */ 3383 if (client_name != (char *) NULL) 3384 { 3385 /* 3386 Get basename of client. 3387 */ 3388 p=client_name+(strlen(client_name)-1); 3389 while ((p > client_name) && (*p != '/')) 3390 p--; 3391 if (*p == '/') 3392 client_name=p+1; 3393 } 3394 c=(int) (*client_name); 3395 if ((c >= XK_a) && (c <= XK_z)) 3396 c-=(XK_a-XK_A); 3397 else 3398 if ((c >= XK_agrave) && (c <= XK_odiaeresis)) 3399 c-=(XK_agrave-XK_Agrave); 3400 else 3401 if ((c >= XK_oslash) && (c <= XK_thorn)) 3402 c-=(XK_oslash-XK_Ooblique); 3403#if defined(X11_APPLICATION_PATH) 3404 (void) FormatLocaleString(filename,MagickPathExtent,"%s%c%s", 3405 X11_APPLICATION_PATH,c,client_name+1); 3406 (void) XrmCombineFileDatabase(filename,&resource_database,MagickFalse); 3407#endif 3408 if (XResourceManagerString(display) != (char *) NULL) 3409 { 3410 /* 3411 Combine server database. 3412 */ 3413 server_database=XrmGetStringDatabase(XResourceManagerString(display)); 3414 XrmCombineDatabase(server_database,&resource_database,MagickFalse); 3415 } 3416 /* 3417 Merge user preferences database. 3418 */ 3419#if defined(X11_PREFERENCES_PATH) 3420 (void) FormatLocaleString(filename,MagickPathExtent,"%s%src", 3421 X11_PREFERENCES_PATH,client_name); 3422 ExpandFilename(filename); 3423 (void) XrmCombineFileDatabase(filename,&resource_database,MagickFalse); 3424#endif 3425 return(resource_database); 3426} 3427 3428/* 3429%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3430% % 3431% % 3432% % 3433% X G e t R e s o u r c e I n f o % 3434% % 3435% % 3436% % 3437%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3438% 3439% XGetResourceInfo(image_info,) initializes the ResourceInfo structure. 3440% 3441% The format of the XGetResourceInfo method is: 3442% 3443% void XGetResourceInfo(const ImageInfo *image_info,XrmDatabase database, 3444% const char *client_name,XResourceInfo *resource_info) 3445% 3446% A description of each parameter follows: 3447% 3448% o image_info: the image info. 3449% 3450% o database: Specifies a resource database; returned from 3451% XrmGetStringDatabase. 3452% 3453% o client_name: Specifies the application name used to retrieve 3454% resource info from the X server database. 3455% 3456% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. 3457% 3458*/ 3459MagickExport void XGetResourceInfo(const ImageInfo *image_info, 3460 XrmDatabase database,const char *client_name,XResourceInfo *resource_info) 3461{ 3462 char 3463 *directory, 3464 *resource_value; 3465 3466 extern const char 3467 BorderColor[], 3468 ForegroundColor[]; 3469 3470 /* 3471 Initialize resource info fields. 3472 */ 3473 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 3474 assert(resource_info != (XResourceInfo *) NULL); 3475 (void) ResetMagickMemory(resource_info,0,sizeof(*resource_info)); 3476 resource_info->resource_database=database; 3477 resource_info->image_info=(ImageInfo *) image_info; 3478 (void) SetImageInfoProgressMonitor(resource_info->image_info, 3479 XMagickProgressMonitor,(void *) NULL); 3480 resource_info->quantize_info=CloneQuantizeInfo((QuantizeInfo *) NULL); 3481 resource_info->close_server=MagickTrue; 3482 resource_info->client_name=AcquireString(client_name); 3483 resource_info->alpha_color=XGetResourceInstance(database,client_name, 3484 "alpha-color",(char *) NULL); 3485 resource_value=XGetResourceClass(database,client_name,"backdrop", 3486 (char *) "False"); 3487 resource_info->backdrop=IsStringTrue(resource_value); 3488 resource_info->background_color=XGetResourceInstance(database,client_name, 3489 "background",(char *) "#d6d6d6d6d6d6"); 3490 resource_info->border_color=XGetResourceInstance(database,client_name, 3491 "borderColor",BorderColor); 3492 resource_value=XGetResourceClass(database,client_name,"borderWidth", 3493 (char *) "2"); 3494 resource_info->border_width=(unsigned int) StringToUnsignedLong( 3495 resource_value); 3496 resource_value=XGetResourceClass(database,client_name,"colormap", 3497 (char *) "shared"); 3498 resource_info->colormap=UndefinedColormap; 3499 if (LocaleCompare("private",resource_value) == 0) 3500 resource_info->colormap=PrivateColormap; 3501 if (LocaleCompare("shared",resource_value) == 0) 3502 resource_info->colormap=SharedColormap; 3503 if (resource_info->colormap == UndefinedColormap) 3504 ThrowXWindowException(OptionError,"UnrecognizedColormapType", 3505 resource_value); 3506 resource_value=XGetResourceClass(database,client_name, 3507 "colorRecovery",(char *) "False"); 3508 resource_info->color_recovery=IsStringTrue(resource_value); 3509 resource_value=XGetResourceClass(database,client_name,"confirmExit", 3510 (char *) "False"); 3511 resource_info->confirm_exit=IsStringTrue(resource_value); 3512 resource_value=XGetResourceClass(database,client_name,"confirmEdit", 3513 (char *) "False"); 3514 resource_info->confirm_edit=IsStringTrue(resource_value); 3515 resource_value=XGetResourceClass(database,client_name,"delay",(char *) "1"); 3516 resource_info->delay=(unsigned int) StringToUnsignedLong(resource_value); 3517 resource_info->display_gamma=XGetResourceClass(database,client_name, 3518 "displayGamma",(char *) "2.2"); 3519 resource_value=XGetResourceClass(database,client_name,"displayWarnings", 3520 (char *) "True"); 3521 resource_info->display_warnings=IsStringTrue(resource_value); 3522 resource_info->font=XGetResourceClass(database,client_name,"font", 3523 (char *) NULL); 3524 resource_info->font=XGetResourceClass(database,client_name,"fontList", 3525 resource_info->font); 3526 resource_info->font_name[0]=XGetResourceClass(database,client_name,"font1", 3527 (char *) "fixed"); 3528 resource_info->font_name[1]=XGetResourceClass(database,client_name,"font2", 3529 (char *) "variable"); 3530 resource_info->font_name[2]=XGetResourceClass(database,client_name,"font3", 3531 (char *) "5x8"); 3532 resource_info->font_name[3]=XGetResourceClass(database,client_name,"font4", 3533 (char *) "6x10"); 3534 resource_info->font_name[4]=XGetResourceClass(database,client_name,"font5", 3535 (char *) "7x13bold"); 3536 resource_info->font_name[5]=XGetResourceClass(database,client_name,"font6", 3537 (char *) "8x13bold"); 3538 resource_info->font_name[6]=XGetResourceClass(database,client_name,"font7", 3539 (char *) "9x15bold"); 3540 resource_info->font_name[7]=XGetResourceClass(database,client_name,"font8", 3541 (char *) "10x20"); 3542 resource_info->font_name[8]=XGetResourceClass(database,client_name,"font9", 3543 (char *) "12x24"); 3544 resource_info->font_name[9]=XGetResourceClass(database,client_name,"font0", 3545 (char *) "fixed"); 3546 resource_info->font_name[10]=XGetResourceClass(database,client_name,"font0", 3547 (char *) "fixed"); 3548 resource_info->foreground_color=XGetResourceInstance(database,client_name, 3549 "foreground",ForegroundColor); 3550 resource_value=XGetResourceClass(database,client_name,"gammaCorrect", 3551 (char *) "False"); 3552 resource_info->gamma_correct=IsStringTrue(resource_value); 3553 resource_info->image_geometry=ConstantString(XGetResourceClass(database, 3554 client_name,"geometry",(char *) NULL)); 3555 resource_value=XGetResourceClass(database,client_name,"gravity", 3556 (char *) "Center"); 3557 resource_info->gravity=(GravityType) ParseCommandOption(MagickGravityOptions, 3558 MagickFalse,resource_value); 3559 directory=getcwd(resource_info->home_directory,MagickPathExtent); 3560 (void) directory; 3561 resource_info->icon_geometry=XGetResourceClass(database,client_name, 3562 "iconGeometry",(char *) NULL); 3563 resource_value=XGetResourceClass(database,client_name,"iconic", 3564 (char *) "False"); 3565 resource_info->iconic=IsStringTrue(resource_value); 3566 resource_value=XGetResourceClass(database,client_name,"immutable", 3567 LocaleCompare(client_name,"PerlMagick") == 0 ? (char *) "True" : 3568 (char *) "False"); 3569 resource_info->immutable=IsStringTrue(resource_value); 3570 resource_value=XGetResourceClass(database,client_name,"magnify", 3571 (char *) "3"); 3572 resource_info->magnify=(unsigned int) StringToUnsignedLong(resource_value); 3573 resource_info->map_type=XGetResourceClass(database,client_name,"map", 3574 (char *) NULL); 3575 resource_info->name=ConstantString(XGetResourceClass(database,client_name, 3576 "name",(char *) NULL)); 3577 resource_info->pen_colors[0]=XGetResourceClass(database,client_name,"pen1", 3578 (char *) "black"); 3579 resource_info->pen_colors[1]=XGetResourceClass(database,client_name,"pen2", 3580 (char *) "blue"); 3581 resource_info->pen_colors[2]=XGetResourceClass(database,client_name,"pen3", 3582 (char *) "cyan"); 3583 resource_info->pen_colors[3]=XGetResourceClass(database,client_name,"pen4", 3584 (char *) "green"); 3585 resource_info->pen_colors[4]=XGetResourceClass(database,client_name,"pen5", 3586 (char *) "gray"); 3587 resource_info->pen_colors[5]=XGetResourceClass(database,client_name,"pen6", 3588 (char *) "red"); 3589 resource_info->pen_colors[6]=XGetResourceClass(database,client_name,"pen7", 3590 (char *) "magenta"); 3591 resource_info->pen_colors[7]=XGetResourceClass(database,client_name,"pen8", 3592 (char *) "yellow"); 3593 resource_info->pen_colors[8]=XGetResourceClass(database,client_name,"pen9", 3594 (char *) "white"); 3595 resource_info->pen_colors[9]=XGetResourceClass(database,client_name,"pen0", 3596 (char *) "gray"); 3597 resource_info->pen_colors[10]=XGetResourceClass(database,client_name,"pen0", 3598 (char *) "gray"); 3599 resource_value=XGetResourceClass(database,client_name,"pause",(char *) "0"); 3600 resource_info->pause=(unsigned int) StringToUnsignedLong(resource_value); 3601 resource_value=XGetResourceClass(database,client_name,"quantum",(char *) "1"); 3602 resource_info->quantum=StringToLong(resource_value); 3603 resource_info->text_font=XGetResourceClass(database,client_name,(char *) 3604 "font",(char *) "fixed"); 3605 resource_info->text_font=XGetResourceClass(database,client_name, 3606 "textFontList",resource_info->text_font); 3607 resource_info->title=XGetResourceClass(database,client_name,"title", 3608 (char *) NULL); 3609 resource_value=XGetResourceClass(database,client_name,"undoCache", 3610 (char *) "256"); 3611 resource_info->undo_cache=(unsigned int) StringToUnsignedLong(resource_value); 3612 resource_value=XGetResourceClass(database,client_name,"update", 3613 (char *) "False"); 3614 resource_info->update=IsStringTrue(resource_value); 3615 resource_value=XGetResourceClass(database,client_name,"usePixmap", 3616 (char *) "True"); 3617 resource_info->use_pixmap=IsStringTrue(resource_value); 3618 resource_value=XGetResourceClass(database,client_name,"sharedMemory", 3619 (char *) "True"); 3620 resource_info->use_shared_memory=IsStringTrue(resource_value); 3621 resource_info->visual_type=XGetResourceClass(database,client_name,"visual", 3622 (char *) NULL); 3623 resource_info->window_group=XGetResourceClass(database,client_name, 3624 "windowGroup",(char *) NULL); 3625 resource_info->window_id=XGetResourceClass(database,client_name,"window", 3626 (char *) NULL); 3627 resource_info->write_filename=XGetResourceClass(database,client_name, 3628 "writeFilename",(char *) NULL); 3629} 3630 3631/* 3632%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3633% % 3634% % 3635% % 3636% X G e t R e s o u r c e I n s t a n c e % 3637% % 3638% % 3639% % 3640%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3641% 3642% XGetResourceInstance() queries the X server for the specified resource name. 3643% If the resource name is not defined in the database, the supplied default 3644% value is returned. 3645% 3646% The format of the XGetResourceInstance method is: 3647% 3648% char *XGetResourceInstance(XrmDatabase database,const char *client_name, 3649% const char *keyword,const char *resource_default) 3650% 3651% A description of each parameter follows: 3652% 3653% o database: Specifies a resource database; returned from 3654% XrmGetStringDatabase. 3655% 3656% o client_name: Specifies the application name used to retrieve 3657% resource info from the X server database. 3658% 3659% o keyword: Specifies the keyword of the value being retrieved. 3660% 3661% o resource_default: Specifies the default value to return if the query 3662% fails to find the specified keyword/class. 3663% 3664*/ 3665MagickExport char *XGetResourceInstance(XrmDatabase database, 3666 const char *client_name,const char *keyword,const char *resource_default) 3667{ 3668 char 3669 *resource_type, 3670 resource_name[MagickPathExtent]; 3671 3672 Status 3673 status; 3674 3675 XrmValue 3676 resource_value; 3677 3678 if (database == (XrmDatabase) NULL) 3679 return((char *) resource_default); 3680 *resource_name='\0'; 3681 if (keyword != (char *) NULL) 3682 (void) FormatLocaleString(resource_name,MagickPathExtent,"%s.%s",client_name, 3683 keyword); 3684 status=XrmGetResource(database,resource_name,"ImageMagick",&resource_type, 3685 &resource_value); 3686 if (status == False) 3687 return((char *) resource_default); 3688 return(resource_value.addr); 3689} 3690 3691/* 3692%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3693% % 3694% % 3695% % 3696% X G e t S c r e e n D e n s i t y % 3697% % 3698% % 3699% % 3700%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3701% 3702% XGetScreenDensity() returns the density of the X server screen in 3703% dots-per-inch. 3704% 3705% The format of the XGetScreenDensity method is: 3706% 3707% char *XGetScreenDensity(Display *display) 3708% 3709% A description of each parameter follows: 3710% 3711% o density: XGetScreenDensity() returns the density of the X screen in 3712% dots-per-inch. 3713% 3714% o display: Specifies a connection to an X server; returned from 3715% XOpenDisplay. 3716% 3717*/ 3718MagickExport char *XGetScreenDensity(Display *display) 3719{ 3720 char 3721 density[MagickPathExtent]; 3722 3723 double 3724 x_density, 3725 y_density; 3726 3727 /* 3728 Set density as determined by screen size. 3729 */ 3730 x_density=((((double) DisplayWidth(display,XDefaultScreen(display)))*25.4)/ 3731 ((double) DisplayWidthMM(display,XDefaultScreen(display)))); 3732 y_density=((((double) DisplayHeight(display,XDefaultScreen(display)))*25.4)/ 3733 ((double) DisplayHeightMM(display,XDefaultScreen(display)))); 3734 (void) FormatLocaleString(density,MagickPathExtent,"%gx%g",x_density, 3735 y_density); 3736 return(GetPageGeometry(density)); 3737} 3738 3739/* 3740%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3741% % 3742% % 3743% % 3744+ X G e t S u b w i n d o w % 3745% % 3746% % 3747% % 3748%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3749% 3750% XGetSubwindow() returns the subwindow of a window chosen the user with the 3751% pointer and a button press. 3752% 3753% The format of the XGetSubwindow method is: 3754% 3755% Window XGetSubwindow(Display *display,Window window,int x,int y) 3756% 3757% A description of each parameter follows: 3758% 3759% o subwindow: XGetSubwindow() returns NULL if no subwindow is found 3760% otherwise the subwindow is returned. 3761% 3762% o display: Specifies a connection to an X server; returned from 3763% XOpenDisplay. 3764% 3765% o window: Specifies a pointer to a Window. 3766% 3767% o x: the x coordinate of the pointer relative to the origin of the 3768% window. 3769% 3770% o y: the y coordinate of the pointer relative to the origin of the 3771% window. 3772% 3773*/ 3774static Window XGetSubwindow(Display *display,Window window,int x,int y) 3775{ 3776 int 3777 x_offset, 3778 y_offset; 3779 3780 Status 3781 status; 3782 3783 Window 3784 source_window, 3785 target_window; 3786 3787 assert(display != (Display *) NULL); 3788 source_window=XRootWindow(display,XDefaultScreen(display)); 3789 if (window == (Window) NULL) 3790 return(source_window); 3791 target_window=window; 3792 for ( ; ; ) 3793 { 3794 status=XTranslateCoordinates(display,source_window,window,x,y, 3795 &x_offset,&y_offset,&target_window); 3796 if (status != True) 3797 break; 3798 if (target_window == (Window) NULL) 3799 break; 3800 source_window=window; 3801 window=target_window; 3802 x=x_offset; 3803 y=y_offset; 3804 } 3805 if (target_window == (Window) NULL) 3806 target_window=window; 3807 return(target_window); 3808} 3809 3810/* 3811%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3812% % 3813% % 3814% % 3815% X G e t W i n d o w C o l o r % 3816% % 3817% % 3818% % 3819%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3820% 3821% XGetWindowColor() returns the color of a pixel interactively chosen from the 3822% X server. 3823% 3824% The format of the XGetWindowColor method is: 3825% 3826% MagickBooleanType XGetWindowColor(Display *display,XWindows *windows, 3827% char *name,ExceptionInfo *exception) 3828% 3829% A description of each parameter follows: 3830% 3831% o display: Specifies a connection to an X server; returned from 3832% XOpenDisplay. 3833% 3834% o windows: Specifies a pointer to a XWindows structure. 3835% 3836% o name: the name of the color if found in the X Color Database is 3837% returned in this character string. 3838% 3839% o exception: return any errors or warnings in this structure. 3840% 3841*/ 3842MagickPrivate MagickBooleanType XGetWindowColor(Display *display, 3843 XWindows *windows,char *name,ExceptionInfo *exception) 3844{ 3845 int 3846 x, 3847 y; 3848 3849 PixelInfo 3850 pixel; 3851 3852 RectangleInfo 3853 crop_info; 3854 3855 Status 3856 status; 3857 3858 Window 3859 child, 3860 client_window, 3861 root_window, 3862 target_window; 3863 3864 XColor 3865 color; 3866 3867 XImage 3868 *ximage; 3869 3870 XWindowAttributes 3871 window_attributes; 3872 3873 /* 3874 Choose a pixel from the X server. 3875 */ 3876 assert(display != (Display *) NULL); 3877 assert(name != (char *) NULL); 3878 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name); 3879 *name='\0'; 3880 target_window=XSelectWindow(display,&crop_info); 3881 if (target_window == (Window) NULL) 3882 return(MagickFalse); 3883 root_window=XRootWindow(display,XDefaultScreen(display)); 3884 client_window=target_window; 3885 if (target_window != root_window) 3886 { 3887 unsigned int 3888 d; 3889 3890 /* 3891 Get client window. 3892 */ 3893 status=XGetGeometry(display,target_window,&root_window,&x,&x,&d,&d,&d,&d); 3894 if (status != False) 3895 { 3896 client_window=XClientWindow(display,target_window); 3897 target_window=client_window; 3898 } 3899 } 3900 /* 3901 Verify window is viewable. 3902 */ 3903 status=XGetWindowAttributes(display,target_window,&window_attributes); 3904 if ((status == False) || (window_attributes.map_state != IsViewable)) 3905 return(MagickFalse); 3906 /* 3907 Get window X image. 3908 */ 3909 (void) XTranslateCoordinates(display,root_window,target_window, 3910 (int) crop_info.x,(int) crop_info.y,&x,&y,&child); 3911 ximage=XGetImage(display,target_window,x,y,1,1,AllPlanes,ZPixmap); 3912 if (ximage == (XImage *) NULL) 3913 return(MagickFalse); 3914 color.pixel=XGetPixel(ximage,0,0); 3915 XDestroyImage(ximage); 3916 /* 3917 Match color against the color database. 3918 */ 3919 (void) XQueryColor(display,window_attributes.colormap,&color); 3920 pixel.red=(double) ScaleShortToQuantum(color.red); 3921 pixel.green=(double) ScaleShortToQuantum(color.green); 3922 pixel.blue=(double) ScaleShortToQuantum(color.blue); 3923 pixel.alpha=OpaqueAlpha; 3924 (void) QueryColorname(windows->image.image,&pixel,X11Compliance,name, 3925 exception); 3926 return(MagickTrue); 3927} 3928 3929/* 3930%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3931% % 3932% % 3933% % 3934+ X G e t W i n d o w I m a g e % 3935% % 3936% % 3937% % 3938%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3939% 3940% XGetWindowImage() reads an image from the target X window and returns it. 3941% XGetWindowImage() optionally descends the window hierarchy and overlays the 3942% target image with each child image in an optimized fashion. Any child 3943% window that have the same visual, colormap, and are contained by its parent 3944% are exempted. 3945% 3946% The format of the XGetWindowImage method is: 3947% 3948% Image *XGetWindowImage(Display *display,const Window window, 3949% const unsigned int borders,const unsigned int level, 3950% ExceptionInfo *exception) 3951% 3952% A description of each parameter follows: 3953% 3954% o display: Specifies a connection to an X server; returned from 3955% XOpenDisplay. 3956% 3957% o window: Specifies the window to obtain the image from. 3958% 3959% o borders: Specifies whether borders pixels are to be saved with 3960% the image. 3961% 3962% o level: Specifies an unsigned integer representing the level of 3963% decent in the window hierarchy. This value must be zero or one on 3964% the initial call to XGetWindowImage. A value of zero returns after 3965% one call. A value of one causes the function to descend the window 3966% hierarchy and overlay the target image with each subwindow image. 3967% 3968% o exception: return any errors or warnings in this structure. 3969% 3970*/ 3971static Image *XGetWindowImage(Display *display,const Window window, 3972 const unsigned int borders,const unsigned int level,ExceptionInfo *exception) 3973{ 3974 typedef struct _ColormapInfo 3975 { 3976 Colormap 3977 colormap; 3978 3979 XColor 3980 *colors; 3981 3982 struct _ColormapInfo 3983 *next; 3984 } ColormapInfo; 3985 3986 typedef struct _WindowInfo 3987 { 3988 Window 3989 window, 3990 parent; 3991 3992 Visual 3993 *visual; 3994 3995 Colormap 3996 colormap; 3997 3998 XSegment 3999 bounds; 4000 4001 RectangleInfo 4002 crop_info; 4003 } WindowInfo; 4004 4005 int 4006 display_height, 4007 display_width, 4008 id, 4009 x_offset, 4010 y_offset; 4011 4012 Quantum 4013 index; 4014 4015 RectangleInfo 4016 crop_info; 4017 4018 register int 4019 i; 4020 4021 static ColormapInfo 4022 *colormap_info = (ColormapInfo *) NULL; 4023 4024 static int 4025 max_windows = 0, 4026 number_windows = 0; 4027 4028 static WindowInfo 4029 *window_info; 4030 4031 Status 4032 status; 4033 4034 Window 4035 child, 4036 root_window; 4037 4038 XWindowAttributes 4039 window_attributes; 4040 4041 /* 4042 Verify window is viewable. 4043 */ 4044 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 4045 assert(display != (Display *) NULL); 4046 status=XGetWindowAttributes(display,window,&window_attributes); 4047 if ((status == False) || (window_attributes.map_state != IsViewable)) 4048 return((Image *) NULL); 4049 /* 4050 Cropping rectangle is relative to root window. 4051 */ 4052 root_window=XRootWindow(display,XDefaultScreen(display)); 4053 (void) XTranslateCoordinates(display,window,root_window,0,0,&x_offset, 4054 &y_offset,&child); 4055 crop_info.x=(ssize_t) x_offset; 4056 crop_info.y=(ssize_t) y_offset; 4057 crop_info.width=(size_t) window_attributes.width; 4058 crop_info.height=(size_t) window_attributes.height; 4059 if (borders != MagickFalse) 4060 { 4061 /* 4062 Include border in image. 4063 */ 4064 crop_info.x-=(ssize_t) window_attributes.border_width; 4065 crop_info.y-=(ssize_t) window_attributes.border_width; 4066 crop_info.width+=(size_t) (window_attributes.border_width << 1); 4067 crop_info.height+=(size_t) (window_attributes.border_width << 1); 4068 } 4069 /* 4070 Crop to root window. 4071 */ 4072 if (crop_info.x < 0) 4073 { 4074 crop_info.width+=crop_info.x; 4075 crop_info.x=0; 4076 } 4077 if (crop_info.y < 0) 4078 { 4079 crop_info.height+=crop_info.y; 4080 crop_info.y=0; 4081 } 4082 display_width=XDisplayWidth(display,XDefaultScreen(display)); 4083 if ((int) (crop_info.x+crop_info.width) > display_width) 4084 crop_info.width=(size_t) (display_width-crop_info.x); 4085 display_height=XDisplayHeight(display,XDefaultScreen(display)); 4086 if ((int) (crop_info.y+crop_info.height) > display_height) 4087 crop_info.height=(size_t) (display_height-crop_info.y); 4088 /* 4089 Initialize window info attributes. 4090 */ 4091 if (number_windows >= max_windows) 4092 { 4093 /* 4094 Allocate or resize window info buffer. 4095 */ 4096 max_windows+=1024; 4097 if (window_info == (WindowInfo *) NULL) 4098 window_info=(WindowInfo *) AcquireQuantumMemory((size_t) max_windows, 4099 sizeof(*window_info)); 4100 else 4101 window_info=(WindowInfo *) ResizeQuantumMemory(window_info,(size_t) 4102 max_windows,sizeof(*window_info)); 4103 } 4104 if (window_info == (WindowInfo *) NULL) 4105 { 4106 ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed","..."); 4107 return((Image *) NULL); 4108 } 4109 id=number_windows++; 4110 window_info[id].window=window; 4111 window_info[id].visual=window_attributes.visual; 4112 window_info[id].colormap=window_attributes.colormap; 4113 window_info[id].bounds.x1=(short) crop_info.x; 4114 window_info[id].bounds.y1=(short) crop_info.y; 4115 window_info[id].bounds.x2=(short) (crop_info.x+(int) crop_info.width-1); 4116 window_info[id].bounds.y2=(short) (crop_info.y+(int) crop_info.height-1); 4117 crop_info.x-=x_offset; 4118 crop_info.y-=y_offset; 4119 window_info[id].crop_info=crop_info; 4120 if (level != 0) 4121 { 4122 unsigned int 4123 number_children; 4124 4125 Window 4126 *children; 4127 4128 /* 4129 Descend the window hierarchy. 4130 */ 4131 status=XQueryTree(display,window,&root_window,&window_info[id].parent, 4132 &children,&number_children); 4133 for (i=0; i < id; i++) 4134 if ((window_info[i].window == window_info[id].parent) && 4135 (window_info[i].visual == window_info[id].visual) && 4136 (window_info[i].colormap == window_info[id].colormap)) 4137 { 4138 if ((window_info[id].bounds.x1 < window_info[i].bounds.x1) || 4139 (window_info[id].bounds.x2 > window_info[i].bounds.x2) || 4140 (window_info[id].bounds.y1 < window_info[i].bounds.y1) || 4141 (window_info[id].bounds.y2 > window_info[i].bounds.y2)) 4142 { 4143 /* 4144 Eliminate windows not circumscribed by their parent. 4145 */ 4146 number_windows--; 4147 break; 4148 } 4149 } 4150 if ((status == True) && (number_children != 0)) 4151 { 4152 for (i=0; i < (int) number_children; i++) 4153 (void) XGetWindowImage(display,children[i],MagickFalse,level+1, 4154 exception); 4155 (void) XFree((void *) children); 4156 } 4157 } 4158 if (level <= 1) 4159 { 4160 CacheView 4161 *composite_view; 4162 4163 ColormapInfo 4164 *next; 4165 4166 Image 4167 *composite_image, 4168 *image; 4169 4170 int 4171 y; 4172 4173 MagickBooleanType 4174 import; 4175 4176 register int 4177 j, 4178 x; 4179 4180 register Quantum 4181 *magick_restrict q; 4182 4183 register size_t 4184 pixel; 4185 4186 unsigned int 4187 number_colors; 4188 4189 XColor 4190 *colors; 4191 4192 XImage 4193 *ximage; 4194 4195 /* 4196 Get X image for each window in the list. 4197 */ 4198 image=NewImageList(); 4199 for (id=0; id < number_windows; id++) 4200 { 4201 /* 4202 Does target window intersect top level window? 4203 */ 4204 import=((window_info[id].bounds.x2 >= window_info[0].bounds.x1) && 4205 (window_info[id].bounds.x1 <= window_info[0].bounds.x2) && 4206 (window_info[id].bounds.y2 >= window_info[0].bounds.y1) && 4207 (window_info[id].bounds.y1 <= window_info[0].bounds.y2)) ? 4208 MagickTrue : MagickFalse; 4209 /* 4210 Is target window contained by another window with the same colormap? 4211 */ 4212 for (j=0; j < id; j++) 4213 if ((window_info[id].visual == window_info[j].visual) && 4214 (window_info[id].colormap == window_info[j].colormap)) 4215 { 4216 if ((window_info[id].bounds.x1 >= window_info[j].bounds.x1) && 4217 (window_info[id].bounds.x2 <= window_info[j].bounds.x2) && 4218 (window_info[id].bounds.y1 >= window_info[j].bounds.y1) && 4219 (window_info[id].bounds.y2 <= window_info[j].bounds.y2)) 4220 import=MagickFalse; 4221 } 4222 if (import == MagickFalse) 4223 continue; 4224 /* 4225 Get X image. 4226 */ 4227 ximage=XGetImage(display,window_info[id].window,(int) 4228 window_info[id].crop_info.x,(int) window_info[id].crop_info.y, 4229 (unsigned int) window_info[id].crop_info.width,(unsigned int) 4230 window_info[id].crop_info.height,AllPlanes,ZPixmap); 4231 if (ximage == (XImage *) NULL) 4232 continue; 4233 /* 4234 Initialize window colormap. 4235 */ 4236 number_colors=0; 4237 colors=(XColor *) NULL; 4238 if (window_info[id].colormap != (Colormap) NULL) 4239 { 4240 ColormapInfo 4241 *p; 4242 4243 /* 4244 Search colormap list for window colormap. 4245 */ 4246 number_colors=(unsigned int) window_info[id].visual->map_entries; 4247 for (p=colormap_info; p != (ColormapInfo *) NULL; p=p->next) 4248 if (p->colormap == window_info[id].colormap) 4249 break; 4250 if (p == (ColormapInfo *) NULL) 4251 { 4252 /* 4253 Get the window colormap. 4254 */ 4255 colors=(XColor *) AcquireQuantumMemory(number_colors, 4256 sizeof(*colors)); 4257 if (colors == (XColor *) NULL) 4258 { 4259 XDestroyImage(ximage); 4260 return((Image *) NULL); 4261 } 4262 if ((window_info[id].visual->klass != DirectColor) && 4263 (window_info[id].visual->klass != TrueColor)) 4264 for (i=0; i < (int) number_colors; i++) 4265 { 4266 colors[i].pixel=(size_t) i; 4267 colors[i].pad='\0'; 4268 } 4269 else 4270 { 4271 size_t 4272 blue, 4273 blue_bit, 4274 green, 4275 green_bit, 4276 red, 4277 red_bit; 4278 4279 /* 4280 DirectColor or TrueColor visual. 4281 */ 4282 red=0; 4283 green=0; 4284 blue=0; 4285 red_bit=window_info[id].visual->red_mask & 4286 (~(window_info[id].visual->red_mask)+1); 4287 green_bit=window_info[id].visual->green_mask & 4288 (~(window_info[id].visual->green_mask)+1); 4289 blue_bit=window_info[id].visual->blue_mask & 4290 (~(window_info[id].visual->blue_mask)+1); 4291 for (i=0; i < (int) number_colors; i++) 4292 { 4293 colors[i].pixel=(unsigned long) (red | green | blue); 4294 colors[i].pad='\0'; 4295 red+=red_bit; 4296 if (red > window_info[id].visual->red_mask) 4297 red=0; 4298 green+=green_bit; 4299 if (green > window_info[id].visual->green_mask) 4300 green=0; 4301 blue+=blue_bit; 4302 if (blue > window_info[id].visual->blue_mask) 4303 blue=0; 4304 } 4305 } 4306 (void) XQueryColors(display,window_info[id].colormap,colors, 4307 (int) number_colors); 4308 /* 4309 Append colormap to colormap list. 4310 */ 4311 p=(ColormapInfo *) AcquireMagickMemory(sizeof(*p)); 4312 if (p == (ColormapInfo *) NULL) 4313 return((Image *) NULL); 4314 p->colormap=window_info[id].colormap; 4315 p->colors=colors; 4316 p->next=colormap_info; 4317 colormap_info=p; 4318 } 4319 colors=p->colors; 4320 } 4321 /* 4322 Allocate image structure. 4323 */ 4324 composite_image=AcquireImage((ImageInfo *) NULL,exception); 4325 if (composite_image == (Image *) NULL) 4326 { 4327 XDestroyImage(ximage); 4328 return((Image *) NULL); 4329 } 4330 /* 4331 Convert X image to MIFF format. 4332 */ 4333 if ((window_info[id].visual->klass != TrueColor) && 4334 (window_info[id].visual->klass != DirectColor)) 4335 composite_image->storage_class=PseudoClass; 4336 composite_image->columns=(size_t) ximage->width; 4337 composite_image->rows=(size_t) ximage->height; 4338 composite_view=AcquireAuthenticCacheView(composite_image,exception); 4339 switch (composite_image->storage_class) 4340 { 4341 case DirectClass: 4342 default: 4343 { 4344 register size_t 4345 color, 4346 index; 4347 4348 size_t 4349 blue_mask, 4350 blue_shift, 4351 green_mask, 4352 green_shift, 4353 red_mask, 4354 red_shift; 4355 4356 /* 4357 Determine shift and mask for red, green, and blue. 4358 */ 4359 red_mask=window_info[id].visual->red_mask; 4360 red_shift=0; 4361 while ((red_mask != 0) && ((red_mask & 0x01) == 0)) 4362 { 4363 red_mask>>=1; 4364 red_shift++; 4365 } 4366 green_mask=window_info[id].visual->green_mask; 4367 green_shift=0; 4368 while ((green_mask != 0) && ((green_mask & 0x01) == 0)) 4369 { 4370 green_mask>>=1; 4371 green_shift++; 4372 } 4373 blue_mask=window_info[id].visual->blue_mask; 4374 blue_shift=0; 4375 while ((blue_mask != 0) && ((blue_mask & 0x01) == 0)) 4376 { 4377 blue_mask>>=1; 4378 blue_shift++; 4379 } 4380 /* 4381 Convert X image to DirectClass packets. 4382 */ 4383 if ((number_colors != 0) && 4384 (window_info[id].visual->klass == DirectColor)) 4385 for (y=0; y < (int) composite_image->rows; y++) 4386 { 4387 q=QueueCacheViewAuthenticPixels(composite_view,0,(ssize_t) y, 4388 composite_image->columns,1,exception); 4389 if (q == (Quantum *) NULL) 4390 break; 4391 for (x=0; x < (int) composite_image->columns; x++) 4392 { 4393 pixel=XGetPixel(ximage,x,y); 4394 index=(pixel >> red_shift) & red_mask; 4395 SetPixelRed(composite_image, 4396 ScaleShortToQuantum(colors[index].red),q); 4397 index=(pixel >> green_shift) & green_mask; 4398 SetPixelGreen(composite_image, 4399 ScaleShortToQuantum(colors[index].green),q); 4400 index=(pixel >> blue_shift) & blue_mask; 4401 SetPixelBlue(composite_image, 4402 ScaleShortToQuantum(colors[index].blue),q); 4403 q+=GetPixelChannels(composite_image); 4404 } 4405 status=SyncCacheViewAuthenticPixels(composite_view,exception); 4406 if (status == MagickFalse) 4407 break; 4408 } 4409 else 4410 for (y=0; y < (int) composite_image->rows; y++) 4411 { 4412 q=QueueCacheViewAuthenticPixels(composite_view,0,(ssize_t) y, 4413 composite_image->columns,1,exception); 4414 if (q == (Quantum *) NULL) 4415 break; 4416 for (x=0; x < (int) composite_image->columns; x++) 4417 { 4418 pixel=XGetPixel(ximage,x,y); 4419 color=(pixel >> red_shift) & red_mask; 4420 if (red_mask != 0) 4421 color=(65535UL*color)/red_mask; 4422 SetPixelRed(composite_image,ScaleShortToQuantum( 4423 (unsigned short) color),q); 4424 color=(pixel >> green_shift) & green_mask; 4425 if (green_mask != 0) 4426 color=(65535UL*color)/green_mask; 4427 SetPixelGreen(composite_image,ScaleShortToQuantum( 4428 (unsigned short) color),q); 4429 color=(pixel >> blue_shift) & blue_mask; 4430 if (blue_mask != 0) 4431 color=(65535UL*color)/blue_mask; 4432 SetPixelBlue(composite_image,ScaleShortToQuantum( 4433 (unsigned short) color),q); 4434 q+=GetPixelChannels(composite_image); 4435 } 4436 status=SyncCacheViewAuthenticPixels(composite_view,exception); 4437 if (status == MagickFalse) 4438 break; 4439 } 4440 break; 4441 } 4442 case PseudoClass: 4443 { 4444 /* 4445 Create colormap. 4446 */ 4447 status=AcquireImageColormap(composite_image,number_colors, 4448 exception); 4449 if (status == MagickFalse) 4450 { 4451 XDestroyImage(ximage); 4452 composite_image=DestroyImage(composite_image); 4453 return((Image *) NULL); 4454 } 4455 for (i=0; i < (int) composite_image->colors; i++) 4456 { 4457 composite_image->colormap[colors[i].pixel].red=(double) 4458 ScaleShortToQuantum(colors[i].red); 4459 composite_image->colormap[colors[i].pixel].green=(double) 4460 ScaleShortToQuantum(colors[i].green); 4461 composite_image->colormap[colors[i].pixel].blue=(double) 4462 ScaleShortToQuantum(colors[i].blue); 4463 } 4464 /* 4465 Convert X image to PseudoClass packets. 4466 */ 4467 for (y=0; y < (int) composite_image->rows; y++) 4468 { 4469 q=QueueCacheViewAuthenticPixels(composite_view,0,(ssize_t) y, 4470 composite_image->columns,1,exception); 4471 if (q == (Quantum *) NULL) 4472 break; 4473 for (x=0; x < (int) composite_image->columns; x++) 4474 { 4475 index=(Quantum) XGetPixel(ximage,x,y); 4476 SetPixelIndex(composite_image,index,q); 4477 SetPixelViaPixelInfo(composite_image, 4478 composite_image->colormap+(ssize_t) index,q); 4479 q+=GetPixelChannels(composite_image); 4480 } 4481 status=SyncCacheViewAuthenticPixels(composite_view,exception); 4482 if (status == MagickFalse) 4483 break; 4484 } 4485 break; 4486 } 4487 } 4488 composite_view=DestroyCacheView(composite_view); 4489 XDestroyImage(ximage); 4490 if (image == (Image *) NULL) 4491 { 4492 image=composite_image; 4493 continue; 4494 } 4495 /* 4496 Composite any children in back-to-front order. 4497 */ 4498 (void) XTranslateCoordinates(display,window_info[id].window,window,0,0, 4499 &x_offset,&y_offset,&child); 4500 x_offset-=(int) crop_info.x; 4501 if (x_offset < 0) 4502 x_offset=0; 4503 y_offset-=(int) crop_info.y; 4504 if (y_offset < 0) 4505 y_offset=0; 4506 (void) CompositeImage(image,composite_image,CopyCompositeOp,MagickTrue, 4507 (ssize_t) x_offset,(ssize_t) y_offset,exception); 4508 composite_image=DestroyImage(composite_image); 4509 } 4510 /* 4511 Relinquish resources. 4512 */ 4513 while (colormap_info != (ColormapInfo *) NULL) 4514 { 4515 next=colormap_info->next; 4516 colormap_info->colors=(XColor *) RelinquishMagickMemory( 4517 colormap_info->colors); 4518 colormap_info=(ColormapInfo *) RelinquishMagickMemory(colormap_info); 4519 colormap_info=next; 4520 } 4521 /* 4522 Relinquish resources and restore initial state. 4523 */ 4524 window_info=(WindowInfo *) RelinquishMagickMemory(window_info); 4525 max_windows=0; 4526 number_windows=0; 4527 colormap_info=(ColormapInfo *) NULL; 4528 return(image); 4529 } 4530 return((Image *) NULL); 4531} 4532 4533/* 4534%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4535% % 4536% % 4537% % 4538% X G e t W i n d o w I n f o % 4539% % 4540% % 4541% % 4542%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4543% 4544% XGetWindowInfo() initializes the XWindowInfo structure. 4545% 4546% The format of the XGetWindowInfo method is: 4547% 4548% void XGetWindowInfo(Display *display,XVisualInfo *visual_info, 4549% XStandardColormap *map_info,XPixelInfo *pixel,XFontStruct *font_info, 4550% XResourceInfo *resource_info,XWindowInfo *window) 4551% resource_info,window) 4552% 4553% A description of each parameter follows: 4554% 4555% o display: Specifies a connection to an X server; returned from 4556% XOpenDisplay. 4557% 4558% o visual_info: Specifies a pointer to a X11 XVisualInfo structure; 4559% returned from XGetVisualInfo. 4560% 4561% o map_info: If map_type is specified, this structure is initialized 4562% with info from the Standard Colormap. 4563% 4564% o pixel: Specifies a pointer to a XPixelInfo structure. 4565% 4566% o font_info: Specifies a pointer to a XFontStruct structure. 4567% 4568% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. 4569% 4570*/ 4571MagickPrivate void XGetWindowInfo(Display *display,XVisualInfo *visual_info, 4572 XStandardColormap *map_info,XPixelInfo *pixel,XFontStruct *font_info, 4573 XResourceInfo *resource_info,XWindowInfo *window) 4574{ 4575 /* 4576 Initialize window info. 4577 */ 4578 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 4579 assert(display != (Display *) NULL); 4580 assert(visual_info != (XVisualInfo *) NULL); 4581 assert(map_info != (XStandardColormap *) NULL); 4582 assert(pixel != (XPixelInfo *) NULL); 4583 assert(resource_info != (XResourceInfo *) NULL); 4584 assert(window != (XWindowInfo *) NULL); 4585 if (window->id != (Window) NULL) 4586 { 4587 if (window->cursor != (Cursor) NULL) 4588 (void) XFreeCursor(display,window->cursor); 4589 if (window->busy_cursor != (Cursor) NULL) 4590 (void) XFreeCursor(display,window->busy_cursor); 4591 if (window->highlight_stipple != (Pixmap) NULL) 4592 (void) XFreePixmap(display,window->highlight_stipple); 4593 if (window->shadow_stipple != (Pixmap) NULL) 4594 (void) XFreePixmap(display,window->shadow_stipple); 4595 if (window->name == (char *) NULL) 4596 window->name=AcquireString(""); 4597 if (window->icon_name == (char *) NULL) 4598 window->icon_name=AcquireString(""); 4599 } 4600 else 4601 { 4602 /* 4603 Initialize these attributes just once. 4604 */ 4605 window->id=(Window) NULL; 4606 if (window->name == (char *) NULL) 4607 window->name=AcquireString(""); 4608 if (window->icon_name == (char *) NULL) 4609 window->icon_name=AcquireString(""); 4610 window->x=XDisplayWidth(display,visual_info->screen) >> 1; 4611 window->y=XDisplayWidth(display,visual_info->screen) >> 1; 4612 window->ximage=(XImage *) NULL; 4613 window->matte_image=(XImage *) NULL; 4614 window->pixmap=(Pixmap) NULL; 4615 window->matte_pixmap=(Pixmap) NULL; 4616 window->mapped=MagickFalse; 4617 window->stasis=MagickFalse; 4618 window->shared_memory=MagickTrue; 4619 window->segment_info=(void *) NULL; 4620#if defined(MAGICKCORE_HAVE_SHARED_MEMORY) 4621 { 4622 XShmSegmentInfo 4623 *segment_info; 4624 4625 if (window->segment_info == (void *) NULL) 4626 window->segment_info=AcquireQuantumMemory(2,sizeof(*segment_info)); 4627 segment_info=(XShmSegmentInfo *) window->segment_info; 4628 segment_info[0].shmid=(-1); 4629 segment_info[0].shmaddr=(char *) NULL; 4630 segment_info[1].shmid=(-1); 4631 segment_info[1].shmaddr=(char *) NULL; 4632 } 4633#endif 4634 } 4635 /* 4636 Initialize these attributes every time function is called. 4637 */ 4638 window->screen=visual_info->screen; 4639 window->root=XRootWindow(display,visual_info->screen); 4640 window->visual=visual_info->visual; 4641 window->storage_class=(unsigned int) visual_info->klass; 4642 window->depth=(unsigned int) visual_info->depth; 4643 window->visual_info=visual_info; 4644 window->map_info=map_info; 4645 window->pixel_info=pixel; 4646 window->font_info=font_info; 4647 window->cursor=XCreateFontCursor(display,XC_left_ptr); 4648 window->busy_cursor=XCreateFontCursor(display,XC_watch); 4649 window->geometry=(char *) NULL; 4650 window->icon_geometry=(char *) NULL; 4651 if (resource_info->icon_geometry != (char *) NULL) 4652 (void) CloneString(&window->icon_geometry,resource_info->icon_geometry); 4653 window->crop_geometry=(char *) NULL; 4654 window->flags=(size_t) PSize; 4655 window->width=1; 4656 window->height=1; 4657 window->min_width=1; 4658 window->min_height=1; 4659 window->width_inc=1; 4660 window->height_inc=1; 4661 window->border_width=resource_info->border_width; 4662 window->annotate_context=pixel->annotate_context; 4663 window->highlight_context=pixel->highlight_context; 4664 window->widget_context=pixel->widget_context; 4665 window->shadow_stipple=(Pixmap) NULL; 4666 window->highlight_stipple=(Pixmap) NULL; 4667 window->use_pixmap=MagickTrue; 4668 window->immutable=MagickFalse; 4669 window->shape=MagickFalse; 4670 window->data=0; 4671 window->mask=(int) (CWBackingStore | CWBackPixel | CWBackPixmap | 4672 CWBitGravity | CWBorderPixel | CWColormap | CWCursor | CWDontPropagate | 4673 CWEventMask | CWOverrideRedirect | CWSaveUnder | CWWinGravity); 4674 window->attributes.background_pixel=pixel->background_color.pixel; 4675 window->attributes.background_pixmap=(Pixmap) NULL; 4676 window->attributes.bit_gravity=ForgetGravity; 4677 window->attributes.backing_store=WhenMapped; 4678 window->attributes.save_under=MagickTrue; 4679 window->attributes.border_pixel=pixel->border_color.pixel; 4680 window->attributes.colormap=map_info->colormap; 4681 window->attributes.cursor=window->cursor; 4682 window->attributes.do_not_propagate_mask=NoEventMask; 4683 window->attributes.event_mask=NoEventMask; 4684 window->attributes.override_redirect=MagickFalse; 4685 window->attributes.win_gravity=NorthWestGravity; 4686 window->orphan=MagickFalse; 4687} 4688 4689/* 4690%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4691% % 4692% % 4693% % 4694% X H i g h l i g h t E l l i p s e % 4695% % 4696% % 4697% % 4698%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4699% 4700% XHighlightEllipse() puts a border on the X server around a region defined by 4701% highlight_info. 4702% 4703% The format of the XHighlightEllipse method is: 4704% 4705% void XHighlightEllipse(Display *display,Window window, 4706% GC annotate_context,const RectangleInfo *highlight_info) 4707% 4708% A description of each parameter follows: 4709% 4710% o display: Specifies a connection to an X server; returned from 4711% XOpenDisplay. 4712% 4713% o window: Specifies a pointer to a Window structure. 4714% 4715% o annotate_context: Specifies a pointer to a GC structure. 4716% 4717% o highlight_info: Specifies a pointer to a RectangleInfo structure. It 4718% contains the extents of any highlighting rectangle. 4719% 4720*/ 4721MagickPrivate void XHighlightEllipse(Display *display,Window window, 4722 GC annotate_context,const RectangleInfo *highlight_info) 4723{ 4724 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 4725 assert(display != (Display *) NULL); 4726 assert(window != (Window) NULL); 4727 assert(annotate_context != (GC) NULL); 4728 assert(highlight_info != (RectangleInfo *) NULL); 4729 if ((highlight_info->width < 4) || (highlight_info->height < 4)) 4730 return; 4731 (void) XDrawArc(display,window,annotate_context,(int) highlight_info->x, 4732 (int) highlight_info->y,(unsigned int) highlight_info->width-1, 4733 (unsigned int) highlight_info->height-1,0,360*64); 4734 (void) XDrawArc(display,window,annotate_context,(int) highlight_info->x+1, 4735 (int) highlight_info->y+1,(unsigned int) highlight_info->width-3, 4736 (unsigned int) highlight_info->height-3,0,360*64); 4737} 4738 4739/* 4740%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4741% % 4742% % 4743% % 4744% X H i g h l i g h t L i n e % 4745% % 4746% % 4747% % 4748%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4749% 4750% XHighlightLine() puts a border on the X server around a region defined by 4751% highlight_info. 4752% 4753% The format of the XHighlightLine method is: 4754% 4755% void XHighlightLine(Display *display,Window window,GC annotate_context, 4756% const XSegment *highlight_info) 4757% 4758% A description of each parameter follows: 4759% 4760% o display: Specifies a connection to an X server; returned from 4761% XOpenDisplay. 4762% 4763% o window: Specifies a pointer to a Window structure. 4764% 4765% o annotate_context: Specifies a pointer to a GC structure. 4766% 4767% o highlight_info: Specifies a pointer to a RectangleInfo structure. It 4768% contains the extents of any highlighting rectangle. 4769% 4770*/ 4771MagickPrivate void XHighlightLine(Display *display,Window window, 4772 GC annotate_context,const XSegment *highlight_info) 4773{ 4774 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 4775 assert(display != (Display *) NULL); 4776 assert(window != (Window) NULL); 4777 assert(annotate_context != (GC) NULL); 4778 assert(highlight_info != (XSegment *) NULL); 4779 (void) XDrawLine(display,window,annotate_context,highlight_info->x1, 4780 highlight_info->y1,highlight_info->x2,highlight_info->y2); 4781} 4782 4783/* 4784%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4785% % 4786% % 4787% % 4788% X H i g h l i g h t R e c t a n g l e % 4789% % 4790% % 4791% % 4792%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4793% 4794% XHighlightRectangle() puts a border on the X server around a region defined 4795% by highlight_info. 4796% 4797% The format of the XHighlightRectangle method is: 4798% 4799% void XHighlightRectangle(Display *display,Window window, 4800% GC annotate_context,const RectangleInfo *highlight_info) 4801% 4802% A description of each parameter follows: 4803% 4804% o display: Specifies a connection to an X server; returned from 4805% XOpenDisplay. 4806% 4807% o window: Specifies a pointer to a Window structure. 4808% 4809% o annotate_context: Specifies a pointer to a GC structure. 4810% 4811% o highlight_info: Specifies a pointer to a RectangleInfo structure. It 4812% contains the extents of any highlighting rectangle. 4813% 4814*/ 4815MagickPrivate void XHighlightRectangle(Display *display,Window window, 4816 GC annotate_context,const RectangleInfo *highlight_info) 4817{ 4818 assert(display != (Display *) NULL); 4819 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 4820 assert(window != (Window) NULL); 4821 assert(annotate_context != (GC) NULL); 4822 assert(highlight_info != (RectangleInfo *) NULL); 4823 if ((highlight_info->width < 4) || (highlight_info->height < 4)) 4824 return; 4825 (void) XDrawRectangle(display,window,annotate_context,(int) highlight_info->x, 4826 (int) highlight_info->y,(unsigned int) highlight_info->width-1, 4827 (unsigned int) highlight_info->height-1); 4828 (void) XDrawRectangle(display,window,annotate_context,(int) highlight_info->x+ 4829 1,(int) highlight_info->y+1,(unsigned int) highlight_info->width-3, 4830 (unsigned int) highlight_info->height-3); 4831} 4832 4833/* 4834%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4835% % 4836% % 4837% % 4838% X I m p o r t I m a g e % 4839% % 4840% % 4841% % 4842%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4843% 4844% XImportImage() reads an image from an X window. 4845% 4846% The format of the XImportImage method is: 4847% 4848% Image *XImportImage(const ImageInfo *image_info,XImportInfo *ximage_info, 4849% ExceptionInfo *exception) 4850% 4851% A description of each parameter follows: 4852% 4853% o image_info: the image info. 4854% 4855% o ximage_info: Specifies a pointer to an XImportInfo structure. 4856% 4857% o exception: return any errors or warnings in this structure. 4858% 4859*/ 4860MagickExport Image *XImportImage(const ImageInfo *image_info, 4861 XImportInfo *ximage_info,ExceptionInfo *exception) 4862{ 4863 Colormap 4864 *colormaps; 4865 4866 Display 4867 *display; 4868 4869 Image 4870 *image; 4871 4872 int 4873 number_colormaps, 4874 number_windows, 4875 x; 4876 4877 RectangleInfo 4878 crop_info; 4879 4880 Status 4881 status; 4882 4883 Window 4884 *children, 4885 client, 4886 prior_target, 4887 root, 4888 target; 4889 4890 XTextProperty 4891 window_name; 4892 4893 /* 4894 Open X server connection. 4895 */ 4896 assert(image_info != (const ImageInfo *) NULL); 4897 assert(image_info->signature == MagickCoreSignature); 4898 if (image_info->debug != MagickFalse) 4899 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", 4900 image_info->filename); 4901 assert(ximage_info != (XImportInfo *) NULL); 4902 display=XOpenDisplay(image_info->server_name); 4903 if (display == (Display *) NULL) 4904 { 4905 ThrowXWindowException(XServerError,"UnableToOpenXServer", 4906 XDisplayName(image_info->server_name)); 4907 return((Image *) NULL); 4908 } 4909 /* 4910 Set our forgiving exception handler. 4911 */ 4912 (void) XSetErrorHandler(XError); 4913 /* 4914 Select target window. 4915 */ 4916 crop_info.x=0; 4917 crop_info.y=0; 4918 crop_info.width=0; 4919 crop_info.height=0; 4920 root=XRootWindow(display,XDefaultScreen(display)); 4921 target=(Window) NULL; 4922 if (*image_info->filename != '\0') 4923 { 4924 if (LocaleCompare(image_info->filename,"root") == 0) 4925 target=root; 4926 else 4927 { 4928 /* 4929 Select window by ID or name. 4930 */ 4931 if (isdigit((int) ((unsigned char) *image_info->filename)) != 0) 4932 target=XWindowByID(display,root,(Window) 4933 strtol(image_info->filename,(char **) NULL,0)); 4934 if (target == (Window) NULL) 4935 target=XWindowByName(display,root,image_info->filename); 4936 if (target == (Window) NULL) 4937 ThrowXWindowException(XServerError,"NoWindowWithSpecifiedIDExists", 4938 image_info->filename); 4939 } 4940 } 4941 /* 4942 If target window is not defined, interactively select one. 4943 */ 4944 prior_target=target; 4945 if (target == (Window) NULL) 4946 target=XSelectWindow(display,&crop_info); 4947 if (target == (Window) NULL) 4948 ThrowXWindowException(XServerError,"UnableToReadXWindowImage", 4949 image_info->filename); 4950 client=target; /* obsolete */ 4951 if (target != root) 4952 { 4953 unsigned int 4954 d; 4955 4956 status=XGetGeometry(display,target,&root,&x,&x,&d,&d,&d,&d); 4957 if (status != False) 4958 { 4959 for ( ; ; ) 4960 { 4961 Window 4962 parent; 4963 4964 /* 4965 Find window manager frame. 4966 */ 4967 status=XQueryTree(display,target,&root,&parent,&children,&d); 4968 if ((status != False) && (children != (Window *) NULL)) 4969 (void) XFree((char *) children); 4970 if ((status == False) || (parent == (Window) NULL) || 4971 (parent == root)) 4972 break; 4973 target=parent; 4974 } 4975 /* 4976 Get client window. 4977 */ 4978 client=XClientWindow(display,target); 4979 if (ximage_info->frame == MagickFalse) 4980 target=client; 4981 if ((ximage_info->frame == MagickFalse) && 4982 (prior_target != MagickFalse)) 4983 target=prior_target; 4984 } 4985 } 4986 if (ximage_info->screen) 4987 { 4988 int 4989 y; 4990 4991 Window 4992 child; 4993 4994 XWindowAttributes 4995 window_attributes; 4996 4997 /* 4998 Obtain window image directly from screen. 4999 */ 5000 status=XGetWindowAttributes(display,target,&window_attributes); 5001 if (status == False) 5002 { 5003 ThrowXWindowException(XServerError,"UnableToReadXWindowAttributes", 5004 image_info->filename); 5005 (void) XCloseDisplay(display); 5006 return((Image *) NULL); 5007 } 5008 (void) XTranslateCoordinates(display,target,root,0,0,&x,&y,&child); 5009 crop_info.x=(ssize_t) x; 5010 crop_info.y=(ssize_t) y; 5011 crop_info.width=(size_t) window_attributes.width; 5012 crop_info.height=(size_t) window_attributes.height; 5013 if (ximage_info->borders != 0) 5014 { 5015 /* 5016 Include border in image. 5017 */ 5018 crop_info.x-=window_attributes.border_width; 5019 crop_info.y-=window_attributes.border_width; 5020 crop_info.width+=window_attributes.border_width << 1; 5021 crop_info.height+=window_attributes.border_width << 1; 5022 } 5023 target=root; 5024 } 5025 /* 5026 If WM_COLORMAP_WINDOWS property is set or multiple colormaps, descend. 5027 */ 5028 number_windows=0; 5029 status=XGetWMColormapWindows(display,target,&children,&number_windows); 5030 if ((status == True) && (number_windows > 0)) 5031 { 5032 ximage_info->descend=MagickTrue; 5033 (void) XFree ((char *) children); 5034 } 5035 colormaps=XListInstalledColormaps(display,target,&number_colormaps); 5036 if (number_colormaps > 0) 5037 { 5038 if (number_colormaps > 1) 5039 ximage_info->descend=MagickTrue; 5040 (void) XFree((char *) colormaps); 5041 } 5042 /* 5043 Alert the user not to alter the screen. 5044 */ 5045 if (ximage_info->silent == MagickFalse) 5046 (void) XBell(display,0); 5047 /* 5048 Get image by window id. 5049 */ 5050 (void) XGrabServer(display); 5051 image=XGetWindowImage(display,target,ximage_info->borders, 5052 ximage_info->descend ? 1U : 0U,exception); 5053 (void) XUngrabServer(display); 5054 if (image == (Image *) NULL) 5055 ThrowXWindowException(XServerError,"UnableToReadXWindowImage", 5056 image_info->filename) 5057 else 5058 { 5059 (void) CopyMagickString(image->filename,image_info->filename, 5060 MagickPathExtent); 5061 if ((crop_info.width != 0) && (crop_info.height != 0)) 5062 { 5063 Image 5064 *clone_image, 5065 *crop_image; 5066 5067 /* 5068 Crop image as defined by the cropping rectangle. 5069 */ 5070 clone_image=CloneImage(image,0,0,MagickTrue,exception); 5071 if (clone_image != (Image *) NULL) 5072 { 5073 crop_image=CropImage(clone_image,&crop_info,exception); 5074 if (crop_image != (Image *) NULL) 5075 { 5076 image=DestroyImage(image); 5077 image=crop_image; 5078 } 5079 } 5080 } 5081 status=XGetWMName(display,target,&window_name); 5082 if (status == True) 5083 { 5084 if (*image_info->filename == '\0') 5085 (void) CopyMagickString(image->filename,(char *) window_name.value, 5086 (size_t) window_name.nitems+1); 5087 (void) XFree((void *) window_name.value); 5088 } 5089 } 5090 if (ximage_info->silent == MagickFalse) 5091 { 5092 /* 5093 Alert the user we're done. 5094 */ 5095 (void) XBell(display,0); 5096 (void) XBell(display,0); 5097 } 5098 (void) XCloseDisplay(display); 5099 return(image); 5100} 5101 5102/* 5103%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5104% % 5105% % 5106% % 5107% X I n i t i a l i z e W i n d o w s % 5108% % 5109% % 5110% % 5111%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5112% 5113% XInitializeWindows() initializes the XWindows structure. 5114% 5115% The format of the XInitializeWindows method is: 5116% 5117% XWindows *XInitializeWindows(Display *display, 5118% XResourceInfo *resource_info) 5119% 5120% A description of each parameter follows: 5121% 5122% o windows: XInitializeWindows returns a pointer to a XWindows structure. 5123% 5124% o display: Specifies a connection to an X server; returned from 5125% XOpenDisplay. 5126% 5127% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. 5128% 5129*/ 5130MagickPrivate XWindows *XInitializeWindows(Display *display, 5131 XResourceInfo *resource_info) 5132{ 5133 Window 5134 root_window; 5135 5136 XWindows 5137 *windows; 5138 5139 /* 5140 Allocate windows structure. 5141 */ 5142 windows=(XWindows *) AcquireMagickMemory(sizeof(*windows)); 5143 if (windows == (XWindows *) NULL) 5144 { 5145 ThrowXWindowFatalException(XServerFatalError,"MemoryAllocationFailed", 5146 "..."); 5147 return((XWindows *) NULL); 5148 } 5149 (void) ResetMagickMemory(windows,0,sizeof(*windows)); 5150 windows->pixel_info=(XPixelInfo *) AcquireMagickMemory( 5151 sizeof(*windows->pixel_info)); 5152 windows->icon_pixel=(XPixelInfo *) AcquireMagickMemory( 5153 sizeof(*windows->icon_pixel)); 5154 windows->icon_resources=(XResourceInfo *) AcquireMagickMemory( 5155 sizeof(*windows->icon_resources)); 5156 if ((windows->pixel_info == (XPixelInfo *) NULL) || 5157 (windows->icon_pixel == (XPixelInfo *) NULL) || 5158 (windows->icon_resources == (XResourceInfo *) NULL)) 5159 { 5160 ThrowXWindowFatalException(XServerFatalError,"MemoryAllocationFailed", 5161 "..."); 5162 return((XWindows *) NULL); 5163 } 5164 /* 5165 Initialize windows structure. 5166 */ 5167 windows->display=display; 5168 windows->wm_protocols=XInternAtom(display,"WM_PROTOCOLS",MagickFalse); 5169 windows->wm_delete_window=XInternAtom(display,"WM_DELETE_WINDOW",MagickFalse); 5170 windows->wm_take_focus=XInternAtom(display,"WM_TAKE_FOCUS",MagickFalse); 5171 windows->im_protocols=XInternAtom(display,"IM_PROTOCOLS",MagickFalse); 5172 windows->im_remote_command= 5173 XInternAtom(display,"IM_REMOTE_COMMAND",MagickFalse); 5174 windows->im_update_widget=XInternAtom(display,"IM_UPDATE_WIDGET",MagickFalse); 5175 windows->im_update_colormap= 5176 XInternAtom(display,"IM_UPDATE_COLORMAP",MagickFalse); 5177 windows->im_former_image=XInternAtom(display,"IM_FORMER_IMAGE",MagickFalse); 5178 windows->im_next_image=XInternAtom(display,"IM_NEXT_IMAGE",MagickFalse); 5179 windows->im_retain_colors=XInternAtom(display,"IM_RETAIN_COLORS",MagickFalse); 5180 windows->im_exit=XInternAtom(display,"IM_EXIT",MagickFalse); 5181 windows->dnd_protocols=XInternAtom(display,"DndProtocol",MagickFalse); 5182#if defined(MAGICKCORE_WINDOWS_SUPPORT) 5183 (void) XSynchronize(display,IsWindows95()); 5184#endif 5185 if (IsEventLogging()) 5186 { 5187 (void) XSynchronize(display,MagickTrue); 5188 (void) LogMagickEvent(X11Event,GetMagickModule(),"Version: %s", 5189 GetMagickVersion((size_t *) NULL)); 5190 (void) LogMagickEvent(X11Event,GetMagickModule(),"Protocols:"); 5191 (void) LogMagickEvent(X11Event,GetMagickModule(), 5192 " Window Manager: 0x%lx",windows->wm_protocols); 5193 (void) LogMagickEvent(X11Event,GetMagickModule(), 5194 " delete window: 0x%lx",windows->wm_delete_window); 5195 (void) LogMagickEvent(X11Event,GetMagickModule()," take focus: 0x%lx", 5196 windows->wm_take_focus); 5197 (void) LogMagickEvent(X11Event,GetMagickModule()," ImageMagick: 0x%lx", 5198 windows->im_protocols); 5199 (void) LogMagickEvent(X11Event,GetMagickModule(), 5200 " remote command: 0x%lx",windows->im_remote_command); 5201 (void) LogMagickEvent(X11Event,GetMagickModule(), 5202 " update widget: 0x%lx",windows->im_update_widget); 5203 (void) LogMagickEvent(X11Event,GetMagickModule(), 5204 " update colormap: 0x%lx",windows->im_update_colormap); 5205 (void) LogMagickEvent(X11Event,GetMagickModule(), 5206 " former image: 0x%lx",windows->im_former_image); 5207 (void) LogMagickEvent(X11Event,GetMagickModule()," next image: 0x%lx", 5208 windows->im_next_image); 5209 (void) LogMagickEvent(X11Event,GetMagickModule(), 5210 " retain colors: 0x%lx",windows->im_retain_colors); 5211 (void) LogMagickEvent(X11Event,GetMagickModule()," exit: 0x%lx", 5212 windows->im_exit); 5213 (void) LogMagickEvent(X11Event,GetMagickModule()," Drag and Drop: 0x%lx", 5214 windows->dnd_protocols); 5215 } 5216 /* 5217 Allocate standard colormap. 5218 */ 5219 windows->map_info=XAllocStandardColormap(); 5220 windows->icon_map=XAllocStandardColormap(); 5221 if ((windows->map_info == (XStandardColormap *) NULL) || 5222 (windows->icon_map == (XStandardColormap *) NULL)) 5223 ThrowXWindowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed", 5224 "..."); 5225 windows->map_info->colormap=(Colormap) NULL; 5226 windows->icon_map->colormap=(Colormap) NULL; 5227 windows->pixel_info->pixels=(unsigned long *) NULL; 5228 windows->pixel_info->annotate_context=(GC) NULL; 5229 windows->pixel_info->highlight_context=(GC) NULL; 5230 windows->pixel_info->widget_context=(GC) NULL; 5231 windows->font_info=(XFontStruct *) NULL; 5232 windows->icon_pixel->annotate_context=(GC) NULL; 5233 windows->icon_pixel->pixels=(unsigned long *) NULL; 5234 /* 5235 Allocate visual. 5236 */ 5237 *windows->icon_resources=(*resource_info); 5238 windows->icon_resources->visual_type=(char *) "default"; 5239 windows->icon_resources->colormap=SharedColormap; 5240 windows->visual_info= 5241 XBestVisualInfo(display,windows->map_info,resource_info); 5242 windows->icon_visual= 5243 XBestVisualInfo(display,windows->icon_map,windows->icon_resources); 5244 if ((windows->visual_info == (XVisualInfo *) NULL) || 5245 (windows->icon_visual == (XVisualInfo *) NULL)) 5246 ThrowXWindowFatalException(XServerFatalError,"UnableToGetVisual", 5247 resource_info->visual_type); 5248 if (IsEventLogging()) 5249 { 5250 (void) LogMagickEvent(X11Event,GetMagickModule(),"Visual:"); 5251 (void) LogMagickEvent(X11Event,GetMagickModule()," visual id: 0x%lx", 5252 windows->visual_info->visualid); 5253 (void) LogMagickEvent(X11Event,GetMagickModule()," class: %s", 5254 XVisualClassName(windows->visual_info->klass)); 5255 (void) LogMagickEvent(X11Event,GetMagickModule()," depth: %d planes", 5256 windows->visual_info->depth); 5257 (void) LogMagickEvent(X11Event,GetMagickModule(), 5258 " size of colormap: %d entries",windows->visual_info->colormap_size); 5259 (void) LogMagickEvent(X11Event,GetMagickModule(), 5260 " red, green, blue masks: 0x%lx 0x%lx 0x%lx", 5261 windows->visual_info->red_mask,windows->visual_info->green_mask, 5262 windows->visual_info->blue_mask); 5263 (void) LogMagickEvent(X11Event,GetMagickModule(), 5264 " significant bits in color: %d bits", 5265 windows->visual_info->bits_per_rgb); 5266 } 5267 /* 5268 Allocate class and manager hints. 5269 */ 5270 windows->class_hints=XAllocClassHint(); 5271 windows->manager_hints=XAllocWMHints(); 5272 if ((windows->class_hints == (XClassHint *) NULL) || 5273 (windows->manager_hints == (XWMHints *) NULL)) 5274 ThrowXWindowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed", 5275 "..."); 5276 /* 5277 Determine group leader if we have one. 5278 */ 5279 root_window=XRootWindow(display,windows->visual_info->screen); 5280 windows->group_leader.id=(Window) NULL; 5281 if (resource_info->window_group != (char *) NULL) 5282 { 5283 if (isdigit((int) ((unsigned char) *resource_info->window_group)) != 0) 5284 windows->group_leader.id=XWindowByID(display,root_window,(Window) 5285 strtol((char *) resource_info->window_group,(char **) NULL,0)); 5286 if (windows->group_leader.id == (Window) NULL) 5287 windows->group_leader.id= 5288 XWindowByName(display,root_window,resource_info->window_group); 5289 } 5290 return(windows); 5291} 5292 5293/* 5294%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5295% % 5296% % 5297% % 5298% X M a k e C u r s o r % 5299% % 5300% % 5301% % 5302%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5303% 5304% XMakeCursor() creates a crosshairs X11 cursor. 5305% 5306% The format of the XMakeCursor method is: 5307% 5308% Cursor XMakeCursor(Display *display,Window window,Colormap colormap, 5309% char *background_color,char *foreground_color) 5310% 5311% A description of each parameter follows: 5312% 5313% o display: Specifies a connection to an X server; returned from 5314% XOpenDisplay. 5315% 5316% o window: Specifies the ID of the window for which the cursor is 5317% assigned. 5318% 5319% o colormap: Specifies the ID of the colormap from which the background 5320% and foreground color will be retrieved. 5321% 5322% o background_color: Specifies the color to use for the cursor background. 5323% 5324% o foreground_color: Specifies the color to use for the cursor foreground. 5325% 5326*/ 5327MagickPrivate Cursor XMakeCursor(Display *display,Window window, 5328 Colormap colormap,char *background_color,char *foreground_color) 5329{ 5330#define scope_height 17 5331#define scope_x_hot 8 5332#define scope_y_hot 8 5333#define scope_width 17 5334 5335 static const unsigned char 5336 scope_bits[] = 5337 { 5338 0x80, 0x03, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 5339 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x7f, 5340 0xfc, 0x01, 0x01, 0x00, 0x01, 0x7f, 0xfc, 0x01, 0x80, 0x02, 0x00, 5341 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 5342 0x00, 0x80, 0x02, 0x00, 0x80, 0x03, 0x00 5343 }, 5344 scope_mask_bits[] = 5345 { 5346 0xc0, 0x07, 0x00, 0xc0, 0x07, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06, 5347 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xff, 0xfe, 0x01, 0x7f, 5348 0xfc, 0x01, 0x03, 0x80, 0x01, 0x7f, 0xfc, 0x01, 0xff, 0xfe, 0x01, 5349 0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06, 5350 0x00, 0xc0, 0x07, 0x00, 0xc0, 0x07, 0x00 5351 }; 5352 5353 Cursor 5354 cursor; 5355 5356 Pixmap 5357 mask, 5358 source; 5359 5360 XColor 5361 background, 5362 foreground; 5363 5364 assert(display != (Display *) NULL); 5365 assert(window != (Window) NULL); 5366 assert(colormap != (Colormap) NULL); 5367 assert(background_color != (char *) NULL); 5368 assert(foreground_color != (char *) NULL); 5369 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",background_color); 5370 source=XCreateBitmapFromData(display,window,(char *) scope_bits,scope_width, 5371 scope_height); 5372 mask=XCreateBitmapFromData(display,window,(char *) scope_mask_bits, 5373 scope_width,scope_height); 5374 if ((source == (Pixmap) NULL) || (mask == (Pixmap) NULL)) 5375 { 5376 ThrowXWindowException(XServerError,"UnableToCreatePixmap","..."); 5377 return((Cursor) NULL); 5378 } 5379 (void) XParseColor(display,colormap,background_color,&background); 5380 (void) XParseColor(display,colormap,foreground_color,&foreground); 5381 cursor=XCreatePixmapCursor(display,source,mask,&foreground,&background, 5382 scope_x_hot,scope_y_hot); 5383 (void) XFreePixmap(display,source); 5384 (void) XFreePixmap(display,mask); 5385 return(cursor); 5386} 5387 5388/* 5389%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5390% % 5391% % 5392% % 5393% X M a k e I m a g e % 5394% % 5395% % 5396% % 5397%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5398% 5399% XMakeImage() creates an X11 image. If the image size differs from the X11 5400% image size, the image is first resized. 5401% 5402% The format of the XMakeImage method is: 5403% 5404% MagickBooleanType XMakeImage(Display *display, 5405% const XResourceInfo *resource_info,XWindowInfo *window,Image *image, 5406% unsigned int width,unsigned int height,ExceptionInfo *exception) 5407% 5408% A description of each parameter follows: 5409% 5410% o display: Specifies a connection to an X server; returned from 5411% XOpenDisplay. 5412% 5413% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. 5414% 5415% o window: Specifies a pointer to a XWindowInfo structure. 5416% 5417% o image: the image. 5418% 5419% o width: Specifies the width in pixels of the rectangular area to 5420% display. 5421% 5422% o height: Specifies the height in pixels of the rectangular area to 5423% display. 5424% 5425% o exception: return any errors or warnings in this structure. 5426% 5427*/ 5428MagickPrivate MagickBooleanType XMakeImage(Display *display, 5429 const XResourceInfo *resource_info,XWindowInfo *window,Image *image, 5430 unsigned int width,unsigned int height,ExceptionInfo *exception) 5431{ 5432#define CheckOverflowException(length,width,height) \ 5433 (((height) != 0) && ((length)/((size_t) height) != ((size_t) width))) 5434 5435 int 5436 depth, 5437 format; 5438 5439 size_t 5440 length; 5441 5442 XImage 5443 *matte_image, 5444 *ximage; 5445 5446 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 5447 assert(display != (Display *) NULL); 5448 assert(resource_info != (XResourceInfo *) NULL); 5449 assert(window != (XWindowInfo *) NULL); 5450 assert(width != 0); 5451 assert(height != 0); 5452 if ((window->width == 0) || (window->height == 0)) 5453 return(MagickFalse); 5454 /* 5455 Apply user transforms to the image. 5456 */ 5457 (void) XCheckDefineCursor(display,window->id,window->busy_cursor); 5458 (void) XFlush(display); 5459 depth=(int) window->depth; 5460 if (window->destroy) 5461 window->image=DestroyImage(window->image); 5462 window->image=image; 5463 window->destroy=MagickFalse; 5464 if (window->image != (Image *) NULL) 5465 { 5466 if (window->crop_geometry != (char *) NULL) 5467 { 5468 Image 5469 *crop_image; 5470 5471 RectangleInfo 5472 crop_info; 5473 5474 /* 5475 Crop image. 5476 */ 5477 window->image->page.x=0; 5478 window->image->page.y=0; 5479 (void) ParsePageGeometry(window->image,window->crop_geometry, 5480 &crop_info,exception); 5481 crop_image=CropImage(window->image,&crop_info,exception); 5482 if (crop_image != (Image *) NULL) 5483 { 5484 if (window->image != image) 5485 window->image=DestroyImage(window->image); 5486 window->image=crop_image; 5487 window->destroy=MagickTrue; 5488 } 5489 } 5490 if ((width != (unsigned int) window->image->columns) || 5491 (height != (unsigned int) window->image->rows)) 5492 { 5493 Image 5494 *resize_image; 5495 5496 /* 5497 Resize image. 5498 */ 5499 resize_image=NewImageList(); 5500 if ((window->pixel_info->colors == 0) && 5501 (window->image->rows > (unsigned long) XDisplayHeight(display,window->screen)) && 5502 (window->image->columns > (unsigned long) XDisplayWidth(display,window->screen))) 5503 resize_image=ResizeImage(window->image,width,height, 5504 image->filter,exception); 5505 else 5506 { 5507 if (window->image->storage_class == PseudoClass) 5508 resize_image=SampleImage(window->image,width,height, 5509 exception); 5510 else 5511 resize_image=ThumbnailImage(window->image,width,height, 5512 exception); 5513 } 5514 if (resize_image != (Image *) NULL) 5515 { 5516 if (window->image != image) 5517 window->image=DestroyImage(window->image); 5518 window->image=resize_image; 5519 window->destroy=MagickTrue; 5520 } 5521 } 5522 width=(unsigned int) window->image->columns; 5523 assert((size_t) width == window->image->columns); 5524 height=(unsigned int) window->image->rows; 5525 assert((size_t) height == window->image->rows); 5526 } 5527 /* 5528 Create X image. 5529 */ 5530 ximage=(XImage *) NULL; 5531 format=(depth == 1) ? XYBitmap : ZPixmap; 5532#if defined(MAGICKCORE_HAVE_SHARED_MEMORY) 5533 if (window->shared_memory != MagickFalse) 5534 { 5535 XShmSegmentInfo 5536 *segment_info; 5537 5538 segment_info=(XShmSegmentInfo *) window->segment_info; 5539 segment_info[1].shmid=(-1); 5540 segment_info[1].shmaddr=(char *) NULL; 5541 ximage=XShmCreateImage(display,window->visual,(unsigned int) depth,format, 5542 (char *) NULL,&segment_info[1],width,height); 5543 if (ximage == (XImage *) NULL) 5544 window->shared_memory=MagickFalse; 5545 else 5546 { 5547 length=(size_t) ximage->bytes_per_line*ximage->height; 5548 if (CheckOverflowException(length,ximage->bytes_per_line,ximage->height)) 5549 window->shared_memory=MagickFalse; 5550 } 5551 if (window->shared_memory != MagickFalse) 5552 segment_info[1].shmid=shmget(IPC_PRIVATE,length,IPC_CREAT | 0777); 5553 if (window->shared_memory != MagickFalse) 5554 segment_info[1].shmaddr=(char *) shmat(segment_info[1].shmid,0,0); 5555 if (segment_info[1].shmid < 0) 5556 window->shared_memory=MagickFalse; 5557 if (window->shared_memory != MagickFalse) 5558 (void) shmctl(segment_info[1].shmid,IPC_RMID,0); 5559 else 5560 { 5561 if (ximage != (XImage *) NULL) 5562 XDestroyImage(ximage); 5563 ximage=(XImage *) NULL; 5564 if (segment_info[1].shmaddr) 5565 { 5566 (void) shmdt(segment_info[1].shmaddr); 5567 segment_info[1].shmaddr=(char *) NULL; 5568 } 5569 if (segment_info[1].shmid >= 0) 5570 { 5571 (void) shmctl(segment_info[1].shmid,IPC_RMID,0); 5572 segment_info[1].shmid=(-1); 5573 } 5574 } 5575 } 5576#endif 5577 /* 5578 Allocate X image pixel data. 5579 */ 5580#if defined(MAGICKCORE_HAVE_SHARED_MEMORY) 5581 if (window->shared_memory) 5582 { 5583 Status 5584 status; 5585 5586 XShmSegmentInfo 5587 *segment_info; 5588 5589 (void) XSync(display,MagickFalse); 5590 xerror_alert=MagickFalse; 5591 segment_info=(XShmSegmentInfo *) window->segment_info; 5592 ximage->data=segment_info[1].shmaddr; 5593 segment_info[1].readOnly=MagickFalse; 5594 status=XShmAttach(display,&segment_info[1]); 5595 if (status != False) 5596 (void) XSync(display,MagickFalse); 5597 if ((status == False) || (xerror_alert != MagickFalse)) 5598 { 5599 window->shared_memory=MagickFalse; 5600 if (status != False) 5601 XShmDetach(display,&segment_info[1]); 5602 ximage->data=NULL; 5603 XDestroyImage(ximage); 5604 ximage=(XImage *) NULL; 5605 if (segment_info[1].shmid >= 0) 5606 { 5607 if (segment_info[1].shmaddr != NULL) 5608 (void) shmdt(segment_info[1].shmaddr); 5609 (void) shmctl(segment_info[1].shmid,IPC_RMID,0); 5610 segment_info[1].shmid=(-1); 5611 segment_info[1].shmaddr=(char *) NULL; 5612 } 5613 } 5614 } 5615#endif 5616 if (window->shared_memory == MagickFalse) 5617 ximage=XCreateImage(display,window->visual,(unsigned int) depth,format,0, 5618 (char *) NULL,width,height,XBitmapPad(display),0); 5619 if (ximage == (XImage *) NULL) 5620 { 5621 /* 5622 Unable to create X image. 5623 */ 5624 (void) XCheckDefineCursor(display,window->id,window->cursor); 5625 return(MagickFalse); 5626 } 5627 length=(size_t) ximage->bytes_per_line*ximage->height; 5628 if (IsEventLogging()) 5629 { 5630 (void) LogMagickEvent(X11Event,GetMagickModule(),"XImage:"); 5631 (void) LogMagickEvent(X11Event,GetMagickModule()," width, height: %dx%d", 5632 ximage->width,ximage->height); 5633 (void) LogMagickEvent(X11Event,GetMagickModule()," format: %d", 5634 ximage->format); 5635 (void) LogMagickEvent(X11Event,GetMagickModule()," byte order: %d", 5636 ximage->byte_order); 5637 (void) LogMagickEvent(X11Event,GetMagickModule(), 5638 " bitmap unit, bit order, pad: %d %d %d",ximage->bitmap_unit, 5639 ximage->bitmap_bit_order,ximage->bitmap_pad); 5640 (void) LogMagickEvent(X11Event,GetMagickModule()," depth: %d", 5641 ximage->depth); 5642 (void) LogMagickEvent(X11Event,GetMagickModule()," bytes per line: %d", 5643 ximage->bytes_per_line); 5644 (void) LogMagickEvent(X11Event,GetMagickModule()," bits per pixel: %d", 5645 ximage->bits_per_pixel); 5646 (void) LogMagickEvent(X11Event,GetMagickModule(), 5647 " red, green, blue masks: 0x%lx 0x%lx 0x%lx",ximage->red_mask, 5648 ximage->green_mask,ximage->blue_mask); 5649 } 5650 if (window->shared_memory == MagickFalse) 5651 { 5652 if (ximage->format != XYBitmap) 5653 ximage->data=(char *) malloc((size_t) ximage->bytes_per_line* 5654 ximage->height); 5655 else 5656 ximage->data=(char *) malloc((size_t) ximage->bytes_per_line* 5657 ximage->depth*ximage->height); 5658 } 5659 if (ximage->data == (char *) NULL) 5660 { 5661 /* 5662 Unable to allocate pixel data. 5663 */ 5664 XDestroyImage(ximage); 5665 ximage=(XImage *) NULL; 5666 (void) XCheckDefineCursor(display,window->id,window->cursor); 5667 return(MagickFalse); 5668 } 5669 if (window->ximage != (XImage *) NULL) 5670 { 5671 /* 5672 Destroy previous X image. 5673 */ 5674 length=(size_t) window->ximage->bytes_per_line*window->ximage->height; 5675#if defined(MAGICKCORE_HAVE_SHARED_MEMORY) 5676 if (window->segment_info != (XShmSegmentInfo *) NULL) 5677 { 5678 XShmSegmentInfo 5679 *segment_info; 5680 5681 segment_info=(XShmSegmentInfo *) window->segment_info; 5682 if (segment_info[0].shmid >= 0) 5683 { 5684 (void) XSync(display,MagickFalse); 5685 (void) XShmDetach(display,&segment_info[0]); 5686 (void) XSync(display,MagickFalse); 5687 if (segment_info[0].shmaddr != (char *) NULL) 5688 (void) shmdt(segment_info[0].shmaddr); 5689 (void) shmctl(segment_info[0].shmid,IPC_RMID,0); 5690 segment_info[0].shmid=(-1); 5691 segment_info[0].shmaddr=(char *) NULL; 5692 window->ximage->data=(char *) NULL; 5693 } 5694 } 5695#endif 5696 if (window->ximage->data != (char *) NULL) 5697 free(window->ximage->data); 5698 window->ximage->data=(char *) NULL; 5699 XDestroyImage(window->ximage); 5700 window->ximage=(XImage *) NULL; 5701 } 5702#if defined(MAGICKCORE_HAVE_SHARED_MEMORY) 5703 if (window->segment_info != (XShmSegmentInfo *) NULL) 5704 { 5705 XShmSegmentInfo 5706 *segment_info; 5707 5708 segment_info=(XShmSegmentInfo *) window->segment_info; 5709 segment_info[0]=segment_info[1]; 5710 } 5711#endif 5712 window->ximage=ximage; 5713 matte_image=(XImage *) NULL; 5714 if ((window->shape != MagickFalse) && (window->image != (Image *) NULL)) 5715 if ((window->image->alpha_trait != UndefinedPixelTrait) && 5716 ((int) width <= XDisplayWidth(display,window->screen)) && 5717 ((int) height <= XDisplayHeight(display,window->screen))) 5718 { 5719 /* 5720 Create matte image. 5721 */ 5722 matte_image=XCreateImage(display,window->visual,1,XYBitmap,0, 5723 (char *) NULL,width,height,XBitmapPad(display),0); 5724 if (IsEventLogging()) 5725 { 5726 (void) LogMagickEvent(X11Event,GetMagickModule(),"Matte Image:"); 5727 (void) LogMagickEvent(X11Event,GetMagickModule(), 5728 " width, height: %dx%d",matte_image->width,matte_image->height); 5729 } 5730 if (matte_image != (XImage *) NULL) 5731 { 5732 /* 5733 Allocate matte image pixel data. 5734 */ 5735 matte_image->data=(char *) malloc((size_t) 5736 matte_image->bytes_per_line*matte_image->depth* 5737 matte_image->height); 5738 if (matte_image->data == (char *) NULL) 5739 { 5740 XDestroyImage(matte_image); 5741 matte_image=(XImage *) NULL; 5742 } 5743 } 5744 } 5745 if (window->matte_image != (XImage *) NULL) 5746 { 5747 /* 5748 Free matte image. 5749 */ 5750 if (window->matte_image->data != (char *) NULL) 5751 free(window->matte_image->data); 5752 window->matte_image->data=(char *) NULL; 5753 XDestroyImage(window->matte_image); 5754 window->matte_image=(XImage *) NULL; 5755 } 5756 window->matte_image=matte_image; 5757 if (window->matte_pixmap != (Pixmap) NULL) 5758 { 5759 (void) XFreePixmap(display,window->matte_pixmap); 5760 window->matte_pixmap=(Pixmap) NULL; 5761#if defined(MAGICKCORE_HAVE_SHAPE) 5762 if (window->shape != MagickFalse) 5763 XShapeCombineMask(display,window->id,ShapeBounding,0,0,None,ShapeSet); 5764#endif 5765 } 5766 window->stasis=MagickFalse; 5767 /* 5768 Convert pixels to X image data. 5769 */ 5770 if (window->image != (Image *) NULL) 5771 { 5772 if ((ximage->byte_order == LSBFirst) || ((ximage->format == XYBitmap) && 5773 (ximage->bitmap_bit_order == LSBFirst))) 5774 XMakeImageLSBFirst(resource_info,window,window->image,ximage, 5775 matte_image,exception); 5776 else 5777 XMakeImageMSBFirst(resource_info,window,window->image,ximage, 5778 matte_image,exception); 5779 } 5780 if (window->matte_image != (XImage *) NULL) 5781 { 5782 /* 5783 Create matte pixmap. 5784 */ 5785 window->matte_pixmap=XCreatePixmap(display,window->id,width,height,1); 5786 if (window->matte_pixmap != (Pixmap) NULL) 5787 { 5788 GC 5789 graphics_context; 5790 5791 XGCValues 5792 context_values; 5793 5794 /* 5795 Copy matte image to matte pixmap. 5796 */ 5797 context_values.background=0; 5798 context_values.foreground=1; 5799 graphics_context=XCreateGC(display,window->matte_pixmap, 5800 (size_t) (GCBackground | GCForeground),&context_values); 5801 (void) XPutImage(display,window->matte_pixmap,graphics_context, 5802 window->matte_image,0,0,0,0,width,height); 5803 (void) XFreeGC(display,graphics_context); 5804#if defined(MAGICKCORE_HAVE_SHAPE) 5805 if (window->shape != MagickFalse) 5806 XShapeCombineMask(display,window->id,ShapeBounding,0,0, 5807 window->matte_pixmap,ShapeSet); 5808#endif 5809 } 5810 } 5811 (void) XMakePixmap(display,resource_info,window); 5812 /* 5813 Restore cursor. 5814 */ 5815 (void) XCheckDefineCursor(display,window->id,window->cursor); 5816 return(MagickTrue); 5817} 5818 5819/* 5820%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5821% % 5822% % 5823% % 5824+ X M a k e I m a g e L S B F i r s t % 5825% % 5826% % 5827% % 5828%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5829% 5830% XMakeImageLSBFirst() initializes the pixel data of an X11 Image. The X image 5831% pixels are copied in least-significant bit and byte first order. The 5832% server's scanline pad is respected. Rather than using one or two general 5833% cases, many special cases are found here to help speed up the image 5834% conversion. 5835% 5836% The format of the XMakeImageLSBFirst method is: 5837% 5838% void XMakeImageLSBFirst(Display *display,XWindows *windows, 5839% ExceptionInfo *exception) 5840% 5841% A description of each parameter follows: 5842% 5843% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. 5844% 5845% o window: Specifies a pointer to a XWindowInfo structure. 5846% 5847% o image: the image. 5848% 5849% o ximage: Specifies a pointer to a XImage structure; returned from 5850% XCreateImage. 5851% 5852% o matte_image: Specifies a pointer to a XImage structure; returned from 5853% XCreateImage. 5854% 5855% o exception: return any errors or warnings in this structure. 5856% 5857*/ 5858static void XMakeImageLSBFirst(const XResourceInfo *resource_info, 5859 const XWindowInfo *window,Image *image,XImage *ximage,XImage *matte_image, 5860 ExceptionInfo *exception) 5861{ 5862 CacheView 5863 *canvas_view; 5864 5865 Image 5866 *canvas; 5867 5868 int 5869 y; 5870 5871 register const Quantum 5872 *p; 5873 5874 register int 5875 x; 5876 5877 register unsigned char 5878 *q; 5879 5880 unsigned char 5881 bit, 5882 byte; 5883 5884 unsigned int 5885 scanline_pad; 5886 5887 unsigned long 5888 pixel, 5889 *pixels; 5890 5891 XStandardColormap 5892 *map_info; 5893 5894 assert(resource_info != (XResourceInfo *) NULL); 5895 assert(window != (XWindowInfo *) NULL); 5896 assert(image != (Image *) NULL); 5897 if (image->debug != MagickFalse) 5898 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 5899 canvas=image; 5900 if ((window->immutable == MagickFalse) && 5901 (image->storage_class == DirectClass) && (image->alpha_trait != UndefinedPixelTrait)) 5902 { 5903 char 5904 size[MagickPathExtent]; 5905 5906 Image 5907 *pattern; 5908 5909 ImageInfo 5910 *image_info; 5911 5912 image_info=AcquireImageInfo(); 5913 (void) CopyMagickString(image_info->filename, 5914 resource_info->image_info->texture != (char *) NULL ? 5915 resource_info->image_info->texture : "pattern:checkerboard", 5916 MagickPathExtent); 5917 (void) FormatLocaleString(size,MagickPathExtent,"%.20gx%.20g",(double) 5918 image->columns,(double) image->rows); 5919 image_info->size=ConstantString(size); 5920 pattern=ReadImage(image_info,exception); 5921 image_info=DestroyImageInfo(image_info); 5922 if (pattern != (Image *) NULL) 5923 { 5924 canvas=CloneImage(image,0,0,MagickTrue,exception); 5925 if (canvas != (Image *) NULL) 5926 (void) CompositeImage(canvas,pattern,DstOverCompositeOp,MagickTrue, 5927 0,0,exception); 5928 pattern=DestroyImage(pattern); 5929 } 5930 } 5931 scanline_pad=(unsigned int) (ximage->bytes_per_line-((ximage->width* 5932 ximage->bits_per_pixel) >> 3)); 5933 map_info=window->map_info; 5934 pixels=window->pixel_info->pixels; 5935 q=(unsigned char *) ximage->data; 5936 x=0; 5937 canvas_view=AcquireVirtualCacheView(canvas,exception); 5938 if (ximage->format == XYBitmap) 5939 { 5940 register unsigned short 5941 polarity; 5942 5943 unsigned char 5944 background, 5945 foreground; 5946 5947 /* 5948 Convert canvas to big-endian bitmap. 5949 */ 5950 background=(unsigned char) 5951 (XPixelIntensity(&window->pixel_info->foreground_color) < 5952 XPixelIntensity(&window->pixel_info->background_color) ? 0x80 : 0x00); 5953 foreground=(unsigned char) 5954 (XPixelIntensity(&window->pixel_info->background_color) < 5955 XPixelIntensity(&window->pixel_info->foreground_color) ? 0x80 : 0x00); 5956 polarity=(unsigned short) ((GetPixelInfoIntensity(image, 5957 &canvas->colormap[0])) < (QuantumRange/2.0) ? 1 : 0); 5958 if (canvas->colors == 2) 5959 polarity=GetPixelInfoIntensity(image,&canvas->colormap[0]) < 5960 GetPixelInfoIntensity(image,&canvas->colormap[1]); 5961 for (y=0; y < (int) canvas->rows; y++) 5962 { 5963 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,canvas->columns,1, 5964 exception); 5965 if (p == (const Quantum *) NULL) 5966 break; 5967 bit=0; 5968 byte=0; 5969 for (x=0; x < (int) canvas->columns; x++) 5970 { 5971 byte>>=1; 5972 if (GetPixelIndex(canvas,p) == (Quantum) polarity) 5973 byte|=foreground; 5974 else 5975 byte|=background; 5976 bit++; 5977 if (bit == 8) 5978 { 5979 *q++=byte; 5980 bit=0; 5981 byte=0; 5982 } 5983 p+=GetPixelChannels(canvas); 5984 } 5985 if (bit != 0) 5986 *q=byte >> (8-bit); 5987 q+=scanline_pad; 5988 } 5989 } 5990 else 5991 if (window->pixel_info->colors != 0) 5992 switch (ximage->bits_per_pixel) 5993 { 5994 case 2: 5995 { 5996 register unsigned int 5997 nibble; 5998 5999 /* 6000 Convert to 2 bit color-mapped X canvas. 6001 */ 6002 for (y=0; y < (int) canvas->rows; y++) 6003 { 6004 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y, 6005 canvas->columns,1,exception); 6006 if (p == (const Quantum *) NULL) 6007 break; 6008 nibble=0; 6009 for (x=0; x < (int) canvas->columns; x++) 6010 { 6011 pixel=pixels[(ssize_t) GetPixelIndex(canvas,p)] & 0x0f; 6012 switch (nibble) 6013 { 6014 case 0: 6015 { 6016 *q=(unsigned char) pixel; 6017 nibble++; 6018 break; 6019 } 6020 case 1: 6021 { 6022 *q|=(unsigned char) (pixel << 2); 6023 nibble++; 6024 break; 6025 } 6026 case 2: 6027 { 6028 *q|=(unsigned char) (pixel << 4); 6029 nibble++; 6030 break; 6031 } 6032 case 3: 6033 { 6034 *q|=(unsigned char) (pixel << 6); 6035 q++; 6036 nibble=0; 6037 break; 6038 } 6039 } 6040 p+=GetPixelChannels(canvas); 6041 } 6042 q+=scanline_pad; 6043 } 6044 break; 6045 } 6046 case 4: 6047 { 6048 register unsigned int 6049 nibble; 6050 6051 /* 6052 Convert to 4 bit color-mapped X canvas. 6053 */ 6054 for (y=0; y < (int) canvas->rows; y++) 6055 { 6056 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y, 6057 canvas->columns,1,exception); 6058 if (p == (const Quantum *) NULL) 6059 break; 6060 nibble=0; 6061 for (x=0; x < (int) canvas->columns; x++) 6062 { 6063 pixel=pixels[(ssize_t) GetPixelIndex(canvas,p)] & 0xf; 6064 switch (nibble) 6065 { 6066 case 0: 6067 { 6068 *q=(unsigned char) pixel; 6069 nibble++; 6070 break; 6071 } 6072 case 1: 6073 { 6074 *q|=(unsigned char) (pixel << 4); 6075 q++; 6076 nibble=0; 6077 break; 6078 } 6079 } 6080 p+=GetPixelChannels(canvas); 6081 } 6082 q+=scanline_pad; 6083 } 6084 break; 6085 } 6086 case 6: 6087 case 8: 6088 { 6089 /* 6090 Convert to 8 bit color-mapped X canvas. 6091 */ 6092 if (resource_info->color_recovery && 6093 resource_info->quantize_info->dither_method != NoDitherMethod) 6094 { 6095 XDitherImage(canvas,ximage,exception); 6096 break; 6097 } 6098 for (y=0; y < (int) canvas->rows; y++) 6099 { 6100 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y, 6101 canvas->columns,1,exception); 6102 if (p == (const Quantum *) NULL) 6103 break; 6104 for (x=0; x < (int) canvas->columns; x++) 6105 { 6106 pixel=pixels[(ssize_t) GetPixelIndex(canvas,p)]; 6107 *q++=(unsigned char) pixel; 6108 p+=GetPixelChannels(canvas); 6109 } 6110 q+=scanline_pad; 6111 } 6112 break; 6113 } 6114 default: 6115 { 6116 register int 6117 k; 6118 6119 register unsigned int 6120 bytes_per_pixel; 6121 6122 /* 6123 Convert to multi-byte color-mapped X canvas. 6124 */ 6125 bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3); 6126 for (y=0; y < (int) canvas->rows; y++) 6127 { 6128 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y, 6129 canvas->columns,1,exception); 6130 if (p == (const Quantum *) NULL) 6131 break; 6132 for (x=0; x < (int) canvas->columns; x++) 6133 { 6134 pixel=pixels[(ssize_t) GetPixelIndex(canvas,p)]; 6135 for (k=0; k < (int) bytes_per_pixel; k++) 6136 { 6137 *q++=(unsigned char) (pixel & 0xff); 6138 pixel>>=8; 6139 } 6140 p+=GetPixelChannels(canvas); 6141 } 6142 q+=scanline_pad; 6143 } 6144 break; 6145 } 6146 } 6147 else 6148 switch (ximage->bits_per_pixel) 6149 { 6150 case 2: 6151 { 6152 register unsigned int 6153 nibble; 6154 6155 /* 6156 Convert to contiguous 2 bit continuous-tone X canvas. 6157 */ 6158 for (y=0; y < (int) canvas->rows; y++) 6159 { 6160 nibble=0; 6161 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y, 6162 canvas->columns,1,exception); 6163 if (p == (const Quantum *) NULL) 6164 break; 6165 for (x=0; x < (int) canvas->columns; x++) 6166 { 6167 pixel=XGammaPixel(canvas,map_info,p); 6168 pixel&=0xf; 6169 switch (nibble) 6170 { 6171 case 0: 6172 { 6173 *q=(unsigned char) pixel; 6174 nibble++; 6175 break; 6176 } 6177 case 1: 6178 { 6179 *q|=(unsigned char) (pixel << 2); 6180 nibble++; 6181 break; 6182 } 6183 case 2: 6184 { 6185 *q|=(unsigned char) (pixel << 4); 6186 nibble++; 6187 break; 6188 } 6189 case 3: 6190 { 6191 *q|=(unsigned char) (pixel << 6); 6192 q++; 6193 nibble=0; 6194 break; 6195 } 6196 } 6197 p+=GetPixelChannels(canvas); 6198 } 6199 q+=scanline_pad; 6200 } 6201 break; 6202 } 6203 case 4: 6204 { 6205 register unsigned int 6206 nibble; 6207 6208 /* 6209 Convert to contiguous 4 bit continuous-tone X canvas. 6210 */ 6211 for (y=0; y < (int) canvas->rows; y++) 6212 { 6213 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y, 6214 canvas->columns,1,exception); 6215 if (p == (const Quantum *) NULL) 6216 break; 6217 nibble=0; 6218 for (x=0; x < (int) canvas->columns; x++) 6219 { 6220 pixel=XGammaPixel(canvas,map_info,p); 6221 pixel&=0xf; 6222 switch (nibble) 6223 { 6224 case 0: 6225 { 6226 *q=(unsigned char) pixel; 6227 nibble++; 6228 break; 6229 } 6230 case 1: 6231 { 6232 *q|=(unsigned char) (pixel << 4); 6233 q++; 6234 nibble=0; 6235 break; 6236 } 6237 } 6238 p+=GetPixelChannels(canvas); 6239 } 6240 q+=scanline_pad; 6241 } 6242 break; 6243 } 6244 case 6: 6245 case 8: 6246 { 6247 /* 6248 Convert to contiguous 8 bit continuous-tone X canvas. 6249 */ 6250 if (resource_info->color_recovery && 6251 resource_info->quantize_info->dither_method != NoDitherMethod) 6252 { 6253 XDitherImage(canvas,ximage,exception); 6254 break; 6255 } 6256 for (y=0; y < (int) canvas->rows; y++) 6257 { 6258 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y, 6259 canvas->columns,1,exception); 6260 if (p == (const Quantum *) NULL) 6261 break; 6262 for (x=0; x < (int) canvas->columns; x++) 6263 { 6264 pixel=XGammaPixel(canvas,map_info,p); 6265 *q++=(unsigned char) pixel; 6266 p+=GetPixelChannels(canvas); 6267 } 6268 q+=scanline_pad; 6269 } 6270 break; 6271 } 6272 default: 6273 { 6274 if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) && 6275 (map_info->green_max == 255) && (map_info->blue_max == 255) && 6276 (map_info->red_mult == 65536L) && (map_info->green_mult == 256) && 6277 (map_info->blue_mult == 1)) 6278 { 6279 /* 6280 Convert to 32 bit continuous-tone X canvas. 6281 */ 6282 for (y=0; y < (int) canvas->rows; y++) 6283 { 6284 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y, 6285 canvas->columns,1,exception); 6286 if (p == (const Quantum *) NULL) 6287 break; 6288 if ((red_gamma != 1.0) || (green_gamma != 1.0) || 6289 (blue_gamma != 1.0)) 6290 { 6291 /* 6292 Gamma correct canvas. 6293 */ 6294 for (x=(int) canvas->columns-1; x >= 0; x--) 6295 { 6296 *q++=ScaleQuantumToChar(XBlueGamma( 6297 GetPixelBlue(canvas,p))); 6298 *q++=ScaleQuantumToChar(XGreenGamma( 6299 GetPixelGreen(canvas,p))); 6300 *q++=ScaleQuantumToChar(XRedGamma( 6301 GetPixelRed(canvas,p))); 6302 *q++=0; 6303 p+=GetPixelChannels(canvas); 6304 } 6305 continue; 6306 } 6307 for (x=(int) canvas->columns-1; x >= 0; x--) 6308 { 6309 *q++=ScaleQuantumToChar((Quantum) GetPixelBlue(canvas,p)); 6310 *q++=ScaleQuantumToChar((Quantum) GetPixelGreen(canvas,p)); 6311 *q++=ScaleQuantumToChar((Quantum) GetPixelRed(canvas,p)); 6312 *q++=0; 6313 p+=GetPixelChannels(canvas); 6314 } 6315 } 6316 } 6317 else 6318 if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) && 6319 (map_info->green_max == 255) && (map_info->blue_max == 255) && 6320 (map_info->red_mult == 1) && (map_info->green_mult == 256) && 6321 (map_info->blue_mult == 65536L)) 6322 { 6323 /* 6324 Convert to 32 bit continuous-tone X canvas. 6325 */ 6326 for (y=0; y < (int) canvas->rows; y++) 6327 { 6328 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y, 6329 canvas->columns,1,exception); 6330 if (p == (const Quantum *) NULL) 6331 break; 6332 if ((red_gamma != 1.0) || (green_gamma != 1.0) || 6333 (blue_gamma != 1.0)) 6334 { 6335 /* 6336 Gamma correct canvas. 6337 */ 6338 for (x=(int) canvas->columns-1; x >= 0; x--) 6339 { 6340 *q++=ScaleQuantumToChar(XRedGamma( 6341 GetPixelRed(canvas,p))); 6342 *q++=ScaleQuantumToChar(XGreenGamma( 6343 GetPixelGreen(canvas,p))); 6344 *q++=ScaleQuantumToChar(XBlueGamma( 6345 GetPixelBlue(canvas,p))); 6346 *q++=0; 6347 p+=GetPixelChannels(canvas); 6348 } 6349 continue; 6350 } 6351 for (x=(int) canvas->columns-1; x >= 0; x--) 6352 { 6353 *q++=ScaleQuantumToChar((Quantum) GetPixelRed(canvas,p)); 6354 *q++=ScaleQuantumToChar((Quantum) GetPixelGreen(canvas,p)); 6355 *q++=ScaleQuantumToChar((Quantum) GetPixelBlue(canvas,p)); 6356 *q++=0; 6357 p+=GetPixelChannels(canvas); 6358 } 6359 } 6360 } 6361 else 6362 { 6363 register int 6364 k; 6365 6366 register unsigned int 6367 bytes_per_pixel; 6368 6369 /* 6370 Convert to multi-byte continuous-tone X canvas. 6371 */ 6372 bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3); 6373 for (y=0; y < (int) canvas->rows; y++) 6374 { 6375 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y, 6376 canvas->columns,1,exception); 6377 if (p == (const Quantum *) NULL) 6378 break; 6379 for (x=0; x < (int) canvas->columns; x++) 6380 { 6381 pixel=XGammaPixel(canvas,map_info,p); 6382 for (k=0; k < (int) bytes_per_pixel; k++) 6383 { 6384 *q++=(unsigned char) (pixel & 0xff); 6385 pixel>>=8; 6386 } 6387 p+=GetPixelChannels(canvas); 6388 } 6389 q+=scanline_pad; 6390 } 6391 } 6392 break; 6393 } 6394 } 6395 if (matte_image != (XImage *) NULL) 6396 { 6397 /* 6398 Initialize matte canvas. 6399 */ 6400 scanline_pad=(unsigned int) (matte_image->bytes_per_line- 6401 ((matte_image->width*matte_image->bits_per_pixel) >> 3)); 6402 q=(unsigned char *) matte_image->data; 6403 for (y=0; y < (int) canvas->rows; y++) 6404 { 6405 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,canvas->columns,1, 6406 exception); 6407 if (p == (const Quantum *) NULL) 6408 break; 6409 bit=0; 6410 byte=0; 6411 for (x=(int) canvas->columns-1; x >= 0; x--) 6412 { 6413 byte>>=1; 6414 if (GetPixelAlpha(canvas,p) > (QuantumRange/2)) 6415 byte|=0x80; 6416 bit++; 6417 if (bit == 8) 6418 { 6419 *q++=byte; 6420 bit=0; 6421 byte=0; 6422 } 6423 p+=GetPixelChannels(canvas); 6424 } 6425 if (bit != 0) 6426 *q=byte >> (8-bit); 6427 q+=scanline_pad; 6428 } 6429 } 6430 canvas_view=DestroyCacheView(canvas_view); 6431 if (canvas != image) 6432 canvas=DestroyImage(canvas); 6433} 6434 6435/* 6436%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6437% % 6438% % 6439% % 6440+ X M a k e I m a g e M S B F i r s t % 6441% % 6442% % 6443% % 6444%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6445% 6446% XMakeImageMSBFirst() initializes the pixel data of an X11 Image. The X 6447% image pixels are copied in most-significant bit and byte first order. The 6448% server's scanline pad is also respected. Rather than using one or two 6449% general cases, many special cases are found here to help speed up the image 6450% conversion. 6451% 6452% The format of the XMakeImageMSBFirst method is: 6453% 6454% XMakeImageMSBFirst(resource_info,window,image,ximage,matte_image, 6455% ExceptionInfo *exception) 6456% 6457% A description of each parameter follows: 6458% 6459% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. 6460% 6461% o window: Specifies a pointer to a XWindowInfo structure. 6462% 6463% o image: the image. 6464% 6465% o ximage: Specifies a pointer to a XImage structure; returned from 6466% XCreateImage. 6467% 6468% o matte_image: Specifies a pointer to a XImage structure; returned from 6469% XCreateImage. 6470% 6471% o exception: return any errors or warnings in this structure. 6472% 6473*/ 6474static void XMakeImageMSBFirst(const XResourceInfo *resource_info, 6475 const XWindowInfo *window,Image *image,XImage *ximage,XImage *matte_image, 6476 ExceptionInfo *exception) 6477{ 6478 CacheView 6479 *canvas_view; 6480 6481 Image 6482 *canvas; 6483 6484 int 6485 y; 6486 6487 register int 6488 x; 6489 6490 register const Quantum 6491 *p; 6492 6493 register unsigned char 6494 *q; 6495 6496 unsigned char 6497 bit, 6498 byte; 6499 6500 unsigned int 6501 scanline_pad; 6502 6503 unsigned long 6504 pixel, 6505 *pixels; 6506 6507 XStandardColormap 6508 *map_info; 6509 6510 assert(resource_info != (XResourceInfo *) NULL); 6511 assert(window != (XWindowInfo *) NULL); 6512 assert(image != (Image *) NULL); 6513 if (image->debug != MagickFalse) 6514 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 6515 canvas=image; 6516 if ((window->immutable != MagickFalse) && 6517 (image->storage_class == DirectClass) && 6518 (image->alpha_trait != UndefinedPixelTrait)) 6519 { 6520 char 6521 size[MagickPathExtent]; 6522 6523 Image 6524 *pattern; 6525 6526 ImageInfo 6527 *image_info; 6528 6529 image_info=AcquireImageInfo(); 6530 (void) CopyMagickString(image_info->filename, 6531 resource_info->image_info->texture != (char *) NULL ? 6532 resource_info->image_info->texture : "pattern:checkerboard", 6533 MagickPathExtent); 6534 (void) FormatLocaleString(size,MagickPathExtent,"%.20gx%.20g",(double) 6535 image->columns,(double) image->rows); 6536 image_info->size=ConstantString(size); 6537 pattern=ReadImage(image_info,exception); 6538 image_info=DestroyImageInfo(image_info); 6539 if (pattern != (Image *) NULL) 6540 { 6541 canvas=CloneImage(image,0,0,MagickTrue,exception); 6542 if (canvas != (Image *) NULL) 6543 (void) CompositeImage(canvas,pattern,DstOverCompositeOp,MagickFalse, 6544 0,0,exception); 6545 pattern=DestroyImage(pattern); 6546 } 6547 } 6548 scanline_pad=(unsigned int) (ximage->bytes_per_line-((ximage->width* 6549 ximage->bits_per_pixel) >> 3)); 6550 map_info=window->map_info; 6551 pixels=window->pixel_info->pixels; 6552 q=(unsigned char *) ximage->data; 6553 x=0; 6554 canvas_view=AcquireVirtualCacheView(canvas,exception); 6555 if (ximage->format == XYBitmap) 6556 { 6557 register unsigned short 6558 polarity; 6559 6560 unsigned char 6561 background, 6562 foreground; 6563 6564 /* 6565 Convert canvas to big-endian bitmap. 6566 */ 6567 background=(unsigned char) 6568 (XPixelIntensity(&window->pixel_info->foreground_color) < 6569 XPixelIntensity(&window->pixel_info->background_color) ? 0x01 : 0x00); 6570 foreground=(unsigned char) 6571 (XPixelIntensity(&window->pixel_info->background_color) < 6572 XPixelIntensity(&window->pixel_info->foreground_color) ? 0x01 : 0x00); 6573 polarity=(unsigned short) ((GetPixelInfoIntensity(image, 6574 &canvas->colormap[0])) < (QuantumRange/2.0) ? 1 : 0); 6575 if (canvas->colors == 2) 6576 polarity=GetPixelInfoIntensity(image,&canvas->colormap[0]) < 6577 GetPixelInfoIntensity(image,&canvas->colormap[1]); 6578 for (y=0; y < (int) canvas->rows; y++) 6579 { 6580 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,canvas->columns,1, 6581 exception); 6582 if (p == (const Quantum *) NULL) 6583 break; 6584 bit=0; 6585 byte=0; 6586 for (x=(int) canvas->columns-1; x >= 0; x--) 6587 { 6588 byte<<=1; 6589 if (GetPixelIndex(canvas,p) == (Quantum) polarity) 6590 byte|=foreground; 6591 else 6592 byte|=background; 6593 bit++; 6594 if (bit == 8) 6595 { 6596 *q++=byte; 6597 bit=0; 6598 byte=0; 6599 } 6600 p+=GetPixelChannels(canvas); 6601 } 6602 if (bit != 0) 6603 *q=byte << (8-bit); 6604 q+=scanline_pad; 6605 } 6606 } 6607 else 6608 if (window->pixel_info->colors != 0) 6609 switch (ximage->bits_per_pixel) 6610 { 6611 case 2: 6612 { 6613 register unsigned int 6614 nibble; 6615 6616 /* 6617 Convert to 2 bit color-mapped X canvas. 6618 */ 6619 for (y=0; y < (int) canvas->rows; y++) 6620 { 6621 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y, 6622 canvas->columns,1,exception); 6623 if (p == (const Quantum *) NULL) 6624 break; 6625 nibble=0; 6626 for (x=0; x < (int) canvas->columns; x++) 6627 { 6628 pixel=pixels[(ssize_t) 6629 GetPixelIndex(canvas,p)] & 0xf; 6630 switch (nibble) 6631 { 6632 case 0: 6633 { 6634 *q=(unsigned char) (pixel << 6); 6635 nibble++; 6636 break; 6637 } 6638 case 1: 6639 { 6640 *q|=(unsigned char) (pixel << 4); 6641 nibble++; 6642 break; 6643 } 6644 case 2: 6645 { 6646 *q|=(unsigned char) (pixel << 2); 6647 nibble++; 6648 break; 6649 } 6650 case 3: 6651 { 6652 *q|=(unsigned char) pixel; 6653 q++; 6654 nibble=0; 6655 break; 6656 } 6657 } 6658 p+=GetPixelChannels(canvas); 6659 } 6660 q+=scanline_pad; 6661 } 6662 break; 6663 } 6664 case 4: 6665 { 6666 register unsigned int 6667 nibble; 6668 6669 /* 6670 Convert to 4 bit color-mapped X canvas. 6671 */ 6672 for (y=0; y < (int) canvas->rows; y++) 6673 { 6674 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y, 6675 canvas->columns,1,exception); 6676 if (p == (const Quantum *) NULL) 6677 break; 6678 nibble=0; 6679 for (x=0; x < (int) canvas->columns; x++) 6680 { 6681 pixel=pixels[(ssize_t) 6682 GetPixelIndex(canvas,p)] & 0xf; 6683 switch (nibble) 6684 { 6685 case 0: 6686 { 6687 *q=(unsigned char) (pixel << 4); 6688 nibble++; 6689 break; 6690 } 6691 case 1: 6692 { 6693 *q|=(unsigned char) pixel; 6694 q++; 6695 nibble=0; 6696 break; 6697 } 6698 } 6699 p+=GetPixelChannels(canvas); 6700 } 6701 q+=scanline_pad; 6702 } 6703 break; 6704 } 6705 case 6: 6706 case 8: 6707 { 6708 /* 6709 Convert to 8 bit color-mapped X canvas. 6710 */ 6711 if (resource_info->color_recovery && 6712 resource_info->quantize_info->dither_method != NoDitherMethod) 6713 { 6714 XDitherImage(canvas,ximage,exception); 6715 break; 6716 } 6717 for (y=0; y < (int) canvas->rows; y++) 6718 { 6719 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y, 6720 canvas->columns,1,exception); 6721 if (p == (const Quantum *) NULL) 6722 break; 6723 for (x=0; x < (int) canvas->columns; x++) 6724 { 6725 pixel=pixels[(ssize_t) GetPixelIndex(canvas,p)]; 6726 *q++=(unsigned char) pixel; 6727 p+=GetPixelChannels(canvas); 6728 } 6729 q+=scanline_pad; 6730 } 6731 break; 6732 } 6733 default: 6734 { 6735 register int 6736 k; 6737 6738 register unsigned int 6739 bytes_per_pixel; 6740 6741 unsigned char 6742 channel[sizeof(size_t)]; 6743 6744 /* 6745 Convert to 8 bit color-mapped X canvas. 6746 */ 6747 bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3); 6748 for (y=0; y < (int) canvas->rows; y++) 6749 { 6750 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y, 6751 canvas->columns,1,exception); 6752 if (p == (const Quantum *) NULL) 6753 break; 6754 for (x=0; x < (int) canvas->columns; x++) 6755 { 6756 pixel=pixels[(ssize_t) 6757 GetPixelIndex(canvas,p)]; 6758 for (k=(int) bytes_per_pixel-1; k >= 0; k--) 6759 { 6760 channel[k]=(unsigned char) pixel; 6761 pixel>>=8; 6762 } 6763 for (k=0; k < (int) bytes_per_pixel; k++) 6764 *q++=channel[k]; 6765 p+=GetPixelChannels(canvas); 6766 } 6767 q+=scanline_pad; 6768 } 6769 break; 6770 } 6771 } 6772 else 6773 switch (ximage->bits_per_pixel) 6774 { 6775 case 2: 6776 { 6777 register unsigned int 6778 nibble; 6779 6780 /* 6781 Convert to 4 bit continuous-tone X canvas. 6782 */ 6783 for (y=0; y < (int) canvas->rows; y++) 6784 { 6785 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y, 6786 canvas->columns,1,exception); 6787 if (p == (const Quantum *) NULL) 6788 break; 6789 nibble=0; 6790 for (x=(int) canvas->columns-1; x >= 0; x--) 6791 { 6792 pixel=XGammaPixel(canvas,map_info,p); 6793 pixel&=0xf; 6794 switch (nibble) 6795 { 6796 case 0: 6797 { 6798 *q=(unsigned char) (pixel << 6); 6799 nibble++; 6800 break; 6801 } 6802 case 1: 6803 { 6804 *q|=(unsigned char) (pixel << 4); 6805 nibble++; 6806 break; 6807 } 6808 case 2: 6809 { 6810 *q|=(unsigned char) (pixel << 2); 6811 nibble++; 6812 break; 6813 } 6814 case 3: 6815 { 6816 *q|=(unsigned char) pixel; 6817 q++; 6818 nibble=0; 6819 break; 6820 } 6821 } 6822 p+=GetPixelChannels(canvas); 6823 } 6824 q+=scanline_pad; 6825 } 6826 break; 6827 } 6828 case 4: 6829 { 6830 register unsigned int 6831 nibble; 6832 6833 /* 6834 Convert to 4 bit continuous-tone X canvas. 6835 */ 6836 for (y=0; y < (int) canvas->rows; y++) 6837 { 6838 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y, 6839 canvas->columns,1,exception); 6840 if (p == (const Quantum *) NULL) 6841 break; 6842 nibble=0; 6843 for (x=(int) canvas->columns-1; x >= 0; x--) 6844 { 6845 pixel=XGammaPixel(canvas,map_info,p); 6846 pixel&=0xf; 6847 switch (nibble) 6848 { 6849 case 0: 6850 { 6851 *q=(unsigned char) (pixel << 4); 6852 nibble++; 6853 break; 6854 } 6855 case 1: 6856 { 6857 *q|=(unsigned char) pixel; 6858 q++; 6859 nibble=0; 6860 break; 6861 } 6862 } 6863 p+=GetPixelChannels(canvas); 6864 } 6865 q+=scanline_pad; 6866 } 6867 break; 6868 } 6869 case 6: 6870 case 8: 6871 { 6872 /* 6873 Convert to 8 bit continuous-tone X canvas. 6874 */ 6875 if (resource_info->color_recovery && 6876 resource_info->quantize_info->dither_method != NoDitherMethod) 6877 { 6878 XDitherImage(canvas,ximage,exception); 6879 break; 6880 } 6881 for (y=0; y < (int) canvas->rows; y++) 6882 { 6883 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y, 6884 canvas->columns,1,exception); 6885 if (p == (const Quantum *) NULL) 6886 break; 6887 for (x=(int) canvas->columns-1; x >= 0; x--) 6888 { 6889 pixel=XGammaPixel(canvas,map_info,p); 6890 *q++=(unsigned char) pixel; 6891 p+=GetPixelChannels(canvas); 6892 } 6893 q+=scanline_pad; 6894 } 6895 break; 6896 } 6897 default: 6898 { 6899 if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) && 6900 (map_info->green_max == 255) && (map_info->blue_max == 255) && 6901 (map_info->red_mult == 65536L) && (map_info->green_mult == 256) && 6902 (map_info->blue_mult == 1)) 6903 { 6904 /* 6905 Convert to 32 bit continuous-tone X canvas. 6906 */ 6907 for (y=0; y < (int) canvas->rows; y++) 6908 { 6909 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y, 6910 canvas->columns,1,exception); 6911 if (p == (const Quantum *) NULL) 6912 break; 6913 if ((red_gamma != 1.0) || (green_gamma != 1.0) || 6914 (blue_gamma != 1.0)) 6915 { 6916 /* 6917 Gamma correct canvas. 6918 */ 6919 for (x=(int) canvas->columns-1; x >= 0; x--) 6920 { 6921 *q++=0; 6922 *q++=ScaleQuantumToChar(XRedGamma( 6923 GetPixelRed(canvas,p))); 6924 *q++=ScaleQuantumToChar(XGreenGamma( 6925 GetPixelGreen(canvas,p))); 6926 *q++=ScaleQuantumToChar(XBlueGamma( 6927 GetPixelBlue(canvas,p))); 6928 p+=GetPixelChannels(canvas); 6929 } 6930 continue; 6931 } 6932 for (x=(int) canvas->columns-1; x >= 0; x--) 6933 { 6934 *q++=0; 6935 *q++=ScaleQuantumToChar((Quantum) GetPixelRed(canvas,p)); 6936 *q++=ScaleQuantumToChar((Quantum) GetPixelGreen(canvas,p)); 6937 *q++=ScaleQuantumToChar((Quantum) GetPixelBlue(canvas,p)); 6938 p+=GetPixelChannels(canvas); 6939 } 6940 } 6941 } 6942 else 6943 if ((ximage->bits_per_pixel == 32) && (map_info->red_max == 255) && 6944 (map_info->green_max == 255) && (map_info->blue_max == 255) && 6945 (map_info->red_mult == 1) && (map_info->green_mult == 256) && 6946 (map_info->blue_mult == 65536L)) 6947 { 6948 /* 6949 Convert to 32 bit continuous-tone X canvas. 6950 */ 6951 for (y=0; y < (int) canvas->rows; y++) 6952 { 6953 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y, 6954 canvas->columns,1,exception); 6955 if (p == (const Quantum *) NULL) 6956 break; 6957 if ((red_gamma != 1.0) || (green_gamma != 1.0) || 6958 (blue_gamma != 1.0)) 6959 { 6960 /* 6961 Gamma correct canvas. 6962 */ 6963 for (x=(int) canvas->columns-1; x >= 0; x--) 6964 { 6965 *q++=0; 6966 *q++=ScaleQuantumToChar(XBlueGamma( 6967 GetPixelBlue(canvas,p))); 6968 *q++=ScaleQuantumToChar(XGreenGamma( 6969 GetPixelGreen(canvas,p))); 6970 *q++=ScaleQuantumToChar(XRedGamma( 6971 GetPixelRed(canvas,p))); 6972 p+=GetPixelChannels(canvas); 6973 } 6974 continue; 6975 } 6976 for (x=(int) canvas->columns-1; x >= 0; x--) 6977 { 6978 *q++=0; 6979 *q++=ScaleQuantumToChar((Quantum) GetPixelBlue(canvas,p)); 6980 *q++=ScaleQuantumToChar((Quantum) GetPixelGreen(canvas,p)); 6981 *q++=ScaleQuantumToChar((Quantum) GetPixelRed(canvas,p)); 6982 p+=GetPixelChannels(canvas); 6983 } 6984 } 6985 } 6986 else 6987 { 6988 register int 6989 k; 6990 6991 register unsigned int 6992 bytes_per_pixel; 6993 6994 unsigned char 6995 channel[sizeof(size_t)]; 6996 6997 /* 6998 Convert to multi-byte continuous-tone X canvas. 6999 */ 7000 bytes_per_pixel=(unsigned int) (ximage->bits_per_pixel >> 3); 7001 for (y=0; y < (int) canvas->rows; y++) 7002 { 7003 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y, 7004 canvas->columns,1,exception); 7005 if (p == (const Quantum *) NULL) 7006 break; 7007 for (x=(int) canvas->columns-1; x >= 0; x--) 7008 { 7009 pixel=XGammaPixel(canvas,map_info,p); 7010 for (k=(int) bytes_per_pixel-1; k >= 0; k--) 7011 { 7012 channel[k]=(unsigned char) pixel; 7013 pixel>>=8; 7014 } 7015 for (k=0; k < (int) bytes_per_pixel; k++) 7016 *q++=channel[k]; 7017 p+=GetPixelChannels(canvas); 7018 } 7019 q+=scanline_pad; 7020 } 7021 } 7022 break; 7023 } 7024 } 7025 if (matte_image != (XImage *) NULL) 7026 { 7027 /* 7028 Initialize matte canvas. 7029 */ 7030 scanline_pad=(unsigned int) (matte_image->bytes_per_line- 7031 ((matte_image->width*matte_image->bits_per_pixel) >> 3)); 7032 q=(unsigned char *) matte_image->data; 7033 for (y=0; y < (int) canvas->rows; y++) 7034 { 7035 p=GetCacheViewVirtualPixels(canvas_view,0,(ssize_t) y,canvas->columns,1, 7036 exception); 7037 if (p == (const Quantum *) NULL) 7038 break; 7039 bit=0; 7040 byte=0; 7041 for (x=(int) canvas->columns-1; x >= 0; x--) 7042 { 7043 byte<<=1; 7044 if (GetPixelAlpha(canvas,p) > (QuantumRange/2)) 7045 byte|=0x01; 7046 bit++; 7047 if (bit == 8) 7048 { 7049 *q++=byte; 7050 bit=0; 7051 byte=0; 7052 } 7053 p+=GetPixelChannels(canvas); 7054 } 7055 if (bit != 0) 7056 *q=byte << (8-bit); 7057 q+=scanline_pad; 7058 } 7059 } 7060 canvas_view=DestroyCacheView(canvas_view); 7061 if (canvas != image) 7062 canvas=DestroyImage(canvas); 7063} 7064 7065/* 7066%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 7067% % 7068% % 7069% % 7070% X M a k e M a g n i f y I m a g e % 7071% % 7072% % 7073% % 7074%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 7075% 7076% XMakeMagnifyImage() magnifies a region of an X image and displays it. 7077% 7078% The format of the XMakeMagnifyImage method is: 7079% 7080% void XMakeMagnifyImage(Display *display,XWindows *windows, 7081% ExceptionInfo *exception) 7082% 7083% A description of each parameter follows: 7084% 7085% o display: Specifies a connection to an X server; returned from 7086% XOpenDisplay. 7087% 7088% o windows: Specifies a pointer to a XWindows structure. 7089% 7090% o exception: return any errors or warnings in this structure. 7091% 7092*/ 7093MagickPrivate void XMakeMagnifyImage(Display *display,XWindows *windows, 7094 ExceptionInfo *exception) 7095{ 7096 char 7097 tuple[MagickPathExtent]; 7098 7099 int 7100 y; 7101 7102 PixelInfo 7103 pixel; 7104 7105 register int 7106 x; 7107 7108 register ssize_t 7109 i; 7110 7111 register unsigned char 7112 *p, 7113 *q; 7114 7115 ssize_t 7116 n; 7117 7118 static unsigned int 7119 previous_magnify = 0; 7120 7121 static XWindowInfo 7122 magnify_window; 7123 7124 unsigned int 7125 height, 7126 j, 7127 k, 7128 l, 7129 magnify, 7130 scanline_pad, 7131 width; 7132 7133 XImage 7134 *ximage; 7135 7136 /* 7137 Check boundary conditions. 7138 */ 7139 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 7140 assert(display != (Display *) NULL); 7141 assert(windows != (XWindows *) NULL); 7142 magnify=1; 7143 for (n=1; n < (ssize_t) windows->magnify.data; n++) 7144 magnify<<=1; 7145 while ((magnify*windows->image.ximage->width) < windows->magnify.width) 7146 magnify<<=1; 7147 while ((magnify*windows->image.ximage->height) < windows->magnify.height) 7148 magnify<<=1; 7149 while (magnify > windows->magnify.width) 7150 magnify>>=1; 7151 while (magnify > windows->magnify.height) 7152 magnify>>=1; 7153 if (magnify == 0) 7154 magnify=1; 7155 if (magnify != previous_magnify) 7156 { 7157 Status 7158 status; 7159 7160 XTextProperty 7161 window_name; 7162 7163 /* 7164 New magnify factor: update magnify window name. 7165 */ 7166 i=0; 7167 while ((1 << i) <= (int) magnify) 7168 i++; 7169 (void) FormatLocaleString(windows->magnify.name,MagickPathExtent, 7170 "Magnify %.20gX",(double) i); 7171 status=XStringListToTextProperty(&windows->magnify.name,1,&window_name); 7172 if (status != False) 7173 { 7174 XSetWMName(display,windows->magnify.id,&window_name); 7175 XSetWMIconName(display,windows->magnify.id,&window_name); 7176 (void) XFree((void *) window_name.value); 7177 } 7178 } 7179 previous_magnify=magnify; 7180 ximage=windows->image.ximage; 7181 width=(unsigned int) windows->magnify.ximage->width; 7182 height=(unsigned int) windows->magnify.ximage->height; 7183 if ((windows->magnify.x < 0) || 7184 (windows->magnify.x >= windows->image.ximage->width)) 7185 windows->magnify.x=windows->image.ximage->width >> 1; 7186 x=windows->magnify.x-((width/magnify) >> 1); 7187 if (x < 0) 7188 x=0; 7189 else 7190 if (x > (int) (ximage->width-(width/magnify))) 7191 x=ximage->width-width/magnify; 7192 if ((windows->magnify.y < 0) || 7193 (windows->magnify.y >= windows->image.ximage->height)) 7194 windows->magnify.y=windows->image.ximage->height >> 1; 7195 y=windows->magnify.y-((height/magnify) >> 1); 7196 if (y < 0) 7197 y=0; 7198 else 7199 if (y > (int) (ximage->height-(height/magnify))) 7200 y=ximage->height-height/magnify; 7201 q=(unsigned char *) windows->magnify.ximage->data; 7202 scanline_pad=(unsigned int) (windows->magnify.ximage->bytes_per_line- 7203 ((width*windows->magnify.ximage->bits_per_pixel) >> 3)); 7204 if (ximage->bits_per_pixel < 8) 7205 { 7206 register unsigned char 7207 background, 7208 byte, 7209 foreground, 7210 p_bit, 7211 q_bit; 7212 7213 register unsigned int 7214 plane; 7215 7216 XPixelInfo 7217 *pixel_info; 7218 7219 pixel_info=windows->magnify.pixel_info; 7220 switch (ximage->bitmap_bit_order) 7221 { 7222 case LSBFirst: 7223 { 7224 /* 7225 Magnify little-endian bitmap. 7226 */ 7227 background=0x00; 7228 foreground=0x80; 7229 if (ximage->format == XYBitmap) 7230 { 7231 background=(unsigned char) 7232 (XPixelIntensity(&pixel_info->foreground_color) < 7233 XPixelIntensity(&pixel_info->background_color) ? 0x80 : 0x00); 7234 foreground=(unsigned char) 7235 (XPixelIntensity(&pixel_info->background_color) < 7236 XPixelIntensity(&pixel_info->foreground_color) ? 0x80 : 0x00); 7237 if (windows->magnify.depth > 1) 7238 Swap(background,foreground); 7239 } 7240 for (i=0; i < (ssize_t) height; i+=magnify) 7241 { 7242 /* 7243 Propogate pixel magnify rows. 7244 */ 7245 for (j=0; j < magnify; j++) 7246 { 7247 p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+ 7248 ((x*ximage->bits_per_pixel) >> 3); 7249 p_bit=(unsigned char) (x*ximage->bits_per_pixel) & 0x07; 7250 q_bit=0; 7251 byte=0; 7252 for (k=0; k < width; k+=magnify) 7253 { 7254 /* 7255 Propogate pixel magnify columns. 7256 */ 7257 for (l=0; l < magnify; l++) 7258 { 7259 /* 7260 Propogate each bit plane. 7261 */ 7262 for (plane=0; (int) plane < ximage->bits_per_pixel; plane++) 7263 { 7264 byte>>=1; 7265 if (*p & (0x01 << (p_bit+plane))) 7266 byte|=foreground; 7267 else 7268 byte|=background; 7269 q_bit++; 7270 if (q_bit == 8) 7271 { 7272 *q++=byte; 7273 q_bit=0; 7274 byte=0; 7275 } 7276 } 7277 } 7278 p_bit+=ximage->bits_per_pixel; 7279 if (p_bit == 8) 7280 { 7281 p++; 7282 p_bit=0; 7283 } 7284 if (q_bit != 0) 7285 *q=byte >> (8-q_bit); 7286 q+=scanline_pad; 7287 } 7288 } 7289 y++; 7290 } 7291 break; 7292 } 7293 case MSBFirst: 7294 default: 7295 { 7296 /* 7297 Magnify big-endian bitmap. 7298 */ 7299 background=0x00; 7300 foreground=0x01; 7301 if (ximage->format == XYBitmap) 7302 { 7303 background=(unsigned char) 7304 (XPixelIntensity(&pixel_info->foreground_color) < 7305 XPixelIntensity(&pixel_info->background_color) ? 0x01 : 0x00); 7306 foreground=(unsigned char) 7307 (XPixelIntensity(&pixel_info->background_color) < 7308 XPixelIntensity(&pixel_info->foreground_color) ? 0x01 : 0x00); 7309 if (windows->magnify.depth > 1) 7310 Swap(background,foreground); 7311 } 7312 for (i=0; i < (ssize_t) height; i+=magnify) 7313 { 7314 /* 7315 Propogate pixel magnify rows. 7316 */ 7317 for (j=0; j < magnify; j++) 7318 { 7319 p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+ 7320 ((x*ximage->bits_per_pixel) >> 3); 7321 p_bit=(unsigned char) (x*ximage->bits_per_pixel) & 0x07; 7322 q_bit=0; 7323 byte=0; 7324 for (k=0; k < width; k+=magnify) 7325 { 7326 /* 7327 Propogate pixel magnify columns. 7328 */ 7329 for (l=0; l < magnify; l++) 7330 { 7331 /* 7332 Propogate each bit plane. 7333 */ 7334 for (plane=0; (int) plane < ximage->bits_per_pixel; plane++) 7335 { 7336 byte<<=1; 7337 if (*p & (0x80 >> (p_bit+plane))) 7338 byte|=foreground; 7339 else 7340 byte|=background; 7341 q_bit++; 7342 if (q_bit == 8) 7343 { 7344 *q++=byte; 7345 q_bit=0; 7346 byte=0; 7347 } 7348 } 7349 } 7350 p_bit+=ximage->bits_per_pixel; 7351 if (p_bit == 8) 7352 { 7353 p++; 7354 p_bit=0; 7355 } 7356 if (q_bit != 0) 7357 *q=byte << (8-q_bit); 7358 q+=scanline_pad; 7359 } 7360 } 7361 y++; 7362 } 7363 break; 7364 } 7365 } 7366 } 7367 else 7368 switch (ximage->bits_per_pixel) 7369 { 7370 case 6: 7371 case 8: 7372 { 7373 /* 7374 Magnify 8 bit X image. 7375 */ 7376 for (i=0; i < (ssize_t) height; i+=magnify) 7377 { 7378 /* 7379 Propogate pixel magnify rows. 7380 */ 7381 for (j=0; j < magnify; j++) 7382 { 7383 p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+ 7384 ((x*ximage->bits_per_pixel) >> 3); 7385 for (k=0; k < width; k+=magnify) 7386 { 7387 /* 7388 Propogate pixel magnify columns. 7389 */ 7390 for (l=0; l < magnify; l++) 7391 *q++=(*p); 7392 p++; 7393 } 7394 q+=scanline_pad; 7395 } 7396 y++; 7397 } 7398 break; 7399 } 7400 default: 7401 { 7402 register unsigned int 7403 bytes_per_pixel, 7404 m; 7405 7406 /* 7407 Magnify multi-byte X image. 7408 */ 7409 bytes_per_pixel=(unsigned int) ximage->bits_per_pixel >> 3; 7410 for (i=0; i < (ssize_t) height; i+=magnify) 7411 { 7412 /* 7413 Propogate pixel magnify rows. 7414 */ 7415 for (j=0; j < magnify; j++) 7416 { 7417 p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+ 7418 ((x*ximage->bits_per_pixel) >> 3); 7419 for (k=0; k < width; k+=magnify) 7420 { 7421 /* 7422 Propogate pixel magnify columns. 7423 */ 7424 for (l=0; l < magnify; l++) 7425 for (m=0; m < bytes_per_pixel; m++) 7426 *q++=(*(p+m)); 7427 p+=bytes_per_pixel; 7428 } 7429 q+=scanline_pad; 7430 } 7431 y++; 7432 } 7433 break; 7434 } 7435 } 7436 /* 7437 Copy X image to magnify pixmap. 7438 */ 7439 x=windows->magnify.x-((width/magnify) >> 1); 7440 if (x < 0) 7441 x=(int) ((width >> 1)-windows->magnify.x*magnify); 7442 else 7443 if (x > (int) (ximage->width-(width/magnify))) 7444 x=(int) ((ximage->width-windows->magnify.x)*magnify-(width >> 1)); 7445 else 7446 x=0; 7447 y=windows->magnify.y-((height/magnify) >> 1); 7448 if (y < 0) 7449 y=(int) ((height >> 1)-windows->magnify.y*magnify); 7450 else 7451 if (y > (int) (ximage->height-(height/magnify))) 7452 y=(int) ((ximage->height-windows->magnify.y)*magnify-(height >> 1)); 7453 else 7454 y=0; 7455 if ((x != 0) || (y != 0)) 7456 (void) XFillRectangle(display,windows->magnify.pixmap, 7457 windows->magnify.annotate_context,0,0,width,height); 7458 (void) XPutImage(display,windows->magnify.pixmap, 7459 windows->magnify.annotate_context,windows->magnify.ximage,0,0,x,y,width-x, 7460 height-y); 7461 if ((magnify > 1) && ((magnify <= (width >> 1)) && 7462 (magnify <= (height >> 1)))) 7463 { 7464 RectangleInfo 7465 highlight_info; 7466 7467 /* 7468 Highlight center pixel. 7469 */ 7470 highlight_info.x=(ssize_t) windows->magnify.width >> 1; 7471 highlight_info.y=(ssize_t) windows->magnify.height >> 1; 7472 highlight_info.width=magnify; 7473 highlight_info.height=magnify; 7474 (void) XDrawRectangle(display,windows->magnify.pixmap, 7475 windows->magnify.highlight_context,(int) highlight_info.x, 7476 (int) highlight_info.y,(unsigned int) highlight_info.width-1, 7477 (unsigned int) highlight_info.height-1); 7478 if (magnify > 2) 7479 (void) XDrawRectangle(display,windows->magnify.pixmap, 7480 windows->magnify.annotate_context,(int) highlight_info.x+1, 7481 (int) highlight_info.y+1,(unsigned int) highlight_info.width-3, 7482 (unsigned int) highlight_info.height-3); 7483 } 7484 /* 7485 Show center pixel color. 7486 */ 7487 (void) GetOneVirtualPixelInfo(windows->image.image,TileVirtualPixelMethod, 7488 (ssize_t) windows->magnify.x,(ssize_t) windows->magnify.y,&pixel,exception); 7489 (void) FormatLocaleString(tuple,MagickPathExtent,"%d,%d: ", 7490 windows->magnify.x,windows->magnify.y); 7491 (void) ConcatenateMagickString(tuple,"(",MagickPathExtent); 7492 ConcatenateColorComponent(&pixel,RedPixelChannel,X11Compliance,tuple); 7493 (void) ConcatenateMagickString(tuple,",",MagickPathExtent); 7494 ConcatenateColorComponent(&pixel,GreenPixelChannel,X11Compliance,tuple); 7495 (void) ConcatenateMagickString(tuple,",",MagickPathExtent); 7496 ConcatenateColorComponent(&pixel,BluePixelChannel,X11Compliance,tuple); 7497 if (pixel.colorspace == CMYKColorspace) 7498 { 7499 (void) ConcatenateMagickString(tuple,",",MagickPathExtent); 7500 ConcatenateColorComponent(&pixel,BlackPixelChannel,X11Compliance,tuple); 7501 } 7502 if (pixel.alpha_trait != UndefinedPixelTrait) 7503 { 7504 (void) ConcatenateMagickString(tuple,",",MagickPathExtent); 7505 ConcatenateColorComponent(&pixel,AlphaPixelChannel,X11Compliance,tuple); 7506 } 7507 (void) ConcatenateMagickString(tuple,")",MagickPathExtent); 7508 height=(unsigned int) windows->magnify.font_info->ascent+ 7509 windows->magnify.font_info->descent; 7510 x=windows->magnify.font_info->max_bounds.width >> 1; 7511 y=windows->magnify.font_info->ascent+(height >> 2); 7512 (void) XDrawImageString(display,windows->magnify.pixmap, 7513 windows->magnify.annotate_context,x,y,tuple,(int) strlen(tuple)); 7514 GetColorTuple(&pixel,MagickTrue,tuple); 7515 y+=height; 7516 (void) XDrawImageString(display,windows->magnify.pixmap, 7517 windows->magnify.annotate_context,x,y,tuple,(int) strlen(tuple)); 7518 (void) QueryColorname(windows->image.image,&pixel,SVGCompliance,tuple, 7519 exception); 7520 y+=height; 7521 (void) XDrawImageString(display,windows->magnify.pixmap, 7522 windows->magnify.annotate_context,x,y,tuple,(int) strlen(tuple)); 7523 /* 7524 Refresh magnify window. 7525 */ 7526 magnify_window=windows->magnify; 7527 magnify_window.x=0; 7528 magnify_window.y=0; 7529 XRefreshWindow(display,&magnify_window,(XEvent *) NULL); 7530} 7531 7532/* 7533%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 7534% % 7535% % 7536% % 7537% X M a k e P i x m a p % 7538% % 7539% % 7540% % 7541%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 7542% 7543% XMakePixmap() creates an X11 pixmap. 7544% 7545% The format of the XMakePixmap method is: 7546% 7547% void XMakeStandardColormap(Display *display,XVisualInfo *visual_info, 7548% XResourceInfo *resource_info,Image *image,XStandardColormap *map_info, 7549% XPixelInfo *pixel) 7550% 7551% A description of each parameter follows: 7552% 7553% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. 7554% 7555% o display: Specifies a connection to an X server; returned from 7556% XOpenDisplay. 7557% 7558% o window: Specifies a pointer to a XWindowInfo structure. 7559% 7560*/ 7561static MagickBooleanType XMakePixmap(Display *display, 7562 const XResourceInfo *resource_info,XWindowInfo *window) 7563{ 7564 unsigned int 7565 height, 7566 width; 7567 7568 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 7569 assert(display != (Display *) NULL); 7570 assert(resource_info != (XResourceInfo *) NULL); 7571 assert(window != (XWindowInfo *) NULL); 7572 if (window->pixmap != (Pixmap) NULL) 7573 { 7574 /* 7575 Destroy previous X pixmap. 7576 */ 7577 (void) XFreePixmap(display,window->pixmap); 7578 window->pixmap=(Pixmap) NULL; 7579 } 7580 if (window->use_pixmap == MagickFalse) 7581 return(MagickFalse); 7582 if (window->ximage == (XImage *) NULL) 7583 return(MagickFalse); 7584 /* 7585 Display busy cursor. 7586 */ 7587 (void) XCheckDefineCursor(display,window->id,window->busy_cursor); 7588 (void) XFlush(display); 7589 /* 7590 Create pixmap. 7591 */ 7592 width=(unsigned int) window->ximage->width; 7593 height=(unsigned int) window->ximage->height; 7594 window->pixmap=XCreatePixmap(display,window->id,width,height,window->depth); 7595 if (window->pixmap == (Pixmap) NULL) 7596 { 7597 /* 7598 Unable to allocate pixmap. 7599 */ 7600 (void) XCheckDefineCursor(display,window->id,window->cursor); 7601 return(MagickFalse); 7602 } 7603 /* 7604 Copy X image to pixmap. 7605 */ 7606#if defined(MAGICKCORE_HAVE_SHARED_MEMORY) 7607 if (window->shared_memory) 7608 (void) XShmPutImage(display,window->pixmap,window->annotate_context, 7609 window->ximage,0,0,0,0,width,height,MagickTrue); 7610#endif 7611 if (window->shared_memory == MagickFalse) 7612 (void) XPutImage(display,window->pixmap,window->annotate_context, 7613 window->ximage,0,0,0,0,width,height); 7614 if (IsEventLogging()) 7615 { 7616 (void) LogMagickEvent(X11Event,GetMagickModule(),"Pixmap:"); 7617 (void) LogMagickEvent(X11Event,GetMagickModule()," width, height: %ux%u", 7618 width,height); 7619 } 7620 /* 7621 Restore cursor. 7622 */ 7623 (void) XCheckDefineCursor(display,window->id,window->cursor); 7624 return(MagickTrue); 7625} 7626 7627/* 7628%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 7629% % 7630% % 7631% % 7632% X M a k e S t a n d a r d C o l o r m a p % 7633% % 7634% % 7635% % 7636%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 7637% 7638% XMakeStandardColormap() creates an X11 Standard Colormap. 7639% 7640% The format of the XMakeStandardColormap method is: 7641% 7642% void XMakeStandardColormap(Display *display,XVisualInfo *visual_info, 7643% XResourceInfo *resource_info,Image *image,XStandardColormap *map_info, 7644% XPixelInfo *pixel,ExceptionInfo *exception) 7645% 7646% A description of each parameter follows: 7647% 7648% o display: Specifies a connection to an X server; returned from 7649% XOpenDisplay. 7650% 7651% o visual_info: Specifies a pointer to a X11 XVisualInfo structure; 7652% returned from XGetVisualInfo. 7653% 7654% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. 7655% 7656% o image: the image. 7657% 7658% o map_info: If a Standard Colormap type is specified, this structure is 7659% initialized with info from the Standard Colormap. 7660% 7661% o pixel: Specifies a pointer to a XPixelInfo structure. 7662% 7663% o exception: return any errors or warnings in this structure. 7664% 7665*/ 7666 7667#if defined(__cplusplus) || defined(c_plusplus) 7668extern "C" { 7669#endif 7670 7671static inline double DiversityPixelIntensity( 7672 const DiversityPacket *pixel) 7673{ 7674 double 7675 intensity; 7676 7677 intensity=0.212656*pixel->red+0.715158*pixel->green+0.072186*pixel->blue; 7678 return(intensity); 7679} 7680 7681static int IntensityCompare(const void *x,const void *y) 7682{ 7683 DiversityPacket 7684 *color_1, 7685 *color_2; 7686 7687 int 7688 diversity; 7689 7690 color_1=(DiversityPacket *) x; 7691 color_2=(DiversityPacket *) y; 7692 diversity=(int) (DiversityPixelIntensity(color_2)- 7693 DiversityPixelIntensity(color_1)); 7694 return(diversity); 7695} 7696 7697static int PopularityCompare(const void *x,const void *y) 7698{ 7699 DiversityPacket 7700 *color_1, 7701 *color_2; 7702 7703 color_1=(DiversityPacket *) x; 7704 color_2=(DiversityPacket *) y; 7705 return((int) color_2->count-(int) color_1->count); 7706} 7707 7708#if defined(__cplusplus) || defined(c_plusplus) 7709} 7710#endif 7711 7712static inline Quantum ScaleXToQuantum(const size_t x, 7713 const size_t scale) 7714{ 7715 return((Quantum) (((double) QuantumRange*x)/scale+0.5)); 7716} 7717 7718MagickPrivate void XMakeStandardColormap(Display *display, 7719 XVisualInfo *visual_info,XResourceInfo *resource_info,Image *image, 7720 XStandardColormap *map_info,XPixelInfo *pixel,ExceptionInfo *exception) 7721{ 7722 Colormap 7723 colormap; 7724 7725 register ssize_t 7726 i; 7727 7728 Status 7729 status; 7730 7731 size_t 7732 number_colors, 7733 retain_colors; 7734 7735 unsigned short 7736 gray_value; 7737 7738 XColor 7739 color, 7740 *colors, 7741 *p; 7742 7743 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 7744 assert(display != (Display *) NULL); 7745 assert(visual_info != (XVisualInfo *) NULL); 7746 assert(map_info != (XStandardColormap *) NULL); 7747 assert(resource_info != (XResourceInfo *) NULL); 7748 assert(pixel != (XPixelInfo *) NULL); 7749 if (resource_info->map_type != (char *) NULL) 7750 { 7751 /* 7752 Standard Colormap is already defined (i.e. xstdcmap). 7753 */ 7754 XGetPixelInfo(display,visual_info,map_info,resource_info,image, 7755 pixel); 7756 number_colors=(unsigned int) (map_info->base_pixel+ 7757 (map_info->red_max+1)*(map_info->green_max+1)*(map_info->blue_max+1)); 7758 if ((map_info->red_max*map_info->green_max*map_info->blue_max) != 0) 7759 if ((image->alpha_trait == UndefinedPixelTrait) && 7760 (resource_info->color_recovery == MagickFalse) && 7761 (resource_info->quantize_info->dither_method != NoDitherMethod) && 7762 (number_colors < MaxColormapSize)) 7763 { 7764 Image 7765 *affinity_image; 7766 7767 register Quantum 7768 *magick_restrict q; 7769 7770 /* 7771 Improve image appearance with error diffusion. 7772 */ 7773 affinity_image=AcquireImage((ImageInfo *) NULL,exception); 7774 if (affinity_image == (Image *) NULL) 7775 ThrowXWindowFatalException(ResourceLimitFatalError, 7776 "UnableToDitherImage",image->filename); 7777 affinity_image->columns=number_colors; 7778 affinity_image->rows=1; 7779 /* 7780 Initialize colormap image. 7781 */ 7782 q=QueueAuthenticPixels(affinity_image,0,0,affinity_image->columns, 7783 1,exception); 7784 if (q != (Quantum *) NULL) 7785 { 7786 for (i=0; i < (ssize_t) number_colors; i++) 7787 { 7788 SetPixelRed(affinity_image,0,q); 7789 if (map_info->red_max != 0) 7790 SetPixelRed(affinity_image,ScaleXToQuantum((size_t) 7791 (i/map_info->red_mult),map_info->red_max),q); 7792 SetPixelGreen(affinity_image,0,q); 7793 if (map_info->green_max != 0) 7794 SetPixelGreen(affinity_image,ScaleXToQuantum((size_t) 7795 ((i/map_info->green_mult) % (map_info->green_max+1)), 7796 map_info->green_max),q); 7797 SetPixelBlue(affinity_image,0,q); 7798 if (map_info->blue_max != 0) 7799 SetPixelBlue(affinity_image,ScaleXToQuantum((size_t) 7800 (i % map_info->green_mult),map_info->blue_max),q); 7801 SetPixelAlpha(affinity_image, 7802 TransparentAlpha,q); 7803 q+=GetPixelChannels(affinity_image); 7804 } 7805 (void) SyncAuthenticPixels(affinity_image,exception); 7806 (void) RemapImage(resource_info->quantize_info,image, 7807 affinity_image,exception); 7808 } 7809 XGetPixelInfo(display,visual_info,map_info,resource_info,image, 7810 pixel); 7811 (void) SetImageStorageClass(image,DirectClass,exception); 7812 affinity_image=DestroyImage(affinity_image); 7813 } 7814 if (IsEventLogging()) 7815 { 7816 (void) LogMagickEvent(X11Event,GetMagickModule(), 7817 "Standard Colormap:"); 7818 (void) LogMagickEvent(X11Event,GetMagickModule(), 7819 " colormap id: 0x%lx",map_info->colormap); 7820 (void) LogMagickEvent(X11Event,GetMagickModule(), 7821 " red, green, blue max: %lu %lu %lu",map_info->red_max, 7822 map_info->green_max,map_info->blue_max); 7823 (void) LogMagickEvent(X11Event,GetMagickModule(), 7824 " red, green, blue mult: %lu %lu %lu",map_info->red_mult, 7825 map_info->green_mult,map_info->blue_mult); 7826 } 7827 return; 7828 } 7829 if ((visual_info->klass != DirectColor) && 7830 (visual_info->klass != TrueColor)) 7831 if ((image->storage_class == DirectClass) || 7832 ((int) image->colors > visual_info->colormap_size)) 7833 { 7834 QuantizeInfo 7835 quantize_info; 7836 7837 /* 7838 Image has more colors than the visual supports. 7839 */ 7840 quantize_info=(*resource_info->quantize_info); 7841 quantize_info.number_colors=(size_t) visual_info->colormap_size; 7842 (void) QuantizeImage(&quantize_info,image,exception); 7843 } 7844 /* 7845 Free previous and create new colormap. 7846 */ 7847 (void) XFreeStandardColormap(display,visual_info,map_info,pixel); 7848 colormap=XDefaultColormap(display,visual_info->screen); 7849 if (visual_info->visual != XDefaultVisual(display,visual_info->screen)) 7850 colormap=XCreateColormap(display,XRootWindow(display,visual_info->screen), 7851 visual_info->visual,visual_info->klass == DirectColor ? 7852 AllocAll : AllocNone); 7853 if (colormap == (Colormap) NULL) 7854 ThrowXWindowFatalException(ResourceLimitFatalError,"UnableToCreateColormap", 7855 image->filename); 7856 /* 7857 Initialize the map and pixel info structures. 7858 */ 7859 XGetMapInfo(visual_info,colormap,map_info); 7860 XGetPixelInfo(display,visual_info,map_info,resource_info,image,pixel); 7861 /* 7862 Allocating colors in server colormap is based on visual class. 7863 */ 7864 switch (visual_info->klass) 7865 { 7866 case StaticGray: 7867 case StaticColor: 7868 { 7869 /* 7870 Define Standard Colormap for StaticGray or StaticColor visual. 7871 */ 7872 number_colors=image->colors; 7873 colors=(XColor *) AcquireQuantumMemory((size_t) 7874 visual_info->colormap_size,sizeof(*colors)); 7875 if (colors == (XColor *) NULL) 7876 ThrowXWindowFatalException(ResourceLimitFatalError, 7877 "UnableToCreateColormap",image->filename); 7878 p=colors; 7879 color.flags=(char) (DoRed | DoGreen | DoBlue); 7880 for (i=0; i < (ssize_t) image->colors; i++) 7881 { 7882 color.red=ScaleQuantumToShort(XRedGamma(image->colormap[i].red)); 7883 color.green=ScaleQuantumToShort(XGreenGamma(image->colormap[i].green)); 7884 color.blue=ScaleQuantumToShort(XBlueGamma(image->colormap[i].blue)); 7885 if (visual_info->klass != StaticColor) 7886 { 7887 gray_value=(unsigned short) XPixelIntensity(&color); 7888 color.red=gray_value; 7889 color.green=gray_value; 7890 color.blue=gray_value; 7891 } 7892 status=XAllocColor(display,colormap,&color); 7893 if (status == False) 7894 { 7895 colormap=XCopyColormapAndFree(display,colormap); 7896 (void) XAllocColor(display,colormap,&color); 7897 } 7898 pixel->pixels[i]=color.pixel; 7899 *p++=color; 7900 } 7901 break; 7902 } 7903 case GrayScale: 7904 case PseudoColor: 7905 { 7906 unsigned int 7907 colormap_type; 7908 7909 /* 7910 Define Standard Colormap for GrayScale or PseudoColor visual. 7911 */ 7912 number_colors=image->colors; 7913 colors=(XColor *) AcquireQuantumMemory((size_t) 7914 visual_info->colormap_size,sizeof(*colors)); 7915 if (colors == (XColor *) NULL) 7916 ThrowXWindowFatalException(ResourceLimitFatalError, 7917 "UnableToCreateColormap",image->filename); 7918 /* 7919 Preallocate our GUI colors. 7920 */ 7921 (void) XAllocColor(display,colormap,&pixel->foreground_color); 7922 (void) XAllocColor(display,colormap,&pixel->background_color); 7923 (void) XAllocColor(display,colormap,&pixel->border_color); 7924 (void) XAllocColor(display,colormap,&pixel->alpha_color); 7925 (void) XAllocColor(display,colormap,&pixel->highlight_color); 7926 (void) XAllocColor(display,colormap,&pixel->shadow_color); 7927 (void) XAllocColor(display,colormap,&pixel->depth_color); 7928 (void) XAllocColor(display,colormap,&pixel->trough_color); 7929 for (i=0; i < MaxNumberPens; i++) 7930 (void) XAllocColor(display,colormap,&pixel->pen_colors[i]); 7931 /* 7932 Determine if image colors will "fit" into X server colormap. 7933 */ 7934 colormap_type=resource_info->colormap; 7935 status=XAllocColorCells(display,colormap,MagickFalse,(unsigned long *) 7936 NULL,0,pixel->pixels,(unsigned int) image->colors); 7937 if (status != False) 7938 colormap_type=PrivateColormap; 7939 if (colormap_type == SharedColormap) 7940 { 7941 CacheView 7942 *image_view; 7943 7944 DiversityPacket 7945 *diversity; 7946 7947 int 7948 y; 7949 7950 register int 7951 x; 7952 7953 unsigned short 7954 index; 7955 7956 XColor 7957 *server_colors; 7958 7959 /* 7960 Define Standard colormap for shared GrayScale or PseudoColor visual. 7961 */ 7962 diversity=(DiversityPacket *) AcquireQuantumMemory(image->colors, 7963 sizeof(*diversity)); 7964 if (diversity == (DiversityPacket *) NULL) 7965 ThrowXWindowFatalException(ResourceLimitFatalError, 7966 "UnableToCreateColormap",image->filename); 7967 for (i=0; i < (ssize_t) image->colors; i++) 7968 { 7969 diversity[i].red=ClampToQuantum(image->colormap[i].red); 7970 diversity[i].green=ClampToQuantum(image->colormap[i].green); 7971 diversity[i].blue=ClampToQuantum(image->colormap[i].blue); 7972 diversity[i].index=(unsigned short) i; 7973 diversity[i].count=0; 7974 } 7975 image_view=AcquireAuthenticCacheView(image,exception); 7976 for (y=0; y < (int) image->rows; y++) 7977 { 7978 register int 7979 x; 7980 7981 register const Quantum 7982 *magick_restrict p; 7983 7984 p=GetCacheViewAuthenticPixels(image_view,0,(ssize_t) y, 7985 image->columns,1,exception); 7986 if (p == (const Quantum *) NULL) 7987 break; 7988 for (x=(int) image->columns-1; x >= 0; x--) 7989 { 7990 diversity[(ssize_t) GetPixelIndex(image,p)].count++; 7991 p+=GetPixelChannels(image); 7992 } 7993 } 7994 image_view=DestroyCacheView(image_view); 7995 /* 7996 Sort colors by decreasing intensity. 7997 */ 7998 qsort((void *) diversity,image->colors,sizeof(*diversity), 7999 IntensityCompare); 8000 for (i=0; i < (ssize_t) image->colors; ) 8001 { 8002 diversity[i].count<<=4; /* increase this colors popularity */ 8003 i+=MagickMax((int) (image->colors >> 4),2); 8004 } 8005 diversity[image->colors-1].count<<=4; 8006 qsort((void *) diversity,image->colors,sizeof(*diversity), 8007 PopularityCompare); 8008 /* 8009 Allocate colors. 8010 */ 8011 p=colors; 8012 color.flags=(char) (DoRed | DoGreen | DoBlue); 8013 for (i=0; i < (ssize_t) image->colors; i++) 8014 { 8015 index=diversity[i].index; 8016 color.red= 8017 ScaleQuantumToShort(XRedGamma(image->colormap[index].red)); 8018 color.green= 8019 ScaleQuantumToShort(XGreenGamma(image->colormap[index].green)); 8020 color.blue= 8021 ScaleQuantumToShort(XBlueGamma(image->colormap[index].blue)); 8022 if (visual_info->klass != PseudoColor) 8023 { 8024 gray_value=(unsigned short) XPixelIntensity(&color); 8025 color.red=gray_value; 8026 color.green=gray_value; 8027 color.blue=gray_value; 8028 } 8029 status=XAllocColor(display,colormap,&color); 8030 if (status == False) 8031 break; 8032 pixel->pixels[index]=color.pixel; 8033 *p++=color; 8034 } 8035 /* 8036 Read X server colormap. 8037 */ 8038 server_colors=(XColor *) AcquireQuantumMemory((size_t) 8039 visual_info->colormap_size,sizeof(*server_colors)); 8040 if (server_colors == (XColor *) NULL) 8041 ThrowXWindowFatalException(ResourceLimitFatalError, 8042 "UnableToCreateColormap",image->filename); 8043 for (x=visual_info->colormap_size-1; x >= 0; x--) 8044 server_colors[x].pixel=(size_t) x; 8045 (void) XQueryColors(display,colormap,server_colors, 8046 (int) MagickMin((unsigned int) visual_info->colormap_size,256)); 8047 /* 8048 Select remaining colors from X server colormap. 8049 */ 8050 for (; i < (ssize_t) image->colors; i++) 8051 { 8052 index=diversity[i].index; 8053 color.red=ScaleQuantumToShort( 8054 XRedGamma(image->colormap[index].red)); 8055 color.green=ScaleQuantumToShort( 8056 XGreenGamma(image->colormap[index].green)); 8057 color.blue=ScaleQuantumToShort( 8058 XBlueGamma(image->colormap[index].blue)); 8059 if (visual_info->klass != PseudoColor) 8060 { 8061 gray_value=(unsigned short) XPixelIntensity(&color); 8062 color.red=gray_value; 8063 color.green=gray_value; 8064 color.blue=gray_value; 8065 } 8066 XBestPixel(display,colormap,server_colors,(unsigned int) 8067 visual_info->colormap_size,&color); 8068 pixel->pixels[index]=color.pixel; 8069 *p++=color; 8070 } 8071 if ((int) image->colors < visual_info->colormap_size) 8072 { 8073 /* 8074 Fill up colors array-- more choices for pen colors. 8075 */ 8076 retain_colors=MagickMin((unsigned int) 8077 (visual_info->colormap_size-image->colors),256); 8078 for (i=0; i < (ssize_t) retain_colors; i++) 8079 *p++=server_colors[i]; 8080 number_colors+=retain_colors; 8081 } 8082 server_colors=(XColor *) RelinquishMagickMemory(server_colors); 8083 diversity=(DiversityPacket *) RelinquishMagickMemory(diversity); 8084 break; 8085 } 8086 /* 8087 Define Standard colormap for private GrayScale or PseudoColor visual. 8088 */ 8089 if (status == False) 8090 { 8091 /* 8092 Not enough colormap entries in the colormap-- Create a new colormap. 8093 */ 8094 colormap=XCreateColormap(display, 8095 XRootWindow(display,visual_info->screen),visual_info->visual, 8096 AllocNone); 8097 if (colormap == (Colormap) NULL) 8098 ThrowXWindowFatalException(ResourceLimitFatalError, 8099 "UnableToCreateColormap",image->filename); 8100 map_info->colormap=colormap; 8101 if ((int) image->colors < visual_info->colormap_size) 8102 { 8103 /* 8104 Retain colors from the default colormap to help lessens the 8105 effects of colormap flashing. 8106 */ 8107 retain_colors=MagickMin((unsigned int) 8108 (visual_info->colormap_size-image->colors),256); 8109 p=colors+image->colors; 8110 for (i=0; i < (ssize_t) retain_colors; i++) 8111 { 8112 p->pixel=(unsigned long) i; 8113 p++; 8114 } 8115 (void) XQueryColors(display, 8116 XDefaultColormap(display,visual_info->screen), 8117 colors+image->colors,(int) retain_colors); 8118 /* 8119 Transfer colors from default to private colormap. 8120 */ 8121 (void) XAllocColorCells(display,colormap,MagickFalse, 8122 (unsigned long *) NULL,0,pixel->pixels,(unsigned int) 8123 retain_colors); 8124 p=colors+image->colors; 8125 for (i=0; i < (ssize_t) retain_colors; i++) 8126 { 8127 p->pixel=pixel->pixels[i]; 8128 p++; 8129 } 8130 (void) XStoreColors(display,colormap,colors+image->colors, 8131 (int) retain_colors); 8132 number_colors+=retain_colors; 8133 } 8134 (void) XAllocColorCells(display,colormap,MagickFalse, 8135 (unsigned long *) NULL,0,pixel->pixels,(unsigned int) 8136 image->colors); 8137 } 8138 /* 8139 Store the image colormap. 8140 */ 8141 p=colors; 8142 color.flags=(char) (DoRed | DoGreen | DoBlue); 8143 for (i=0; i < (ssize_t) image->colors; i++) 8144 { 8145 color.red=ScaleQuantumToShort(XRedGamma(image->colormap[i].red)); 8146 color.green=ScaleQuantumToShort(XGreenGamma(image->colormap[i].green)); 8147 color.blue=ScaleQuantumToShort(XBlueGamma(image->colormap[i].blue)); 8148 if (visual_info->klass != PseudoColor) 8149 { 8150 gray_value=(unsigned short) XPixelIntensity(&color); 8151 color.red=gray_value; 8152 color.green=gray_value; 8153 color.blue=gray_value; 8154 } 8155 color.pixel=pixel->pixels[i]; 8156 *p++=color; 8157 } 8158 (void) XStoreColors(display,colormap,colors,(int) image->colors); 8159 break; 8160 } 8161 case TrueColor: 8162 case DirectColor: 8163 default: 8164 { 8165 MagickBooleanType 8166 linear_colormap; 8167 8168 /* 8169 Define Standard Colormap for TrueColor or DirectColor visual. 8170 */ 8171 number_colors=(unsigned int) ((map_info->red_max*map_info->red_mult)+ 8172 (map_info->green_max*map_info->green_mult)+ 8173 (map_info->blue_max*map_info->blue_mult)+1); 8174 linear_colormap=(number_colors > 4096) || 8175 (((int) (map_info->red_max+1) == visual_info->colormap_size) && 8176 ((int) (map_info->green_max+1) == visual_info->colormap_size) && 8177 ((int) (map_info->blue_max+1) == visual_info->colormap_size)) ? 8178 MagickTrue : MagickFalse; 8179 if (linear_colormap != MagickFalse) 8180 number_colors=(size_t) visual_info->colormap_size; 8181 /* 8182 Allocate color array. 8183 */ 8184 colors=(XColor *) AcquireQuantumMemory(number_colors,sizeof(*colors)); 8185 if (colors == (XColor *) NULL) 8186 ThrowXWindowFatalException(ResourceLimitFatalError, 8187 "UnableToCreateColormap",image->filename); 8188 /* 8189 Initialize linear color ramp. 8190 */ 8191 p=colors; 8192 color.flags=(char) (DoRed | DoGreen | DoBlue); 8193 if (linear_colormap != MagickFalse) 8194 for (i=0; i < (ssize_t) number_colors; i++) 8195 { 8196 color.blue=(unsigned short) 0; 8197 if (map_info->blue_max != 0) 8198 color.blue=(unsigned short) ((size_t) 8199 ((65535L*(i % map_info->green_mult))/map_info->blue_max)); 8200 color.green=color.blue; 8201 color.red=color.blue; 8202 color.pixel=XStandardPixel(map_info,&color); 8203 *p++=color; 8204 } 8205 else 8206 for (i=0; i < (ssize_t) number_colors; i++) 8207 { 8208 color.red=(unsigned short) 0; 8209 if (map_info->red_max != 0) 8210 color.red=(unsigned short) ((size_t) 8211 ((65535L*(i/map_info->red_mult))/map_info->red_max)); 8212 color.green=(unsigned int) 0; 8213 if (map_info->green_max != 0) 8214 color.green=(unsigned short) ((size_t) 8215 ((65535L*((i/map_info->green_mult) % (map_info->green_max+1)))/ 8216 map_info->green_max)); 8217 color.blue=(unsigned short) 0; 8218 if (map_info->blue_max != 0) 8219 color.blue=(unsigned short) ((size_t) 8220 ((65535L*(i % map_info->green_mult))/map_info->blue_max)); 8221 color.pixel=XStandardPixel(map_info,&color); 8222 *p++=color; 8223 } 8224 if ((visual_info->klass == DirectColor) && 8225 (colormap != XDefaultColormap(display,visual_info->screen))) 8226 (void) XStoreColors(display,colormap,colors,(int) number_colors); 8227 else 8228 for (i=0; i < (ssize_t) number_colors; i++) 8229 (void) XAllocColor(display,colormap,&colors[i]); 8230 break; 8231 } 8232 } 8233 if ((visual_info->klass != DirectColor) && 8234 (visual_info->klass != TrueColor)) 8235 { 8236 /* 8237 Set foreground, background, border, etc. pixels. 8238 */ 8239 XBestPixel(display,colormap,colors,(unsigned int) number_colors, 8240 &pixel->foreground_color); 8241 XBestPixel(display,colormap,colors,(unsigned int) number_colors, 8242 &pixel->background_color); 8243 if (pixel->background_color.pixel == pixel->foreground_color.pixel) 8244 { 8245 /* 8246 Foreground and background colors must differ. 8247 */ 8248 pixel->background_color.red=(~pixel->foreground_color.red); 8249 pixel->background_color.green= 8250 (~pixel->foreground_color.green); 8251 pixel->background_color.blue= 8252 (~pixel->foreground_color.blue); 8253 XBestPixel(display,colormap,colors,(unsigned int) number_colors, 8254 &pixel->background_color); 8255 } 8256 XBestPixel(display,colormap,colors,(unsigned int) number_colors, 8257 &pixel->border_color); 8258 XBestPixel(display,colormap,colors,(unsigned int) number_colors, 8259 &pixel->alpha_color); 8260 XBestPixel(display,colormap,colors,(unsigned int) number_colors, 8261 &pixel->highlight_color); 8262 XBestPixel(display,colormap,colors,(unsigned int) number_colors, 8263 &pixel->shadow_color); 8264 XBestPixel(display,colormap,colors,(unsigned int) number_colors, 8265 &pixel->depth_color); 8266 XBestPixel(display,colormap,colors,(unsigned int) number_colors, 8267 &pixel->trough_color); 8268 for (i=0; i < MaxNumberPens; i++) 8269 { 8270 XBestPixel(display,colormap,colors,(unsigned int) number_colors, 8271 &pixel->pen_colors[i]); 8272 pixel->pixels[image->colors+i]=pixel->pen_colors[i].pixel; 8273 } 8274 pixel->colors=(ssize_t) (image->colors+MaxNumberPens); 8275 } 8276 colors=(XColor *) RelinquishMagickMemory(colors); 8277 if (IsEventLogging()) 8278 { 8279 (void) LogMagickEvent(X11Event,GetMagickModule(),"Standard Colormap:"); 8280 (void) LogMagickEvent(X11Event,GetMagickModule()," colormap id: 0x%lx", 8281 map_info->colormap); 8282 (void) LogMagickEvent(X11Event,GetMagickModule(), 8283 " red, green, blue max: %lu %lu %lu",map_info->red_max, 8284 map_info->green_max,map_info->blue_max); 8285 (void) LogMagickEvent(X11Event,GetMagickModule(), 8286 " red, green, blue mult: %lu %lu %lu",map_info->red_mult, 8287 map_info->green_mult,map_info->blue_mult); 8288 } 8289} 8290 8291/* 8292%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8293% % 8294% % 8295% % 8296% X M a k e W i n d o w % 8297% % 8298% % 8299% % 8300%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8301% 8302% XMakeWindow() creates an X11 window. 8303% 8304% The format of the XMakeWindow method is: 8305% 8306% void XMakeWindow(Display *display,Window parent,char **argv,int argc, 8307% XClassHint *class_hint,XWMHints *manager_hints, 8308% XWindowInfo *window_info) 8309% 8310% A description of each parameter follows: 8311% 8312% o display: Specifies a connection to an X server; returned from 8313% XOpenDisplay. 8314% 8315% o parent: Specifies the parent window_info. 8316% 8317% o argv: Specifies the application's argument list. 8318% 8319% o argc: Specifies the number of arguments. 8320% 8321% o class_hint: Specifies a pointer to a X11 XClassHint structure. 8322% 8323% o manager_hints: Specifies a pointer to a X11 XWMHints structure. 8324% 8325% o window_info: Specifies a pointer to a X11 XWindowInfo structure. 8326% 8327*/ 8328MagickPrivate void XMakeWindow(Display *display,Window parent,char **argv, 8329 int argc,XClassHint *class_hint,XWMHints *manager_hints, 8330 XWindowInfo *window_info) 8331{ 8332#define MinWindowSize 64 8333 8334 Atom 8335 atom_list[2]; 8336 8337 int 8338 gravity; 8339 8340 static XTextProperty 8341 icon_name, 8342 window_name; 8343 8344 Status 8345 status; 8346 8347 XSizeHints 8348 *size_hints; 8349 8350 /* 8351 Set window info hints. 8352 */ 8353 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 8354 assert(display != (Display *) NULL); 8355 assert(window_info != (XWindowInfo *) NULL); 8356 size_hints=XAllocSizeHints(); 8357 if (size_hints == (XSizeHints *) NULL) 8358 ThrowXWindowFatalException(XServerFatalError,"UnableToMakeXWindow",argv[0]); 8359 size_hints->flags=(int) window_info->flags; 8360 size_hints->x=window_info->x; 8361 size_hints->y=window_info->y; 8362 size_hints->width=(int) window_info->width; 8363 size_hints->height=(int) window_info->height; 8364 if (window_info->immutable != MagickFalse) 8365 { 8366 /* 8367 Window size cannot be changed. 8368 */ 8369 size_hints->min_width=size_hints->width; 8370 size_hints->min_height=size_hints->height; 8371 size_hints->max_width=size_hints->width; 8372 size_hints->max_height=size_hints->height; 8373 size_hints->flags|=PMinSize; 8374 size_hints->flags|=PMaxSize; 8375 } 8376 else 8377 { 8378 /* 8379 Window size can be changed. 8380 */ 8381 size_hints->min_width=(int) window_info->min_width; 8382 size_hints->min_height=(int) window_info->min_height; 8383 size_hints->flags|=PResizeInc; 8384 size_hints->width_inc=(int) window_info->width_inc; 8385 size_hints->height_inc=(int) window_info->height_inc; 8386#if !defined(PRE_R4_ICCCM) 8387 size_hints->flags|=PBaseSize; 8388 size_hints->base_width=size_hints->width_inc; 8389 size_hints->base_height=size_hints->height_inc; 8390#endif 8391 } 8392 gravity=NorthWestGravity; 8393 if (window_info->geometry != (char *) NULL) 8394 { 8395 char 8396 default_geometry[MagickPathExtent], 8397 geometry[MagickPathExtent]; 8398 8399 int 8400 flags; 8401 8402 register char 8403 *p; 8404 8405 /* 8406 User specified geometry. 8407 */ 8408 (void) FormatLocaleString(default_geometry,MagickPathExtent,"%dx%d", 8409 size_hints->width,size_hints->height); 8410 (void) CopyMagickString(geometry,window_info->geometry,MagickPathExtent); 8411 p=geometry; 8412 while (strlen(p) != 0) 8413 { 8414 if ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '%')) 8415 p++; 8416 else 8417 (void) CopyMagickString(p,p+1,MagickPathExtent-(p-geometry)); 8418 } 8419 flags=XWMGeometry(display,window_info->screen,geometry,default_geometry, 8420 window_info->border_width,size_hints,&size_hints->x,&size_hints->y, 8421 &size_hints->width,&size_hints->height,&gravity); 8422 if ((flags & WidthValue) && (flags & HeightValue)) 8423 size_hints->flags|=USSize; 8424 if ((flags & XValue) && (flags & YValue)) 8425 { 8426 size_hints->flags|=USPosition; 8427 window_info->x=size_hints->x; 8428 window_info->y=size_hints->y; 8429 } 8430 } 8431#if !defined(PRE_R4_ICCCM) 8432 size_hints->win_gravity=gravity; 8433 size_hints->flags|=PWinGravity; 8434#endif 8435 if (window_info->id == (Window) NULL) 8436 window_info->id=XCreateWindow(display,parent,window_info->x,window_info->y, 8437 (unsigned int) size_hints->width,(unsigned int) size_hints->height, 8438 window_info->border_width,(int) window_info->depth,InputOutput, 8439 window_info->visual,(unsigned long) window_info->mask, 8440 &window_info->attributes); 8441 else 8442 { 8443 MagickStatusType 8444 mask; 8445 8446 XEvent 8447 sans_event; 8448 8449 XWindowChanges 8450 window_changes; 8451 8452 /* 8453 Window already exists; change relevant attributes. 8454 */ 8455 (void) XChangeWindowAttributes(display,window_info->id,(unsigned long) 8456 window_info->mask,&window_info->attributes); 8457 mask=ConfigureNotify; 8458 while (XCheckTypedWindowEvent(display,window_info->id,(int) mask,&sans_event)) ; 8459 window_changes.x=window_info->x; 8460 window_changes.y=window_info->y; 8461 window_changes.width=(int) window_info->width; 8462 window_changes.height=(int) window_info->height; 8463 mask=(MagickStatusType) (CWWidth | CWHeight); 8464 if (window_info->flags & USPosition) 8465 mask|=CWX | CWY; 8466 (void) XReconfigureWMWindow(display,window_info->id,window_info->screen, 8467 mask,&window_changes); 8468 } 8469 if (window_info->id == (Window) NULL) 8470 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateWindow", 8471 window_info->name); 8472 status=XStringListToTextProperty(&window_info->name,1,&window_name); 8473 if (status == False) 8474 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateTextProperty", 8475 window_info->name); 8476 status=XStringListToTextProperty(&window_info->icon_name,1,&icon_name); 8477 if (status == False) 8478 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateTextProperty", 8479 window_info->icon_name); 8480 if (window_info->icon_geometry != (char *) NULL) 8481 { 8482 int 8483 flags, 8484 height, 8485 width; 8486 8487 /* 8488 User specified icon geometry. 8489 */ 8490 size_hints->flags|=USPosition; 8491 flags=XWMGeometry(display,window_info->screen,window_info->icon_geometry, 8492 (char *) NULL,0,size_hints,&manager_hints->icon_x, 8493 &manager_hints->icon_y,&width,&height,&gravity); 8494 if ((flags & XValue) && (flags & YValue)) 8495 manager_hints->flags|=IconPositionHint; 8496 } 8497 XSetWMProperties(display,window_info->id,&window_name,&icon_name,argv,argc, 8498 size_hints,manager_hints,class_hint); 8499 if (window_name.value != (void *) NULL) 8500 { 8501 (void) XFree((void *) window_name.value); 8502 window_name.value=(unsigned char *) NULL; 8503 window_name.nitems=0; 8504 } 8505 if (icon_name.value != (void *) NULL) 8506 { 8507 (void) XFree((void *) icon_name.value); 8508 icon_name.value=(unsigned char *) NULL; 8509 icon_name.nitems=0; 8510 } 8511 atom_list[0]=XInternAtom(display,"WM_DELETE_WINDOW",MagickFalse); 8512 atom_list[1]=XInternAtom(display,"WM_TAKE_FOCUS",MagickFalse); 8513 (void) XSetWMProtocols(display,window_info->id,atom_list,2); 8514 (void) XFree((void *) size_hints); 8515 if (window_info->shape != MagickFalse) 8516 { 8517#if defined(MAGICKCORE_HAVE_SHAPE) 8518 int 8519 error_base, 8520 event_base; 8521 8522 /* 8523 Can we apply a non-rectangular shaping mask? 8524 */ 8525 error_base=0; 8526 event_base=0; 8527 if (XShapeQueryExtension(display,&error_base,&event_base) == 0) 8528 window_info->shape=MagickFalse; 8529#else 8530 window_info->shape=MagickFalse; 8531#endif 8532 } 8533 if (window_info->shared_memory) 8534 { 8535#if defined(MAGICKCORE_HAVE_SHARED_MEMORY) 8536 /* 8537 Can we use shared memory with this window? 8538 */ 8539 if (XShmQueryExtension(display) == 0) 8540 window_info->shared_memory=MagickFalse; 8541#else 8542 window_info->shared_memory=MagickFalse; 8543#endif 8544 } 8545 window_info->image=NewImageList(); 8546 window_info->destroy=MagickFalse; 8547} 8548 8549/* 8550%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8551% % 8552% % 8553% % 8554% X M a g i c k P r o g r e s s M o n i t o r % 8555% % 8556% % 8557% % 8558%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8559% 8560% XMagickProgressMonitor() displays the progress a task is making in 8561% completing a task. 8562% 8563% The format of the XMagickProgressMonitor method is: 8564% 8565% void XMagickProgressMonitor(const char *task, 8566% const MagickOffsetType quantum,const MagickSizeType span, 8567% void *client_data) 8568% 8569% A description of each parameter follows: 8570% 8571% o task: Identifies the task in progress. 8572% 8573% o quantum: Specifies the quantum position within the span which represents 8574% how much progress has been made in completing a task. 8575% 8576% o span: Specifies the span relative to completing a task. 8577% 8578% o client_data: Pointer to any client data. 8579% 8580*/ 8581 8582static const char *GetLocaleMonitorMessage(const char *text) 8583{ 8584 char 8585 message[MagickPathExtent], 8586 tag[MagickPathExtent]; 8587 8588 const char 8589 *locale_message; 8590 8591 register char 8592 *p; 8593 8594 (void) CopyMagickString(tag,text,MagickPathExtent); 8595 p=strrchr(tag,'/'); 8596 if (p != (char *) NULL) 8597 *p='\0'; 8598 (void) FormatLocaleString(message,MagickPathExtent,"Monitor/%s",tag); 8599 locale_message=GetLocaleMessage(message); 8600 if (locale_message == message) 8601 return(text); 8602 return(locale_message); 8603} 8604 8605MagickPrivate MagickBooleanType XMagickProgressMonitor(const char *tag, 8606 const MagickOffsetType quantum,const MagickSizeType span, 8607 void *magick_unused(client_data)) 8608{ 8609 XWindows 8610 *windows; 8611 8612 windows=XSetWindows((XWindows *) ~0); 8613 if (windows == (XWindows *) NULL) 8614 return(MagickTrue); 8615 if (windows->info.mapped != MagickFalse) 8616 XProgressMonitorWidget(windows->display,windows, 8617 GetLocaleMonitorMessage(tag),quantum,span); 8618 return(MagickTrue); 8619} 8620 8621/* 8622%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8623% % 8624% % 8625% % 8626% X Q u e r y C o l o r D a t a b a s e % 8627% % 8628% % 8629% % 8630%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8631% 8632% XQueryColorCompliance() looks up a RGB values for a color given in the target 8633% string. 8634% 8635% The format of the XQueryColorDatabase method is: 8636% 8637% MagickBooleanType XQueryColorCompliance(const char *target,XColor *color) 8638% 8639% A description of each parameter follows: 8640% 8641% o target: Specifies the color to lookup in the X color database. 8642% 8643% o color: A pointer to an PixelInfo structure. The RGB value of the target 8644% color is returned as this value. 8645% 8646*/ 8647MagickPrivate MagickBooleanType XQueryColorCompliance(const char *target, 8648 XColor *color) 8649{ 8650 Colormap 8651 colormap; 8652 8653 static Display 8654 *display = (Display *) NULL; 8655 8656 Status 8657 status; 8658 8659 XColor 8660 xcolor; 8661 8662 /* 8663 Initialize color return value. 8664 */ 8665 assert(color != (XColor *) NULL); 8666 color->red=0; 8667 color->green=0; 8668 color->blue=0; 8669 color->flags=(char) (DoRed | DoGreen | DoBlue); 8670 if ((target == (char *) NULL) || (*target == '\0')) 8671 target="#ffffffffffff"; 8672 /* 8673 Let the X server define the color for us. 8674 */ 8675 if (display == (Display *) NULL) 8676 display=XOpenDisplay((char *) NULL); 8677 if (display == (Display *) NULL) 8678 { 8679 ThrowXWindowException(XServerError,"ColorIsNotKnownToServer",target); 8680 return(MagickFalse); 8681 } 8682 colormap=XDefaultColormap(display,XDefaultScreen(display)); 8683 status=XParseColor(display,colormap,(char *) target,&xcolor); 8684 if (status == False) 8685 ThrowXWindowException(XServerError,"ColorIsNotKnownToServer",target) 8686 else 8687 { 8688 color->red=xcolor.red; 8689 color->green=xcolor.green; 8690 color->blue=xcolor.blue; 8691 color->flags=xcolor.flags; 8692 } 8693 return(status != False ? MagickTrue : MagickFalse); 8694} 8695 8696/* 8697%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8698% % 8699% % 8700% % 8701% X Q u e r y P o s i t i o n % 8702% % 8703% % 8704% % 8705%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8706% 8707% XQueryPosition() gets the pointer coordinates relative to a window. 8708% 8709% The format of the XQueryPosition method is: 8710% 8711% void XQueryPosition(Display *display,const Window window,int *x,int *y) 8712% 8713% A description of each parameter follows: 8714% 8715% o display: Specifies a connection to an X server; returned from 8716% XOpenDisplay. 8717% 8718% o window: Specifies a pointer to a Window. 8719% 8720% o x: Return the x coordinate of the pointer relative to the origin of the 8721% window. 8722% 8723% o y: Return the y coordinate of the pointer relative to the origin of the 8724% window. 8725% 8726*/ 8727MagickPrivate void XQueryPosition(Display *display,const Window window,int *x, 8728 int *y) 8729{ 8730 int 8731 x_root, 8732 y_root; 8733 8734 unsigned int 8735 mask; 8736 8737 Window 8738 root_window; 8739 8740 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 8741 assert(display != (Display *) NULL); 8742 assert(window != (Window) NULL); 8743 assert(x != (int *) NULL); 8744 assert(y != (int *) NULL); 8745 (void) XQueryPointer(display,window,&root_window,&root_window,&x_root,&y_root, 8746 x,y,&mask); 8747} 8748 8749/* 8750%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8751% % 8752% % 8753% % 8754% X R e f r e s h W i n d o w % 8755% % 8756% % 8757% % 8758%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8759% 8760% XRefreshWindow() refreshes an image in a X window. 8761% 8762% The format of the XRefreshWindow method is: 8763% 8764% void XRefreshWindow(Display *display,const XWindowInfo *window, 8765% const XEvent *event) 8766% 8767% A description of each parameter follows: 8768% 8769% o display: Specifies a connection to an X server; returned from 8770% XOpenDisplay. 8771% 8772% o window: Specifies a pointer to a XWindowInfo structure. 8773% 8774% o event: Specifies a pointer to a XEvent structure. If it is NULL, 8775% the entire image is refreshed. 8776% 8777*/ 8778MagickPrivate void XRefreshWindow(Display *display,const XWindowInfo *window, 8779 const XEvent *event) 8780{ 8781 int 8782 x, 8783 y; 8784 8785 unsigned int 8786 height, 8787 width; 8788 8789 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 8790 assert(display != (Display *) NULL); 8791 assert(window != (XWindowInfo *) NULL); 8792 if (window->ximage == (XImage *) NULL) 8793 return; 8794 if (event != (XEvent *) NULL) 8795 { 8796 /* 8797 Determine geometry from expose event. 8798 */ 8799 x=event->xexpose.x; 8800 y=event->xexpose.y; 8801 width=(unsigned int) event->xexpose.width; 8802 height=(unsigned int) event->xexpose.height; 8803 } 8804 else 8805 { 8806 XEvent 8807 sans_event; 8808 8809 /* 8810 Refresh entire window; discard outstanding expose events. 8811 */ 8812 x=0; 8813 y=0; 8814 width=window->width; 8815 height=window->height; 8816 while (XCheckTypedWindowEvent(display,window->id,Expose,&sans_event)) ; 8817 if (window->matte_pixmap != (Pixmap) NULL) 8818 { 8819#if defined(MAGICKCORE_HAVE_SHAPE) 8820 if (window->shape != MagickFalse) 8821 XShapeCombineMask(display,window->id,ShapeBounding,0,0, 8822 window->matte_pixmap,ShapeSet); 8823#endif 8824 } 8825 } 8826 /* 8827 Check boundary conditions. 8828 */ 8829 if ((window->ximage->width-(x+window->x)) < (int) width) 8830 width=(unsigned int) (window->ximage->width-(x+window->x)); 8831 if ((window->ximage->height-(y+window->y)) < (int) height) 8832 height=(unsigned int) (window->ximage->height-(y+window->y)); 8833 /* 8834 Refresh image. 8835 */ 8836 if (window->matte_pixmap != (Pixmap) NULL) 8837 (void) XSetClipMask(display,window->annotate_context,window->matte_pixmap); 8838 if (window->pixmap != (Pixmap) NULL) 8839 { 8840 if (window->depth > 1) 8841 (void) XCopyArea(display,window->pixmap,window->id, 8842 window->annotate_context,x+window->x,y+window->y,width,height,x,y); 8843 else 8844 (void) XCopyPlane(display,window->pixmap,window->id, 8845 window->highlight_context,x+window->x,y+window->y,width,height,x,y, 8846 1L); 8847 } 8848 else 8849 { 8850#if defined(MAGICKCORE_HAVE_SHARED_MEMORY) 8851 if (window->shared_memory) 8852 (void) XShmPutImage(display,window->id,window->annotate_context, 8853 window->ximage,x+window->x,y+window->y,x,y,width,height,MagickTrue); 8854#endif 8855 if (window->shared_memory == MagickFalse) 8856 (void) XPutImage(display,window->id,window->annotate_context, 8857 window->ximage,x+window->x,y+window->y,x,y,width,height); 8858 } 8859 if (window->matte_pixmap != (Pixmap) NULL) 8860 (void) XSetClipMask(display,window->annotate_context,None); 8861 (void) XFlush(display); 8862} 8863 8864/* 8865%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8866% % 8867% % 8868% % 8869% X R e m o t e C o m m a n d % 8870% % 8871% % 8872% % 8873%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8874% 8875% XRemoteCommand() forces a remote display(1) to display the specified 8876% image filename. 8877% 8878% The format of the XRemoteCommand method is: 8879% 8880% MagickBooleanType XRemoteCommand(Display *display,const char *window, 8881% const char *filename) 8882% 8883% A description of each parameter follows: 8884% 8885% o display: Specifies a connection to an X server; returned from 8886% XOpenDisplay. 8887% 8888% o window: Specifies the name or id of an X window. 8889% 8890% o filename: the name of the image filename to display. 8891% 8892*/ 8893MagickExport MagickBooleanType XRemoteCommand(Display *display, 8894 const char *window,const char *filename) 8895{ 8896 Atom 8897 remote_atom; 8898 8899 Window 8900 remote_window, 8901 root_window; 8902 8903 assert(filename != (char *) NULL); 8904 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename); 8905 if (display == (Display *) NULL) 8906 display=XOpenDisplay((char *) NULL); 8907 if (display == (Display *) NULL) 8908 { 8909 ThrowXWindowException(XServerError,"UnableToOpenXServer",filename); 8910 return(MagickFalse); 8911 } 8912 remote_atom=XInternAtom(display,"IM_PROTOCOLS",MagickFalse); 8913 remote_window=(Window) NULL; 8914 root_window=XRootWindow(display,XDefaultScreen(display)); 8915 if (window != (char *) NULL) 8916 { 8917 /* 8918 Search window hierarchy and identify any clients by name or ID. 8919 */ 8920 if (isdigit((int) ((unsigned char) *window)) != 0) 8921 remote_window=XWindowByID(display,root_window,(Window) 8922 strtol((char *) window,(char **) NULL,0)); 8923 if (remote_window == (Window) NULL) 8924 remote_window=XWindowByName(display,root_window,window); 8925 } 8926 if (remote_window == (Window) NULL) 8927 remote_window=XWindowByProperty(display,root_window,remote_atom); 8928 if (remote_window == (Window) NULL) 8929 { 8930 ThrowXWindowException(XServerError,"UnableToConnectToRemoteDisplay", 8931 filename); 8932 return(MagickFalse); 8933 } 8934 /* 8935 Send remote command. 8936 */ 8937 remote_atom=XInternAtom(display,"IM_REMOTE_COMMAND",MagickFalse); 8938 (void) XChangeProperty(display,remote_window,remote_atom,XA_STRING,8, 8939 PropModeReplace,(unsigned char *) filename,(int) strlen(filename)); 8940 (void) XSync(display,MagickFalse); 8941 return(MagickTrue); 8942} 8943 8944/* 8945%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8946% % 8947% % 8948% % 8949% X R e n d e r I m a g e % 8950% % 8951% % 8952% % 8953%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8954% 8955% XRenderImage() renders text on the image with an X11 font. It also returns 8956% the bounding box of the text relative to the image. 8957% 8958% The format of the XRenderImage method is: 8959% 8960% MagickBooleanType XRenderImage(Image *image,DrawInfo *draw_info, 8961% const PointInfo *offset,TypeMetric *metrics,ExceptionInfo *exception) 8962% 8963% A description of each parameter follows: 8964% 8965% o image: the image. 8966% 8967% o draw_info: the draw info. 8968% 8969% o offset: (x,y) location of text relative to image. 8970% 8971% o metrics: bounding box of text. 8972% 8973% o exception: return any errors or warnings in this structure. 8974% 8975*/ 8976MagickPrivate MagickBooleanType XRenderImage(Image *image, 8977 const DrawInfo *draw_info,const PointInfo *offset,TypeMetric *metrics, 8978 ExceptionInfo *exception) 8979{ 8980 const char 8981 *client_name; 8982 8983 DrawInfo 8984 cache_info; 8985 8986 Display 8987 *display; 8988 8989 ImageInfo 8990 *image_info; 8991 8992 MagickBooleanType 8993 status; 8994 8995 size_t 8996 height, 8997 width; 8998 8999 XAnnotateInfo 9000 annotate_info; 9001 9002 XFontStruct 9003 *font_info; 9004 9005 XPixelInfo 9006 pixel; 9007 9008 XResourceInfo 9009 resource_info; 9010 9011 XrmDatabase 9012 resource_database; 9013 9014 XStandardColormap 9015 *map_info; 9016 9017 XVisualInfo 9018 *visual_info; 9019 9020 /* 9021 Open X server connection. 9022 */ 9023 display=XOpenDisplay(draw_info->server_name); 9024 if (display == (Display *) NULL) 9025 { 9026 ThrowXWindowException(XServerError,"UnableToOpenXServer", 9027 draw_info->server_name); 9028 return(MagickFalse); 9029 } 9030 /* 9031 Get user defaults from X resource database. 9032 */ 9033 (void) XSetErrorHandler(XError); 9034 image_info=AcquireImageInfo(); 9035 client_name=GetClientName(); 9036 resource_database=XGetResourceDatabase(display,client_name); 9037 XGetResourceInfo(image_info,resource_database,client_name,&resource_info); 9038 resource_info.close_server=MagickFalse; 9039 resource_info.colormap=PrivateColormap; 9040 resource_info.font=AcquireString(draw_info->font); 9041 resource_info.background_color=AcquireString("#ffffffffffff"); 9042 resource_info.foreground_color=AcquireString("#000000000000"); 9043 map_info=XAllocStandardColormap(); 9044 visual_info=(XVisualInfo *) NULL; 9045 font_info=(XFontStruct *) NULL; 9046 pixel.pixels=(unsigned long *) NULL; 9047 if (map_info == (XStandardColormap *) NULL) 9048 { 9049 ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed", 9050 image->filename); 9051 return(MagickFalse); 9052 } 9053 /* 9054 Initialize visual info. 9055 */ 9056 visual_info=XBestVisualInfo(display,map_info,&resource_info); 9057 if (visual_info == (XVisualInfo *) NULL) 9058 { 9059 XFreeResources(display,visual_info,map_info,&pixel,font_info, 9060 &resource_info,(XWindowInfo *) NULL); 9061 ThrowXWindowException(XServerError,"UnableToGetVisual",image->filename); 9062 return(MagickFalse); 9063 } 9064 map_info->colormap=(Colormap) NULL; 9065 /* 9066 Initialize Standard Colormap info. 9067 */ 9068 XGetMapInfo(visual_info,XDefaultColormap(display,visual_info->screen), 9069 map_info); 9070 XGetPixelInfo(display,visual_info,map_info,&resource_info,(Image *) NULL, 9071 &pixel); 9072 pixel.annotate_context=XDefaultGC(display,visual_info->screen); 9073 /* 9074 Initialize font info. 9075 */ 9076 font_info=XBestFont(display,&resource_info,MagickFalse); 9077 if (font_info == (XFontStruct *) NULL) 9078 { 9079 XFreeResources(display,visual_info,map_info,&pixel,font_info, 9080 &resource_info,(XWindowInfo *) NULL); 9081 ThrowXWindowException(XServerError,"UnableToLoadFont",draw_info->font); 9082 return(MagickFalse); 9083 } 9084 cache_info=(*draw_info); 9085 /* 9086 Initialize annotate info. 9087 */ 9088 XGetAnnotateInfo(&annotate_info); 9089 annotate_info.stencil=ForegroundStencil; 9090 if (cache_info.font != draw_info->font) 9091 { 9092 /* 9093 Type name has changed. 9094 */ 9095 (void) XFreeFont(display,font_info); 9096 (void) CloneString(&resource_info.font,draw_info->font); 9097 font_info=XBestFont(display,&resource_info,MagickFalse); 9098 if (font_info == (XFontStruct *) NULL) 9099 { 9100 ThrowXWindowException(XServerError,"UnableToLoadFont", 9101 draw_info->font); 9102 return(MagickFalse); 9103 } 9104 } 9105 if (image->debug != MagickFalse) 9106 (void) LogMagickEvent(AnnotateEvent,GetMagickModule(), 9107 "Font %s; pointsize %g",draw_info->font != (char *) NULL ? 9108 draw_info->font : "none",draw_info->pointsize); 9109 cache_info=(*draw_info); 9110 annotate_info.font_info=font_info; 9111 annotate_info.text=(char *) draw_info->text; 9112 annotate_info.width=(unsigned int) XTextWidth(font_info,draw_info->text,(int) 9113 strlen(draw_info->text)); 9114 annotate_info.height=(unsigned int) font_info->ascent+font_info->descent; 9115 metrics->pixels_per_em.x=(double) font_info->max_bounds.width; 9116 metrics->pixels_per_em.y=(double) font_info->ascent+font_info->descent; 9117 metrics->ascent=(double) font_info->ascent+4; 9118 metrics->descent=(double) (-font_info->descent); 9119 metrics->width=annotate_info.width/ExpandAffine(&draw_info->affine); 9120 metrics->height=font_info->ascent+font_info->descent; 9121 metrics->max_advance=(double) font_info->max_bounds.width; 9122 metrics->bounds.x1=0.0; 9123 metrics->bounds.y1=metrics->descent; 9124 metrics->bounds.x2=metrics->ascent+metrics->descent; 9125 metrics->bounds.y2=metrics->ascent+metrics->descent; 9126 metrics->underline_position=(-2.0); 9127 metrics->underline_thickness=1.0; 9128 if (draw_info->render == MagickFalse) 9129 return(MagickTrue); 9130 if (draw_info->fill.alpha == TransparentAlpha) 9131 return(MagickTrue); 9132 /* 9133 Render fill color. 9134 */ 9135 width=annotate_info.width; 9136 height=annotate_info.height; 9137 if ((fabs(draw_info->affine.rx) >= MagickEpsilon) || 9138 (fabs(draw_info->affine.ry) >= MagickEpsilon)) 9139 { 9140 if ((fabs(draw_info->affine.sx-draw_info->affine.sy) < MagickEpsilon) && 9141 (fabs(draw_info->affine.rx+draw_info->affine.ry) < MagickEpsilon)) 9142 annotate_info.degrees=(double) (180.0/MagickPI)* 9143 atan2(draw_info->affine.rx,draw_info->affine.sx); 9144 } 9145 (void) FormatLocaleString(annotate_info.geometry,MagickPathExtent, 9146 "%.20gx%.20g%+.20g%+.20g",(double) width,(double) height, 9147 ceil(offset->x-0.5),ceil(offset->y-metrics->ascent-metrics->descent+ 9148 draw_info->interline_spacing-0.5)); 9149 pixel.pen_color.red=ScaleQuantumToShort(draw_info->fill.red); 9150 pixel.pen_color.green=ScaleQuantumToShort(draw_info->fill.green); 9151 pixel.pen_color.blue=ScaleQuantumToShort(draw_info->fill.blue); 9152 status=XAnnotateImage(display,&pixel,&annotate_info,image,exception); 9153 if (status == 0) 9154 { 9155 ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed", 9156 image->filename); 9157 return(MagickFalse); 9158 } 9159 return(MagickTrue); 9160} 9161 9162/* 9163%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9164% % 9165% % 9166% % 9167% X R e t a i n W i n d o w C o l o r s % 9168% % 9169% % 9170% % 9171%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9172% 9173% XRetainWindowColors() sets X11 color resources on a window. This preserves 9174% the colors associated with an image displayed on the window. 9175% 9176% The format of the XRetainWindowColors method is: 9177% 9178% void XRetainWindowColors(Display *display,const Window window) 9179% 9180% A description of each parameter follows: 9181% 9182% o display: Specifies a connection to an X server; returned from 9183% XOpenDisplay. 9184% 9185% o window: Specifies a pointer to a XWindowInfo structure. 9186% 9187*/ 9188MagickExport void XRetainWindowColors(Display *display,const Window window) 9189{ 9190 Atom 9191 property; 9192 9193 Pixmap 9194 pixmap; 9195 9196 /* 9197 Put property on the window. 9198 */ 9199 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 9200 assert(display != (Display *) NULL); 9201 assert(window != (Window) NULL); 9202 property=XInternAtom(display,"_XSETROOT_ID",MagickFalse); 9203 if (property == (Atom) NULL) 9204 { 9205 ThrowXWindowException(XServerError,"UnableToCreateProperty", 9206 "_XSETROOT_ID"); 9207 return; 9208 } 9209 pixmap=XCreatePixmap(display,window,1,1,1); 9210 if (pixmap == (Pixmap) NULL) 9211 { 9212 ThrowXWindowException(XServerError,"UnableToCreateBitmap",""); 9213 return; 9214 } 9215 (void) XChangeProperty(display,window,property,XA_PIXMAP,32,PropModeReplace, 9216 (unsigned char *) &pixmap,1); 9217 (void) XSetCloseDownMode(display,RetainPermanent); 9218} 9219 9220/* 9221%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9222% % 9223% % 9224% % 9225% X S e l e c t W i n d o w % 9226% % 9227% % 9228% % 9229%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9230% 9231% XSelectWindow() allows a user to select a window using the mouse. If the 9232% mouse moves, a cropping rectangle is drawn and the extents of the rectangle 9233% is returned in the crop_info structure. 9234% 9235% The format of the XSelectWindow function is: 9236% 9237% target_window=XSelectWindow(display,crop_info) 9238% 9239% A description of each parameter follows: 9240% 9241% o window: XSelectWindow returns the window id. 9242% 9243% o display: Specifies a pointer to the Display structure; returned from 9244% XOpenDisplay. 9245% 9246% o crop_info: Specifies a pointer to a RectangleInfo structure. It 9247% contains the extents of any cropping rectangle. 9248% 9249*/ 9250static Window XSelectWindow(Display *display,RectangleInfo *crop_info) 9251{ 9252#define MinimumCropArea (unsigned int) 9 9253 9254 Cursor 9255 target_cursor; 9256 9257 GC 9258 annotate_context; 9259 9260 int 9261 presses, 9262 x_offset, 9263 y_offset; 9264 9265 Status 9266 status; 9267 9268 Window 9269 root_window, 9270 target_window; 9271 9272 XEvent 9273 event; 9274 9275 XGCValues 9276 context_values; 9277 9278 /* 9279 Initialize graphic context. 9280 */ 9281 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 9282 assert(display != (Display *) NULL); 9283 assert(crop_info != (RectangleInfo *) NULL); 9284 root_window=XRootWindow(display,XDefaultScreen(display)); 9285 context_values.background=XBlackPixel(display,XDefaultScreen(display)); 9286 context_values.foreground=XWhitePixel(display,XDefaultScreen(display)); 9287 context_values.function=GXinvert; 9288 context_values.plane_mask= 9289 context_values.background ^ context_values.foreground; 9290 context_values.subwindow_mode=IncludeInferiors; 9291 annotate_context=XCreateGC(display,root_window,(size_t) (GCBackground | 9292 GCForeground | GCFunction | GCSubwindowMode),&context_values); 9293 if (annotate_context == (GC) NULL) 9294 return(MagickFalse); 9295 /* 9296 Grab the pointer using target cursor. 9297 */ 9298 target_cursor=XMakeCursor(display,root_window,XDefaultColormap(display, 9299 XDefaultScreen(display)),(char * ) "white",(char * ) "black"); 9300 status=XGrabPointer(display,root_window,MagickFalse,(unsigned int) 9301 (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask),GrabModeSync, 9302 GrabModeAsync,root_window,target_cursor,CurrentTime); 9303 if (status != GrabSuccess) 9304 { 9305 ThrowXWindowException(XServerError,"UnableToGrabMouse",""); 9306 return((Window) NULL); 9307 } 9308 /* 9309 Select a window. 9310 */ 9311 crop_info->width=0; 9312 crop_info->height=0; 9313 presses=0; 9314 target_window=(Window) NULL; 9315 x_offset=0; 9316 y_offset=0; 9317 do 9318 { 9319 if ((crop_info->width*crop_info->height) >= MinimumCropArea) 9320 (void) XDrawRectangle(display,root_window,annotate_context, 9321 (int) crop_info->x,(int) crop_info->y,(unsigned int) crop_info->width-1, 9322 (unsigned int) crop_info->height-1); 9323 /* 9324 Allow another event. 9325 */ 9326 (void) XAllowEvents(display,SyncPointer,CurrentTime); 9327 (void) XWindowEvent(display,root_window,ButtonPressMask | 9328 ButtonReleaseMask | ButtonMotionMask,&event); 9329 if ((crop_info->width*crop_info->height) >= MinimumCropArea) 9330 (void) XDrawRectangle(display,root_window,annotate_context, 9331 (int) crop_info->x,(int) crop_info->y,(unsigned int) crop_info->width-1, 9332 (unsigned int) crop_info->height-1); 9333 switch (event.type) 9334 { 9335 case ButtonPress: 9336 { 9337 target_window=XGetSubwindow(display,event.xbutton.subwindow, 9338 event.xbutton.x,event.xbutton.y); 9339 if (target_window == (Window) NULL) 9340 target_window=root_window; 9341 x_offset=event.xbutton.x_root; 9342 y_offset=event.xbutton.y_root; 9343 crop_info->x=(ssize_t) x_offset; 9344 crop_info->y=(ssize_t) y_offset; 9345 crop_info->width=0; 9346 crop_info->height=0; 9347 presses++; 9348 break; 9349 } 9350 case ButtonRelease: 9351 { 9352 presses--; 9353 break; 9354 } 9355 case MotionNotify: 9356 { 9357 /* 9358 Discard pending button motion events. 9359 */ 9360 while (XCheckMaskEvent(display,ButtonMotionMask,&event)) ; 9361 crop_info->x=(ssize_t) event.xmotion.x; 9362 crop_info->y=(ssize_t) event.xmotion.y; 9363 /* 9364 Check boundary conditions. 9365 */ 9366 if ((int) crop_info->x < x_offset) 9367 crop_info->width=(size_t) (x_offset-crop_info->x); 9368 else 9369 { 9370 crop_info->width=(size_t) (crop_info->x-x_offset); 9371 crop_info->x=(ssize_t) x_offset; 9372 } 9373 if ((int) crop_info->y < y_offset) 9374 crop_info->height=(size_t) (y_offset-crop_info->y); 9375 else 9376 { 9377 crop_info->height=(size_t) (crop_info->y-y_offset); 9378 crop_info->y=(ssize_t) y_offset; 9379 } 9380 } 9381 default: 9382 break; 9383 } 9384 } while ((target_window == (Window) NULL) || (presses > 0)); 9385 (void) XUngrabPointer(display,CurrentTime); 9386 (void) XFreeCursor(display,target_cursor); 9387 (void) XFreeGC(display,annotate_context); 9388 if ((crop_info->width*crop_info->height) < MinimumCropArea) 9389 { 9390 crop_info->width=0; 9391 crop_info->height=0; 9392 } 9393 if ((crop_info->width != 0) && (crop_info->height != 0)) 9394 target_window=root_window; 9395 return(target_window); 9396} 9397 9398/* 9399%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9400% % 9401% % 9402% % 9403% X S e t C u r s o r S t a t e % 9404% % 9405% % 9406% % 9407%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9408% 9409% XSetCursorState() sets the cursor state to busy, otherwise the cursor are 9410% reset to their default. 9411% 9412% The format of the XXSetCursorState method is: 9413% 9414% XSetCursorState(display,windows,const MagickStatusType state) 9415% 9416% A description of each parameter follows: 9417% 9418% o display: Specifies a connection to an X server; returned from 9419% XOpenDisplay. 9420% 9421% o windows: Specifies a pointer to a XWindows structure. 9422% 9423% o state: An unsigned integer greater than 0 sets the cursor state 9424% to busy, otherwise the cursor are reset to their default. 9425% 9426*/ 9427MagickPrivate void XSetCursorState(Display *display,XWindows *windows, 9428 const MagickStatusType state) 9429{ 9430 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 9431 assert(display != (Display *) NULL); 9432 assert(windows != (XWindows *) NULL); 9433 if (state) 9434 { 9435 (void) XCheckDefineCursor(display,windows->image.id, 9436 windows->image.busy_cursor); 9437 (void) XCheckDefineCursor(display,windows->pan.id, 9438 windows->pan.busy_cursor); 9439 (void) XCheckDefineCursor(display,windows->magnify.id, 9440 windows->magnify.busy_cursor); 9441 (void) XCheckDefineCursor(display,windows->command.id, 9442 windows->command.busy_cursor); 9443 } 9444 else 9445 { 9446 (void) XCheckDefineCursor(display,windows->image.id, 9447 windows->image.cursor); 9448 (void) XCheckDefineCursor(display,windows->pan.id,windows->pan.cursor); 9449 (void) XCheckDefineCursor(display,windows->magnify.id, 9450 windows->magnify.cursor); 9451 (void) XCheckDefineCursor(display,windows->command.id, 9452 windows->command.cursor); 9453 (void) XCheckDefineCursor(display,windows->command.id, 9454 windows->widget.cursor); 9455 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen); 9456 } 9457 windows->info.mapped=MagickFalse; 9458} 9459 9460/* 9461%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9462% % 9463% % 9464% % 9465% X S e t W i n d o w s % 9466% % 9467% % 9468% % 9469%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9470% 9471% XSetWindows() sets the X windows structure if the windows info is specified. 9472% Otherwise the current windows structure is returned. 9473% 9474% The format of the XSetWindows method is: 9475% 9476% XWindows *XSetWindows(XWindows *windows_info) 9477% 9478% A description of each parameter follows: 9479% 9480% o windows_info: Initialize the Windows structure with this information. 9481% 9482*/ 9483MagickPrivate XWindows *XSetWindows(XWindows *windows_info) 9484{ 9485 static XWindows 9486 *windows = (XWindows *) NULL; 9487 9488 if (windows_info != (XWindows *) ~0) 9489 { 9490 windows=(XWindows *) RelinquishMagickMemory(windows); 9491 windows=windows_info; 9492 } 9493 return(windows); 9494} 9495/* 9496%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9497% % 9498% % 9499% % 9500% X U s e r P r e f e r e n c e s % 9501% % 9502% % 9503% % 9504%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9505% 9506% XUserPreferences() saves the preferences in a configuration file in the 9507% users' home directory. 9508% 9509% The format of the XUserPreferences method is: 9510% 9511% void XUserPreferences(XResourceInfo *resource_info) 9512% 9513% A description of each parameter follows: 9514% 9515% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. 9516% 9517*/ 9518MagickPrivate void XUserPreferences(XResourceInfo *resource_info) 9519{ 9520#if defined(X11_PREFERENCES_PATH) 9521 char 9522 cache[MagickPathExtent], 9523 filename[MagickPathExtent], 9524 specifier[MagickPathExtent]; 9525 9526 const char 9527 *client_name, 9528 *value; 9529 9530 XrmDatabase 9531 preferences_database; 9532 9533 /* 9534 Save user preferences to the client configuration file. 9535 */ 9536 assert(resource_info != (XResourceInfo *) NULL); 9537 client_name=GetClientName(); 9538 preferences_database=XrmGetStringDatabase(""); 9539 (void) FormatLocaleString(specifier,MagickPathExtent,"%s.backdrop",client_name); 9540 value=resource_info->backdrop ? "True" : "False"; 9541 XrmPutStringResource(&preferences_database,specifier,(char *) value); 9542 (void) FormatLocaleString(specifier,MagickPathExtent,"%s.colormap",client_name); 9543 value=resource_info->colormap == SharedColormap ? "Shared" : "Private"; 9544 XrmPutStringResource(&preferences_database,specifier,(char *) value); 9545 (void) FormatLocaleString(specifier,MagickPathExtent,"%s.confirmExit", 9546 client_name); 9547 value=resource_info->confirm_exit ? "True" : "False"; 9548 XrmPutStringResource(&preferences_database,specifier,(char *) value); 9549 (void) FormatLocaleString(specifier,MagickPathExtent,"%s.confirmEdit", 9550 client_name); 9551 value=resource_info->confirm_edit ? "True" : "False"; 9552 XrmPutStringResource(&preferences_database,specifier,(char *) value); 9553 (void) FormatLocaleString(specifier,MagickPathExtent,"%s.displayWarnings", 9554 client_name); 9555 value=resource_info->display_warnings ? "True" : "False"; 9556 XrmPutStringResource(&preferences_database,specifier,(char *) value); 9557 (void) FormatLocaleString(specifier,MagickPathExtent,"%s.dither",client_name); 9558 value=resource_info->quantize_info->dither_method != NoDitherMethod ? 9559 "True" : "False"; 9560 XrmPutStringResource(&preferences_database,specifier,(char *) value); 9561 (void) FormatLocaleString(specifier,MagickPathExtent,"%s.gammaCorrect", 9562 client_name); 9563 value=resource_info->gamma_correct ? "True" : "False"; 9564 XrmPutStringResource(&preferences_database,specifier,(char *) value); 9565 (void) FormatLocaleString(specifier,MagickPathExtent,"%s.undoCache",client_name); 9566 (void) FormatLocaleString(cache,MagickPathExtent,"%.20g",(double) 9567 resource_info->undo_cache); 9568 XrmPutStringResource(&preferences_database,specifier,cache); 9569 (void) FormatLocaleString(specifier,MagickPathExtent,"%s.usePixmap",client_name); 9570 value=resource_info->use_pixmap ? "True" : "False"; 9571 XrmPutStringResource(&preferences_database,specifier,(char *) value); 9572 (void) FormatLocaleString(filename,MagickPathExtent,"%s%src", 9573 X11_PREFERENCES_PATH,client_name); 9574 ExpandFilename(filename); 9575 XrmPutFileDatabase(preferences_database,filename); 9576#endif 9577} 9578 9579/* 9580%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9581% % 9582% % 9583% % 9584% X V i s u a l C l a s s N a m e % 9585% % 9586% % 9587% % 9588%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9589% 9590% XVisualClassName() returns the visual class name as a character string. 9591% 9592% The format of the XVisualClassName method is: 9593% 9594% char *XVisualClassName(const int visual_class) 9595% 9596% A description of each parameter follows: 9597% 9598% o visual_type: XVisualClassName returns the visual class as a character 9599% string. 9600% 9601% o class: Specifies the visual class. 9602% 9603*/ 9604static const char *XVisualClassName(const int visual_class) 9605{ 9606 switch (visual_class) 9607 { 9608 case StaticGray: return("StaticGray"); 9609 case GrayScale: return("GrayScale"); 9610 case StaticColor: return("StaticColor"); 9611 case PseudoColor: return("PseudoColor"); 9612 case TrueColor: return("TrueColor"); 9613 case DirectColor: return("DirectColor"); 9614 } 9615 return("unknown visual class"); 9616} 9617 9618/* 9619%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9620% % 9621% % 9622% % 9623% X W a r n i n g % 9624% % 9625% % 9626% % 9627%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9628% 9629% XWarning() displays a warning reason in a Notice widget. 9630% 9631% The format of the XWarning method is: 9632% 9633% void XWarning(const unsigned int warning,const char *reason, 9634% const char *description) 9635% 9636% A description of each parameter follows: 9637% 9638% o warning: Specifies the numeric warning category. 9639% 9640% o reason: Specifies the reason to display before terminating the 9641% program. 9642% 9643% o description: Specifies any description to the reason. 9644% 9645*/ 9646MagickPrivate void XWarning(const ExceptionType magick_unused(warning), 9647 const char *reason,const char *description) 9648{ 9649 char 9650 text[MagickPathExtent]; 9651 9652 XWindows 9653 *windows; 9654 9655 if (reason == (char *) NULL) 9656 return; 9657 (void) CopyMagickString(text,reason,MagickPathExtent); 9658 (void) ConcatenateMagickString(text,":",MagickPathExtent); 9659 windows=XSetWindows((XWindows *) ~0); 9660 XNoticeWidget(windows->display,windows,text,(char *) description); 9661} 9662 9663/* 9664%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9665% % 9666% % 9667% % 9668% X W i n d o w B y I D % 9669% % 9670% % 9671% % 9672%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9673% 9674% XWindowByID() locates a child window with a given ID. If not window with 9675% the given name is found, 0 is returned. Only the window specified and its 9676% subwindows are searched. 9677% 9678% The format of the XWindowByID function is: 9679% 9680% child=XWindowByID(display,window,id) 9681% 9682% A description of each parameter follows: 9683% 9684% o child: XWindowByID returns the window with the specified 9685% id. If no windows are found, XWindowByID returns 0. 9686% 9687% o display: Specifies a pointer to the Display structure; returned from 9688% XOpenDisplay. 9689% 9690% o id: Specifies the id of the window to locate. 9691% 9692*/ 9693MagickPrivate Window XWindowByID(Display *display,const Window root_window, 9694 const size_t id) 9695{ 9696 RectangleInfo 9697 rectangle_info; 9698 9699 register int 9700 i; 9701 9702 Status 9703 status; 9704 9705 unsigned int 9706 number_children; 9707 9708 Window 9709 child, 9710 *children, 9711 window; 9712 9713 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 9714 assert(display != (Display *) NULL); 9715 assert(root_window != (Window) NULL); 9716 if (id == 0) 9717 return(XSelectWindow(display,&rectangle_info)); 9718 if (root_window == id) 9719 return(root_window); 9720 status=XQueryTree(display,root_window,&child,&child,&children, 9721 &number_children); 9722 if (status == False) 9723 return((Window) NULL); 9724 window=(Window) NULL; 9725 for (i=0; i < (int) number_children; i++) 9726 { 9727 /* 9728 Search each child and their children. 9729 */ 9730 window=XWindowByID(display,children[i],id); 9731 if (window != (Window) NULL) 9732 break; 9733 } 9734 if (children != (Window *) NULL) 9735 (void) XFree((void *) children); 9736 return(window); 9737} 9738 9739/* 9740%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9741% % 9742% % 9743% % 9744% X W i n d o w B y N a m e % 9745% % 9746% % 9747% % 9748%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9749% 9750% XWindowByName() locates a window with a given name on a display. If no 9751% window with the given name is found, 0 is returned. If more than one window 9752% has the given name, the first one is returned. Only root and its children 9753% are searched. 9754% 9755% The format of the XWindowByName function is: 9756% 9757% window=XWindowByName(display,root_window,name) 9758% 9759% A description of each parameter follows: 9760% 9761% o window: XWindowByName returns the window id. 9762% 9763% o display: Specifies a pointer to the Display structure; returned from 9764% XOpenDisplay. 9765% 9766% o root_window: Specifies the id of the root window. 9767% 9768% o name: Specifies the name of the window to locate. 9769% 9770*/ 9771MagickPrivate Window XWindowByName(Display *display,const Window root_window, 9772 const char *name) 9773{ 9774 register int 9775 i; 9776 9777 Status 9778 status; 9779 9780 unsigned int 9781 number_children; 9782 9783 Window 9784 *children, 9785 child, 9786 window; 9787 9788 XTextProperty 9789 window_name; 9790 9791 assert(display != (Display *) NULL); 9792 assert(root_window != (Window) NULL); 9793 assert(name != (char *) NULL); 9794 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name); 9795 if (XGetWMName(display,root_window,&window_name) != 0) 9796 if (LocaleCompare((char *) window_name.value,name) == 0) 9797 return(root_window); 9798 status=XQueryTree(display,root_window,&child,&child,&children, 9799 &number_children); 9800 if (status == False) 9801 return((Window) NULL); 9802 window=(Window) NULL; 9803 for (i=0; i < (int) number_children; i++) 9804 { 9805 /* 9806 Search each child and their children. 9807 */ 9808 window=XWindowByName(display,children[i],name); 9809 if (window != (Window) NULL) 9810 break; 9811 } 9812 if (children != (Window *) NULL) 9813 (void) XFree((void *) children); 9814 return(window); 9815} 9816 9817/* 9818%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9819% % 9820% % 9821% % 9822% X W i n d o w B y P r o p e r y % 9823% % 9824% % 9825% % 9826%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9827% 9828% XWindowByProperty() locates a child window with a given property. If not 9829% window with the given name is found, 0 is returned. If more than one window 9830% has the given property, the first one is returned. Only the window 9831% specified and its subwindows are searched. 9832% 9833% The format of the XWindowByProperty function is: 9834% 9835% child=XWindowByProperty(display,window,property) 9836% 9837% A description of each parameter follows: 9838% 9839% o child: XWindowByProperty returns the window id with the specified 9840% property. If no windows are found, XWindowByProperty returns 0. 9841% 9842% o display: Specifies a pointer to the Display structure; returned from 9843% XOpenDisplay. 9844% 9845% o property: Specifies the property of the window to locate. 9846% 9847*/ 9848MagickPrivate Window XWindowByProperty(Display *display,const Window window, 9849 const Atom property) 9850{ 9851 Atom 9852 type; 9853 9854 int 9855 format; 9856 9857 Status 9858 status; 9859 9860 unsigned char 9861 *data; 9862 9863 unsigned int 9864 i, 9865 number_children; 9866 9867 unsigned long 9868 after, 9869 number_items; 9870 9871 Window 9872 child, 9873 *children, 9874 parent, 9875 root; 9876 9877 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 9878 assert(display != (Display *) NULL); 9879 assert(window != (Window) NULL); 9880 assert(property != (Atom) NULL); 9881 status=XQueryTree(display,window,&root,&parent,&children,&number_children); 9882 if (status == False) 9883 return((Window) NULL); 9884 type=(Atom) NULL; 9885 child=(Window) NULL; 9886 for (i=0; (i < number_children) && (child == (Window) NULL); i++) 9887 { 9888 status=XGetWindowProperty(display,children[i],property,0L,0L,MagickFalse, 9889 (Atom) AnyPropertyType,&type,&format,&number_items,&after,&data); 9890 if (data != NULL) 9891 (void) XFree((void *) data); 9892 if ((status == Success) && (type != (Atom) NULL)) 9893 child=children[i]; 9894 } 9895 for (i=0; (i < number_children) && (child == (Window) NULL); i++) 9896 child=XWindowByProperty(display,children[i],property); 9897 if (children != (Window *) NULL) 9898 (void) XFree((void *) children); 9899 return(child); 9900} 9901#else 9902 9903/* 9904%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9905% % 9906% % 9907% % 9908% X I m p o r t I m a g e % 9909% % 9910% % 9911% % 9912%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9913% 9914% XImportImage() reads an image from an X window. 9915% 9916% The format of the XImportImage method is: 9917% 9918% Image *XImportImage(const ImageInfo *image_info,XImportInfo *ximage_info, 9919% ExceptionInfo *exception) 9920% 9921% A description of each parameter follows: 9922% 9923% o image_info: the image info.. 9924% 9925% o ximage_info: Specifies a pointer to an XImportInfo structure. 9926% 9927% o exception: return any errors or warnings in this structure. 9928% 9929*/ 9930MagickExport Image *XImportImage(const ImageInfo *image_info, 9931 XImportInfo *ximage_info,ExceptionInfo *exception) 9932{ 9933 assert(image_info != (const ImageInfo *) NULL); 9934 assert(image_info->signature == MagickCoreSignature); 9935 if (image_info->debug != MagickFalse) 9936 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", 9937 image_info->filename); 9938 assert(ximage_info != (XImportInfo *) NULL); 9939 assert(exception != (ExceptionInfo *) NULL); 9940 assert(exception->signature == MagickCoreSignature); 9941 return((Image *) NULL); 9942} 9943 9944/* 9945%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9946% % 9947% % 9948% % 9949% X R e n d e r X 1 1 % 9950% % 9951% % 9952% % 9953%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9954% 9955% XRenderImage() renders text on the image with an X11 font. It also returns 9956% the bounding box of the text relative to the image. 9957% 9958% The format of the XRenderImage method is: 9959% 9960% MagickBooleanType XRenderImage(Image *image,DrawInfo *draw_info, 9961% const PointInfo *offset,TypeMetric *metrics,ExceptionInfo *exception) 9962% 9963% A description of each parameter follows: 9964% 9965% o image: the image. 9966% 9967% o draw_info: the draw info. 9968% 9969% o offset: (x,y) location of text relative to image. 9970% 9971% o metrics: bounding box of text. 9972% 9973% o exception: return any errors or warnings in this structure. 9974% 9975*/ 9976MagickPrivate MagickBooleanType XRenderImage(Image *image, 9977 const DrawInfo *draw_info,const PointInfo *offset,TypeMetric *metrics, 9978 ExceptionInfo *exception) 9979{ 9980 (void) draw_info; 9981 (void) offset; 9982 (void) metrics; 9983 (void) ThrowMagickException(exception,GetMagickModule(), 9984 MissingDelegateError,"DelegateLibrarySupportNotBuiltIn","'%s' (X11)", 9985 image->filename); 9986 return(MagickFalse); 9987} 9988#endif 9989 9990/* 9991%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9992% % 9993% % 9994% % 9995+ X C o m p o n e n t G e n e s i s % 9996% % 9997% % 9998% % 9999%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 10000% 10001% XComponentGenesis() instantiates the X component. 10002% 10003% The format of the XComponentGenesis method is: 10004% 10005% MagickBooleanType XComponentGenesis(void) 10006% 10007*/ 10008MagickPrivate MagickBooleanType XComponentGenesis(void) 10009{ 10010 return(MagickTrue); 10011} 10012 10013/* 10014%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 10015% % 10016% % 10017% % 10018% X G e t I m p o r t I n f o % 10019% % 10020% % 10021% % 10022%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 10023% 10024% XGetImportInfo() initializes the XImportInfo structure. 10025% 10026% The format of the XGetImportInfo method is: 10027% 10028% void XGetImportInfo(XImportInfo *ximage_info) 10029% 10030% A description of each parameter follows: 10031% 10032% o ximage_info: Specifies a pointer to an ImageInfo structure. 10033% 10034*/ 10035MagickExport void XGetImportInfo(XImportInfo *ximage_info) 10036{ 10037 assert(ximage_info != (XImportInfo *) NULL); 10038 ximage_info->frame=MagickFalse; 10039 ximage_info->borders=MagickFalse; 10040 ximage_info->screen=MagickFalse; 10041 ximage_info->descend=MagickTrue; 10042 ximage_info->silent=MagickFalse; 10043} 10044