|
MagickCore
6.7.5
|
00001 /* 00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00003 % % 00004 % % 00005 % % 00006 % AAA N N IIIII M M AAA TTTTT EEEEE % 00007 % A A NN N I MM MM A A T E % 00008 % AAAAA N N N I M M M AAAAA T EEE % 00009 % A A N NN I M M A A T E % 00010 % A A N N IIIII M M A A T EEEEE % 00011 % % 00012 % % 00013 % Methods to Interactively Animate an Image Sequence % 00014 % % 00015 % Software Design % 00016 % John Cristy % 00017 % July 1992 % 00018 % % 00019 % % 00020 % Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization % 00021 % dedicated to making software imaging solutions freely available. % 00022 % % 00023 % You may not use this file except in compliance with the License. You may % 00024 % obtain a copy of the License at % 00025 % % 00026 % http://www.imagemagick.org/script/license.php % 00027 % % 00028 % Unless required by applicable law or agreed to in writing, software % 00029 % distributed under the License is distributed on an "AS IS" BASIS, % 00030 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 00031 % See the License for the specific language governing permissions and % 00032 % limitations under the License. % 00033 % % 00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00035 % 00036 % 00037 */ 00038 00039 /* 00040 Include declarations. 00041 */ 00042 #include "MagickCore/studio.h" 00043 #include "MagickCore/animate.h" 00044 #include "MagickCore/animate-private.h" 00045 #include "MagickCore/client.h" 00046 #include "MagickCore/color.h" 00047 #include "MagickCore/color-private.h" 00048 #include "MagickCore/colorspace.h" 00049 #include "MagickCore/constitute.h" 00050 #include "MagickCore/delegate.h" 00051 #include "MagickCore/exception.h" 00052 #include "MagickCore/exception-private.h" 00053 #include "MagickCore/geometry.h" 00054 #include "MagickCore/image-private.h" 00055 #include "MagickCore/layer.h" 00056 #include "MagickCore/list.h" 00057 #include "MagickCore/log.h" 00058 #include "MagickCore/image.h" 00059 #include "MagickCore/memory_.h" 00060 #include "MagickCore/monitor.h" 00061 #include "MagickCore/monitor-private.h" 00062 #include "MagickCore/option.h" 00063 #include "MagickCore/pixel-accessor.h" 00064 #include "MagickCore/property.h" 00065 #include "MagickCore/resource_.h" 00066 #include "MagickCore/string_.h" 00067 #include "MagickCore/string-private.h" 00068 #include "MagickCore/transform.h" 00069 #include "MagickCore/utility.h" 00070 #include "MagickCore/utility-private.h" 00071 #include "MagickCore/version.h" 00072 #include "MagickCore/widget.h" 00073 #include "MagickCore/widget-private.h" 00074 #include "MagickCore/xwindow.h" 00075 #include "MagickCore/xwindow-private.h" 00076 00077 #if defined(MAGICKCORE_X11_DELEGATE) 00078 /* 00079 Animate state declarations. 00080 */ 00081 #define AutoReverseAnimationState 0x0004 00082 #define ForwardAnimationState 0x0008 00083 #define HighlightState 0x0010 00084 #define PlayAnimationState 0x0020 00085 #define RepeatAnimationState 0x0040 00086 #define StepAnimationState 0x0080 00087 00088 /* 00089 Static declarations. 00090 */ 00091 static const char 00092 *AnimateHelp[]= 00093 { 00094 "BUTTONS", 00095 "", 00096 " Press any button to map or unmap the Command widget.", 00097 "", 00098 "COMMAND WIDGET", 00099 " The Command widget lists a number of sub-menus and commands.", 00100 " They are", 00101 "", 00102 " Animate", 00103 " Open...", 00104 " Save...", 00105 " Play", 00106 " Step", 00107 " Repeat", 00108 " Auto Reverse", 00109 " Speed", 00110 " Slower", 00111 " Faster", 00112 " Direction", 00113 " Forward", 00114 " Reverse", 00115 " Help", 00116 " Overview", 00117 " Browse Documentation", 00118 " About Animate", 00119 " Image Info", 00120 " Quit", 00121 "", 00122 " Menu items with a indented triangle have a sub-menu. They", 00123 " are represented above as the indented items. To access a", 00124 " sub-menu item, move the pointer to the appropriate menu and", 00125 " press a button and drag. When you find the desired sub-menu", 00126 " item, release the button and the command is executed. Move", 00127 " the pointer away from the sub-menu if you decide not to", 00128 " execute a particular command.", 00129 "", 00130 "KEYBOARD ACCELERATORS", 00131 " Accelerators are one or two key presses that effect a", 00132 " particular command. The keyboard accelerators that", 00133 " animate(1) understands is:", 00134 "", 00135 " Ctl+O Press to open an image from a file.", 00136 "", 00137 " space Press to display the next image in the sequence.", 00138 "", 00139 " < Press to speed-up the display of the images. Refer to", 00140 " -delay for more information.", 00141 "", 00142 " > Press to slow the display of the images. Refer to", 00143 " -delay for more information.", 00144 "", 00145 " F1 Press to display helpful information about animate(1).", 00146 "", 00147 " Find Press to browse documentation about ImageMagick.", 00148 "", 00149 " ? Press to display information about the image. Press", 00150 " any key or button to erase the information.", 00151 "", 00152 " This information is printed: image name; image size;", 00153 " and the total number of unique colors in the image.", 00154 "", 00155 " Ctl-q Press to discard all images and exit program.", 00156 (char *) NULL 00157 }; 00158 00159 /* 00160 Constant declarations. 00161 */ 00162 static const char 00163 *PageSizes[]= 00164 { 00165 "Letter", 00166 "Tabloid", 00167 "Ledger", 00168 "Legal", 00169 "Statement", 00170 "Executive", 00171 "A3", 00172 "A4", 00173 "A5", 00174 "B4", 00175 "B5", 00176 "Folio", 00177 "Quarto", 00178 "10x14", 00179 (char *) NULL 00180 }; 00181 00182 static const unsigned char 00183 HighlightBitmap[8] = 00184 { 00185 (unsigned char) 0xaa, 00186 (unsigned char) 0x55, 00187 (unsigned char) 0xaa, 00188 (unsigned char) 0x55, 00189 (unsigned char) 0xaa, 00190 (unsigned char) 0x55, 00191 (unsigned char) 0xaa, 00192 (unsigned char) 0x55 00193 }, 00194 ShadowBitmap[8] = 00195 { 00196 (unsigned char) 0x00, 00197 (unsigned char) 0x00, 00198 (unsigned char) 0x00, 00199 (unsigned char) 0x00, 00200 (unsigned char) 0x00, 00201 (unsigned char) 0x00, 00202 (unsigned char) 0x00, 00203 (unsigned char) 0x00 00204 }; 00205 00206 /* 00207 Enumeration declarations. 00208 */ 00209 typedef enum 00210 { 00211 OpenCommand, 00212 SaveCommand, 00213 PlayCommand, 00214 StepCommand, 00215 RepeatCommand, 00216 AutoReverseCommand, 00217 SlowerCommand, 00218 FasterCommand, 00219 ForwardCommand, 00220 ReverseCommand, 00221 HelpCommand, 00222 BrowseDocumentationCommand, 00223 VersionCommand, 00224 InfoCommand, 00225 QuitCommand, 00226 StepBackwardCommand, 00227 StepForwardCommand, 00228 NullCommand 00229 } CommandType; 00230 00231 /* 00232 Stipples. 00233 */ 00234 #define HighlightWidth 8 00235 #define HighlightHeight 8 00236 #define ShadowWidth 8 00237 #define ShadowHeight 8 00238 00239 /* 00240 Forward declarations. 00241 */ 00242 static Image 00243 *XMagickCommand(Display *,XResourceInfo *,XWindows *,const CommandType, 00244 Image **,MagickStatusType *,ExceptionInfo *); 00245 00246 static MagickBooleanType 00247 XSaveImage(Display *,XResourceInfo *,XWindows *,Image *,ExceptionInfo *); 00248 00249 /* 00250 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00251 % % 00252 % % 00253 % % 00254 % A n i m a t e I m a g e s % 00255 % % 00256 % % 00257 % % 00258 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00259 % 00260 % AnimateImages() repeatedly displays an image sequence to any X window 00261 % screen. It returns a value other than 0 if successful. Check the 00262 % exception member of image to determine the reason for any failure. 00263 % 00264 % The format of the AnimateImages method is: 00265 % 00266 % MagickBooleanType AnimateImages(const ImageInfo *image_info, 00267 % Image *images,ExceptionInfo *exception) 00268 % 00269 % A description of each parameter follows: 00270 % 00271 % o image_info: the image info. 00272 % 00273 % o image: the image. 00274 % 00275 % o exception: return any errors or warnings in this structure. 00276 % 00277 */ 00278 MagickExport MagickBooleanType AnimateImages(const ImageInfo *image_info, 00279 Image *images,ExceptionInfo *exception) 00280 { 00281 char 00282 *argv[1]; 00283 00284 Display 00285 *display; 00286 00287 MagickStatusType 00288 status; 00289 00290 XrmDatabase 00291 resource_database; 00292 00293 XResourceInfo 00294 resource_info; 00295 00296 assert(image_info != (const ImageInfo *) NULL); 00297 assert(image_info->signature == MagickSignature); 00298 assert(images != (Image *) NULL); 00299 assert(images->signature == MagickSignature); 00300 if (images->debug != MagickFalse) 00301 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename); 00302 display=XOpenDisplay(image_info->server_name); 00303 if (display == (Display *) NULL) 00304 { 00305 (void) ThrowMagickException(exception,GetMagickModule(),XServerError, 00306 "UnableToOpenXServer","`%s'",XDisplayName(image_info->server_name)); 00307 return(MagickFalse); 00308 } 00309 if (exception->severity != UndefinedException) 00310 CatchException(exception); 00311 (void) XSetErrorHandler(XError); 00312 resource_database=XGetResourceDatabase(display,GetClientName()); 00313 (void) ResetMagickMemory(&resource_info,0,sizeof(XResourceInfo)); 00314 XGetResourceInfo(image_info,resource_database,GetClientName(),&resource_info); 00315 if (image_info->page != (char *) NULL) 00316 resource_info.image_geometry=AcquireString(image_info->page); 00317 resource_info.immutable=MagickTrue; 00318 argv[0]=AcquireString(GetClientName()); 00319 (void) XAnimateImages(display,&resource_info,argv,1,images,exception); 00320 SetErrorHandler((ErrorHandler) NULL); 00321 SetWarningHandler((WarningHandler) NULL); 00322 SetErrorHandler((ErrorHandler) NULL); 00323 SetWarningHandler((WarningHandler) NULL); 00324 argv[0]=DestroyString(argv[0]); 00325 (void) XCloseDisplay(display); 00326 XDestroyResourceInfo(&resource_info); 00327 status=exception->severity == UndefinedException ? MagickTrue : MagickFalse; 00328 return(status != 0 ? MagickTrue : MagickFalse); 00329 } 00330 00331 /* 00332 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00333 % % 00334 % % 00335 % % 00336 + X M a g i c k C o m m a n d % 00337 % % 00338 % % 00339 % % 00340 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00341 % 00342 % XMagickCommand() makes a transform to the image or Image window as specified 00343 % by a user menu button or keyboard command. 00344 % 00345 % The format of the XMagickCommand method is: 00346 % 00347 % Image *XMagickCommand(Display *display,XResourceInfo *resource_info, 00348 % XWindows *windows,const CommandType command_type,Image **image, 00349 % MagickStatusType *state,ExceptionInfo *exception) 00350 % 00351 % A description of each parameter follows: 00352 % 00353 % o display: Specifies a connection to an X server; returned from 00354 % XOpenDisplay. 00355 % 00356 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure. 00357 % 00358 % o windows: Specifies a pointer to a XWindows structure. 00359 % 00360 % o image: the image; XMagickCommand 00361 % may transform the image and return a new image pointer. 00362 % 00363 % o state: Specifies a MagickStatusType; XMagickCommand may return a 00364 % modified state. 00365 % 00366 % o exception: return any errors or warnings in this structure. 00367 % 00368 % 00369 */ 00370 static Image *XMagickCommand(Display *display,XResourceInfo *resource_info, 00371 XWindows *windows,const CommandType command_type,Image **image, 00372 MagickStatusType *state,ExceptionInfo *exception) 00373 { 00374 Image 00375 *nexus; 00376 00377 MagickBooleanType 00378 proceed; 00379 00380 MagickStatusType 00381 status; 00382 00383 XTextProperty 00384 window_name; 00385 00386 /* 00387 Process user command. 00388 */ 00389 nexus=NewImageList(); 00390 switch (command_type) 00391 { 00392 case OpenCommand: 00393 { 00394 char 00395 **filelist; 00396 00397 Image 00398 *images, 00399 *next; 00400 00401 ImageInfo 00402 *read_info; 00403 00404 int 00405 number_files; 00406 00407 register int 00408 i; 00409 00410 static char 00411 filenames[MaxTextExtent] = "*"; 00412 00413 if (resource_info->immutable != MagickFalse) 00414 break; 00415 /* 00416 Request file name from user. 00417 */ 00418 XFileBrowserWidget(display,windows,"Animate",filenames); 00419 if (*filenames == '\0') 00420 return((Image *) NULL); 00421 /* 00422 Expand the filenames. 00423 */ 00424 filelist=(char **) AcquireMagickMemory(sizeof(char *)); 00425 if (filelist == (char **) NULL) 00426 { 00427 ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed", 00428 filenames); 00429 return((Image *) NULL); 00430 } 00431 number_files=1; 00432 filelist[0]=filenames; 00433 status=ExpandFilenames(&number_files,&filelist); 00434 if ((status == MagickFalse) || (number_files == 0)) 00435 { 00436 if (number_files == 0) 00437 { 00438 ThrowXWindowException(ImageError,"NoImagesWereLoaded",filenames); 00439 return((Image *) NULL); 00440 } 00441 ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed", 00442 filenames); 00443 return((Image *) NULL); 00444 } 00445 read_info=CloneImageInfo(resource_info->image_info); 00446 images=NewImageList(); 00447 XSetCursorState(display,windows,MagickTrue); 00448 XCheckRefreshWindows(display,windows); 00449 for (i=0; i < number_files; i++) 00450 { 00451 (void) CopyMagickString(read_info->filename,filelist[i],MaxTextExtent); 00452 filelist[i]=DestroyString(filelist[i]); 00453 *read_info->magick='\0'; 00454 next=ReadImage(read_info,exception); 00455 CatchException(exception); 00456 if (next != (Image *) NULL) 00457 AppendImageToList(&images,next); 00458 if (number_files <= 5) 00459 continue; 00460 proceed=SetImageProgress(images,LoadImageTag,i,(MagickSizeType) 00461 number_files); 00462 if (proceed == MagickFalse) 00463 break; 00464 } 00465 filelist=(char **) RelinquishMagickMemory(filelist); 00466 read_info=DestroyImageInfo(read_info); 00467 if (images == (Image *) NULL) 00468 { 00469 XSetCursorState(display,windows,MagickFalse); 00470 ThrowXWindowException(ImageError,"NoImagesWereLoaded",filenames); 00471 return((Image *) NULL); 00472 } 00473 nexus=GetFirstImageInList(images); 00474 *state|=ExitState; 00475 break; 00476 } 00477 case PlayCommand: 00478 { 00479 char 00480 basename[MaxTextExtent]; 00481 00482 int 00483 status; 00484 00485 /* 00486 Window name is the base of the filename. 00487 */ 00488 *state|=PlayAnimationState; 00489 *state&=(~AutoReverseAnimationState); 00490 GetPathComponent((*image)->magick_filename,BasePath,basename); 00491 (void) FormatLocaleString(windows->image.name,MaxTextExtent, 00492 "%s: %s",MagickPackageName,basename); 00493 if (resource_info->title != (char *) NULL) 00494 { 00495 char 00496 *title; 00497 00498 title=InterpretImageProperties(resource_info->image_info,*image, 00499 resource_info->title,exception); 00500 (void) CopyMagickString(windows->image.name,title,MaxTextExtent); 00501 title=DestroyString(title); 00502 } 00503 status=XStringListToTextProperty(&windows->image.name,1,&window_name); 00504 if (status == 0) 00505 break; 00506 XSetWMName(display,windows->image.id,&window_name); 00507 (void) XFree((void *) window_name.value); 00508 break; 00509 } 00510 case StepCommand: 00511 case StepBackwardCommand: 00512 case StepForwardCommand: 00513 { 00514 *state|=StepAnimationState; 00515 *state&=(~PlayAnimationState); 00516 if (command_type == StepBackwardCommand) 00517 *state&=(~ForwardAnimationState); 00518 if (command_type == StepForwardCommand) 00519 *state|=ForwardAnimationState; 00520 if (resource_info->title != (char *) NULL) 00521 break; 00522 break; 00523 } 00524 case RepeatCommand: 00525 { 00526 *state|=RepeatAnimationState; 00527 *state&=(~AutoReverseAnimationState); 00528 *state|=PlayAnimationState; 00529 break; 00530 } 00531 case AutoReverseCommand: 00532 { 00533 *state|=AutoReverseAnimationState; 00534 *state&=(~RepeatAnimationState); 00535 *state|=PlayAnimationState; 00536 break; 00537 } 00538 case SaveCommand: 00539 { 00540 /* 00541 Save image. 00542 */ 00543 status=XSaveImage(display,resource_info,windows,*image,exception); 00544 if (status == MagickFalse) 00545 { 00546 char 00547 message[MaxTextExtent]; 00548 00549 (void) FormatLocaleString(message,MaxTextExtent,"%s:%s", 00550 exception->reason != (char *) NULL ? exception->reason : "", 00551 exception->description != (char *) NULL ? exception->description : 00552 ""); 00553 XNoticeWidget(display,windows,"Unable to save file:",message); 00554 break; 00555 } 00556 break; 00557 } 00558 case SlowerCommand: 00559 { 00560 resource_info->delay++; 00561 break; 00562 } 00563 case FasterCommand: 00564 { 00565 if (resource_info->delay == 0) 00566 break; 00567 resource_info->delay--; 00568 break; 00569 } 00570 case ForwardCommand: 00571 { 00572 *state=ForwardAnimationState; 00573 *state&=(~AutoReverseAnimationState); 00574 break; 00575 } 00576 case ReverseCommand: 00577 { 00578 *state&=(~ForwardAnimationState); 00579 *state&=(~AutoReverseAnimationState); 00580 break; 00581 } 00582 case InfoCommand: 00583 { 00584 XDisplayImageInfo(display,resource_info,windows,(Image *) NULL,*image, 00585 exception); 00586 break; 00587 } 00588 case HelpCommand: 00589 { 00590 /* 00591 User requested help. 00592 */ 00593 XTextViewWidget(display,resource_info,windows,MagickFalse, 00594 "Help Viewer - Animate",AnimateHelp); 00595 break; 00596 } 00597 case BrowseDocumentationCommand: 00598 { 00599 Atom 00600 mozilla_atom; 00601 00602 Window 00603 mozilla_window, 00604 root_window; 00605 00606 /* 00607 Browse the ImageMagick documentation. 00608 */ 00609 root_window=XRootWindow(display,XDefaultScreen(display)); 00610 mozilla_atom=XInternAtom(display,"_MOZILLA_VERSION",MagickFalse); 00611 mozilla_window=XWindowByProperty(display,root_window,mozilla_atom); 00612 if (mozilla_window != (Window) NULL) 00613 { 00614 char 00615 command[MaxTextExtent], 00616 *url; 00617 00618 /* 00619 Display documentation using Netscape remote control. 00620 */ 00621 url=GetMagickHomeURL(); 00622 (void) FormatLocaleString(command,MaxTextExtent, 00623 "openurl(%s,new-tab)",url); 00624 url=DestroyString(url); 00625 mozilla_atom=XInternAtom(display,"_MOZILLA_COMMAND",MagickFalse); 00626 (void) XChangeProperty(display,mozilla_window,mozilla_atom, 00627 XA_STRING,8,PropModeReplace,(unsigned char *) command, 00628 (int) strlen(command)); 00629 XSetCursorState(display,windows,MagickFalse); 00630 break; 00631 } 00632 XSetCursorState(display,windows,MagickTrue); 00633 XCheckRefreshWindows(display,windows); 00634 status=InvokeDelegate(resource_info->image_info,*image,"browse", 00635 (char *) NULL,exception); 00636 if (status == MagickFalse) 00637 XNoticeWidget(display,windows,"Unable to browse documentation", 00638 (char *) NULL); 00639 XDelay(display,1500); 00640 XSetCursorState(display,windows,MagickFalse); 00641 break; 00642 } 00643 case VersionCommand: 00644 { 00645 XNoticeWidget(display,windows,GetMagickVersion((size_t *) NULL), 00646 GetMagickCopyright()); 00647 break; 00648 } 00649 case QuitCommand: 00650 { 00651 /* 00652 exit program 00653 */ 00654 if (resource_info->confirm_exit == MagickFalse) 00655 XClientMessage(display,windows->image.id,windows->im_protocols, 00656 windows->im_exit,CurrentTime); 00657 else 00658 { 00659 int 00660 status; 00661 00662 /* 00663 Confirm program exit. 00664 */ 00665 status=XConfirmWidget(display,windows,"Do you really want to exit", 00666 resource_info->client_name); 00667 if (status != 0) 00668 XClientMessage(display,windows->image.id,windows->im_protocols, 00669 windows->im_exit,CurrentTime); 00670 } 00671 break; 00672 } 00673 default: 00674 break; 00675 } 00676 return(nexus); 00677 } 00678 00679 /* 00680 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00681 % % 00682 % % 00683 % % 00684 + X A n i m a t e B a c k g r o u n d I m a g e % 00685 % % 00686 % % 00687 % % 00688 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00689 % 00690 % XAnimateBackgroundImage() animates an image sequence in the background of 00691 % a window. 00692 % 00693 % The format of the XAnimateBackgroundImage method is: 00694 % 00695 % void XAnimateBackgroundImage(Display *display, 00696 % XResourceInfo *resource_info,Image *images,ExceptionInfo *exception) 00697 % 00698 % A description of each parameter follows: 00699 % 00700 % o display: Specifies a connection to an X server; returned from 00701 % XOpenDisplay. 00702 % 00703 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure. 00704 % 00705 % o images: the image list. 00706 % 00707 % o exception: return any errors or warnings in this structure. 00708 % 00709 */ 00710 00711 static inline ssize_t MagickMax(const ssize_t x,const ssize_t y) 00712 { 00713 if (x > y) 00714 return(x); 00715 return(y); 00716 } 00717 00718 #if defined(__cplusplus) || defined(c_plusplus) 00719 extern "C" { 00720 #endif 00721 00722 static int SceneCompare(const void *x,const void *y) 00723 { 00724 const Image 00725 **image_1, 00726 **image_2; 00727 00728 image_1=(const Image **) x; 00729 image_2=(const Image **) y; 00730 return((int) ((*image_1)->scene-(*image_2)->scene)); 00731 } 00732 00733 #if defined(__cplusplus) || defined(c_plusplus) 00734 } 00735 #endif 00736 00737 MagickExport void XAnimateBackgroundImage(Display *display, 00738 XResourceInfo *resource_info,Image *images,ExceptionInfo *exception) 00739 { 00740 char 00741 geometry[MaxTextExtent], 00742 visual_type[MaxTextExtent]; 00743 00744 Image 00745 *coalesce_image, 00746 *display_image, 00747 **image_list; 00748 00749 int 00750 scene; 00751 00752 MagickStatusType 00753 status; 00754 00755 RectangleInfo 00756 geometry_info; 00757 00758 register ssize_t 00759 i; 00760 00761 size_t 00762 number_scenes; 00763 00764 static XPixelInfo 00765 pixel; 00766 00767 static XStandardColormap 00768 *map_info; 00769 00770 static XVisualInfo 00771 *visual_info = (XVisualInfo *) NULL; 00772 00773 static XWindowInfo 00774 window_info; 00775 00776 unsigned int 00777 height, 00778 width; 00779 00780 size_t 00781 delay; 00782 00783 Window 00784 root_window; 00785 00786 XEvent 00787 event; 00788 00789 XGCValues 00790 context_values; 00791 00792 XResourceInfo 00793 resources; 00794 00795 XWindowAttributes 00796 window_attributes; 00797 00798 /* 00799 Determine target window. 00800 */ 00801 assert(images != (Image *) NULL); 00802 assert(images->signature == MagickSignature); 00803 if (images->debug != MagickFalse) 00804 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename); 00805 resources=(*resource_info); 00806 window_info.id=(Window) NULL; 00807 root_window=XRootWindow(display,XDefaultScreen(display)); 00808 if (LocaleCompare(resources.window_id,"root") == 0) 00809 window_info.id=root_window; 00810 else 00811 { 00812 if (isdigit((int) ((unsigned char) *resources.window_id)) != 0) 00813 window_info.id=XWindowByID(display,root_window, 00814 (Window) strtol((char *) resources.window_id,(char **) NULL,0)); 00815 if (window_info.id == (Window) NULL) 00816 window_info.id= 00817 XWindowByName(display,root_window,resources.window_id); 00818 } 00819 if (window_info.id == (Window) NULL) 00820 { 00821 ThrowXWindowException(XServerError,"NoWindowWithSpecifiedIDExists", 00822 resources.window_id); 00823 return; 00824 } 00825 /* 00826 Determine window visual id. 00827 */ 00828 window_attributes.width=XDisplayWidth(display,XDefaultScreen(display)); 00829 window_attributes.height=XDisplayHeight(display,XDefaultScreen(display)); 00830 (void) CopyMagickString(visual_type,"default",MaxTextExtent); 00831 status=XGetWindowAttributes(display,window_info.id,&window_attributes) != 0 ? 00832 MagickTrue : MagickFalse; 00833 if (status != MagickFalse) 00834 (void) FormatLocaleString(visual_type,MaxTextExtent,"0x%lx", 00835 XVisualIDFromVisual(window_attributes.visual)); 00836 if (visual_info == (XVisualInfo *) NULL) 00837 { 00838 /* 00839 Allocate standard colormap. 00840 */ 00841 map_info=XAllocStandardColormap(); 00842 if (map_info == (XStandardColormap *) NULL) 00843 ThrowXWindowFatalException(ResourceLimitError,"MemoryAllocationFailed", 00844 images->filename); 00845 map_info->colormap=(Colormap) NULL; 00846 pixel.pixels=(unsigned long *) NULL; 00847 /* 00848 Initialize visual info. 00849 */ 00850 resources.map_type=(char *) NULL; 00851 resources.visual_type=visual_type; 00852 visual_info=XBestVisualInfo(display,map_info,&resources); 00853 if (visual_info == (XVisualInfo *) NULL) 00854 ThrowXWindowFatalException(XServerFatalError,"UnableToGetVisual", 00855 images->filename); 00856 /* 00857 Initialize window info. 00858 */ 00859 window_info.ximage=(XImage *) NULL; 00860 window_info.matte_image=(XImage *) NULL; 00861 window_info.pixmap=(Pixmap) NULL; 00862 window_info.matte_pixmap=(Pixmap) NULL; 00863 } 00864 /* 00865 Free previous root colors. 00866 */ 00867 if (window_info.id == root_window) 00868 XDestroyWindowColors(display,root_window); 00869 coalesce_image=CoalesceImages(images,exception); 00870 if (coalesce_image == (Image *) NULL) 00871 ThrowXWindowFatalException(ResourceLimitError,"MemoryAllocationFailed", 00872 images->filename); 00873 images=coalesce_image; 00874 if (resources.map_type == (char *) NULL) 00875 if ((visual_info->klass != TrueColor) && 00876 (visual_info->klass != DirectColor)) 00877 { 00878 Image 00879 *next; 00880 00881 /* 00882 Determine if the sequence of images has the identical colormap. 00883 */ 00884 for (next=images; next != (Image *) NULL; ) 00885 { 00886 next->matte=MagickFalse; 00887 if ((next->storage_class == DirectClass) || 00888 (next->colors != images->colors) || 00889 (next->colors > (size_t) visual_info->colormap_size)) 00890 break; 00891 for (i=0; i < (ssize_t) images->colors; i++) 00892 if (IsPixelInfoEquivalent(next->colormap+i,images->colormap+i) == MagickFalse) 00893 break; 00894 if (i < (ssize_t) images->colors) 00895 break; 00896 next=GetNextImageInList(next); 00897 } 00898 if (next != (Image *) NULL) 00899 (void) RemapImages(resources.quantize_info,images,(Image *) NULL, 00900 exception); 00901 } 00902 /* 00903 Sort images by increasing scene number. 00904 */ 00905 number_scenes=GetImageListLength(images); 00906 image_list=ImageListToArray(images,exception); 00907 if (image_list == (Image **) NULL) 00908 ThrowXWindowFatalException(ResourceLimitFatalError, 00909 "MemoryAllocationFailed",images->filename); 00910 for (i=0; i < (ssize_t) number_scenes; i++) 00911 if (image_list[i]->scene == 0) 00912 break; 00913 if (i == (ssize_t) number_scenes) 00914 qsort((void *) image_list,number_scenes,sizeof(Image *),SceneCompare); 00915 /* 00916 Initialize Standard Colormap. 00917 */ 00918 resources.colormap=SharedColormap; 00919 display_image=image_list[0]; 00920 for (scene=0; scene < (int) number_scenes; scene++) 00921 { 00922 if ((resource_info->map_type != (char *) NULL) || 00923 (visual_info->klass == TrueColor) || 00924 (visual_info->klass == DirectColor)) 00925 (void) SetImageType(image_list[scene],image_list[scene]->matte == 00926 MagickFalse ? TrueColorType : TrueColorMatteType,exception); 00927 if ((display_image->columns < image_list[scene]->columns) && 00928 (display_image->rows < image_list[scene]->rows)) 00929 display_image=image_list[scene]; 00930 } 00931 if ((resource_info->map_type != (char *) NULL) || 00932 (visual_info->klass == TrueColor) || (visual_info->klass == DirectColor)) 00933 (void) SetImageType(display_image,display_image->matte == MagickFalse ? 00934 TrueColorType : TrueColorMatteType,exception); 00935 XMakeStandardColormap(display,visual_info,&resources,display_image,map_info, 00936 &pixel,exception); 00937 /* 00938 Graphic context superclass. 00939 */ 00940 context_values.background=pixel.background_color.pixel; 00941 context_values.foreground=pixel.foreground_color.pixel; 00942 pixel.annotate_context=XCreateGC(display,window_info.id,(unsigned long) 00943 (GCBackground | GCForeground),&context_values); 00944 if (pixel.annotate_context == (GC) NULL) 00945 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateGraphicContext", 00946 images->filename); 00947 /* 00948 Initialize Image window attributes. 00949 */ 00950 XGetWindowInfo(display,visual_info,map_info,&pixel,(XFontStruct *) NULL, 00951 &resources,&window_info); 00952 /* 00953 Create the X image. 00954 */ 00955 window_info.width=(unsigned int) image_list[0]->columns; 00956 window_info.height=(unsigned int) image_list[0]->rows; 00957 if ((image_list[0]->columns != window_info.width) || 00958 (image_list[0]->rows != window_info.height)) 00959 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateXImage", 00960 image_list[0]->filename); 00961 (void) FormatLocaleString(geometry,MaxTextExtent,"%ux%u+0+0>", 00962 window_attributes.width,window_attributes.height); 00963 geometry_info.width=window_info.width; 00964 geometry_info.height=window_info.height; 00965 geometry_info.x=(ssize_t) window_info.x; 00966 geometry_info.y=(ssize_t) window_info.y; 00967 (void) ParseMetaGeometry(geometry,&geometry_info.x,&geometry_info.y, 00968 &geometry_info.width,&geometry_info.height); 00969 window_info.width=(unsigned int) geometry_info.width; 00970 window_info.height=(unsigned int) geometry_info.height; 00971 window_info.x=(int) geometry_info.x; 00972 window_info.y=(int) geometry_info.y; 00973 status=XMakeImage(display,&resources,&window_info,image_list[0], 00974 window_info.width,window_info.height,exception); 00975 if (status == MagickFalse) 00976 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateXImage", 00977 images->filename); 00978 window_info.x=0; 00979 window_info.y=0; 00980 if (display_image->debug != MagickFalse) 00981 { 00982 (void) LogMagickEvent(X11Event,GetMagickModule(), 00983 "Image: %s[%.20g] %.20gx%.20g ",image_list[0]->filename,(double) 00984 image_list[0]->scene,(double) image_list[0]->columns,(double) 00985 image_list[0]->rows); 00986 if (image_list[0]->colors != 0) 00987 (void) LogMagickEvent(X11Event,GetMagickModule(),"%.20gc ",(double) 00988 image_list[0]->colors); 00989 (void) LogMagickEvent(X11Event,GetMagickModule(),"%s", 00990 image_list[0]->magick); 00991 } 00992 /* 00993 Adjust image dimensions as specified by backdrop or geometry options. 00994 */ 00995 width=window_info.width; 00996 height=window_info.height; 00997 if (resources.backdrop != MagickFalse) 00998 { 00999 /* 01000 Center image on window. 01001 */ 01002 window_info.x=(int) (window_attributes.width/2)- 01003 (window_info.ximage->width/2); 01004 window_info.y=(int) (window_attributes.height/2)- 01005 (window_info.ximage->height/2); 01006 width=(unsigned int) window_attributes.width; 01007 height=(unsigned int) window_attributes.height; 01008 } 01009 if (resources.image_geometry != (char *) NULL) 01010 { 01011 char 01012 default_geometry[MaxTextExtent]; 01013 01014 int 01015 flags, 01016 gravity; 01017 01018 XSizeHints 01019 *size_hints; 01020 01021 /* 01022 User specified geometry. 01023 */ 01024 size_hints=XAllocSizeHints(); 01025 if (size_hints == (XSizeHints *) NULL) 01026 ThrowXWindowFatalException(ResourceLimitFatalError, 01027 "MemoryAllocationFailed",images->filename); 01028 size_hints->flags=0L; 01029 (void) FormatLocaleString(default_geometry,MaxTextExtent,"%ux%u",width, 01030 height); 01031 flags=XWMGeometry(display,visual_info->screen,resources.image_geometry, 01032 default_geometry,window_info.border_width,size_hints,&window_info.x, 01033 &window_info.y,(int *) &width,(int *) &height,&gravity); 01034 if (((flags & (XValue | YValue))) != 0) 01035 { 01036 width=(unsigned int) window_attributes.width; 01037 height=(unsigned int) window_attributes.height; 01038 } 01039 (void) XFree((void *) size_hints); 01040 } 01041 /* 01042 Create the X pixmap. 01043 */ 01044 window_info.pixmap=XCreatePixmap(display,window_info.id,(unsigned int) width, 01045 (unsigned int) height,window_info.depth); 01046 if (window_info.pixmap == (Pixmap) NULL) 01047 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateXPixmap", 01048 images->filename); 01049 /* 01050 Display pixmap on the window. 01051 */ 01052 if (((unsigned int) width > window_info.width) || 01053 ((unsigned int) height > window_info.height)) 01054 (void) XFillRectangle(display,window_info.pixmap, 01055 window_info.annotate_context,0,0,(unsigned int) width, 01056 (unsigned int) height); 01057 (void) XPutImage(display,window_info.pixmap,window_info.annotate_context, 01058 window_info.ximage,0,0,window_info.x,window_info.y,window_info.width, 01059 window_info.height); 01060 (void) XSetWindowBackgroundPixmap(display,window_info.id,window_info.pixmap); 01061 (void) XClearWindow(display,window_info.id); 01062 /* 01063 Initialize image pixmaps structure. 01064 */ 01065 window_info.pixmaps=(Pixmap *) AcquireQuantumMemory(number_scenes, 01066 sizeof(*window_info.pixmaps)); 01067 window_info.matte_pixmaps=(Pixmap *) AcquireQuantumMemory(number_scenes, 01068 sizeof(*window_info.matte_pixmaps)); 01069 if ((window_info.pixmaps == (Pixmap *) NULL) || 01070 (window_info.matte_pixmaps == (Pixmap *) NULL)) 01071 ThrowXWindowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed", 01072 images->filename); 01073 window_info.pixmaps[0]=window_info.pixmap; 01074 window_info.matte_pixmaps[0]=window_info.pixmap; 01075 for (scene=1; scene < (int) number_scenes; scene++) 01076 { 01077 unsigned int 01078 columns, 01079 rows; 01080 01081 /* 01082 Create X image. 01083 */ 01084 window_info.pixmap=(Pixmap) NULL; 01085 window_info.matte_pixmap=(Pixmap) NULL; 01086 if ((resources.map_type != (char *) NULL) || 01087 (visual_info->klass == TrueColor) || 01088 (visual_info->klass == DirectColor)) 01089 if (image_list[scene]->storage_class == PseudoClass) 01090 XGetPixelInfo(display,visual_info,map_info,&resources, 01091 image_list[scene],window_info.pixel_info); 01092 columns=(unsigned int) image_list[scene]->columns; 01093 rows=(unsigned int) image_list[scene]->rows; 01094 if ((image_list[scene]->columns != columns) || 01095 (image_list[scene]->rows != rows)) 01096 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateXImage", 01097 image_list[scene]->filename); 01098 status=XMakeImage(display,&resources,&window_info,image_list[scene], 01099 columns,rows,exception); 01100 if (status == MagickFalse) 01101 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateXImage", 01102 images->filename); 01103 if (display_image->debug != MagickFalse) 01104 { 01105 (void) LogMagickEvent(X11Event,GetMagickModule(), 01106 "Image: [%.20g] %s %.20gx%.20g ",(double) image_list[scene]->scene, 01107 image_list[scene]->filename,(double) columns,(double) rows); 01108 if (image_list[scene]->colors != 0) 01109 (void) LogMagickEvent(X11Event,GetMagickModule(),"%.20gc ",(double) 01110 image_list[scene]->colors); 01111 (void) LogMagickEvent(X11Event,GetMagickModule(),"%s", 01112 image_list[scene]->magick); 01113 } 01114 /* 01115 Create the X pixmap. 01116 */ 01117 window_info.pixmap=XCreatePixmap(display,window_info.id,width,height, 01118 window_info.depth); 01119 if (window_info.pixmap == (Pixmap) NULL) 01120 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateXPixmap", 01121 images->filename); 01122 /* 01123 Display pixmap on the window. 01124 */ 01125 if ((width > window_info.width) || (height > window_info.height)) 01126 (void) XFillRectangle(display,window_info.pixmap, 01127 window_info.annotate_context,0,0,width,height); 01128 (void) XPutImage(display,window_info.pixmap,window_info.annotate_context, 01129 window_info.ximage,0,0,window_info.x,window_info.y,window_info.width, 01130 window_info.height); 01131 (void) XSetWindowBackgroundPixmap(display,window_info.id, 01132 window_info.pixmap); 01133 (void) XClearWindow(display,window_info.id); 01134 window_info.pixmaps[scene]=window_info.pixmap; 01135 window_info.matte_pixmaps[scene]=window_info.matte_pixmap; 01136 if (image_list[scene]->matte) 01137 (void) XClearWindow(display,window_info.id); 01138 delay=1000*image_list[scene]->delay/MagickMax( 01139 image_list[scene]->ticks_per_second,1L); 01140 XDelay(display,resources.delay*(delay == 0 ? 10 : delay)); 01141 } 01142 window_info.pixel_info=(&pixel); 01143 /* 01144 Display pixmap on the window. 01145 */ 01146 (void) XSelectInput(display,window_info.id,SubstructureNotifyMask); 01147 event.type=Expose; 01148 do 01149 { 01150 for (scene=0; scene < (int) number_scenes; scene++) 01151 { 01152 if (XEventsQueued(display,QueuedAfterFlush) > 0) 01153 { 01154 (void) XNextEvent(display,&event); 01155 if (event.type == DestroyNotify) 01156 break; 01157 } 01158 window_info.pixmap=window_info.pixmaps[scene]; 01159 window_info.matte_pixmap=window_info.matte_pixmaps[scene]; 01160 (void) XSetWindowBackgroundPixmap(display,window_info.id, 01161 window_info.pixmap); 01162 (void) XClearWindow(display,window_info.id); 01163 (void) XSync(display,MagickFalse); 01164 delay=1000*image_list[scene]->delay/MagickMax( 01165 image_list[scene]->ticks_per_second,1L); 01166 XDelay(display,resources.delay*(delay == 0 ? 10 : delay)); 01167 } 01168 } while (event.type != DestroyNotify); 01169 (void) XSync(display,MagickFalse); 01170 image_list=(Image **) RelinquishMagickMemory(image_list); 01171 images=DestroyImageList(images); 01172 } 01173 01174 /* 01175 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01176 % % 01177 % % 01178 % % 01179 + X A n i m a t e I m a g e s % 01180 % % 01181 % % 01182 % % 01183 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01184 % 01185 % XAnimateImages() displays an image via X11. 01186 % 01187 % The format of the XAnimateImages method is: 01188 % 01189 % Image *XAnimateImages(Display *display,XResourceInfo *resource_info, 01190 % char **argv,const int argc,Image *images,ExceptionInfo *exception) 01191 % 01192 % A description of each parameter follows: 01193 % 01194 % o display: Specifies a connection to an X server; returned from 01195 % XOpenDisplay. 01196 % 01197 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure. 01198 % 01199 % o argv: Specifies the application's argument list. 01200 % 01201 % o argc: Specifies the number of arguments. 01202 % 01203 % o images: the image list. 01204 % 01205 % o exception: return any errors or warnings in this structure. 01206 % 01207 */ 01208 MagickExport Image *XAnimateImages(Display *display, 01209 XResourceInfo *resource_info,char **argv,const int argc,Image *images, 01210 ExceptionInfo *exception) 01211 { 01212 #define MagickMenus 4 01213 #define MaXWindows 8 01214 #define MagickTitle "Commands" 01215 01216 static const char 01217 *CommandMenu[]= 01218 { 01219 "Animate", 01220 "Speed", 01221 "Direction", 01222 "Help", 01223 "Image Info", 01224 "Quit", 01225 (char *) NULL 01226 }, 01227 *AnimateMenu[]= 01228 { 01229 "Open...", 01230 "Play", 01231 "Step", 01232 "Repeat", 01233 "Auto Reverse", 01234 "Save...", 01235 (char *) NULL 01236 }, 01237 *SpeedMenu[]= 01238 { 01239 "Faster", 01240 "Slower", 01241 (char *) NULL 01242 }, 01243 *DirectionMenu[]= 01244 { 01245 "Forward", 01246 "Reverse", 01247 (char *) NULL 01248 }, 01249 *HelpMenu[]= 01250 { 01251 "Overview", 01252 "Browse Documentation", 01253 "About Animate", 01254 (char *) NULL 01255 }; 01256 01257 static const char 01258 **Menus[MagickMenus]= 01259 { 01260 AnimateMenu, 01261 SpeedMenu, 01262 DirectionMenu, 01263 HelpMenu 01264 }; 01265 01266 static const CommandType 01267 CommandMenus[]= 01268 { 01269 NullCommand, 01270 NullCommand, 01271 NullCommand, 01272 NullCommand, 01273 InfoCommand, 01274 QuitCommand 01275 }, 01276 CommandTypes[]= 01277 { 01278 OpenCommand, 01279 PlayCommand, 01280 StepCommand, 01281 RepeatCommand, 01282 AutoReverseCommand, 01283 SaveCommand 01284 }, 01285 SpeedCommands[]= 01286 { 01287 FasterCommand, 01288 SlowerCommand 01289 }, 01290 DirectionCommands[]= 01291 { 01292 ForwardCommand, 01293 ReverseCommand 01294 }, 01295 HelpCommands[]= 01296 { 01297 HelpCommand, 01298 BrowseDocumentationCommand, 01299 VersionCommand 01300 }; 01301 01302 static const CommandType 01303 *Commands[MagickMenus]= 01304 { 01305 CommandTypes, 01306 SpeedCommands, 01307 DirectionCommands, 01308 HelpCommands 01309 }; 01310 01311 char 01312 command[MaxTextExtent], 01313 *directory, 01314 geometry[MaxTextExtent], 01315 resource_name[MaxTextExtent]; 01316 01317 CommandType 01318 command_type; 01319 01320 Image 01321 *coalesce_image, 01322 *display_image, 01323 *image, 01324 **image_list, 01325 *nexus; 01326 01327 int 01328 status; 01329 01330 KeySym 01331 key_symbol; 01332 01333 MagickStatusType 01334 context_mask, 01335 state; 01336 01337 RectangleInfo 01338 geometry_info; 01339 01340 register char 01341 *p; 01342 01343 register ssize_t 01344 i; 01345 01346 ssize_t 01347 first_scene, 01348 iterations, 01349 scene; 01350 01351 static char 01352 working_directory[MaxTextExtent]; 01353 01354 static size_t 01355 number_windows; 01356 01357 static XWindowInfo 01358 *magick_windows[MaXWindows]; 01359 01360 time_t 01361 timestamp; 01362 01363 size_t 01364 delay, 01365 number_scenes; 01366 01367 WarningHandler 01368 warning_handler; 01369 01370 Window 01371 root_window; 01372 01373 XClassHint 01374 *class_hints; 01375 01376 XEvent 01377 event; 01378 01379 XFontStruct 01380 *font_info; 01381 01382 XGCValues 01383 context_values; 01384 01385 XPixelInfo 01386 *icon_pixel, 01387 *pixel; 01388 01389 XResourceInfo 01390 *icon_resources; 01391 01392 XStandardColormap 01393 *icon_map, 01394 *map_info; 01395 01396 XTextProperty 01397 window_name; 01398 01399 XVisualInfo 01400 *icon_visual, 01401 *visual_info; 01402 01403 XWindowChanges 01404 window_changes; 01405 01406 XWindows 01407 *windows; 01408 01409 XWMHints 01410 *manager_hints; 01411 01412 assert(images != (Image *) NULL); 01413 assert(images->signature == MagickSignature); 01414 if (images->debug != MagickFalse) 01415 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename); 01416 warning_handler=(WarningHandler) NULL; 01417 windows=XSetWindows((XWindows *) ~0); 01418 if (windows != (XWindows *) NULL) 01419 { 01420 int 01421 status; 01422 01423 status=chdir(working_directory); 01424 if (status == -1) 01425 (void) ThrowMagickException(exception,GetMagickModule(),FileOpenError, 01426 "UnableToOpenFile","%s",working_directory); 01427 warning_handler=resource_info->display_warnings ? 01428 SetErrorHandler(XWarning) : SetErrorHandler((ErrorHandler) NULL); 01429 warning_handler=resource_info->display_warnings ? 01430 SetWarningHandler(XWarning) : SetWarningHandler((WarningHandler) NULL); 01431 } 01432 else 01433 { 01434 register Image 01435 *p; 01436 01437 /* 01438 Initialize window structure. 01439 */ 01440 for (p=images; p != (Image *) NULL; p=GetNextImageInList(p)) 01441 { 01442 if (p->storage_class == DirectClass) 01443 { 01444 resource_info->colors=0; 01445 break; 01446 } 01447 if (p->colors > resource_info->colors) 01448 resource_info->colors=p->colors; 01449 } 01450 windows=XSetWindows(XInitializeWindows(display,resource_info)); 01451 if (windows == (XWindows *) NULL) 01452 ThrowXWindowFatalException(XServerFatalError,"MemoryAllocationFailed", 01453 images->filename); 01454 /* 01455 Initialize window id's. 01456 */ 01457 number_windows=0; 01458 magick_windows[number_windows++]=(&windows->icon); 01459 magick_windows[number_windows++]=(&windows->backdrop); 01460 magick_windows[number_windows++]=(&windows->image); 01461 magick_windows[number_windows++]=(&windows->info); 01462 magick_windows[number_windows++]=(&windows->command); 01463 magick_windows[number_windows++]=(&windows->widget); 01464 magick_windows[number_windows++]=(&windows->popup); 01465 for (i=0; i < (ssize_t) number_windows; i++) 01466 magick_windows[i]->id=(Window) NULL; 01467 } 01468 /* 01469 Initialize font info. 01470 */ 01471 if (windows->font_info != (XFontStruct *) NULL) 01472 (void) XFreeFont(display,windows->font_info); 01473 windows->font_info=XBestFont(display,resource_info,MagickFalse); 01474 if (windows->font_info == (XFontStruct *) NULL) 01475 ThrowXWindowFatalException(XServerFatalError,"UnableToLoadFont", 01476 resource_info->font); 01477 /* 01478 Initialize Standard Colormap. 01479 */ 01480 map_info=windows->map_info; 01481 icon_map=windows->icon_map; 01482 visual_info=windows->visual_info; 01483 icon_visual=windows->icon_visual; 01484 pixel=windows->pixel_info; 01485 icon_pixel=windows->icon_pixel; 01486 font_info=windows->font_info; 01487 icon_resources=windows->icon_resources; 01488 class_hints=windows->class_hints; 01489 manager_hints=windows->manager_hints; 01490 root_window=XRootWindow(display,visual_info->screen); 01491 coalesce_image=CoalesceImages(images,exception); 01492 if (coalesce_image == (Image *) NULL) 01493 ThrowXWindowFatalException(XServerFatalError,"MemoryAllocationFailed", 01494 images->filename); 01495 images=coalesce_image; 01496 if (resource_info->map_type == (char *) NULL) 01497 if ((visual_info->klass != TrueColor) && 01498 (visual_info->klass != DirectColor)) 01499 { 01500 Image 01501 *next; 01502 01503 /* 01504 Determine if the sequence of images has the identical colormap. 01505 */ 01506 for (next=images; next != (Image *) NULL; ) 01507 { 01508 next->matte=MagickFalse; 01509 if ((next->storage_class == DirectClass) || 01510 (next->colors != images->colors) || 01511 (next->colors > (size_t) visual_info->colormap_size)) 01512 break; 01513 for (i=0; i < (ssize_t) images->colors; i++) 01514 if (IsPixelInfoEquivalent(next->colormap+i,images->colormap+i) == MagickFalse) 01515 break; 01516 if (i < (ssize_t) images->colors) 01517 break; 01518 next=GetNextImageInList(next); 01519 } 01520 if (next != (Image *) NULL) 01521 (void) RemapImages(resource_info->quantize_info,images, 01522 (Image *) NULL,exception); 01523 } 01524 /* 01525 Sort images by increasing scene number. 01526 */ 01527 number_scenes=GetImageListLength(images); 01528 image_list=ImageListToArray(images,exception); 01529 if (image_list == (Image **) NULL) 01530 ThrowXWindowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed", 01531 images->filename); 01532 for (scene=0; scene < (ssize_t) number_scenes; scene++) 01533 if (image_list[scene]->scene == 0) 01534 break; 01535 if (scene == (ssize_t) number_scenes) 01536 qsort((void *) image_list,number_scenes,sizeof(Image *),SceneCompare); 01537 /* 01538 Initialize Standard Colormap. 01539 */ 01540 nexus=NewImageList(); 01541 display_image=image_list[0]; 01542 for (scene=0; scene < (ssize_t) number_scenes; scene++) 01543 { 01544 if ((resource_info->map_type != (char *) NULL) || 01545 (visual_info->klass == TrueColor) || 01546 (visual_info->klass == DirectColor)) 01547 (void) SetImageType(image_list[scene],image_list[scene]->matte == 01548 MagickFalse ? TrueColorType : TrueColorMatteType,exception); 01549 if ((display_image->columns < image_list[scene]->columns) && 01550 (display_image->rows < image_list[scene]->rows)) 01551 display_image=image_list[scene]; 01552 } 01553 if (display_image->debug != MagickFalse) 01554 { 01555 (void) LogMagickEvent(X11Event,GetMagickModule(), 01556 "Image: %s[%.20g] %.20gx%.20g ",display_image->filename,(double) 01557 display_image->scene,(double) display_image->columns,(double) 01558 display_image->rows); 01559 if (display_image->colors != 0) 01560 (void) LogMagickEvent(X11Event,GetMagickModule(),"%.20gc ",(double) 01561 display_image->colors); 01562 (void) LogMagickEvent(X11Event,GetMagickModule(),"%s", 01563 display_image->magick); 01564 } 01565 XMakeStandardColormap(display,visual_info,resource_info,display_image, 01566 map_info,pixel,exception); 01567 /* 01568 Initialize graphic context. 01569 */ 01570 windows->context.id=(Window) NULL; 01571 XGetWindowInfo(display,visual_info,map_info,pixel,font_info, 01572 resource_info,&windows->context); 01573 (void) CloneString(&class_hints->res_name,resource_info->client_name); 01574 (void) CloneString(&class_hints->res_class,resource_info->client_name); 01575 class_hints->res_class[0]=(char) toupper((int) class_hints->res_class[0]); 01576 manager_hints->flags=InputHint | StateHint; 01577 manager_hints->input=MagickFalse; 01578 manager_hints->initial_state=WithdrawnState; 01579 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints, 01580 &windows->context); 01581 if (display_image->debug != MagickFalse) 01582 (void) LogMagickEvent(X11Event,GetMagickModule(), 01583 "Window id: 0x%lx (context)",windows->context.id); 01584 context_values.background=pixel->background_color.pixel; 01585 context_values.font=font_info->fid; 01586 context_values.foreground=pixel->foreground_color.pixel; 01587 context_values.graphics_exposures=MagickFalse; 01588 context_mask=(MagickStatusType) 01589 (GCBackground | GCFont | GCForeground | GCGraphicsExposures); 01590 if (pixel->annotate_context != (GC) NULL) 01591 (void) XFreeGC(display,pixel->annotate_context); 01592 pixel->annotate_context= 01593 XCreateGC(display,windows->context.id,context_mask,&context_values); 01594 if (pixel->annotate_context == (GC) NULL) 01595 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateGraphicContext", 01596 images->filename); 01597 context_values.background=pixel->depth_color.pixel; 01598 if (pixel->widget_context != (GC) NULL) 01599 (void) XFreeGC(display,pixel->widget_context); 01600 pixel->widget_context= 01601 XCreateGC(display,windows->context.id,context_mask,&context_values); 01602 if (pixel->widget_context == (GC) NULL) 01603 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateGraphicContext", 01604 images->filename); 01605 context_values.background=pixel->foreground_color.pixel; 01606 context_values.foreground=pixel->background_color.pixel; 01607 context_values.plane_mask= 01608 context_values.background ^ context_values.foreground; 01609 if (pixel->highlight_context != (GC) NULL) 01610 (void) XFreeGC(display,pixel->highlight_context); 01611 pixel->highlight_context=XCreateGC(display,windows->context.id, 01612 (size_t) (context_mask | GCPlaneMask),&context_values); 01613 if (pixel->highlight_context == (GC) NULL) 01614 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateGraphicContext", 01615 images->filename); 01616 (void) XDestroyWindow(display,windows->context.id); 01617 /* 01618 Initialize icon window. 01619 */ 01620 XGetWindowInfo(display,icon_visual,icon_map,icon_pixel,(XFontStruct *) NULL, 01621 icon_resources,&windows->icon); 01622 windows->icon.geometry=resource_info->icon_geometry; 01623 XBestIconSize(display,&windows->icon,display_image); 01624 windows->icon.attributes.colormap= 01625 XDefaultColormap(display,icon_visual->screen); 01626 windows->icon.attributes.event_mask=ExposureMask | StructureNotifyMask; 01627 manager_hints->flags=InputHint | StateHint; 01628 manager_hints->input=MagickFalse; 01629 manager_hints->initial_state=IconicState; 01630 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints, 01631 &windows->icon); 01632 if (display_image->debug != MagickFalse) 01633 (void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (icon)", 01634 windows->icon.id); 01635 /* 01636 Initialize graphic context for icon window. 01637 */ 01638 if (icon_pixel->annotate_context != (GC) NULL) 01639 (void) XFreeGC(display,icon_pixel->annotate_context); 01640 context_values.background=icon_pixel->background_color.pixel; 01641 context_values.foreground=icon_pixel->foreground_color.pixel; 01642 icon_pixel->annotate_context=XCreateGC(display,windows->icon.id, 01643 (size_t) (GCBackground | GCForeground),&context_values); 01644 if (icon_pixel->annotate_context == (GC) NULL) 01645 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateGraphicContext", 01646 images->filename); 01647 windows->icon.annotate_context=icon_pixel->annotate_context; 01648 /* 01649 Initialize Image window. 01650 */ 01651 XGetWindowInfo(display,visual_info,map_info,pixel,font_info, 01652 resource_info,&windows->image); 01653 windows->image.shape=MagickTrue; /* non-rectangular shape hint */ 01654 if (resource_info->use_shared_memory == MagickFalse) 01655 windows->image.shared_memory=MagickFalse; 01656 if (resource_info->title != (char *) NULL) 01657 { 01658 char 01659 *title; 01660 01661 title=InterpretImageProperties(resource_info->image_info,display_image, 01662 resource_info->title,exception); 01663 (void) CopyMagickString(windows->image.name,title,MaxTextExtent); 01664 (void) CopyMagickString(windows->image.icon_name,title,MaxTextExtent); 01665 title=DestroyString(title); 01666 } 01667 else 01668 { 01669 char 01670 filename[MaxTextExtent]; 01671 01672 /* 01673 Window name is the base of the filename. 01674 */ 01675 GetPathComponent(display_image->magick_filename,TailPath,filename); 01676 (void) FormatLocaleString(windows->image.name,MaxTextExtent, 01677 "%s: %s[scene: %.20g frames: %.20g]",MagickPackageName,filename,(double) 01678 display_image->scene,(double) number_scenes); 01679 (void) CopyMagickString(windows->image.icon_name,filename,MaxTextExtent); 01680 } 01681 if (resource_info->immutable != MagickFalse) 01682 windows->image.immutable=MagickTrue; 01683 windows->image.shape=MagickTrue; 01684 windows->image.geometry=resource_info->image_geometry; 01685 (void) FormatLocaleString(geometry,MaxTextExtent,"%ux%u+0+0>!", 01686 XDisplayWidth(display,visual_info->screen), 01687 XDisplayHeight(display,visual_info->screen)); 01688 geometry_info.width=display_image->columns; 01689 geometry_info.height=display_image->rows; 01690 geometry_info.x=0; 01691 geometry_info.y=0; 01692 (void) ParseMetaGeometry(geometry,&geometry_info.x,&geometry_info.y, 01693 &geometry_info.width,&geometry_info.height); 01694 windows->image.width=(unsigned int) geometry_info.width; 01695 windows->image.height=(unsigned int) geometry_info.height; 01696 windows->image.attributes.event_mask=ButtonMotionMask | ButtonPressMask | 01697 ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask | 01698 KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask | 01699 PropertyChangeMask | StructureNotifyMask | SubstructureNotifyMask; 01700 XGetWindowInfo(display,visual_info,map_info,pixel,font_info, 01701 resource_info,&windows->backdrop); 01702 if ((resource_info->backdrop) || (windows->backdrop.id != (Window) NULL)) 01703 { 01704 /* 01705 Initialize backdrop window. 01706 */ 01707 windows->backdrop.x=0; 01708 windows->backdrop.y=0; 01709 (void) CloneString(&windows->backdrop.name,"ImageMagick Backdrop"); 01710 windows->backdrop.flags=(size_t) (USSize | USPosition); 01711 windows->backdrop.width=(unsigned int) 01712 XDisplayWidth(display,visual_info->screen); 01713 windows->backdrop.height=(unsigned int) 01714 XDisplayHeight(display,visual_info->screen); 01715 windows->backdrop.border_width=0; 01716 windows->backdrop.immutable=MagickTrue; 01717 windows->backdrop.attributes.do_not_propagate_mask=ButtonPressMask | 01718 ButtonReleaseMask; 01719 windows->backdrop.attributes.event_mask=ButtonPressMask | KeyPressMask | 01720 StructureNotifyMask; 01721 manager_hints->flags=IconWindowHint | InputHint | StateHint; 01722 manager_hints->icon_window=windows->icon.id; 01723 manager_hints->input=MagickTrue; 01724 manager_hints->initial_state= 01725 resource_info->iconic ? IconicState : NormalState; 01726 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints, 01727 &windows->backdrop); 01728 if (display_image->debug != MagickFalse) 01729 (void) LogMagickEvent(X11Event,GetMagickModule(), 01730 "Window id: 0x%lx (backdrop)",windows->backdrop.id); 01731 (void) XMapWindow(display,windows->backdrop.id); 01732 (void) XClearWindow(display,windows->backdrop.id); 01733 if (windows->image.id != (Window) NULL) 01734 { 01735 (void) XDestroyWindow(display,windows->image.id); 01736 windows->image.id=(Window) NULL; 01737 } 01738 /* 01739 Position image in the center the backdrop. 01740 */ 01741 windows->image.flags|=USPosition; 01742 windows->image.x=(XDisplayWidth(display,visual_info->screen)/2)- 01743 (windows->image.width/2); 01744 windows->image.y=(XDisplayHeight(display,visual_info->screen)/2)- 01745 (windows->image.height/2); 01746 } 01747 manager_hints->flags=IconWindowHint | InputHint | StateHint; 01748 manager_hints->icon_window=windows->icon.id; 01749 manager_hints->input=MagickTrue; 01750 manager_hints->initial_state= 01751 resource_info->iconic ? IconicState : NormalState; 01752 if (windows->group_leader.id != (Window) NULL) 01753 { 01754 /* 01755 Follow the leader. 01756 */ 01757 manager_hints->flags|=(MagickStatusType) WindowGroupHint; 01758 manager_hints->window_group=windows->group_leader.id; 01759 (void) XSelectInput(display,windows->group_leader.id,StructureNotifyMask); 01760 if (display_image->debug != MagickFalse) 01761 (void) LogMagickEvent(X11Event,GetMagickModule(), 01762 "Window id: 0x%lx (group leader)",windows->group_leader.id); 01763 } 01764 XMakeWindow(display, 01765 (Window) (resource_info->backdrop ? windows->backdrop.id : root_window), 01766 argv,argc,class_hints,manager_hints,&windows->image); 01767 (void) XChangeProperty(display,windows->image.id,windows->im_protocols, 01768 XA_STRING,8,PropModeReplace,(unsigned char *) NULL,0); 01769 if (windows->group_leader.id != (Window) NULL) 01770 (void) XSetTransientForHint(display,windows->image.id, 01771 windows->group_leader.id); 01772 if (display_image->debug != MagickFalse) 01773 (void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (image)", 01774 windows->image.id); 01775 /* 01776 Initialize Info widget. 01777 */ 01778 XGetWindowInfo(display,visual_info,map_info,pixel,font_info, 01779 resource_info,&windows->info); 01780 (void) CloneString(&windows->info.name,"Info"); 01781 (void) CloneString(&windows->info.icon_name,"Info"); 01782 windows->info.border_width=1; 01783 windows->info.x=2; 01784 windows->info.y=2; 01785 windows->info.flags|=PPosition; 01786 windows->info.attributes.win_gravity=UnmapGravity; 01787 windows->info.attributes.event_mask=ButtonPressMask | ExposureMask | 01788 StructureNotifyMask; 01789 manager_hints->flags=InputHint | StateHint | WindowGroupHint; 01790 manager_hints->input=MagickFalse; 01791 manager_hints->initial_state=NormalState; 01792 manager_hints->window_group=windows->image.id; 01793 XMakeWindow(display,windows->image.id,argv,argc,class_hints,manager_hints, 01794 &windows->info); 01795 windows->info.highlight_stipple=XCreateBitmapFromData(display, 01796 windows->info.id,(char *) HighlightBitmap,HighlightWidth,HighlightHeight); 01797 windows->info.shadow_stipple=XCreateBitmapFromData(display, 01798 windows->info.id,(char *) ShadowBitmap,ShadowWidth,ShadowHeight); 01799 (void) XSetTransientForHint(display,windows->info.id,windows->image.id); 01800 if (windows->image.mapped) 01801 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen); 01802 if (display_image->debug != MagickFalse) 01803 (void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (info)", 01804 windows->info.id); 01805 /* 01806 Initialize Command widget. 01807 */ 01808 XGetWindowInfo(display,visual_info,map_info,pixel,font_info, 01809 resource_info,&windows->command); 01810 windows->command.data=MagickMenus; 01811 (void) XCommandWidget(display,windows,CommandMenu,(XEvent *) NULL); 01812 (void) FormatLocaleString(resource_name,MaxTextExtent,"%s.command", 01813 resource_info->client_name); 01814 windows->command.geometry=XGetResourceClass(resource_info->resource_database, 01815 resource_name,"geometry",(char *) NULL); 01816 (void) CloneString(&windows->command.name,MagickTitle); 01817 windows->command.border_width=0; 01818 windows->command.flags|=PPosition; 01819 windows->command.attributes.event_mask=ButtonMotionMask | ButtonPressMask | 01820 ButtonReleaseMask | EnterWindowMask | ExposureMask | LeaveWindowMask | 01821 OwnerGrabButtonMask | StructureNotifyMask; 01822 manager_hints->flags=InputHint | StateHint | WindowGroupHint; 01823 manager_hints->input=MagickTrue; 01824 manager_hints->initial_state=NormalState; 01825 manager_hints->window_group=windows->image.id; 01826 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints, 01827 &windows->command); 01828 windows->command.highlight_stipple=XCreateBitmapFromData(display, 01829 windows->command.id,(char *) HighlightBitmap,HighlightWidth, 01830 HighlightHeight); 01831 windows->command.shadow_stipple=XCreateBitmapFromData(display, 01832 windows->command.id,(char *) ShadowBitmap,ShadowWidth,ShadowHeight); 01833 (void) XSetTransientForHint(display,windows->command.id,windows->image.id); 01834 if (display_image->debug != MagickFalse) 01835 (void) LogMagickEvent(X11Event,GetMagickModule(), 01836 "Window id: 0x%lx (command)",windows->command.id); 01837 /* 01838 Initialize Widget window. 01839 */ 01840 XGetWindowInfo(display,visual_info,map_info,pixel,font_info, 01841 resource_info,&windows->widget); 01842 (void) FormatLocaleString(resource_name,MaxTextExtent,"%s.widget", 01843 resource_info->client_name); 01844 windows->widget.geometry=XGetResourceClass(resource_info->resource_database, 01845 resource_name,"geometry",(char *) NULL); 01846 windows->widget.border_width=0; 01847 windows->widget.flags|=PPosition; 01848 windows->widget.attributes.event_mask=ButtonMotionMask | ButtonPressMask | 01849 ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask | 01850 KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask | 01851 StructureNotifyMask; 01852 manager_hints->flags=InputHint | StateHint | WindowGroupHint; 01853 manager_hints->input=MagickTrue; 01854 manager_hints->initial_state=NormalState; 01855 manager_hints->window_group=windows->image.id; 01856 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints, 01857 &windows->widget); 01858 windows->widget.highlight_stipple=XCreateBitmapFromData(display, 01859 windows->widget.id,(char *) HighlightBitmap,HighlightWidth,HighlightHeight); 01860 windows->widget.shadow_stipple=XCreateBitmapFromData(display, 01861 windows->widget.id,(char *) ShadowBitmap,ShadowWidth,ShadowHeight); 01862 (void) XSetTransientForHint(display,windows->widget.id,windows->image.id); 01863 if (display_image->debug != MagickFalse) 01864 (void) LogMagickEvent(X11Event,GetMagickModule(), 01865 "Window id: 0x%lx (widget)",windows->widget.id); 01866 /* 01867 Initialize popup window. 01868 */ 01869 XGetWindowInfo(display,visual_info,map_info,pixel,font_info, 01870 resource_info,&windows->popup); 01871 windows->popup.border_width=0; 01872 windows->popup.flags|=PPosition; 01873 windows->popup.attributes.event_mask=ButtonMotionMask | ButtonPressMask | 01874 ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask | 01875 KeyReleaseMask | LeaveWindowMask | StructureNotifyMask; 01876 manager_hints->flags=InputHint | StateHint | WindowGroupHint; 01877 manager_hints->input=MagickTrue; 01878 manager_hints->initial_state=NormalState; 01879 manager_hints->window_group=windows->image.id; 01880 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints, 01881 &windows->popup); 01882 windows->popup.highlight_stipple=XCreateBitmapFromData(display, 01883 windows->popup.id,(char *) HighlightBitmap,HighlightWidth,HighlightHeight); 01884 windows->popup.shadow_stipple=XCreateBitmapFromData(display, 01885 windows->popup.id,(char *) ShadowBitmap,ShadowWidth,ShadowHeight); 01886 (void) XSetTransientForHint(display,windows->popup.id,windows->image.id); 01887 if (display_image->debug != MagickFalse) 01888 (void) LogMagickEvent(X11Event,GetMagickModule(), 01889 "Window id: 0x%lx (pop up)",windows->popup.id); 01890 /* 01891 Set out progress and warning handlers. 01892 */ 01893 if (warning_handler == (WarningHandler) NULL) 01894 { 01895 warning_handler=resource_info->display_warnings ? 01896 SetErrorHandler(XWarning) : SetErrorHandler((ErrorHandler) NULL); 01897 warning_handler=resource_info->display_warnings ? 01898 SetWarningHandler(XWarning) : SetWarningHandler((WarningHandler) NULL); 01899 } 01900 /* 01901 Initialize X image structure. 01902 */ 01903 windows->image.x=0; 01904 windows->image.y=0; 01905 /* 01906 Initialize image pixmaps structure. 01907 */ 01908 window_changes.width=(int) windows->image.width; 01909 window_changes.height=(int) windows->image.height; 01910 (void) XReconfigureWMWindow(display,windows->image.id,windows->command.screen, 01911 (unsigned int) (CWWidth | CWHeight),&window_changes); 01912 windows->image.pixmaps=(Pixmap *) AcquireQuantumMemory(number_scenes, 01913 sizeof(*windows->image.pixmaps)); 01914 windows->image.matte_pixmaps=(Pixmap *) AcquireQuantumMemory(number_scenes, 01915 sizeof(*windows->image.pixmaps)); 01916 if ((windows->image.pixmaps == (Pixmap *) NULL) || 01917 (windows->image.matte_pixmaps == (Pixmap *) NULL)) 01918 ThrowXWindowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed", 01919 images->filename); 01920 if ((windows->image.mapped == MagickFalse) || 01921 (windows->backdrop.id != (Window) NULL)) 01922 (void) XMapWindow(display,windows->image.id); 01923 XSetCursorState(display,windows,MagickTrue); 01924 for (scene=0; scene < (ssize_t) number_scenes; scene++) 01925 { 01926 unsigned int 01927 columns, 01928 rows; 01929 01930 /* 01931 Create X image. 01932 */ 01933 (void) TransformImageColorspace(image_list[scene],RGBColorspace,exception); 01934 windows->image.pixmap=(Pixmap) NULL; 01935 windows->image.matte_pixmap=(Pixmap) NULL; 01936 if ((resource_info->map_type != (char *) NULL) || 01937 (visual_info->klass == TrueColor) || 01938 (visual_info->klass == DirectColor)) 01939 if (image_list[scene]->storage_class == PseudoClass) 01940 XGetPixelInfo(display,visual_info,map_info,resource_info, 01941 image_list[scene],windows->image.pixel_info); 01942 columns=(unsigned int) image_list[scene]->columns; 01943 rows=(unsigned int) image_list[scene]->rows; 01944 if ((image_list[scene]->columns != columns) || 01945 (image_list[scene]->rows != rows)) 01946 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateXImage", 01947 image_list[scene]->filename); 01948 status=XMakeImage(display,resource_info,&windows->image,image_list[scene], 01949 columns,rows,exception); 01950 if (status == MagickFalse) 01951 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateXImage", 01952 images->filename); 01953 if (image_list[scene]->debug != MagickFalse) 01954 { 01955 (void) LogMagickEvent(X11Event,GetMagickModule(), 01956 "Image: [%.20g] %s %.20gx%.20g ",(double) image_list[scene]->scene, 01957 image_list[scene]->filename,(double) columns,(double) rows); 01958 if (image_list[scene]->colors != 0) 01959 (void) LogMagickEvent(X11Event,GetMagickModule(),"%.20gc ",(double) 01960 image_list[scene]->colors); 01961 (void) LogMagickEvent(X11Event,GetMagickModule(),"%s", 01962 image_list[scene]->magick); 01963 } 01964 /* 01965 Window name is the base of the filename. 01966 */ 01967 if (resource_info->title != (char *) NULL) 01968 { 01969 char 01970 *title; 01971 01972 title=InterpretImageProperties(resource_info->image_info, 01973 image_list[scene],resource_info->title,exception); 01974 (void) CopyMagickString(windows->image.name,title,MaxTextExtent); 01975 title=DestroyString(title); 01976 } 01977 else 01978 { 01979 p=image_list[scene]->magick_filename+ 01980 strlen(image_list[scene]->magick_filename)-1; 01981 while ((p > image_list[scene]->magick_filename) && (*(p-1) != '/')) 01982 p--; 01983 (void) FormatLocaleString(windows->image.name,MaxTextExtent, 01984 "%s: %s[%.20g of %.20g]",MagickPackageName,p,(double) scene+1, 01985 (double) number_scenes); 01986 } 01987 status=XStringListToTextProperty(&windows->image.name,1,&window_name); 01988 if (status != Success) 01989 { 01990 XSetWMName(display,windows->image.id,&window_name); 01991 (void) XFree((void *) window_name.value); 01992 } 01993 windows->image.pixmaps[scene]=windows->image.pixmap; 01994 windows->image.matte_pixmaps[scene]=windows->image.matte_pixmap; 01995 if (scene == 0) 01996 { 01997 event.xexpose.x=0; 01998 event.xexpose.y=0; 01999 event.xexpose.width=(int) image_list[scene]->columns; 02000 event.xexpose.height=(int) image_list[scene]->rows; 02001 XRefreshWindow(display,&windows->image,&event); 02002 (void) XSync(display,MagickFalse); 02003 } 02004 } 02005 XSetCursorState(display,windows,MagickFalse); 02006 if (windows->command.mapped) 02007 (void) XMapRaised(display,windows->command.id); 02008 /* 02009 Respond to events. 02010 */ 02011 nexus=NewImageList(); 02012 scene=0; 02013 first_scene=0; 02014 iterations=0; 02015 image=image_list[0]; 02016 state=(MagickStatusType) (ForwardAnimationState | RepeatAnimationState); 02017 (void) XMagickCommand(display,resource_info,windows,PlayCommand,&images, 02018 &state,exception); 02019 do 02020 { 02021 if (XEventsQueued(display,QueuedAfterFlush) == 0) 02022 if ((state & PlayAnimationState) || (state & StepAnimationState)) 02023 { 02024 MagickBooleanType 02025 pause; 02026 02027 pause=MagickFalse; 02028 delay=1000*image->delay/MagickMax(image->ticks_per_second,1L); 02029 XDelay(display,resource_info->delay*(delay == 0 ? 10 : delay)); 02030 if (state & ForwardAnimationState) 02031 { 02032 /* 02033 Forward animation: increment scene number. 02034 */ 02035 if (scene < ((ssize_t) number_scenes-1)) 02036 scene++; 02037 else 02038 { 02039 iterations++; 02040 if (iterations == (ssize_t) image_list[0]->iterations) 02041 { 02042 iterations=0; 02043 state|=ExitState; 02044 } 02045 if ((state & AutoReverseAnimationState) != 0) 02046 { 02047 state&=(~ForwardAnimationState); 02048 scene--; 02049 } 02050 else 02051 { 02052 if ((state & RepeatAnimationState) == 0) 02053 state&=(~PlayAnimationState); 02054 scene=first_scene; 02055 pause=MagickTrue; 02056 } 02057 } 02058 } 02059 else 02060 { 02061 /* 02062 Reverse animation: decrement scene number. 02063 */ 02064 if (scene > first_scene) 02065 scene--; 02066 else 02067 { 02068 iterations++; 02069 if (iterations == (ssize_t) image_list[0]->iterations) 02070 { 02071 iterations=0; 02072 state&=(~RepeatAnimationState); 02073 } 02074 if (state & AutoReverseAnimationState) 02075 { 02076 state|=ForwardAnimationState; 02077 scene=first_scene; 02078 pause=MagickTrue; 02079 } 02080 else 02081 { 02082 if ((state & RepeatAnimationState) == MagickFalse) 02083 state&=(~PlayAnimationState); 02084 scene=(ssize_t) number_scenes-1; 02085 } 02086 } 02087 } 02088 scene=MagickMax(scene,0); 02089 image=image_list[scene]; 02090 if ((image != (Image *) NULL) && (image->start_loop != 0)) 02091 first_scene=scene; 02092 if ((state & StepAnimationState) || 02093 (resource_info->title != (char *) NULL)) 02094 { 02095 /* 02096 Update window title. 02097 */ 02098 p=image_list[scene]->filename+ 02099 strlen(image_list[scene]->filename)-1; 02100 while ((p > image_list[scene]->filename) && (*(p-1) != '/')) 02101 p--; 02102 (void) FormatLocaleString(windows->image.name,MaxTextExtent, 02103 "%s: %s[%.20g of %.20g]",MagickPackageName,p,(double) 02104 scene+1,(double) number_scenes); 02105 if (resource_info->title != (char *) NULL) 02106 { 02107 char 02108 *title; 02109 02110 title=InterpretImageProperties(resource_info->image_info, 02111 image,resource_info->title,exception); 02112 (void) CopyMagickString(windows->image.name,title, 02113 MaxTextExtent); 02114 title=DestroyString(title); 02115 } 02116 status=XStringListToTextProperty(&windows->image.name,1, 02117 &window_name); 02118 if (status != Success) 02119 { 02120 XSetWMName(display,windows->image.id,&window_name); 02121 (void) XFree((void *) window_name.value); 02122 } 02123 } 02124 /* 02125 Copy X pixmap to Image window. 02126 */ 02127 XGetPixelInfo(display,visual_info,map_info,resource_info, 02128 image_list[scene],windows->image.pixel_info); 02129 windows->image.ximage->width=(int) image->columns; 02130 windows->image.ximage->height=(int) image->rows; 02131 windows->image.pixmap=windows->image.pixmaps[scene]; 02132 windows->image.matte_pixmap=windows->image.matte_pixmaps[scene]; 02133 event.xexpose.x=0; 02134 event.xexpose.y=0; 02135 event.xexpose.width=(int) image->columns; 02136 event.xexpose.height=(int) image->rows; 02137 if ((state & ExitState) == 0) 02138 { 02139 XRefreshWindow(display,&windows->image,&event); 02140 (void) XSync(display,MagickFalse); 02141 } 02142 state&=(~StepAnimationState); 02143 if (pause != MagickFalse) 02144 for (i=0; i < (ssize_t) resource_info->pause; i++) 02145 { 02146 int 02147 status; 02148 02149 status=XCheckTypedWindowEvent(display,windows->image.id,KeyPress, 02150 &event); 02151 if (status != 0) 02152 { 02153 int 02154 length; 02155 02156 length=XLookupString((XKeyEvent *) &event.xkey,command,(int) 02157 sizeof(command),&key_symbol,(XComposeStatus *) NULL); 02158 *(command+length)='\0'; 02159 if ((key_symbol == XK_q) || (key_symbol == XK_Escape)) 02160 { 02161 XClientMessage(display,windows->image.id, 02162 windows->im_protocols,windows->im_exit,CurrentTime); 02163 break; 02164 } 02165 } 02166 (void) sleep(1); 02167 } 02168 continue; 02169 } 02170 /* 02171 Handle a window event. 02172 */ 02173 timestamp=time((time_t *) NULL); 02174 (void) XNextEvent(display,&event); 02175 if (windows->image.stasis == MagickFalse) 02176 windows->image.stasis=(time((time_t *) NULL)-timestamp) > 0 ? 02177 MagickTrue : MagickFalse; 02178 if (event.xany.window == windows->command.id) 02179 { 02180 int 02181 id; 02182 02183 /* 02184 Select a command from the Command widget. 02185 */ 02186 id=XCommandWidget(display,windows,CommandMenu,&event); 02187 if (id < 0) 02188 continue; 02189 (void) CopyMagickString(command,CommandMenu[id],MaxTextExtent); 02190 command_type=CommandMenus[id]; 02191 if (id < MagickMenus) 02192 { 02193 int 02194 entry; 02195 02196 /* 02197 Select a command from a pop-up menu. 02198 */ 02199 entry=XMenuWidget(display,windows,CommandMenu[id],Menus[id], 02200 command); 02201 if (entry < 0) 02202 continue; 02203 (void) CopyMagickString(command,Menus[id][entry],MaxTextExtent); 02204 command_type=Commands[id][entry]; 02205 } 02206 if (command_type != NullCommand) 02207 nexus=XMagickCommand(display,resource_info,windows, 02208 command_type,&image,&state,exception); 02209 continue; 02210 } 02211 switch (event.type) 02212 { 02213 case ButtonPress: 02214 { 02215 if (display_image->debug != MagickFalse) 02216 (void) LogMagickEvent(X11Event,GetMagickModule(), 02217 "Button Press: 0x%lx %u +%d+%d",event.xbutton.window, 02218 event.xbutton.button,event.xbutton.x,event.xbutton.y); 02219 if ((event.xbutton.button == Button3) && 02220 (event.xbutton.state & Mod1Mask)) 02221 { 02222 /* 02223 Convert Alt-Button3 to Button2. 02224 */ 02225 event.xbutton.button=Button2; 02226 event.xbutton.state&=(~Mod1Mask); 02227 } 02228 if (event.xbutton.window == windows->backdrop.id) 02229 { 02230 (void) XSetInputFocus(display,event.xbutton.window,RevertToParent, 02231 event.xbutton.time); 02232 break; 02233 } 02234 if (event.xbutton.window == windows->image.id) 02235 { 02236 if (resource_info->immutable != MagickFalse) 02237 { 02238 state|=ExitState; 02239 break; 02240 } 02241 /* 02242 Map/unmap Command widget. 02243 */ 02244 if (windows->command.mapped) 02245 (void) XWithdrawWindow(display,windows->command.id, 02246 windows->command.screen); 02247 else 02248 { 02249 (void) XCommandWidget(display,windows,CommandMenu, 02250 (XEvent *) NULL); 02251 (void) XMapRaised(display,windows->command.id); 02252 } 02253 } 02254 break; 02255 } 02256 case ButtonRelease: 02257 { 02258 if (display_image->debug != MagickFalse) 02259 (void) LogMagickEvent(X11Event,GetMagickModule(), 02260 "Button Release: 0x%lx %u +%d+%d",event.xbutton.window, 02261 event.xbutton.button,event.xbutton.x,event.xbutton.y); 02262 break; 02263 } 02264 case ClientMessage: 02265 { 02266 if (display_image->debug != MagickFalse) 02267 (void) LogMagickEvent(X11Event,GetMagickModule(), 02268 "Client Message: 0x%lx 0x%lx %d 0x%lx",(unsigned long) 02269 event.xclient.window,(unsigned long) event.xclient.message_type, 02270 event.xclient.format,(unsigned long) event.xclient.data.l[0]); 02271 if (event.xclient.message_type == windows->im_protocols) 02272 { 02273 if (*event.xclient.data.l == (long) windows->im_update_colormap) 02274 { 02275 /* 02276 Update graphic context and window colormap. 02277 */ 02278 for (i=0; i < (ssize_t) number_windows; i++) 02279 { 02280 if (magick_windows[i]->id == windows->icon.id) 02281 continue; 02282 context_values.background=pixel->background_color.pixel; 02283 context_values.foreground=pixel->foreground_color.pixel; 02284 (void) XChangeGC(display,magick_windows[i]->annotate_context, 02285 context_mask,&context_values); 02286 (void) XChangeGC(display,magick_windows[i]->widget_context, 02287 context_mask,&context_values); 02288 context_values.background=pixel->foreground_color.pixel; 02289 context_values.foreground=pixel->background_color.pixel; 02290 context_values.plane_mask= 02291 context_values.background ^ context_values.foreground; 02292 (void) XChangeGC(display,magick_windows[i]->highlight_context, 02293 (size_t) (context_mask | GCPlaneMask), 02294 &context_values); 02295 magick_windows[i]->attributes.background_pixel= 02296 pixel->background_color.pixel; 02297 magick_windows[i]->attributes.border_pixel= 02298 pixel->border_color.pixel; 02299 magick_windows[i]->attributes.colormap=map_info->colormap; 02300 (void) XChangeWindowAttributes(display,magick_windows[i]->id, 02301 (unsigned long) magick_windows[i]->mask, 02302 &magick_windows[i]->attributes); 02303 } 02304 if (windows->backdrop.id != (Window) NULL) 02305 (void) XInstallColormap(display,map_info->colormap); 02306 break; 02307 } 02308 if (*event.xclient.data.l == (long) windows->im_exit) 02309 { 02310 state|=ExitState; 02311 break; 02312 } 02313 break; 02314 } 02315 if (event.xclient.message_type == windows->dnd_protocols) 02316 { 02317 Atom 02318 selection, 02319 type; 02320 02321 int 02322 format, 02323 status; 02324 02325 unsigned char 02326 *data; 02327 02328 unsigned long 02329 after, 02330 length; 02331 02332 /* 02333 Display image named by the Drag-and-Drop selection. 02334 */ 02335 if ((*event.xclient.data.l != 2) && (*event.xclient.data.l != 128)) 02336 break; 02337 selection=XInternAtom(display,"DndSelection",MagickFalse); 02338 status=XGetWindowProperty(display,root_window,selection,0L,2047L, 02339 MagickFalse,(Atom) AnyPropertyType,&type,&format,&length,&after, 02340 &data); 02341 if ((status != Success) || (length == 0)) 02342 break; 02343 if (*event.xclient.data.l == 2) 02344 { 02345 /* 02346 Offix DND. 02347 */ 02348 (void) CopyMagickString(resource_info->image_info->filename, 02349 (char *) data,MaxTextExtent); 02350 } 02351 else 02352 { 02353 /* 02354 XDND. 02355 */ 02356 if (LocaleNCompare((char *) data,"file:",5) != 0) 02357 { 02358 (void) XFree((void *) data); 02359 break; 02360 } 02361 (void) CopyMagickString(resource_info->image_info->filename, 02362 ((char *) data)+5,MaxTextExtent); 02363 } 02364 nexus=ReadImage(resource_info->image_info,exception); 02365 CatchException(exception); 02366 if (nexus != (Image *) NULL) 02367 state|=ExitState; 02368 (void) XFree((void *) data); 02369 break; 02370 } 02371 /* 02372 If client window delete message, exit. 02373 */ 02374 if (event.xclient.message_type != windows->wm_protocols) 02375 break; 02376 if (*event.xclient.data.l == (long) windows->wm_take_focus) 02377 { 02378 (void) XSetInputFocus(display,event.xclient.window,RevertToParent, 02379 (Time) event.xclient.data.l[1]); 02380 break; 02381 } 02382 if (*event.xclient.data.l != (long) windows->wm_delete_window) 02383 break; 02384 (void) XWithdrawWindow(display,event.xclient.window, 02385 visual_info->screen); 02386 if (event.xclient.window == windows->image.id) 02387 { 02388 state|=ExitState; 02389 break; 02390 } 02391 break; 02392 } 02393 case ConfigureNotify: 02394 { 02395 if (display_image->debug != MagickFalse) 02396 (void) LogMagickEvent(X11Event,GetMagickModule(), 02397 "Configure Notify: 0x%lx %dx%d+%d+%d %d",event.xconfigure.window, 02398 event.xconfigure.width,event.xconfigure.height,event.xconfigure.x, 02399 event.xconfigure.y,event.xconfigure.send_event); 02400 if (event.xconfigure.window == windows->image.id) 02401 { 02402 if (event.xconfigure.send_event != 0) 02403 { 02404 XWindowChanges 02405 window_changes; 02406 02407 /* 02408 Position the transient windows relative of the Image window. 02409 */ 02410 if (windows->command.geometry == (char *) NULL) 02411 if (windows->command.mapped == MagickFalse) 02412 { 02413 windows->command.x= 02414 event.xconfigure.x-windows->command.width-25; 02415 windows->command.y=event.xconfigure.y; 02416 XConstrainWindowPosition(display,&windows->command); 02417 window_changes.x=windows->command.x; 02418 window_changes.y=windows->command.y; 02419 (void) XReconfigureWMWindow(display,windows->command.id, 02420 windows->command.screen,(unsigned int) (CWX | CWY), 02421 &window_changes); 02422 } 02423 if (windows->widget.geometry == (char *) NULL) 02424 if (windows->widget.mapped == MagickFalse) 02425 { 02426 windows->widget.x= 02427 event.xconfigure.x+event.xconfigure.width/10; 02428 windows->widget.y= 02429 event.xconfigure.y+event.xconfigure.height/10; 02430 XConstrainWindowPosition(display,&windows->widget); 02431 window_changes.x=windows->widget.x; 02432 window_changes.y=windows->widget.y; 02433 (void) XReconfigureWMWindow(display,windows->widget.id, 02434 windows->widget.screen,(unsigned int) (CWX | CWY), 02435 &window_changes); 02436 } 02437 } 02438 /* 02439 Image window has a new configuration. 02440 */ 02441 windows->image.width=(unsigned int) event.xconfigure.width; 02442 windows->image.height=(unsigned int) event.xconfigure.height; 02443 break; 02444 } 02445 if (event.xconfigure.window == windows->icon.id) 02446 { 02447 /* 02448 Icon window has a new configuration. 02449 */ 02450 windows->icon.width=(unsigned int) event.xconfigure.width; 02451 windows->icon.height=(unsigned int) event.xconfigure.height; 02452 break; 02453 } 02454 break; 02455 } 02456 case DestroyNotify: 02457 { 02458 /* 02459 Group leader has exited. 02460 */ 02461 if (display_image->debug != MagickFalse) 02462 (void) LogMagickEvent(X11Event,GetMagickModule(), 02463 "Destroy Notify: 0x%lx",event.xdestroywindow.window); 02464 if (event.xdestroywindow.window == windows->group_leader.id) 02465 { 02466 state|=ExitState; 02467 break; 02468 } 02469 break; 02470 } 02471 case EnterNotify: 02472 { 02473 /* 02474 Selectively install colormap. 02475 */ 02476 if (map_info->colormap != XDefaultColormap(display,visual_info->screen)) 02477 if (event.xcrossing.mode != NotifyUngrab) 02478 XInstallColormap(display,map_info->colormap); 02479 break; 02480 } 02481 case Expose: 02482 { 02483 if (display_image->debug != MagickFalse) 02484 (void) LogMagickEvent(X11Event,GetMagickModule(), 02485 "Expose: 0x%lx %dx%d+%d+%d",event.xexpose.window, 02486 event.xexpose.width,event.xexpose.height,event.xexpose.x, 02487 event.xexpose.y); 02488 /* 02489 Repaint windows that are now exposed. 02490 */ 02491 if (event.xexpose.window == windows->image.id) 02492 { 02493 windows->image.pixmap=windows->image.pixmaps[scene]; 02494 windows->image.matte_pixmap=windows->image.matte_pixmaps[scene]; 02495 XRefreshWindow(display,&windows->image,&event); 02496 break; 02497 } 02498 if (event.xexpose.window == windows->icon.id) 02499 if (event.xexpose.count == 0) 02500 { 02501 XRefreshWindow(display,&windows->icon,&event); 02502 break; 02503 } 02504 break; 02505 } 02506 case KeyPress: 02507 { 02508 static int 02509 length; 02510 02511 /* 02512 Respond to a user key press. 02513 */ 02514 length=XLookupString((XKeyEvent *) &event.xkey,command,(int) 02515 sizeof(command),&key_symbol,(XComposeStatus *) NULL); 02516 *(command+length)='\0'; 02517 if (display_image->debug != MagickFalse) 02518 (void) LogMagickEvent(X11Event,GetMagickModule(), 02519 "Key press: 0x%lx (%c)",(unsigned long) key_symbol,*command); 02520 command_type=NullCommand; 02521 switch (key_symbol) 02522 { 02523 case XK_o: 02524 { 02525 if ((event.xkey.state & ControlMask) == MagickFalse) 02526 break; 02527 command_type=OpenCommand; 02528 break; 02529 } 02530 case XK_BackSpace: 02531 { 02532 command_type=StepBackwardCommand; 02533 break; 02534 } 02535 case XK_space: 02536 { 02537 command_type=StepForwardCommand; 02538 break; 02539 } 02540 case XK_less: 02541 { 02542 command_type=FasterCommand; 02543 break; 02544 } 02545 case XK_greater: 02546 { 02547 command_type=SlowerCommand; 02548 break; 02549 } 02550 case XK_F1: 02551 { 02552 command_type=HelpCommand; 02553 break; 02554 } 02555 case XK_Find: 02556 { 02557 command_type=BrowseDocumentationCommand; 02558 break; 02559 } 02560 case XK_question: 02561 { 02562 command_type=InfoCommand; 02563 break; 02564 } 02565 case XK_q: 02566 case XK_Escape: 02567 { 02568 command_type=QuitCommand; 02569 break; 02570 } 02571 default: 02572 break; 02573 } 02574 if (command_type != NullCommand) 02575 nexus=XMagickCommand(display,resource_info,windows, 02576 command_type,&image,&state,exception); 02577 break; 02578 } 02579 case KeyRelease: 02580 { 02581 /* 02582 Respond to a user key release. 02583 */ 02584 (void) XLookupString((XKeyEvent *) &event.xkey,command,(int) 02585 sizeof(command),&key_symbol,(XComposeStatus *) NULL); 02586 if (display_image->debug != MagickFalse) 02587 (void) LogMagickEvent(X11Event,GetMagickModule(), 02588 "Key release: 0x%lx (%c)",(unsigned long) key_symbol,*command); 02589 break; 02590 } 02591 case LeaveNotify: 02592 { 02593 /* 02594 Selectively uninstall colormap. 02595 */ 02596 if (map_info->colormap != XDefaultColormap(display,visual_info->screen)) 02597 if (event.xcrossing.mode != NotifyUngrab) 02598 XUninstallColormap(display,map_info->colormap); 02599 break; 02600 } 02601 case MapNotify: 02602 { 02603 if (display_image->debug != MagickFalse) 02604 (void) LogMagickEvent(X11Event,GetMagickModule(),"Map Notify: 0x%lx", 02605 event.xmap.window); 02606 if (event.xmap.window == windows->backdrop.id) 02607 { 02608 (void) XSetInputFocus(display,event.xmap.window,RevertToParent, 02609 CurrentTime); 02610 windows->backdrop.mapped=MagickTrue; 02611 break; 02612 } 02613 if (event.xmap.window == windows->image.id) 02614 { 02615 if (windows->backdrop.id != (Window) NULL) 02616 (void) XInstallColormap(display,map_info->colormap); 02617 if (LocaleCompare(image_list[0]->magick,"LOGO") == 0) 02618 { 02619 if (LocaleCompare(display_image->filename,"LOGO") == 0) 02620 nexus=XMagickCommand(display,resource_info,windows, 02621 OpenCommand,&image,&state,exception); 02622 else 02623 state|=ExitState; 02624 } 02625 windows->image.mapped=MagickTrue; 02626 break; 02627 } 02628 if (event.xmap.window == windows->info.id) 02629 { 02630 windows->info.mapped=MagickTrue; 02631 break; 02632 } 02633 if (event.xmap.window == windows->icon.id) 02634 { 02635 /* 02636 Create an icon image. 02637 */ 02638 XMakeStandardColormap(display,icon_visual,icon_resources, 02639 display_image,icon_map,icon_pixel,exception); 02640 (void) XMakeImage(display,icon_resources,&windows->icon, 02641 display_image,windows->icon.width,windows->icon.height, 02642 exception); 02643 (void) XSetWindowBackgroundPixmap(display,windows->icon.id, 02644 windows->icon.pixmap); 02645 (void) XClearWindow(display,windows->icon.id); 02646 (void) XWithdrawWindow(display,windows->info.id, 02647 windows->info.screen); 02648 windows->icon.mapped=MagickTrue; 02649 break; 02650 } 02651 if (event.xmap.window == windows->command.id) 02652 { 02653 windows->command.mapped=MagickTrue; 02654 break; 02655 } 02656 if (event.xmap.window == windows->popup.id) 02657 { 02658 windows->popup.mapped=MagickTrue; 02659 break; 02660 } 02661 if (event.xmap.window == windows->widget.id) 02662 { 02663 windows->widget.mapped=MagickTrue; 02664 break; 02665 } 02666 break; 02667 } 02668 case MappingNotify: 02669 { 02670 (void) XRefreshKeyboardMapping(&event.xmapping); 02671 break; 02672 } 02673 case NoExpose: 02674 break; 02675 case PropertyNotify: 02676 { 02677 Atom 02678 type; 02679 02680 int 02681 format, 02682 status; 02683 02684 unsigned char 02685 *data; 02686 02687 unsigned long 02688 after, 02689 length; 02690 02691 if (display_image->debug != MagickFalse) 02692 (void) LogMagickEvent(X11Event,GetMagickModule(), 02693 "Property Notify: 0x%lx 0x%lx %d",(unsigned long) 02694 event.xproperty.window,(unsigned long) event.xproperty.atom, 02695 event.xproperty.state); 02696 if (event.xproperty.atom != windows->im_remote_command) 02697 break; 02698 /* 02699 Display image named by the remote command protocol. 02700 */ 02701 status=XGetWindowProperty(display,event.xproperty.window, 02702 event.xproperty.atom,0L,(long) MaxTextExtent,MagickFalse,(Atom) 02703 AnyPropertyType,&type,&format,&length,&after,&data); 02704 if ((status != Success) || (length == 0)) 02705 break; 02706 (void) CopyMagickString(resource_info->image_info->filename, 02707 (char *) data,MaxTextExtent); 02708 nexus=ReadImage(resource_info->image_info,exception); 02709 CatchException(exception); 02710 if (nexus != (Image *) NULL) 02711 state|=ExitState; 02712 (void) XFree((void *) data); 02713 break; 02714 } 02715 case ReparentNotify: 02716 { 02717 if (display_image->debug != MagickFalse) 02718 (void) LogMagickEvent(X11Event,GetMagickModule(), 02719 "Reparent Notify: 0x%lx=>0x%lx",event.xreparent.parent, 02720 event.xreparent.window); 02721 break; 02722 } 02723 case UnmapNotify: 02724 { 02725 if (display_image->debug != MagickFalse) 02726 (void) LogMagickEvent(X11Event,GetMagickModule(), 02727 "Unmap Notify: 0x%lx",event.xunmap.window); 02728 if (event.xunmap.window == windows->backdrop.id) 02729 { 02730 windows->backdrop.mapped=MagickFalse; 02731 break; 02732 } 02733 if (event.xunmap.window == windows->image.id) 02734 { 02735 windows->image.mapped=MagickFalse; 02736 break; 02737 } 02738 if (event.xunmap.window == windows->info.id) 02739 { 02740 windows->info.mapped=MagickFalse; 02741 break; 02742 } 02743 if (event.xunmap.window == windows->icon.id) 02744 { 02745 if (map_info->colormap == icon_map->colormap) 02746 XConfigureImageColormap(display,resource_info,windows, 02747 display_image,exception); 02748 (void) XFreeStandardColormap(display,icon_visual,icon_map, 02749 icon_pixel); 02750 windows->icon.mapped=MagickFalse; 02751 break; 02752 } 02753 if (event.xunmap.window == windows->command.id) 02754 { 02755 windows->command.mapped=MagickFalse; 02756 break; 02757 } 02758 if (event.xunmap.window == windows->popup.id) 02759 { 02760 if (windows->backdrop.id != (Window) NULL) 02761 (void) XSetInputFocus(display,windows->image.id,RevertToParent, 02762 CurrentTime); 02763 windows->popup.mapped=MagickFalse; 02764 break; 02765 } 02766 if (event.xunmap.window == windows->widget.id) 02767 { 02768 if (windows->backdrop.id != (Window) NULL) 02769 (void) XSetInputFocus(display,windows->image.id,RevertToParent, 02770 CurrentTime); 02771 windows->widget.mapped=MagickFalse; 02772 break; 02773 } 02774 break; 02775 } 02776 default: 02777 { 02778 if (display_image->debug != MagickFalse) 02779 (void) LogMagickEvent(X11Event,GetMagickModule(),"Event type: %d", 02780 event.type); 02781 break; 02782 } 02783 } 02784 } 02785 while (!(state & ExitState)); 02786 image_list=(Image **) RelinquishMagickMemory(image_list); 02787 images=DestroyImageList(images); 02788 if ((windows->visual_info->klass == GrayScale) || 02789 (windows->visual_info->klass == PseudoColor) || 02790 (windows->visual_info->klass == DirectColor)) 02791 { 02792 /* 02793 Withdraw windows. 02794 */ 02795 if (windows->info.mapped) 02796 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen); 02797 if (windows->command.mapped) 02798 (void) XWithdrawWindow(display,windows->command.id, 02799 windows->command.screen); 02800 } 02801 if (resource_info->backdrop == MagickFalse) 02802 if (windows->backdrop.mapped) 02803 { 02804 (void) XWithdrawWindow(display,windows->backdrop.id,\ 02805 windows->backdrop.screen); 02806 (void) XDestroyWindow(display,windows->backdrop.id); 02807 windows->backdrop.id=(Window) NULL; 02808 (void) XWithdrawWindow(display,windows->image.id,windows->image.screen); 02809 (void) XDestroyWindow(display,windows->image.id); 02810 windows->image.id=(Window) NULL; 02811 } 02812 XSetCursorState(display,windows,MagickTrue); 02813 XCheckRefreshWindows(display,windows); 02814 for (scene=1; scene < (ssize_t) number_scenes; scene++) 02815 { 02816 if (windows->image.pixmaps[scene] != (Pixmap) NULL) 02817 (void) XFreePixmap(display,windows->image.pixmaps[scene]); 02818 windows->image.pixmaps[scene]=(Pixmap) NULL; 02819 if (windows->image.matte_pixmaps[scene] != (Pixmap) NULL) 02820 (void) XFreePixmap(display,windows->image.matte_pixmaps[scene]); 02821 windows->image.matte_pixmaps[scene]=(Pixmap) NULL; 02822 } 02823 XSetCursorState(display,windows,MagickFalse); 02824 windows->image.pixmaps=(Pixmap *) 02825 RelinquishMagickMemory(windows->image.pixmaps); 02826 windows->image.matte_pixmaps=(Pixmap *) 02827 RelinquishMagickMemory(windows->image.matte_pixmaps); 02828 if (nexus == (Image *) NULL) 02829 { 02830 /* 02831 Free X resources. 02832 */ 02833 if (windows->image.mapped != MagickFalse) 02834 (void) XWithdrawWindow(display,windows->image.id,windows->image.screen); XDelay(display,SuspendTime); 02835 (void) XFreeStandardColormap(display,icon_visual,icon_map,icon_pixel); 02836 if (resource_info->map_type == (char *) NULL) 02837 (void) XFreeStandardColormap(display,visual_info,map_info,pixel); 02838 DestroyXResources(); 02839 } 02840 (void) XSync(display,MagickFalse); 02841 /* 02842 Restore our progress monitor and warning handlers. 02843 */ 02844 (void) SetErrorHandler(warning_handler); 02845 (void) SetWarningHandler(warning_handler); 02846 /* 02847 Change to home directory. 02848 */ 02849 directory=getcwd(working_directory,MaxTextExtent); 02850 (void) directory; 02851 status=chdir(resource_info->home_directory); 02852 if (status == -1) 02853 (void) ThrowMagickException(exception,GetMagickModule(),FileOpenError, 02854 "UnableToOpenFile","%s",resource_info->home_directory); 02855 return(nexus); 02856 } 02857 02858 /* 02859 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 02860 % % 02861 % % 02862 % % 02863 + X S a v e I m a g e % 02864 % % 02865 % % 02866 % % 02867 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 02868 % 02869 % XSaveImage() saves an image to a file. 02870 % 02871 % The format of the XSaveImage method is: 02872 % 02873 % MagickBooleanType XSaveImage(Display *display, 02874 % XResourceInfo *resource_info,XWindows *windows,Image *image, 02875 % ExceptionInfo *exception) 02876 % 02877 % A description of each parameter follows: 02878 % 02879 % o status: Method XSaveImage return True if the image is 02880 % written. False is returned is there is a memory shortage or if the 02881 % image fails to write. 02882 % 02883 % o display: Specifies a connection to an X server; returned from 02884 % XOpenDisplay. 02885 % 02886 % o resource_info: Specifies a pointer to a X11 XResourceInfo structure. 02887 % 02888 % o windows: Specifies a pointer to a XWindows structure. 02889 % 02890 % o image: the image. 02891 % 02892 */ 02893 static MagickBooleanType XSaveImage(Display *display, 02894 XResourceInfo *resource_info,XWindows *windows,Image *image, 02895 ExceptionInfo *exception) 02896 { 02897 char 02898 filename[MaxTextExtent]; 02899 02900 ImageInfo 02901 *image_info; 02902 02903 MagickStatusType 02904 status; 02905 02906 /* 02907 Request file name from user. 02908 */ 02909 if (resource_info->write_filename != (char *) NULL) 02910 (void) CopyMagickString(filename,resource_info->write_filename, 02911 MaxTextExtent); 02912 else 02913 { 02914 char 02915 path[MaxTextExtent]; 02916 02917 int 02918 status; 02919 02920 GetPathComponent(image->filename,HeadPath,path); 02921 GetPathComponent(image->filename,TailPath,filename); 02922 status=chdir(path); 02923 if (status == -1) 02924 (void) ThrowMagickException(exception,GetMagickModule(),FileOpenError, 02925 "UnableToOpenFile","%s",path); 02926 } 02927 XFileBrowserWidget(display,windows,"Save",filename); 02928 if (*filename == '\0') 02929 return(MagickTrue); 02930 if (IsPathAccessible(filename) != MagickFalse) 02931 { 02932 int 02933 status; 02934 02935 /* 02936 File exists-- seek user's permission before overwriting. 02937 */ 02938 status=XConfirmWidget(display,windows,"Overwrite",filename); 02939 if (status == 0) 02940 return(MagickTrue); 02941 } 02942 image_info=CloneImageInfo(resource_info->image_info); 02943 (void) CopyMagickString(image_info->filename,filename,MaxTextExtent); 02944 (void) SetImageInfo(image_info,1,exception); 02945 if ((LocaleCompare(image_info->magick,"JPEG") == 0) || 02946 (LocaleCompare(image_info->magick,"JPG") == 0)) 02947 { 02948 char 02949 quality[MaxTextExtent]; 02950 02951 int 02952 status; 02953 02954 /* 02955 Request JPEG quality from user. 02956 */ 02957 (void) FormatLocaleString(quality,MaxTextExtent,"%.20g",(double) 02958 image_info->quality); 02959 status=XDialogWidget(display,windows,"Save","Enter JPEG quality:", 02960 quality); 02961 if (*quality == '\0') 02962 return(MagickTrue); 02963 image->quality=StringToUnsignedLong(quality); 02964 image_info->interlace=status != MagickFalse ? NoInterlace : 02965 PlaneInterlace; 02966 } 02967 if ((LocaleCompare(image_info->magick,"EPS") == 0) || 02968 (LocaleCompare(image_info->magick,"PDF") == 0) || 02969 (LocaleCompare(image_info->magick,"PS") == 0) || 02970 (LocaleCompare(image_info->magick,"PS2") == 0)) 02971 { 02972 char 02973 geometry[MaxTextExtent]; 02974 02975 /* 02976 Request page geometry from user. 02977 */ 02978 (void) CopyMagickString(geometry,PSPageGeometry,MaxTextExtent); 02979 if (LocaleCompare(image_info->magick,"PDF") == 0) 02980 (void) CopyMagickString(geometry,PSPageGeometry,MaxTextExtent); 02981 if (image_info->page != (char *) NULL) 02982 (void) CopyMagickString(geometry,image_info->page,MaxTextExtent); 02983 XListBrowserWidget(display,windows,&windows->widget,PageSizes,"Select", 02984 "Select page geometry:",geometry); 02985 if (*geometry != '\0') 02986 image_info->page=GetPageGeometry(geometry); 02987 } 02988 /* 02989 Write image. 02990 */ 02991 image=GetFirstImageInList(image); 02992 status=WriteImages(image_info,image,filename,exception); 02993 if (status != MagickFalse) 02994 image->taint=MagickFalse; 02995 image_info=DestroyImageInfo(image_info); 02996 XSetCursorState(display,windows,MagickFalse); 02997 return(status != 0 ? MagickTrue : MagickFalse); 02998 } 02999 #else 03000 03001 /* 03002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03003 % % 03004 % % 03005 % % 03006 + A n i m a t e I m a g e s % 03007 % % 03008 % % 03009 % % 03010 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03011 % 03012 % AnimateImages() repeatedly displays an image sequence to any X window 03013 % screen. It returns a value other than 0 if successful. Check the 03014 % exception member of image to determine the reason for any failure. 03015 % 03016 % The format of the AnimateImages method is: 03017 % 03018 % MagickBooleanType AnimateImages(const ImageInfo *image_info, 03019 % Image *images) 03020 % 03021 % A description of each parameter follows: 03022 % 03023 % o image_info: the image info. 03024 % 03025 % o image: the image. 03026 % 03027 % o exception: return any errors or warnings in this structure. 03028 % 03029 */ 03030 MagickExport MagickBooleanType AnimateImages(const ImageInfo *image_info, 03031 Image *image,ExceptionInfo *exception) 03032 { 03033 assert(image_info != (const ImageInfo *) NULL); 03034 assert(image_info->signature == MagickSignature); 03035 assert(image != (Image *) NULL); 03036 assert(image->signature == MagickSignature); 03037 if (image->debug != MagickFalse) 03038 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 03039 (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError, 03040 "DelegateLibrarySupportNotBuiltIn","`%s' (X11)",image->filename); 03041 return(MagickFalse); 03042 } 03043 #endif