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