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