2
% Copyright (C) 2003, 2004 GraphicsMagick Group
3
% Copyright (C) 2002 ImageMagick Studio
4
% Copyright 1991-1999 E. I. du Pont de Nemours and Company
6
% This program is covered by multiple licenses, which are described in
7
% Copyright.txt. You should have received a copy of Copyright.txt with this
8
% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
10
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14
% AAA N N IIIII M M AAA TTTTT EEEEE %
15
% A A NN N I MM MM A A T E %
16
% AAAAA N N N I M M M AAAAA T EEE %
17
% A A N NN I M M A A T E %
18
% A A N N IIIII M M A A T EEEEE %
21
% Methods to Interactively Animate an Image Sequence %
30
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38
#include "magick/studio.h"
39
#include "magick/constitute.h"
40
#include "magick/delegate.h"
41
#include "magick/log.h"
42
#include "magick/monitor.h"
43
#include "magick/transform.h"
44
#include "magick/utility.h"
45
#include "magick/version.h"
46
#include "magick/xwindow.h"
48
#include "magick/animate.h"
51
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
55
+ X M a g i c k C o m m a n d %
59
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
61
% Method XMagickCommand makes a transform to the image or Image window as
62
% specified by a user menu button or keyboard command.
64
% The format of the XMagickCommand method is:
66
% Image *XMagickCommand(Display *display,XResourceInfo *resource_info,
67
% XWindows *windows,const CommandType command_type,Image **image,
68
% unsigned int *state)
70
% A description of each parameter follows:
72
% o display: Specifies a connection to an X server; returned from
75
% o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
77
% o windows: Specifies a pointer to a XWindows structure.
79
% o image: Specifies a pointer to an Image structure; XMagickCommand
80
% may transform the image and return a new image pointer.
82
% o state: Specifies an unsigned int; XMagickCommand may return a
87
static Image *XMagickCommand(Display *display,XResourceInfo *resource_info,
88
XWindows *windows,const CommandType command_type,Image **image,
101
Process user command.
103
nexus=(Image *) NULL;
104
switch (command_type)
131
filenames[MaxTextExtent] = "*";
136
if (resource_info->immutable)
139
Request file name from user.
141
XFileBrowserWidget(display,windows,"Animate",filenames);
142
if (*filenames == '\0')
143
return((Image *) NULL);
145
Expand the filenames.
147
filelist=MagickAllocateMemory(char **,sizeof(char *));
148
if (filelist == (char **) NULL)
150
MagickError(ResourceLimitError,MemoryAllocationFailed,filenames);
151
return((Image *) NULL);
154
filelist[0]=filenames;
155
status=ExpandFilenames(&number_files,&filelist);
156
if ((status == False) || (number_files == 0))
158
if (number_files == 0)
159
MagickError(ImageError,NoImagesWereLoaded,filenames);
161
MagickError(ResourceLimitError,MemoryAllocationFailed,filenames);
162
return((Image *) NULL);
164
clone_info=CloneImageInfo(resource_info->image_info);
165
if (clone_info == (ImageInfo *) NULL)
167
GetExceptionInfo(&exception);
168
image=(Image *) NULL;
169
handler=(MonitorHandler) NULL;
170
XSetCursorState(display,windows,True);
171
XCheckRefreshWindows(display,windows);
172
for (i=0; i < number_files; i++)
174
if (number_files > 5)
175
handler=SetMonitorHandler((MonitorHandler) NULL);
176
(void) strncpy(clone_info->filename,filelist[i],MaxTextExtent-1);
177
*clone_info->magick='\0';
178
next=ReadImage(clone_info,&exception);
179
if (exception.severity != UndefinedException)
180
CatchException(&exception);
181
if (next != (Image *) NULL)
183
if (image == (Image *) NULL)
188
image->next->previous=image;
192
if (number_files <= 5)
194
(void) SetMonitorHandler(handler);
195
if (!MagickMonitor(LoadImageText,i,number_files,&image->exception))
198
DestroyExceptionInfo(&exception);
199
DestroyImageInfo(clone_info);
200
if (image == (Image *) NULL)
202
XSetCursorState(display,windows,False);
203
MagickError(ImageError,NoImagesWereLoaded,filenames);
204
return((Image *) NULL);
206
while (image->previous != (Image *) NULL)
207
image=image->previous;
215
basename[MaxTextExtent];
218
Window name is the base of the filename.
220
*state|=PlayAnimationState;
221
*state&=(~AutoReverseAnimationState);
222
GetPathComponent((*image)->filename,BasePath,basename);
223
FormatString(windows->image.name,"GraphicsMagick: %.1024s",basename);
224
if (resource_info->title != (char *) NULL)
225
windows->image.name=TranslateText(resource_info->image_info,*image,
226
resource_info->title);
227
status=XStringListToTextProperty(&windows->image.name,1,&window_name);
230
XSetWMName(display,windows->image.id,&window_name);
231
(void) XFree((void *) window_name.value);
235
case StepBackwardCommand:
236
case StepForwardCommand:
238
*state|=StepAnimationState;
239
*state&=(~PlayAnimationState);
240
if (command_type == StepBackwardCommand)
241
*state&=(~ForwardAnimationState);
242
if (command_type == StepForwardCommand)
243
*state|=ForwardAnimationState;
244
if (resource_info->title != (char *) NULL)
250
*state|=RepeatAnimationState;
251
*state&=(~AutoReverseAnimationState);
252
*state|=PlayAnimationState;
255
case AutoReverseCommand:
257
*state|=AutoReverseAnimationState;
258
*state&=(~RepeatAnimationState);
259
*state|=PlayAnimationState;
264
resource_info->delay++;
269
if (resource_info->delay == 0)
271
resource_info->delay--;
276
*state=ForwardAnimationState;
277
*state&=(~AutoReverseAnimationState);
282
*state&=(~ForwardAnimationState);
283
*state&=(~AutoReverseAnimationState);
288
XDisplayImageInfo(display,resource_info,windows,(Image *) NULL,*image);
296
XTextViewWidget(display,resource_info,windows,False,
297
"Help Viewer - Animate",AnimateHelp);
300
case BrowseDocumentationCommand:
310
Browse the GraphicsMagick documentation.
312
root_window=XRootWindow(display,XDefaultScreen(display));
313
mozilla_atom=XInternAtom(display,"_MOZILLA_VERSION",False);
314
mozilla_window=XWindowByProperty(display,root_window,mozilla_atom);
315
if (mozilla_window != (Window) NULL)
318
command[MaxTextExtent];
321
Display documentation using Netscape remote control.
323
FormatString(command,"openURL(%.1024s,new-window,noraise)",
324
"http://www.graphicsmagick.org/");
325
mozilla_atom=XInternAtom(display,"_MOZILLA_COMMAND",False);
326
(void) XChangeProperty(display,mozilla_window,mozilla_atom,
327
XA_STRING,8,PropModeReplace,(unsigned char *) command,
328
(int) strlen(command));
329
XSetCursorState(display,windows,False);
332
XSetCursorState(display,windows,True);
333
XCheckRefreshWindows(display,windows);
334
status=InvokeDelegate(resource_info->image_info,*image,"browse",
335
(char *) NULL,&(*image)->exception);
337
XNoticeWidget(display,windows,"Unable to browse documentation",
339
XDelay(display,1500);
340
XSetCursorState(display,windows,False);
345
XNoticeWidget(display,windows,GetMagickVersion((unsigned long *) NULL),
346
GetMagickCopyright());
354
if (!resource_info->confirm_exit)
355
XClientMessage(display,windows->image.id,windows->im_protocols,
356
windows->im_exit,CurrentTime);
360
Confirm program exit.
362
status=XConfirmWidget(display,windows,"Do you really want to exit",
363
resource_info->client_name);
365
XClientMessage(display,windows->image.id,windows->im_protocols,
366
windows->im_exit,CurrentTime);
377
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
381
% X A n i m a t e B a c k g r o u n d I m a g e %
385
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
387
% XAnimateBackgroundImage() animates an image sequence in the background of
390
% The format of the XAnimateBackgroundImage method is:
392
% void XAnimateBackgroundImage(Display *display,
393
% XResourceInfo *resource_info,Image *images)
395
% A description of each parameter follows:
397
% o display: Specifies a connection to an X server; returned from
400
% o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
402
% o images: The image list.
407
#if defined(__cplusplus) || defined(c_plusplus)
411
static int SceneCompare(const void *x,const void *y)
417
image_1=(Image **) x;
418
image_2=(Image **) y;
419
return((int) ((*image_1)->scene-(*image_2)->scene));
422
#if defined(__cplusplus) || defined(c_plusplus)
426
MagickExport void XAnimateBackgroundImage(Display *display,
427
XResourceInfo *resource_info,Image *images)
430
geometry[MaxTextExtent],
431
visual_type[MaxTextExtent];
440
static XStandardColormap
444
*visual_info = (XVisualInfo *) NULL;
489
Determine target window.
491
assert(images != (Image *) NULL);
492
assert(images->signature == MagickSignature);
493
resources=(*resource_info);
494
window_info.id=(Window) NULL;
495
root_window=XRootWindow(display,XDefaultScreen(display));
496
if (LocaleCompare(resources.window_id,"root") == 0)
497
window_info.id=root_window;
500
if (isdigit((int) (*resources.window_id)))
501
window_info.id=XWindowByID(display,root_window,
502
(Window) strtol((char *) resources.window_id,(char **) NULL,0));
503
if (window_info.id == (Window) NULL)
505
XWindowByName(display,root_window,resources.window_id);
507
if (window_info.id == (Window) NULL)
509
MagickError(XServerError,NoWindowWithSpecifiedIDExists,
510
resources.window_id);
514
Determine window visual id.
516
window_attributes.width=XDisplayWidth(display,XDefaultScreen(display));
517
window_attributes.height=XDisplayHeight(display,XDefaultScreen(display));
518
(void) strcpy(visual_type,"default");
519
status=XGetWindowAttributes(display,window_info.id,&window_attributes);
521
FormatString(visual_type,"0x%lx",
522
XVisualIDFromVisual(window_attributes.visual));
523
if (visual_info == (XVisualInfo *) NULL)
526
Allocate standard colormap.
528
map_info=XAllocStandardColormap();
529
if (map_info == (XStandardColormap *) NULL)
530
MagickFatalError(ResourceLimitFatalError,MemoryAllocationFailed,
531
MagickMsg(XServerFatalError,UnableToCreateStandardColormap));
532
map_info->colormap=(Colormap) NULL;
533
pixel.pixels=(unsigned long *) NULL;
535
Initialize visual info.
537
resources.map_type=(char *) NULL;
538
resources.visual_type=visual_type;
539
visual_info=XBestVisualInfo(display,map_info,&resources);
540
if (visual_info == (XVisualInfo *) NULL)
541
MagickFatalError(XServerFatalError,UnableToGetVisual,
542
resources.visual_type);
544
Initialize window info.
546
window_info.ximage=(XImage *) NULL;
547
window_info.matte_image=(XImage *) NULL;
548
window_info.pixmap=(Pixmap) NULL;
549
window_info.matte_pixmap=(Pixmap) NULL;
552
Free previous root colors.
554
if (window_info.id == root_window)
555
XDestroyWindowColors(display,root_window);
557
if (images->next != (Image *) NULL)
563
Determine if the sequence of images have identical page info.
565
for (next=images; next != (Image *) NULL; )
567
if ((images->page.width != 0) && (images->page.height != 0))
568
if ((images->columns != next->columns) ||
569
(images->rows != next->rows))
571
if ((images->page.x != next->page.x) ||
572
(images->page.y != next->page.y))
576
coalesce=next != (Image *) NULL;
582
coalesce_image=CoalesceImages(images,&images->exception);
583
if (coalesce_image == (Image *) NULL)
584
MagickFatalError2(images->exception.severity,
585
images->exception.reason,images->exception.description);
586
images=coalesce_image;
589
if (resources.map_type == (char *) NULL)
590
if ((visual_info->storage_class != TrueColor) &&
591
(visual_info->storage_class != DirectColor))
597
Determine if the sequence of images has the identical colormap.
599
for (next=images; next != (Image *) NULL; )
602
if ((next->storage_class == DirectClass) ||
603
(next->colors != images->colors) ||
604
(next->colors > (unsigned long) visual_info->colormap_size))
606
for (i=0; i < (long) images->colors; i++)
607
if (!ColorMatch(next->colormap+i,images->colormap+i))
609
if (i < (long) images->colors)
613
if (next != (Image *) NULL)
614
(void) MapImages(images,(Image *) NULL,
615
resources.quantize_info->dither);
618
Sort images by increasing scene number.
620
number_scenes=GetImageListLength(images);
621
image_list=ImageListToArray(images,&images->exception);
622
if (image_list == (Image **) NULL)
623
MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
624
UnableToAnimateImageSequence);
625
for (i=0; i < (long) number_scenes; i++)
626
if (image_list[i]->scene == 0)
628
if (i == (long) number_scenes)
629
qsort((void *) image_list,number_scenes,sizeof(Image *),SceneCompare);
631
Initialize Standard Colormap.
633
resources.colormap=SharedColormap;
634
display_image=image_list[0];
635
for (scene=0; scene < (int) number_scenes; scene++)
637
if ((resource_info->map_type != (char *) NULL) ||
638
(visual_info->storage_class == TrueColor) ||
639
(visual_info->storage_class == DirectColor))
640
SetImageType(image_list[scene],TrueColorType);
641
if ((display_image->columns < image_list[scene]->columns) &&
642
(display_image->rows < image_list[scene]->rows))
643
display_image=image_list[scene];
645
if ((resource_info->map_type != (char *) NULL) ||
646
(visual_info->storage_class == TrueColor) ||
647
(visual_info->storage_class == DirectColor))
648
SetImageType(display_image,TrueColorType);
649
XMakeStandardColormap(display,visual_info,&resources,display_image,map_info,
652
Graphic context superclass.
654
context_values.background=pixel.background_color.pixel;
655
context_values.foreground=pixel.foreground_color.pixel;
656
pixel.annotate_context=XCreateGC(display,window_info.id,GCBackground |
657
GCForeground,&context_values);
658
if (pixel.annotate_context == (GC) NULL)
659
MagickFatalError(XServerFatalError,UnableToCreateGraphicContext,
662
Initialize Image window attributes.
664
XGetWindowInfo(display,visual_info,map_info,&pixel,(XFontStruct *) NULL,
665
&resources,&window_info);
669
window_info.width=(unsigned int) image_list[0]->columns;
670
window_info.height=(unsigned int) image_list[0]->rows;
671
FormatString(geometry,"%ux%u+0+0>",window_attributes.width,
672
window_attributes.height);
673
width=window_info.width;
674
height=window_info.height;
679
geometry_width=width,
680
geometry_height=height;
682
(void) GetMagickGeometry(geometry,&x,&y,&geometry_width,&geometry_height);
683
width=(unsigned int) geometry_width;
684
height=(unsigned int) geometry_height;
686
window_info.width=(unsigned int) height;
687
window_info.height=(unsigned int) height;
688
window_info.x=(int) x;
689
window_info.y=(int) y;
690
status=XMakeImage(display,&resources,&window_info,image_list[0],
691
window_info.width,window_info.height);
693
MagickFatalError(XServerFatalError,UnableToCreateXImage,(char *) NULL);
696
if (IsEventLogging())
698
(void) LogMagickEvent(X11Event,GetMagickModule(),
699
"Image: %.1024s[%lu] %lux%lu ",image_list[0]->filename,
700
image_list[0]->scene,image_list[0]->columns,image_list[0]->rows);
701
if (image_list[0]->colors != 0)
702
(void) LogMagickEvent(X11Event,GetMagickModule(),"%luc ",
703
image_list[0]->colors);
704
(void) LogMagickEvent(X11Event,GetMagickModule(),"%.1024s",
705
image_list[0]->magick);
708
Adjust image dimensions as specified by backdrop or geometry options.
710
width=window_info.width;
711
height=window_info.height;
712
if (resources.backdrop)
715
Center image on window.
717
window_info.x=(window_attributes.width/2)-(window_info.ximage->width/2);
718
window_info.y=(window_attributes.height/2)-(window_info.ximage->height/2);
719
width=window_attributes.width;
720
height=window_attributes.height;
722
if (resources.image_geometry != (char *) NULL)
725
default_geometry[MaxTextExtent];
737
User specified geometry.
739
size_hints=XAllocSizeHints();
740
if (size_hints == (XSizeHints *) NULL)
741
MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
742
UnableToDisplayImage);
743
size_hints->flags=(long) NULL;
744
FormatString(default_geometry,"%ux%u",width,height);
745
flags=XWMGeometry(display,visual_info->screen,resources.image_geometry,
746
default_geometry,window_info.border_width,size_hints,&window_info.x,
747
&window_info.y,(int *) &width,(int *) &height,&gravity);
748
if (flags & (XValue | YValue))
750
width=window_attributes.width;
751
height=window_attributes.height;
753
(void) XFree((void *) size_hints);
758
window_info.pixmap=XCreatePixmap(display,window_info.id,(unsigned int) width,
759
(unsigned int) height,window_info.depth);
760
if (window_info.pixmap == (Pixmap) NULL)
761
MagickFatalError(XServerFatalError,UnableToCreateXPixmap,(char *) NULL);
763
Display pixmap on the window.
765
if (((unsigned int) width > window_info.width) ||
766
((unsigned int) height > window_info.height))
767
(void) XFillRectangle(display,window_info.pixmap,
768
window_info.annotate_context,0,0,(unsigned int) width,
769
(unsigned int) height);
770
(void) XPutImage(display,window_info.pixmap,window_info.annotate_context,
771
window_info.ximage,0,0,window_info.x,window_info.y,window_info.width,
773
(void) XSetWindowBackgroundPixmap(display,window_info.id,window_info.pixmap);
774
(void) XClearWindow(display,window_info.id);
776
Initialize image pixmaps structure.
778
window_info.pixmaps=MagickAllocateMemory(Pixmap *,number_scenes*sizeof(Pixmap));
779
window_info.matte_pixmaps=MagickAllocateMemory(Pixmap *,
780
number_scenes*sizeof(Pixmap));
781
if ((window_info.pixmaps == (Pixmap *) NULL) ||
782
(window_info.matte_pixmaps == (Pixmap *) NULL))
783
MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
784
UnableToAnimateImageSequence);
785
window_info.pixmaps[0]=window_info.pixmap;
786
window_info.matte_pixmaps[0]=window_info.pixmap;
787
scene_info.pixels=(unsigned long *) NULL;
788
for (scene=1; scene < (int) number_scenes; scene++)
793
window_info.pixmap=(Pixmap) NULL;
794
window_info.matte_pixmap=(Pixmap) NULL;
795
if ((resources.map_type != (char *) NULL) ||
796
(visual_info->storage_class == TrueColor) ||
797
(visual_info->storage_class == DirectColor))
798
if (image_list[scene]->storage_class == PseudoClass)
801
Get pixel info for this scene.
803
XGetPixelPacket(display,visual_info,map_info,&resources,
804
image_list[scene],&scene_info);
805
window_info.pixel_info=(&scene_info);
807
status=XMakeImage(display,&resources,&window_info,image_list[scene],
808
(unsigned int) image_list[scene]->columns,
809
(unsigned int) image_list[scene]->rows);
811
MagickFatalError(XServerFatalError,UnableToCreateXImage,(char *) NULL);
812
if (IsEventLogging())
814
(void) LogMagickEvent(X11Event,GetMagickModule(),
815
"Image: [%lu] %.1024s %lux%lu ",image_list[scene]->scene,
816
image_list[scene]->filename,image_list[scene]->columns,
817
image_list[scene]->rows);
818
if (image_list[scene]->colors != 0)
819
(void) LogMagickEvent(X11Event,GetMagickModule(),"%luc ",
820
image_list[scene]->colors);
821
(void) LogMagickEvent(X11Event,GetMagickModule(),"%.1024s",
822
image_list[scene]->magick);
827
window_info.pixmap=XCreatePixmap(display,window_info.id,
828
(unsigned int) width,(unsigned int) height,window_info.depth);
829
if (window_info.pixmap == (Pixmap) NULL)
830
MagickFatalError(XServerFatalError,UnableToCreateXPixmap,(char *) NULL);
832
Display pixmap on the window.
834
if (((unsigned int) width > window_info.width) ||
835
((unsigned int) height > window_info.height))
836
(void) XFillRectangle(display,window_info.pixmap,
837
window_info.annotate_context,0,0,(unsigned int) width,
838
(unsigned int) height);
839
(void) XPutImage(display,window_info.pixmap,window_info.annotate_context,
840
window_info.ximage,0,0,window_info.x,window_info.y,window_info.width,
842
(void) XSetWindowBackgroundPixmap(display,window_info.id,
844
(void) XClearWindow(display,window_info.id);
845
window_info.pixmaps[scene]=window_info.pixmap;
846
window_info.matte_pixmaps[scene]=window_info.matte_pixmap;
847
if (image_list[scene]->matte)
848
(void) XClearWindow(display,window_info.id);
849
XDelay(display,(unsigned long) resources.delay*10*Max(images->delay,1));
851
window_info.pixel_info=(&pixel);
853
Display pixmap on the window.
855
(void) XSelectInput(display,window_info.id,SubstructureNotifyMask);
859
for (scene=0; scene < (int) number_scenes; scene++)
861
if (XEventsQueued(display,QueuedAfterFlush) > 0)
863
(void) XNextEvent(display,&event);
864
if (event.type == DestroyNotify)
867
window_info.pixmap=window_info.pixmaps[scene];
868
window_info.matte_pixmap=window_info.matte_pixmaps[scene];
869
(void) XSetWindowBackgroundPixmap(display,window_info.id,
871
(void) XClearWindow(display,window_info.id);
872
(void) XSync(display,False);
873
XDelay(display,(unsigned long) resources.delay*10*
874
Max(image_list[scene]->delay,1));
876
} while (event.type != DestroyNotify);
877
(void) XSync(display,False);
878
MagickFreeMemory(image_list);
880
DestroyImageList(images);
884
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
888
% X A n i m a t e I m a g e %
892
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
894
% XAnimateImages() displays an image via X11.
896
% The format of the XAnimateImages method is:
898
% Image *XAnimateImages(Display *display,XResourceInfo *resource_info,
899
% char **argv,const int argc,Image *images)
901
% A description of each parameter follows:
903
% o display: Specifies a connection to an X server; returned from
906
% o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
908
% o argv: Specifies the application's argument list.
910
% o argc: Specifies the number of arguments.
912
% o images: The image list.
916
MagickExport Image *XAnimateImages(Display *display,
917
XResourceInfo *resource_info,char **argv,const int argc,Image *images)
919
#define MagickMenus 4
921
#define MagickTitle "Commands"
958
"Browse Documentation",
965
**Menus[MagickMenus]=
973
static const CommandType
1004
BrowseDocumentationCommand,
1008
static const CommandType
1009
*Commands[MagickMenus]=
1018
command[MaxTextExtent],
1019
geometry[MaxTextExtent],
1020
resource_name[MaxTextExtent];
1054
working_directory[MaxTextExtent];
1056
static unsigned long
1060
*magick_windows[MaxWindows];
1118
assert(images != (Image *) NULL);
1119
assert(images->signature == MagickSignature);
1120
monitor_handler=(MonitorHandler) NULL;
1121
warning_handler=(WarningHandler) NULL;
1122
windows=XSetWindows((XWindows *) ~0);
1123
if (windows != (XWindows *) NULL)
1125
(void) chdir(working_directory);
1126
monitor_handler=SetMonitorHandler(XMagickMonitor);
1127
warning_handler=resource_info->display_warnings ?
1128
SetErrorHandler(XWarning) : SetErrorHandler((ErrorHandler) NULL);
1129
warning_handler=resource_info->display_warnings ?
1130
SetWarningHandler(XWarning) : SetWarningHandler((WarningHandler) NULL);
1131
(void) signal(SIGINT,XSignalHandler);
1132
(void) signal(SIGSEGV,XSignalHandler);
1133
(void) signal(SIGTERM,XSignalHandler);
1141
Initialize window structure.
1143
for (p=images; p != (Image *) NULL; p=p->next)
1145
if (p->storage_class == DirectClass)
1147
resource_info->colors=0;
1150
if (p->colors > resource_info->colors)
1151
resource_info->colors=p->colors;
1153
windows=XSetWindows(XInitializeWindows(display,resource_info));
1154
if (windows == (XWindows *) NULL)
1155
MagickFatalError(ResourceLimitFatalError,MemoryAllocationFailed,
1156
MagickMsg(XServerFatalError,UnableToCreateXWindow));
1158
Initialize window id's.
1161
magick_windows[number_windows++]=(&windows->icon);
1162
magick_windows[number_windows++]=(&windows->backdrop);
1163
magick_windows[number_windows++]=(&windows->image);
1164
magick_windows[number_windows++]=(&windows->info);
1165
magick_windows[number_windows++]=(&windows->command);
1166
magick_windows[number_windows++]=(&windows->widget);
1167
magick_windows[number_windows++]=(&windows->popup);
1168
for (i=0; i < (long) number_windows; i++)
1169
magick_windows[i]->id=(Window) NULL;
1172
Initialize font info.
1174
if (windows->font_info != (XFontStruct *) NULL)
1175
(void) XFreeFont(display,windows->font_info);
1176
windows->font_info=XBestFont(display,resource_info,False);
1177
if (windows->font_info == (XFontStruct *) NULL)
1178
MagickFatalError(XServerFatalError,UnableToLoadFont,resource_info->font);
1180
Initialize Standard Colormap.
1182
map_info=windows->map_info;
1183
icon_map=windows->icon_map;
1184
visual_info=windows->visual_info;
1185
icon_visual=windows->icon_visual;
1186
pixel=windows->pixel_info;
1187
icon_pixel=windows->icon_pixel;
1188
font_info=windows->font_info;
1189
icon_resources=windows->icon_resources;
1190
class_hints=windows->class_hints;
1191
manager_hints=windows->manager_hints;
1192
root_window=XRootWindow(display,visual_info->screen);
1194
if (images->next != (Image *) NULL)
1200
Determine if the sequence of images have identical page info.
1202
for (next=images; next != (Image *) NULL; )
1204
if ((images->columns != next->columns) ||
1205
(images->rows != next->rows))
1207
if ((images->page.x != next->page.x) ||
1208
(images->page.y != next->page.y))
1212
coalesce=next != (Image *) NULL;
1218
coalesce_image=CoalesceImages(images,&images->exception);
1219
if (coalesce_image == (Image *) NULL)
1220
MagickFatalError2(images->exception.severity,
1221
images->exception.reason,images->exception.description);
1222
images=coalesce_image;
1225
if (resource_info->map_type == (char *) NULL)
1226
if ((visual_info->storage_class != TrueColor) &&
1227
(visual_info->storage_class != DirectColor))
1233
Determine if the sequence of images has the identical colormap.
1235
for (next=images; next != (Image *) NULL; )
1238
if ((next->storage_class == DirectClass) ||
1239
(next->colors != images->colors) ||
1240
(next->colors > (unsigned long) visual_info->colormap_size))
1242
for (i=0; i < (long) images->colors; i++)
1243
if (!ColorMatch(next->colormap+i,images->colormap+i))
1245
if (i < (long) images->colors)
1249
if (next != (Image *) NULL)
1250
(void) MapImages(images,(Image *) NULL,
1251
resource_info->quantize_info->dither);
1254
Sort images by increasing scene number.
1256
number_scenes=GetImageListLength(images);
1257
image_list=ImageListToArray(images,&images->exception);
1258
if (image_list == (Image **) NULL)
1259
MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
1260
UnableToAnimateImageSequence);
1261
for (scene=0; scene < (long) number_scenes; scene++)
1262
if (image_list[scene]->scene == 0)
1264
if (scene == (long) number_scenes)
1265
qsort((void *) image_list,number_scenes,sizeof(Image *),SceneCompare);
1267
Initialize Standard Colormap.
1269
nexus=(Image *) NULL;
1270
display_image=image_list[0];
1271
TransformColorspace(display_image,RGBColorspace);
1272
for (scene=0; scene < (long) number_scenes; scene++)
1274
if ((resource_info->map_type != (char *) NULL) ||
1275
(visual_info->storage_class == TrueColor) ||
1276
(visual_info->storage_class == DirectColor))
1277
SetImageType(image_list[scene],TrueColorType);
1278
if ((display_image->columns < image_list[scene]->columns) &&
1279
(display_image->rows < image_list[scene]->rows))
1280
display_image=image_list[scene];
1282
if (IsEventLogging())
1284
(void) LogMagickEvent(X11Event,GetMagickModule(),
1285
"Image: %.1024s[%lu] %lux%lu ",display_image->filename,
1286
display_image->scene,display_image->columns,display_image->rows);
1287
if (display_image->colors != 0)
1288
(void) LogMagickEvent(X11Event,GetMagickModule(),"%luc ",
1289
display_image->colors);
1290
(void) LogMagickEvent(X11Event,GetMagickModule(),"%.1024s",
1291
display_image->magick);
1293
XMakeStandardColormap(display,visual_info,resource_info,display_image,
1296
Initialize graphic context.
1298
windows->context.id=(Window) NULL;
1299
XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
1300
resource_info,&windows->context);
1301
class_hints->res_name=(char *) "superclass";
1302
class_hints->res_class=(char *) "Display";
1303
manager_hints->flags=InputHint | StateHint;
1304
manager_hints->input=False;
1305
manager_hints->initial_state=WithdrawnState;
1306
XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
1308
if (IsEventLogging())
1309
(void) LogMagickEvent(X11Event,GetMagickModule(),
1310
"Window id: 0x%lx (context)",windows->context.id);
1311
context_values.background=pixel->background_color.pixel;
1312
context_values.font=font_info->fid;
1313
context_values.foreground=pixel->foreground_color.pixel;
1314
context_values.graphics_exposures=False;
1315
context_mask=GCBackground | GCFont | GCForeground | GCGraphicsExposures;
1316
if (pixel->annotate_context != (GC) NULL)
1317
(void) XFreeGC(display,pixel->annotate_context);
1318
pixel->annotate_context=
1319
XCreateGC(display,windows->context.id,context_mask,&context_values);
1320
if (pixel->annotate_context == (GC) NULL)
1321
MagickFatalError(XServerFatalError,UnableToCreateGraphicContext,
1323
context_values.background=pixel->depth_color.pixel;
1324
if (pixel->widget_context != (GC) NULL)
1325
(void) XFreeGC(display,pixel->widget_context);
1326
pixel->widget_context=
1327
XCreateGC(display,windows->context.id,context_mask,&context_values);
1328
if (pixel->widget_context == (GC) NULL)
1329
MagickFatalError(XServerFatalError,UnableToCreateGraphicContext,
1331
context_values.background=pixel->foreground_color.pixel;
1332
context_values.foreground=pixel->background_color.pixel;
1333
context_values.plane_mask=
1334
context_values.background ^ context_values.foreground;
1335
if (pixel->highlight_context != (GC) NULL)
1336
(void) XFreeGC(display,pixel->highlight_context);
1337
pixel->highlight_context=XCreateGC(display,windows->context.id,
1338
context_mask | GCPlaneMask,&context_values);
1339
if (pixel->highlight_context == (GC) NULL)
1340
MagickFatalError(XServerFatalError,UnableToCreateGraphicContext,
1342
(void) XDestroyWindow(display,windows->context.id);
1344
Initialize icon window.
1346
XGetWindowInfo(display,icon_visual,icon_map,icon_pixel,(XFontStruct *) NULL,
1347
icon_resources,&windows->icon);
1348
windows->icon.geometry=resource_info->icon_geometry;
1349
XBestIconSize(display,&windows->icon,display_image);
1350
windows->icon.attributes.colormap=
1351
XDefaultColormap(display,icon_visual->screen);
1352
windows->icon.attributes.event_mask=ExposureMask | StructureNotifyMask;
1353
class_hints->res_name=(char *) "icon";
1354
manager_hints->flags=InputHint | StateHint;
1355
manager_hints->input=False;
1356
manager_hints->initial_state=IconicState;
1357
XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
1359
if (IsEventLogging())
1360
(void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (icon)",
1363
Initialize graphic context for icon window.
1365
if (icon_pixel->annotate_context != (GC) NULL)
1366
(void) XFreeGC(display,icon_pixel->annotate_context);
1367
context_values.background=icon_pixel->background_color.pixel;
1368
context_values.foreground=icon_pixel->foreground_color.pixel;
1369
icon_pixel->annotate_context=XCreateGC(display,windows->icon.id,
1370
GCBackground | GCForeground,&context_values);
1371
if (icon_pixel->annotate_context == (GC) NULL)
1372
MagickFatalError(XServerFatalError,UnableToCreateGraphicContext,
1374
windows->icon.annotate_context=icon_pixel->annotate_context;
1376
Initialize Image window.
1378
if (windows->image.id != (Window) NULL)
1380
MagickFreeMemory(windows->image.name);
1381
MagickFreeMemory(windows->image.icon_name);
1383
XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
1384
resource_info,&windows->image);
1385
windows->image.shape=True; /* non-rectangular shape hint */
1386
windows->image.shared_memory&=resource_info->use_shared_memory;
1387
if (resource_info->title != (char *) NULL)
1389
windows->image.name=TranslateText(resource_info->image_info,
1390
display_image,resource_info->title);
1391
windows->image.icon_name=TranslateText(resource_info->image_info,
1392
display_image,resource_info->title);
1397
filename[MaxTextExtent];
1400
Window name is the base of the filename.
1402
windows->image.name=AllocateString((char *) NULL);
1403
windows->image.icon_name=AllocateString((char *) NULL);
1404
GetPathComponent(display_image->filename,TailPath,filename);
1405
FormatString(windows->image.name,"GraphicsMagick: %.1024s[%lu of %lu]",
1406
filename,display_image->scene,number_scenes);
1407
(void) strncpy(windows->image.icon_name,filename,MaxTextExtent-1);
1409
if (resource_info->immutable)
1410
windows->image.immutable=True;
1411
windows->image.shape=True;
1412
windows->image.geometry=resource_info->image_geometry;
1413
FormatString(geometry,"%ux%u+0+0>!",
1414
90*XDisplayWidth(display,visual_info->screen)/100,
1415
90*XDisplayHeight(display,visual_info->screen)/100);
1416
width=display_image->columns;
1417
height=display_image->rows;
1420
(void) GetMagickGeometry(geometry,&x,&y,&width,&height);
1421
windows->image.width=(unsigned int) width;
1422
windows->image.height=(unsigned int) height;
1423
windows->image.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
1424
ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
1425
KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask |
1426
PropertyChangeMask | StructureNotifyMask | SubstructureNotifyMask;
1427
XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
1428
resource_info,&windows->backdrop);
1429
if ((resource_info->backdrop) || (windows->backdrop.id != (Window) NULL))
1432
Initialize backdrop window.
1434
windows->backdrop.x=0;
1435
windows->backdrop.y=0;
1436
(void) CloneString(&windows->backdrop.name,"GraphicsMagick Backdrop");
1437
windows->backdrop.flags=USSize | USPosition;
1438
windows->backdrop.width=XDisplayWidth(display,visual_info->screen);
1439
windows->backdrop.height=XDisplayHeight(display,visual_info->screen);
1440
windows->backdrop.border_width=0;
1441
windows->backdrop.immutable=True;
1442
windows->backdrop.attributes.do_not_propagate_mask=ButtonPressMask |
1444
windows->backdrop.attributes.event_mask=ButtonPressMask | KeyPressMask |
1445
StructureNotifyMask;
1446
windows->backdrop.attributes.override_redirect=True;
1447
class_hints->res_name=(char *) "backdrop";
1448
manager_hints->flags=IconWindowHint | InputHint | StateHint;
1449
manager_hints->icon_window=windows->icon.id;
1450
manager_hints->input=True;
1451
manager_hints->initial_state=
1452
resource_info->iconic ? IconicState : NormalState;
1453
XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
1454
&windows->backdrop);
1455
if (IsEventLogging())
1456
(void) LogMagickEvent(X11Event,GetMagickModule(),
1457
"Window id: 0x%lx (backdrop)",windows->backdrop.id);
1458
(void) XMapWindow(display,windows->backdrop.id);
1459
(void) XClearWindow(display,windows->backdrop.id);
1460
if (windows->image.id != (Window) NULL)
1462
(void) XDestroyWindow(display,windows->image.id);
1463
windows->image.id=(Window) NULL;
1466
Position image in the center the backdrop.
1468
windows->image.flags|=USPosition;
1469
windows->image.x=(XDisplayWidth(display,visual_info->screen)/2)-
1470
(windows->image.width/2);
1471
windows->image.y=(XDisplayHeight(display,visual_info->screen)/2)-
1472
(windows->image.height/2);
1474
if (resource_info->name == (char *) NULL)
1475
class_hints->res_name=resource_info->client_name;
1477
class_hints->res_name=resource_info->name;
1478
manager_hints->flags=IconWindowHint | InputHint | StateHint;
1479
manager_hints->icon_window=windows->icon.id;
1480
manager_hints->input=True;
1481
manager_hints->initial_state=
1482
resource_info->iconic ? IconicState : NormalState;
1483
if (windows->group_leader.id != (Window) NULL)
1488
manager_hints->flags|=(unsigned int) WindowGroupHint;
1489
manager_hints->window_group=windows->group_leader.id;
1490
(void) XSelectInput(display,windows->group_leader.id,StructureNotifyMask);
1491
if (IsEventLogging())
1492
(void) LogMagickEvent(X11Event,GetMagickModule(),
1493
"Window id: 0x%lx (group leader)",windows->group_leader.id);
1495
XMakeWindow(display,
1496
(Window) (resource_info->backdrop ? windows->backdrop.id : root_window),
1497
argv,argc,class_hints,manager_hints,&windows->image);
1498
(void) XChangeProperty(display,windows->image.id,windows->im_protocols,
1499
XA_STRING,8,PropModeReplace,(unsigned char *) NULL,0);
1500
if (windows->group_leader.id != (Window) NULL)
1501
(void) XSetTransientForHint(display,windows->image.id,
1502
windows->group_leader.id);
1503
if (IsEventLogging())
1504
(void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (image)",
1507
Initialize Info widget.
1509
XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
1510
resource_info,&windows->info);
1511
(void) CloneString(&windows->info.name,"Info");
1512
(void) CloneString(&windows->info.icon_name,"Info");
1513
windows->info.border_width=1;
1516
windows->info.flags|=PPosition;
1517
windows->info.attributes.win_gravity=UnmapGravity;
1518
windows->info.attributes.event_mask=
1519
ButtonPressMask | ExposureMask | StructureNotifyMask;
1520
class_hints->res_name=(char *) "info";
1521
manager_hints->flags=InputHint | StateHint | WindowGroupHint;
1522
manager_hints->input=False;
1523
manager_hints->initial_state=NormalState;
1524
manager_hints->window_group=windows->image.id;
1525
XMakeWindow(display,windows->image.id,argv,argc,class_hints,manager_hints,
1527
windows->info.highlight_stipple=XCreateBitmapFromData(display,
1528
windows->info.id,(char *) HighlightBitmap,HighlightWidth,HighlightHeight);
1529
windows->info.shadow_stipple=XCreateBitmapFromData(display,
1530
windows->info.id,(char *) ShadowBitmap,ShadowWidth,ShadowHeight);
1531
(void) XSetTransientForHint(display,windows->info.id,windows->image.id);
1532
if (windows->image.mapped)
1533
(void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
1534
if (IsEventLogging())
1535
(void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (info)",
1538
Initialize Command widget.
1540
XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
1541
resource_info,&windows->command);
1542
windows->command.data=MagickMenus;
1543
(void) XCommandWidget(display,windows,CommandMenu,(XEvent *) NULL);
1544
FormatString(resource_name,"%.1024s.command",resource_info->client_name);
1545
windows->command.geometry=XGetResourceClass(resource_info->resource_database,
1546
resource_name,"geometry",(char *) NULL);
1547
(void) CloneString(&windows->command.name,MagickTitle);
1548
windows->command.border_width=0;
1549
windows->command.flags|=PPosition;
1550
windows->command.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
1551
ButtonReleaseMask | EnterWindowMask | ExposureMask | LeaveWindowMask |
1552
OwnerGrabButtonMask | StructureNotifyMask;
1553
class_hints->res_name=(char *) "command";
1554
manager_hints->flags=InputHint | StateHint | WindowGroupHint;
1555
manager_hints->input=False;
1556
manager_hints->initial_state=NormalState;
1557
manager_hints->window_group=windows->image.id;
1558
XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
1560
windows->command.highlight_stipple=windows->info.highlight_stipple;
1561
windows->command.shadow_stipple=windows->info.shadow_stipple;
1562
(void) XSetTransientForHint(display,windows->command.id,windows->image.id);
1563
if (IsEventLogging())
1564
(void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (command)",
1565
windows->command.id);
1567
Initialize Widget window.
1569
if (windows->widget.id != (Window) NULL)
1570
MagickFreeMemory(windows->widget.name);
1571
XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
1572
resource_info,&windows->widget);
1573
FormatString(resource_name,"%.1024s.widget",resource_info->client_name);
1574
windows->widget.geometry=XGetResourceClass(resource_info->resource_database,
1575
resource_name,"geometry",(char *) NULL);
1576
windows->widget.name=AllocateString((char *) NULL);
1577
*windows->widget.name='\0';
1578
windows->widget.border_width=0;
1579
windows->widget.flags|=PPosition;
1580
windows->widget.attributes.backing_store=WhenMapped;
1581
windows->widget.attributes.save_under=True;
1582
windows->widget.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
1583
ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
1584
KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask |
1585
StructureNotifyMask;
1586
class_hints->res_name=(char *) "widget";
1587
manager_hints->flags=InputHint | StateHint | WindowGroupHint;
1588
manager_hints->input=True;
1589
manager_hints->initial_state=NormalState;
1590
manager_hints->window_group=windows->image.id;
1591
XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
1593
windows->widget.highlight_stipple=windows->info.highlight_stipple;
1594
windows->widget.shadow_stipple=windows->info.shadow_stipple;
1595
(void) XSetTransientForHint(display,windows->widget.id,windows->image.id);
1596
if (IsEventLogging())
1597
(void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (widget)",
1598
windows->widget.id);
1600
Initialize popup window.
1602
if (windows->popup.id != (Window) NULL)
1603
MagickFreeMemory(windows->popup.name);
1604
XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
1605
resource_info,&windows->popup);
1606
windows->popup.name=AllocateString((char *) NULL);
1607
*windows->popup.name='\0';
1608
windows->popup.border_width=0;
1609
windows->popup.flags|=PPosition;
1610
windows->popup.attributes.backing_store=WhenMapped;
1611
windows->popup.attributes.save_under=True;
1612
windows->popup.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
1613
ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
1614
KeyReleaseMask | LeaveWindowMask | StructureNotifyMask;
1615
class_hints->res_name=(char *) "popup";
1616
manager_hints->flags=InputHint | StateHint | WindowGroupHint;
1617
manager_hints->input=True;
1618
manager_hints->initial_state=NormalState;
1619
manager_hints->window_group=windows->image.id;
1620
XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
1622
windows->popup.highlight_stipple=windows->info.highlight_stipple;
1623
windows->popup.shadow_stipple=windows->info.shadow_stipple;
1624
(void) XSetTransientForHint(display,windows->popup.id,windows->image.id);
1625
if (IsEventLogging())
1626
(void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (pop up)",
1628
if (!windows->image.mapped || (windows->backdrop.id != (Window) NULL))
1629
(void) XMapWindow(display,windows->image.id);
1631
Set out progress and warning handlers.
1633
if (monitor_handler == (MonitorHandler) NULL)
1634
monitor_handler=SetMonitorHandler(XMagickMonitor);
1635
if (warning_handler == (WarningHandler) NULL)
1637
warning_handler=resource_info->display_warnings ?
1638
SetErrorHandler(XWarning) : SetErrorHandler((ErrorHandler) NULL);
1639
warning_handler=resource_info->display_warnings ?
1640
SetWarningHandler(XWarning) : SetWarningHandler((WarningHandler) NULL);
1642
(void) signal(SIGINT,XSignalHandler);
1643
(void) signal(SIGSEGV,XSignalHandler);
1644
(void) signal(SIGTERM,XSignalHandler);
1646
Initialize X image structure.
1650
status=XMakeImage(display,resource_info,&windows->image,display_image,
1651
(unsigned int) display_image->columns,(unsigned int) display_image->rows);
1652
if (status == False)
1653
MagickFatalError(XServerFatalError,UnableToCreateXImage,(char *) NULL);
1654
if (windows->image.mapped)
1655
XRefreshWindow(display,&windows->image,(XEvent *) NULL);
1657
Initialize image pixmaps structure.
1659
(void) XMapWindow(display,windows->image.id);
1660
windows->image.pixmaps=MagickAllocateMemory(Pixmap *,number_scenes*sizeof(Pixmap));
1661
windows->image.matte_pixmaps=MagickAllocateMemory(Pixmap *,
1662
number_scenes*sizeof(Pixmap));
1663
if ((windows->image.pixmaps == (Pixmap *) NULL) ||
1664
(windows->image.matte_pixmaps == (Pixmap *) NULL))
1665
MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
1666
UnableToAnimateImageSequence);
1667
windows->image.pixmaps[0]=windows->image.pixmap;
1668
windows->image.matte_pixmaps[0]=windows->image.matte_pixmap;
1669
scene_info.pixels=(unsigned long *) NULL;
1670
for (scene=1; scene < (long) number_scenes; scene++)
1675
TransformColorspace(image_list[scene],RGBColorspace);
1676
windows->image.pixmap=(Pixmap) NULL;
1677
windows->image.matte_pixmap=(Pixmap) NULL;
1678
if ((resource_info->map_type != (char *) NULL) ||
1679
(visual_info->storage_class == TrueColor) ||
1680
(visual_info->storage_class == DirectColor))
1681
if (image_list[scene]->storage_class == PseudoClass)
1684
Get pixel info for this scene.
1686
XGetPixelPacket(display,visual_info,map_info,resource_info,
1687
image_list[scene],&scene_info);
1688
windows->image.pixel_info=(&scene_info);
1690
status=XMakeImage(display,resource_info,&windows->image,image_list[scene],
1691
(unsigned int) image_list[scene]->columns,
1692
(unsigned int) image_list[scene]->rows);
1693
if (status == False)
1694
MagickFatalError(XServerFatalError,UnableToCreateXImage,(char *) NULL);
1695
if (IsEventLogging())
1697
(void) LogMagickEvent(X11Event,GetMagickModule(),
1698
"Image: [%lu] %.1024s %lux%lu ",image_list[scene]->scene,
1699
image_list[scene]->filename,image_list[scene]->columns,
1700
image_list[scene]->rows);
1701
if (image_list[scene]->colors != 0)
1702
(void) LogMagickEvent(X11Event,GetMagickModule(),"%luc ",
1703
image_list[scene]->colors);
1704
(void) LogMagickEvent(X11Event,GetMagickModule(),"%.1024s",
1705
image_list[scene]->magick);
1708
Window name is the base of the filename.
1710
if (resource_info->title != (char *) NULL)
1711
windows->image.name=TranslateText(resource_info->image_info,
1712
image_list[scene],resource_info->title);
1715
p=image_list[scene]->filename+strlen(image_list[scene]->filename)-1;
1716
while ((p > image_list[scene]->filename) && (*(p-1) != '/'))
1718
FormatString(windows->image.name,"GraphicsMagick: %.1024s[%lu of %lu]",p,
1719
scene,number_scenes);
1721
status=XStringListToTextProperty(&windows->image.name,1,&window_name);
1724
XSetWMName(display,windows->image.id,&window_name);
1725
(void) XFree((void *) window_name.value);
1727
windows->image.pixmaps[scene]=windows->image.pixmap;
1728
windows->image.matte_pixmaps[scene]=windows->image.matte_pixmap;
1731
event.xexpose.width=(unsigned int) image_list[scene]->columns;
1732
event.xexpose.height=(unsigned int) image_list[scene]->rows;
1733
XRefreshWindow(display,&windows->image,&event);
1734
XDelay(display,(unsigned long) resource_info->delay*10*Max(images->delay,1));
1736
if (windows->command.mapped)
1737
(void) XMapRaised(display,windows->command.id);
1741
nexus=(Image *) NULL;
1745
image=image_list[0];
1746
state=ForwardAnimationState | RepeatAnimationState;
1747
(void) XMagickCommand(display,resource_info,windows,PlayCommand,&images,
1751
if (XEventsQueued(display,QueuedAfterFlush) == 0)
1752
if ((state & PlayAnimationState) || (state & StepAnimationState))
1754
if (state & ForwardAnimationState)
1757
Forward animation: increment scene number.
1759
if (scene < ((long) number_scenes-1))
1764
if (iterations == image_list[0]->iterations)
1767
state&=(~RepeatAnimationState);
1769
if (state & AutoReverseAnimationState)
1771
state&=(~ForwardAnimationState);
1776
if (!(state & RepeatAnimationState))
1777
state&=(~PlayAnimationState);
1779
(void) sleep(resource_info->pause);
1786
Reverse animation: decrement scene number.
1788
if (scene > first_scene)
1793
if (iterations == image_list[0]->iterations)
1796
state&=(~RepeatAnimationState);
1798
if (state & AutoReverseAnimationState)
1800
state|=ForwardAnimationState;
1802
(void) sleep(resource_info->pause);
1806
if (!(state & RepeatAnimationState))
1807
state&=(~PlayAnimationState);
1808
scene=(long) number_scenes-1;
1812
image=image_list[scene];
1813
if ((image != (Image *) NULL) && image->start_loop)
1815
if ((state & StepAnimationState) ||
1816
(resource_info->title != (char *) NULL))
1819
Update window title.
1821
p=image_list[scene]->filename+
1822
strlen(image_list[scene]->filename)-1;
1823
while ((p > image_list[scene]->filename) && (*(p-1) != '/'))
1825
FormatString(windows->image.name,
1826
"GraphicsMagick: %.1024s[%lu of %lu]",p,scene,number_scenes);
1827
if (resource_info->title != (char *) NULL)
1828
windows->image.name=TranslateText(resource_info->image_info,
1829
image,resource_info->title);
1831
XStringListToTextProperty(&windows->image.name,1,&window_name);
1834
XSetWMName(display,windows->image.id,&window_name);
1835
(void) XFree((void *) window_name.value);
1839
Copy X pixmap to Image window.
1841
XGetPixelPacket(display,visual_info,map_info,resource_info,
1842
image_list[scene],&scene_info); /* FIXME leak here */
1843
windows->image.pixel_info=(&scene_info);
1844
windows->image.ximage->width=(unsigned int) image->columns;
1845
windows->image.ximage->height=(unsigned int) image->rows;
1846
windows->image.pixmap=windows->image.pixmaps[scene];
1847
windows->image.matte_pixmap=windows->image.matte_pixmaps[scene];
1850
event.xexpose.width=(unsigned int) image->columns;
1851
event.xexpose.height=(unsigned int) image->rows;
1852
XRefreshWindow(display,&windows->image,&event);
1853
(void) XSync(display,False);
1854
state&=(~StepAnimationState);
1855
XDelay(display,(unsigned long) resource_info->delay*10*
1856
Max(image->delay,1));
1860
Handle a window event.
1862
timestamp=time((time_t *) NULL);
1863
(void) XNextEvent(display,&event);
1864
if (!windows->image.stasis)
1865
windows->image.stasis=(time((time_t *) NULL)-timestamp) > 0;
1866
if (event.xany.window == windows->command.id)
1872
Select a command from the Command widget.
1874
id=XCommandWidget(display,windows,CommandMenu,&event);
1877
(void) strncpy(command,CommandMenu[id],MaxTextExtent-1);
1878
command_type=CommandMenus[id];
1879
if (id < MagickMenus)
1885
Select a command from a pop-up menu.
1887
entry=XMenuWidget(display,windows,CommandMenu[id],Menus[id],
1891
(void) strncpy(command,Menus[id][entry],MaxTextExtent-1);
1892
command_type=Commands[id][entry];
1894
if (command_type != NullCommand)
1895
nexus=XMagickCommand(display,resource_info,windows,
1896
command_type,&image,&state);
1903
if (IsEventLogging())
1904
(void) LogMagickEvent(X11Event,GetMagickModule(),
1905
"Button Press: 0x%lx %u +%d+%d",event.xbutton.window,
1906
event.xbutton.button,event.xbutton.x,event.xbutton.y);
1907
if ((event.xbutton.button == Button3) &&
1908
(event.xbutton.state & Mod1Mask))
1911
Convert Alt-Button3 to Button2.
1913
event.xbutton.button=Button2;
1914
event.xbutton.state&=(~Mod1Mask);
1916
if (event.xbutton.window == windows->backdrop.id)
1918
(void) XSetInputFocus(display,event.xbutton.window,RevertToParent,
1919
event.xbutton.time);
1922
if (event.xbutton.window == windows->image.id)
1924
if (resource_info->immutable)
1930
Map/unmap Command widget.
1932
if (windows->command.mapped)
1933
(void) XWithdrawWindow(display,windows->command.id,
1934
windows->command.screen);
1937
(void) XCommandWidget(display,windows,CommandMenu,
1939
(void) XMapRaised(display,windows->command.id);
1946
if (IsEventLogging())
1947
(void) LogMagickEvent(X11Event,GetMagickModule(),
1948
"Button Release: 0x%lx %u +%d+%d",event.xbutton.window,
1949
event.xbutton.button,event.xbutton.x,event.xbutton.y);
1954
if (IsEventLogging())
1955
(void) LogMagickEvent(X11Event,GetMagickModule(),
1956
"Client Message: 0x%lx 0x%lx %d 0x%lx",event.xclient.window,
1957
event.xclient.message_type,event.xclient.format,(unsigned long)
1958
event.xclient.data.l[0]);
1959
if (event.xclient.message_type == windows->im_protocols)
1961
if (*event.xclient.data.l == (long) windows->im_update_colormap)
1964
Update graphic context and window colormap.
1966
for (i=0; i < (long) number_windows; i++)
1968
if (magick_windows[i]->id == windows->icon.id)
1970
context_values.background=pixel->background_color.pixel;
1971
context_values.foreground=pixel->foreground_color.pixel;
1972
(void) XChangeGC(display,magick_windows[i]->annotate_context,
1973
context_mask,&context_values);
1974
(void) XChangeGC(display,magick_windows[i]->widget_context,
1975
context_mask,&context_values);
1976
context_values.background=pixel->foreground_color.pixel;
1977
context_values.foreground=pixel->background_color.pixel;
1978
context_values.plane_mask=
1979
context_values.background ^ context_values.foreground;
1980
(void) XChangeGC(display,magick_windows[i]->highlight_context,
1981
context_mask | GCPlaneMask,&context_values);
1982
magick_windows[i]->attributes.background_pixel=
1983
pixel->background_color.pixel;
1984
magick_windows[i]->attributes.border_pixel=
1985
pixel->border_color.pixel;
1986
magick_windows[i]->attributes.colormap=map_info->colormap;
1987
(void) XChangeWindowAttributes(display,magick_windows[i]->id,
1988
magick_windows[i]->mask,&magick_windows[i]->attributes);
1990
if (windows->backdrop.id != (Window) NULL)
1991
(void) XInstallColormap(display,map_info->colormap);
1994
if (*event.xclient.data.l == (long) windows->im_exit)
2001
if (event.xclient.message_type == windows->dnd_protocols)
2018
Display image named by the Drag-and-Drop selection.
2020
if ((*event.xclient.data.l != 2) && (*event.xclient.data.l != 128))
2022
selection=XInternAtom(display,"DndSelection",False);
2023
status=XGetWindowProperty(display,root_window,selection,0L,2047L,
2024
False,(Atom) AnyPropertyType,&type,&format,&length,&after,&data);
2025
if ((status != Success) || (length == 0))
2027
if (*event.xclient.data.l == 2)
2032
(void) strncpy(resource_info->image_info->filename,
2033
(char *) data,MaxTextExtent-1);
2040
if (LocaleNCompare((char *) data,"file:",5) != 0)
2042
(void) XFree((void *) data);
2045
(void) strncpy(resource_info->image_info->filename,
2046
((char *) data)+5,MaxTextExtent-1);
2048
nexus=ReadImage(resource_info->image_info,&image->exception);
2049
if (image->exception.severity != UndefinedException)
2050
MagickError2(image->exception.severity,image->exception.reason,
2051
image->exception.description);
2052
if (nexus != (Image *) NULL)
2054
(void) XFree((void *) data);
2058
If client window delete message, exit.
2060
if (event.xclient.message_type != windows->wm_protocols)
2062
if (*event.xclient.data.l == (long) windows->wm_take_focus)
2064
(void) XSetInputFocus(display,event.xclient.window,RevertToParent,
2065
event.xclient.data.l[1]);
2068
if (*event.xclient.data.l != (long) windows->wm_delete_window)
2070
(void) XWithdrawWindow(display,event.xclient.window,
2071
visual_info->screen);
2072
if (event.xclient.window == windows->image.id)
2079
case ConfigureNotify:
2081
if (IsEventLogging())
2082
(void) LogMagickEvent(X11Event,GetMagickModule(),
2083
"Configure Notify: 0x%lx %dx%d+%d+%d %d",event.xconfigure.window,
2084
event.xconfigure.width,event.xconfigure.height,event.xconfigure.x,
2085
event.xconfigure.y,event.xconfigure.send_event);
2086
if (event.xconfigure.window == windows->image.id)
2088
if (event.xconfigure.send_event != 0)
2094
Position the transient windows relative of the Image window.
2096
if (windows->command.geometry == (char *) NULL)
2097
if (!windows->command.mapped)
2100
event.xconfigure.x-windows->command.width-25;
2101
windows->command.y=event.xconfigure.y;
2102
XConstrainWindowPosition(display,&windows->command);
2103
window_changes.x=windows->command.x;
2104
window_changes.y=windows->command.y;
2105
(void) XReconfigureWMWindow(display,windows->command.id,
2106
windows->command.screen,CWX | CWY,&window_changes);
2108
if (windows->widget.geometry == (char *) NULL)
2109
if (!windows->widget.mapped)
2112
event.xconfigure.x+event.xconfigure.width/10;
2114
event.xconfigure.y+event.xconfigure.height/10;
2115
XConstrainWindowPosition(display,&windows->widget);
2116
window_changes.x=windows->widget.x;
2117
window_changes.y=windows->widget.y;
2118
(void) XReconfigureWMWindow(display,windows->widget.id,
2119
windows->widget.screen,CWX | CWY,&window_changes);
2123
Image window has a new configuration.
2125
windows->image.width=event.xconfigure.width;
2126
windows->image.height=event.xconfigure.height;
2129
if (event.xconfigure.window == windows->icon.id)
2132
Icon window has a new configuration.
2134
windows->icon.width=event.xconfigure.width;
2135
windows->icon.height=event.xconfigure.height;
2143
Group leader has exited.
2145
if (IsEventLogging())
2146
(void) LogMagickEvent(X11Event,GetMagickModule(),"Destroy Notify: 0x%lx",
2147
event.xdestroywindow.window);
2148
if (event.xdestroywindow.window == windows->group_leader.id)
2158
Selectively install colormap.
2160
if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
2161
if (event.xcrossing.mode != NotifyUngrab)
2162
XInductColormap(display,map_info->colormap);
2167
if (IsEventLogging())
2168
(void) LogMagickEvent(X11Event,GetMagickModule(),
2169
"Expose: 0x%lx %dx%d+%d+%d",event.xexpose.window,
2170
event.xexpose.width,event.xexpose.height,event.xexpose.x,
2173
Repaint windows that are now exposed.
2175
if (event.xexpose.window == windows->image.id)
2177
windows->image.pixmap=windows->image.pixmaps[scene];
2178
windows->image.matte_pixmap=windows->image.matte_pixmaps[scene];
2179
XRefreshWindow(display,&windows->image,&event);
2182
if (event.xexpose.window == windows->icon.id)
2183
if (event.xexpose.count == 0)
2185
XRefreshWindow(display,&windows->icon,&event);
2196
Respond to a user key press.
2198
length=XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
2199
&key_symbol,(XComposeStatus *) NULL);
2200
*(command+length)='\0';
2201
if (IsEventLogging())
2202
(void) LogMagickEvent(X11Event,GetMagickModule(),"Key press: 0x%lx (%c)",
2203
key_symbol,*command);
2204
command_type=NullCommand;
2209
if (!(event.xkey.state & ControlMask))
2211
command_type=OpenCommand;
2216
command_type=StepBackwardCommand;
2221
command_type=StepForwardCommand;
2226
command_type=FasterCommand;
2231
command_type=SlowerCommand;
2236
command_type=HelpCommand;
2241
command_type=BrowseDocumentationCommand;
2246
command_type=InfoCommand;
2252
if (!(event.xkey.state & ControlMask))
2254
command_type=QuitCommand;
2260
if (command_type != NullCommand)
2261
nexus=XMagickCommand(display,resource_info,windows,
2262
command_type,&image,&state);
2268
Respond to a user key release.
2270
(void) XLookupString((XKeyEvent *) &event.xkey,command,sizeof(command),
2271
&key_symbol,(XComposeStatus *) NULL);
2272
if (IsEventLogging())
2273
(void) LogMagickEvent(X11Event,GetMagickModule(),
2274
"Key release: 0x%lx (%c)",key_symbol,*command);
2280
Selectively uninstall colormap.
2282
if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
2283
if (event.xcrossing.mode != NotifyUngrab)
2284
XUninductColormap(display,map_info->colormap);
2289
if (IsEventLogging())
2290
(void) LogMagickEvent(X11Event,GetMagickModule(),"Map Notify: 0x%lx",
2292
if (event.xmap.window == windows->backdrop.id)
2294
(void) XSetInputFocus(display,event.xmap.window,RevertToParent,
2296
windows->backdrop.mapped=True;
2299
if (event.xmap.window == windows->image.id)
2301
if (windows->backdrop.id != (Window) NULL)
2302
(void) XInstallColormap(display,map_info->colormap);
2303
if (LocaleCompare(image_list[0]->magick,"LOGO") == 0)
2305
if (LocaleCompare(display_image->filename,"Untitled") == 0)
2306
nexus=XMagickCommand(display,resource_info,windows,
2307
OpenCommand,&image,&state);
2311
windows->image.mapped=True;
2314
if (event.xmap.window == windows->info.id)
2316
windows->info.mapped=True;
2319
if (event.xmap.window == windows->icon.id)
2322
Create an icon image.
2324
XMakeStandardColormap(display,icon_visual,icon_resources,
2325
display_image,icon_map,icon_pixel);
2326
(void) XMakeImage(display,icon_resources,&windows->icon,
2327
display_image,windows->icon.width,windows->icon.height);
2328
(void) XSetWindowBackgroundPixmap(display,windows->icon.id,
2329
windows->icon.pixmap);
2330
(void) XClearWindow(display,windows->icon.id);
2331
(void) XWithdrawWindow(display,windows->info.id,
2332
windows->info.screen);
2333
windows->icon.mapped=True;
2336
if (event.xmap.window == windows->command.id)
2338
windows->command.mapped=True;
2341
if (event.xmap.window == windows->popup.id)
2343
windows->popup.mapped=True;
2346
if (event.xmap.window == windows->widget.id)
2348
windows->widget.mapped=True;
2355
(void) XRefreshKeyboardMapping(&event.xmapping);
2360
case PropertyNotify:
2375
if (IsEventLogging())
2376
(void) LogMagickEvent(X11Event,GetMagickModule(),
2377
"Property Notify: 0x%lx 0x%lx %d",event.xproperty.window,
2378
event.xproperty.atom,event.xproperty.state);
2379
if (event.xproperty.atom != windows->im_remote_command)
2382
Display image named by the remote command protocol.
2384
status=XGetWindowProperty(display,event.xproperty.window,
2385
event.xproperty.atom,0L,MaxTextExtent-1,False,(Atom) AnyPropertyType,
2386
&type,&format,&length,&after,&data);
2387
if ((status != Success) || (length == 0))
2389
(void) strncpy(resource_info->image_info->filename,(char *) data,
2391
nexus=ReadImage(resource_info->image_info,&image->exception);
2392
if (image->exception.severity != UndefinedException)
2393
MagickError2(image->exception.severity,image->exception.reason,
2394
image->exception.description);
2395
if (nexus != (Image *) NULL)
2397
(void) XFree((void *) data);
2400
case ReparentNotify:
2402
if (IsEventLogging())
2403
(void) LogMagickEvent(X11Event,GetMagickModule(),
2404
"Reparent Notify: 0x%lx=>0x%lx",event.xreparent.parent,
2405
event.xreparent.window);
2410
if (IsEventLogging())
2411
(void) LogMagickEvent(X11Event,GetMagickModule(),"Unmap Notify: 0x%lx",
2412
event.xunmap.window);
2413
if (event.xunmap.window == windows->backdrop.id)
2415
windows->backdrop.mapped=False;
2418
if (event.xunmap.window == windows->image.id)
2420
windows->image.mapped=False;
2423
if (event.xunmap.window == windows->info.id)
2425
windows->info.mapped=False;
2428
if (event.xunmap.window == windows->icon.id)
2430
if (map_info->colormap == icon_map->colormap)
2431
XConfigureImageColormap(display,resource_info,windows,
2433
(void) XFreeStandardColormap(display,icon_visual,icon_map,
2435
windows->icon.mapped=False;
2438
if (event.xunmap.window == windows->command.id)
2440
windows->command.mapped=False;
2443
if (event.xunmap.window == windows->popup.id)
2445
if (windows->backdrop.id != (Window) NULL)
2446
(void) XSetInputFocus(display,windows->image.id,RevertToParent,
2448
windows->popup.mapped=False;
2451
if (event.xunmap.window == windows->widget.id)
2453
if (windows->backdrop.id != (Window) NULL)
2454
(void) XSetInputFocus(display,windows->image.id,RevertToParent,
2456
windows->widget.mapped=False;
2463
if (IsEventLogging())
2464
(void) LogMagickEvent(X11Event,GetMagickModule(),"Event type: %d",
2470
while (!(state & ExitState));
2471
MagickFreeMemory(image_list);
2474
DestroyImageList(images);
2475
images=(Image *) NULL;
2477
if ((windows->visual_info->storage_class == GrayScale) ||
2478
(windows->visual_info->storage_class == PseudoColor) ||
2479
(windows->visual_info->storage_class == DirectColor))
2484
if (windows->info.mapped)
2485
(void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
2486
if (windows->command.mapped)
2487
(void) XWithdrawWindow(display,windows->command.id,
2488
windows->command.screen);
2490
if (!resource_info->backdrop)
2491
if (windows->backdrop.mapped)
2493
(void) XWithdrawWindow(display,windows->backdrop.id,
2494
windows->backdrop.screen);
2495
(void) XDestroyWindow(display,windows->backdrop.id);
2496
windows->backdrop.id=(Window) NULL;
2497
(void) XWithdrawWindow(display,windows->image.id,windows->image.screen);
2498
(void) XDestroyWindow(display,windows->image.id);
2499
windows->image.id=(Window) NULL;
2501
XSetCursorState(display,windows,True);
2502
XCheckRefreshWindows(display,windows);
2503
for (scene=1; scene < (long) number_scenes; scene++)
2505
if (windows->image.pixmaps[scene] != (Pixmap) NULL)
2506
(void) XFreePixmap(display,windows->image.pixmaps[scene]);
2507
windows->image.pixmaps[scene]=(Pixmap) NULL;
2509
if (windows->image.matte_pixmaps[scene] != (Pixmap) NULL)
2510
(void) XFreePixmap(display,windows->image.matte_pixmaps[scene]);
2511
windows->image.matte_pixmaps[scene]=(Pixmap) NULL;
2513
MagickFreeMemory(windows->image.pixmaps);
2514
MagickFreeMemory(windows->image.matte_pixmaps);
2515
if (nexus == (Image *) NULL)
2520
if (windows->image.mapped)
2521
(void) XWithdrawWindow(display,windows->image.id,windows->image.screen);
2522
XDelay(display,SuspendTime);
2525
Free Standard Colormap.
2527
(void) XFreeStandardColormap(display,icon_visual,icon_map,icon_pixel);
2528
if (resource_info->map_type == (char *) NULL)
2529
(void) XFreeStandardColormap(display,visual_info,map_info,pixel);
2533
XDestroyXWindows(windows);
2535
(void) XSync(display,False);
2537
Restore our progress monitor and warning handlers.
2539
(void) SetMonitorHandler(monitor_handler);
2540
(void) SetErrorHandler(warning_handler);
2541
(void) SetWarningHandler(warning_handler);
2543
Change to home directory.
2545
(void) getcwd(working_directory,MaxTextExtent-1);
2546
(void) chdir(resource_info->home_directory);