00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "magick/studio.h"
00043 #include "magick/animate.h"
00044 #include "magick/animate-private.h"
00045 #include "magick/client.h"
00046 #include "magick/color.h"
00047 #include "magick/color-private.h"
00048 #include "magick/colorspace.h"
00049 #include "magick/constitute.h"
00050 #include "magick/delegate.h"
00051 #include "magick/exception.h"
00052 #include "magick/exception-private.h"
00053 #include "magick/geometry.h"
00054 #include "magick/image-private.h"
00055 #include "magick/layer.h"
00056 #include "magick/list.h"
00057 #include "magick/log.h"
00058 #include "magick/image.h"
00059 #include "magick/memory_.h"
00060 #include "magick/monitor.h"
00061 #include "magick/monitor-private.h"
00062 #include "magick/option.h"
00063 #include "magick/property.h"
00064 #include "magick/resource_.h"
00065 #include "magick/string_.h"
00066 #include "magick/transform.h"
00067 #include "magick/utility.h"
00068 #include "magick/version.h"
00069 #include "magick/widget.h"
00070 #include "magick/xwindow-private.h"
00071
00072 #if defined(MAGICKCORE_X11_DELEGATE)
00073
00074
00075
00076 #define AutoReverseAnimationState 0x0004
00077 #define ForwardAnimationState 0x0008
00078 #define HighlightState 0x0010
00079 #define PlayAnimationState 0x0020
00080 #define RepeatAnimationState 0x0040
00081 #define StepAnimationState 0x0080
00082
00083
00084
00085
00086 static const char
00087 *AnimateHelp[]=
00088 {
00089 "BUTTONS",
00090 "",
00091 " Press any button to map or unmap the Command widget.",
00092 "",
00093 "COMMAND WIDGET",
00094 " The Command widget lists a number of sub-menus and commands.",
00095 " They are",
00096 "",
00097 " Animate",
00098 " Open...",
00099 " Save...",
00100 " Play",
00101 " Step",
00102 " Repeat",
00103 " Auto Reverse",
00104 " Speed",
00105 " Slower",
00106 " Faster",
00107 " Direction",
00108 " Forward",
00109 " Reverse",
00110 " Help",
00111 " Overview",
00112 " Browse Documentation",
00113 " About Animate",
00114 " Image Info",
00115 " Quit",
00116 "",
00117 " Menu items with a indented triangle have a sub-menu. They",
00118 " are represented above as the indented items. To access a",
00119 " sub-menu item, move the pointer to the appropriate menu and",
00120 " press a button and drag. When you find the desired sub-menu",
00121 " item, release the button and the command is executed. Move",
00122 " the pointer away from the sub-menu if you decide not to",
00123 " execute a particular command.",
00124 "",
00125 "KEYBOARD ACCELERATORS",
00126 " Accelerators are one or two key presses that effect a",
00127 " particular command. The keyboard accelerators that",
00128 " animate(1) understands is:",
00129 "",
00130 " Ctl+O Press to open an image from a file.",
00131 "",
00132 " space Press to display the next image in the sequence.",
00133 "",
00134 " < Press to speed-up the display of the images. Refer to",
00135 " -delay for more information.",
00136 "",
00137 " > Press to slow the display of the images. Refer to",
00138 " -delay for more information.",
00139 "",
00140 " F1 Press to display helpful information about animate(1).",
00141 "",
00142 " Find Press to browse documentation about ImageMagick.",
00143 "",
00144 " ? Press to display information about the image. Press",
00145 " any key or button to erase the information.",
00146 "",
00147 " This information is printed: image name; image size;",
00148 " and the total number of unique colors in the image.",
00149 "",
00150 " Ctl-q Press to discard all images and exit program.",
00151 (char *) NULL
00152 };
00153
00154
00155
00156
00157 static const char
00158 *PageSizes[]=
00159 {
00160 "Letter",
00161 "Tabloid",
00162 "Ledger",
00163 "Legal",
00164 "Statement",
00165 "Executive",
00166 "A3",
00167 "A4",
00168 "A5",
00169 "B4",
00170 "B5",
00171 "Folio",
00172 "Quarto",
00173 "10x14",
00174 (char *) NULL
00175 };
00176
00177 static const unsigned char
00178 HighlightBitmap[8] =
00179 {
00180 (unsigned char) 0xaa,
00181 (unsigned char) 0x55,
00182 (unsigned char) 0xaa,
00183 (unsigned char) 0x55,
00184 (unsigned char) 0xaa,
00185 (unsigned char) 0x55,
00186 (unsigned char) 0xaa,
00187 (unsigned char) 0x55
00188 },
00189 ShadowBitmap[8] =
00190 {
00191 (unsigned char) 0x00,
00192 (unsigned char) 0x00,
00193 (unsigned char) 0x00,
00194 (unsigned char) 0x00,
00195 (unsigned char) 0x00,
00196 (unsigned char) 0x00,
00197 (unsigned char) 0x00,
00198 (unsigned char) 0x00
00199 };
00200
00201
00202
00203
00204 typedef enum
00205 {
00206 OpenCommand,
00207 SaveCommand,
00208 PlayCommand,
00209 StepCommand,
00210 RepeatCommand,
00211 AutoReverseCommand,
00212 SlowerCommand,
00213 FasterCommand,
00214 ForwardCommand,
00215 ReverseCommand,
00216 HelpCommand,
00217 BrowseDocumentationCommand,
00218 VersionCommand,
00219 InfoCommand,
00220 QuitCommand,
00221 StepBackwardCommand,
00222 StepForwardCommand,
00223 NullCommand
00224 } CommandType;
00225
00226
00227
00228
00229 #define HighlightWidth 8
00230 #define HighlightHeight 8
00231 #define ShadowWidth 8
00232 #define ShadowHeight 8
00233
00234
00235
00236
00237 static Image
00238 *XMagickCommand(Display *,XResourceInfo *,XWindows *,const CommandType,
00239 Image **,MagickStatusType *);
00240
00241 static MagickBooleanType
00242 XSaveImage(Display *,XResourceInfo *,XWindows *,Image *);
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 MagickExport MagickBooleanType AnimateImages(const ImageInfo *image_info,
00272 Image *images)
00273 {
00274 char
00275 *argv[1];
00276
00277 Display
00278 *display;
00279
00280 MagickStatusType
00281 status;
00282
00283 XrmDatabase
00284 resource_database;
00285
00286 XResourceInfo
00287 resource_info;
00288
00289 assert(image_info != (const ImageInfo *) NULL);
00290 assert(image_info->signature == MagickSignature);
00291 assert(images != (Image *) NULL);
00292 assert(images->signature == MagickSignature);
00293 if (images->debug != MagickFalse)
00294 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
00295 display=XOpenDisplay(image_info->server_name);
00296 if (display == (Display *) NULL)
00297 {
00298 (void) ThrowMagickException(&images->exception,GetMagickModule(),
00299 XServerError,"UnableToOpenXServer","`%s'",XDisplayName(
00300 image_info->server_name));
00301 return(MagickFalse);
00302 }
00303 if (images->exception.severity != UndefinedException)
00304 CatchException(&images->exception);
00305 (void) XSetErrorHandler(XError);
00306 resource_database=XGetResourceDatabase(display,GetClientName());
00307 (void) ResetMagickMemory(&resource_info,0,sizeof(XResourceInfo));
00308 XGetResourceInfo(image_info,resource_database,GetClientName(),&resource_info);
00309 if (image_info->page != (char *) NULL)
00310 resource_info.image_geometry=AcquireString(image_info->page);
00311 resource_info.immutable=MagickTrue;
00312 argv[0]=AcquireString(GetClientName());
00313 (void) XAnimateImages(display,&resource_info,argv,1,images);
00314 argv[0]=DestroyString(argv[0]);
00315 (void) XCloseDisplay(display);
00316 XDestroyResourceInfo(&resource_info);
00317 status=images->exception.severity == UndefinedException ?
00318 MagickTrue : MagickFalse;
00319 return(status != 0 ? MagickTrue : MagickFalse);
00320 }
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 static Image *XMagickCommand(Display *display,XResourceInfo *resource_info,
00360 XWindows *windows,const CommandType command_type,Image **image,
00361 MagickStatusType *state)
00362 {
00363 Image
00364 *nexus;
00365
00366 MagickBooleanType
00367 proceed;
00368
00369 MagickStatusType
00370 status;
00371
00372 XTextProperty
00373 window_name;
00374
00375
00376
00377
00378 nexus=NewImageList();
00379 switch (command_type)
00380 {
00381 case OpenCommand:
00382 {
00383 char
00384 **filelist;
00385
00386 ExceptionInfo
00387 *exception;
00388
00389 Image
00390 *images,
00391 *next;
00392
00393 ImageInfo
00394 *read_info;
00395
00396 int
00397 number_files;
00398
00399 register int
00400 i;
00401
00402 static char
00403 filenames[MaxTextExtent] = "*";
00404
00405 if (resource_info->immutable != MagickFalse)
00406 break;
00407
00408
00409
00410 XFileBrowserWidget(display,windows,"Animate",filenames);
00411 if (*filenames == '\0')
00412 return((Image *) NULL);
00413
00414
00415
00416 filelist=(char **) AcquireMagickMemory(sizeof(char *));
00417 if (filelist == (char **) NULL)
00418 {
00419 ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed",
00420 filenames);
00421 return((Image *) NULL);
00422 }
00423 number_files=1;
00424 filelist[0]=filenames;
00425 status=ExpandFilenames(&number_files,&filelist);
00426 if ((status == MagickFalse) || (number_files == 0))
00427 {
00428 if (number_files == 0)
00429 {
00430 ThrowXWindowException(ImageError,"NoImagesWereLoaded",filenames);
00431 return((Image *) NULL);
00432 }
00433 ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed",
00434 filenames);
00435 return((Image *) NULL);
00436 }
00437 read_info=CloneImageInfo(resource_info->image_info);
00438 exception=AcquireExceptionInfo();
00439 images=NewImageList();
00440 XSetCursorState(display,windows,MagickTrue);
00441 XCheckRefreshWindows(display,windows);
00442 for (i=0; i < number_files; i++)
00443 {
00444 (void) CopyMagickString(read_info->filename,filelist[i],MaxTextExtent);
00445 filelist[i]=DestroyString(filelist[i]);
00446 *read_info->magick='\0';
00447 next=ReadImage(read_info,exception);
00448 CatchException(exception);
00449 if (next != (Image *) NULL)
00450 AppendImageToList(&images,next);
00451 if (number_files <= 5)
00452 continue;
00453 proceed=SetImageProgress(images,LoadImageTag,i,(MagickSizeType)
00454 number_files);
00455 if (proceed == MagickFalse)
00456 break;
00457 }
00458 filelist=(char **) RelinquishMagickMemory(filelist);
00459 exception=DestroyExceptionInfo(exception);
00460 read_info=DestroyImageInfo(read_info);
00461 if (images == (Image *) NULL)
00462 {
00463 XSetCursorState(display,windows,MagickFalse);
00464 ThrowXWindowException(ImageError,"NoImagesWereLoaded",filenames);
00465 return((Image *) NULL);
00466 }
00467 nexus=GetFirstImageInList(images);
00468 *state|=ExitState;
00469 break;
00470 }
00471 case PlayCommand:
00472 {
00473 char
00474 basename[MaxTextExtent];
00475
00476 int
00477 status;
00478
00479
00480
00481
00482 *state|=PlayAnimationState;
00483 *state&=(~AutoReverseAnimationState);
00484 GetPathComponent((*image)->magick_filename,BasePath,basename);
00485 (void) FormatMagickString(windows->image.name,MaxTextExtent,
00486 "ImageMagick: %s",basename);
00487 if (resource_info->title != (char *) NULL)
00488 {
00489 char
00490 *title;
00491
00492 title=InterpretImageProperties(resource_info->image_info,*image,
00493 resource_info->title);
00494 (void) CopyMagickString(windows->image.name,title,MaxTextExtent);
00495 title=DestroyString(title);
00496 }
00497 status=XStringListToTextProperty(&windows->image.name,1,&window_name);
00498 if (status == 0)
00499 break;
00500 XSetWMName(display,windows->image.id,&window_name);
00501 (void) XFree((void *) window_name.value);
00502 break;
00503 }
00504 case StepCommand:
00505 case StepBackwardCommand:
00506 case StepForwardCommand:
00507 {
00508 *state|=StepAnimationState;
00509 *state&=(~PlayAnimationState);
00510 if (command_type == StepBackwardCommand)
00511 *state&=(~ForwardAnimationState);
00512 if (command_type == StepForwardCommand)
00513 *state|=ForwardAnimationState;
00514 if (resource_info->title != (char *) NULL)
00515 break;
00516 break;
00517 }
00518 case RepeatCommand:
00519 {
00520 *state|=RepeatAnimationState;
00521 *state&=(~AutoReverseAnimationState);
00522 *state|=PlayAnimationState;
00523 break;
00524 }
00525 case AutoReverseCommand:
00526 {
00527 *state|=AutoReverseAnimationState;
00528 *state&=(~RepeatAnimationState);
00529 *state|=PlayAnimationState;
00530 break;
00531 }
00532 case SaveCommand:
00533 {
00534
00535
00536
00537 status=XSaveImage(display,resource_info,windows,*image);
00538 if (status == MagickFalse)
00539 {
00540 XNoticeWidget(display,windows,"Unable to write X image:",
00541 (*image)->filename);
00542 break;
00543 }
00544 break;
00545 }
00546 case SlowerCommand:
00547 {
00548 resource_info->delay++;
00549 break;
00550 }
00551 case FasterCommand:
00552 {
00553 if (resource_info->delay == 0)
00554 break;
00555 resource_info->delay--;
00556 break;
00557 }
00558 case ForwardCommand:
00559 {
00560 *state=ForwardAnimationState;
00561 *state&=(~AutoReverseAnimationState);
00562 break;
00563 }
00564 case ReverseCommand:
00565 {
00566 *state&=(~ForwardAnimationState);
00567 *state&=(~AutoReverseAnimationState);
00568 break;
00569 }
00570 case InfoCommand:
00571 {
00572 XDisplayImageInfo(display,resource_info,windows,(Image *) NULL,*image);
00573 break;
00574 }
00575 case HelpCommand:
00576 {
00577
00578
00579
00580 XTextViewWidget(display,resource_info,windows,MagickFalse,
00581 "Help Viewer - Animate",AnimateHelp);
00582 break;
00583 }
00584 case BrowseDocumentationCommand:
00585 {
00586 Atom
00587 mozilla_atom;
00588
00589 Window
00590 mozilla_window,
00591 root_window;
00592
00593
00594
00595
00596 root_window=XRootWindow(display,XDefaultScreen(display));
00597 mozilla_atom=XInternAtom(display,"_MOZILLA_VERSION",MagickFalse);
00598 mozilla_window=XWindowByProperty(display,root_window,mozilla_atom);
00599 if (mozilla_window != (Window) NULL)
00600 {
00601 char
00602 command[MaxTextExtent],
00603 *url;
00604
00605
00606
00607
00608 url=GetMagickHomeURL();
00609 (void) FormatMagickString(command,MaxTextExtent,
00610 "openurl(%s,new-tab)",url);
00611 url=DestroyString(url);
00612 mozilla_atom=XInternAtom(display,"_MOZILLA_COMMAND",MagickFalse);
00613 (void) XChangeProperty(display,mozilla_window,mozilla_atom,
00614 XA_STRING,8,PropModeReplace,(unsigned char *) command,
00615 (int) strlen(command));
00616 XSetCursorState(display,windows,MagickFalse);
00617 break;
00618 }
00619 XSetCursorState(display,windows,MagickTrue);
00620 XCheckRefreshWindows(display,windows);
00621 status=InvokeDelegate(resource_info->image_info,*image,"browse",
00622 (char *) NULL,&(*image)->exception);
00623 if (status == MagickFalse)
00624 XNoticeWidget(display,windows,"Unable to browse documentation",
00625 (char *) NULL);
00626 XDelay(display,1500);
00627 XSetCursorState(display,windows,MagickFalse);
00628 break;
00629 }
00630 case VersionCommand:
00631 {
00632 XNoticeWidget(display,windows,GetMagickVersion((unsigned long *) NULL),
00633 GetMagickCopyright());
00634 break;
00635 }
00636 case QuitCommand:
00637 {
00638
00639
00640
00641 if (resource_info->confirm_exit == MagickFalse)
00642 XClientMessage(display,windows->image.id,windows->im_protocols,
00643 windows->im_exit,CurrentTime);
00644 else
00645 {
00646 int
00647 status;
00648
00649
00650
00651
00652 status=XConfirmWidget(display,windows,"Do you really want to exit",
00653 resource_info->client_name);
00654 if (status != 0)
00655 XClientMessage(display,windows->image.id,windows->im_protocols,
00656 windows->im_exit,CurrentTime);
00657 }
00658 break;
00659 }
00660 default:
00661 break;
00662 }
00663 return(nexus);
00664 }
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696 static inline long MagickMax(const long x,const long y)
00697 {
00698 if (x > y)
00699 return(x);
00700 return(y);
00701 }
00702
00703 #if defined(__cplusplus) || defined(c_plusplus)
00704 extern "C" {
00705 #endif
00706
00707 static int SceneCompare(const void *x,const void *y)
00708 {
00709 const Image
00710 **image_1,
00711 **image_2;
00712
00713 image_1=(const Image **) x;
00714 image_2=(const Image **) y;
00715 return((int) ((*image_1)->scene-(*image_2)->scene));
00716 }
00717
00718 #if defined(__cplusplus) || defined(c_plusplus)
00719 }
00720 #endif
00721
00722 MagickExport void XAnimateBackgroundImage(Display *display,
00723 XResourceInfo *resource_info,Image *images)
00724 {
00725 char
00726 geometry[MaxTextExtent],
00727 visual_type[MaxTextExtent];
00728
00729 Image
00730 *coalesce_image,
00731 *display_image,
00732 **image_list;
00733
00734 int
00735 scene;
00736
00737 MagickStatusType
00738 status;
00739
00740 RectangleInfo
00741 geometry_info;
00742
00743 register long
00744 i;
00745
00746 size_t
00747 number_scenes;
00748
00749 static XPixelInfo
00750 pixel;
00751
00752 static XStandardColormap
00753 *map_info;
00754
00755 static XVisualInfo
00756 *visual_info = (XVisualInfo *) NULL;
00757
00758 static XWindowInfo
00759 window_info;
00760
00761 unsigned int
00762 height,
00763 width;
00764
00765 unsigned long
00766 delay;
00767
00768 Window
00769 root_window;
00770
00771 XEvent
00772 event;
00773
00774 XGCValues
00775 context_values;
00776
00777 XResourceInfo
00778 resources;
00779
00780 XWindowAttributes
00781 window_attributes;
00782
00783
00784
00785
00786 assert(images != (Image *) NULL);
00787 assert(images->signature == MagickSignature);
00788 if (images->debug != MagickFalse)
00789 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
00790 resources=(*resource_info);
00791 window_info.id=(Window) NULL;
00792 root_window=XRootWindow(display,XDefaultScreen(display));
00793 if (LocaleCompare(resources.window_id,"root") == 0)
00794 window_info.id=root_window;
00795 else
00796 {
00797 if (isdigit((int) ((unsigned char) *resources.window_id)) != 0)
00798 window_info.id=XWindowByID(display,root_window,
00799 (Window) strtol((char *) resources.window_id,(char **) NULL,0));
00800 if (window_info.id == (Window) NULL)
00801 window_info.id=
00802 XWindowByName(display,root_window,resources.window_id);
00803 }
00804 if (window_info.id == (Window) NULL)
00805 {
00806 ThrowXWindowException(XServerError,"NoWindowWithSpecifiedIDExists",
00807 resources.window_id);
00808 return;
00809 }
00810
00811
00812
00813 window_attributes.width=XDisplayWidth(display,XDefaultScreen(display));
00814 window_attributes.height=XDisplayHeight(display,XDefaultScreen(display));
00815 (void) CopyMagickString(visual_type,"default",MaxTextExtent);
00816 status=XGetWindowAttributes(display,window_info.id,&window_attributes) != 0 ?
00817 MagickTrue : MagickFalse;
00818 if (status != MagickFalse)
00819 (void) FormatMagickString(visual_type,MaxTextExtent,"0x%lx",
00820 XVisualIDFromVisual(window_attributes.visual));
00821 if (visual_info == (XVisualInfo *) NULL)
00822 {
00823
00824
00825
00826 map_info=XAllocStandardColormap();
00827 if (map_info == (XStandardColormap *) NULL)
00828 ThrowXWindowFatalException(ResourceLimitError,"MemoryAllocationFailed",
00829 images->filename);
00830 map_info->colormap=(Colormap) NULL;
00831 pixel.pixels=(unsigned long *) NULL;
00832
00833
00834
00835 resources.map_type=(char *) NULL;
00836 resources.visual_type=visual_type;
00837 visual_info=XBestVisualInfo(display,map_info,&resources);
00838 if (visual_info == (XVisualInfo *) NULL)
00839 ThrowXWindowFatalException(XServerFatalError,"UnableToGetVisual",
00840 images->filename);
00841
00842
00843
00844 window_info.ximage=(XImage *) NULL;
00845 window_info.matte_image=(XImage *) NULL;
00846 window_info.pixmap=(Pixmap) NULL;
00847 window_info.matte_pixmap=(Pixmap) NULL;
00848 }
00849
00850
00851
00852 if (window_info.id == root_window)
00853 XDestroyWindowColors(display,root_window);
00854 coalesce_image=CoalesceImages(images,&images->exception);
00855 if (coalesce_image == (Image *) NULL)
00856 ThrowXWindowFatalException(ResourceLimitError,"MemoryAllocationFailed",
00857 images->filename);
00858 images=coalesce_image;
00859 if (resources.map_type == (char *) NULL)
00860 if ((visual_info->klass != TrueColor) &&
00861 (visual_info->klass != DirectColor))
00862 {
00863 Image
00864 *next;
00865
00866
00867
00868
00869 for (next=images; next != (Image *) NULL; )
00870 {
00871 next->matte=MagickFalse;
00872 if ((next->storage_class == DirectClass) ||
00873 (next->colors != images->colors) ||
00874 (next->colors > (unsigned long) visual_info->colormap_size))
00875 break;
00876 for (i=0; i < (long) images->colors; i++)
00877 if (IsColorEqual(next->colormap+i,images->colormap+i) == MagickFalse)
00878 break;
00879 if (i < (long) images->colors)
00880 break;
00881 next=GetNextImageInList(next);
00882 }
00883 if (next != (Image *) NULL)
00884 (void) RemapImages(resources.quantize_info,images,(Image *) NULL);
00885 }
00886
00887
00888
00889 number_scenes=GetImageListLength(images);
00890 image_list=ImageListToArray(images,&images->exception);
00891 if (image_list == (Image **) NULL)
00892 ThrowXWindowFatalException(ResourceLimitFatalError,
00893 "MemoryAllocationFailed",images->filename);
00894 for (i=0; i < (long) number_scenes; i++)
00895 if (image_list[i]->scene == 0)
00896 break;
00897 if (i == (long) number_scenes)
00898 qsort((void *) image_list,number_scenes,sizeof(Image *),SceneCompare);
00899
00900
00901
00902 resources.colormap=SharedColormap;
00903 display_image=image_list[0];
00904 for (scene=0; scene < (int) number_scenes; scene++)
00905 {
00906 if ((resource_info->map_type != (char *) NULL) ||
00907 (visual_info->klass == TrueColor) ||
00908 (visual_info->klass == DirectColor))
00909 (void) SetImageType(image_list[scene],image_list[scene]->matte ==
00910 MagickFalse ? TrueColorType : TrueColorMatteType);
00911 if ((display_image->columns < image_list[scene]->columns) &&
00912 (display_image->rows < image_list[scene]->rows))
00913 display_image=image_list[scene];
00914 }
00915 if ((resource_info->map_type != (char *) NULL) ||
00916 (visual_info->klass == TrueColor) || (visual_info->klass == DirectColor))
00917 (void) SetImageType(display_image,display_image->matte == MagickFalse ?
00918 TrueColorType : TrueColorMatteType);
00919 XMakeStandardColormap(display,visual_info,&resources,display_image,map_info,
00920 &pixel);
00921
00922
00923
00924 context_values.background=pixel.background_color.pixel;
00925 context_values.foreground=pixel.foreground_color.pixel;
00926 pixel.annotate_context=XCreateGC(display,window_info.id,(unsigned long)
00927 GCBackground | GCForeground,&context_values);
00928 if (pixel.annotate_context == (GC) NULL)
00929 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateGraphicContext",
00930 images->filename);
00931
00932
00933
00934 XGetWindowInfo(display,visual_info,map_info,&pixel,(XFontStruct *) NULL,
00935 &resources,&window_info);
00936
00937
00938
00939 window_info.width=(unsigned int) image_list[0]->columns;
00940 window_info.height=(unsigned int) image_list[0]->rows;
00941 (void) FormatMagickString(geometry,MaxTextExtent,"%ux%u+0+0>",
00942 window_attributes.width,window_attributes.height);
00943 geometry_info.width=window_info.width;
00944 geometry_info.height=window_info.height;
00945 geometry_info.x=window_info.x;
00946 geometry_info.y=window_info.y;
00947 (void) ParseMetaGeometry(geometry,&geometry_info.x,&geometry_info.y,
00948 &geometry_info.width,&geometry_info.height);
00949 window_info.width=(unsigned int) geometry_info.width;
00950 window_info.height=(unsigned int) geometry_info.height;
00951 window_info.x=(int) geometry_info.x;
00952 window_info.y=(int) geometry_info.y;
00953 status=XMakeImage(display,&resources,&window_info,image_list[0],
00954 window_info.width,window_info.height);
00955 if (status == MagickFalse)
00956 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateXImage",
00957 images->filename);
00958 window_info.x=0;
00959 window_info.y=0;
00960 if (display_image->debug != MagickFalse)
00961 {
00962 (void) LogMagickEvent(X11Event,GetMagickModule(),
00963 "Image: %s[%lu] %lux%lu ",image_list[0]->filename,
00964 image_list[0]->scene,image_list[0]->columns,image_list[0]->rows);
00965 if (image_list[0]->colors != 0)
00966 (void) LogMagickEvent(X11Event,GetMagickModule(),"%luc ",
00967 image_list[0]->colors);
00968 (void) LogMagickEvent(X11Event,GetMagickModule(),"%s",
00969 image_list[0]->magick);
00970 }
00971
00972
00973
00974 width=window_info.width;
00975 height=window_info.height;
00976 if (resources.backdrop != MagickFalse)
00977 {
00978
00979
00980
00981 window_info.x=(int) (window_attributes.width/2)-
00982 (window_info.ximage->width/2);
00983 window_info.y=(int) (window_attributes.height/2)-
00984 (window_info.ximage->height/2);
00985 width=(unsigned int) window_attributes.width;
00986 height=(unsigned int) window_attributes.height;
00987 }
00988 if (resources.image_geometry != (char *) NULL)
00989 {
00990 char
00991 default_geometry[MaxTextExtent];
00992
00993 int
00994 flags,
00995 gravity;
00996
00997 XSizeHints
00998 *size_hints;
00999
01000
01001
01002
01003 size_hints=XAllocSizeHints();
01004 if (size_hints == (XSizeHints *) NULL)
01005 ThrowXWindowFatalException(ResourceLimitFatalError,
01006 "MemoryAllocationFailed",images->filename);
01007 size_hints->flags=0L;
01008 (void) FormatMagickString(default_geometry,MaxTextExtent,"%ux%u",width,
01009 height);
01010 flags=XWMGeometry(display,visual_info->screen,resources.image_geometry,
01011 default_geometry,window_info.border_width,size_hints,&window_info.x,
01012 &window_info.y,(int *) &width,(int *) &height,&gravity);
01013 if (((flags & (XValue | YValue))) != 0)
01014 {
01015 width=(unsigned int) window_attributes.width;
01016 height=(unsigned int) window_attributes.height;
01017 }
01018 (void) XFree((void *) size_hints);
01019 }
01020
01021
01022
01023 window_info.pixmap=XCreatePixmap(display,window_info.id,(unsigned int) width,
01024 (unsigned int) height,window_info.depth);
01025 if (window_info.pixmap == (Pixmap) NULL)
01026 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateXPixmap",
01027 images->filename);
01028
01029
01030
01031 if (((unsigned int) width > window_info.width) ||
01032 ((unsigned int) height > window_info.height))
01033 (void) XFillRectangle(display,window_info.pixmap,
01034 window_info.annotate_context,0,0,(unsigned int) width,
01035 (unsigned int) height);
01036 (void) XPutImage(display,window_info.pixmap,window_info.annotate_context,
01037 window_info.ximage,0,0,window_info.x,window_info.y,window_info.width,
01038 window_info.height);
01039 (void) XSetWindowBackgroundPixmap(display,window_info.id,window_info.pixmap);
01040 (void) XClearWindow(display,window_info.id);
01041
01042
01043
01044 window_info.pixmaps=(Pixmap *) AcquireQuantumMemory(number_scenes,
01045 sizeof(*window_info.pixmaps));
01046 window_info.matte_pixmaps=(Pixmap *) AcquireQuantumMemory(number_scenes,
01047 sizeof(*window_info.matte_pixmaps));
01048 if ((window_info.pixmaps == (Pixmap *) NULL) ||
01049 (window_info.matte_pixmaps == (Pixmap *) NULL))
01050 ThrowXWindowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
01051 images->filename);
01052 window_info.pixmaps[0]=window_info.pixmap;
01053 window_info.matte_pixmaps[0]=window_info.pixmap;
01054 for (scene=1; scene < (int) number_scenes; scene++)
01055 {
01056
01057
01058
01059 window_info.pixmap=(Pixmap) NULL;
01060 window_info.matte_pixmap=(Pixmap) NULL;
01061 if ((resources.map_type != (char *) NULL) ||
01062 (visual_info->klass == TrueColor) ||
01063 (visual_info->klass == DirectColor))
01064 if (image_list[scene]->storage_class == PseudoClass)
01065 XGetPixelPacket(display,visual_info,map_info,&resources,
01066 image_list[scene],window_info.pixel_info);
01067 status=XMakeImage(display,&resources,&window_info,image_list[scene],
01068 (unsigned int) image_list[scene]->columns,
01069 (unsigned int) image_list[scene]->rows);
01070 if (status == MagickFalse)
01071 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateXImage",
01072 images->filename);
01073 if (display_image->debug != MagickFalse)
01074 {
01075 (void) LogMagickEvent(X11Event,GetMagickModule(),
01076 "Image: [%lu] %s %lux%lu ",image_list[scene]->scene,
01077 image_list[scene]->filename,image_list[scene]->columns,
01078 image_list[scene]->rows);
01079 if (image_list[scene]->colors != 0)
01080 (void) LogMagickEvent(X11Event,GetMagickModule(),"%luc ",
01081 image_list[scene]->colors);
01082 (void) LogMagickEvent(X11Event,GetMagickModule(),"%s",
01083 image_list[scene]->magick);
01084 }
01085
01086
01087
01088 window_info.pixmap=XCreatePixmap(display,window_info.id,
01089 (unsigned int) width,(unsigned int) height,window_info.depth);
01090 if (window_info.pixmap == (Pixmap) NULL)
01091 ThrowXWindowFatalException(XServerFatalError,"UnableToCreateXPixmap",
01092 images->filename);
01093
01094
01095
01096 if (((unsigned int) width > window_info.width) ||
01097 ((unsigned int) height > window_info.height))
01098 (void) XFillRectangle(display,window_info.pixmap,
01099 window_info.annotate_context,0,0,(unsigned int) width,
01100 (unsigned int) height);
01101 (void) XPutImage(display,window_info.pixmap,window_info.annotate_context,
01102 window_info.ximage,0,0,window_info.x,window_info.y,window_info.width,
01103 window_info.height);
01104 (void) XSetWindowBackgroundPixmap(display,window_info.id,
01105 window_info.pixmap);
01106 (void) XClearWindow(display,window_info.id);
01107 window_info.pixmaps[scene]=window_info.pixmap;
01108 window_info.matte_pixmaps[scene]=window_info.matte_pixmap;
01109 if (image_list[scene]->matte)
01110 (void) XClearWindow(display,window_info.id);
01111 delay=1000*image_list[scene]->delay/MagickMax(
01112 image_list[scene]->ticks_per_second,1L);
01113 XDelay(display,resources.delay*(delay == 0 ? 10 : delay));
01114 }
01115 window_info.pixel_info=(&pixel);
01116
01117
01118
01119 (void) XSelectInput(display,window_info.id,SubstructureNotifyMask);
01120 event.type=Expose;
01121 do
01122 {
01123 for (scene=0; scene < (int) number_scenes; scene++)
01124 {
01125 if (XEventsQueued(display,QueuedAfterFlush) > 0)
01126 {
01127 (void) XNextEvent(display,&event);
01128 if (event.type == DestroyNotify)
01129 break;
01130 }
01131 window_info.pixmap=window_info.pixmaps[scene];
01132 window_info.matte_pixmap=window_info.matte_pixmaps[scene];
01133 (void) XSetWindowBackgroundPixmap(display,window_info.id,
01134 window_info.pixmap);
01135 (void) XClearWindow(display,window_info.id);
01136 (void) XSync(display,MagickFalse);
01137 delay=1000*image_list[scene]->delay/MagickMax(
01138 image_list[scene]->ticks_per_second,1L);
01139 XDelay(display,resources.delay*(delay == 0 ? 10 : delay));
01140 }
01141 } while (event.type != DestroyNotify);
01142 (void) XSync(display,MagickFalse);
01143 image_list=(Image **) RelinquishMagickMemory(image_list);
01144 images=DestroyImageList(images);
01145 }
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179 MagickExport Image *XAnimateImages(Display *display,
01180 XResourceInfo *resource_info,char **argv,const int argc,Image *images)
01181 {
01182 #define MagickMenus 4
01183 #define MaXWindows 8
01184 #define MagickTitle "Commands"
01185
01186 static const char
01187 *CommandMenu[]=
01188 {
01189 "Animate",
01190 "Speed",
01191 "Direction",
01192 "Help",
01193 "Image Info",
01194 "Quit",
01195 (char *) NULL
01196 },
01197 *AnimateMenu[]=
01198 {
01199 "Open...",
01200 "Play",
01201 "Step",
01202 "Repeat",
01203 "Auto Reverse",
01204 "Save...",
01205 (char *) NULL
01206 },
01207 *SpeedMenu[]=
01208 {
01209 "Faster",
01210 "Slower",
01211 (char *) NULL
01212 },
01213 *DirectionMenu[]=
01214 {
01215 "Forward",
01216 "Reverse",
01217 (char *) NULL
01218 },
01219 *HelpMenu[]=
01220 {
01221 "Overview",
01222 "Browse Documentation",
01223 "About Animate",
01224 (char *) NULL
01225 };
01226
01227
01228 static const char
01229 **Menus[MagickMenus]=
01230 {
01231 AnimateMenu,
01232 SpeedMenu,
01233 DirectionMenu,
01234 HelpMenu
01235 };
01236
01237 static const CommandType
01238 CommandMenus[]=
01239 {
01240 NullCommand,
01241 NullCommand,
01242 NullCommand,
01243 NullCommand,
01244 InfoCommand,
01245 QuitCommand
01246 },
01247 CommandTypes[]=
01248 {
01249 OpenCommand,
01250 PlayCommand,
01251 StepCommand,
01252 RepeatCommand,
01253 AutoReverseCommand,
01254 SaveCommand
01255 },
01256 SpeedCommands[]=
01257 {
01258 FasterCommand,
01259 SlowerCommand
01260 },
01261 DirectionCommands[]=
01262 {
01263 ForwardCommand,
01264 ReverseCommand
01265 },
01266 HelpCommands[]=
01267 {
01268 HelpCommand,
01269 BrowseDocumentationCommand,
01270 VersionCommand
01271 };
01272
01273 static const CommandType
01274 *Commands[MagickMenus]=
01275 {
01276 CommandTypes,
01277 SpeedCommands,
01278 DirectionCommands,
01279 HelpCommands
01280 };
01281
01282 char
01283 command[MaxTextExtent],
01284 geometry[MaxTextExtent],
01285 resource_name[MaxTextExtent];
01286
01287 CommandType
01288 command_type;
01289
0