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