42#include "MagickCore/studio.h"
43#include "MagickCore/artifact.h"
44#include "MagickCore/attribute.h"
45#include "MagickCore/blob.h"
46#include "MagickCore/cache.h"
47#include "MagickCore/cache-private.h"
48#include "MagickCore/channel.h"
49#include "MagickCore/client.h"
50#include "MagickCore/color.h"
51#include "MagickCore/colorspace.h"
52#include "MagickCore/composite.h"
53#include "MagickCore/constitute.h"
54#include "MagickCore/decorate.h"
55#include "MagickCore/delegate.h"
56#include "MagickCore/display.h"
57#include "MagickCore/display-private.h"
58#include "MagickCore/distort.h"
59#include "MagickCore/draw.h"
60#include "MagickCore/effect.h"
61#include "MagickCore/enhance.h"
62#include "MagickCore/exception.h"
63#include "MagickCore/exception-private.h"
64#include "MagickCore/fx.h"
65#include "MagickCore/geometry.h"
66#include "MagickCore/image.h"
67#include "MagickCore/image-private.h"
68#include "MagickCore/list.h"
69#include "MagickCore/locale-private.h"
70#include "MagickCore/log.h"
71#include "MagickCore/magick.h"
72#include "MagickCore/memory_.h"
73#include "MagickCore/monitor.h"
74#include "MagickCore/monitor-private.h"
75#include "MagickCore/montage.h"
76#include "MagickCore/nt-base-private.h"
77#include "MagickCore/option.h"
78#include "MagickCore/paint.h"
79#include "MagickCore/pixel.h"
80#include "MagickCore/pixel-accessor.h"
81#include "MagickCore/property.h"
82#include "MagickCore/quantum.h"
83#include "MagickCore/quantum-private.h"
84#include "MagickCore/resize.h"
85#include "MagickCore/resource_.h"
86#include "MagickCore/shear.h"
87#include "MagickCore/segment.h"
88#include "MagickCore/statistic.h"
89#include "MagickCore/string_.h"
90#include "MagickCore/string-private.h"
91#include "MagickCore/timer-private.h"
92#include "MagickCore/transform.h"
93#include "MagickCore/transform-private.h"
94#include "MagickCore/threshold.h"
95#include "MagickCore/utility.h"
96#include "MagickCore/utility-private.h"
97#include "MagickCore/version.h"
98#include "MagickCore/visual-effects.h"
99#include "MagickCore/widget.h"
100#include "MagickCore/widget-private.h"
101#include "MagickCore/xwindow.h"
102#include "MagickCore/xwindow-private.h"
104#if defined(MAGICKCORE_X11_DELEGATE)
108#define MaxColors MagickMin((ssize_t) windows->visual_info->colormap_size,256L)
113static const unsigned char
116 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55
120 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
124 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
131 ImageAnnotateHelp[] =
133 "In annotate mode, the Command widget has these options:\n"
183 "Choose a font name from the Font Name sub-menu. Additional\n"
184 "font names can be specified with the font browser. You can\n"
185 "change the menu names by setting the X resources font1\n"
188 "Choose a font color from the Font Color sub-menu.\n"
189 "Additional font colors can be specified with the color\n"
190 "browser. You can change the menu colors by setting the X\n"
191 "resources pen1 through pen9.\n"
193 "If you select the color browser and press Grab, you can\n"
194 "choose the font color by moving the pointer to the desired\n"
195 "color on the screen and press any button.\n"
197 "If you choose to rotate the text, choose Rotate Text from the\n"
198 "menu and select an angle. Typically you will only want to\n"
199 "rotate one line of text at a time. Depending on the angle you\n"
200 "choose, subsequent lines may end up overwriting each other.\n"
202 "Choosing a font and its color is optional. The default font\n"
203 "is fixed and the default color is black. However, you must\n"
204 "choose a location to begin entering text and press button 1.\n"
205 "An underscore character will appear at the location of the\n"
206 "pointer. The cursor changes to a pencil to indicate you are\n"
207 "in text mode. To exit immediately, press Dismiss.\n"
209 "In text mode, any key presses will display the character at\n"
210 "the location of the underscore and advance the underscore\n"
211 "cursor. Enter your text and once completed press Apply to\n"
212 "finish your image annotation. To correct errors press BACK\n"
213 "SPACE. To delete an entire line of text, press DELETE. Any\n"
214 "text that exceeds the boundaries of the image window is\n"
215 "automagically continued onto the next line.\n"
217 "The actual color you request for the font is saved in the\n"
218 "image. However, the color that appears in your image window\n"
219 "may be different. For example, on a monochrome screen the\n"
220 "text will appear black or white even if you choose the color\n"
221 "red as the font color. However, the image saved to a file\n"
222 "with -write is written with red lettering. To assure the\n"
223 "correct color text in the final image, any PseudoClass image\n"
224 "is promoted to DirectClass (see miff(5)). To force a\n"
225 "PseudoClass image to remain PseudoClass, use -colors.\n"
229 "In chop mode, the Command widget has these options:\n"
237 "If the you choose the horizontal direction (this the\n"
238 "default), the area of the image between the two horizontal\n"
239 "endpoints of the chop line is removed. Otherwise, the area\n"
240 "of the image between the two vertical endpoints of the chop\n"
243 "Select a location within the image window to begin your chop,\n"
244 "press and hold any button. Next, move the pointer to\n"
245 "another location in the image. As you move a line will\n"
246 "connect the initial location and the pointer. When you\n"
247 "release the button, the area within the image to chop is\n"
248 "determined by which direction you choose from the Command\n"
251 "To cancel the image chopping, move the pointer back to the\n"
252 "starting point of the line and release the button.\n"
254 ImageColorEditHelp[] =
256 "In color edit mode, the Command widget has these options:\n"
297 "Choose a color editing method from the Method sub-menu\n"
298 "of the Command widget. The point method recolors any pixel\n"
299 "selected with the pointer until the button is released. The\n"
300 "replace method recolors any pixel that matches the color of\n"
301 "the pixel you select with a button press. Floodfill recolors\n"
302 "any pixel that matches the color of the pixel you select with\n"
303 "a button press and is a neighbor. Whereas filltoborder recolors\n"
304 "any neighbor pixel that is not the border color. Finally reset\n"
305 "changes the entire image to the designated color.\n"
307 "Next, choose a pixel color from the Pixel Color sub-menu.\n"
308 "Additional pixel colors can be specified with the color\n"
309 "browser. You can change the menu colors by setting the X\n"
310 "resources pen1 through pen9.\n"
312 "Now press button 1 to select a pixel within the image window\n"
313 "to change its color. Additional pixels may be recolored as\n"
314 "prescribed by the method you choose.\n"
316 "If the Magnify widget is mapped, it can be helpful in positioning\n"
317 "your pointer within the image (refer to button 2).\n"
319 "The actual color you request for the pixels is saved in the\n"
320 "image. However, the color that appears in your image window\n"
321 "may be different. For example, on a monochrome screen the\n"
322 "pixel will appear black or white even if you choose the\n"
323 "color red as the pixel color. However, the image saved to a\n"
324 "file with -write is written with red pixels. To assure the\n"
325 "correct color text in the final image, any PseudoClass image\n"
326 "is promoted to DirectClass (see miff(5)). To force a\n"
327 "PseudoClass image to remain PseudoClass, use -colors.\n"
329 ImageCompositeHelp[] =
331 "First a widget window is displayed requesting you to enter an\n"
332 "image name. Press Composite, Grab or type a file name.\n"
333 "Press Cancel if you choose not to create a composite image.\n"
334 "When you choose Grab, move the pointer to the desired window\n"
335 "and press any button.\n"
337 "If the Composite image does not have any matte information,\n"
338 "you are informed and the file browser is displayed again.\n"
339 "Enter the name of a mask image. The image is typically\n"
340 "grayscale and the same size as the composite image. If the\n"
341 "image is not grayscale, it is converted to grayscale and the\n"
342 "resulting intensities are used as matte information.\n"
344 "A small window appears showing the location of the cursor in\n"
345 "the image window. You are now in composite mode. To exit\n"
346 "immediately, press Dismiss. In composite mode, the Command\n"
347 "widget has these options:\n"
373 "Choose a composite operation from the Operators sub-menu of\n"
374 "the Command widget. How each operator behaves is described\n"
375 "below. Image window is the image currently displayed on\n"
376 "your X server and image is the image obtained with the File\n"
379 "Over The result is the union of the two image shapes,\n"
380 " with image obscuring image window in the region of\n"
383 "In The result is simply image cut by the shape of\n"
384 " image window. None of the image data of image\n"
385 " window is in the result.\n"
387 "Out The resulting image is image with the shape of\n"
388 " image window cut out.\n"
390 "Atop The result is the same shape as the image window,\n"
391 " with image obscuring image window where the image\n"
392 " shapes overlap. Note this differs from over\n"
393 " because the portion of image outside image window's\n"
394 " shape does not appear in the result.\n"
396 "Xor The result is the image data from both image and\n"
397 " image window that is outside the overlap region.\n"
398 " The overlap region is blank.\n"
400 "Plus The result is just the sum of the image data.\n"
401 " Output values are cropped to QuantumRange (no overflow).\n"
403 "Minus The result of image - image window, with underflow\n"
404 " cropped to zero.\n"
406 "Add The result of image + image window, with overflow\n"
407 " wrapping around (mod 256).\n"
409 "Subtract The result of image - image window, with underflow\n"
410 " wrapping around (mod 256). The add and subtract\n"
411 " operators can be used to perform reversible\n"
412 " transformations.\n"
415 " The result of abs(image - image window). This\n"
416 " useful for comparing two very similar images.\n"
419 " The result of image * image window. This\n"
420 " useful for the creation of drop-shadows.\n"
422 "Bumpmap The result of surface normals from image * image\n"
425 "Copy The resulting image is image window replaced with\n"
426 " image. Here the matte information is ignored.\n"
428 "CopyRed The red layer of the image window is replace with\n"
429 " the red layer of the image. The other layers are\n"
433 " The green layer of the image window is replace with\n"
434 " the green layer of the image. The other layers are\n"
437 "CopyBlue The blue layer of the image window is replace with\n"
438 " the blue layer of the image. The other layers are\n"
442 " The matte layer of the image window is replace with\n"
443 " the matte layer of the image. The other layers are\n"
446 "The image compositor requires a matte, or alpha channel in\n"
447 "the image for some operations. This extra channel usually\n"
448 "defines a mask which represents a sort of a cookie-cutter\n"
449 "for the image. This the case when matte is opaque (full\n"
450 "coverage) for pixels inside the shape, zero outside, and\n"
451 "between 0 and QuantumRange on the boundary. If image does not\n"
452 "have a matte channel, it is initialized with 0 for any pixel\n"
453 "matching in color to pixel location (0,0), otherwise QuantumRange.\n"
455 "If you choose Dissolve, the composite operator becomes Over. The\n"
456 "image matte channel percent transparency is initialized to factor.\n"
457 "The image window is initialized to (100-factor). Where factor is the\n"
458 "value you specify in the Dialog widget.\n"
460 "Displace shifts the image pixels as defined by a displacement\n"
461 "map. With this option, image is used as a displacement map.\n"
462 "Black, within the displacement map, is a maximum positive\n"
463 "displacement. White is a maximum negative displacement and\n"
464 "middle gray is neutral. The displacement is scaled to determine\n"
465 "the pixel shift. By default, the displacement applies in both the\n"
466 "horizontal and vertical directions. However, if you specify a mask,\n"
467 "image is the horizontal X displacement and mask the vertical Y\n"
470 "Note that matte information for image window is not retained\n"
471 "for colormapped X server visuals (e.g. StaticColor,\n"
472 "StaticColor, GrayScale, PseudoColor). Correct compositing\n"
473 "behavior may require a TrueColor or DirectColor visual or a\n"
474 "Standard Colormap.\n"
476 "Choosing a composite operator is optional. The default\n"
477 "operator is replace. However, you must choose a location to\n"
478 "composite your image and press button 1. Press and hold the\n"
479 "button before releasing and an outline of the image will\n"
480 "appear to help you identify your location.\n"
482 "The actual colors of the composite image is saved. However,\n"
483 "the color that appears in image window may be different.\n"
484 "For example, on a monochrome screen image window will appear\n"
485 "black or white even though your composited image may have\n"
486 "many colors. If the image is saved to a file it is written\n"
487 "with the correct colors. To assure the correct colors are\n"
488 "saved in the final image, any PseudoClass image is promoted\n"
489 "to DirectClass (see miff(5)). To force a PseudoClass image\n"
490 "to remain PseudoClass, use -colors.\n"
494 "In cut mode, the Command widget has these options:\n"
499 "To define a cut region, press button 1 and drag. The\n"
500 "cut region is defined by a highlighted rectangle that\n"
501 "expands or contracts as it follows the pointer. Once you\n"
502 "are satisfied with the cut region, release the button.\n"
503 "You are now in rectify mode. In rectify mode, the Command\n"
504 "widget has these options:\n"
510 "You can make adjustments by moving the pointer to one of the\n"
511 "cut rectangle corners, pressing a button, and dragging.\n"
512 "Finally, press Cut to commit your copy region. To\n"
513 "exit without cutting the image, press Dismiss.\n"
517 "In copy mode, the Command widget has these options:\n"
522 "To define a copy region, press button 1 and drag. The\n"
523 "copy region is defined by a highlighted rectangle that\n"
524 "expands or contracts as it follows the pointer. Once you\n"
525 "are satisfied with the copy region, release the button.\n"
526 "You are now in rectify mode. In rectify mode, the Command\n"
527 "widget has these options:\n"
533 "You can make adjustments by moving the pointer to one of the\n"
534 "copy rectangle corners, pressing a button, and dragging.\n"
535 "Finally, press Copy to commit your copy region. To\n"
536 "exit without copying the image, press Dismiss.\n"
540 "In crop mode, the Command widget has these options:\n"
545 "To define a cropping region, press button 1 and drag. The\n"
546 "cropping region is defined by a highlighted rectangle that\n"
547 "expands or contracts as it follows the pointer. Once you\n"
548 "are satisfied with the cropping region, release the button.\n"
549 "You are now in rectify mode. In rectify mode, the Command\n"
550 "widget has these options:\n"
556 "You can make adjustments by moving the pointer to one of the\n"
557 "cropping rectangle corners, pressing a button, and dragging.\n"
558 "Finally, press Crop to commit your cropping region. To\n"
559 "exit without cropping the image, press Dismiss.\n"
563 "The cursor changes to a crosshair to indicate you are in\n"
564 "draw mode. To exit immediately, press Dismiss. In draw mode,\n"
565 "the Command widget has these options:\n"
610 "Choose a drawing primitive from the Element sub-menu.\n"
612 "Choose a color from the Color sub-menu. Additional\n"
613 "colors can be specified with the color browser.\n"
615 "If you choose the color browser and press Grab, you can\n"
616 "select the color by moving the pointer to the desired\n"
617 "color on the screen and press any button. The transparent\n"
618 "color updates the image matte channel and is useful for\n"
619 "image compositing.\n"
621 "Choose a stipple, if appropriate, from the Stipple sub-menu.\n"
622 "Additional stipples can be specified with the file browser.\n"
623 "Stipples obtained from the file browser must be on disk in the\n"
624 "X11 bitmap format.\n"
626 "Choose a width, if appropriate, from the Width sub-menu. To\n"
627 "choose a specific width select the Dialog widget.\n"
629 "Choose a point in the Image window and press button 1 and\n"
630 "hold. Next, move the pointer to another location in the\n"
631 "image. As you move, a line connects the initial location and\n"
632 "the pointer. When you release the button, the image is\n"
633 "updated with the primitive you just drew. For polygons, the\n"
634 "image is updated when you press and release the button without\n"
635 "moving the pointer.\n"
637 "To cancel image drawing, move the pointer back to the\n"
638 "starting point of the line and release the button.\n"
643 " The effects of each button press is described below. Three\n"
644 " buttons are required. If you have a two button mouse,\n"
645 " button 1 and 3 are returned. Press ALT and button 3 to\n"
646 " simulate button 2.\n"
648 " 1 Press this button to map or unmap the Command widget.\n"
650 " 2 Press and drag to define a region of the image to\n"
653 " 3 Press and drag to choose from a select set of commands.\n"
654 " This button behaves differently if the image being\n"
655 " displayed is a visual image directory. Here, choose a\n"
656 " particular tile of the directory and press this button and\n"
657 " drag to select a command from a pop-up menu. Choose from\n"
658 " these menu items:\n"
666 " If you choose Open, the image represented by the tile is\n"
667 " displayed. To return to the visual image directory, choose\n"
668 " Next from the Command widget. Next and Former moves to the\n"
669 " next or former image respectively. Choose Delete to delete\n"
670 " a particular image tile. Finally, choose Update to\n"
671 " synchronize all the image tiles with their respective\n"
675 " The Command widget lists a number of sub-menus and commands.\n"
687 " Visual Directory...\n"
721 " Contrast Stretch...\n"
722 " Sigmoidal Contrast...\n"
750 " Charcoal Drawing...\n"
761 " Region of Interest...\n"
773 " Browse Documentation\n"
776 " Menu items with a indented triangle have a sub-menu. They\n"
777 " are represented above as the indented items. To access a\n"
778 " sub-menu item, move the pointer to the appropriate menu and\n"
779 " press a button and drag. When you find the desired sub-menu\n"
780 " item, release the button and the command is executed. Move\n"
781 " the pointer away from the sub-menu if you decide not to\n"
782 " execute a particular command.\n"
784 "KEYBOARD ACCELERATORS\n"
785 " Accelerators are one or two key presses that effect a\n"
786 " particular command. The keyboard accelerators that\n"
787 " display(1) understands is:\n"
789 " Ctl+O Press to open an image from a file.\n"
791 " space Press to display the next image.\n"
793 " If the image is a multi-paged document such as a Postscript\n"
794 " document, you can skip ahead several pages by preceding\n"
795 " this command with a number. For example to display the\n"
796 " third page beyond the current page, press 3<space>.\n"
798 " backspace Press to display the former image.\n"
800 " If the image is a multi-paged document such as a Postscript\n"
801 " document, you can skip behind several pages by preceding\n"
802 " this command with a number. For example to display the\n"
803 " third page preceding the current page, press 3<backspace>.\n"
805 " Ctl+S Press to write the image to a file.\n"
807 " Ctl+P Press to print the image to a Postscript printer.\n"
809 " Ctl+D Press to delete an image file.\n"
811 " Ctl+N Press to create a blank canvas.\n"
813 " Ctl+Q Press to discard all images and exit program.\n"
815 " Ctl+Z Press to undo last image transformation.\n"
817 " Ctl+R Press to redo last image transformation.\n"
819 " Ctl+X Press to cut a region of the image.\n"
821 " Ctl+C Press to copy a region of the image.\n"
823 " Ctl+V Press to paste a region to the image.\n"
825 " < Press to half the image size.\n"
827 " - Press to return to the original image size.\n"
829 " > Press to double the image size.\n"
831 " % Press to resize the image to a width and height you\n"
834 "Cmd-A Press to make any image transformations permanent."
836 " By default, any image size transformations are applied\n"
837 " to the original image to create the image displayed on\n"
838 " the X server. However, the transformations are not\n"
839 " permanent (i.e. the original image does not change\n"
840 " size only the X image does). For example, if you\n"
841 " press > the X image will appear to double in size,\n"
842 " but the original image will in fact remain the same size.\n"
843 " To force the original image to double in size, press >\n"
844 " followed by Cmd-A.\n"
846 " @ Press to refresh the image window.\n"
848 " C Press to cut out a rectangular region of the image.\n"
850 " [ Press to chop the image.\n"
852 " H Press to flop image in the horizontal direction.\n"
854 " V Press to flip image in the vertical direction.\n"
856 " / Press to rotate the image 90 degrees clockwise.\n"
858 " \\ Press to rotate the image 90 degrees counter-clockwise.\n"
860 " * Press to rotate the image the number of degrees you\n"
863 " S Press to shear the image the number of degrees you\n"
866 " R Press to roll the image.\n"
868 " T Press to trim the image edges.\n"
870 " Shft-H Press to vary the image hue.\n"
872 " Shft-S Press to vary the color saturation.\n"
874 " Shft-L Press to vary the color brightness.\n"
876 " Shft-G Press to gamma correct the image.\n"
878 " Shft-C Press to sharpen the image contrast.\n"
880 " Shft-Z Press to dull the image contrast.\n"
882 " = Press to perform histogram equalization on the image.\n"
884 " Shft-N Press to perform histogram normalization on the image.\n"
886 " Shft-~ Press to negate the colors of the image.\n"
888 " . Press to convert the image colors to gray.\n"
890 " Shft-# Press to set the maximum number of unique colors in the\n"
893 " F2 Press to reduce the speckles in an image.\n"
895 " F3 Press to eliminate peak noise from an image.\n"
897 " F4 Press to add noise to an image.\n"
899 " F5 Press to sharpen an image.\n"
901 " F6 Press to delete an image file.\n"
903 " F7 Press to threshold the image.\n"
905 " F8 Press to detect edges within an image.\n"
907 " F9 Press to emboss an image.\n"
909 " F10 Press to displace pixels by a random amount.\n"
911 " F11 Press to negate all pixels above the threshold level.\n"
913 " F12 Press to shade the image using a distant light source.\n"
915 " F13 Press to lighten or darken image edges to create a 3-D effect.\n"
917 " F14 Press to segment the image by color.\n"
919 " Meta-S Press to swirl image pixels about the center.\n"
921 " Meta-I Press to implode image pixels about the center.\n"
923 " Meta-W Press to alter an image along a sine wave.\n"
925 " Meta-P Press to simulate an oil painting.\n"
927 " Meta-C Press to simulate a charcoal drawing.\n"
929 " Alt-A Press to annotate the image with text.\n"
931 " Alt-D Press to draw on an image.\n"
933 " Alt-P Press to edit an image pixel color.\n"
935 " Alt-M Press to edit the image matte information.\n"
937 " Alt-V Press to composite the image with another.\n"
939 " Alt-B Press to add a border to the image.\n"
941 " Alt-F Press to add an ornamental border to the image.\n"
944 " Press to add an image comment.\n"
946 " Ctl-A Press to apply image processing techniques to a region\n"
949 " Shft-? Press to display information about the image.\n"
951 " Shft-+ Press to map the zoom image window.\n"
953 " Shft-P Press to preview an image enhancement, effect, or f/x.\n"
955 " F1 Press to display helpful information about display(1).\n"
957 " Find Press to browse documentation about ImageMagick.\n"
959 " 1-9 Press to change the level of magnification.\n"
961 " Use the arrow keys to move the image one pixel up, down,\n"
962 " left, or right within the magnify window. Be sure to first\n"
963 " map the magnify window by pressing button 2.\n"
965 " Press ALT and one of the arrow keys to trim off one pixel\n"
966 " from any side of the image.\n"
968 ImageMatteEditHelp[] =
970 "Matte information within an image is useful for some\n"
971 "operations such as image compositing (See IMAGE\n"
972 "COMPOSITING). This extra channel usually defines a mask\n"
973 "which represents a sort of a cookie-cutter for the image.\n"
974 "This the case when matte is opaque (full coverage) for\n"
975 "pixels inside the shape, zero outside, and between 0 and\n"
976 "QuantumRange on the boundary.\n"
978 "A small window appears showing the location of the cursor in\n"
979 "the image window. You are now in matte edit mode. To exit\n"
980 "immediately, press Dismiss. In matte edit mode, the Command\n"
981 "widget has these options:\n"
1015 "Choose a matte editing method from the Method sub-menu of\n"
1016 "the Command widget. The point method changes the matte value\n"
1017 "of any pixel selected with the pointer until the button is\n"
1018 "is released. The replace method changes the matte value of\n"
1019 "any pixel that matches the color of the pixel you select with\n"
1020 "a button press. Floodfill changes the matte value of any pixel\n"
1021 "that matches the color of the pixel you select with a button\n"
1022 "press and is a neighbor. Whereas filltoborder changes the matte\n"
1023 "value any neighbor pixel that is not the border color. Finally\n"
1024 "reset changes the entire image to the designated matte value.\n"
1026 "Choose Matte Value and pick Opaque or Transparent. For other values\n"
1027 "select the Dialog entry. Here a dialog appears requesting a matte\n"
1028 "value. The value you select is assigned as the opacity value of the\n"
1029 "selected pixel or pixels.\n"
1031 "Now, press any button to select a pixel within the image\n"
1032 "window to change its matte value.\n"
1034 "If the Magnify widget is mapped, it can be helpful in positioning\n"
1035 "your pointer within the image (refer to button 2).\n"
1037 "Matte information is only valid in a DirectClass image.\n"
1038 "Therefore, any PseudoClass image is promoted to DirectClass\n"
1039 "(see miff(5)). Note that matte information for PseudoClass\n"
1040 "is not retained for colormapped X server visuals (e.g.\n"
1041 "StaticColor, StaticColor, GrayScale, PseudoColor) unless you\n"
1042 "immediately save your image to a file (refer to Write).\n"
1043 "Correct matte editing behavior may require a TrueColor or\n"
1044 "DirectColor visual or a Standard Colormap.\n"
1048 "When an image exceeds the width or height of the X server\n"
1049 "screen, display maps a small panning icon. The rectangle\n"
1050 "within the panning icon shows the area that is currently\n"
1051 "displayed in the image window. To pan about the image,\n"
1052 "press any button and drag the pointer within the panning\n"
1053 "icon. The pan rectangle moves with the pointer and the\n"
1054 "image window is updated to reflect the location of the\n"
1055 "rectangle within the panning icon. When you have selected\n"
1056 "the area of the image you wish to view, release the button.\n"
1058 "Use the arrow keys to pan the image one pixel up, down,\n"
1059 "left, or right within the image window.\n"
1061 "The panning icon is withdrawn if the image becomes smaller\n"
1062 "than the dimensions of the X server screen.\n"
1066 "A small window appears showing the location of the cursor in\n"
1067 "the image window. You are now in paste mode. To exit\n"
1068 "immediately, press Dismiss. In paste mode, the Command\n"
1069 "widget has these options:\n"
1086 "Choose a composite operation from the Operators sub-menu of\n"
1087 "the Command widget. How each operator behaves is described\n"
1088 "below. Image window is the image currently displayed on\n"
1089 "your X server and image is the image obtained with the File\n"
1092 "Over The result is the union of the two image shapes,\n"
1093 " with image obscuring image window in the region of\n"
1096 "In The result is simply image cut by the shape of\n"
1097 " image window. None of the image data of image\n"
1098 " window is in the result.\n"
1100 "Out The resulting image is image with the shape of\n"
1101 " image window cut out.\n"
1103 "Atop The result is the same shape as the image window,\n"
1104 " with image obscuring image window where the image\n"
1105 " shapes overlap. Note this differs from over\n"
1106 " because the portion of image outside image window's\n"
1107 " shape does not appear in the result.\n"
1109 "Xor The result is the image data from both image and\n"
1110 " image window that is outside the overlap region.\n"
1111 " The overlap region is blank.\n"
1113 "Plus The result is just the sum of the image data.\n"
1114 " Output values are cropped to QuantumRange (no overflow).\n"
1115 " This operation is independent of the matte\n"
1118 "Minus The result of image - image window, with underflow\n"
1119 " cropped to zero.\n"
1121 "Add The result of image + image window, with overflow\n"
1122 " wrapping around (mod 256).\n"
1124 "Subtract The result of image - image window, with underflow\n"
1125 " wrapping around (mod 256). The add and subtract\n"
1126 " operators can be used to perform reversible\n"
1127 " transformations.\n"
1130 " The result of abs(image - image window). This\n"
1131 " useful for comparing two very similar images.\n"
1133 "Copy The resulting image is image window replaced with\n"
1134 " image. Here the matte information is ignored.\n"
1136 "CopyRed The red layer of the image window is replace with\n"
1137 " the red layer of the image. The other layers are\n"
1141 " The green layer of the image window is replace with\n"
1142 " the green layer of the image. The other layers are\n"
1145 "CopyBlue The blue layer of the image window is replace with\n"
1146 " the blue layer of the image. The other layers are\n"
1150 " The matte layer of the image window is replace with\n"
1151 " the matte layer of the image. The other layers are\n"
1154 "The image compositor requires a matte, or alpha channel in\n"
1155 "the image for some operations. This extra channel usually\n"
1156 "defines a mask which represents a sort of a cookie-cutter\n"
1157 "for the image. This the case when matte is opaque (full\n"
1158 "coverage) for pixels inside the shape, zero outside, and\n"
1159 "between 0 and QuantumRange on the boundary. If image does not\n"
1160 "have a matte channel, it is initialized with 0 for any pixel\n"
1161 "matching in color to pixel location (0,0), otherwise QuantumRange.\n"
1163 "Note that matte information for image window is not retained\n"
1164 "for colormapped X server visuals (e.g. StaticColor,\n"
1165 "StaticColor, GrayScale, PseudoColor). Correct compositing\n"
1166 "behavior may require a TrueColor or DirectColor visual or a\n"
1167 "Standard Colormap.\n"
1169 "Choosing a composite operator is optional. The default\n"
1170 "operator is replace. However, you must choose a location to\n"
1171 "paste your image and press button 1. Press and hold the\n"
1172 "button before releasing and an outline of the image will\n"
1173 "appear to help you identify your location.\n"
1175 "The actual colors of the pasted image is saved. However,\n"
1176 "the color that appears in image window may be different.\n"
1177 "For example, on a monochrome screen image window will appear\n"
1178 "black or white even though your pasted image may have\n"
1179 "many colors. If the image is saved to a file it is written\n"
1180 "with the correct colors. To assure the correct colors are\n"
1181 "saved in the final image, any PseudoClass image is promoted\n"
1182 "to DirectClass (see miff(5)). To force a PseudoClass image\n"
1183 "to remain PseudoClass, use -colors.\n"
1187 "In region of interest mode, the Command widget has these\n"
1193 "To define a region of interest, press button 1 and drag.\n"
1194 "The region of interest is defined by a highlighted rectangle\n"
1195 "that expands or contracts as it follows the pointer. Once\n"
1196 "you are satisfied with the region of interest, release the\n"
1197 "button. You are now in apply mode. In apply mode the\n"
1198 "Command widget has these options:\n"
1218 " Contrast Stretch\n"
1219 " Sigmoidal Contrast...\n"
1245 " Oil Painting...\n"
1246 " Charcoal Drawing...\n"
1250 " Show Preview...\n"
1256 "You can make adjustments to the region of interest by moving\n"
1257 "the pointer to one of the rectangle corners, pressing a\n"
1258 "button, and dragging. Finally, choose an image processing\n"
1259 "technique from the Command widget. You can choose more than\n"
1260 "one image processing technique to apply to an area.\n"
1261 "Alternatively, you can move the region of interest before\n"
1262 "applying another image processing technique. To exit, press\n"
1267 "In rotate mode, the Command widget has these options:\n"
1286 "Choose a background color from the Pixel Color sub-menu.\n"
1287 "Additional background colors can be specified with the color\n"
1288 "browser. You can change the menu colors by setting the X\n"
1289 "resources pen1 through pen9.\n"
1291 "If you choose the color browser and press Grab, you can\n"
1292 "select the background color by moving the pointer to the\n"
1293 "desired color on the screen and press any button.\n"
1295 "Choose a point in the image window and press this button and\n"
1296 "hold. Next, move the pointer to another location in the\n"
1297 "image. As you move a line connects the initial location and\n"
1298 "the pointer. When you release the button, the degree of\n"
1299 "image rotation is determined by the slope of the line you\n"
1300 "just drew. The slope is relative to the direction you\n"
1301 "choose from the Direction sub-menu of the Command widget.\n"
1303 "To cancel the image rotation, move the pointer back to the\n"
1304 "starting point of the line and release the button.\n"
1327 VisualDirectoryCommand,
1335 OriginalSizeCommand,
1357 ContrastStretchCommand,
1358 SigmoidalContrastCommand,
1384 CharcoalDrawCommand,
1394 RegionOfInterestCommand,
1400 ShowHistogramCommand,
1406 BrowseDocumentationCommand,
1408 SaveToUndoBufferCommand,
1415 AnnotateNameCommand,
1416 AnnotateFontColorCommand,
1417 AnnotateBackgroundColorCommand,
1418 AnnotateRotateCommand,
1419 AnnotateHelpCommand,
1420 AnnotateDismissCommand,
1423 ChopDirectionCommand,
1426 HorizontalChopCommand,
1427 VerticalChopCommand,
1428 ColorEditMethodCommand,
1429 ColorEditColorCommand,
1430 ColorEditBorderCommand,
1431 ColorEditFuzzCommand,
1432 ColorEditUndoCommand,
1433 ColorEditHelpCommand,
1434 ColorEditDismissCommand,
1435 CompositeOperatorsCommand,
1436 CompositeDissolveCommand,
1437 CompositeDisplaceCommand,
1438 CompositeHelpCommand,
1439 CompositeDismissCommand,
1444 RectifyDismissCommand,
1453 MatteEditBorderCommand,
1454 MatteEditFuzzCommand,
1455 MatteEditValueCommand,
1456 MatteEditUndoCommand,
1457 MatteEditHelpCommand,
1458 MatteEditDismissCommand,
1459 PasteOperatorsCommand,
1461 PasteDismissCommand,
1463 RotateDirectionCommand,
1465 RotateSharpenCommand,
1467 RotateDismissCommand,
1468 HorizontalRotateCommand,
1469 VerticalRotateCommand,
1480#define BricksWidth 20
1481#define BricksHeight 20
1482#define DiagonalWidth 16
1483#define DiagonalHeight 16
1484#define HighlightWidth 8
1485#define HighlightHeight 8
1486#define OpaqueWidth 8
1487#define OpaqueHeight 8
1488#define ScalesWidth 16
1489#define ScalesHeight 16
1490#define ShadowWidth 8
1491#define ShadowHeight 8
1492#define VerticalWidth 16
1493#define VerticalHeight 16
1495#define WavyHeight 16
1503static const unsigned char
1506 0xff, 0xff, 0x0f, 0x03, 0x0c, 0x00, 0x03, 0x0c, 0x00, 0x03, 0x0c, 0x00,
1507 0x03, 0x0c, 0x00, 0xff, 0xff, 0x0f, 0x60, 0x80, 0x01, 0x60, 0x80, 0x01,
1508 0x60, 0x80, 0x01, 0x60, 0x80, 0x01, 0xff, 0xff, 0x0f, 0x03, 0x0c, 0x00,
1509 0x03, 0x0c, 0x00, 0x03, 0x0c, 0x00, 0x03, 0x0c, 0x00, 0xff, 0xff, 0x0f,
1510 0x60, 0x80, 0x01, 0x60, 0x80, 0x01, 0x60, 0x80, 0x01, 0x60, 0x80, 0x01
1514 0x44, 0x44, 0x88, 0x88, 0x11, 0x11, 0x22, 0x22, 0x44, 0x44, 0x88, 0x88,
1515 0x11, 0x11, 0x22, 0x22, 0x44, 0x44, 0x88, 0x88, 0x11, 0x11, 0x22, 0x22,
1516 0x44, 0x44, 0x88, 0x88, 0x11, 0x11, 0x22, 0x22
1520 0x08, 0x08, 0x08, 0x08, 0x14, 0x14, 0xe3, 0xe3, 0x80, 0x80, 0x80, 0x80,
1521 0x41, 0x41, 0x3e, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x14, 0x14, 0xe3, 0xe3,
1522 0x80, 0x80, 0x80, 0x80, 0x41, 0x41, 0x3e, 0x3e
1526 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1527 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1528 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11
1532 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfb, 0xff,
1533 0xe7, 0xff, 0x1f, 0xff, 0xff, 0xf8, 0xff, 0xe7, 0xff, 0xdf, 0xff, 0xbf,
1534 0xff, 0xbf, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f
1540static DisplayCommand
1541 XImageWindowCommand(Display *,XResourceInfo *,XWindows *,
1542 const MagickStatusType,KeySym,Image **,ExceptionInfo *);
1545 *XMagickCommand(Display *,XResourceInfo *,XWindows *,
const DisplayCommand,
1546 Image **,ExceptionInfo *),
1547 *XOpenImage(Display *,XResourceInfo *,XWindows *,
const MagickBooleanType),
1548 *XTileImage(Display *,XResourceInfo *,XWindows *,Image *,XEvent *,
1550 *XVisualDirectoryImage(Display *,XResourceInfo *,XWindows *,
1553static MagickBooleanType
1554 XAnnotateEditImage(Display *,XResourceInfo *,XWindows *,Image *,
1556 XBackgroundImage(Display *,XResourceInfo *,XWindows *,Image **,
1558 XChopImage(Display *,XResourceInfo *,XWindows *,Image **,
1560 XCropImage(Display *,XResourceInfo *,XWindows *,Image *,
const ClipboardMode,
1562 XColorEditImage(Display *,XResourceInfo *,XWindows *,Image **,
1564 XCompositeImage(Display *,XResourceInfo *,XWindows *,Image *,
1566 XConfigureImage(Display *,XResourceInfo *,XWindows *,Image *,ExceptionInfo *),
1567 XDrawEditImage(Display *,XResourceInfo *,XWindows *,Image **,
1569 XMatteEditImage(Display *,XResourceInfo *,XWindows *,Image **,
1571 XPasteImage(Display *,XResourceInfo *,XWindows *,Image *,ExceptionInfo *),
1572 XPrintImage(Display *,XResourceInfo *,XWindows *,Image *,ExceptionInfo *),
1573 XRotateImage(Display *,XResourceInfo *,XWindows *,
double,Image **,
1575 XROIImage(Display *,XResourceInfo *,XWindows *,Image **,ExceptionInfo *),
1576 XSaveImage(Display *,XResourceInfo *,XWindows *,Image *,ExceptionInfo *),
1577 XTrimImage(Display *,XResourceInfo *,XWindows *,Image *,ExceptionInfo *);
1580 XDrawPanRectangle(Display *,XWindows *),
1581 XImageCache(Display *,XResourceInfo *,XWindows *,
const DisplayCommand,Image **,
1583 XMagnifyImage(Display *,XWindows *,XEvent *,ExceptionInfo *),
1584 XMakePanImage(Display *,XResourceInfo *,XWindows *,Image *,ExceptionInfo *),
1585 XPanImage(Display *,XWindows *,XEvent *,ExceptionInfo *),
1586 XMagnifyWindowCommand(Display *,XWindows *,
const MagickStatusType,
1587 const KeySym,ExceptionInfo *),
1588 XSetCropGeometry(Display *,XWindows *,RectangleInfo *,Image *),
1589 XScreenEvent(Display *,XWindows *,XEvent *,ExceptionInfo *),
1590 XTranslateImage(Display *,XWindows *,Image *,
const KeySym);
1621MagickExport MagickBooleanType DisplayImages(
const ImageInfo *image_info,
1622 Image *images,ExceptionInfo *exception)
1645 assert(image_info != (
const ImageInfo *) NULL);
1646 assert(image_info->signature == MagickCoreSignature);
1647 assert(images != (Image *) NULL);
1648 assert(images->signature == MagickCoreSignature);
1649 if (IsEventLogging() != MagickFalse)
1650 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",images->filename);
1651 display=XOpenDisplay(image_info->server_name);
1652 if (display == (Display *) NULL)
1654 (void) ThrowMagickException(exception,GetMagickModule(),XServerError,
1655 "UnableToOpenXServer",
"`%s'",XDisplayName(image_info->server_name));
1656 return(MagickFalse);
1658 if (exception->severity != UndefinedException)
1659 CatchException(exception);
1660 (void) XSetErrorHandler(XError);
1661 resource_database=XGetResourceDatabase(display,GetClientName());
1662 (void) memset(&resource_info,0,
sizeof(resource_info));
1663 XGetResourceInfo(image_info,resource_database,GetClientName(),&resource_info);
1664 if (image_info->page != (
char *) NULL)
1665 resource_info.image_geometry=AcquireString(image_info->page);
1666 resource_info.immutable=MagickTrue;
1667 argv[0]=AcquireString(GetClientName());
1669 for (i=0; (state & ExitState) == 0; i++)
1671 if ((images->iterations != 0) && (i >= (ssize_t) images->iterations))
1673 image=GetImageFromList(images,i % (ssize_t) GetImageListLength(images));
1674 (void) XDisplayImage(display,&resource_info,argv,1,&image,&state,exception);
1676 (void) SetErrorHandler((ErrorHandler) NULL);
1677 (void) SetWarningHandler((WarningHandler) NULL);
1678 argv[0]=DestroyString(argv[0]);
1679 (void) XCloseDisplay(display);
1680 XDestroyResourceInfo(&resource_info);
1681 if (exception->severity != UndefinedException)
1682 return(MagickFalse);
1716MagickExport MagickBooleanType RemoteDisplayCommand(
const ImageInfo *image_info,
1717 const char *window,
const char *filename,ExceptionInfo *exception)
1725 assert(image_info != (
const ImageInfo *) NULL);
1726 assert(image_info->signature == MagickCoreSignature);
1727 assert(filename != (
char *) NULL);
1728 if (IsEventLogging() != MagickFalse)
1729 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",filename);
1730 display=XOpenDisplay(image_info->server_name);
1731 if (display == (Display *) NULL)
1733 (void) ThrowMagickException(exception,GetMagickModule(),XServerError,
1734 "UnableToOpenXServer",
"`%s'",XDisplayName(image_info->server_name));
1735 return(MagickFalse);
1737 (void) XSetErrorHandler(XError);
1738 status=XRemoteCommand(display,window,filename);
1739 (void) XCloseDisplay(display);
1740 return(status != 0 ? MagickTrue : MagickFalse);
1775static MagickBooleanType XAnnotateEditImage(Display *display,
1776 XResourceInfo *resource_info,XWindows *windows,Image *image,
1777 ExceptionInfo *exception)
1780 *
const AnnotateMenu[] =
1797 static const ModeType
1798 AnnotateCommands[] =
1800 AnnotateNameCommand,
1801 AnnotateFontColorCommand,
1802 AnnotateBackgroundColorCommand,
1803 AnnotateRotateCommand,
1804 AnnotateHelpCommand,
1805 AnnotateDismissCommand
1813 static MagickBooleanType
1814 transparent_box = MagickTrue,
1815 transparent_pen = MagickFalse;
1821 box_id = MaxNumberPens-2,
1826 command[MagickPathExtent],
1828 text[MagickPathExtent];
1831 *ColorMenu[MaxNumberPens+1];
1876 (void) CloneString(&windows->command.name,
"Annotate");
1877 windows->command.data=4;
1878 (void) XCommandWidget(display,windows,AnnotateMenu,(XEvent *) NULL);
1879 (void) XMapRaised(display,windows->command.id);
1880 XClientMessage(display,windows->image.id,windows->im_protocols,
1881 windows->im_update_widget,CurrentTime);
1885 XQueryPosition(display,windows->image.id,&x,&y);
1886 (void) XSelectInput(display,windows->image.id,
1887 windows->image.attributes.event_mask | PointerMotionMask);
1888 cursor=XCreateFontCursor(display,XC_left_side);
1889 (void) XCheckDefineCursor(display,windows->image.id,cursor);
1893 if (windows->info.mapped != MagickFalse)
1898 (void) FormatLocaleString(text,MagickPathExtent,
" %+d%+d ",
1899 x+windows->image.x,y+windows->image.y);
1900 XInfoWidget(display,windows,text);
1905 XScreenEvent(display,windows,&event,exception);
1906 if (event.xany.window == windows->command.id)
1911 id=XCommandWidget(display,windows,AnnotateMenu,&event);
1912 (void) XCheckDefineCursor(display,windows->image.id,cursor);
1915 switch (AnnotateCommands[
id])
1917 case AnnotateNameCommand:
1920 *FontMenu[MaxNumberFonts];
1928 for (i=0; i < MaxNumberFonts; i++)
1929 FontMenu[i]=resource_info->font_name[i];
1930 FontMenu[MaxNumberFonts-2]=
"Browser...";
1931 FontMenu[MaxNumberFonts-1]=(
const char *) NULL;
1935 font_number=XMenuWidget(display,windows,AnnotateMenu[
id],
1936 (
const char **) FontMenu,command);
1937 if (font_number < 0)
1939 if (font_number == (MaxNumberFonts-2))
1942 font_name[MagickPathExtent] =
"fixed";
1947 resource_info->font_name[font_number]=font_name;
1948 XFontBrowserWidget(display,windows,
"Select",font_name);
1949 if (*font_name ==
'\0')
1955 font_info=XLoadQueryFont(display,resource_info->font_name[
1957 if (font_info == (XFontStruct *) NULL)
1959 XNoticeWidget(display,windows,
"Unable to load font:",
1960 resource_info->font_name[font_number]);
1963 font_id=(
unsigned int) font_number;
1964 (void) XFreeFont(display,font_info);
1967 case AnnotateFontColorCommand:
1972 for (i=0; i < (int) (MaxNumberPens-2); i++)
1973 ColorMenu[i]=resource_info->pen_colors[i];
1974 ColorMenu[MaxNumberPens-2]=
"transparent";
1975 ColorMenu[MaxNumberPens-1]=
"Browser...";
1976 ColorMenu[MaxNumberPens]=(
const char *) NULL;
1980 pen_number=XMenuWidget(display,windows,AnnotateMenu[
id],
1981 (
const char **) ColorMenu,command);
1984 transparent_pen=pen_number == (MaxNumberPens-2) ? MagickTrue :
1986 if (transparent_pen != MagickFalse)
1988 if (pen_number == (MaxNumberPens-1))
1991 color_name[MagickPathExtent] =
"gray";
1996 resource_info->pen_colors[pen_number]=color_name;
1997 XColorBrowserWidget(display,windows,
"Select",color_name);
1998 if (*color_name ==
'\0')
2004 (void) XParseColor(display,windows->map_info->colormap,
2005 resource_info->pen_colors[pen_number],&color);
2006 XBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
2007 (
unsigned int) MaxColors,&color);
2008 windows->pixel_info->pen_colors[pen_number]=color;
2009 pen_id=(
unsigned int) pen_number;
2012 case AnnotateBackgroundColorCommand:
2017 for (i=0; i < (int) (MaxNumberPens-2); i++)
2018 ColorMenu[i]=resource_info->pen_colors[i];
2019 ColorMenu[MaxNumberPens-2]=
"transparent";
2020 ColorMenu[MaxNumberPens-1]=
"Browser...";
2021 ColorMenu[MaxNumberPens]=(
const char *) NULL;
2025 pen_number=XMenuWidget(display,windows,AnnotateMenu[
id],
2026 (
const char **) ColorMenu,command);
2029 transparent_box=pen_number == (MaxNumberPens-2) ? MagickTrue :
2031 if (transparent_box != MagickFalse)
2033 if (pen_number == (MaxNumberPens-1))
2036 color_name[MagickPathExtent] =
"gray";
2041 resource_info->pen_colors[pen_number]=color_name;
2042 XColorBrowserWidget(display,windows,
"Select",color_name);
2043 if (*color_name ==
'\0')
2049 (void) XParseColor(display,windows->map_info->colormap,
2050 resource_info->pen_colors[pen_number],&color);
2051 XBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
2052 (
unsigned int) MaxColors,&color);
2053 windows->pixel_info->pen_colors[pen_number]=color;
2054 box_id=(
unsigned int) pen_number;
2057 case AnnotateRotateCommand:
2063 *
const RotateMenu[] =
2078 angle[MagickPathExtent] =
"30.0";
2083 entry=XMenuWidget(display,windows,AnnotateMenu[
id],RotateMenu,
2089 degrees=StringToDouble(RotateMenu[entry],(
char **) NULL);
2092 (void) XDialogWidget(display,windows,
"OK",
"Enter rotation angle:",
2096 degrees=StringToDouble(angle,(
char **) NULL);
2099 case AnnotateHelpCommand:
2101 XTextViewHelp(display,resource_info,windows,MagickFalse,
2102 "Help Viewer - Image Annotation",ImageAnnotateHelp);
2105 case AnnotateDismissCommand:
2123 if (event.xbutton.button != Button1)
2125 if (event.xbutton.window != windows->image.id)
2141 if (event.xkey.window != windows->image.id)
2146 (void) XLookupString((XKeyEvent *) &event.xkey,command,(
int)
2147 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
2148 switch ((
int) key_symbol)
2163 XTextViewHelp(display,resource_info,windows,MagickFalse,
2164 "Help Viewer - Image Annotation",ImageAnnotateHelp);
2169 (void) XBell(display,0);
2182 if (windows->info.mapped != MagickFalse)
2184 if ((x < (windows->info.x+(
int) windows->info.width)) &&
2185 (y < (windows->info.y+(
int) windows->info.height)))
2186 (void) XWithdrawWindow(display,windows->info.id,
2187 windows->info.screen);
2190 if ((x > (windows->info.x+(
int) windows->info.width)) ||
2191 (y > (windows->info.y+(
int) windows->info.height)))
2192 (void) XMapWindow(display,windows->info.id);
2198 }
while ((state & ExitState) == 0);
2199 (void) XSelectInput(display,windows->image.id,
2200 windows->image.attributes.event_mask);
2201 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
2202 if ((state & EscapeState) != 0)
2207 font_info=XLoadQueryFont(display,resource_info->font_name[font_id]);
2208 if (font_info == (XFontStruct *) NULL)
2210 XNoticeWidget(display,windows,
"Unable to load font:",
2211 resource_info->font_name[font_id]);
2212 font_info=windows->font_info;
2214 if ((x+font_info->max_bounds.width) >= (
int) windows->image.width)
2215 x=(int) windows->image.width-font_info->max_bounds.width;
2216 if (y < (
int) (font_info->ascent+font_info->descent))
2217 y=(int) font_info->ascent+font_info->descent;
2218 if (((
int) font_info->max_bounds.width > (
int) windows->image.width) ||
2219 ((font_info->ascent+font_info->descent) >= (
int) windows->image.height))
2220 return(MagickFalse);
2224 annotate_info=(XAnnotateInfo *) AcquireMagickMemory(
sizeof(*annotate_info));
2225 if (annotate_info == (XAnnotateInfo *) NULL)
2226 return(MagickFalse);
2227 XGetAnnotateInfo(annotate_info);
2230 if ((transparent_box == MagickFalse) && (transparent_pen == MagickFalse))
2231 annotate_info->stencil=OpaqueStencil;
2233 if (transparent_box == MagickFalse)
2234 annotate_info->stencil=BackgroundStencil;
2236 annotate_info->stencil=ForegroundStencil;
2237 annotate_info->height=(
unsigned int) (font_info->ascent+font_info->descent);
2238 annotate_info->degrees=degrees;
2239 annotate_info->font_info=font_info;
2240 annotate_info->text=(
char *) AcquireQuantumMemory((
size_t)
2241 windows->image.width/(
size_t) MagickMax(font_info->min_bounds.width,1)+2UL,
2242 sizeof(*annotate_info->text));
2243 if (annotate_info->text == (
char *) NULL)
2244 return(MagickFalse);
2248 cursor=XCreateFontCursor(display,XC_pencil);
2249 (void) XCheckDefineCursor(display,windows->image.id,cursor);
2250 annotate_context=windows->image.annotate_context;
2251 (void) XSetFont(display,annotate_context,font_info->fid);
2252 (void) XSetBackground(display,annotate_context,
2253 windows->pixel_info->pen_colors[box_id].pixel);
2254 (void) XSetForeground(display,annotate_context,
2255 windows->pixel_info->pen_colors[pen_id].pixel);
2259 (void) CloneString(&windows->command.name,
"Text");
2260 windows->command.data=0;
2261 (void) XCommandWidget(display,windows,TextMenu,(XEvent *) NULL);
2263 (void) XDrawString(display,windows->image.id,annotate_context,x,y,
"_",1);
2264 text_event.xexpose.width=(int) font_info->max_bounds.width;
2265 text_event.xexpose.height=font_info->max_bounds.ascent+
2266 font_info->max_bounds.descent;
2267 p=annotate_info->text;
2274 (void) XDrawString(display,windows->image.id,annotate_context,x,y,
"_",1);
2278 XScreenEvent(display,windows,&event,exception);
2279 if (event.xany.window == windows->command.id)
2284 (void) XSetBackground(display,annotate_context,
2285 windows->pixel_info->background_color.pixel);
2286 (void) XSetForeground(display,annotate_context,
2287 windows->pixel_info->foreground_color.pixel);
2288 id=XCommandWidget(display,windows,AnnotateMenu,&event);
2289 (void) XSetBackground(display,annotate_context,
2290 windows->pixel_info->pen_colors[box_id].pixel);
2291 (void) XSetForeground(display,annotate_context,
2292 windows->pixel_info->pen_colors[pen_id].pixel);
2295 switch (TextCommands[
id])
2297 case TextHelpCommand:
2299 XTextViewHelp(display,resource_info,windows,MagickFalse,
2300 "Help Viewer - Image Annotation",ImageAnnotateHelp);
2301 (void) XCheckDefineCursor(display,windows->image.id,cursor);
2304 case TextApplyCommand:
2309 annotate_info->width=(
unsigned int) XTextWidth(font_info,
2310 annotate_info->text,(
int) strlen(annotate_info->text));
2311 XRefreshWindow(display,&windows->image,&text_event);
2323 text_event.xexpose.x=x;
2324 text_event.xexpose.y=y-font_info->max_bounds.ascent;
2325 (void) XClearArea(display,windows->image.id,x,text_event.xexpose.y,
2326 (
unsigned int) text_event.xexpose.width,(
unsigned int)
2327 text_event.xexpose.height,MagickFalse);
2328 XRefreshWindow(display,&windows->image,&text_event);
2333 if (event.xbutton.window != windows->image.id)
2335 if (event.xbutton.button == Button2)
2340 (void) XConvertSelection(display,XA_PRIMARY,XA_STRING,XA_STRING,
2341 windows->image.id,CurrentTime);
2348 if (event.xexpose.count == 0)
2356 XRefreshWindow(display,&windows->image,(XEvent *) NULL);
2357 text_info=annotate_info;
2358 while (text_info != (XAnnotateInfo *) NULL)
2360 if (annotate_info->stencil == ForegroundStencil)
2361 (void) XDrawString(display,windows->image.id,annotate_context,
2362 text_info->x,text_info->y,text_info->text,
2363 (
int) strlen(text_info->text));
2365 (
void) XDrawImageString(display,windows->image.id,
2366 annotate_context,text_info->x,text_info->y,text_info->text,
2367 (
int) strlen(text_info->text));
2368 text_info=text_info->previous;
2370 (void) XDrawString(display,windows->image.id,annotate_context,
2380 if (event.xkey.window != windows->image.id)
2385 length=XLookupString((XKeyEvent *) &event.xkey,command,(
int)
2386 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
2387 *(command+length)=
'\0';
2388 if (((event.xkey.state & ControlMask) != 0) ||
2389 ((event.xkey.state & Mod1Mask) != 0))
2390 state|=ModifierState;
2391 if ((state & ModifierState) != 0)
2392 switch ((
int) key_symbol)
2397 key_symbol=DeleteCommand;
2403 switch ((
int) key_symbol)
2410 if (p == annotate_info->text)
2412 if (annotate_info->previous == (XAnnotateInfo *) NULL)
2419 annotate_info=annotate_info->previous;
2420 p=annotate_info->text;
2421 x=annotate_info->x+(int) annotate_info->width;
2423 if (annotate_info->width != 0)
2424 p+=(ptrdiff_t) strlen(annotate_info->text);
2429 x-=XTextWidth(font_info,p,1);
2430 text_event.xexpose.x=x;
2431 text_event.xexpose.y=y-font_info->max_bounds.ascent;
2432 XRefreshWindow(display,&windows->image,&text_event);
2435 case XK_bracketleft:
2437 key_symbol=XK_Escape;
2445 while (p != annotate_info->text)
2448 x-=XTextWidth(font_info,p,1);
2449 text_event.xexpose.x=x;
2450 XRefreshWindow(display,&windows->image,&text_event);
2460 annotate_info->width=(
unsigned int) XTextWidth(font_info,
2461 annotate_info->text,(
int) strlen(annotate_info->text));
2462 XRefreshWindow(display,&windows->image,&text_event);
2471 if ((state & ModifierState) != 0)
2473 if (*command ==
'\0')
2476 if (annotate_info->stencil == ForegroundStencil)
2477 (void) XDrawString(display,windows->image.id,annotate_context,
2480 (
void) XDrawImageString(display,windows->image.id,
2481 annotate_context,x,y,p,1);
2482 x+=XTextWidth(font_info,p,1);
2484 if ((x+font_info->max_bounds.width) < (
int) windows->image.width)
2495 annotate_info->width=(
unsigned int) XTextWidth(font_info,
2496 annotate_info->text,(
int) strlen(annotate_info->text));
2497 if (annotate_info->next != (XAnnotateInfo *) NULL)
2502 annotate_info=annotate_info->next;
2505 p=annotate_info->text;
2508 annotate_info->next=(XAnnotateInfo *) AcquireQuantumMemory(1,
2509 sizeof(*annotate_info->next));
2510 if (annotate_info->next == (XAnnotateInfo *) NULL)
2511 return(MagickFalse);
2512 *annotate_info->next=(*annotate_info);
2513 annotate_info->next->previous=annotate_info;
2514 annotate_info=annotate_info->next;
2515 annotate_info->text=(
char *) AcquireQuantumMemory((
size_t) (
2516 (ssize_t) windows->image.width/MagickMax((ssize_t)
2517 font_info->min_bounds.width,1)+2L),
sizeof(*annotate_info->text));
2518 if (annotate_info->text == (
char *) NULL)
2519 return(MagickFalse);
2520 annotate_info->y+=(ssize_t) annotate_info->height;
2521 if (annotate_info->y > (
int) windows->image.height)
2522 annotate_info->y=(int) annotate_info->height;
2523 annotate_info->next=(XAnnotateInfo *) NULL;
2526 p=annotate_info->text;
2537 (void) XLookupString((XKeyEvent *) &event.xkey,command,(
int)
2538 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
2539 state&=(size_t) (~ModifierState);
2542 case SelectionNotify:
2560 if (event.xselection.property == (Atom) None)
2562 status=XGetWindowProperty(display,event.xselection.requestor,
2563 event.xselection.property,0L,(
long) MagickPathExtent,True,XA_STRING,
2564 &type,&format,&length,&after,&data);
2565 if ((status != Success) || (type != XA_STRING) || (format == 32) ||
2571 for (i=0; i < (ssize_t) length; i++)
2573 if ((
char) data[i] !=
'\n')
2579 (void) XDrawString(display,windows->image.id,annotate_context,
2581 x+=XTextWidth(font_info,p,1);
2583 if ((x+font_info->max_bounds.width) < (
int) windows->image.width)
2590 annotate_info->width=(
unsigned int) XTextWidth(font_info,
2591 annotate_info->text,(
int) strlen(annotate_info->text));
2592 if (annotate_info->next != (XAnnotateInfo *) NULL)
2597 annotate_info=annotate_info->next;
2600 p=annotate_info->text;
2603 annotate_info->next=(XAnnotateInfo *) AcquireQuantumMemory(1,
2604 sizeof(*annotate_info->next));
2605 if (annotate_info->next == (XAnnotateInfo *) NULL)
2606 return(MagickFalse);
2607 *annotate_info->next=(*annotate_info);
2608 annotate_info->next->previous=annotate_info;
2609 annotate_info=annotate_info->next;
2610 annotate_info->text=(
char *) AcquireQuantumMemory((
size_t)
2611 (windows->image.width/MagickMax((ssize_t)
2612 font_info->min_bounds.width,1)+2L),
sizeof(*annotate_info->text));
2613 if (annotate_info->text == (
char *) NULL)
2614 return(MagickFalse);
2615 annotate_info->y+=(ssize_t) annotate_info->height;
2616 if (annotate_info->y > (
int) windows->image.height)
2617 annotate_info->y=(int) annotate_info->height;
2618 annotate_info->next=(XAnnotateInfo *) NULL;
2621 p=annotate_info->text;
2623 (void) XFree((
void *) data);
2629 }
while ((state & ExitState) == 0);
2630 (void) XFreeCursor(display,cursor);
2634 width=(
unsigned int) image->columns;
2635 height=(
unsigned int) image->rows;
2638 if (windows->image.crop_geometry != (
char *) NULL)
2639 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
2643 XSetCursorState(display,windows,MagickTrue);
2644 XCheckRefreshWindows(display,windows);
2645 while (annotate_info != (XAnnotateInfo *) NULL)
2647 if (annotate_info->width == 0)
2652 previous_info=annotate_info->previous;
2653 annotate_info->text=(
char *)
2654 RelinquishMagickMemory(annotate_info->text);
2655 annotate_info=(XAnnotateInfo *) RelinquishMagickMemory(annotate_info);
2656 annotate_info=previous_info;
2662 windows->pixel_info->box_color=windows->pixel_info->pen_colors[box_id];
2663 if (windows->pixel_info->colors != 0)
2664 for (i=0; i < (ssize_t) windows->pixel_info->colors; i++)
2665 if (windows->pixel_info->pixels[i] ==
2666 windows->pixel_info->pen_colors[box_id].pixel)
2668 windows->pixel_info->box_index=(
unsigned short) i;
2671 windows->pixel_info->pen_color=windows->pixel_info->pen_colors[pen_id];
2672 if (windows->pixel_info->colors != 0)
2673 for (i=0; i < (ssize_t) windows->pixel_info->colors; i++)
2674 if (windows->pixel_info->pixels[i] ==
2675 windows->pixel_info->pen_colors[pen_id].pixel)
2677 windows->pixel_info->pen_index=(
unsigned short) i;
2683 annotate_info->x=(int)
2684 width*(annotate_info->x+windows->image.x)/windows->image.ximage->width;
2685 annotate_info->y=(int) height*(annotate_info->y-font_info->ascent+
2686 windows->image.y)/windows->image.ximage->height;
2687 (void) FormatLocaleString(annotate_info->geometry,MagickPathExtent,
2688 "%gx%g%+g%+g",(
double) width*annotate_info->width/
2689 windows->image.ximage->width,(
double) height*annotate_info->height/
2690 windows->image.ximage->height,(
double) annotate_info->x+x,(
double)
2691 annotate_info->y+y);
2695 status=XAnnotateImage(display,windows->pixel_info,annotate_info,image,
2696 exception) == MagickFalse ? 0 : 1;
2698 return(MagickFalse);
2702 previous_info=annotate_info->previous;
2703 annotate_info->text=DestroyString(annotate_info->text);
2704 annotate_info=(XAnnotateInfo *) RelinquishMagickMemory(annotate_info);
2705 annotate_info=previous_info;
2707 (void) XSetForeground(display,annotate_context,
2708 windows->pixel_info->foreground_color.pixel);
2709 (void) XSetBackground(display,annotate_context,
2710 windows->pixel_info->background_color.pixel);
2711 (void) XSetFont(display,annotate_context,windows->font_info->fid);
2712 XSetCursorState(display,windows,MagickFalse);
2713 (void) XFreeFont(display,font_info);
2717 XConfigureImageColormap(display,resource_info,windows,image,exception);
2718 (void) XConfigureImage(display,resource_info,windows,image,exception);
2755static MagickBooleanType XBackgroundImage(Display *display,
2756 XResourceInfo *resource_info,XWindows *windows,Image **image,
2757 ExceptionInfo *exception)
2759#define BackgroundImageTag "Background/Image"
2765 window_id[MagickPathExtent] =
"root";
2768 background_resources;
2773 status=XDialogWidget(display,windows,
"Background",
2774 "Enter window id (id 0x00 selects window with pointer):",window_id);
2775 if (*window_id ==
'\0')
2776 return(MagickFalse);
2777 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
2779 XInfoWidget(display,windows,BackgroundImageTag);
2780 XSetCursorState(display,windows,MagickTrue);
2781 XCheckRefreshWindows(display,windows);
2782 background_resources=(*resource_info);
2783 background_resources.window_id=window_id;
2784 background_resources.backdrop=status != 0 ? MagickTrue : MagickFalse;
2785 status=XDisplayBackgroundImage(display,&background_resources,*image,
2786 exception) == MagickFalse ? 0 : 1;
2787 if (status != MagickFalse)
2788 XClientMessage(display,windows->image.id,windows->im_protocols,
2789 windows->im_retain_colors,CurrentTime);
2790 XSetCursorState(display,windows,MagickFalse);
2791 (void) XMagickCommand(display,resource_info,windows,UndoCommand,image,
2828static MagickBooleanType XChopImage(Display *display,
2829 XResourceInfo *resource_info,XWindows *windows,Image **image,
2830 ExceptionInfo *exception)
2842 direction = HorizontalChopCommand;
2844 static const ModeType
2847 ChopDirectionCommand,
2851 DirectionCommands[] =
2853 HorizontalChopCommand,
2858 text[MagickPathExtent];
2891 (void) CloneString(&windows->command.name,
"Chop");
2892 windows->command.data=1;
2893 (void) XCommandWidget(display,windows,ChopMenu,(XEvent *) NULL);
2894 (void) XMapRaised(display,windows->command.id);
2895 XClientMessage(display,windows->image.id,windows->im_protocols,
2896 windows->im_update_widget,CurrentTime);
2900 XQueryPosition(display,windows->image.id,&x,&y);
2901 (void) XSelectInput(display,windows->image.id,
2902 windows->image.attributes.event_mask | PointerMotionMask);
2904 (void) memset(&segment_info,0,
sizeof(segment_info));
2907 if (windows->info.mapped != MagickFalse)
2912 (void) FormatLocaleString(text,MagickPathExtent,
" %+d%+d ",
2913 x+windows->image.x,y+windows->image.y);
2914 XInfoWidget(display,windows,text);
2919 XScreenEvent(display,windows,&event,exception);
2920 if (event.xany.window == windows->command.id)
2925 id=XCommandWidget(display,windows,ChopMenu,&event);
2928 switch (ChopCommands[
id])
2930 case ChopDirectionCommand:
2933 command[MagickPathExtent];
2936 *
const Directions[] =
2946 id=XMenuWidget(display,windows,ChopMenu[
id],Directions,command);
2948 direction=DirectionCommands[id];
2951 case ChopHelpCommand:
2953 XTextViewHelp(display,resource_info,windows,MagickFalse,
2954 "Help Viewer - Image Chop",ImageChopHelp);
2957 case ChopDismissCommand:
2975 if (event.xbutton.button != Button1)
2977 if (event.xbutton.window != windows->image.id)
2982 segment_info.x1=(
short int) event.xbutton.x;
2983 segment_info.x2=(
short int) event.xbutton.x;
2984 segment_info.y1=(
short int) event.xbutton.y;
2985 segment_info.y2=(
short int) event.xbutton.y;
2996 command[MagickPathExtent];
3001 if (event.xkey.window != windows->image.id)
3006 (void) XLookupString((XKeyEvent *) &event.xkey,command,(
int)
3007 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
3008 switch ((
int) key_symbol)
3023 (void) XSetFunction(display,windows->image.highlight_context,
3025 XTextViewHelp(display,resource_info,windows,MagickFalse,
3026 "Help Viewer - Image Chop",ImageChopHelp);
3027 (void) XSetFunction(display,windows->image.highlight_context,
3033 (void) XBell(display,0);
3046 if (windows->info.mapped != MagickFalse)
3048 if ((x < (windows->info.x+(
int) windows->info.width)) &&
3049 (y < (windows->info.y+(
int) windows->info.height)))
3050 (void) XWithdrawWindow(display,windows->info.id,
3051 windows->info.screen);
3054 if ((x > (windows->info.x+(
int) windows->info.width)) ||
3055 (y > (windows->info.y+(
int) windows->info.height)))
3056 (void) XMapWindow(display,windows->info.id);
3059 }
while ((state & ExitState) == 0);
3060 (void) XSelectInput(display,windows->image.id,
3061 windows->image.attributes.event_mask);
3062 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
3063 if ((state & EscapeState) != 0)
3073 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
3082 if (windows->info.mapped == MagickFalse)
3083 (void) XMapWindow(display,windows->info.id);
3084 (void) FormatLocaleString(text,MagickPathExtent,
3085 " %.20gx%.20g%+.20g%+.20g",(
double) chop_info.width,(
double)
3086 chop_info.height,(
double) chop_info.x,(
double) chop_info.y);
3087 XInfoWidget(display,windows,text);
3088 XHighlightLine(display,windows->image.id,
3089 windows->image.highlight_context,&segment_info);
3092 if (windows->info.mapped != MagickFalse)
3093 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
3097 XScreenEvent(display,windows,&event,exception);
3099 XHighlightLine(display,windows->image.id,
3100 windows->image.highlight_context,&segment_info);
3105 segment_info.x2=(
short int) event.xmotion.x;
3106 segment_info.y2=(
short int) event.xmotion.y;
3114 segment_info.x2=(
short int) event.xbutton.x;
3115 segment_info.y2=(
short int) event.xbutton.y;
3123 segment_info.x2=(
short int) event.xmotion.x;
3124 segment_info.y2=(
short int) event.xmotion.y;
3132 if (segment_info.x2 < 0)
3135 if (segment_info.x2 > windows->image.ximage->width)
3136 segment_info.x2=windows->image.ximage->width;
3137 if (segment_info.y2 < 0)
3140 if (segment_info.y2 > windows->image.ximage->height)
3141 segment_info.y2=windows->image.ximage->height;
3142 distance=(
unsigned int)
3143 (((segment_info.x2-segment_info.x1)*(segment_info.x2-segment_info.x1))+
3144 ((segment_info.y2-segment_info.y1)*(segment_info.y2-segment_info.y1)));
3148 if (direction == HorizontalChopCommand)
3150 chop_info.width=(size_t) (segment_info.x2-segment_info.x1+1);
3152 chop_info.x=(ssize_t) windows->image.x+segment_info.x1;
3154 if (segment_info.x1 > segment_info.x2)
3156 chop_info.width=(size_t) (segment_info.x1-segment_info.x2+1);
3157 chop_info.x=(ssize_t) windows->image.x+segment_info.x2;
3163 chop_info.height=(size_t) (segment_info.y2-segment_info.y1+1);
3165 chop_info.y=(ssize_t) windows->image.y+segment_info.y1;
3166 if (segment_info.y1 > segment_info.y2)
3168 chop_info.height=(size_t) (segment_info.y1-segment_info.y2+1);
3169 chop_info.y=(ssize_t) windows->image.y+segment_info.y2;
3172 }
while ((state & ExitState) == 0);
3173 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
3174 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
3180 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
3182 XSetCursorState(display,windows,MagickTrue);
3183 XCheckRefreshWindows(display,windows);
3184 windows->image.window_changes.width=windows->image.ximage->width-
3185 (int) chop_info.width;
3186 windows->image.window_changes.height=windows->image.ximage->height-
3187 (int) chop_info.height;
3188 width=(
unsigned int) (*image)->columns;
3189 height=(
unsigned int) (*image)->rows;
3192 if (windows->image.crop_geometry != (
char *) NULL)
3193 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
3194 scale_factor=(double) width/windows->image.ximage->width;
3196 chop_info.x=(ssize_t) (scale_factor*chop_info.x+0.5);
3197 chop_info.width=(
unsigned int) (scale_factor*chop_info.width+0.5);
3198 scale_factor=(double) height/windows->image.ximage->height;
3200 chop_info.y=(ssize_t) (scale_factor*chop_info.y+0.5);
3201 chop_info.height=(
unsigned int) (scale_factor*chop_info.height+0.5);
3205 chop_image=ChopImage(*image,&chop_info,exception);
3206 XSetCursorState(display,windows,MagickFalse);
3207 if (chop_image == (Image *) NULL)
3208 return(MagickFalse);
3209 *image=DestroyImage(*image);
3214 XConfigureImageColormap(display,resource_info,windows,*image,exception);
3215 (void) XConfigureImage(display,resource_info,windows,*image,exception);
3253static MagickBooleanType XColorEditImage(Display *display,
3254 XResourceInfo *resource_info,XWindows *windows,Image **image,
3255 ExceptionInfo *exception)
3258 *
const ColorEditMenu[] =
3270 static const ModeType
3271 ColorEditCommands[] =
3273 ColorEditMethodCommand,
3274 ColorEditColorCommand,
3275 ColorEditBorderCommand,
3276 ColorEditFuzzCommand,
3277 ColorEditUndoCommand,
3278 ColorEditHelpCommand,
3279 ColorEditDismissCommand
3283 method = PointMethod;
3289 border_color = { 0, 0, 0, 0, 0, 0 };
3292 command[MagickPathExtent],
3293 text[MagickPathExtent];
3328 (void) CloneString(&windows->command.name,
"Color Edit");
3329 windows->command.data=4;
3330 (void) XCommandWidget(display,windows,ColorEditMenu,(XEvent *) NULL);
3331 (void) XMapRaised(display,windows->command.id);
3332 XClientMessage(display,windows->image.id,windows->im_protocols,
3333 windows->im_update_widget,CurrentTime);
3337 cursor=XMakeCursor(display,windows->image.id,windows->map_info->colormap,
3338 resource_info->background_color,resource_info->foreground_color);
3339 (void) XCheckDefineCursor(display,windows->image.id,cursor);
3343 XQueryPosition(display,windows->image.id,&x,&y);
3344 (void) XSelectInput(display,windows->image.id,
3345 windows->image.attributes.event_mask | PointerMotionMask);
3349 if (windows->info.mapped != MagickFalse)
3354 (void) FormatLocaleString(text,MagickPathExtent,
" %+d%+d ",
3355 x+windows->image.x,y+windows->image.y);
3356 XInfoWidget(display,windows,text);
3361 XScreenEvent(display,windows,&event,exception);
3362 if (event.xany.window == windows->command.id)
3367 id=XCommandWidget(display,windows,ColorEditMenu,&event);
3370 (void) XCheckDefineCursor(display,windows->image.id,cursor);
3373 switch (ColorEditCommands[
id])
3375 case ColorEditMethodCommand:
3383 methods=(
char **) GetCommandOptions(MagickMethodOptions);
3384 if (methods == (
char **) NULL)
3386 entry=XMenuWidget(display,windows,ColorEditMenu[
id],
3387 (
const char **) methods,command);
3389 method=(PaintMethod) ParseCommandOption(MagickMethodOptions,
3390 MagickFalse,methods[entry]);
3391 methods=DestroyStringList(methods);
3394 case ColorEditColorCommand:
3397 *ColorMenu[MaxNumberPens];
3405 for (i=0; i < (int) (MaxNumberPens-2); i++)
3406 ColorMenu[i]=resource_info->pen_colors[i];
3407 ColorMenu[MaxNumberPens-2]=
"Browser...";
3408 ColorMenu[MaxNumberPens-1]=(
const char *) NULL;
3412 pen_number=XMenuWidget(display,windows,ColorEditMenu[
id],
3413 (
const char **) ColorMenu,command);
3416 if (pen_number == (MaxNumberPens-2))
3419 color_name[MagickPathExtent] =
"gray";
3424 resource_info->pen_colors[pen_number]=color_name;
3425 XColorBrowserWidget(display,windows,
"Select",color_name);
3426 if (*color_name ==
'\0')
3432 (void) XParseColor(display,windows->map_info->colormap,
3433 resource_info->pen_colors[pen_number],&color);
3434 XBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
3435 (
unsigned int) MaxColors,&color);
3436 windows->pixel_info->pen_colors[pen_number]=color;
3437 pen_id=(
unsigned int) pen_number;
3440 case ColorEditBorderCommand:
3443 *ColorMenu[MaxNumberPens];
3451 for (i=0; i < (int) (MaxNumberPens-2); i++)
3452 ColorMenu[i]=resource_info->pen_colors[i];
3453 ColorMenu[MaxNumberPens-2]=
"Browser...";
3454 ColorMenu[MaxNumberPens-1]=(
const char *) NULL;
3458 pen_number=XMenuWidget(display,windows,ColorEditMenu[
id],
3459 (
const char **) ColorMenu,command);
3462 if (pen_number == (MaxNumberPens-2))
3465 color_name[MagickPathExtent] =
"gray";
3470 resource_info->pen_colors[pen_number]=color_name;
3471 XColorBrowserWidget(display,windows,
"Select",color_name);
3472 if (*color_name ==
'\0')
3478 (void) XParseColor(display,windows->map_info->colormap,
3479 resource_info->pen_colors[pen_number],&border_color);
3482 case ColorEditFuzzCommand:
3497 fuzz[MagickPathExtent];
3502 entry=XMenuWidget(display,windows,ColorEditMenu[
id],FuzzMenu,
3508 (*image)->fuzz=StringToDoubleInterval(FuzzMenu[entry],(
double)
3512 (void) (
void) CopyMagickString(fuzz,
"20%",MagickPathExtent);
3513 (void) XDialogWidget(display,windows,
"Ok",
3514 "Enter fuzz factor (0.0 - 99.9%):",fuzz);
3517 (void) ConcatenateMagickString(fuzz,
"%",MagickPathExtent);
3518 (*image)->fuzz=StringToDoubleInterval(fuzz,(
double) QuantumRange+
3522 case ColorEditUndoCommand:
3524 (void) XMagickCommand(display,resource_info,windows,UndoCommand,
3528 case ColorEditHelpCommand:
3531 XTextViewHelp(display,resource_info,windows,MagickFalse,
3532 "Help Viewer - Image Annotation",ImageColorEditHelp);
3535 case ColorEditDismissCommand:
3545 (void) XCheckDefineCursor(display,windows->image.id,cursor);
3552 if (event.xbutton.button != Button1)
3554 if ((event.xbutton.window != windows->image.id) &&
3555 (event.xbutton.window != windows->magnify.id))
3562 (void) XMagickCommand(display,resource_info,windows,
3563 SaveToUndoBufferCommand,image,exception);
3564 state|=UpdateConfigurationState;
3569 if (event.xbutton.button != Button1)
3571 if ((event.xbutton.window != windows->image.id) &&
3572 (event.xbutton.window != windows->magnify.id))
3579 XConfigureImageColormap(display,resource_info,windows,*image,exception);
3580 (void) XConfigureImage(display,resource_info,windows,*image,exception);
3581 XInfoWidget(display,windows,text);
3582 (void) XCheckDefineCursor(display,windows->image.id,cursor);
3583 state&=(size_t) (~UpdateConfigurationState);
3593 if (event.xkey.window == windows->magnify.id)
3598 window=windows->magnify.id;
3599 while (XCheckWindowEvent(display,window,KeyPressMask,&event)) ;
3601 if (event.xkey.window != windows->image.id)
3606 (void) XLookupString((XKeyEvent *) &event.xkey,command,(
int)
3607 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
3608 switch ((
int) key_symbol)
3622 XTextViewHelp(display,resource_info,windows,MagickFalse,
3623 "Help Viewer - Image Annotation",ImageColorEditHelp);
3628 (void) XBell(display,0);
3641 if (windows->info.mapped != MagickFalse)
3643 if ((x < (windows->info.x+(
int) windows->info.width)) &&
3644 (y < (windows->info.y+(
int) windows->info.height)))
3645 (void) XWithdrawWindow(display,windows->info.id,
3646 windows->info.screen);
3649 if ((x > (windows->info.x+(
int) windows->info.width)) ||
3650 (y > (windows->info.y+(
int) windows->info.height)))
3651 (void) XMapWindow(display,windows->info.id);
3657 if (event.xany.window == windows->magnify.id)
3659 x=windows->magnify.x-windows->image.x;
3660 y=windows->magnify.y-windows->image.y;
3664 if ((state & UpdateConfigurationState) != 0)
3676 (void) XClearArea(display,windows->image.id,x_offset,y_offset,1,1,
3678 color=windows->pixel_info->pen_colors[pen_id];
3679 XPutPixel(windows->image.ximage,x_offset,y_offset,color.pixel);
3680 width=(
unsigned int) (*image)->columns;
3681 height=(
unsigned int) (*image)->rows;
3684 if (windows->image.crop_geometry != (
char *) NULL)
3685 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
3687 x_offset=((int) width*(windows->image.x+x_offset)/(int)
3688 windows->image.ximage->width+x);
3689 y_offset=((int) height*(windows->image.y+y_offset)/(int)
3690 windows->image.ximage->height+y);
3691 if ((x_offset < 0) || (y_offset < 0))
3693 if ((x_offset >= (
int) (*image)->columns) ||
3694 (y_offset >= (
int) (*image)->rows))
3696 image_view=AcquireAuthenticCacheView(*image,exception);
3705 if (SetImageStorageClass(*image,DirectClass,exception) == MagickFalse)
3706 return(MagickFalse);
3707 q=GetCacheViewAuthenticPixels(image_view,(ssize_t)x_offset,
3708 (ssize_t) y_offset,1,1,exception);
3709 if (q == (Quantum *) NULL)
3711 SetPixelRed(*image,ScaleShortToQuantum(color.red),q);
3712 SetPixelGreen(*image,ScaleShortToQuantum(color.green),q);
3713 SetPixelBlue(*image,ScaleShortToQuantum(color.blue),q);
3714 (void) SyncCacheViewAuthenticPixels(image_view,exception);
3726 (void) GetOneCacheViewVirtualPixelInfo(image_view,(ssize_t)
3727 x_offset,(ssize_t) y_offset,&target,exception);
3728 if ((*image)->storage_class == DirectClass)
3730 for (y=0; y < (int) (*image)->rows; y++)
3732 q=GetCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
3733 (*image)->columns,1,exception);
3734 if (q == (Quantum *) NULL)
3736 for (x=0; x < (int) (*image)->columns; x++)
3738 GetPixelInfoPixel(*image,q,&pixel);
3739 if (IsFuzzyEquivalencePixelInfo(&pixel,&target))
3741 SetPixelRed(*image,ScaleShortToQuantum(
3743 SetPixelGreen(*image,ScaleShortToQuantum(
3745 SetPixelBlue(*image,ScaleShortToQuantum(
3748 q+=(ptrdiff_t) GetPixelChannels(*image);
3750 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
3756 for (i=0; i < (ssize_t) (*image)->colors; i++)
3757 if (IsFuzzyEquivalencePixelInfo((*image)->colormap+i,&target))
3759 (*image)->colormap[i].red=(double) ScaleShortToQuantum(
3761 (*image)->colormap[i].green=(double) ScaleShortToQuantum(
3763 (*image)->colormap[i].blue=(double) ScaleShortToQuantum(
3766 (void) SyncImage(*image,exception);
3770 case FloodfillMethod:
3771 case FillToBorderMethod:
3782 (void) GetOneVirtualPixelInfo(*image,
3783 GetPixelCacheVirtualMethod(*image),(ssize_t) x_offset,(ssize_t)
3784 y_offset,&target,exception);
3785 if (method == FillToBorderMethod)
3788 ScaleShortToQuantum(border_color.red);
3789 target.green=(double)
3790 ScaleShortToQuantum(border_color.green);
3791 target.blue=(double)
3792 ScaleShortToQuantum(border_color.blue);
3794 draw_info=CloneDrawInfo(resource_info->image_info,
3796 (void) QueryColorCompliance(resource_info->pen_colors[pen_id],
3797 AllCompliance,&draw_info->fill,exception);
3798 (void) FloodfillPaintImage(*image,draw_info,&target,
3799 (ssize_t)x_offset,(ssize_t)y_offset,
3800 method != FloodfillMethod ? MagickTrue : MagickFalse,exception);
3801 draw_info=DestroyDrawInfo(draw_info);
3809 if (SetImageStorageClass(*image,DirectClass,exception) == MagickFalse)
3810 return(MagickFalse);
3811 for (y=0; y < (int) (*image)->rows; y++)
3813 q=QueueCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
3814 (*image)->columns,1,exception);
3815 if (q == (Quantum *) NULL)
3817 for (x=0; x < (int) (*image)->columns; x++)
3819 SetPixelRed(*image,ScaleShortToQuantum(color.red),q);
3820 SetPixelGreen(*image,ScaleShortToQuantum(color.green),q);
3821 SetPixelBlue(*image,ScaleShortToQuantum(color.blue),q);
3822 q+=(ptrdiff_t) GetPixelChannels(*image);
3824 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
3830 image_view=DestroyCacheView(image_view);
3833 }
while ((state & ExitState) == 0);
3834 (void) XSelectInput(display,windows->image.id,
3835 windows->image.attributes.event_mask);
3836 XSetCursorState(display,windows,MagickFalse);
3837 (void) XFreeCursor(display,cursor);
3876static MagickBooleanType XCompositeImage(Display *display,
3877 XResourceInfo *resource_info,XWindows *windows,Image *image,
3878 ExceptionInfo *exception)
3881 *
const CompositeMenu[] =
3892 displacement_geometry[MagickPathExtent] =
"30x30",
3893 filename[MagickPathExtent] =
"\0";
3895 static CompositeOperator
3896 compose = CopyCompositeOp;
3898 static const ModeType
3899 CompositeCommands[] =
3901 CompositeOperatorsCommand,
3902 CompositeDissolveCommand,
3903 CompositeDisplaceCommand,
3904 CompositeHelpCommand,
3905 CompositeDismissCommand
3909 text[MagickPathExtent];
3944 XFileBrowserWidget(display,windows,
"Composite",filename);
3945 if (*filename ==
'\0')
3950 XSetCursorState(display,windows,MagickTrue);
3951 XCheckRefreshWindows(display,windows);
3952 (void) CopyMagickString(resource_info->image_info->filename,filename,
3954 composite_image=ReadImage(resource_info->image_info,exception);
3955 CatchException(exception);
3956 XSetCursorState(display,windows,MagickFalse);
3957 if (composite_image == (Image *) NULL)
3958 return(MagickFalse);
3962 (void) CloneString(&windows->command.name,
"Composite");
3963 windows->command.data=1;
3964 (void) XCommandWidget(display,windows,CompositeMenu,(XEvent *) NULL);
3965 (void) XMapRaised(display,windows->command.id);
3966 XClientMessage(display,windows->image.id,windows->im_protocols,
3967 windows->im_update_widget,CurrentTime);
3971 XQueryPosition(display,windows->image.id,&x,&y);
3972 (void) XSelectInput(display,windows->image.id,
3973 windows->image.attributes.event_mask | PointerMotionMask);
3974 composite_info.x=(ssize_t) windows->image.x+x;
3975 composite_info.y=(ssize_t) windows->image.y+y;
3976 composite_info.width=0;
3977 composite_info.height=0;
3978 cursor=XCreateFontCursor(display,XC_ul_angle);
3979 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
3984 if (windows->info.mapped != MagickFalse)
3989 (void) FormatLocaleString(text,MagickPathExtent,
" %+ld%+ld ",
3990 (
long) composite_info.x,(
long) composite_info.y);
3991 XInfoWidget(display,windows,text);
3993 highlight_info=composite_info;
3994 highlight_info.x=composite_info.x-windows->image.x;
3995 highlight_info.y=composite_info.y-windows->image.y;
3996 XHighlightRectangle(display,windows->image.id,
3997 windows->image.highlight_context,&highlight_info);
4001 XScreenEvent(display,windows,&event,exception);
4002 XHighlightRectangle(display,windows->image.id,
4003 windows->image.highlight_context,&highlight_info);
4004 if (event.xany.window == windows->command.id)
4009 id=XCommandWidget(display,windows,CompositeMenu,&event);
4012 switch (CompositeCommands[
id])
4014 case CompositeOperatorsCommand:
4017 command[MagickPathExtent],
4023 operators=GetCommandOptions(MagickComposeOptions);
4024 if (operators == (
char **) NULL)
4026 entry=XMenuWidget(display,windows,CompositeMenu[
id],
4027 (
const char **) operators,command);
4029 compose=(CompositeOperator) ParseCommandOption(
4030 MagickComposeOptions,MagickFalse,operators[entry]);
4031 operators=DestroyStringList(operators);
4034 case CompositeDissolveCommand:
4037 factor[MagickPathExtent] =
"20.0";
4042 (void) XSetFunction(display,windows->image.highlight_context,
4044 (void) XDialogWidget(display,windows,
"Dissolve",
4045 "Enter the blend factor (0.0 - 99.9%):",factor);
4046 (void) XSetFunction(display,windows->image.highlight_context,
4048 if (*factor ==
'\0')
4050 blend=StringToDouble(factor,(
char **) NULL);
4051 compose=DissolveCompositeOp;
4054 case CompositeDisplaceCommand:
4059 (void) XSetFunction(display,windows->image.highlight_context,
4061 (void) XDialogWidget(display,windows,
"Displace",
4062 "Enter the horizontal and vertical scale:",displacement_geometry);
4063 (void) XSetFunction(display,windows->image.highlight_context,
4065 if (*displacement_geometry ==
'\0')
4067 compose=DisplaceCompositeOp;
4070 case CompositeHelpCommand:
4072 (void) XSetFunction(display,windows->image.highlight_context,
4074 XTextViewHelp(display,resource_info,windows,MagickFalse,
4075 "Help Viewer - Image Composite",ImageCompositeHelp);
4076 (void) XSetFunction(display,windows->image.highlight_context,
4080 case CompositeDismissCommand:
4098 if (resource_info->debug != MagickFalse)
4099 (void) LogMagickEvent(X11Event,GetMagickModule(),
4100 "Button Press: 0x%lx %u +%d+%d",event.xbutton.window,
4101 event.xbutton.button,event.xbutton.x,event.xbutton.y);
4102 if (event.xbutton.button != Button1)
4104 if (event.xbutton.window != windows->image.id)
4109 composite_info.width=composite_image->columns;
4110 composite_info.height=composite_image->rows;
4111 (void) XCheckDefineCursor(display,windows->image.id,cursor);
4112 composite_info.x=(ssize_t) windows->image.x+event.xbutton.x;
4113 composite_info.y=(ssize_t) windows->image.y+event.xbutton.y;
4118 if (resource_info->debug != MagickFalse)
4119 (void) LogMagickEvent(X11Event,GetMagickModule(),
4120 "Button Release: 0x%lx %u +%d+%d",event.xbutton.window,
4121 event.xbutton.button,event.xbutton.x,event.xbutton.y);
4122 if (event.xbutton.button != Button1)
4124 if (event.xbutton.window != windows->image.id)
4126 if ((composite_info.width != 0) && (composite_info.height != 0))
4131 composite_info.x=(ssize_t) windows->image.x+event.xbutton.x;
4132 composite_info.y=(ssize_t) windows->image.y+event.xbutton.y;
4142 command[MagickPathExtent];
4150 if (event.xkey.window != windows->image.id)
4155 length=XLookupString((XKeyEvent *) &event.xkey,command,(
int)
4156 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
4157 *(command+length)=
'\0';
4158 if (resource_info->debug != MagickFalse)
4159 (void) LogMagickEvent(X11Event,GetMagickModule(),
4160 "Key press: 0x%lx (%s)",(
unsigned long) key_symbol,command);
4161 switch ((
int) key_symbol)
4169 composite_image=DestroyImage(composite_image);
4177 (void) XSetFunction(display,windows->image.highlight_context,
4179 XTextViewHelp(display,resource_info,windows,MagickFalse,
4180 "Help Viewer - Image Composite",ImageCompositeHelp);
4181 (void) XSetFunction(display,windows->image.highlight_context,
4187 (void) XBell(display,0);
4200 if (windows->info.mapped != MagickFalse)
4202 if ((x < (windows->info.x+(
int) windows->info.width)) &&
4203 (y < (windows->info.y+(
int) windows->info.height)))
4204 (void) XWithdrawWindow(display,windows->info.id,
4205 windows->info.screen);
4208 if ((x > (windows->info.x+(
int) windows->info.width)) ||
4209 (y > (windows->info.y+(
int) windows->info.height)))
4210 (void) XMapWindow(display,windows->info.id);
4211 composite_info.x=(ssize_t) windows->image.x+x;
4212 composite_info.y=(ssize_t) windows->image.y+y;
4217 if (resource_info->debug != MagickFalse)
4218 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Event type: %d",
4223 }
while ((state & ExitState) == 0);
4224 (void) XSelectInput(display,windows->image.id,
4225 windows->image.attributes.event_mask);
4226 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
4227 XSetCursorState(display,windows,MagickFalse);
4228 (void) XFreeCursor(display,cursor);
4229 if ((state & EscapeState) != 0)
4234 XSetCursorState(display,windows,MagickTrue);
4235 XCheckRefreshWindows(display,windows);
4236 width=(
unsigned int) image->columns;
4237 height=(
unsigned int) image->rows;
4240 if (windows->image.crop_geometry != (
char *) NULL)
4241 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
4242 scale_factor=(double) width/windows->image.ximage->width;
4243 composite_info.x+=x;
4244 composite_info.x=(ssize_t) (scale_factor*composite_info.x+0.5);
4245 composite_info.width=(
unsigned int) (scale_factor*composite_info.width+0.5);
4246 scale_factor=(double) height/windows->image.ximage->height;
4247 composite_info.y+=y;
4248 composite_info.y=(ssize_t) (scale_factor*composite_info.y+0.5);
4249 composite_info.height=(
unsigned int) (scale_factor*composite_info.height+0.5);
4250 if ((composite_info.width != composite_image->columns) ||
4251 (composite_info.height != composite_image->rows))
4259 resize_image=ResizeImage(composite_image,composite_info.width,
4260 composite_info.height,composite_image->filter,exception);
4261 composite_image=DestroyImage(composite_image);
4262 if (resize_image == (Image *) NULL)
4264 XSetCursorState(display,windows,MagickFalse);
4265 return(MagickFalse);
4267 composite_image=resize_image;
4269 if (compose == DisplaceCompositeOp)
4270 (void) SetImageArtifact(composite_image,
"compose:args",
4271 displacement_geometry);
4292 (void) SetImageAlphaChannel(composite_image,OpaqueAlphaChannel,exception);
4293 opacity=(Quantum) (ScaleQuantumToChar(QuantumRange)-
4294 ((ssize_t) ScaleQuantumToChar(QuantumRange)*blend)/100);
4295 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
4296 return(MagickFalse);
4297 image->alpha_trait=BlendPixelTrait;
4298 image_view=AcquireAuthenticCacheView(image,exception);
4299 for (y=0; y < (int) image->rows; y++)
4301 q=GetCacheViewAuthenticPixels(image_view,0,(ssize_t) y,image->columns,1,
4303 if (q == (Quantum *) NULL)
4305 for (x=0; x < (int) image->columns; x++)
4307 SetPixelAlpha(image,opacity,q);
4308 q+=(ptrdiff_t) GetPixelChannels(image);
4310 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
4313 image_view=DestroyCacheView(image_view);
4318 (void) CompositeImage(image,composite_image,compose,MagickTrue,
4319 composite_info.x,composite_info.y,exception);
4320 composite_image=DestroyImage(composite_image);
4321 XSetCursorState(display,windows,MagickFalse);
4325 XConfigureImageColormap(display,resource_info,windows,image,exception);
4326 (void) XConfigureImage(display,resource_info,windows,image,exception);
4366static MagickBooleanType XConfigureImage(Display *display,
4367 XResourceInfo *resource_info,XWindows *windows,Image *image,
4368 ExceptionInfo *exception)
4371 geometry[MagickPathExtent];
4394 width=(
unsigned int) windows->image.window_changes.width;
4395 height=(
unsigned int) windows->image.window_changes.height;
4396 if (resource_info->debug != MagickFalse)
4397 (void) LogMagickEvent(X11Event,GetMagickModule(),
4398 "Configure Image: %dx%d=>%.20gx%.20g",windows->image.ximage->width,
4399 windows->image.ximage->height,(
double) width,(
double) height);
4400 if ((width*height) == 0)
4407 XSetCursorState(display,windows,MagickTrue);
4408 (void) XFlush(display);
4409 if (((
int) width != windows->image.ximage->width) ||
4410 ((
int) height != windows->image.ximage->height))
4411 image->taint=MagickTrue;
4412 windows->magnify.x=(int)
4413 width*windows->magnify.x/windows->image.ximage->width;
4414 windows->magnify.y=(int)
4415 height*windows->magnify.y/windows->image.ximage->height;
4416 windows->image.x=((int) width*windows->image.x/windows->image.ximage->width);
4417 windows->image.y=((int) height*windows->image.y/
4418 windows->image.ximage->height);
4419 status=XMakeImage(display,resource_info,&windows->image,image,
4420 (
unsigned int) width,(
unsigned int) height,exception);
4421 if (status == MagickFalse)
4422 XNoticeWidget(display,windows,
"Unable to configure X image:",
4423 windows->image.name);
4427 if (resource_info->image_geometry != (
char *) NULL)
4428 (void) FormatLocaleString(geometry,MagickPathExtent,
"%s>!",
4429 resource_info->image_geometry);
4431 (
void) FormatLocaleString(geometry,MagickPathExtent,
"%ux%u+0+0>!",
4432 XDisplayWidth(display,windows->image.screen),
4433 XDisplayHeight(display,windows->image.screen));
4434 (void) ParseMetaGeometry(geometry,&x,&y,&width,&height);
4435 window_changes.width=(int) width;
4436 if (window_changes.width > XDisplayWidth(display,windows->image.screen))
4437 window_changes.width=XDisplayWidth(display,windows->image.screen);
4438 window_changes.height=(int) height;
4439 if (window_changes.height > XDisplayHeight(display,windows->image.screen))
4440 window_changes.height=XDisplayHeight(display,windows->image.screen);
4441 mask=(size_t) (CWWidth | CWHeight);
4442 if (resource_info->backdrop)
4445 window_changes.x=((XDisplayWidth(display,windows->image.screen)/2)-
4447 window_changes.y=((XDisplayHeight(display,windows->image.screen)/2)-
4450 (void) XReconfigureWMWindow(display,windows->image.id,windows->image.screen,
4451 (
unsigned int) mask,&window_changes);
4452 (void) XClearWindow(display,windows->image.id);
4453 XRefreshWindow(display,&windows->image,(XEvent *) NULL);
4457 if (windows->magnify.mapped != MagickFalse)
4458 XMakeMagnifyImage(display,windows,exception);
4459 windows->pan.crop_geometry=windows->image.crop_geometry;
4460 XBestIconSize(display,&windows->pan,image);
4461 while (((windows->pan.width << 1) < MaxIconSize) &&
4462 ((windows->pan.height << 1) < MaxIconSize))
4464 windows->pan.width<<=1;
4465 windows->pan.height<<=1;
4467 if (windows->pan.geometry != (
char *) NULL)
4468 (void) XParseGeometry(windows->pan.geometry,&windows->pan.x,&windows->pan.y,
4469 &windows->pan.width,&windows->pan.height);
4470 window_changes.width=(int) windows->pan.width;
4471 window_changes.height=(int) windows->pan.height;
4472 size_hints=XAllocSizeHints();
4473 if (size_hints != (XSizeHints *) NULL)
4478 size_hints->flags=PSize | PMinSize | PMaxSize;
4479 size_hints->width=window_changes.width;
4480 size_hints->height=window_changes.height;
4481 size_hints->min_width=size_hints->width;
4482 size_hints->min_height=size_hints->height;
4483 size_hints->max_width=size_hints->width;
4484 size_hints->max_height=size_hints->height;
4485 (void) XSetNormalHints(display,windows->pan.id,size_hints);
4486 (void) XFree((
void *) size_hints);
4488 (void) XReconfigureWMWindow(display,windows->pan.id,windows->pan.screen,
4489 (
unsigned int) (CWWidth | CWHeight),&window_changes);
4493 windows->icon.crop_geometry=windows->image.crop_geometry;
4494 XBestIconSize(display,&windows->icon,image);
4495 window_changes.width=(int) windows->icon.width;
4496 window_changes.height=(int) windows->icon.height;
4497 (void) XReconfigureWMWindow(display,windows->icon.id,windows->icon.screen,
4498 (
unsigned int) (CWWidth | CWHeight),&window_changes);
4499 XSetCursorState(display,windows,MagickFalse);
4500 return(status != 0 ? MagickTrue : MagickFalse);
4541static MagickBooleanType XCropImage(Display *display,
4542 XResourceInfo *resource_info,XWindows *windows,Image *image,
4543 const ClipboardMode mode,ExceptionInfo *exception)
4546 *
const CropModeMenu[] =
4552 *RectifyModeMenu[] =
4560 static const ModeType
4570 RectifyDismissCommand
4577 command[MagickPathExtent],
4578 text[MagickPathExtent];
4621 (void) CloneString(&windows->command.name,
"Copy");
4626 (void) CloneString(&windows->command.name,
"Crop");
4631 (void) CloneString(&windows->command.name,
"Cut");
4635 RectifyModeMenu[0]=windows->command.name;
4636 windows->command.data=0;
4637 (void) XCommandWidget(display,windows,CropModeMenu,(XEvent *) NULL);
4638 (void) XMapRaised(display,windows->command.id);
4639 XClientMessage(display,windows->image.id,windows->im_protocols,
4640 windows->im_update_widget,CurrentTime);
4644 XQueryPosition(display,windows->image.id,&x,&y);
4645 (void) XSelectInput(display,windows->image.id,
4646 windows->image.attributes.event_mask | PointerMotionMask);
4647 crop_info.x=(ssize_t) windows->image.x+x;
4648 crop_info.y=(ssize_t) windows->image.y+y;
4651 cursor=XCreateFontCursor(display,XC_fleur);
4655 if (windows->info.mapped != MagickFalse)
4660 (void) FormatLocaleString(text,MagickPathExtent,
" %+ld%+ld ",
4661 (
long) crop_info.x,(
long) crop_info.y);
4662 XInfoWidget(display,windows,text);
4667 XScreenEvent(display,windows,&event,exception);
4668 if (event.xany.window == windows->command.id)
4673 id=XCommandWidget(display,windows,CropModeMenu,&event);
4676 switch (CropCommands[
id])
4678 case CropHelpCommand:
4684 XTextViewHelp(display,resource_info,windows,MagickFalse,
4685 "Help Viewer - Image Copy",ImageCopyHelp);
4690 XTextViewHelp(display,resource_info,windows,MagickFalse,
4691 "Help Viewer - Image Crop",ImageCropHelp);
4696 XTextViewHelp(display,resource_info,windows,MagickFalse,
4697 "Help Viewer - Image Cut",ImageCutHelp);
4703 case CropDismissCommand:
4721 if (event.xbutton.button != Button1)
4723 if (event.xbutton.window != windows->image.id)
4728 (void) XCheckDefineCursor(display,windows->image.id,cursor);
4729 crop_info.x=(ssize_t) windows->image.x+event.xbutton.x;
4730 crop_info.y=(ssize_t) windows->image.y+event.xbutton.y;
4740 if (event.xkey.window != windows->image.id)
4745 (void) XLookupString((XKeyEvent *) &event.xkey,command,(
int)
4746 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
4747 switch ((
int) key_symbol)
4766 XTextViewHelp(display,resource_info,windows,MagickFalse,
4767 "Help Viewer - Image Copy",ImageCopyHelp);
4772 XTextViewHelp(display,resource_info,windows,MagickFalse,
4773 "Help Viewer - Image Crop",ImageCropHelp);
4778 XTextViewHelp(display,resource_info,windows,MagickFalse,
4779 "Help Viewer - Image Cut",ImageCutHelp);
4787 (void) XBell(display,0);
4795 if (event.xmotion.window != windows->image.id)
4802 if (windows->info.mapped != MagickFalse)
4804 if ((x < (windows->info.x+(
int) windows->info.width)) &&
4805 (y < (windows->info.y+(
int) windows->info.height)))
4806 (void) XWithdrawWindow(display,windows->info.id,
4807 windows->info.screen);
4810 if ((x > (windows->info.x+(
int) windows->info.width)) ||
4811 (y > (windows->info.y+(
int) windows->info.height)))
4812 (void) XMapWindow(display,windows->info.id);
4813 crop_info.x=(ssize_t) windows->image.x+x;
4814 crop_info.y=(ssize_t) windows->image.y+y;
4820 }
while ((state & ExitState) == 0);
4821 (void) XSelectInput(display,windows->image.id,
4822 windows->image.attributes.event_mask);
4823 if ((state & EscapeState) != 0)
4828 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
4829 (void) XFreeCursor(display,cursor);
4832 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
4838 x=(int) crop_info.x;
4839 y=(int) crop_info.y;
4845 highlight_info=crop_info;
4846 highlight_info.x=crop_info.x-windows->image.x;
4847 highlight_info.y=crop_info.y-windows->image.y;
4848 if ((highlight_info.width > 3) && (highlight_info.height > 3))
4853 if (windows->info.mapped == MagickFalse)
4854 (void) XMapWindow(display,windows->info.id);
4855 (void) FormatLocaleString(text,MagickPathExtent,
4856 " %.20gx%.20g%+.20g%+.20g",(
double) crop_info.width,(
double)
4857 crop_info.height,(
double) crop_info.x,(
double) crop_info.y);
4858 XInfoWidget(display,windows,text);
4859 XHighlightRectangle(display,windows->image.id,
4860 windows->image.highlight_context,&highlight_info);
4863 if (windows->info.mapped != MagickFalse)
4864 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
4868 XScreenEvent(display,windows,&event,exception);
4869 if ((highlight_info.width > 3) && (highlight_info.height > 3))
4870 XHighlightRectangle(display,windows->image.id,
4871 windows->image.highlight_context,&highlight_info);
4876 crop_info.x=(ssize_t) windows->image.x+event.xbutton.x;
4877 crop_info.y=(ssize_t) windows->image.y+event.xbutton.y;
4885 crop_info.x=(ssize_t) windows->image.x+event.xbutton.x;
4886 crop_info.y=(ssize_t) windows->image.y+event.xbutton.y;
4887 XSetCursorState(display,windows,MagickFalse);
4889 windows->command.data=0;
4890 (void) XCommandWidget(display,windows,RectifyModeMenu,
4898 crop_info.x=(ssize_t) windows->image.x+event.xmotion.x;
4899 crop_info.y=(ssize_t) windows->image.y+event.xmotion.y;
4904 if ((((
int) crop_info.x != x) && ((
int) crop_info.y != y)) ||
4905 ((state & ExitState) != 0))
4910 if (crop_info.x < 0)
4913 if (crop_info.x > (ssize_t) windows->image.ximage->width)
4914 crop_info.x=(ssize_t) windows->image.ximage->width;
4915 if ((
int) crop_info.x < x)
4916 crop_info.width=(
unsigned int) (x-crop_info.x);
4919 crop_info.width=(
unsigned int) (crop_info.x-x);
4920 crop_info.x=(ssize_t) x;
4922 if (crop_info.y < 0)
4925 if (crop_info.y > (ssize_t) windows->image.ximage->height)
4926 crop_info.y=(ssize_t) windows->image.ximage->height;
4927 if ((
int) crop_info.y < y)
4928 crop_info.height=(
unsigned int) (y-crop_info.y);
4931 crop_info.height=(
unsigned int) (crop_info.y-y);
4932 crop_info.y=(ssize_t) y;
4935 }
while ((state & ExitState) == 0);
4940 (void) XMapWindow(display,windows->info.id);
4943 if (windows->info.mapped != MagickFalse)
4948 (void) FormatLocaleString(text,MagickPathExtent,
4949 " %.20gx%.20g%+.20g%+.20g",(
double) crop_info.width,(
double)
4950 crop_info.height,(
double) crop_info.x,(
double) crop_info.y);
4951 XInfoWidget(display,windows,text);
4953 highlight_info=crop_info;
4954 highlight_info.x=crop_info.x-windows->image.x;
4955 highlight_info.y=crop_info.y-windows->image.y;
4956 if ((highlight_info.width <= 3) || (highlight_info.height <= 3))
4962 XHighlightRectangle(display,windows->image.id,
4963 windows->image.highlight_context,&highlight_info);
4964 XScreenEvent(display,windows,&event,exception);
4965 if (event.xany.window == windows->command.id)
4970 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
4971 id=XCommandWidget(display,windows,RectifyModeMenu,&event);
4972 (void) XSetFunction(display,windows->image.highlight_context,
4974 XHighlightRectangle(display,windows->image.id,
4975 windows->image.highlight_context,&highlight_info);
4977 switch (RectifyCommands[
id])
4979 case RectifyCopyCommand:
4984 case RectifyHelpCommand:
4986 (void) XSetFunction(display,windows->image.highlight_context,
4992 XTextViewHelp(display,resource_info,windows,MagickFalse,
4993 "Help Viewer - Image Copy",ImageCopyHelp);
4998 XTextViewHelp(display,resource_info,windows,MagickFalse,
4999 "Help Viewer - Image Crop",ImageCropHelp);
5004 XTextViewHelp(display,resource_info,windows,MagickFalse,
5005 "Help Viewer - Image Cut",ImageCutHelp);
5009 (void) XSetFunction(display,windows->image.highlight_context,
5013 case RectifyDismissCommand:
5027 XHighlightRectangle(display,windows->image.id,
5028 windows->image.highlight_context,&highlight_info);
5033 if (event.xbutton.button != Button1)
5035 if (event.xbutton.window != windows->image.id)
5037 x=windows->image.x+
event.xbutton.x;
5038 y=windows->image.y+
event.xbutton.y;
5039 if ((x < (
int) (crop_info.x+RoiDelta)) &&
5040 (x > (
int) (crop_info.x-RoiDelta)) &&
5041 (y < (
int) (crop_info.y+RoiDelta)) &&
5042 (y > (
int) (crop_info.y-RoiDelta)))
5044 crop_info.x=crop_info.x+(ssize_t) crop_info.width;
5045 crop_info.y=crop_info.y+(ssize_t) crop_info.height;
5046 state|=UpdateConfigurationState;
5049 if ((x < (
int) (crop_info.x+RoiDelta)) &&
5050 (x > (
int) (crop_info.x-RoiDelta)) &&
5051 (y < (
int) (crop_info.y+(
int) crop_info.height+RoiDelta)) &&
5052 (y > (
int) (crop_info.y+(
int) crop_info.height-RoiDelta)))
5054 crop_info.x=(crop_info.x+(int) crop_info.width);
5055 state|=UpdateConfigurationState;
5058 if ((x < (
int) (crop_info.x+(
int) crop_info.width+RoiDelta)) &&
5059 (x > (
int) (crop_info.x+(
int) crop_info.width-RoiDelta)) &&
5060 (y < (
int) (crop_info.y+RoiDelta)) &&
5061 (y > (
int) (crop_info.y-RoiDelta)))
5063 crop_info.y=(crop_info.y+(ssize_t) crop_info.height);
5064 state|=UpdateConfigurationState;
5067 if ((x < (
int) (crop_info.x+(
int) crop_info.width+RoiDelta)) &&
5068 (x > (
int) (crop_info.x+(
int) crop_info.width-RoiDelta)) &&
5069 (y < (
int) (crop_info.y+(
int) crop_info.height+RoiDelta)) &&
5070 (y > (
int) (crop_info.y+(
int) crop_info.height-RoiDelta)))
5072 state|=UpdateConfigurationState;
5079 if (event.xbutton.window == windows->pan.id)
5080 if ((highlight_info.x != crop_info.x-windows->image.x) ||
5081 (highlight_info.y != crop_info.y-windows->image.y))
5082 XHighlightRectangle(display,windows->image.id,
5083 windows->image.highlight_context,&highlight_info);
5084 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id,
5085 event.xbutton.time);
5090 if (event.xexpose.window == windows->image.id)
5091 if (event.xexpose.count == 0)
5093 event.xexpose.x=(int) highlight_info.x;
5094 event.xexpose.y=(int) highlight_info.y;
5095 event.xexpose.width=(int) highlight_info.width;
5096 event.xexpose.height=(int) highlight_info.height;
5097 XRefreshWindow(display,&windows->image,&event);
5099 if (event.xexpose.window == windows->info.id)
5100 if (event.xexpose.count == 0)
5101 XInfoWidget(display,windows,text);
5106 if (event.xkey.window != windows->image.id)
5111 (void) XLookupString((XKeyEvent *) &event.xkey,command,(
int)
5112 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
5113 switch ((
int) key_symbol)
5129 crop_info.x=(ssize_t) (windows->image.width/2L-crop_info.width/
5131 crop_info.y=(ssize_t) (windows->image.height/2L-crop_info.height/
5164 (void) XSetFunction(display,windows->image.highlight_context,
5170 XTextViewHelp(display,resource_info,windows,MagickFalse,
5171 "Help Viewer - Image Copy",ImageCopyHelp);
5176 XTextViewHelp(display,resource_info,windows,MagickFalse,
5177 "Help Viewer - Image Cropg",ImageCropHelp);
5182 XTextViewHelp(display,resource_info,windows,MagickFalse,
5183 "Help Viewer - Image Cutg",ImageCutHelp);
5187 (void) XSetFunction(display,windows->image.highlight_context,
5193 (void) XBell(display,0);
5197 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id,
5205 if (event.xmotion.window != windows->image.id)
5212 if (windows->info.mapped != MagickFalse)
5214 if ((x < (windows->info.x+(
int) windows->info.width)) &&
5215 (y < (windows->info.y+(
int) windows->info.height)))
5216 (void) XWithdrawWindow(display,windows->info.id,
5217 windows->info.screen);
5220 if ((x > (windows->info.x+(
int) windows->info.width)) ||
5221 (y > (windows->info.y+(
int) windows->info.height)))
5222 (void) XMapWindow(display,windows->info.id);
5223 crop_info.x=(ssize_t) windows->image.x+event.xmotion.x;
5224 crop_info.y=(ssize_t) windows->image.y+event.xmotion.y;
5227 case SelectionRequest:
5232 XSelectionRequestEvent
5238 (void) FormatLocaleString(text,MagickPathExtent,
5239 "%.20gx%.20g%+.20g%+.20g",(
double) crop_info.width,(
double)
5240 crop_info.height,(
double) crop_info.x,(
double) crop_info.y);
5241 request=(&(
event.xselectionrequest));
5242 (void) XChangeProperty(request->display,request->requestor,
5243 request->property,request->target,8,PropModeReplace,
5244 (
unsigned char *) text,(
int) strlen(text));
5245 notify.type=SelectionNotify;
5246 notify.display=request->display;
5247 notify.requestor=request->requestor;
5248 notify.selection=request->selection;
5249 notify.target=request->target;
5250 notify.time=request->time;
5251 if (request->property == None)
5252 notify.property=request->target;
5254 notify.property=request->property;
5255 (void) XSendEvent(request->display,request->requestor,False,0,
5256 (XEvent *) ¬ify);
5261 if ((state & UpdateConfigurationState) != 0)
5263 (void) XPutBackEvent(display,&event);
5264 (void) XCheckDefineCursor(display,windows->image.id,cursor);
5267 }
while ((state & ExitState) == 0);
5268 }
while ((state & ExitState) == 0);
5269 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
5270 XSetCursorState(display,windows,MagickFalse);
5271 if ((state & EscapeState) != 0)
5273 if (mode == CropMode)
5274 if (((
int) crop_info.width != windows->image.ximage->width) ||
5275 ((
int) crop_info.height != windows->image.ximage->height))
5280 XSetCropGeometry(display,windows,&crop_info,image);
5281 windows->image.window_changes.width=(int) crop_info.width;
5282 windows->image.window_changes.height=(int) crop_info.height;
5283 (void) XConfigureImage(display,resource_info,windows,image,exception);
5289 XSetCursorState(display,windows,MagickTrue);
5290 XCheckRefreshWindows(display,windows);
5291 width=(
unsigned int) image->columns;
5292 height=(
unsigned int) image->rows;
5295 if (windows->image.crop_geometry != (
char *) NULL)
5296 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
5297 scale_factor=(double) width/windows->image.ximage->width;
5299 crop_info.x=(ssize_t) (scale_factor*crop_info.x+0.5);
5300 crop_info.width=(
unsigned int) (scale_factor*crop_info.width+0.5);
5301 scale_factor=(double) height/windows->image.ximage->height;
5303 crop_info.y=(ssize_t) (scale_factor*crop_info.y+0.5);
5304 crop_info.height=(
unsigned int) (scale_factor*crop_info.height+0.5);
5305 crop_info.x+=image->page.x;
5306 crop_info.y+=image->page.y;
5307 crop_image=CropImage(image,&crop_info,exception);
5308 XSetCursorState(display,windows,MagickFalse);
5309 if (crop_image == (Image *) NULL)
5310 return(MagickFalse);
5311 if (resource_info->copy_image != (Image *) NULL)
5312 resource_info->copy_image=DestroyImage(resource_info->copy_image);
5313 resource_info->copy_image=crop_image;
5314 if (mode == CopyMode)
5316 (void) XConfigureImage(display,resource_info,windows,image,exception);
5322 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
5323 return(MagickFalse);
5324 image->alpha_trait=BlendPixelTrait;
5325 image_view=AcquireAuthenticCacheView(image,exception);
5326 for (y=0; y < (int) crop_info.height; y++)
5328 q=GetCacheViewAuthenticPixels(image_view,crop_info.x,y+crop_info.y,
5329 crop_info.width,1,exception);
5330 if (q == (Quantum *) NULL)
5332 for (x=0; x < (int) crop_info.width; x++)
5334 SetPixelAlpha(image,TransparentAlpha,q);
5335 q+=(ptrdiff_t) GetPixelChannels(image);
5337 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
5340 image_view=DestroyCacheView(image_view);
5344 XConfigureImageColormap(display,resource_info,windows,image,exception);
5345 (void) XConfigureImage(display,resource_info,windows,image,exception);
5383static MagickBooleanType XDrawEditImage(Display *display,
5384 XResourceInfo *resource_info,XWindows *windows,Image **image,
5385 ExceptionInfo *exception)
5401 element = PointElement;
5403 static const ModeType
5416 stipple = (Pixmap) NULL;
5423 command[MagickPathExtent],
5424 text[MagickPathExtent];
5475 max_coordinates=2048;
5476 coordinate_info=(XPoint *) AcquireQuantumMemory((
size_t) max_coordinates,
5477 sizeof(*coordinate_info));
5478 if (coordinate_info == (XPoint *) NULL)
5480 (void) ThrowMagickException(exception,GetMagickModule(),
5481 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",
"...");
5482 return(MagickFalse);
5487 (void) CloneString(&windows->command.name,
"Draw");
5488 windows->command.data=4;
5489 (void) XCommandWidget(display,windows,DrawMenu,(XEvent *) NULL);
5490 (void) XMapRaised(display,windows->command.id);
5491 XClientMessage(display,windows->image.id,windows->im_protocols,
5492 windows->im_update_widget,CurrentTime);
5496 root_window=XRootWindow(display,XDefaultScreen(display));
5497 draw_info.stencil=OpaqueStencil;
5499 cursor=XCreateFontCursor(display,XC_tcross);
5502 XQueryPosition(display,windows->image.id,&x,&y);
5503 (void) XSelectInput(display,windows->image.id,
5504 windows->image.attributes.event_mask | PointerMotionMask);
5505 (void) XCheckDefineCursor(display,windows->image.id,cursor);
5509 if (windows->info.mapped != MagickFalse)
5514 (void) FormatLocaleString(text,MagickPathExtent,
" %+d%+d ",
5515 x+windows->image.x,y+windows->image.y);
5516 XInfoWidget(display,windows,text);
5521 XScreenEvent(display,windows,&event,exception);
5522 if (event.xany.window == windows->command.id)
5527 id=XCommandWidget(display,windows,DrawMenu,&event);
5530 switch (DrawCommands[
id])
5532 case DrawElementCommand:
5553 element=(ElementType) (XMenuWidget(display,windows,
5554 DrawMenu[
id],Elements,command)+1);
5557 case DrawColorCommand:
5560 *ColorMenu[MaxNumberPens+1];
5574 for (i=0; i < (int) (MaxNumberPens-2); i++)
5575 ColorMenu[i]=resource_info->pen_colors[i];
5576 ColorMenu[MaxNumberPens-2]=
"transparent";
5577 ColorMenu[MaxNumberPens-1]=
"Browser...";
5578 ColorMenu[MaxNumberPens]=(
char *) NULL;
5582 pen_number=XMenuWidget(display,windows,DrawMenu[
id],
5583 (
const char **) ColorMenu,command);
5586 transparent=pen_number == (MaxNumberPens-2) ? MagickTrue :
5588 if (transparent != MagickFalse)
5590 draw_info.stencil=TransparentStencil;
5593 if (pen_number == (MaxNumberPens-1))
5596 color_name[MagickPathExtent] =
"gray";
5601 resource_info->pen_colors[pen_number]=color_name;
5602 XColorBrowserWidget(display,windows,
"Select",color_name);
5603 if (*color_name ==
'\0')
5609 (void) XParseColor(display,windows->map_info->colormap,
5610 resource_info->pen_colors[pen_number],&color);
5611 XBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
5612 (
unsigned int) MaxColors,&color);
5613 windows->pixel_info->pen_colors[pen_number]=color;
5614 pen_id=(
unsigned int) pen_number;
5615 draw_info.stencil=OpaqueStencil;
5618 case DrawStippleCommand:
5644 filename[MagickPathExtent] =
"\0";
5649 StipplesMenu[7]=
"Open...";
5650 entry=XMenuWidget(display,windows,DrawMenu[
id],StipplesMenu,
5654 if (stipple != (Pixmap) NULL)
5655 (void) XFreePixmap(display,stipple);
5656 stipple=(Pixmap) NULL;
5663 stipple=XCreateBitmapFromData(display,root_window,
5664 (
char *) BricksBitmap,BricksWidth,BricksHeight);
5669 stipple=XCreateBitmapFromData(display,root_window,
5670 (
char *) DiagonalBitmap,DiagonalWidth,DiagonalHeight);
5675 stipple=XCreateBitmapFromData(display,root_window,
5676 (
char *) ScalesBitmap,ScalesWidth,ScalesHeight);
5681 stipple=XCreateBitmapFromData(display,root_window,
5682 (
char *) VerticalBitmap,VerticalWidth,VerticalHeight);
5687 stipple=XCreateBitmapFromData(display,root_window,
5688 (
char *) WavyBitmap,WavyWidth,WavyHeight);
5693 stipple=XCreateBitmapFromData(display,root_window,
5694 (
char *) HighlightBitmap,HighlightWidth,
5701 stipple=XCreateBitmapFromData(display,root_window,
5702 (
char *) OpaqueBitmap,OpaqueWidth,OpaqueHeight);
5708 XFileBrowserWidget(display,windows,
"Stipple",filename);
5709 if (*filename ==
'\0')
5714 XSetCursorState(display,windows,MagickTrue);
5715 XCheckRefreshWindows(display,windows);
5716 image_info=AcquireImageInfo();
5717 (void) CopyMagickString(image_info->filename,filename,
5719 stipple_image=ReadImage(image_info,exception);
5720 CatchException(exception);
5721 XSetCursorState(display,windows,MagickFalse);
5722 if (stipple_image == (Image *) NULL)
5724 (void) AcquireUniqueFileResource(filename);
5725 (void) FormatLocaleString(stipple_image->filename,
5726 MagickPathExtent,
"xbm:%s",filename);
5727 (void) WriteImage(image_info,stipple_image,exception);
5728 stipple_image=DestroyImage(stipple_image);
5729 image_info=DestroyImageInfo(image_info);
5730 status=XReadBitmapFile(display,root_window,filename,&width,
5731 &height,&stipple,&x,&y);
5732 (void) RelinquishUniqueFileResource(filename);
5733 if ((status != BitmapSuccess) != 0)
5734 XNoticeWidget(display,windows,
"Unable to read X bitmap image:",
5738 case DrawWidthCommand:
5741 *
const WidthsMenu[] =
5753 width[MagickPathExtent] =
"0";
5758 entry=XMenuWidget(display,windows,DrawMenu[
id],WidthsMenu,
5764 line_width=(
unsigned int) StringToUnsignedLong(
5768 (void) XDialogWidget(display,windows,
"Ok",
"Enter line width:",
5772 line_width=(
unsigned int) StringToUnsignedLong(width);
5775 case DrawUndoCommand:
5777 (void) XMagickCommand(display,resource_info,windows,UndoCommand,
5781 case DrawHelpCommand:
5783 XTextViewHelp(display,resource_info,windows,MagickFalse,
5784 "Help Viewer - Image Rotation",ImageDrawHelp);
5785 (void) XCheckDefineCursor(display,windows->image.id,cursor);
5788 case DrawDismissCommand:
5800 (void) XCheckDefineCursor(display,windows->image.id,cursor);
5807 if (event.xbutton.button != Button1)
5809 if (event.xbutton.window != windows->image.id)
5828 if (event.xkey.window != windows->image.id)
5833 (void) XLookupString((XKeyEvent *) &event.xkey,command,(
int)
5834 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
5835 switch ((
int) key_symbol)
5850 XTextViewHelp(display,resource_info,windows,MagickFalse,
5851 "Help Viewer - Image Rotation",ImageDrawHelp);
5856 (void) XBell(display,0);
5869 if (windows->info.mapped != MagickFalse)
5871 if ((x < (windows->info.x+(
int) windows->info.width)) &&
5872 (y < (windows->info.y+(
int) windows->info.height)))
5873 (void) XWithdrawWindow(display,windows->info.id,
5874 windows->info.screen);
5877 if ((x > (windows->info.x+(
int) windows->info.width)) ||
5878 (y > (windows->info.y+(
int) windows->info.height)))
5879 (void) XMapWindow(display,windows->info.id);
5883 }
while ((state & ExitState) == 0);
5884 (void) XSelectInput(display,windows->image.id,
5885 windows->image.attributes.event_mask);
5886 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
5887 if ((state & EscapeState) != 0)
5898 rectangle_info.x=(ssize_t) x;
5899 rectangle_info.y=(ssize_t) y;
5900 rectangle_info.width=0;
5901 rectangle_info.height=0;
5902 number_coordinates=1;
5903 coordinate_info->x=x;
5904 coordinate_info->y=y;
5905 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
5914 if (number_coordinates > 1)
5916 (void) XDrawLines(display,windows->image.id,
5917 windows->image.highlight_context,coordinate_info,
5918 number_coordinates,CoordModeOrigin);
5919 (void) FormatLocaleString(text,MagickPathExtent,
" %+d%+d",
5920 coordinate_info[number_coordinates-1].x,
5921 coordinate_info[number_coordinates-1].y);
5922 XInfoWidget(display,windows,text);
5933 degrees=RadiansToDegrees(-atan2((
double) (line_info.y2-
5934 line_info.y1),(
double) (line_info.x2-line_info.x1)));
5935 (void) FormatLocaleString(text,MagickPathExtent,
" %g",
5937 XInfoWidget(display,windows,text);
5938 XHighlightLine(display,windows->image.id,
5939 windows->image.highlight_context,&line_info);
5942 if (windows->info.mapped != MagickFalse)
5943 (void) XWithdrawWindow(display,windows->info.id,
5944 windows->info.screen);
5947 case RectangleElement:
5948 case FillRectangleElement:
5950 if ((rectangle_info.width > 3) && (rectangle_info.height > 3))
5955 (void) FormatLocaleString(text,MagickPathExtent,
5956 " %.20gx%.20g%+.20g%+.20g",(
double) rectangle_info.width,
5957 (
double) rectangle_info.height,(
double) rectangle_info.x,
5958 (
double) rectangle_info.y);
5959 XInfoWidget(display,windows,text);
5960 XHighlightRectangle(display,windows->image.id,
5961 windows->image.highlight_context,&rectangle_info);
5964 if (windows->info.mapped != MagickFalse)
5965 (void) XWithdrawWindow(display,windows->info.id,
5966 windows->info.screen);
5970 case FillCircleElement:
5971 case EllipseElement:
5972 case FillEllipseElement:
5974 if ((rectangle_info.width > 3) && (rectangle_info.height > 3))
5979 (void) FormatLocaleString(text,MagickPathExtent,
5980 " %.20gx%.20g%+.20g%+.20g",(
double) rectangle_info.width,
5981 (
double) rectangle_info.height,(
double) rectangle_info.x,
5982 (
double) rectangle_info.y);
5983 XInfoWidget(display,windows,text);
5984 XHighlightEllipse(display,windows->image.id,
5985 windows->image.highlight_context,&rectangle_info);
5988 if (windows->info.mapped != MagickFalse)
5989 (void) XWithdrawWindow(display,windows->info.id,
5990 windows->info.screen);
5993 case PolygonElement:
5994 case FillPolygonElement:
5996 if (number_coordinates > 1)
5997 (void) XDrawLines(display,windows->image.id,
5998 windows->image.highlight_context,coordinate_info,
5999 number_coordinates,CoordModeOrigin);
6005 degrees=RadiansToDegrees(-atan2((
double) (line_info.y2-
6006 line_info.y1),(
double) (line_info.x2-line_info.x1)));
6007 (void) FormatLocaleString(text,MagickPathExtent,
" %g",
6009 XInfoWidget(display,windows,text);
6010 XHighlightLine(display,windows->image.id,
6011 windows->image.highlight_context,&line_info);
6014 if (windows->info.mapped != MagickFalse)
6015 (void) XWithdrawWindow(display,windows->info.id,
6016 windows->info.screen);
6023 XScreenEvent(display,windows,&event,exception);
6029 if (number_coordinates > 1)
6030 (void) XDrawLines(display,windows->image.id,
6031 windows->image.highlight_context,coordinate_info,
6032 number_coordinates,CoordModeOrigin);
6038 XHighlightLine(display,windows->image.id,
6039 windows->image.highlight_context,&line_info);
6042 case RectangleElement:
6043 case FillRectangleElement:
6045 if ((rectangle_info.width > 3) && (rectangle_info.height > 3))
6046 XHighlightRectangle(display,windows->image.id,
6047 windows->image.highlight_context,&rectangle_info);
6051 case FillCircleElement:
6052 case EllipseElement:
6053 case FillEllipseElement:
6055 if ((rectangle_info.width > 3) && (rectangle_info.height > 3))
6056 XHighlightEllipse(display,windows->image.id,
6057 windows->image.highlight_context,&rectangle_info);
6060 case PolygonElement:
6061 case FillPolygonElement:
6063 if (number_coordinates > 1)
6064 (void) XDrawLines(display,windows->image.id,
6065 windows->image.highlight_context,coordinate_info,
6066 number_coordinates,CoordModeOrigin);
6068 XHighlightLine(display,windows->image.id,
6069 windows->image.highlight_context,&line_info);
6082 line_info.x2=
event.xbutton.x;
6083 line_info.y2=
event.xbutton.y;
6084 rectangle_info.x=(ssize_t) event.xbutton.x;
6085 rectangle_info.y=(ssize_t) event.xbutton.y;
6086 coordinate_info[number_coordinates].x=
event.xbutton.x;
6087 coordinate_info[number_coordinates].y=
event.xbutton.y;
6088 if (((element != PolygonElement) &&
6089 (element != FillPolygonElement)) || (distance <= 9))
6094 number_coordinates++;
6095 if (number_coordinates < (
int) max_coordinates)
6097 line_info.x1=
event.xbutton.x;
6098 line_info.y1=
event.xbutton.y;
6101 max_coordinates<<=1;
6102 coordinate_info=(XPoint *) ResizeQuantumMemory(coordinate_info,
6103 max_coordinates,
sizeof(*coordinate_info));
6104 if (coordinate_info == (XPoint *) NULL)
6105 (void) ThrowMagickException(exception,GetMagickModule(),
6106 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",
"...");
6113 if (event.xmotion.window != windows->image.id)
6115 if (element != PointElement)
6117 line_info.x2=
event.xmotion.x;
6118 line_info.y2=
event.xmotion.y;
6119 rectangle_info.x=(ssize_t) event.xmotion.x;
6120 rectangle_info.y=(ssize_t) event.xmotion.y;
6123 coordinate_info[number_coordinates].x=
event.xbutton.x;
6124 coordinate_info[number_coordinates].y=
event.xbutton.y;
6125 number_coordinates++;
6126 if (number_coordinates < (
int) max_coordinates)
6128 max_coordinates<<=1;
6129 coordinate_info=(XPoint *) ResizeQuantumMemory(coordinate_info,
6130 max_coordinates,
sizeof(*coordinate_info));
6131 if (coordinate_info == (XPoint *) NULL)
6132 (void) ThrowMagickException(exception,GetMagickModule(),
6133 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",
"...");
6142 if (line_info.x2 < 0)
6145 if (line_info.x2 > (
int) windows->image.width)
6146 line_info.x2=(short) windows->image.width;
6147 if (line_info.y2 < 0)
6150 if (line_info.y2 > (
int) windows->image.height)
6151 line_info.y2=(short) windows->image.height;
6152 distance=(
unsigned int)
6153 (((line_info.x2-line_info.x1+1)*(line_info.x2-line_info.x1+1))+
6154 ((line_info.y2-line_info.y1+1)*(line_info.y2-line_info.y1+1)));
6155 if ((((
int) rectangle_info.x != x) && ((
int) rectangle_info.y != y)) ||
6156 ((state & ExitState) != 0))
6158 if (rectangle_info.x < 0)
6161 if (rectangle_info.x > (ssize_t) windows->image.width)
6162 rectangle_info.x=(ssize_t) windows->image.width;
6163 if ((
int) rectangle_info.x < x)
6164 rectangle_info.width=(
unsigned int) (x-rectangle_info.x);
6167 rectangle_info.width=(
unsigned int) (rectangle_info.x-x);
6168 rectangle_info.x=(ssize_t) x;
6170 if (rectangle_info.y < 0)
6173 if (rectangle_info.y > (ssize_t) windows->image.height)
6174 rectangle_info.y=(ssize_t) windows->image.height;
6175 if ((
int) rectangle_info.y < y)
6176 rectangle_info.height=(
unsigned int) (y-rectangle_info.y);
6179 rectangle_info.height=(
unsigned int) (rectangle_info.y-y);
6180 rectangle_info.y=(ssize_t) y;
6183 }
while ((state & ExitState) == 0);
6184 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
6185 if ((element == PointElement) || (element == PolygonElement) ||
6186 (element == FillPolygonElement))
6191 rectangle_info.x=(ssize_t) coordinate_info->x;
6192 rectangle_info.y=(ssize_t) coordinate_info->y;
6193 x=coordinate_info->x;
6194 y=coordinate_info->y;
6195 for (i=1; i < number_coordinates; i++)
6197 if (coordinate_info[i].x > x)
6198 x=coordinate_info[i].x;
6199 if (coordinate_info[i].y > y)
6200 y=coordinate_info[i].y;
6201 if ((ssize_t) coordinate_info[i].x < rectangle_info.x)
6202 rectangle_info.x=MagickMax((ssize_t) coordinate_info[i].x,0);
6203 if ((ssize_t) coordinate_info[i].y < rectangle_info.y)
6204 rectangle_info.y=MagickMax((ssize_t) coordinate_info[i].y,0);
6206 rectangle_info.width=(size_t) (x-rectangle_info.x);
6207 rectangle_info.height=(size_t) (y-rectangle_info.y);
6208 for (i=0; i < number_coordinates; i++)
6210 coordinate_info[i].x-=rectangle_info.x;
6211 coordinate_info[i].y-=rectangle_info.y;
6218 if ((element == RectangleElement) ||
6219 (element == CircleElement) || (element == EllipseElement))
6221 rectangle_info.width--;
6222 rectangle_info.height--;
6227 draw_info.x=(int) rectangle_info.x;
6228 draw_info.y=(int) rectangle_info.y;
6229 (void) XMagickCommand(display,resource_info,windows,SaveToUndoBufferCommand,
6231 width=(
unsigned int) (*image)->columns;
6232 height=(
unsigned int) (*image)->rows;
6235 if (windows->image.crop_geometry != (
char *) NULL)
6236 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
6237 draw_info.x+=windows->image.x-((int) line_width/2);
6238 if (draw_info.x < 0)
6240 draw_info.x=(int) width*draw_info.x/windows->image.ximage->width;
6241 draw_info.y+=windows->image.y-((int) line_width/2);
6242 if (draw_info.y < 0)
6244 draw_info.y=(int) height*draw_info.y/windows->image.ximage->height;
6245 draw_info.width=(
unsigned int) rectangle_info.width+(line_width << 1);
6246 if (draw_info.width > (
unsigned int) (*image)->columns)
6247 draw_info.width=(
unsigned int) (*image)->columns;
6248 draw_info.height=(
unsigned int) rectangle_info.height+(line_width << 1);
6249 if (draw_info.height > (
unsigned int) (*image)->rows)
6250 draw_info.height=(
unsigned int) (*image)->rows;
6251 (void) FormatLocaleString(draw_info.geometry,MagickPathExtent,
"%ux%u%+d%+d",
6252 width*draw_info.width/(
unsigned int) windows->image.ximage->width,
6253 height*draw_info.height/(
unsigned int) windows->image.ximage->height,
6254 draw_info.x+x,draw_info.y+y);
6258 draw_info.degrees=0.0;
6259 draw_info.element=element;
6260 draw_info.stipple=stipple;
6261 draw_info.line_width=line_width;
6262 draw_info.line_info=line_info;
6263 if (line_info.x1 > (
int) (line_width/2))
6264 draw_info.line_info.x1=(short) line_width/2;
6265 if (line_info.y1 > (
int) (line_width/2))
6266 draw_info.line_info.y1=(short) line_width/2;
6267 draw_info.line_info.x2=(short) (line_info.x2-line_info.x1+
6268 ((
int) line_width/2));
6269 draw_info.line_info.y2=(short) (line_info.y2-line_info.y1+
6270 ((
int) line_width/2));
6271 if ((draw_info.line_info.x2 < 0) && (draw_info.line_info.y2 < 0))
6273 draw_info.line_info.x2=(-draw_info.line_info.x2);
6274 draw_info.line_info.y2=(-draw_info.line_info.y2);
6276 if (draw_info.line_info.x2 < 0)
6278 draw_info.line_info.x2=(-draw_info.line_info.x2);
6279 Swap(draw_info.line_info.x1,draw_info.line_info.x2);
6281 if (draw_info.line_info.y2 < 0)
6283 draw_info.line_info.y2=(-draw_info.line_info.y2);
6284 Swap(draw_info.line_info.y1,draw_info.line_info.y2);
6286 draw_info.rectangle_info=rectangle_info;
6287 if (draw_info.rectangle_info.x > (ssize_t) (line_width/2))
6288 draw_info.rectangle_info.x=(ssize_t) line_width/2;
6289 if (draw_info.rectangle_info.y > (ssize_t) (line_width/2))
6290 draw_info.rectangle_info.y=(ssize_t) line_width/2;
6291 draw_info.number_coordinates=(
unsigned int) number_coordinates;
6292 draw_info.coordinate_info=coordinate_info;
6293 windows->pixel_info->pen_color=windows->pixel_info->pen_colors[pen_id];
6297 XSetCursorState(display,windows,MagickTrue);
6298 XCheckRefreshWindows(display,windows);
6299 status=XDrawImage(display,windows->pixel_info,&draw_info,*image,exception);
6300 XSetCursorState(display,windows,MagickFalse);
6304 XConfigureImageColormap(display,resource_info,windows,*image,exception);
6305 (void) XConfigureImage(display,resource_info,windows,*image,exception);
6307 XSetCursorState(display,windows,MagickFalse);
6308 coordinate_info=(XPoint *) RelinquishMagickMemory(coordinate_info);
6309 return(status != 0 ? MagickTrue : MagickFalse);
6339static void XDrawPanRectangle(Display *display,XWindows *windows)
6350 scale_factor=(double) windows->pan.width/windows->image.ximage->width;
6351 highlight_info.x=(ssize_t) (scale_factor*windows->image.x+0.5);
6352 highlight_info.width=(
unsigned int) (scale_factor*windows->image.width+0.5);
6353 scale_factor=(double)
6354 windows->pan.height/windows->image.ximage->height;
6355 highlight_info.y=(ssize_t) (scale_factor*windows->image.y+0.5);
6356 highlight_info.height=(
unsigned int) (scale_factor*windows->image.height+0.5);
6360 (void) XClearWindow(display,windows->pan.id);
6361 XHighlightRectangle(display,windows->pan.id,windows->pan.annotate_context,
6402static void XImageCache(Display *display,XResourceInfo *resource_info,
6403 XWindows *windows,
const DisplayCommand command,Image **image,
6404 ExceptionInfo *exception)
6410 *redo_image = (Image *) NULL,
6411 *undo_image = (Image *) NULL;
6415 case FreeBuffersCommand:
6420 while (undo_image != (Image *) NULL)
6422 cache_image=undo_image;
6423 undo_image=GetPreviousImageInList(undo_image);
6424 cache_image->list=DestroyImage(cache_image->list);
6425 cache_image=DestroyImage(cache_image);
6427 undo_image=NewImageList();
6428 if (redo_image != (Image *) NULL)
6429 redo_image=DestroyImage(redo_image);
6430 redo_image=NewImageList();
6436 image_geometry[MagickPathExtent];
6441 if (undo_image == (Image *) NULL)
6443 (void) XBell(display,0);
6444 ThrowXWindowException(ImageError,
"NoImagesWereFound",
6445 (*image)->filename);
6448 cache_image=undo_image;
6449 undo_image=GetPreviousImageInList(undo_image);
6450 windows->image.window_changes.width=(int) cache_image->columns;
6451 windows->image.window_changes.height=(int) cache_image->rows;
6452 (void) FormatLocaleString(image_geometry,MagickPathExtent,
"%dx%d!",
6453 windows->image.ximage->width,windows->image.ximage->height);
6454 (void) TransformImage(image,windows->image.crop_geometry,image_geometry,
6456 if (windows->image.crop_geometry != (
char *) NULL)
6457 windows->image.crop_geometry=(
char *) RelinquishMagickMemory(
6458 windows->image.crop_geometry);
6459 windows->image.crop_geometry=cache_image->geometry;
6460 if (redo_image != (Image *) NULL)
6461 redo_image=DestroyImage(redo_image);
6462 redo_image=(*image);
6463 *image=cache_image->list;
6464 cache_image=DestroyImage(cache_image);
6465 if (windows->image.orphan != MagickFalse)
6467 XConfigureImageColormap(display,resource_info,windows,*image,exception);
6468 (void) XConfigureImage(display,resource_info,windows,*image,exception);
6474 case HalfSizeCommand:
6475 case OriginalSizeCommand:
6476 case DoubleSizeCommand:
6483 case RotateRightCommand:
6484 case RotateLeftCommand:
6489 case ContrastStretchCommand:
6490 case SigmoidalContrastCommand:
6491 case NormalizeCommand:
6492 case EqualizeCommand:
6494 case SaturationCommand:
6495 case BrightnessCommand:
6499 case GrayscaleCommand:
6501 case QuantizeCommand:
6502 case DespeckleCommand:
6504 case ReduceNoiseCommand:
6505 case AddNoiseCommand:
6506 case SharpenCommand:
6508 case ThresholdCommand:
6509 case EdgeDetectCommand:
6513 case SegmentCommand:
6514 case SolarizeCommand:
6515 case SepiaToneCommand:
6517 case ImplodeCommand:
6518 case VignetteCommand:
6520 case OilPaintCommand:
6521 case CharcoalDrawCommand:
6522 case AnnotateCommand:
6523 case AddBorderCommand:
6524 case AddFrameCommand:
6525 case CompositeCommand:
6526 case CommentCommand:
6528 case RegionOfInterestCommand:
6529 case SaveToUndoBufferCommand:
6538 bytes=(*image)->columns*(*image)->rows*
sizeof(PixelInfo);
6539 if (undo_image != (Image *) NULL)
6544 previous_image=undo_image;
6545 while (previous_image != (Image *) NULL)
6547 bytes+=previous_image->list->columns*previous_image->list->rows*
6549 if (bytes <= (resource_info->undo_cache << 20))
6551 previous_image=GetPreviousImageInList(previous_image);
6554 bytes-=previous_image->list->columns*previous_image->list->rows*
6556 if (previous_image == undo_image)
6557 undo_image=NewImageList();
6559 previous_image->next->previous=NewImageList();
6562 while (previous_image != (Image *) NULL)
6567 cache_image=previous_image;
6568 previous_image=GetPreviousImageInList(previous_image);
6569 cache_image->list=DestroyImage(cache_image->list);
6570 cache_image=DestroyImage(cache_image);
6573 if (bytes > (resource_info->undo_cache << 20))
6578 cache_image=AcquireImage((ImageInfo *) NULL,exception);
6579 if (cache_image == (Image *) NULL)
6581 XSetCursorState(display,windows,MagickTrue);
6582 XCheckRefreshWindows(display,windows);
6583 cache_image->list=CloneImage(*image,0,0,MagickTrue,exception);
6584 XSetCursorState(display,windows,MagickFalse);
6585 if (cache_image->list == (Image *) NULL)
6587 cache_image=DestroyImage(cache_image);
6590 cache_image->columns=(size_t) windows->image.ximage->width;
6591 cache_image->rows=(size_t) windows->image.ximage->height;
6592 cache_image->geometry=windows->image.crop_geometry;
6593 if (windows->image.crop_geometry != (
char *) NULL)
6595 cache_image->geometry=AcquireString((
char *) NULL);
6596 (void) CopyMagickString(cache_image->geometry,
6597 windows->image.crop_geometry,MagickPathExtent);
6599 if (undo_image == (Image *) NULL)
6601 undo_image=cache_image;
6604 undo_image->next=cache_image;
6605 undo_image->next->previous=undo_image;
6606 undo_image=undo_image->next;
6612 if (command == RedoCommand)
6617 if (redo_image == (Image *) NULL)
6619 (void) XBell(display,0);
6622 windows->image.window_changes.width=(int) redo_image->columns;
6623 windows->image.window_changes.height=(int) redo_image->rows;
6624 if (windows->image.crop_geometry != (
char *) NULL)
6625 windows->image.crop_geometry=(
char *)
6626 RelinquishMagickMemory(windows->image.crop_geometry);
6627 windows->image.crop_geometry=redo_image->geometry;
6628 *image=DestroyImage(*image);
6630 redo_image=NewImageList();
6631 if (windows->image.orphan != MagickFalse)
6633 XConfigureImageColormap(display,resource_info,windows,*image,exception);
6634 (void) XConfigureImage(display,resource_info,windows,*image,exception);
6637 if (command != InfoCommand)
6642 XSetCursorState(display,windows,MagickTrue);
6643 XCheckRefreshWindows(display,windows);
6644 XDisplayImageInfo(display,resource_info,windows,undo_image,*image,exception);
6645 XSetCursorState(display,windows,MagickFalse);
6692static DisplayCommand XImageWindowCommand(Display *display,
6693 XResourceInfo *resource_info,XWindows *windows,
const MagickStatusType state,
6694 KeySym key_symbol,Image **image,ExceptionInfo *exception)
6697 delta[MagickPathExtent+1] =
"";
6700 Digits[] =
"01234567890";
6705 if ((key_symbol >= XK_0) && (key_symbol <= XK_9))
6710 if (((last_symbol < XK_0) || (last_symbol > XK_9)))
6713 resource_info->quantum=1;
6715 last_symbol=key_symbol;
6716 length=strlen(delta);
6717 if (length < MagickPathExtent)
6719 delta[length]=Digits[key_symbol-XK_0];
6720 delta[length+1]=
'\0';
6722 resource_info->quantum=StringToLong(delta);
6723 return(NullCommand);
6725 last_symbol=key_symbol;
6726 if (resource_info->immutable)
6734 return(InfoCommand);
6737 return(PrintCommand);
6739 return(NextCommand);
6742 return(QuitCommand);
6746 return(NullCommand);
6748 switch ((
int) key_symbol)
6752 if ((state & ControlMask) == 0)
6754 return(OpenCommand);
6757 return(NextCommand);
6759 return(FormerCommand);
6762 if ((state & Mod1Mask) != 0)
6763 return(SwirlCommand);
6764 if ((state & ControlMask) == 0)
6765 return(ShearCommand);
6766 return(SaveCommand);
6771 if ((state & Mod1Mask) != 0)
6772 return(OilPaintCommand);
6773 if ((state & Mod4Mask) != 0)
6774 return(ColorCommand);
6775 if ((state & ControlMask) == 0)
6776 return(NullCommand);
6777 return(PrintCommand);
6781 if ((state & Mod4Mask) != 0)
6782 return(DrawCommand);
6783 if ((state & ControlMask) == 0)
6784 return(NullCommand);
6785 return(DeleteCommand);
6789 if ((state & ControlMask) == 0)
6790 return(NullCommand);
6791 return(SelectCommand);
6795 if ((state & ControlMask) == 0)
6796 return(NullCommand);
6801 return(QuitCommand);
6805 if ((state & ControlMask) == 0)
6806 return(NullCommand);
6807 return(UndoCommand);
6812 if ((state & ControlMask) == 0)
6813 return(RollCommand);
6814 return(RedoCommand);
6818 if ((state & ControlMask) == 0)
6819 return(NullCommand);
6824 if ((state & Mod1Mask) != 0)
6825 return(CharcoalDrawCommand);
6826 if ((state & ControlMask) == 0)
6827 return(CropCommand);
6828 return(CopyCommand);
6833 if ((state & Mod4Mask) != 0)
6834 return(CompositeCommand);
6835 if ((state & ControlMask) == 0)
6836 return(FlipCommand);
6837 return(PasteCommand);
6840 return(HalfSizeCommand);
6842 return(OriginalSizeCommand);
6844 return(DoubleSizeCommand);
6846 return(ResizeCommand);
6848 return(RefreshCommand);
6849 case XK_bracketleft:
6850 return(ChopCommand);
6852 return(FlopCommand);
6854 return(RotateRightCommand);
6856 return(RotateLeftCommand);
6858 return(RotateCommand);
6860 return(TrimCommand);
6864 return(SaturationCommand);
6866 return(BrightnessCommand);
6868 return(GammaCommand);
6870 return(SpiffCommand);
6872 return(DullCommand);
6874 return(NormalizeCommand);
6876 return(EqualizeCommand);
6878 return(NegateCommand);
6880 return(GrayscaleCommand);
6882 return(QuantizeCommand);
6884 return(DespeckleCommand);
6886 return(EmbossCommand);
6888 return(ReduceNoiseCommand);
6890 return(AddNoiseCommand);
6892 return(SharpenCommand);
6894 return(BlurCommand);
6896 return(ThresholdCommand);
6898 return(EdgeDetectCommand);
6900 return(SpreadCommand);
6902 return(ShadeCommand);
6904 return(RaiseCommand);
6906 return(SegmentCommand);
6909 if ((state & Mod1Mask) == 0)
6910 return(NullCommand);
6911 return(ImplodeCommand);
6915 if ((state & Mod1Mask) == 0)
6916 return(NullCommand);
6917 return(WaveCommand);
6921 if ((state & Mod4Mask) == 0)
6922 return(NullCommand);
6923 return(MatteCommand);
6927 if ((state & Mod4Mask) == 0)
6928 return(NullCommand);
6929 return(AddBorderCommand);
6933 if ((state & Mod4Mask) == 0)
6934 return(NullCommand);
6935 return(AddFrameCommand);
6939 if ((state & Mod4Mask) == 0)
6940 return(NullCommand);
6941 return(CommentCommand);
6945 if ((state & Mod1Mask) != 0)
6946 return(ApplyCommand);
6947 if ((state & Mod4Mask) != 0)
6948 return(AnnotateCommand);
6949 if ((state & ControlMask) == 0)
6950 return(NullCommand);
6951 return(RegionOfInterestCommand);
6954 return(InfoCommand);
6956 return(ZoomCommand);
6959 if ((state & ShiftMask) == 0)
6960 return(NullCommand);
6961 return(ShowPreviewCommand);
6964 return(LaunchCommand);
6966 return(HelpCommand);
6968 return(BrowseDocumentationCommand);
6971 (void) XMapRaised(display,windows->command.id);
6972 return(NullCommand);
6979 XTranslateImage(display,windows,*image,key_symbol);
6980 return(NullCommand);
6991 if ((state & Mod1Mask) != 0)
7001 crop_info.width=(size_t) windows->image.ximage->width;
7002 crop_info.height=(size_t) windows->image.ximage->height;
7003 if ((key_symbol == XK_Up) || (key_symbol == XK_KP_Up))
7005 if (resource_info->quantum >= (
int) crop_info.height)
7006 resource_info->quantum=(int) crop_info.height-1;
7007 crop_info.height-=(size_t) resource_info->quantum;
7009 if ((key_symbol == XK_Down) || (key_symbol == XK_KP_Down))
7011 if (resource_info->quantum >= (
int) (crop_info.height-(ssize_t) crop_info.y))
7012 resource_info->quantum=(int) (crop_info.height-(ssize_t) crop_info.y-1);
7013 crop_info.y+=resource_info->quantum;
7014 crop_info.height-=(size_t) resource_info->quantum;
7016 if ((key_symbol == XK_Left) || (key_symbol == XK_KP_Left))
7018 if (resource_info->quantum >= (
int) crop_info.width)
7019 resource_info->quantum=(int) crop_info.width-1;
7020 crop_info.width-=(size_t) resource_info->quantum;
7022 if ((key_symbol == XK_Right) || (key_symbol == XK_KP_Right))
7024 if (resource_info->quantum >= (
int) (crop_info.width-(ssize_t) crop_info.x))
7025 resource_info->quantum=(int) (crop_info.width-(ssize_t) crop_info.x-1);
7026 crop_info.x+=resource_info->quantum;
7027 crop_info.width-=(size_t) resource_info->quantum;
7029 if ((windows->image.x+(
int) windows->image.width) > (
int) crop_info.width)
7030 windows->image.x=(int) (crop_info.width-windows->image.width);
7031 if ((windows->image.y+(
int) windows->image.height) > (
int) crop_info.height)
7032 windows->image.y=(int) (crop_info.height-windows->image.height);
7033 XSetCropGeometry(display,windows,&crop_info,*image);
7034 windows->image.window_changes.width=(int) crop_info.width;
7035 windows->image.window_changes.height=(int) crop_info.height;
7036 (void) XSetWindowBackgroundPixmap(display,windows->image.id,None);
7037 (void) XConfigureImage(display,resource_info,windows,*image,
7039 return(NullCommand);
7041 XTranslateImage(display,windows,*image,key_symbol);
7042 return(NullCommand);
7045 return(NullCommand);
7047 return(NullCommand);
7087static Image *XMagickCommand(Display *display,XResourceInfo *resource_info,
7088 XWindows *windows,
const DisplayCommand command,Image **image,
7089 ExceptionInfo *exception)
7092 filename[MagickPathExtent],
7093 geometry[MagickPathExtent],
7094 modulate_factors[MagickPathExtent];
7123 color[MagickPathExtent] =
"gray";
7132 XCheckRefreshWindows(display,windows);
7133 XImageCache(display,resource_info,windows,command,image,exception);
7134 nexus=NewImageList();
7135 windows->image.window_changes.width=windows->image.ximage->width;
7136 windows->image.window_changes.height=windows->image.ximage->height;
7137 image_info=CloneImageInfo(resource_info->image_info);
7138 SetGeometryInfo(&geometry_info);
7139 GetQuantizeInfo(&quantize_info);
7147 nexus=XOpenImage(display,resource_info,windows,MagickFalse);
7155 for (i=0; i < resource_info->quantum; i++)
7156 XClientMessage(display,windows->image.id,windows->im_protocols,
7157 windows->im_next_image,CurrentTime);
7165 for (i=0; i < resource_info->quantum; i++)
7166 XClientMessage(display,windows->image.id,windows->im_protocols,
7167 windows->im_former_image,CurrentTime);
7178 if (*resource_info->home_directory ==
'\0')
7179 (void) CopyMagickString(resource_info->home_directory,
".",
7181 status=chdir(resource_info->home_directory);
7183 (void) ThrowMagickException(exception,GetMagickModule(),FileOpenError,
7184 "UnableToOpenFile",
"%s",resource_info->home_directory);
7185 nexus=XOpenImage(display,resource_info,windows,MagickTrue);
7193 status=XSaveImage(display,resource_info,windows,*image,exception);
7194 if (status == MagickFalse)
7197 message[MagickPathExtent];
7199 (void) FormatLocaleString(message,MagickPathExtent,
"%s:%s",
7200 exception->reason != (
char *) NULL ? exception->reason :
"",
7201 exception->description != (
char *) NULL ? exception->description :
7203 XNoticeWidget(display,windows,
"Unable to save file:",message);
7213 status=XPrintImage(display,resource_info,windows,*image,exception);
7214 if (status == MagickFalse)
7217 message[MagickPathExtent];
7219 (void) FormatLocaleString(message,MagickPathExtent,
"%s:%s",
7220 exception->reason != (
char *) NULL ? exception->reason :
"",
7221 exception->description != (
char *) NULL ? exception->description :
7223 XNoticeWidget(display,windows,
"Unable to print file:",message);
7231 filename[MagickPathExtent] =
"\0";
7236 XFileBrowserWidget(display,windows,
"Delete",filename);
7237 if (*filename ==
'\0')
7239 status=ShredFile(filename);
7240 if (remove_utf8(filename) < 0)
7242 if (status != MagickFalse)
7243 XNoticeWidget(display,windows,
"Unable to delete image file:",filename);
7252 color[MagickPathExtent] =
"gray",
7253 geometry[MagickPathExtent] =
"640x480";
7256 *format =
"gradient";
7261 status=XDialogWidget(display,windows,
"New",
"Enter image geometry:",
7263 if (*geometry ==
'\0')
7267 XColorBrowserWidget(display,windows,
"Select",color);
7273 (void) FormatLocaleString(image_info->filename,MagickPathExtent,
7274 "%s:%s",format,color);
7275 (void) CloneString(&image_info->size,geometry);
7276 nexus=ReadImage(image_info,exception);
7277 CatchException(exception);
7278 XClientMessage(display,windows->image.id,windows->im_protocols,
7279 windows->im_next_image,CurrentTime);
7282 case VisualDirectoryCommand:
7287 nexus=XVisualDirectoryImage(display,resource_info,windows,exception);
7295 if (resource_info->confirm_exit == MagickFalse)
7296 XClientMessage(display,windows->image.id,windows->im_protocols,
7297 windows->im_exit,CurrentTime);
7306 status=XConfirmWidget(display,windows,
"Do you really want to exit",
7307 resource_info->client_name);
7309 XClientMessage(display,windows->image.id,windows->im_protocols,
7310 windows->im_exit,CurrentTime);
7319 (void) XCropImage(display,resource_info,windows,*image,CutMode,exception);
7327 (void) XCropImage(display,resource_info,windows,*image,CopyMode,
7336 status=XPasteImage(display,resource_info,windows,*image,exception);
7337 if (status == MagickFalse)
7339 XNoticeWidget(display,windows,
"Unable to paste X image",
7340 (*image)->filename);
7345 case HalfSizeCommand:
7350 windows->image.window_changes.width=windows->image.ximage->width/2;
7351 windows->image.window_changes.height=windows->image.ximage->height/2;
7352 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7355 case OriginalSizeCommand:
7360 windows->image.window_changes.width=(int) (*image)->columns;
7361 windows->image.window_changes.height=(int) (*image)->rows;
7362 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7365 case DoubleSizeCommand:
7370 windows->image.window_changes.width=windows->image.ximage->width << 1;
7371 windows->image.window_changes.height=windows->image.ximage->height << 1;
7372 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7391 width=(size_t) windows->image.ximage->width;
7392 height=(size_t) windows->image.ximage->height;
7395 (void) FormatLocaleString(geometry,MagickPathExtent,
"%.20gx%.20g+0+0",
7396 (
double) width,(
double) height);
7397 status=XDialogWidget(display,windows,
"Resize",
7398 "Enter resize geometry (e.g. 640x480, 200%):",geometry);
7399 if (*geometry ==
'\0')
7402 (void) ConcatenateMagickString(geometry,
"!",MagickPathExtent);
7403 (void) ParseMetaGeometry(geometry,&x,&y,&width,&height);
7404 windows->image.window_changes.width=(int) width;
7405 windows->image.window_changes.height=(int) height;
7406 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7412 image_geometry[MagickPathExtent];
7414 if ((windows->image.crop_geometry == (
char *) NULL) &&
7415 ((
int) (*image)->columns == windows->image.ximage->width) &&
7416 ((
int) (*image)->rows == windows->image.ximage->height))
7421 XSetCursorState(display,windows,MagickTrue);
7422 XCheckRefreshWindows(display,windows);
7426 (void) FormatLocaleString(image_geometry,MagickPathExtent,
"%dx%d!",
7427 windows->image.ximage->width,windows->image.ximage->height);
7428 (void) TransformImage(image,windows->image.crop_geometry,image_geometry,
7430 if (windows->image.crop_geometry != (
char *) NULL)
7431 windows->image.crop_geometry=(
char *) RelinquishMagickMemory(
7432 windows->image.crop_geometry);
7435 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7436 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7439 case RefreshCommand:
7441 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7444 case RestoreCommand:
7449 if ((windows->image.width == (
unsigned int) (*image)->columns) &&
7450 (windows->image.height == (
unsigned int) (*image)->rows) &&
7451 (windows->image.crop_geometry == (
char *) NULL))
7453 (void) XBell(display,0);
7456 windows->image.window_changes.width=(int) (*image)->columns;
7457 windows->image.window_changes.height=(int) (*image)->rows;
7458 if (windows->image.crop_geometry != (
char *) NULL)
7460 windows->image.crop_geometry=(
char *)
7461 RelinquishMagickMemory(windows->image.crop_geometry);
7462 windows->image.crop_geometry=(
char *) NULL;
7466 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7467 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7475 (void) XCropImage(display,resource_info,windows,*image,CropMode,
7484 status=XChopImage(display,resource_info,windows,image,exception);
7485 if (status == MagickFalse)
7487 XNoticeWidget(display,windows,
"Unable to cut X image",
7488 (*image)->filename);
7501 XSetCursorState(display,windows,MagickTrue);
7502 XCheckRefreshWindows(display,windows);
7503 flop_image=FlopImage(*image,exception);
7504 if (flop_image != (Image *) NULL)
7506 *image=DestroyImage(*image);
7509 CatchException(exception);
7510 XSetCursorState(display,windows,MagickFalse);
7511 if (windows->image.crop_geometry != (
char *) NULL)
7516 width=(
unsigned int) (*image)->columns;
7517 height=(
unsigned int) (*image)->rows;
7518 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
7520 (void) FormatLocaleString(windows->image.crop_geometry,
7521 MagickPathExtent,
"%ux%u%+d%+d",width,height,(
int) (*image)->columns-
7524 if (windows->image.orphan != MagickFalse)
7526 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7537 XSetCursorState(display,windows,MagickTrue);
7538 XCheckRefreshWindows(display,windows);
7539 flip_image=FlipImage(*image,exception);
7540 if (flip_image != (Image *) NULL)
7542 *image=DestroyImage(*image);
7545 CatchException(exception);
7546 XSetCursorState(display,windows,MagickFalse);
7547 if (windows->image.crop_geometry != (
char *) NULL)
7552 width=(
unsigned int) (*image)->columns;
7553 height=(
unsigned int) (*image)->rows;
7554 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
7556 (void) FormatLocaleString(windows->image.crop_geometry,
7557 MagickPathExtent,
"%ux%u%+d%+d",width,height,x,(
int) (*image)->rows-
7560 if (windows->image.orphan != MagickFalse)
7562 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7565 case RotateRightCommand:
7570 status=XRotateImage(display,resource_info,windows,90.0,image,exception);
7571 if (status == MagickFalse)
7573 XNoticeWidget(display,windows,
"Unable to rotate X image",
7574 (*image)->filename);
7579 case RotateLeftCommand:
7584 status=XRotateImage(display,resource_info,windows,-90.0,image,exception);
7585 if (status == MagickFalse)
7587 XNoticeWidget(display,windows,
"Unable to rotate X image",
7588 (*image)->filename);
7598 status=XRotateImage(display,resource_info,windows,0.0,image,exception);
7599 if (status == MagickFalse)
7601 XNoticeWidget(display,windows,
"Unable to rotate X image",
7602 (*image)->filename);
7613 geometry[MagickPathExtent] =
"45.0x45.0";
7618 XColorBrowserWidget(display,windows,
"Select",color);
7621 (void) XDialogWidget(display,windows,
"Shear",
"Enter shear geometry:",
7623 if (*geometry ==
'\0')
7628 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
7630 XSetCursorState(display,windows,MagickTrue);
7631 XCheckRefreshWindows(display,windows);
7632 (void) QueryColorCompliance(color,AllCompliance,
7633 &(*image)->background_color,exception);
7634 flags=ParseGeometry(geometry,&geometry_info);
7635 if ((flags & SigmaValue) == 0)
7636 geometry_info.sigma=geometry_info.rho;
7637 shear_image=ShearImage(*image,geometry_info.rho,geometry_info.sigma,
7639 if (shear_image != (Image *) NULL)
7641 *image=DestroyImage(*image);
7644 CatchException(exception);
7645 XSetCursorState(display,windows,MagickFalse);
7646 if (windows->image.orphan != MagickFalse)
7648 windows->image.window_changes.width=(int) (*image)->columns;
7649 windows->image.window_changes.height=(int) (*image)->rows;
7650 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7651 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7660 geometry[MagickPathExtent] =
"+2+2";
7665 (void) XDialogWidget(display,windows,
"Roll",
"Enter roll geometry:",
7667 if (*geometry ==
'\0')
7672 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
7674 XSetCursorState(display,windows,MagickTrue);
7675 XCheckRefreshWindows(display,windows);
7676 (void) ParsePageGeometry(*image,geometry,&page_geometry,
7678 roll_image=RollImage(*image,page_geometry.x,page_geometry.y,
7680 if (roll_image != (Image *) NULL)
7682 *image=DestroyImage(*image);
7685 CatchException(exception);
7686 XSetCursorState(display,windows,MagickFalse);
7687 if (windows->image.orphan != MagickFalse)
7689 windows->image.window_changes.width=(int) (*image)->columns;
7690 windows->image.window_changes.height=(int) (*image)->rows;
7691 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7692 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7698 fuzz[MagickPathExtent];
7703 (void) FormatLocaleString(fuzz,MagickPathExtent,
"%g%%",100.0*
7704 (*image)->fuzz/((
double) QuantumRange+1.0));
7705 (void) XDialogWidget(display,windows,
"Trim",
"Enter fuzz factor:",fuzz);
7708 (*image)->fuzz=StringToDoubleInterval(fuzz,(
double) QuantumRange+1.0);
7712 status=XTrimImage(display,resource_info,windows,*image,exception);
7713 if (status == MagickFalse)
7715 XNoticeWidget(display,windows,
"Unable to trim X image",
7716 (*image)->filename);
7724 hue_percent[MagickPathExtent] =
"110";
7729 (void) XDialogWidget(display,windows,
"Apply",
7730 "Enter percent change in image hue (0-200):",hue_percent);
7731 if (*hue_percent ==
'\0')
7736 XSetCursorState(display,windows,MagickTrue);
7737 XCheckRefreshWindows(display,windows);
7738 (void) CopyMagickString(modulate_factors,
"100.0/100.0/",MagickPathExtent);
7739 (void) ConcatenateMagickString(modulate_factors,hue_percent,
7741 (void) ModulateImage(*image,modulate_factors,exception);
7742 XSetCursorState(display,windows,MagickFalse);
7743 if (windows->image.orphan != MagickFalse)
7745 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7746 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7749 case SaturationCommand:
7752 saturation_percent[MagickPathExtent] =
"110";
7757 (void) XDialogWidget(display,windows,
"Apply",
7758 "Enter percent change in color saturation (0-200):",saturation_percent);
7759 if (*saturation_percent ==
'\0')
7764 XSetCursorState(display,windows,MagickTrue);
7765 XCheckRefreshWindows(display,windows);
7766 (void) CopyMagickString(modulate_factors,
"100.0/",MagickPathExtent);
7767 (void) ConcatenateMagickString(modulate_factors,saturation_percent,
7769 (void) ModulateImage(*image,modulate_factors,exception);
7770 XSetCursorState(display,windows,MagickFalse);
7771 if (windows->image.orphan != MagickFalse)
7773 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7774 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7777 case BrightnessCommand:
7780 brightness_percent[MagickPathExtent] =
"110";
7785 (void) XDialogWidget(display,windows,
"Apply",
7786 "Enter percent change in color brightness (0-200):",brightness_percent);
7787 if (*brightness_percent ==
'\0')
7792 XSetCursorState(display,windows,MagickTrue);
7793 XCheckRefreshWindows(display,windows);
7794 (void) CopyMagickString(modulate_factors,brightness_percent,
7796 (void) ModulateImage(*image,modulate_factors,exception);
7797 XSetCursorState(display,windows,MagickFalse);
7798 if (windows->image.orphan != MagickFalse)
7800 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7801 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7807 factor[MagickPathExtent] =
"1.6";
7812 (void) XDialogWidget(display,windows,
"Gamma",
7813 "Enter gamma value (e.g. 1.2):",factor);
7814 if (*factor ==
'\0')
7819 XSetCursorState(display,windows,MagickTrue);
7820 XCheckRefreshWindows(display,windows);
7821 (void) GammaImage(*image,strtod(factor,(
char **) NULL),exception);
7822 XSetCursorState(display,windows,MagickFalse);
7823 if (windows->image.orphan != MagickFalse)
7825 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7826 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7834 XSetCursorState(display,windows,MagickTrue);
7835 XCheckRefreshWindows(display,windows);
7836 (void) ContrastImage(*image,MagickTrue,exception);
7837 XSetCursorState(display,windows,MagickFalse);
7838 if (windows->image.orphan != MagickFalse)
7840 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7841 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7849 XSetCursorState(display,windows,MagickTrue);
7850 XCheckRefreshWindows(display,windows);
7851 (void) ContrastImage(*image,MagickFalse,exception);
7852 XSetCursorState(display,windows,MagickFalse);
7853 if (windows->image.orphan != MagickFalse)
7855 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7856 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7859 case ContrastStretchCommand:
7866 levels[MagickPathExtent] =
"1%";
7871 (void) XDialogWidget(display,windows,
"Contrast Stretch",
7872 "Enter black and white points:",levels);
7873 if (*levels ==
'\0')
7878 XSetCursorState(display,windows,MagickTrue);
7879 XCheckRefreshWindows(display,windows);
7880 flags=ParseGeometry(levels,&geometry_info);
7881 black_point=geometry_info.rho;
7882 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma : black_point;
7883 if ((flags & PercentValue) != 0)
7885 black_point*=(double) (*image)->columns*(*image)->rows/100.0;
7886 white_point*=(double) (*image)->columns*(*image)->rows/100.0;
7888 white_point=(double) (*image)->columns*(*image)->rows-white_point;
7889 (void) ContrastStretchImage(*image,black_point,white_point,
7891 XSetCursorState(display,windows,MagickFalse);
7892 if (windows->image.orphan != MagickFalse)
7894 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7895 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7898 case SigmoidalContrastCommand:
7907 levels[MagickPathExtent] =
"3x50%";
7912 (void) XDialogWidget(display,windows,
"Sigmoidal Contrast",
7913 "Enter contrast and midpoint:",levels);
7914 if (*levels ==
'\0')
7919 XSetCursorState(display,windows,MagickTrue);
7920 XCheckRefreshWindows(display,windows);
7921 flags=ParseGeometry(levels,&geometry_info);
7922 if ((flags & SigmaValue) == 0)
7923 geometry_info.sigma=1.0*(double) QuantumRange/2.0;
7924 if ((flags & PercentValue) != 0)
7925 geometry_info.sigma=1.0*(double) QuantumRange*geometry_info.sigma/100.0;
7926 (void) SigmoidalContrastImage(*image,MagickTrue,geometry_info.rho,
7927 geometry_info.sigma,exception);
7928 XSetCursorState(display,windows,MagickFalse);
7929 if (windows->image.orphan != MagickFalse)
7931 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7932 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7935 case NormalizeCommand:
7940 XSetCursorState(display,windows,MagickTrue);
7941 XCheckRefreshWindows(display,windows);
7942 (void) NormalizeImage(*image,exception);
7943 XSetCursorState(display,windows,MagickFalse);
7944 if (windows->image.orphan != MagickFalse)
7946 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7947 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7950 case EqualizeCommand:
7955 XSetCursorState(display,windows,MagickTrue);
7956 XCheckRefreshWindows(display,windows);
7957 (void) EqualizeImage(*image,exception);
7958 XSetCursorState(display,windows,MagickFalse);
7959 if (windows->image.orphan != MagickFalse)
7961 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7962 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7970 XSetCursorState(display,windows,MagickTrue);
7971 XCheckRefreshWindows(display,windows);
7972 (void) NegateImage(*image,MagickFalse,exception);
7973 XSetCursorState(display,windows,MagickFalse);
7974 if (windows->image.orphan != MagickFalse)
7976 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7977 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7980 case GrayscaleCommand:
7985 XSetCursorState(display,windows,MagickTrue);
7986 XCheckRefreshWindows(display,windows);
7987 (void) SetImageType(*image,(*image)->alpha_trait == UndefinedPixelTrait ?
7988 GrayscaleType : GrayscaleAlphaType,exception);
7989 XSetCursorState(display,windows,MagickFalse);
7990 if (windows->image.orphan != MagickFalse)
7992 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7993 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8002 filename[MagickPathExtent] =
"\0";
8007 XFileBrowserWidget(display,windows,
"Map",filename);
8008 if (*filename ==
'\0')
8013 XSetCursorState(display,windows,MagickTrue);
8014 XCheckRefreshWindows(display,windows);
8015 (void) CopyMagickString(image_info->filename,filename,MagickPathExtent);
8016 affinity_image=ReadImage(image_info,exception);
8017 if (affinity_image != (Image *) NULL)
8019 (void) RemapImage(&quantize_info,*image,affinity_image,exception);
8020 affinity_image=DestroyImage(affinity_image);
8022 CatchException(exception);
8023 XSetCursorState(display,windows,MagickFalse);
8024 if (windows->image.orphan != MagickFalse)
8026 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8027 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8030 case QuantizeCommand:
8036 colors[MagickPathExtent] =
"256";
8041 status=XDialogWidget(display,windows,
"Quantize",
8042 "Maximum number of colors:",colors);
8043 if (*colors ==
'\0')
8048 XSetCursorState(display,windows,MagickTrue);
8049 XCheckRefreshWindows(display,windows);
8050 quantize_info.number_colors=StringToUnsignedLong(colors);
8051 quantize_info.dither_method=status != 0 ? RiemersmaDitherMethod :
8053 (void) QuantizeImage(&quantize_info,*image,exception);
8054 XSetCursorState(display,windows,MagickFalse);
8055 if (windows->image.orphan != MagickFalse)
8057 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8058 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8061 case DespeckleCommand:
8069 XSetCursorState(display,windows,MagickTrue);
8070 XCheckRefreshWindows(display,windows);
8071 despeckle_image=DespeckleImage(*image,exception);
8072 if (despeckle_image != (Image *) NULL)
8074 *image=DestroyImage(*image);
8075 *image=despeckle_image;
8077 CatchException(exception);
8078 XSetCursorState(display,windows,MagickFalse);
8079 if (windows->image.orphan != MagickFalse)
8081 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8082 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8091 radius[MagickPathExtent] =
"0.0x1.0";
8096 (void) XDialogWidget(display,windows,
"Emboss",
8097 "Enter the emboss radius and standard deviation:",radius);
8098 if (*radius ==
'\0')
8103 XSetCursorState(display,windows,MagickTrue);
8104 XCheckRefreshWindows(display,windows);
8105 flags=ParseGeometry(radius,&geometry_info);
8106 if ((flags & SigmaValue) == 0)
8107 geometry_info.sigma=1.0;
8108 emboss_image=EmbossImage(*image,geometry_info.rho,geometry_info.sigma,
8110 if (emboss_image != (Image *) NULL)
8112 *image=DestroyImage(*image);
8113 *image=emboss_image;
8115 CatchException(exception);
8116 XSetCursorState(display,windows,MagickFalse);
8117 if (windows->image.orphan != MagickFalse)
8119 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8120 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8123 case ReduceNoiseCommand:
8129 radius[MagickPathExtent] =
"0";
8134 (void) XDialogWidget(display,windows,
"Reduce Noise",
8135 "Enter the noise radius:",radius);
8136 if (*radius ==
'\0')
8141 XSetCursorState(display,windows,MagickTrue);
8142 XCheckRefreshWindows(display,windows);
8143 flags=ParseGeometry(radius,&geometry_info);
8144 noise_image=StatisticImage(*image,NonpeakStatistic,(
size_t)
8145 geometry_info.rho,(
size_t) geometry_info.rho,exception);
8146 if (noise_image != (Image *) NULL)
8148 *image=DestroyImage(*image);
8151 CatchException(exception);
8152 XSetCursorState(display,windows,MagickFalse);
8153 if (windows->image.orphan != MagickFalse)
8155 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8156 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8159 case AddNoiseCommand:
8168 noise_type[MagickPathExtent] =
"Gaussian";
8173 noises=GetCommandOptions(MagickNoiseOptions);
8174 if (noises == (
char **) NULL)
8176 XListBrowserWidget(display,windows,&windows->widget,
8177 (
const char **) noises,
"Add Noise",
8178 "Select a type of noise to add to your image:",noise_type);
8179 noises=DestroyStringList(noises);
8180 if (*noise_type ==
'\0')
8182 XSetCursorState(display,windows,MagickTrue);
8183 XCheckRefreshWindows(display,windows);
8184 noise_image=AddNoiseImage(*image,(NoiseType) ParseCommandOption(
8185 MagickNoiseOptions,MagickFalse,noise_type),1.0,exception);
8186 if (noise_image != (Image *) NULL)
8188 *image=DestroyImage(*image);
8191 CatchException(exception);
8192 XSetCursorState(display,windows,MagickFalse);
8193 if (windows->image.orphan != MagickFalse)
8195 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8196 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8199 case SharpenCommand:
8205 radius[MagickPathExtent] =
"0.0x1.0";
8210 (void) XDialogWidget(display,windows,
"Sharpen",
8211 "Enter the sharpen radius and standard deviation:",radius);
8212 if (*radius ==
'\0')
8217 XSetCursorState(display,windows,MagickTrue);
8218 XCheckRefreshWindows(display,windows);
8219 flags=ParseGeometry(radius,&geometry_info);
8220 sharp_image=SharpenImage(*image,geometry_info.rho,geometry_info.sigma,
8222 if (sharp_image != (Image *) NULL)
8224 *image=DestroyImage(*image);
8227 CatchException(exception);
8228 XSetCursorState(display,windows,MagickFalse);
8229 if (windows->image.orphan != MagickFalse)
8231 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8232 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8241 radius[MagickPathExtent] =
"0.0x1.0";
8246 (void) XDialogWidget(display,windows,
"Blur",
8247 "Enter the blur radius and standard deviation:",radius);
8248 if (*radius ==
'\0')
8253 XSetCursorState(display,windows,MagickTrue);
8254 XCheckRefreshWindows(display,windows);
8255 flags=ParseGeometry(radius,&geometry_info);
8256 blur_image=BlurImage(*image,geometry_info.rho,geometry_info.sigma,
8258 if (blur_image != (Image *) NULL)
8260 *image=DestroyImage(*image);
8263 CatchException(exception);
8264 XSetCursorState(display,windows,MagickFalse);
8265 if (windows->image.orphan != MagickFalse)
8267 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8268 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8271 case ThresholdCommand:
8277 factor[MagickPathExtent] =
"128";
8282 (void) XDialogWidget(display,windows,
"Threshold",
8283 "Enter threshold value:",factor);
8284 if (*factor ==
'\0')
8289 XSetCursorState(display,windows,MagickTrue);
8290 XCheckRefreshWindows(display,windows);
8291 threshold=StringToDoubleInterval(factor,(
double) QuantumRange+1.0);
8292 (void) BilevelImage(*image,threshold,exception);
8293 XSetCursorState(display,windows,MagickFalse);
8294 if (windows->image.orphan != MagickFalse)
8296 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8297 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8300 case EdgeDetectCommand:
8306 radius[MagickPathExtent] =
"0";
8311 (void) XDialogWidget(display,windows,
"Detect Edges",
8312 "Enter the edge detect radius:",radius);
8313 if (*radius ==
'\0')
8318 XSetCursorState(display,windows,MagickTrue);
8319 XCheckRefreshWindows(display,windows);
8320 flags=ParseGeometry(radius,&geometry_info);
8321 edge_image=EdgeImage(*image,geometry_info.rho,exception);
8322 if (edge_image != (Image *) NULL)
8324 *image=DestroyImage(*image);
8327 CatchException(exception);
8328 XSetCursorState(display,windows,MagickFalse);
8329 if (windows->image.orphan != MagickFalse)
8331 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8332 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8341 amount[MagickPathExtent] =
"2";
8346 (void) XDialogWidget(display,windows,
"Spread",
8347 "Enter the displacement amount:",amount);
8348 if (*amount ==
'\0')
8353 XSetCursorState(display,windows,MagickTrue);
8354 XCheckRefreshWindows(display,windows);
8355 flags=ParseGeometry(amount,&geometry_info);
8356 spread_image=EdgeImage(*image,geometry_info.rho,exception);
8357 if (spread_image != (Image *) NULL)
8359 *image=DestroyImage(*image);
8360 *image=spread_image;
8362 CatchException(exception);
8363 XSetCursorState(display,windows,MagickFalse);
8364 if (windows->image.orphan != MagickFalse)
8366 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8367 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8379 geometry[MagickPathExtent] =
"30x30";
8384 status=XDialogWidget(display,windows,
"Shade",
8385 "Enter the azimuth and elevation of the light source:",geometry);
8386 if (*geometry ==
'\0')
8391 XSetCursorState(display,windows,MagickTrue);
8392 XCheckRefreshWindows(display,windows);
8393 flags=ParseGeometry(geometry,&geometry_info);
8394 if ((flags & SigmaValue) == 0)
8395 geometry_info.sigma=1.0;
8396 shade_image=ShadeImage(*image,status != 0 ? MagickTrue : MagickFalse,
8397 geometry_info.rho,geometry_info.sigma,exception);
8398 if (shade_image != (Image *) NULL)
8400 *image=DestroyImage(*image);
8403 CatchException(exception);
8404 XSetCursorState(display,windows,MagickFalse);
8405 if (windows->image.orphan != MagickFalse)
8407 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8408 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8414 bevel_width[MagickPathExtent] =
"10";
8419 (void) XDialogWidget(display,windows,
"Raise",
"Bevel width:",bevel_width);
8420 if (*bevel_width ==
'\0')
8425 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
8427 XSetCursorState(display,windows,MagickTrue);
8428 XCheckRefreshWindows(display,windows);
8429 (void) ParsePageGeometry(*image,bevel_width,&page_geometry,
8431 (void) RaiseImage(*image,&page_geometry,MagickTrue,exception);
8432 XSetCursorState(display,windows,MagickFalse);
8433 if (windows->image.orphan != MagickFalse)
8435 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8436 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8439 case SegmentCommand:
8442 threshold[MagickPathExtent] =
"1.0x1.5";
8447 (void) XDialogWidget(display,windows,
"Segment",
"Smooth threshold:",
8449 if (*threshold ==
'\0')
8454 XSetCursorState(display,windows,MagickTrue);
8455 XCheckRefreshWindows(display,windows);
8456 flags=ParseGeometry(threshold,&geometry_info);
8457 if ((flags & SigmaValue) == 0)
8458 geometry_info.sigma=1.0;
8459 (void) SegmentImage(*image,sRGBColorspace,MagickFalse,geometry_info.rho,
8460 geometry_info.sigma,exception);
8461 XSetCursorState(display,windows,MagickFalse);
8462 if (windows->image.orphan != MagickFalse)
8464 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8465 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8468 case SepiaToneCommand:
8477 factor[MagickPathExtent] =
"80%";
8482 (void) XDialogWidget(display,windows,
"Sepia Tone",
8483 "Enter the sepia tone factor (0 - 99.9%):",factor);
8484 if (*factor ==
'\0')
8489 XSetCursorState(display,windows,MagickTrue);
8490 XCheckRefreshWindows(display,windows);
8491 threshold=StringToDoubleInterval(factor,(
double) QuantumRange+1.0);
8492 sepia_image=SepiaToneImage(*image,threshold,exception);
8493 if (sepia_image != (Image *) NULL)
8495 *image=DestroyImage(*image);
8498 CatchException(exception);
8499 XSetCursorState(display,windows,MagickFalse);
8500 if (windows->image.orphan != MagickFalse)
8502 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8503 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8506 case SolarizeCommand:
8512 factor[MagickPathExtent] =
"60%";
8517 (void) XDialogWidget(display,windows,
"Solarize",
8518 "Enter the solarize factor (0 - 99.9%):",factor);
8519 if (*factor ==
'\0')
8524 XSetCursorState(display,windows,MagickTrue);
8525 XCheckRefreshWindows(display,windows);
8526 threshold=StringToDoubleInterval(factor,(
double) QuantumRange+1.0);
8527 (void) SolarizeImage(*image,threshold,exception);
8528 XSetCursorState(display,windows,MagickFalse);
8529 if (windows->image.orphan != MagickFalse)
8531 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8532 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8541 degrees[MagickPathExtent] =
"60";
8546 (void) XDialogWidget(display,windows,
"Swirl",
"Enter the swirl angle:",
8548 if (*degrees ==
'\0')
8553 XSetCursorState(display,windows,MagickTrue);
8554 XCheckRefreshWindows(display,windows);
8555 flags=ParseGeometry(degrees,&geometry_info);
8556 swirl_image=SwirlImage(*image,geometry_info.rho,(*image)->interpolate,
8558 if (swirl_image != (Image *) NULL)
8560 *image=DestroyImage(*image);
8563 CatchException(exception);
8564 XSetCursorState(display,windows,MagickFalse);
8565 if (windows->image.orphan != MagickFalse)
8567 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8568 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8571 case ImplodeCommand:
8577 factor[MagickPathExtent] =
"0.3";
8582 (void) XDialogWidget(display,windows,
"Implode",
8583 "Enter the implosion/explosion factor (-1.0 - 1.0):",factor);
8584 if (*factor ==
'\0')
8589 XSetCursorState(display,windows,MagickTrue);
8590 XCheckRefreshWindows(display,windows);
8591 flags=ParseGeometry(factor,&geometry_info);
8592 implode_image=ImplodeImage(*image,geometry_info.rho,(*image)->interpolate,
8594 if (implode_image != (Image *) NULL)
8596 *image=DestroyImage(*image);
8597 *image=implode_image;
8599 CatchException(exception);
8600 XSetCursorState(display,windows,MagickFalse);
8601 if (windows->image.orphan != MagickFalse)
8603 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8604 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8607 case VignetteCommand:
8613 geometry[MagickPathExtent] =
"0x20";
8618 (void) XDialogWidget(display,windows,
"Vignette",
8619 "Enter the radius, sigma, and x and y offsets:",geometry);
8620 if (*geometry ==
'\0')
8625 XSetCursorState(display,windows,MagickTrue);
8626 XCheckRefreshWindows(display,windows);
8627 flags=ParseGeometry(geometry,&geometry_info);
8628 if ((flags & SigmaValue) == 0)
8629 geometry_info.sigma=1.0;
8630 if ((flags & XiValue) == 0)
8631 geometry_info.xi=0.1*(*image)->columns;
8632 if ((flags & PsiValue) == 0)
8633 geometry_info.psi=0.1*(*image)->rows;
8634 vignette_image=VignetteImage(*image,geometry_info.rho,0.0,(ssize_t)
8635 ceil(geometry_info.xi-0.5),(ssize_t) ceil(geometry_info.psi-0.5),
8637 if (vignette_image != (Image *) NULL)
8639 *image=DestroyImage(*image);
8640 *image=vignette_image;
8642 CatchException(exception);
8643 XSetCursorState(display,windows,MagickFalse);
8644 if (windows->image.orphan != MagickFalse)
8646 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8647 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8656 geometry[MagickPathExtent] =
"25x150";
8661 (void) XDialogWidget(display,windows,
"Wave",
8662 "Enter the amplitude and length of the wave:",geometry);
8663 if (*geometry ==
'\0')
8668 XSetCursorState(display,windows,MagickTrue);
8669 XCheckRefreshWindows(display,windows);
8670 flags=ParseGeometry(geometry,&geometry_info);
8671 if ((flags & SigmaValue) == 0)
8672 geometry_info.sigma=1.0;
8673 wave_image=WaveImage(*image,geometry_info.rho,geometry_info.sigma,
8674 (*image)->interpolate,exception);
8675 if (wave_image != (Image *) NULL)
8677 *image=DestroyImage(*image);
8680 CatchException(exception);
8681 XSetCursorState(display,windows,MagickFalse);
8682 if (windows->image.orphan != MagickFalse)
8684 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8685 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8688 case OilPaintCommand:
8694 radius[MagickPathExtent] =
"0";
8699 (void) XDialogWidget(display,windows,
"Oil Paint",
8700 "Enter the mask radius:",radius);
8701 if (*radius ==
'\0')
8706 XSetCursorState(display,windows,MagickTrue);
8707 XCheckRefreshWindows(display,windows);
8708 flags=ParseGeometry(radius,&geometry_info);
8709 paint_image=OilPaintImage(*image,geometry_info.rho,geometry_info.sigma,
8711 if (paint_image != (Image *) NULL)
8713 *image=DestroyImage(*image);
8716 CatchException(exception);
8717 XSetCursorState(display,windows,MagickFalse);
8718 if (windows->image.orphan != MagickFalse)
8720 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8721 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8724 case CharcoalDrawCommand:
8730 radius[MagickPathExtent] =
"0x1";
8735 (void) XDialogWidget(display,windows,
"Charcoal Draw",
8736 "Enter the charcoal radius and sigma:",radius);
8737 if (*radius ==
'\0')
8742 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
8744 XSetCursorState(display,windows,MagickTrue);
8745 XCheckRefreshWindows(display,windows);
8746 flags=ParseGeometry(radius,&geometry_info);
8747 if ((flags & SigmaValue) == 0)
8748 geometry_info.sigma=geometry_info.rho;
8749 charcoal_image=CharcoalImage(*image,geometry_info.rho,geometry_info.sigma,
8751 if (charcoal_image != (Image *) NULL)
8753 *image=DestroyImage(*image);
8754 *image=charcoal_image;
8756 CatchException(exception);
8757 XSetCursorState(display,windows,MagickFalse);
8758 if (windows->image.orphan != MagickFalse)
8760 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8761 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8764 case AnnotateCommand:
8769 status=XAnnotateEditImage(display,resource_info,windows,*image,exception);
8770 if (status == MagickFalse)
8772 XNoticeWidget(display,windows,
"Unable to annotate X image",
8773 (*image)->filename);
8783 status=XDrawEditImage(display,resource_info,windows,image,exception);
8784 if (status == MagickFalse)
8786 XNoticeWidget(display,windows,
"Unable to draw on the X image",
8787 (*image)->filename);
8797 status=XColorEditImage(display,resource_info,windows,image,exception);
8798 if (status == MagickFalse)
8800 XNoticeWidget(display,windows,
"Unable to pixel edit X image",
8801 (*image)->filename);
8811 status=XMatteEditImage(display,resource_info,windows,image,exception);
8812 if (status == MagickFalse)
8814 XNoticeWidget(display,windows,
"Unable to matte edit X image",
8815 (*image)->filename);
8820 case CompositeCommand:
8825 status=XCompositeImage(display,resource_info,windows,*image,
8827 if (status == MagickFalse)
8829 XNoticeWidget(display,windows,
"Unable to composite X image",
8830 (*image)->filename);
8835 case AddBorderCommand:
8841 geometry[MagickPathExtent] =
"6x6";
8846 XColorBrowserWidget(display,windows,
"Select",color);
8849 (void) XDialogWidget(display,windows,
"Add Border",
8850 "Enter border geometry:",geometry);
8851 if (*geometry ==
'\0')
8856 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
8858 XSetCursorState(display,windows,MagickTrue);
8859 XCheckRefreshWindows(display,windows);
8860 (void) QueryColorCompliance(color,AllCompliance,&(*image)->border_color,
8862 (void) ParsePageGeometry(*image,geometry,&page_geometry,
8864 border_image=BorderImage(*image,&page_geometry,(*image)->compose,
8866 if (border_image != (Image *) NULL)
8868 *image=DestroyImage(*image);
8869 *image=border_image;
8871 CatchException(exception);
8872 XSetCursorState(display,windows,MagickFalse);
8873 if (windows->image.orphan != MagickFalse)
8875 windows->image.window_changes.width=(int) (*image)->columns;
8876 windows->image.window_changes.height=(int) (*image)->rows;
8877 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8878 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8881 case AddFrameCommand:
8890 geometry[MagickPathExtent] =
"6x6";
8895 XColorBrowserWidget(display,windows,
"Select",color);
8898 (void) XDialogWidget(display,windows,
"Add Frame",
"Enter frame geometry:",
8900 if (*geometry ==
'\0')
8905 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
8907 XSetCursorState(display,windows,MagickTrue);
8908 XCheckRefreshWindows(display,windows);
8909 (void) QueryColorCompliance(color,AllCompliance,&(*image)->matte_color,
8911 (void) ParsePageGeometry(*image,geometry,&page_geometry,
8913 frame_info.width=page_geometry.width;
8914 frame_info.height=page_geometry.height;
8915 frame_info.outer_bevel=page_geometry.x;
8916 frame_info.inner_bevel=page_geometry.y;
8917 frame_info.x=(ssize_t) frame_info.width;
8918 frame_info.y=(ssize_t) frame_info.height;
8919 frame_info.width=(*image)->columns+2*frame_info.width;
8920 frame_info.height=(*image)->rows+2*frame_info.height;
8921 frame_image=FrameImage(*image,&frame_info,(*image)->compose,exception);
8922 if (frame_image != (Image *) NULL)
8924 *image=DestroyImage(*image);
8927 CatchException(exception);
8928 XSetCursorState(display,windows,MagickFalse);
8929 if (windows->image.orphan != MagickFalse)
8931 windows->image.window_changes.width=(int) (*image)->columns;
8932 windows->image.window_changes.height=(int) (*image)->rows;
8933 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8934 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8937 case CommentCommand:
8951 unique_file=AcquireUniqueFileResource(image_info->filename);
8952 if (unique_file == -1)
8954 XNoticeWidget(display,windows,
"Unable to edit image comment",
8955 image_info->filename);
8958 value=GetImageProperty(*image,
"comment",exception);
8959 if (value == (
char *) NULL)
8960 unique_file=close_utf8(unique_file)-1;
8966 file=fdopen(unique_file,
"w");
8967 if (file == (FILE *) NULL)
8969 XNoticeWidget(display,windows,
"Unable to edit image comment",
8970 image_info->filename);
8973 for (p=value; *p !=
'\0'; p++)
8974 (
void) fputc((
int) *p,file);
8975 (void) fputc(
'\n',file);
8976 (void) fclose(file);
8978 XSetCursorState(display,windows,MagickTrue);
8979 XCheckRefreshWindows(display,windows);
8980 status=InvokeDelegate(image_info,*image,
"edit",(
char *) NULL,
8982 if (status == MagickFalse)
8983 XNoticeWidget(display,windows,
"Unable to edit image comment",
8990 comment=FileToString(image_info->filename,~0UL,exception);
8991 if (comment != (
char *) NULL)
8993 (void) SetImageProperty(*image,
"comment",comment,exception);
8994 (*image)->taint=MagickTrue;
8997 (void) RelinquishUniqueFileResource(image_info->filename);
8998 XSetCursorState(display,windows,MagickFalse);
9006 XSetCursorState(display,windows,MagickTrue);
9007 XCheckRefreshWindows(display,windows);
9008 (void) AcquireUniqueFilename(filename);
9009 (void) FormatLocaleString((*image)->filename,MagickPathExtent,
"launch:%s",
9011 status=WriteImage(image_info,*image,exception);
9012 if (status == MagickFalse)
9013 XNoticeWidget(display,windows,
"Unable to launch image editor",
9017 nexus=ReadImage(resource_info->image_info,exception);
9018 CatchException(exception);
9019 XClientMessage(display,windows->image.id,windows->im_protocols,
9020 windows->im_next_image,CurrentTime);
9022 (void) RelinquishUniqueFileResource(filename);
9023 XSetCursorState(display,windows,MagickFalse);
9026 case RegionOfInterestCommand:
9031 (void) XROIImage(display,resource_info,windows,image,exception);
9041 if (windows->magnify.mapped != MagickFalse)
9042 (void) XRaiseWindow(display,windows->magnify.id);
9048 XSetCursorState(display,windows,MagickTrue);
9049 (void) XMapRaised(display,windows->magnify.id);
9050 XSetCursorState(display,windows,MagickFalse);
9054 case ShowPreviewCommand:
9066 preview_type[MagickPathExtent] =
"Gamma";
9071 previews=GetCommandOptions(MagickPreviewOptions);
9072 if (previews == (
char **) NULL)
9074 XListBrowserWidget(display,windows,&windows->widget,
9075 (
const char **) previews,
"Preview",
9076 "Select an enhancement, effect, or F/X:",preview_type);
9077 previews=DestroyStringList(previews);
9078 if (*preview_type ==
'\0')
9083 XSetCursorState(display,windows,MagickTrue);
9084 XCheckRefreshWindows(display,windows);
9085 preview=(PreviewType) ParseCommandOption(MagickPreviewOptions,
9086 MagickFalse,preview_type);
9087 (void) FormatImageProperty(*image,
"group",
"%.20g",(
double)
9089 (void) DeleteImageProperty(*image,
"label");
9090 (void) SetImageProperty(*image,
"label",
"Preview",exception);
9091 preview_image=PreviewImage(*image,preview,exception);
9092 if (preview_image == (Image *) NULL)
9094 (void) AcquireUniqueFilename(filename);
9095 (void) FormatLocaleString(preview_image->filename,MagickPathExtent,
9096 "show:%s",filename);
9097 status=WriteImage(image_info,preview_image,exception);
9098 (void) RelinquishUniqueFileResource(filename);
9099 preview_image=DestroyImage(preview_image);
9100 if (status == MagickFalse)
9101 XNoticeWidget(display,windows,
"Unable to show image preview",
9102 (*image)->filename);
9103 XDelay(display,1500);
9104 XSetCursorState(display,windows,MagickFalse);
9107 case ShowHistogramCommand:
9115 XSetCursorState(display,windows,MagickTrue);
9116 XCheckRefreshWindows(display,windows);
9117 (void) DeleteImageProperty(*image,
"label");
9118 (void) FormatImageProperty(*image,
"group",
"%.20g",(
double)
9120 (void) SetImageProperty(*image,
"label",
"Histogram",exception);
9121 (void) AcquireUniqueFilename(filename);
9122 (void) FormatLocaleString((*image)->filename,MagickPathExtent,
9123 "histogram:%s",filename);
9124 status=WriteImage(image_info,*image,exception);
9125 (void) CopyMagickString(image_info->filename,filename,MagickPathExtent);
9126 histogram_image=ReadImage(image_info,exception);
9127 (void) RelinquishUniqueFileResource(filename);
9128 if (histogram_image == (Image *) NULL)
9130 (void) FormatLocaleString(histogram_image->filename,MagickPathExtent,
9131 "show:%s",filename);
9132 status=WriteImage(image_info,histogram_image,exception);
9133 histogram_image=DestroyImage(histogram_image);
9134 if (status == MagickFalse)
9135 XNoticeWidget(display,windows,
"Unable to show histogram",
9136 (*image)->filename);
9137 XDelay(display,1500);
9138 XSetCursorState(display,windows,MagickFalse);
9141 case ShowMatteCommand:
9146 if ((*image)->alpha_trait == UndefinedPixelTrait)
9148 XNoticeWidget(display,windows,
9149 "Image does not have any matte information",(*image)->filename);
9155 XSetCursorState(display,windows,MagickTrue);
9156 XCheckRefreshWindows(display,windows);
9157 (void) FormatImageProperty(*image,
"group",
"%.20g",(
double)
9159 (void) DeleteImageProperty(*image,
"label");
9160 (void) SetImageProperty(*image,
"label",
"Matte",exception);
9161 (void) AcquireUniqueFilename(filename);
9162 (void) FormatLocaleString((*image)->filename,MagickPathExtent,
"matte:%s",
9164 status=WriteImage(image_info,*image,exception);
9165 (void) CopyMagickString(image_info->filename,filename,MagickPathExtent);
9166 matte_image=ReadImage(image_info,exception);
9167 (void) RelinquishUniqueFileResource(filename);
9168 if (matte_image == (Image *) NULL)
9170 (void) FormatLocaleString(matte_image->filename,MagickPathExtent,
9171 "show:%s",filename);
9172 status=WriteImage(image_info,matte_image,exception);
9173 matte_image=DestroyImage(matte_image);
9174 if (status == MagickFalse)
9175 XNoticeWidget(display,windows,
"Unable to show matte",
9176 (*image)->filename);
9177 XDelay(display,1500);
9178 XSetCursorState(display,windows,MagickFalse);
9181 case BackgroundCommand:
9186 status=XBackgroundImage(display,resource_info,windows,image,exception);
9187 if (status == MagickFalse)
9189 nexus=CloneImage(*image,0,0,MagickTrue,exception);
9190 if (nexus != (Image *) NULL)
9191 XClientMessage(display,windows->image.id,windows->im_protocols,
9192 windows->im_next_image,CurrentTime);
9195 case SlideShowCommand:
9198 delay[MagickPathExtent] =
"5";
9203 (void) XDialogWidget(display,windows,
"Slide Show",
9204 "Pause how many 1/100ths of a second between images:",delay);
9207 resource_info->delay=StringToUnsignedLong(delay);
9208 XClientMessage(display,windows->image.id,windows->im_protocols,
9209 windows->im_next_image,CurrentTime);
9212 case PreferencesCommand:
9217 status=XPreferencesWidget(display,resource_info,windows);
9218 if (status == MagickFalse)
9220 nexus=CloneImage(*image,0,0,MagickTrue,exception);
9221 if (nexus != (Image *) NULL)
9222 XClientMessage(display,windows->image.id,windows->im_protocols,
9223 windows->im_next_image,CurrentTime);
9231 XTextViewHelp(display,resource_info,windows,MagickFalse,
9232 "Help Viewer - Display",DisplayHelp);
9235 case BrowseDocumentationCommand:
9247 root_window=XRootWindow(display,XDefaultScreen(display));
9248 mozilla_atom=XInternAtom(display,
"_MOZILLA_VERSION",MagickFalse);
9249 mozilla_window=XWindowByProperty(display,root_window,mozilla_atom);
9250 if (mozilla_window != (Window) NULL)
9253 command[MagickPathExtent];
9258 (void) FormatLocaleString(command,MagickPathExtent,
9259 "openurl(%s,new-tab)",MagickAuthoritativeURL);
9260 mozilla_atom=XInternAtom(display,
"_MOZILLA_COMMAND",MagickFalse);
9261 (void) XChangeProperty(display,mozilla_window,mozilla_atom,XA_STRING,
9262 8,PropModeReplace,(
unsigned char *) command,(
int) strlen(command));
9263 XSetCursorState(display,windows,MagickFalse);
9266 XSetCursorState(display,windows,MagickTrue);
9267 XCheckRefreshWindows(display,windows);
9268 status=InvokeDelegate(image_info,*image,
"browse",(
char *) NULL,
9270 if (status == MagickFalse)
9271 XNoticeWidget(display,windows,
"Unable to browse documentation",
9273 XDelay(display,1500);
9274 XSetCursorState(display,windows,MagickFalse);
9277 case VersionCommand:
9279 XNoticeWidget(display,windows,GetMagickVersion((
size_t *) NULL),
9280 GetMagickCopyright());
9283 case SaveToUndoBufferCommand:
9287 (void) XBell(display,0);
9291 image_info=DestroyImageInfo(image_info);
9327static void XMagnifyImage(Display *display,XWindows *windows,XEvent *event,
9328 ExceptionInfo *exception)
9331 text[MagickPathExtent];
9343 (void) XCheckDefineCursor(display,windows->image.id,windows->magnify.cursor);
9347 windows->magnify.x=(int) windows->image.x+x;
9348 windows->magnify.y=(int) windows->image.y+y;
9354 if (windows->info.mapped != MagickFalse)
9356 if ((x < (windows->info.x+(
int) windows->info.width)) &&
9357 (y < (windows->info.y+(
int) windows->info.height)))
9358 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
9361 if ((x > (windows->info.x+(
int) windows->info.width)) ||
9362 (y > (windows->info.y+(
int) windows->info.height)))
9363 (void) XMapWindow(display,windows->info.id);
9364 if (windows->info.mapped != MagickFalse)
9369 (void) FormatLocaleString(text,MagickPathExtent,
" %+d%+d ",
9370 windows->magnify.x,windows->magnify.y);
9371 XInfoWidget(display,windows,text);
9376 XScreenEvent(display,windows,event,exception);
9377 switch (event->type)
9408 if (x >= (
int) windows->image.width)
9409 x=(int) windows->image.width-1;
9413 if (y >= (
int) windows->image.height)
9414 y=(int) windows->image.height-1;
9415 }
while ((state & ExitState) == 0);
9419 XSetCursorState(display,windows,MagickFalse);
9457static void XMagnifyWindowCommand(Display *display,XWindows *windows,
9458 const MagickStatusType state,
const KeySym key_symbol,ExceptionInfo *exception)
9467 if ((state & Mod1Mask) != 0)
9469 switch ((
int) key_symbol)
9473 (void) XWithdrawWindow(display,windows->magnify.id,
9474 windows->magnify.screen);
9480 windows->magnify.x=(int) windows->image.width/2;
9481 windows->magnify.y=(int) windows->image.height/2;
9487 if (windows->magnify.x > 0)
9488 windows->magnify.x-=(int) quantum;
9494 if (windows->magnify.y > 0)
9495 windows->magnify.y-=(int) quantum;
9501 if (windows->magnify.x < (
int) (windows->image.ximage->width-1))
9502 windows->magnify.x+=(int) quantum;
9508 if (windows->magnify.y < (
int) (windows->image.ximage->height-1))
9509 windows->magnify.y+=(int) quantum;
9523 windows->magnify.data=(key_symbol-XK_0);
9537 windows->magnify.data=(key_symbol-XK_KP_0);
9543 XMakeMagnifyImage(display,windows,exception);
9579static void XMakePanImage(Display *display,XResourceInfo *resource_info,
9580 XWindows *windows,Image *image,ExceptionInfo *exception)
9588 XSetCursorState(display,windows,MagickTrue);
9589 XCheckRefreshWindows(display,windows);
9590 windows->pan.x=(int) windows->image.x;
9591 windows->pan.y=(int) windows->image.y;
9592 status=XMakeImage(display,resource_info,&windows->pan,image,
9593 windows->pan.width,windows->pan.height,exception);
9594 if (status == MagickFalse)
9595 ThrowXWindowException(ResourceLimitError,
"MemoryAllocationFailed",
9597 (void) XSetWindowBackgroundPixmap(display,windows->pan.id,
9598 windows->pan.pixmap);
9599 (void) XClearWindow(display,windows->pan.id);
9600 XDrawPanRectangle(display,windows);
9601 XSetCursorState(display,windows,MagickFalse);
9639static MagickBooleanType XMatteEditImage(Display *display,
9640 XResourceInfo *resource_info,XWindows *windows,Image **image,
9641 ExceptionInfo *exception)
9644 *
const MatteEditMenu[] =
9657 matte[MagickPathExtent] =
"0";
9659 static const ModeType
9660 MatteEditCommands[] =
9663 MatteEditBorderCommand,
9664 MatteEditFuzzCommand,
9665 MatteEditValueCommand,
9666 MatteEditUndoCommand,
9667 MatteEditHelpCommand,
9668 MatteEditDismissCommand
9672 method = PointMethod;
9675 border_color = { 0, 0, 0, 0, 0, 0 };
9678 command[MagickPathExtent],
9679 text[MagickPathExtent];
9711 (void) CloneString(&windows->command.name,
"Matte Edit");
9712 windows->command.data=4;
9713 (void) XCommandWidget(display,windows,MatteEditMenu,(XEvent *) NULL);
9714 (void) XMapRaised(display,windows->command.id);
9715 XClientMessage(display,windows->image.id,windows->im_protocols,
9716 windows->im_update_widget,CurrentTime);
9720 cursor=XMakeCursor(display,windows->image.id,windows->map_info->colormap,
9721 resource_info->background_color,resource_info->foreground_color);
9722 (void) XCheckDefineCursor(display,windows->image.id,cursor);
9726 XQueryPosition(display,windows->image.id,&x,&y);
9727 (void) XSelectInput(display,windows->image.id,
9728 windows->image.attributes.event_mask | PointerMotionMask);
9732 if (windows->info.mapped != MagickFalse)
9737 (void) FormatLocaleString(text,MagickPathExtent,
" %+d%+d ",
9738 x+windows->image.x,y+windows->image.y);
9739 XInfoWidget(display,windows,text);
9744 XScreenEvent(display,windows,&event,exception);
9745 if (event.xany.window == windows->command.id)
9750 id=XCommandWidget(display,windows,MatteEditMenu,&event);
9753 (void) XCheckDefineCursor(display,windows->image.id,cursor);
9756 switch (MatteEditCommands[
id])
9758 case MatteEditMethod:
9766 methods=GetCommandOptions(MagickMethodOptions);
9767 if (methods == (
char **) NULL)
9769 entry=XMenuWidget(display,windows,MatteEditMenu[
id],
9770 (
const char **) methods,command);
9772 method=(PaintMethod) ParseCommandOption(MagickMethodOptions,
9773 MagickFalse,methods[entry]);
9774 methods=DestroyStringList(methods);
9777 case MatteEditBorderCommand:
9780 *ColorMenu[MaxNumberPens];
9788 for (i=0; i < (int) (MaxNumberPens-2); i++)
9789 ColorMenu[i]=resource_info->pen_colors[i];
9790 ColorMenu[MaxNumberPens-2]=
"Browser...";
9791 ColorMenu[MaxNumberPens-1]=(
const char *) NULL;
9795 pen_number=XMenuWidget(display,windows,MatteEditMenu[
id],
9796 (
const char **) ColorMenu,command);
9799 if (pen_number == (MaxNumberPens-2))
9802 color_name[MagickPathExtent] =
"gray";
9807 resource_info->pen_colors[pen_number]=color_name;
9808 XColorBrowserWidget(display,windows,
"Select",color_name);
9809 if (*color_name ==
'\0')
9815 (void) XParseColor(display,windows->map_info->colormap,
9816 resource_info->pen_colors[pen_number],&border_color);
9819 case MatteEditFuzzCommand:
9834 fuzz[MagickPathExtent];
9839 entry=XMenuWidget(display,windows,MatteEditMenu[
id],FuzzMenu,
9845 (*image)->fuzz=StringToDoubleInterval(FuzzMenu[entry],(
double)
9849 (void) CopyMagickString(fuzz,
"20%",MagickPathExtent);
9850 (void) XDialogWidget(display,windows,
"Ok",
9851 "Enter fuzz factor (0.0 - 99.9%):",fuzz);
9854 (void) ConcatenateMagickString(fuzz,
"%",MagickPathExtent);
9855 (*image)->fuzz=StringToDoubleInterval(fuzz,(
double) QuantumRange+
9859 case MatteEditValueCommand:
9862 *
const MatteMenu[] =
9871 message[MagickPathExtent];
9876 entry=XMenuWidget(display,windows,MatteEditMenu[
id],MatteMenu,
9882 (void) FormatLocaleString(matte,MagickPathExtent,
"%g",
9883 (
double) OpaqueAlpha);
9884 if (LocaleCompare(MatteMenu[entry],
"Transparent") == 0)
9885 (void) FormatLocaleString(matte,MagickPathExtent,
"%g",
9886 (
double) TransparentAlpha);
9889 (void) FormatLocaleString(message,MagickPathExtent,
9890 "Enter matte value (0 - " "%g" "):",(
double) QuantumRange);
9891 (void) XDialogWidget(display,windows,
"Matte",message,matte);
9896 case MatteEditUndoCommand:
9898 (void) XMagickCommand(display,resource_info,windows,UndoCommand,
9902 case MatteEditHelpCommand:
9904 XTextViewHelp(display,resource_info,windows,MagickFalse,
9905 "Help Viewer - Matte Edit",ImageMatteEditHelp);
9908 case MatteEditDismissCommand:
9920 (void) XCheckDefineCursor(display,windows->image.id,cursor);
9927 if (event.xbutton.button != Button1)
9929 if ((event.xbutton.window != windows->image.id) &&
9930 (event.xbutton.window != windows->magnify.id))
9937 (void) XMagickCommand(display,resource_info,windows,
9938 SaveToUndoBufferCommand,image,exception);
9939 state|=UpdateConfigurationState;
9944 if (event.xbutton.button != Button1)
9946 if ((event.xbutton.window != windows->image.id) &&
9947 (event.xbutton.window != windows->magnify.id))
9954 XConfigureImageColormap(display,resource_info,windows,*image,exception);
9955 (void) XConfigureImage(display,resource_info,windows,*image,exception);
9956 XInfoWidget(display,windows,text);
9957 (void) XCheckDefineCursor(display,windows->image.id,cursor);
9958 state&=(
unsigned int) (~UpdateConfigurationState);
9966 command[MagickPathExtent];
9971 if (event.xkey.window == windows->magnify.id)
9976 window=windows->magnify.id;
9977 while (XCheckWindowEvent(display,window,KeyPressMask,&event)) ;
9979 if (event.xkey.window != windows->image.id)
9984 (void) XLookupString((XKeyEvent *) &event.xkey,command,(
int)
9985 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
9986 switch ((
int) key_symbol)
10000 XTextViewHelp(display,resource_info,windows,MagickFalse,
10001 "Help Viewer - Matte Edit",ImageMatteEditHelp);
10006 (void) XBell(display,0);
10019 if (windows->info.mapped != MagickFalse)
10021 if ((x < (windows->info.x+(
int) windows->info.width)) &&
10022 (y < (windows->info.y+(
int) windows->info.height)))
10023 (void) XWithdrawWindow(display,windows->info.id,
10024 windows->info.screen);
10027 if ((x > (windows->info.x+(
int) windows->info.width)) ||
10028 (y > (windows->info.y+(
int) windows->info.height)))
10029 (void) XMapWindow(display,windows->info.id);
10035 if (event.xany.window == windows->magnify.id)
10037 x=windows->magnify.x-windows->image.x;
10038 y=windows->magnify.y-windows->image.y;
10042 if ((state & UpdateConfigurationState) != 0)
10054 (void) XClearArea(display,windows->image.id,x_offset,y_offset,1,1,
10056 XPutPixel(windows->image.ximage,x_offset,y_offset,
10057 windows->pixel_info->background_color.pixel);
10058 width=(
unsigned int) (*image)->columns;
10059 height=(
unsigned int) (*image)->rows;
10062 if (windows->image.crop_geometry != (
char *) NULL)
10063 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,
10065 x_offset=((int) width*(windows->image.x+x_offset)/
10066 windows->image.ximage->width+x);
10067 y_offset=((int) height*(windows->image.y+y_offset)/
10068 windows->image.ximage->height+y);
10069 if ((x_offset < 0) || (y_offset < 0))
10071 if ((x_offset >= (
int) (*image)->columns) ||
10072 (y_offset >= (
int) (*image)->rows))
10074 if (SetImageStorageClass(*image,DirectClass,exception) == MagickFalse)
10075 return(MagickFalse);
10076 if ((*image)->alpha_trait == UndefinedPixelTrait)
10077 (void) SetImageAlphaChannel(*image,OpaqueAlphaChannel,exception);
10078 image_view=AcquireAuthenticCacheView(*image,exception);
10087 q=GetCacheViewAuthenticPixels(image_view,(ssize_t) x_offset,
10088 (ssize_t) y_offset,1,1,exception);
10089 if (q == (Quantum *) NULL)
10091 SetPixelAlpha(*image,(Quantum) StringToLong(matte),q);
10092 (void) SyncCacheViewAuthenticPixels(image_view,exception);
10095 case ReplaceMethod:
10104 (void) GetOneCacheViewVirtualPixelInfo(image_view,(ssize_t)
10105 x_offset,(ssize_t) y_offset,&target,exception);
10106 for (y=0; y < (int) (*image)->rows; y++)
10108 q=GetCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
10109 (*image)->columns,1,exception);
10110 if (q == (Quantum *) NULL)
10112 for (x=0; x < (int) (*image)->columns; x++)
10114 GetPixelInfoPixel(*image,q,&pixel);
10115 if (IsFuzzyEquivalencePixelInfo(&pixel,&target))
10116 SetPixelAlpha(*image,(Quantum) StringToLong(matte),q);
10117 q+=(ptrdiff_t) GetPixelChannels(*image);
10119 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
10124 case FloodfillMethod:
10125 case FillToBorderMethod:
10139 (void) GetOneVirtualPixelInfo(*image,
10140 GetPixelCacheVirtualMethod(*image),(ssize_t) x_offset,(ssize_t)
10141 y_offset,&target,exception);
10142 if (method == FillToBorderMethod)
10144 target.red=(double) ScaleShortToQuantum(
10146 target.green=(double) ScaleShortToQuantum(
10147 border_color.green);
10148 target.blue=(double) ScaleShortToQuantum(
10149 border_color.blue);
10151 draw_info=CloneDrawInfo(resource_info->image_info,
10152 (DrawInfo *) NULL);
10153 draw_info->fill.alpha=(double) ClampToQuantum(
10154 StringToDouble(matte,(
char **) NULL));
10155 channel_mask=SetImageChannelMask(*image,AlphaChannel);
10156 (void) FloodfillPaintImage(*image,draw_info,&target,(ssize_t)
10157 x_offset,(ssize_t) y_offset,
10158 method != FloodfillMethod ? MagickTrue : MagickFalse,exception);
10159 (void) SetPixelChannelMask(*image,channel_mask);
10160 draw_info=DestroyDrawInfo(draw_info);
10168 if (SetImageStorageClass(*image,DirectClass,exception) == MagickFalse)
10169 return(MagickFalse);
10170 for (y=0; y < (int) (*image)->rows; y++)
10172 q=QueueCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
10173 (*image)->columns,1,exception);
10174 if (q == (Quantum *) NULL)
10176 for (x=0; x < (int) (*image)->columns; x++)
10178 SetPixelAlpha(*image,(Quantum) StringToLong(matte),q);
10179 q+=(ptrdiff_t) GetPixelChannels(*image);
10181 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
10184 if (StringToLong(matte) == (
long) OpaqueAlpha)
10185 (*image)->alpha_trait=UndefinedPixelTrait;
10189 image_view=DestroyCacheView(image_view);
10190 state&=(
unsigned int) (~UpdateConfigurationState);
10192 }
while ((state & ExitState) == 0);
10193 (void) XSelectInput(display,windows->image.id,
10194 windows->image.attributes.event_mask);
10195 XSetCursorState(display,windows,MagickFalse);
10196 (void) XFreeCursor(display,cursor);
10197 return(MagickTrue);
10231static Image *XOpenImage(Display *display,XResourceInfo *resource_info,
10232 XWindows *windows,
const MagickBooleanType command)
10247 filename[MagickPathExtent] =
"\0";
10252 if (command == MagickFalse)
10253 XFileBrowserWidget(display,windows,
"Open",filename);
10271 status=XGetCommand(display,windows->image.id,&files,&count);
10274 ThrowXWindowException(XServerError,
"UnableToGetProperty",
"...");
10275 return((Image *) NULL);
10277 filelist=(
char **) AcquireQuantumMemory((
size_t) count,
sizeof(*filelist));
10278 if (filelist == (
char **) NULL)
10280 ThrowXWindowException(ResourceLimitError,
"MemoryAllocationFailed",
10282 (void) XFreeStringList(files);
10283 return((Image *) NULL);
10286 for (i=1; i < count; i++)
10287 if (*files[i] !=
'-')
10288 filelist[j++]=files[i];
10289 filelist[j]=(
char *) NULL;
10290 XListBrowserWidget(display,windows,&windows->widget,
10291 (
const char **) filelist,
"Load",
"Select Image to Load:",filename);
10292 filelist=(
char **) RelinquishMagickMemory(filelist);
10293 (void) XFreeStringList(files);
10295 if (*filename ==
'\0')
10296 return((Image *) NULL);
10297 image_info=CloneImageInfo(resource_info->image_info);
10298 (void) SetImageInfoProgressMonitor(image_info,(MagickProgressMonitor) NULL,
10300 (void) CopyMagickString(image_info->filename,filename,MagickPathExtent);
10301 exception=AcquireExceptionInfo();
10302 (void) SetImageInfo(image_info,0,exception);
10303 if (LocaleCompare(image_info->magick,
"X") == 0)
10306 seconds[MagickPathExtent];
10311 (void) CopyMagickString(seconds,
"0",MagickPathExtent);
10312 (void) XDialogWidget(display,windows,
"Grab",
"Enter any delay in seconds:",
10314 if (*seconds ==
'\0')
10315 return((Image *) NULL);
10316 XDelay(display,(
size_t) (1000*StringToLong(seconds)));
10318 magick_info=GetMagickInfo(image_info->magick,exception);
10319 if ((magick_info != (
const MagickInfo *) NULL) &&
10320 GetMagickRawSupport(magick_info) == MagickTrue)
10323 geometry[MagickPathExtent];
10328 (void) CopyMagickString(geometry,
"512x512",MagickPathExtent);
10329 if (image_info->size != (
char *) NULL)
10330 (void) CopyMagickString(geometry,image_info->size,MagickPathExtent);
10331 (void) XDialogWidget(display,windows,
"Load",
"Enter the image geometry:",
10333 (void) CloneString(&image_info->size,geometry);
10338 XSetCursorState(display,windows,MagickTrue);
10339 XCheckRefreshWindows(display,windows);
10340 (void) CopyMagickString(image_info->filename,filename,MagickPathExtent);
10341 nexus=ReadImage(image_info,exception);
10342 CatchException(exception);
10343 XSetCursorState(display,windows,MagickFalse);
10344 if (nexus != (Image *) NULL)
10345 XClientMessage(display,windows->image.id,windows->im_protocols,
10346 windows->im_next_image,CurrentTime);
10356 text=FileToString(filename,~0UL,exception);
10357 if (text == (
char *) NULL)
10358 return((Image *) NULL);
10359 textlist=StringToList(text);
10360 if (textlist != (
char **) NULL)
10363 title[MagickPathExtent];
10368 (void) FormatLocaleString(title,MagickPathExtent,
10369 "Unknown format: %s",filename);
10370 XTextViewWidget(display,resource_info,windows,MagickTrue,title,
10371 (
const char **) textlist);
10372 for (i=0; textlist[i] != (
char *) NULL; i++)
10373 textlist[i]=DestroyString(textlist[i]);
10374 textlist=(
char **) RelinquishMagickMemory(textlist);
10376 text=DestroyString(text);
10378 exception=DestroyExceptionInfo(exception);
10379 image_info=DestroyImageInfo(image_info);
10414static void XPanImage(Display *display,XWindows *windows,XEvent *event,
10415 ExceptionInfo *exception)
10418 text[MagickPathExtent];
10436 if ((windows->image.ximage->width > (
int) windows->image.width) &&
10437 (windows->image.ximage->height > (
int) windows->image.height))
10438 cursor=XCreateFontCursor(display,XC_fleur);
10440 if (windows->image.ximage->width > (
int) windows->image.width)
10441 cursor=XCreateFontCursor(display,XC_sb_h_double_arrow);
10443 if (windows->image.ximage->height > (
int) windows->image.height)
10444 cursor=XCreateFontCursor(display,XC_sb_v_double_arrow);
10446 cursor=XCreateFontCursor(display,XC_arrow);
10447 (void) XCheckDefineCursor(display,windows->pan.id,cursor);
10451 x_factor=(double) windows->image.ximage->width/windows->pan.width;
10452 y_factor=(double) windows->image.ximage->height/windows->pan.height;
10453 pan_info.width=windows->pan.width*windows->image.width/
10454 (
unsigned int) windows->image.ximage->width;
10455 pan_info.height=windows->pan.height*windows->image.height/
10456 (
unsigned int) windows->image.ximage->height;
10459 state=UpdateConfigurationState;
10462 switch (event->type)
10469 pan_info.x=(ssize_t) event->xbutton.x;
10470 pan_info.y=(ssize_t) event->xbutton.y;
10471 state|=UpdateConfigurationState;
10474 case ButtonRelease:
10479 pan_info.x=(ssize_t) event->xbutton.x;
10480 pan_info.y=(ssize_t) event->xbutton.y;
10481 state|=UpdateConfigurationState | ExitState;
10486 pan_info.x=(ssize_t) event->xmotion.x;
10487 pan_info.y=(ssize_t) event->xmotion.y;
10488 state|=UpdateConfigurationState;
10493 if ((state & UpdateConfigurationState) != 0)
10498 if (pan_info.x < (ssize_t) (pan_info.width/2))
10501 pan_info.x=(ssize_t) (x_factor*(pan_info.x-((
int) pan_info.width/2)));
10502 if (pan_info.x < 0)
10505 if ((
int) (pan_info.x+windows->image.width) >
10506 windows->image.ximage->width)
10507 pan_info.x=(ssize_t) (windows->image.ximage->width-(
int) windows->image.width);
10508 if (pan_info.y < (ssize_t) (pan_info.height/2))
10511 pan_info.y=(ssize_t) (y_factor*(pan_info.y-((
int) pan_info.height/2)));
10512 if (pan_info.y < 0)
10515 if ((
int) (pan_info.y+windows->image.height) >
10516 windows->image.ximage->height)
10517 pan_info.y=(ssize_t) (windows->image.ximage->height-(
int)
10518 windows->image.height);
10519 if ((windows->image.x != (
int) pan_info.x) ||
10520 (windows->image.y != (
int) pan_info.y))
10525 windows->image.x=(int) pan_info.x;
10526 windows->image.y=(int) pan_info.y;
10527 (void) FormatLocaleString(text,MagickPathExtent,
" %ux%u%+d%+d ",
10528 windows->image.width,windows->image.height,windows->image.x,
10530 XInfoWidget(display,windows,text);
10534 XDrawPanRectangle(display,windows);
10535 XRefreshWindow(display,&windows->image,(XEvent *) NULL);
10537 state&=(
unsigned int) (~UpdateConfigurationState);
10542 if ((state & ExitState) == 0)
10543 XScreenEvent(display,windows,event,exception);
10544 }
while ((state & ExitState) == 0);
10548 (void) XCheckDefineCursor(display,windows->pan.id,windows->pan.cursor);
10549 (void) XFreeCursor(display,cursor);
10550 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
10587static MagickBooleanType XPasteImage(Display *display,
10588 XResourceInfo *resource_info,XWindows *windows,Image *image,
10589 ExceptionInfo *exception)
10592 *
const PasteMenu[] =
10600 static const ModeType
10603 PasteOperatorsCommand,
10605 PasteDismissCommand
10608 static CompositeOperator
10609 compose = CopyCompositeOp;
10612 text[MagickPathExtent];
10646 if (resource_info->copy_image == (Image *) NULL)
10647 return(MagickFalse);
10648 paste_image=CloneImage(resource_info->copy_image,0,0,MagickTrue,exception);
10649 if (paste_image == (Image *) NULL)
10650 return(MagickFalse);
10654 (void) CloneString(&windows->command.name,
"Paste");
10655 windows->command.data=1;
10656 (void) XCommandWidget(display,windows,PasteMenu,(XEvent *) NULL);
10657 (void) XMapRaised(display,windows->command.id);
10658 XClientMessage(display,windows->image.id,windows->im_protocols,
10659 windows->im_update_widget,CurrentTime);
10663 XSetCursorState(display,windows,MagickFalse);
10664 XQueryPosition(display,windows->image.id,&x,&y);
10665 (void) XSelectInput(display,windows->image.id,
10666 windows->image.attributes.event_mask | PointerMotionMask);
10667 paste_info.x=(ssize_t) windows->image.x+x;
10668 paste_info.y=(ssize_t) windows->image.y+y;
10669 paste_info.width=0;
10670 paste_info.height=0;
10671 cursor=XCreateFontCursor(display,XC_ul_angle);
10672 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
10673 state=DefaultState;
10676 if (windows->info.mapped != MagickFalse)
10681 (void) FormatLocaleString(text,MagickPathExtent,
" %+ld%+ld ",
10682 (
long) paste_info.x,(
long) paste_info.y);
10683 XInfoWidget(display,windows,text);
10685 highlight_info=paste_info;
10686 highlight_info.x=paste_info.x-windows->image.x;
10687 highlight_info.y=paste_info.y-windows->image.y;
10688 XHighlightRectangle(display,windows->image.id,
10689 windows->image.highlight_context,&highlight_info);
10693 XScreenEvent(display,windows,&event,exception);
10694 XHighlightRectangle(display,windows->image.id,
10695 windows->image.highlight_context,&highlight_info);
10696 if (event.xany.window == windows->command.id)
10701 id=XCommandWidget(display,windows,PasteMenu,&event);
10704 switch (PasteCommands[
id])
10706 case PasteOperatorsCommand:
10709 command[MagickPathExtent],
10715 operators=GetCommandOptions(MagickComposeOptions);
10716 if (operators == (
char **) NULL)
10718 entry=XMenuWidget(display,windows,PasteMenu[
id],
10719 (
const char **) operators,command);
10721 compose=(CompositeOperator) ParseCommandOption(
10722 MagickComposeOptions,MagickFalse,operators[entry]);
10723 operators=DestroyStringList(operators);
10726 case PasteHelpCommand:
10728 XTextViewHelp(display,resource_info,windows,MagickFalse,
10729 "Help Viewer - Image Composite",ImagePasteHelp);
10732 case PasteDismissCommand:
10737 state|=EscapeState;
10746 switch (event.type)
10750 if (resource_info->debug != MagickFalse)
10751 (void) LogMagickEvent(X11Event,GetMagickModule(),
10752 "Button Press: 0x%lx %u +%d+%d",event.xbutton.window,
10753 event.xbutton.button,event.xbutton.x,event.xbutton.y);
10754 if (event.xbutton.button != Button1)
10756 if (event.xbutton.window != windows->image.id)
10761 width=(
unsigned int) image->columns;
10762 height=(
unsigned int) image->rows;
10765 if (windows->image.crop_geometry != (
char *) NULL)
10766 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
10768 scale_factor=(double) windows->image.ximage->width/width;
10769 paste_info.width=(
unsigned int) (scale_factor*paste_image->columns+0.5);
10770 scale_factor=(double) windows->image.ximage->height/height;
10771 paste_info.height=(
unsigned int) (scale_factor*paste_image->rows+0.5);
10772 (void) XCheckDefineCursor(display,windows->image.id,cursor);
10773 paste_info.x=(ssize_t) windows->image.x+event.xbutton.x;
10774 paste_info.y=(ssize_t) windows->image.y+event.xbutton.y;
10777 case ButtonRelease:
10779 if (resource_info->debug != MagickFalse)
10780 (void) LogMagickEvent(X11Event,GetMagickModule(),
10781 "Button Release: 0x%lx %u +%d+%d",event.xbutton.window,
10782 event.xbutton.button,event.xbutton.x,event.xbutton.y);
10783 if (event.xbutton.button != Button1)
10785 if (event.xbutton.window != windows->image.id)
10787 if ((paste_info.width != 0) && (paste_info.height != 0))
10792 paste_info.x=(ssize_t) windows->image.x+event.xbutton.x;
10793 paste_info.y=(ssize_t) windows->image.y+event.xbutton.y;
10803 command[MagickPathExtent];
10811 if (event.xkey.window != windows->image.id)
10816 length=XLookupString((XKeyEvent *) &event.xkey,command,(
int)
10817 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
10818 *(command+length)=
'\0';
10819 if (resource_info->debug != MagickFalse)
10820 (void) LogMagickEvent(X11Event,GetMagickModule(),
10821 "Key press: 0x%lx (%s)",(
long) key_symbol,command);
10822 switch ((
int) key_symbol)
10830 paste_image=DestroyImage(paste_image);
10831 state|=EscapeState;
10838 (void) XSetFunction(display,windows->image.highlight_context,
10840 XTextViewHelp(display,resource_info,windows,MagickFalse,
10841 "Help Viewer - Image Composite",ImagePasteHelp);
10842 (void) XSetFunction(display,windows->image.highlight_context,
10848 (void) XBell(display,0);
10861 if (windows->info.mapped != MagickFalse)
10863 if ((x < (windows->info.x+(
int) windows->info.width)) &&
10864 (y < (windows->info.y+(
int) windows->info.height)))
10865 (void) XWithdrawWindow(display,windows->info.id,
10866 windows->info.screen);
10869 if ((x > (windows->info.x+(
int) windows->info.width)) ||
10870 (y > (windows->info.y+(
int) windows->info.height)))
10871 (void) XMapWindow(display,windows->info.id);
10872 paste_info.x=(ssize_t) windows->image.x+x;
10873 paste_info.y=(ssize_t) windows->image.y+y;
10878 if (resource_info->debug != MagickFalse)
10879 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Event type: %d",
10884 }
while ((state & ExitState) == 0);
10885 (void) XSelectInput(display,windows->image.id,
10886 windows->image.attributes.event_mask);
10887 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
10888 XSetCursorState(display,windows,MagickFalse);
10889 (void) XFreeCursor(display,cursor);
10890 if ((state & EscapeState) != 0)
10891 return(MagickTrue);
10895 XSetCursorState(display,windows,MagickTrue);
10896 XCheckRefreshWindows(display,windows);
10897 width=(
unsigned int) image->columns;
10898 height=(
unsigned int) image->rows;
10901 if (windows->image.crop_geometry != (
char *) NULL)
10902 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
10903 scale_factor=(double) width/windows->image.ximage->width;
10905 paste_info.x=(ssize_t) (scale_factor*paste_info.x+0.5);
10906 paste_info.width=(
unsigned int) (scale_factor*paste_info.width+0.5);
10907 scale_factor=(double) height/windows->image.ximage->height;
10909 paste_info.y=(ssize_t) (scale_factor*paste_info.y*scale_factor+0.5);
10910 paste_info.height=(
unsigned int) (scale_factor*paste_info.height+0.5);
10914 (void) CompositeImage(image,paste_image,compose,MagickTrue,paste_info.x,
10915 paste_info.y,exception);
10916 paste_image=DestroyImage(paste_image);
10917 XSetCursorState(display,windows,MagickFalse);
10921 XConfigureImageColormap(display,resource_info,windows,image,exception);
10922 (void) XConfigureImage(display,resource_info,windows,image,exception);
10923 return(MagickTrue);
10959static MagickBooleanType XPrintImage(Display *display,
10960 XResourceInfo *resource_info,XWindows *windows,Image *image,
10961 ExceptionInfo *exception)
10964 filename[MagickPathExtent],
10965 geometry[MagickPathExtent];
10968 *
const PageSizes[] =
10999 image_info=CloneImageInfo(resource_info->image_info);
11000 (void) FormatLocaleString(geometry,MagickPathExtent,
"Letter");
11001 if (image_info->page != (
char *) NULL)
11002 (void) CopyMagickString(geometry,image_info->page,MagickPathExtent);
11003 XListBrowserWidget(display,windows,&windows->widget,PageSizes,
"Select",
11004 "Select Postscript Page Geometry:",geometry);
11005 if (*geometry ==
'\0')
11006 return(MagickTrue);
11007 image_info->page=GetPageGeometry(geometry);
11011 XSetCursorState(display,windows,MagickTrue);
11012 XCheckRefreshWindows(display,windows);
11013 print_image=CloneImage(image,0,0,MagickTrue,exception);
11014 if (print_image == (Image *) NULL)
11015 return(MagickFalse);
11016 (void) FormatLocaleString(geometry,MagickPathExtent,
"%dx%d!",
11017 windows->image.ximage->width,windows->image.ximage->height);
11018 (void) TransformImage(&print_image,windows->image.crop_geometry,geometry,
11023 (void) AcquireUniqueFilename(filename);
11024 (void) FormatLocaleString(print_image->filename,MagickPathExtent,
"print:%s",
11026 status=WriteImage(image_info,print_image,exception);
11027 (void) RelinquishUniqueFileResource(filename);
11028 print_image=DestroyImage(print_image);
11029 image_info=DestroyImageInfo(image_info);
11030 XSetCursorState(display,windows,MagickFalse);
11031 return(status != 0 ? MagickTrue : MagickFalse);
11067static MagickBooleanType XROIImage(Display *display,
11068 XResourceInfo *resource_info,XWindows *windows,Image **image,
11069 ExceptionInfo *exception)
11071#define ApplyMenus 7
11080 *
const ApplyMenu[] =
11093 *
const FileMenu[] =
11099 *
const EditMenu[] =
11105 *
const TransformMenu[] =
11113 *
const EnhanceMenu[] =
11121 "Contrast Stretch...",
11122 "Sigmoidal Contrast...",
11131 *
const EffectsMenu[] =
11156 "Charcoal Draw...",
11159 *
const MiscellanyMenu[] =
11170 *
const *Menus[ApplyMenus] =
11181 static const DisplayCommand
11204 TransformCommands[] =
11208 RotateRightCommand,
11211 EnhanceCommands[] =
11219 ContrastStretchCommand,
11220 SigmoidalContrastCommand,
11228 EffectsCommands[] =
11232 ReduceNoiseCommand,
11252 CharcoalDrawCommand
11254 MiscellanyCommands[] =
11258 ShowPreviewCommand,
11259 ShowHistogramCommand,
11268 static const DisplayCommand
11269 *Commands[ApplyMenus] =
11281 command[MagickPathExtent],
11282 text[MagickPathExtent];
11302 MagickProgressMonitor
11323 (void) CloneString(&windows->command.name,
"ROI");
11324 windows->command.data=0;
11325 (void) XCommandWidget(display,windows,ROIMenu,(XEvent *) NULL);
11326 (void) XMapRaised(display,windows->command.id);
11327 XClientMessage(display,windows->image.id,windows->im_protocols,
11328 windows->im_update_widget,CurrentTime);
11332 XQueryPosition(display,windows->image.id,&x,&y);
11333 (void) XSelectInput(display,windows->image.id,
11334 windows->image.attributes.event_mask | PointerMotionMask);
11335 roi_info.x=(ssize_t) windows->image.x+x;
11336 roi_info.y=(ssize_t) windows->image.y+y;
11339 cursor=XCreateFontCursor(display,XC_fleur);
11340 state=DefaultState;
11343 if (windows->info.mapped != MagickFalse)
11348 (void) FormatLocaleString(text,MagickPathExtent,
" %+ld%+ld ",
11349 (
long) roi_info.x,(
long) roi_info.y);
11350 XInfoWidget(display,windows,text);
11355 XScreenEvent(display,windows,&event,exception);
11356 if (event.xany.window == windows->command.id)
11361 id=XCommandWidget(display,windows,ROIMenu,&event);
11364 switch (ROICommands[
id])
11366 case ROIHelpCommand:
11368 XTextViewHelp(display,resource_info,windows,MagickFalse,
11369 "Help Viewer - Region of Interest",ImageROIHelp);
11372 case ROIDismissCommand:
11377 state|=EscapeState;
11386 switch (event.type)
11390 if (event.xbutton.button != Button1)
11392 if (event.xbutton.window != windows->image.id)
11397 (void) XCheckDefineCursor(display,windows->image.id,cursor);
11398 roi_info.x=(ssize_t) windows->image.x+event.xbutton.x;
11399 roi_info.y=(ssize_t) windows->image.y+event.xbutton.y;
11403 case ButtonRelease:
11412 if (event.xkey.window != windows->image.id)
11417 (void) XLookupString((XKeyEvent *) &event.xkey,command,(
int)
11418 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
11419 switch ((
int) key_symbol)
11427 state|=EscapeState;
11434 XTextViewHelp(display,resource_info,windows,MagickFalse,
11435 "Help Viewer - Region of Interest",ImageROIHelp);
11440 (void) XBell(display,0);
11453 if (windows->info.mapped != MagickFalse)
11455 if ((x < (windows->info.x+(
int) windows->info.width)) &&
11456 (y < (windows->info.y+(
int) windows->info.height)))
11457 (void) XWithdrawWindow(display,windows->info.id,
11458 windows->info.screen);
11461 if ((x > (windows->info.x+(
int) windows->info.width)) ||
11462 (y > (windows->info.y+(
int) windows->info.height)))
11463 (void) XMapWindow(display,windows->info.id);
11464 roi_info.x=(ssize_t) windows->image.x+x;
11465 roi_info.y=(ssize_t) windows->image.y+y;
11471 }
while ((state & ExitState) == 0);
11472 (void) XSelectInput(display,windows->image.id,
11473 windows->image.attributes.event_mask);
11474 if ((state & EscapeState) != 0)
11479 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
11480 (void) XFreeCursor(display,cursor);
11481 return(MagickTrue);
11483 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
11489 x=(int) roi_info.x;
11490 y=(int) roi_info.y;
11493 state=DefaultState;
11496 highlight_info=roi_info;
11497 highlight_info.x=roi_info.x-windows->image.x;
11498 highlight_info.y=roi_info.y-windows->image.y;
11499 if ((highlight_info.width > 3) && (highlight_info.height > 3))
11504 if (windows->info.mapped == MagickFalse)
11505 (void) XMapWindow(display,windows->info.id);
11506 (void) FormatLocaleString(text,MagickPathExtent,
11507 " %.20gx%.20g%+.20g%+.20g",(
double) roi_info.width,(
double)
11508 roi_info.height,(
double) roi_info.x,(
double) roi_info.y);
11509 XInfoWidget(display,windows,text);
11510 XHighlightRectangle(display,windows->image.id,
11511 windows->image.highlight_context,&highlight_info);
11514 if (windows->info.mapped != MagickFalse)
11515 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
11519 XScreenEvent(display,windows,&event,exception);
11520 if ((highlight_info.width > 3) && (highlight_info.height > 3))
11521 XHighlightRectangle(display,windows->image.id,
11522 windows->image.highlight_context,&highlight_info);
11523 switch (event.type)
11527 roi_info.x=(ssize_t) windows->image.x+event.xbutton.x;
11528 roi_info.y=(ssize_t) windows->image.y+event.xbutton.y;
11531 case ButtonRelease:
11536 roi_info.x=(ssize_t) windows->image.x+event.xbutton.x;
11537 roi_info.y=(ssize_t) windows->image.y+event.xbutton.y;
11538 XSetCursorState(display,windows,MagickFalse);
11540 if (LocaleCompare(windows->command.name,
"Apply") == 0)
11542 (void) CloneString(&windows->command.name,
"Apply");
11543 windows->command.data=ApplyMenus;
11544 (void) XCommandWidget(display,windows,ApplyMenu,(XEvent *) NULL);
11551 roi_info.x=(ssize_t) windows->image.x+event.xmotion.x;
11552 roi_info.y=(ssize_t) windows->image.y+event.xmotion.y;
11557 if ((((
int) roi_info.x != x) && ((
int) roi_info.y != y)) ||
11558 ((state & ExitState) != 0))
11563 if (roi_info.x < 0)
11566 if (roi_info.x > (ssize_t) windows->image.ximage->width)
11567 roi_info.x=(ssize_t) windows->image.ximage->width;
11568 if ((
int) roi_info.x < x)
11569 roi_info.width=(
unsigned int) (x-roi_info.x);
11572 roi_info.width=(
unsigned int) (roi_info.x-x);
11573 roi_info.x=(ssize_t) x;
11575 if (roi_info.y < 0)
11578 if (roi_info.y > (ssize_t) windows->image.ximage->height)
11579 roi_info.y=(ssize_t) windows->image.ximage->height;
11580 if ((
int) roi_info.y < y)
11581 roi_info.height=(
unsigned int) (y-roi_info.y);
11584 roi_info.height=(
unsigned int) (roi_info.y-y);
11585 roi_info.y=(ssize_t) y;
11588 }
while ((state & ExitState) == 0);
11592 state=DefaultState;
11593 display_command=NullCommand;
11596 (void) XMapWindow(display,windows->info.id);
11599 if (windows->info.mapped != MagickFalse)
11604 (void) FormatLocaleString(text,MagickPathExtent,
11605 " %.20gx%.20g%+.20g%+.20g",(
double) roi_info.width,(
double)
11606 roi_info.height,(
double) roi_info.x,(
double) roi_info.y);
11607 XInfoWidget(display,windows,text);
11609 highlight_info=roi_info;
11610 highlight_info.x=roi_info.x-windows->image.x;
11611 highlight_info.y=roi_info.y-windows->image.y;
11612 if ((highlight_info.width <= 3) || (highlight_info.height <= 3))
11614 state|=EscapeState;
11618 if ((state & UpdateRegionState) != 0)
11620 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
11621 switch (display_command)
11626 (void) XMagickCommand(display,resource_info,windows,
11627 display_command,image,exception);
11635 progress_monitor=SetImageProgressMonitor(*image,
11636 (MagickProgressMonitor) NULL,(*image)->client_data);
11637 crop_info=roi_info;
11638 width=(
unsigned int) (*image)->columns;
11639 height=(
unsigned int) (*image)->rows;
11642 if (windows->image.crop_geometry != (
char *) NULL)
11643 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
11645 scale_factor=(double) width/windows->image.ximage->width;
11647 crop_info.x=(ssize_t) (scale_factor*crop_info.x+0.5);
11648 crop_info.width=(
unsigned int) (scale_factor*crop_info.width+0.5);
11649 scale_factor=(double)
11650 height/windows->image.ximage->height;
11652 crop_info.y=(ssize_t) (scale_factor*crop_info.y+0.5);
11653 crop_info.height=(
unsigned int)
11654 (scale_factor*crop_info.height+0.5);
11655 roi_image=CropImage(*image,&crop_info,exception);
11656 (void) SetImageProgressMonitor(*image,progress_monitor,
11657 (*image)->client_data);
11658 if (roi_image == (Image *) NULL)
11663 windows->image.orphan=MagickTrue;
11664 (void) XMagickCommand(display,resource_info,windows,
11665 display_command,&roi_image,exception);
11666 progress_monitor=SetImageProgressMonitor(*image,
11667 (MagickProgressMonitor) NULL,(*image)->client_data);
11668 (void) XMagickCommand(display,resource_info,windows,
11669 SaveToUndoBufferCommand,image,exception);
11670 windows->image.orphan=MagickFalse;
11671 (void) CompositeImage(*image,roi_image,CopyCompositeOp,
11672 MagickTrue,crop_info.x,crop_info.y,exception);
11673 roi_image=DestroyImage(roi_image);
11674 (void) SetImageProgressMonitor(*image,progress_monitor,
11675 (*image)->client_data);
11679 if (display_command != InfoCommand)
11681 XConfigureImageColormap(display,resource_info,windows,*image,
11683 (void) XConfigureImage(display,resource_info,windows,*image,
11686 XCheckRefreshWindows(display,windows);
11687 XInfoWidget(display,windows,text);
11688 (void) XSetFunction(display,windows->image.highlight_context,
11690 state&=(
unsigned int) (~UpdateRegionState);
11692 XHighlightRectangle(display,windows->image.id,
11693 windows->image.highlight_context,&highlight_info);
11694 XScreenEvent(display,windows,&event,exception);
11695 if (event.xany.window == windows->command.id)
11700 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
11701 display_command=NullCommand;
11702 id=XCommandWidget(display,windows,ApplyMenu,&event);
11705 (void) CopyMagickString(command,ApplyMenu[
id],MagickPathExtent);
11706 display_command=ApplyCommands[id];
11707 if (
id < ApplyMenus)
11712 entry=XMenuWidget(display,windows,ApplyMenu[
id],
11713 (
const char **) Menus[
id],command);
11716 (void) CopyMagickString(command,Menus[
id][entry],
11718 display_command=Commands[id][entry];
11722 (void) XSetFunction(display,windows->image.highlight_context,
11724 XHighlightRectangle(display,windows->image.id,
11725 windows->image.highlight_context,&highlight_info);
11726 if (display_command == HelpCommand)
11728 (void) XSetFunction(display,windows->image.highlight_context,
11730 XTextViewHelp(display,resource_info,windows,MagickFalse,
11731 "Help Viewer - Region of Interest",ImageROIHelp);
11732 (void) XSetFunction(display,windows->image.highlight_context,
11736 if (display_command == QuitCommand)
11741 state|=EscapeState;
11745 if (display_command != NullCommand)
11746 state|=UpdateRegionState;
11749 XHighlightRectangle(display,windows->image.id,
11750 windows->image.highlight_context,&highlight_info);
11751 switch (event.type)
11755 x=windows->image.x;
11756 y=windows->image.y;
11757 if (event.xbutton.button != Button1)
11759 if (event.xbutton.window != windows->image.id)
11761 x=windows->image.x+
event.xbutton.x;
11762 y=windows->image.y+
event.xbutton.y;
11763 if ((x < (
int) (roi_info.x+RoiDelta)) &&
11764 (x > (
int) (roi_info.x-RoiDelta)) &&
11765 (y < (
int) (roi_info.y+RoiDelta)) &&
11766 (y > (
int) (roi_info.y-RoiDelta)))
11768 roi_info.x=roi_info.x+(int) roi_info.width;
11769 roi_info.y=roi_info.y+(int) roi_info.height;
11770 state|=UpdateConfigurationState;
11773 if ((x < (
int) (roi_info.x+RoiDelta)) &&
11774 (x > (
int) (roi_info.x-RoiDelta)) &&
11775 (y < (
int) (roi_info.y+(
int) roi_info.height+RoiDelta)) &&
11776 (y > (
int) (roi_info.y+(
int) roi_info.height-RoiDelta)))
11778 roi_info.x=roi_info.x+(int) roi_info.width;
11779 state|=UpdateConfigurationState;
11782 if ((x < (
int) (roi_info.x+(
int) roi_info.width+RoiDelta)) &&
11783 (x > (
int) (roi_info.x+(
int) roi_info.width-RoiDelta)) &&
11784 (y < (
int) (roi_info.y+RoiDelta)) &&
11785 (y > (
int) (roi_info.y-RoiDelta)))
11787 roi_info.y=roi_info.y+(int) roi_info.height;
11788 state|=UpdateConfigurationState;
11791 if ((x < (
int) (roi_info.x+(
int) roi_info.width+RoiDelta)) &&
11792 (x > (
int) (roi_info.x+(
int) roi_info.width-RoiDelta)) &&
11793 (y < (
int) (roi_info.y+(
int) roi_info.height+RoiDelta)) &&
11794 (y > (
int) (roi_info.y+(
int) roi_info.height-RoiDelta)))
11796 state|=UpdateConfigurationState;
11799 magick_fallthrough;
11801 case ButtonRelease:
11803 if (event.xbutton.window == windows->pan.id)
11804 if ((highlight_info.x != crop_info.x-windows->image.x) ||
11805 (highlight_info.y != crop_info.y-windows->image.y))
11806 XHighlightRectangle(display,windows->image.id,
11807 windows->image.highlight_context,&highlight_info);
11808 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id,
11809 event.xbutton.time);
11814 if (event.xexpose.window == windows->image.id)
11815 if (event.xexpose.count == 0)
11817 event.xexpose.x=(int) highlight_info.x;
11818 event.xexpose.y=(int) highlight_info.y;
11819 event.xexpose.width=(int) highlight_info.width;
11820 event.xexpose.height=(int) highlight_info.height;
11821 XRefreshWindow(display,&windows->image,&event);
11823 if (event.xexpose.window == windows->info.id)
11824 if (event.xexpose.count == 0)
11825 XInfoWidget(display,windows,text);
11833 if (event.xkey.window != windows->image.id)
11838 (void) XLookupString((XKeyEvent *) &event.xkey,command,(
int)
11839 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
11840 switch ((
int) key_symbol)
11848 state|=EscapeState;
11849 magick_fallthrough;
11859 roi_info.x=(ssize_t) (windows->image.width/2L-roi_info.width/2L);
11860 roi_info.y=(ssize_t) (windows->image.height/2L-
11861 roi_info.height/2L);
11893 (void) XSetFunction(display,windows->image.highlight_context,
11895 XTextViewHelp(display,resource_info,windows,MagickFalse,
11896 "Help Viewer - Region of Interest",ImageROIHelp);
11897 (void) XSetFunction(display,windows->image.highlight_context,
11903 display_command=XImageWindowCommand(display,resource_info,windows,
11904 event.xkey.state,key_symbol,image,exception);
11905 if (display_command != NullCommand)
11906 state|=UpdateRegionState;
11910 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id,
11918 if (event.xbutton.window != windows->image.id)
11925 if (windows->info.mapped != MagickFalse)
11927 if ((x < (windows->info.x+(
int) windows->info.width)) &&
11928 (y < (windows->info.y+(
int) windows->info.height)))
11929 (void) XWithdrawWindow(display,windows->info.id,
11930 windows->info.screen);
11933 if ((x > (windows->info.x+(
int) windows->info.width)) ||
11934 (y > (windows->info.y+(
int) windows->info.height)))
11935 (void) XMapWindow(display,windows->info.id);
11936 roi_info.x=(ssize_t) windows->image.x+event.xmotion.x;
11937 roi_info.y=(ssize_t) windows->image.y+event.xmotion.y;
11940 case SelectionRequest:
11945 XSelectionRequestEvent
11951 (void) FormatLocaleString(text,MagickPathExtent,
11952 "%.20gx%.20g%+.20g%+.20g",(
double) roi_info.width,(
double)
11953 roi_info.height,(
double) roi_info.x,(
double) roi_info.y);
11954 request=(&(
event.xselectionrequest));
11955 (void) XChangeProperty(request->display,request->requestor,
11956 request->property,request->target,8,PropModeReplace,
11957 (
unsigned char *) text,(
int) strlen(text));
11958 notify.type=SelectionNotify;
11959 notify.display=request->display;
11960 notify.requestor=request->requestor;
11961 notify.selection=request->selection;
11962 notify.target=request->target;
11963 notify.time=request->time;
11964 if (request->property == None)
11965 notify.property=request->target;
11967 notify.property=request->property;
11968 (void) XSendEvent(request->display,request->requestor,False,0,
11969 (XEvent *) ¬ify);
11974 if ((state & UpdateConfigurationState) != 0)
11976 (void) XPutBackEvent(display,&event);
11977 (void) XCheckDefineCursor(display,windows->image.id,cursor);
11980 }
while ((state & ExitState) == 0);
11981 }
while ((state & ExitState) == 0);
11982 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
11983 XSetCursorState(display,windows,MagickFalse);
11984 if ((state & EscapeState) != 0)
11985 return(MagickTrue);
11986 return(MagickTrue);
12025static MagickBooleanType XRotateImage(Display *display,
12026 XResourceInfo *resource_info,XWindows *windows,
double degrees,Image **image,
12027 ExceptionInfo *exception)
12030 *
const RotateMenu[] =
12040 direction = HorizontalRotateCommand;
12042 static const ModeType
12043 DirectionCommands[] =
12045 HorizontalRotateCommand,
12046 VerticalRotateCommand
12050 RotateColorCommand,
12051 RotateDirectionCommand,
12053 RotateDismissCommand
12056 static unsigned int
12060 command[MagickPathExtent],
12061 text[MagickPathExtent];
12072 normalized_degrees;
12082 if (degrees == 0.0)
12099 (void) CloneString(&windows->command.name,
"Rotate");
12100 windows->command.data=2;
12101 (void) XCommandWidget(display,windows,RotateMenu,(XEvent *) NULL);
12102 (void) XMapRaised(display,windows->command.id);
12103 XClientMessage(display,windows->image.id,windows->im_protocols,
12104 windows->im_update_widget,CurrentTime);
12108 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
12109 XQueryPosition(display,windows->image.id,&x,&y);
12114 state=DefaultState;
12117 XHighlightLine(display,windows->image.id,
12118 windows->image.highlight_context,&rotate_info);
12122 XScreenEvent(display,windows,&event,exception);
12123 XHighlightLine(display,windows->image.id,
12124 windows->image.highlight_context,&rotate_info);
12125 if (event.xany.window == windows->command.id)
12130 id=XCommandWidget(display,windows,RotateMenu,&event);
12133 (void) XSetFunction(display,windows->image.highlight_context,
12135 switch (RotateCommands[
id])
12137 case RotateColorCommand:
12140 *ColorMenu[MaxNumberPens];
12151 for (i=0; i < (int) (MaxNumberPens-2); i++)
12152 ColorMenu[i]=resource_info->pen_colors[i];
12153 ColorMenu[MaxNumberPens-2]=
"Browser...";
12154 ColorMenu[MaxNumberPens-1]=(
const char *) NULL;
12158 pen_number=XMenuWidget(display,windows,RotateMenu[
id],
12159 (
const char **) ColorMenu,command);
12160 if (pen_number < 0)
12162 if (pen_number == (MaxNumberPens-2))
12165 color_name[MagickPathExtent] =
"gray";
12170 resource_info->pen_colors[pen_number]=color_name;
12171 XColorBrowserWidget(display,windows,
"Select",color_name);
12172 if (*color_name ==
'\0')
12178 (void) XParseColor(display,windows->map_info->colormap,
12179 resource_info->pen_colors[pen_number],&color);
12180 XBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
12181 (
unsigned int) MaxColors,&color);
12182 windows->pixel_info->pen_colors[pen_number]=color;
12183 pen_id=(
unsigned int) pen_number;
12186 case RotateDirectionCommand:
12199 id=XMenuWidget(display,windows,RotateMenu[
id],
12200 Directions,command);
12202 direction=DirectionCommands[id];
12205 case RotateHelpCommand:
12207 XTextViewHelp(display,resource_info,windows,MagickFalse,
12208 "Help Viewer - Image Rotation",ImageRotateHelp);
12211 case RotateDismissCommand:
12216 state|=EscapeState;
12223 (void) XSetFunction(display,windows->image.highlight_context,
12227 switch (event.type)
12231 if (event.xbutton.button != Button1)
12233 if (event.xbutton.window != windows->image.id)
12238 (void) XSetFunction(display,windows->image.highlight_context,
12240 rotate_info.x1=
event.xbutton.x;
12241 rotate_info.y1=
event.xbutton.y;
12245 case ButtonRelease:
12252 command[MagickPathExtent];
12257 if (event.xkey.window != windows->image.id)
12262 (void) XLookupString((XKeyEvent *) &event.xkey,command,(
int)
12263 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
12264 switch ((
int) key_symbol)
12272 state|=EscapeState;
12279 (void) XSetFunction(display,windows->image.highlight_context,
12281 XTextViewHelp(display,resource_info,windows,MagickFalse,
12282 "Help Viewer - Image Rotation",ImageRotateHelp);
12283 (void) XSetFunction(display,windows->image.highlight_context,
12289 (void) XBell(display,0);
12297 rotate_info.x1=
event.xmotion.x;
12298 rotate_info.y1=
event.xmotion.y;
12301 rotate_info.x2=rotate_info.x1;
12302 rotate_info.y2=rotate_info.y1;
12303 if (direction == HorizontalRotateCommand)
12304 rotate_info.x2+=32;
12306 rotate_info.y2-=32;
12307 }
while ((state & ExitState) == 0);
12308 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
12309 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
12310 if ((state & EscapeState) != 0)
12311 return(MagickTrue);
12316 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
12317 state=DefaultState;
12325 if (windows->info.mapped == MagickFalse)
12326 (void) XMapWindow(display,windows->info.id);
12327 (void) FormatLocaleString(text,MagickPathExtent,
" %g",
12328 direction == VerticalRotateCommand ? degrees-90.0 : degrees);
12329 XInfoWidget(display,windows,text);
12330 XHighlightLine(display,windows->image.id,
12331 windows->image.highlight_context,&rotate_info);
12334 if (windows->info.mapped != MagickFalse)
12335 (void) XWithdrawWindow(display,windows->info.id,
12336 windows->info.screen);
12340 XScreenEvent(display,windows,&event,exception);
12342 XHighlightLine(display,windows->image.id,
12343 windows->image.highlight_context,&rotate_info);
12344 switch (event.type)
12348 case ButtonRelease:
12353 rotate_info.x2=
event.xbutton.x;
12354 rotate_info.y2=
event.xbutton.y;
12362 rotate_info.x2=
event.xmotion.x;
12363 rotate_info.y2=
event.xmotion.y;
12371 if (rotate_info.x2 < 0)
12374 if (rotate_info.x2 > (
int) windows->image.width)
12375 rotate_info.x2=(short) windows->image.width;
12376 if (rotate_info.y2 < 0)
12379 if (rotate_info.y2 > (
int) windows->image.height)
12380 rotate_info.y2=(short) windows->image.height;
12385 distance=(
unsigned int)
12386 (((rotate_info.x2-rotate_info.x1+1)*(rotate_info.x2-rotate_info.x1+1))+
12387 ((rotate_info.y2-rotate_info.y1+1)*(rotate_info.y2-rotate_info.y1+1)));
12389 degrees=RadiansToDegrees(-atan2((
double) (rotate_info.y2-
12390 rotate_info.y1),(
double) (rotate_info.x2-rotate_info.x1)));
12391 }
while ((state & ExitState) == 0);
12392 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
12393 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
12395 return(MagickTrue);
12397 if (direction == VerticalRotateCommand)
12399 if (degrees == 0.0)
12400 return(MagickTrue);
12404 normalized_degrees=degrees;
12405 while (normalized_degrees < -45.0)
12406 normalized_degrees+=360.0;
12407 for (rotations=0; normalized_degrees > 45.0; rotations++)
12408 normalized_degrees-=90.0;
12409 if (normalized_degrees != 0.0)
12410 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
12412 XSetCursorState(display,windows,MagickTrue);
12413 XCheckRefreshWindows(display,windows);
12414 (*image)->background_color.red=(double) ScaleShortToQuantum(
12415 windows->pixel_info->pen_colors[pen_id].red);
12416 (*image)->background_color.green=(double) ScaleShortToQuantum(
12417 windows->pixel_info->pen_colors[pen_id].green);
12418 (*image)->background_color.blue=(double) ScaleShortToQuantum(
12419 windows->pixel_info->pen_colors[pen_id].blue);
12420 rotate_image=RotateImage(*image,degrees,exception);
12421 XSetCursorState(display,windows,MagickFalse);
12422 if (rotate_image == (Image *) NULL)
12423 return(MagickFalse);
12424 *image=DestroyImage(*image);
12425 *image=rotate_image;
12426 if (windows->image.crop_geometry != (
char *) NULL)
12431 width=(
unsigned int) (*image)->columns;
12432 height=(
unsigned int) (*image)->rows;
12433 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
12434 switch (rotations % 4)
12444 (void) FormatLocaleString(windows->image.crop_geometry,
12445 MagickPathExtent,
"%ux%u%+d%+d",height,width,(
int) (*image)->columns-
12454 (void) FormatLocaleString(windows->image.crop_geometry,
12455 MagickPathExtent,
"%ux%u%+d%+d",width,height,(
int) width-x,(
int)
12464 (void) FormatLocaleString(windows->image.crop_geometry,
12465 MagickPathExtent,
"%ux%u%+d%+d",height,width,y,(
int) (*image)->rows-
12471 if (windows->image.orphan != MagickFalse)
12472 return(MagickTrue);
12473 if (normalized_degrees != 0.0)
12478 windows->image.window_changes.width=(int) (*image)->columns;
12479 windows->image.window_changes.height=(int) (*image)->rows;
12480 if (windows->image.crop_geometry != (
char *) NULL)
12485 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
12487 windows->image.window_changes.width=(int) width;
12488 windows->image.window_changes.height=(int) height;
12490 XConfigureImageColormap(display,resource_info,windows,*image,exception);
12493 if (((rotations % 4) == 1) || ((rotations % 4) == 3))
12495 windows->image.window_changes.width=windows->image.ximage->height;
12496 windows->image.window_changes.height=windows->image.ximage->width;
12501 (void) XConfigureImage(display,resource_info,windows,*image,exception);
12502 return(MagickTrue);
12538static MagickBooleanType XSaveImage(Display *display,
12539 XResourceInfo *resource_info,XWindows *windows,Image *image,
12540 ExceptionInfo *exception)
12543 filename[MagickPathExtent],
12544 geometry[MagickPathExtent];
12558 if (resource_info->write_filename != (
char *) NULL)
12559 (void) CopyMagickString(filename,resource_info->write_filename,
12564 path[MagickPathExtent];
12569 GetPathComponent(image->filename,HeadPath,path);
12570 GetPathComponent(image->filename,TailPath,filename);
12573 status=chdir(path);
12575 (void) ThrowMagickException(exception,GetMagickModule(),
12576 FileOpenError,
"UnableToOpenFile",
"%s",path);
12579 XFileBrowserWidget(display,windows,
"Save",filename);
12580 if (*filename ==
'\0')
12581 return(MagickTrue);
12582 if (IsPathAccessible(filename) != MagickFalse)
12590 status=XConfirmWidget(display,windows,
"Overwrite",filename);
12592 return(MagickTrue);
12594 image_info=CloneImageInfo(resource_info->image_info);
12595 (void) CopyMagickString(image_info->filename,filename,MagickPathExtent);
12596 (void) SetImageInfo(image_info,1,exception);
12597 if ((LocaleCompare(image_info->magick,
"JPEG") == 0) ||
12598 (LocaleCompare(image_info->magick,
"JPG") == 0))
12601 quality[MagickPathExtent];
12609 (void) FormatLocaleString(quality,MagickPathExtent,
"%.20g",(
double)
12611 status=XDialogWidget(display,windows,
"Save",
"Enter JPEG quality:",
12613 if (*quality ==
'\0')
12614 return(MagickTrue);
12615 image->quality=StringToUnsignedLong(quality);
12616 image_info->interlace=status != 0 ? NoInterlace : PlaneInterlace;
12618 if ((LocaleCompare(image_info->magick,
"EPS") == 0) ||
12619 (LocaleCompare(image_info->magick,
"PDF") == 0) ||
12620 (LocaleCompare(image_info->magick,
"PS") == 0) ||
12621 (LocaleCompare(image_info->magick,
"PS2") == 0))
12624 geometry[MagickPathExtent];
12627 *
const PageSizes[] =
12649 (void) CopyMagickString(geometry,PSPageGeometry,MagickPathExtent);
12650 if (LocaleCompare(image_info->magick,
"PDF") == 0)
12651 (void) CopyMagickString(geometry,PSPageGeometry,MagickPathExtent);
12652 if (image_info->page != (
char *) NULL)
12653 (void) CopyMagickString(geometry,image_info->page,MagickPathExtent);
12654 XListBrowserWidget(display,windows,&windows->widget,PageSizes,
"Select",
12655 "Select page geometry:",geometry);
12656 if (*geometry !=
'\0')
12657 image_info->page=GetPageGeometry(geometry);
12662 XSetCursorState(display,windows,MagickTrue);
12663 XCheckRefreshWindows(display,windows);
12664 save_image=CloneImage(image,0,0,MagickTrue,exception);
12665 if (save_image == (Image *) NULL)
12666 return(MagickFalse);
12667 (void) FormatLocaleString(geometry,MagickPathExtent,
"%dx%d!",
12668 windows->image.ximage->width,windows->image.ximage->height);
12669 (void) TransformImage(&save_image,windows->image.crop_geometry,geometry,
12674 (void) CopyMagickString(save_image->filename,filename,MagickPathExtent);
12675 status=WriteImage(image_info,save_image,exception);
12676 if (status != MagickFalse)
12677 image->taint=MagickFalse;
12678 save_image=DestroyImage(save_image);
12679 image_info=DestroyImageInfo(image_info);
12680 XSetCursorState(display,windows,MagickFalse);
12681 return(status != 0 ? MagickTrue : MagickFalse);
12716#if defined(__cplusplus) || defined(c_plusplus)
12720static int XPredicate(Display *magick_unused(display),XEvent *event,
char *data)
12725 windows=(XWindows *) data;
12726 if ((event->type == ClientMessage) &&
12727 (event->xclient.window == windows->image.id))
12728 return(MagickFalse);
12729 return(MagickTrue);
12732#if defined(__cplusplus) || defined(c_plusplus)
12736static void XScreenEvent(Display *display,XWindows *windows,XEvent *event,
12737 ExceptionInfo *exception)
12743 (void) XIfEvent(display,event,XPredicate,(
char *) windows);
12744 if (event->xany.window == windows->command.id)
12746 switch (event->type)
12749 case ButtonRelease:
12751 if ((event->xbutton.button == Button3) &&
12752 (event->xbutton.state & Mod1Mask))
12757 event->xbutton.button=Button2;
12758 event->xbutton.state&=(
unsigned int) (~Mod1Mask);
12760 if (event->xbutton.window == windows->backdrop.id)
12762 (void) XSetInputFocus(display,event->xbutton.window,RevertToParent,
12763 event->xbutton.time);
12766 if (event->xbutton.window == windows->pan.id)
12768 XPanImage(display,windows,event,exception);
12771 if (event->xbutton.window == windows->image.id)
12772 if (event->xbutton.button == Button2)
12777 x=
event->xbutton.x;
12778 y=
event->xbutton.y;
12782 if (x >= (
int) windows->image.width)
12783 x=(int) (windows->image.width-1);
12784 windows->magnify.x=(int) windows->image.x+x;
12788 if (y >= (
int) windows->image.height)
12789 y=(int) (windows->image.height-1);
12790 windows->magnify.y=windows->image.y+y;
12791 if (windows->magnify.mapped == MagickFalse)
12792 (void) XMapRaised(display,windows->magnify.id);
12793 XMakeMagnifyImage(display,windows,exception);
12794 if (event->type == ButtonRelease)
12795 (void) XWithdrawWindow(display,windows->info.id,
12796 windows->info.screen);
12801 case ClientMessage:
12806 if (event->xclient.message_type != windows->wm_protocols)
12808 if (*event->xclient.data.l != (
long) windows->wm_delete_window)
12810 if (event->xclient.window == windows->magnify.id)
12812 (void) XWithdrawWindow(display,windows->magnify.id,
12813 windows->magnify.screen);
12818 case ConfigureNotify:
12820 if (event->xconfigure.window == windows->magnify.id)
12828 windows->magnify.width=(
unsigned int) event->xconfigure.width;
12829 windows->magnify.height=(
unsigned int) event->xconfigure.height;
12830 if (windows->magnify.mapped == MagickFalse)
12833 while ((
int) magnify <= event->xconfigure.width)
12835 while ((
int) magnify <= event->xconfigure.height)
12838 if (((
int) magnify != event->xconfigure.width) ||
12839 ((
int) magnify != event->xconfigure.height))
12844 window_changes.width=(int) magnify;
12845 window_changes.height=(int) magnify;
12846 (void) XReconfigureWMWindow(display,windows->magnify.id,
12847 windows->magnify.screen,(
unsigned int) (CWWidth | CWHeight),
12851 XMakeMagnifyImage(display,windows,exception);
12858 if (event->xexpose.window == windows->image.id)
12860 XRefreshWindow(display,&windows->image,event);
12863 if (event->xexpose.window == windows->pan.id)
12864 if (event->xexpose.count == 0)
12866 XDrawPanRectangle(display,windows);
12869 if (event->xexpose.window == windows->magnify.id)
12870 if (event->xexpose.count == 0)
12872 XMakeMagnifyImage(display,windows,exception);
12880 command[MagickPathExtent];
12885 if (event->xkey.window != windows->magnify.id)
12890 (void) XLookupString((XKeyEvent *) &event->xkey,command,(
int)
12891 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
12892 XMagnifyWindowCommand(display,windows,event->xkey.state,key_symbol,
12898 if (event->xmap.window == windows->magnify.id)
12900 windows->magnify.mapped=MagickTrue;
12901 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
12904 if (event->xmap.window == windows->info.id)
12906 windows->info.mapped=MagickTrue;
12913 while (XCheckMaskEvent(display,ButtonMotionMask,event)) ;
12914 if (event->xmotion.window == windows->image.id)
12915 if (windows->magnify.mapped != MagickFalse)
12920 x=
event->xmotion.x;
12921 y=
event->xmotion.y;
12925 if (x >= (
int) windows->image.width)
12926 x=(int) (windows->image.width-1);
12927 windows->magnify.x=(int) windows->image.x+x;
12931 if (y >= (
int) windows->image.height)
12932 y=(int) (windows->image.height-1);
12933 windows->magnify.y=windows->image.y+y;
12934 XMakeMagnifyImage(display,windows,exception);
12940 if (event->xunmap.window == windows->magnify.id)
12942 windows->magnify.mapped=MagickFalse;
12945 if (event->xunmap.window == windows->info.id)
12947 windows->info.mapped=MagickFalse;
12989static void XSetCropGeometry(Display *display,XWindows *windows,
12990 RectangleInfo *crop_info,Image *image)
12993 text[MagickPathExtent];
13006 if (windows->info.mapped != MagickFalse)
13011 (void) FormatLocaleString(text,MagickPathExtent,
" %.20gx%.20g%+.20g%+.20g",
13012 (
double) crop_info->width,(
double) crop_info->height,(
double)
13013 crop_info->x,(
double) crop_info->y);
13014 XInfoWidget(display,windows,text);
13021 width=(
unsigned int) image->columns;
13022 height=(
unsigned int) image->rows;
13023 if (windows->image.crop_geometry != (
char *) NULL)
13024 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
13026 windows->image.crop_geometry=AcquireString((
char *) NULL);
13030 scale_factor=(double) width/windows->image.ximage->width;
13031 if (crop_info->x > 0)
13032 x+=(int) (scale_factor*crop_info->x+0.5);
13033 width=(
unsigned int) (scale_factor*crop_info->width+0.5);
13036 scale_factor=(double) height/windows->image.ximage->height;
13037 if (crop_info->y > 0)
13038 y+=(int) (scale_factor*crop_info->y+0.5);
13039 height=(
unsigned int) (scale_factor*crop_info->height+0.5);
13042 (void) FormatLocaleString(windows->image.crop_geometry,MagickPathExtent,
13043 "%ux%u%+d%+d",width,height,x,y);
13085static Image *XTileImage(Display *display,XResourceInfo *resource_info,
13086 XWindows *windows,Image *image,XEvent *event,ExceptionInfo *exception)
13089 *
const VerbMenu[] =
13099 static const ModeType
13110 command[MagickPathExtent],
13111 filename[MagickPathExtent];
13142 width=(
unsigned int) image->columns;
13143 height=(
unsigned int) image->rows;
13144 if (windows->image.crop_geometry != (
char *) NULL)
13145 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
13146 scale_factor=(double) width/windows->image.ximage->width;
13147 event->xbutton.x+=windows->image.x;
13148 event->xbutton.x=(int) (scale_factor*event->xbutton.x+x+0.5);
13149 scale_factor=(double) height/windows->image.ximage->height;
13150 event->xbutton.y+=windows->image.y;
13151 event->xbutton.y=(int) (scale_factor*event->xbutton.y+y+0.5);
13155 width=(
unsigned int) image->columns;
13156 height=(
unsigned int) image->rows;
13159 (void) XParseGeometry(image->montage,&x,&y,&width,&height);
13160 tile=((
event->xbutton.y-y)/(int) height)*(((
int) image->columns-x)/(
int)
13161 width)+(
event->xbutton.x-x)/(
int) width;
13167 (void) XBell(display,0);
13168 return((Image *) NULL);
13173 p=image->directory;
13174 for (i=tile; (i != 0) && (*p !=
'\0'); )
13185 (void) XBell(display,0);
13186 return((Image *) NULL);
13191 id=XMenuWidget(display,windows,
"Tile Verb",VerbMenu,command);
13193 return((Image *) NULL);
13195 while ((*q !=
'\xff') && (*q !=
'\0'))
13197 (void) CopyMagickString(filename,p,(
size_t) (q-p+1));
13201 XSetCursorState(display,windows,MagickTrue);
13202 XCheckRefreshWindows(display,windows);
13203 tile_image=NewImageList();
13204 switch (TileCommands[
id])
13206 case TileLoadCommand:
13211 XCheckRefreshWindows(display,windows);
13212 (void) CopyMagickString(resource_info->image_info->magick,
"MIFF",
13214 (void) CopyMagickString(resource_info->image_info->filename,filename,
13216 tile_image=ReadImage(resource_info->image_info,exception);
13217 CatchException(exception);
13218 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
13221 case TileNextCommand:
13226 XClientMessage(display,windows->image.id,windows->im_protocols,
13227 windows->im_next_image,CurrentTime);
13230 case TileFormerCommand:
13235 XClientMessage(display,windows->image.id,windows->im_protocols,
13236 windows->im_former_image,CurrentTime);
13239 case TileDeleteCommand:
13244 if (IsPathAccessible(filename) == MagickFalse)
13246 XNoticeWidget(display,windows,
"Image file does not exist:",filename);
13249 status=XConfirmWidget(display,windows,
"Really delete tile",filename);
13252 status=ShredFile(filename) == MagickFalse ? 0 : 1;
13253 status|=remove_utf8(filename);
13254 if (status != MagickFalse)
13256 XNoticeWidget(display,windows,
"Unable to delete image file:",
13260 magick_fallthrough;
13262 case TileUpdateCommand:
13281 GetPixelInfo(image,&pixel);
13282 for (p=image->directory; *p !=
'\0'; p++)
13288 while ((*q !=
'\xff') && (*q !=
'\0'))
13290 (void) CopyMagickString(filename,p,(
size_t) (q-p+1));
13292 if (IsPathAccessible(filename) != MagickFalse)
13300 x_offset=((int) width*(tile % (((int) image->columns-x)/(int) width))+
13302 y_offset=((int) height*(tile/(((int) image->columns-x)/(int) width))+
13304 image_view=AcquireAuthenticCacheView(image,exception);
13305 (void) GetOneCacheViewVirtualPixelInfo(image_view,0,0,&pixel,exception);
13306 for (i=0; i < (int) height; i++)
13308 s=GetCacheViewAuthenticPixels(image_view,(ssize_t) x_offset,(ssize_t)
13309 y_offset+i,width,1,exception);
13310 if (s == (Quantum *) NULL)
13312 for (j=0; j < (int) width; j++)
13314 SetPixelViaPixelInfo(image,&pixel,s);
13315 s+=(ptrdiff_t) GetPixelChannels(image);
13317 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
13320 image_view=DestroyCacheView(image_view);
13323 windows->image.window_changes.width=(int) image->columns;
13324 windows->image.window_changes.height=(int) image->rows;
13325 XConfigureImageColormap(display,resource_info,windows,image,exception);
13326 (void) XConfigureImage(display,resource_info,windows,image,exception);
13332 XSetCursorState(display,windows,MagickFalse);
13333 return(tile_image);
13369static void XTranslateImage(Display *display,XWindows *windows,
13370 Image *image,
const KeySym key_symbol)
13373 text[MagickPathExtent];
13386 x_offset=windows->image.width;
13387 y_offset=windows->image.height;
13388 if (image->montage != (
char *) NULL)
13389 (void) XParseGeometry(image->montage,&x,&y,&x_offset,&y_offset);
13390 switch ((
int) key_symbol)
13395 windows->image.x=(int) windows->image.width/2;
13396 windows->image.y=(int) windows->image.height/2;
13402 windows->image.x-=(int) x_offset;
13409 windows->image.y-=(int) y_offset;
13415 windows->image.x+=(int) x_offset;
13422 windows->image.y+=(int) y_offset;
13431 if (windows->image.x < 0)
13432 windows->image.x=0;
13434 if ((windows->image.x+(
int) windows->image.width) > windows->image.ximage->width)
13435 windows->image.x=windows->image.ximage->width-(int) windows->image.width;
13436 if (windows->image.y < 0)
13437 windows->image.y=0;
13439 if ((windows->image.y+(
int) windows->image.height) > windows->image.ximage->height)
13440 windows->image.y=windows->image.ximage->height-(int)
13441 windows->image.height;
13445 (void) FormatLocaleString(text,MagickPathExtent,
" %ux%u%+d%+d ",
13446 windows->image.width,windows->image.height,windows->image.x,
13448 XInfoWidget(display,windows,text);
13449 XCheckRefreshWindows(display,windows);
13450 XDrawPanRectangle(display,windows);
13451 XRefreshWindow(display,&windows->image,(XEvent *) NULL);
13452 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
13488static MagickBooleanType XTrimImage(Display *display,
13489 XResourceInfo *resource_info,XWindows *windows,Image *image,
13490 ExceptionInfo *exception)
13506 XSetCursorState(display,windows,MagickTrue);
13507 XCheckRefreshWindows(display,windows);
13511 background=XGetPixel(windows->image.ximage,0,0);
13512 trim_info.width=(size_t) windows->image.ximage->width;
13513 for (x=0; x < windows->image.ximage->width; x++)
13515 for (y=0; y < windows->image.ximage->height; y++)
13517 pixel=XGetPixel(windows->image.ximage,x,y);
13518 if (pixel != background)
13521 if (y < windows->image.ximage->height)
13524 trim_info.x=(ssize_t) x;
13525 if (trim_info.x == (ssize_t) windows->image.ximage->width)
13527 XSetCursorState(display,windows,MagickFalse);
13528 return(MagickFalse);
13533 background=XGetPixel(windows->image.ximage,windows->image.ximage->width-1,0);
13534 for (x=windows->image.ximage->width-1; x != 0; x--)
13536 for (y=0; y < windows->image.ximage->height; y++)
13538 pixel=XGetPixel(windows->image.ximage,x,y);
13539 if (pixel != background)
13542 if (y < windows->image.ximage->height)
13545 trim_info.width=(size_t) (x-trim_info.x+1);
13549 background=XGetPixel(windows->image.ximage,0,0);
13550 trim_info.height=(size_t) windows->image.ximage->height;
13551 for (y=0; y < windows->image.ximage->height; y++)
13553 for (x=0; x < windows->image.ximage->width; x++)
13555 pixel=XGetPixel(windows->image.ximage,x,y);
13556 if (pixel != background)
13559 if (x < windows->image.ximage->width)
13562 trim_info.y=(ssize_t) y;
13566 background=XGetPixel(windows->image.ximage,0,windows->image.ximage->height-1);
13567 for (y=windows->image.ximage->height-1; y != 0; y--)
13569 for (x=0; x < windows->image.ximage->width; x++)
13571 pixel=XGetPixel(windows->image.ximage,x,y);
13572 if (pixel != background)
13575 if (x < windows->image.ximage->width)
13578 trim_info.height=(size_t) (y-trim_info.y+1);
13579 if (((
unsigned int) trim_info.width != windows->image.width) ||
13580 ((
unsigned int) trim_info.height != windows->image.height))
13585 XSetCropGeometry(display,windows,&trim_info,image);
13586 windows->image.window_changes.width=(int) trim_info.width;
13587 windows->image.window_changes.height=(int) trim_info.height;
13588 (void) XConfigureImage(display,resource_info,windows,image,exception);
13590 XSetCursorState(display,windows,MagickFalse);
13591 return(MagickTrue);
13625static Image *XVisualDirectoryImage(Display *display,
13626 XResourceInfo *resource_info,XWindows *windows,ExceptionInfo *exception)
13628#define TileImageTag "Scale/Image"
13629#define XClientName "montage"
13662 filename[MagickPathExtent] =
"\0",
13663 filenames[MagickPathExtent] =
"*";
13666 background_resources;
13671 XFileBrowserWidget(display,windows,
"Directory",filenames);
13672 if (*filenames ==
'\0')
13673 return((Image *) NULL);
13677 filelist=(
char **) AcquireMagickMemory(
sizeof(*filelist));
13678 if (filelist == (
char **) NULL)
13680 ThrowXWindowException(ResourceLimitError,
"MemoryAllocationFailed",
13682 return((Image *) NULL);
13685 filelist[0]=filenames;
13686 status=ExpandFilenames(&number_files,&filelist);
13687 if ((status == MagickFalse) || (number_files == 0))
13689 if (number_files == 0)
13690 ThrowXWindowException(ImageError,
"NoImagesWereFound",filenames)
13692 ThrowXWindowException(ResourceLimitError,
"MemoryAllocationFailed",
13694 return((Image *) NULL);
13699 background_resources=(*resource_info);
13700 background_resources.window_id=AcquireString(
"");
13701 (void) FormatLocaleString(background_resources.window_id,MagickPathExtent,
13702 "0x%lx",windows->image.id);
13703 background_resources.backdrop=MagickTrue;
13707 backdrop=((windows->visual_info->klass == TrueColor) ||
13708 (windows->visual_info->klass == DirectColor)) ? MagickTrue : MagickFalse;
13709 read_info=CloneImageInfo(resource_info->image_info);
13710 (void) SetImageOption(read_info,
"jpeg:size",
"120x120");
13711 (void) CloneString(&read_info->size,DefaultTileGeometry);
13712 (void) SetImageInfoProgressMonitor(read_info,(MagickProgressMonitor) NULL,
13714 images=NewImageList();
13715 XSetCursorState(display,windows,MagickTrue);
13716 XCheckRefreshWindows(display,windows);
13717 for (i=0; i < (int) number_files; i++)
13719 (void) CopyMagickString(read_info->filename,filelist[i],MagickPathExtent);
13720 filelist[i]=DestroyString(filelist[i]);
13721 *read_info->magick=
'\0';
13722 next_image=ReadImage(read_info,exception);
13723 CatchException(exception);
13724 if (next_image != (Image *) NULL)
13726 (void) DeleteImageProperty(next_image,
"label");
13727 (void) SetImageProperty(next_image,
"label",InterpretImageProperties(
13728 read_info,next_image,DefaultTileLabel,exception),exception);
13729 (void) ParseRegionGeometry(next_image,read_info->size,&geometry,
13731 thumbnail_image=ThumbnailImage(next_image,geometry.width,
13732 geometry.height,exception);
13733 if (thumbnail_image != (Image *) NULL)
13735 next_image=DestroyImage(next_image);
13736 next_image=thumbnail_image;
13740 (void) XDisplayBackgroundImage(display,&background_resources,
13741 next_image,exception);
13742 XSetCursorState(display,windows,MagickTrue);
13744 AppendImageToList(&images,next_image);
13745 if (images->progress_monitor != (MagickProgressMonitor) NULL)
13750 proceed=SetImageProgress(images,LoadImageTag,(MagickOffsetType) i,
13751 (MagickSizeType) number_files);
13752 if (proceed == MagickFalse)
13757 filelist=(
char **) RelinquishMagickMemory(filelist);
13758 if (images == (Image *) NULL)
13760 read_info=DestroyImageInfo(read_info);
13761 XSetCursorState(display,windows,MagickFalse);
13762 ThrowXWindowException(ImageError,
"NoImagesWereLoaded",filenames);
13763 return((Image *) NULL);
13768 montage_info=CloneMontageInfo(read_info,(MontageInfo *) NULL);
13769 montage_info->pointsize=10;
13770 if (resource_info->font != (
char *) NULL)
13771 (void) CloneString(&montage_info->font,resource_info->font);
13772 (void) CopyMagickString(montage_info->filename,filename,MagickPathExtent);
13773 montage_image=MontageImageList(read_info,montage_info,GetFirstImageInList(
13774 images),exception);
13775 images=DestroyImageList(images);
13776 montage_info=DestroyMontageInfo(montage_info);
13777 read_info=DestroyImageInfo(read_info);
13778 XSetCursorState(display,windows,MagickFalse);
13779 if (montage_image == (Image *) NULL)
13780 return(montage_image);
13781 XClientMessage(display,windows->image.id,windows->im_protocols,
13782 windows->im_next_image,CurrentTime);
13783 return(montage_image);
13816MagickExport MagickBooleanType XDisplayBackgroundImage(Display *display,
13817 XResourceInfo *resource_info,Image *image,ExceptionInfo *exception)
13820 geometry[MagickPathExtent],
13821 visual_type[MagickPathExtent];
13834 static XStandardColormap
13838 *visual_info = (XVisualInfo *) NULL;
13861 assert(image != (Image *) NULL);
13862 assert(image->signature == MagickCoreSignature);
13863 if (IsEventLogging() != MagickFalse)
13864 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
13865 resources=(*resource_info);
13866 window_info.id=(Window) NULL;
13867 root_window=XRootWindow(display,XDefaultScreen(display));
13868 if (LocaleCompare(resources.window_id,
"root") == 0)
13869 window_info.id=root_window;
13872 if (isdigit((
int) ((
unsigned char) *resources.window_id)) != 0)
13873 window_info.id=XWindowByID(display,root_window,
13874 (Window) strtol((
char *) resources.window_id,(
char **) NULL,0));
13875 if (window_info.id == (Window) NULL)
13876 window_info.id=XWindowByName(display,root_window,resources.window_id);
13878 if (window_info.id == (Window) NULL)
13880 ThrowXWindowException(XServerError,
"NoWindowWithSpecifiedIDExists",
13881 resources.window_id);
13882 return(MagickFalse);
13887 window_attributes.width=XDisplayWidth(display,XDefaultScreen(display));
13888 window_attributes.height=XDisplayHeight(display,XDefaultScreen(display));
13889 (void) CopyMagickString(visual_type,
"default",MagickPathExtent);
13890 status=XGetWindowAttributes(display,window_info.id,&window_attributes);
13892 (void) FormatLocaleString(visual_type,MagickPathExtent,
"0x%lx",
13893 XVisualIDFromVisual(window_attributes.visual));
13894 if (visual_info == (XVisualInfo *) NULL)
13899 map_info=XAllocStandardColormap();
13900 if (map_info == (XStandardColormap *) NULL)
13901 ThrowXWindowFatalException(XServerFatalError,
"MemoryAllocationFailed",
13903 map_info->colormap=(Colormap) NULL;
13904 pixel.pixels=(
unsigned long *) NULL;
13908 resources.map_type=(
char *) NULL;
13909 resources.visual_type=visual_type;
13910 visual_info=XBestVisualInfo(display,map_info,&resources);
13911 if (visual_info == (XVisualInfo *) NULL)
13912 ThrowXWindowFatalException(XServerFatalError,
"UnableToGetVisual",
13913 resources.visual_type);
13917 window_info.ximage=(XImage *) NULL;
13918 window_info.matte_image=(XImage *) NULL;
13919 window_info.pixmap=(Pixmap) NULL;
13920 window_info.matte_pixmap=(Pixmap) NULL;
13925 if (window_info.id == root_window)
13926 (void) XDestroyWindowColors(display,root_window);
13930 resources.colormap=SharedColormap;
13931 XMakeStandardColormap(display,visual_info,&resources,image,map_info,&pixel,
13936 context_values.background=pixel.foreground_color.pixel;
13937 context_values.foreground=pixel.background_color.pixel;
13938 pixel.annotate_context=XCreateGC(display,window_info.id,
13939 (
size_t) (GCBackground | GCForeground),&context_values);
13940 if (pixel.annotate_context == (GC) NULL)
13941 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
13946 window_info.name=AcquireString(
"\0");
13947 window_info.icon_name=AcquireString(
"\0");
13948 XGetWindowInfo(display,visual_info,map_info,&pixel,(XFontStruct *) NULL,
13949 &resources,&window_info);
13953 window_info.width=(
unsigned int) image->columns;
13954 window_info.height=(
unsigned int) image->rows;
13955 if ((image->columns != window_info.width) ||
13956 (image->rows != window_info.height))
13957 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
13959 (void) FormatLocaleString(geometry,MagickPathExtent,
"%ux%u+0+0>",
13960 window_attributes.width,window_attributes.height);
13961 geometry_info.width=window_info.width;
13962 geometry_info.height=window_info.height;
13963 geometry_info.x=(ssize_t) window_info.x;
13964 geometry_info.y=(ssize_t) window_info.y;
13965 (void) ParseMetaGeometry(geometry,&geometry_info.x,&geometry_info.y,
13966 &geometry_info.width,&geometry_info.height);
13967 window_info.width=(
unsigned int) geometry_info.width;
13968 window_info.height=(
unsigned int) geometry_info.height;
13969 window_info.x=(int) geometry_info.x;
13970 window_info.y=(int) geometry_info.y;
13971 status=XMakeImage(display,&resources,&window_info,image,window_info.width,
13972 window_info.height,exception) == MagickFalse ? 0 : 1;
13973 if (status == MagickFalse)
13974 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
13978 if (resource_info->debug != MagickFalse)
13980 (void) LogMagickEvent(X11Event,GetMagickModule(),
13981 "Image: %s[%.20g] %.20gx%.20g ",image->filename,(
double) image->scene,
13982 (
double) image->columns,(
double) image->rows);
13983 if (image->colors != 0)
13984 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%.20gc ",(
double)
13986 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%s",image->magick);
13991 width=(int) window_info.width;
13992 height=(int) window_info.height;
13993 if (resources.backdrop != MagickFalse)
13998 window_info.x=(window_attributes.width/2)-(window_info.ximage->width/2);
13999 window_info.y=(window_attributes.height/2)-(window_info.ximage->height/2);
14000 width=window_attributes.width;
14001 height=window_attributes.height;
14003 if ((resources.image_geometry != (
char *) NULL) &&
14004 (*resources.image_geometry !=
'\0'))
14007 default_geometry[MagickPathExtent];
14019 size_hints=XAllocSizeHints();
14020 if (size_hints == (XSizeHints *) NULL)
14021 ThrowXWindowFatalException(ResourceLimitFatalError,
14022 "MemoryAllocationFailed",image->filename);
14023 size_hints->flags=0L;
14024 (void) FormatLocaleString(default_geometry,MagickPathExtent,
"%dx%d",
14026 flags=XWMGeometry(display,visual_info->screen,resources.image_geometry,
14027 default_geometry,window_info.border_width,size_hints,&window_info.x,
14028 &window_info.y,&width,&height,&gravity);
14029 if (flags & (XValue | YValue))
14031 width=window_attributes.width;
14032 height=window_attributes.height;
14034 (void) XFree((
void *) size_hints);
14039 window_info.pixmap=XCreatePixmap(display,window_info.id,(
unsigned int) width,
14040 (
unsigned int) height,window_info.depth);
14041 if (window_info.pixmap == (Pixmap) NULL)
14042 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXPixmap",
14047 if (((
unsigned int) width > window_info.width) ||
14048 ((
unsigned int) height > window_info.height))
14049 (void) XFillRectangle(display,window_info.pixmap,
14050 window_info.annotate_context,0,0,(
unsigned int) width,
14051 (
unsigned int) height);
14052 (void) XPutImage(display,window_info.pixmap,window_info.annotate_context,
14053 window_info.ximage,0,0,window_info.x,window_info.y,(
unsigned int)
14054 window_info.width,(
unsigned int) window_info.height);
14055 (void) XSetWindowBackgroundPixmap(display,window_info.id,window_info.pixmap);
14056 (void) XClearWindow(display,window_info.id);
14057 delay=1000*image->delay/(size_t) MagickMax(image->ticks_per_second,1L);
14058 XDelay(display,delay == 0UL ? 10UL : delay);
14059 (void) XSync(display,MagickFalse);
14060 return(window_info.id == root_window ? MagickTrue : MagickFalse);
14103MagickExport Image *XDisplayImage(Display *display,XResourceInfo *resource_info,
14104 char **argv,
int argc,Image **image,
size_t *state,ExceptionInfo *exception)
14106#define MagnifySize 256
14107#define MagickMenus 10
14108#define MagickTitle "Commands"
14111 *
const CommandMenu[] =
14125 *
const FileMenu[] =
14135 "Visual Directory...",
14139 *
const EditMenu[] =
14148 *
const ViewMenu[] =
14159 *
const TransformMenu[] =
14173 *
const EnhanceMenu[] =
14181 "Contrast Stretch...",
14182 "Sigmoidal Contrast...",
14191 *
const EffectsMenu[] =
14216 "Charcoal Draw...",
14219 *
const ImageEditMenu[] =
14230 "Region of Interest...",
14233 *
const MiscellanyMenu[] =
14245 *
const HelpMenu[] =
14248 "Browse Documentation",
14252 *
const ShortCutsMenu[] =
14265 *
const VirtualMenu[] =
14275 *
const *Menus[MagickMenus] =
14289 static DisplayCommand
14313 VisualDirectoryCommand,
14327 OriginalSizeCommand,
14334 TransformCommands[] =
14340 RotateRightCommand,
14347 EnhanceCommands[] =
14355 ContrastStretchCommand,
14356 SigmoidalContrastCommand,
14364 EffectsCommands[] =
14368 ReduceNoiseCommand,
14388 CharcoalDrawCommand
14390 ImageEditCommands[] =
14401 RegionOfInterestCommand
14403 MiscellanyCommands[] =
14407 ShowPreviewCommand,
14408 ShowHistogramCommand,
14417 BrowseDocumentationCommand,
14420 ShortCutsCommands[] =
14432 VirtualCommands[] =
14440 static DisplayCommand
14441 *Commands[MagickMenus] =
14451 MiscellanyCommands,
14456 command[MagickPathExtent],
14458 geometry[MagickPathExtent],
14459 resource_name[MagickPathExtent];
14486 working_directory[MagickPathExtent];
14492 *magick_windows[MaxXWindows];
14494 static unsigned int
14554 assert(image != (Image **) NULL);
14555 assert((*image)->signature == MagickCoreSignature);
14556 if (IsEventLogging() != MagickFalse)
14557 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",(*image)->filename);
14558 display_image=(*image);
14559 warning_handler=(WarningHandler) NULL;
14560 windows=XSetWindows((XWindows *) ~0);
14561 if (windows != (XWindows *) NULL)
14566 if (*working_directory ==
'\0')
14567 (void) CopyMagickString(working_directory,
".",MagickPathExtent);
14568 status=chdir(working_directory);
14570 (void) ThrowMagickException(exception,GetMagickModule(),FileOpenError,
14571 "UnableToOpenFile",
"%s",working_directory);
14572 warning_handler=resource_info->display_warnings ?
14573 SetErrorHandler(XWarning) : SetErrorHandler((ErrorHandler) NULL);
14574 warning_handler=resource_info->display_warnings ?
14575 SetWarningHandler(XWarning) : SetWarningHandler((WarningHandler) NULL);
14582 resource_info->colors=display_image->colors;
14583 windows=XSetWindows(XInitializeWindows(display,resource_info));
14584 if (windows == (XWindows *) NULL)
14585 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateWindow",
14586 (*image)->filename);
14591 magick_windows[number_windows++]=(&windows->icon);
14592 magick_windows[number_windows++]=(&windows->backdrop);
14593 magick_windows[number_windows++]=(&windows->image);
14594 magick_windows[number_windows++]=(&windows->info);
14595 magick_windows[number_windows++]=(&windows->command);
14596 magick_windows[number_windows++]=(&windows->widget);
14597 magick_windows[number_windows++]=(&windows->popup);
14598 magick_windows[number_windows++]=(&windows->magnify);
14599 magick_windows[number_windows++]=(&windows->pan);
14600 for (i=0; i < (int) number_windows; i++)
14601 magick_windows[i]->
id=(Window) NULL;
14608 if (windows->font_info != (XFontStruct *) NULL)
14609 (void) XFreeFont(display,windows->font_info);
14610 windows->font_info=XBestFont(display,resource_info,MagickFalse);
14611 if (windows->font_info == (XFontStruct *) NULL)
14612 ThrowXWindowFatalException(XServerFatalError,
"UnableToLoadFont",
14613 resource_info->font);
14617 map_info=windows->map_info;
14618 icon_map=windows->icon_map;
14619 visual_info=windows->visual_info;
14620 icon_visual=windows->icon_visual;
14621 pixel=windows->pixel_info;
14622 icon_pixel=windows->icon_pixel;
14623 font_info=windows->font_info;
14624 icon_resources=windows->icon_resources;
14625 class_hints=windows->class_hints;
14626 manager_hints=windows->manager_hints;
14627 root_window=XRootWindow(display,visual_info->screen);
14628 nexus=NewImageList();
14629 if (resource_info->debug != MagickFalse)
14631 (void) LogMagickEvent(X11Event,GetMagickModule(),
14632 "Image: %s[%.20g] %.20gx%.20g ",display_image->filename,
14633 (
double) display_image->scene,(
double) display_image->columns,
14634 (
double) display_image->rows);
14635 if (display_image->colors != 0)
14636 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%.20gc ",(
double)
14637 display_image->colors);
14638 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%s",
14639 display_image->magick);
14641 XMakeStandardColormap(display,visual_info,resource_info,display_image,
14642 map_info,pixel,exception);
14643 display_image->taint=MagickFalse;
14647 windows->context.id=(Window) NULL;
14648 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14649 resource_info,&windows->context);
14650 (void) CloneString(&class_hints->res_name,resource_info->client_name);
14651 (void) CloneString(&class_hints->res_class,resource_info->client_name);
14652 class_hints->res_class[0]=(char) LocaleToUppercase((
int)
14653 class_hints->res_class[0]);
14654 manager_hints->flags=InputHint | StateHint;
14655 manager_hints->input=MagickFalse;
14656 manager_hints->initial_state=WithdrawnState;
14657 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14658 &windows->context);
14659 if (resource_info->debug != MagickFalse)
14660 (void) LogMagickEvent(X11Event,GetMagickModule(),
14661 "Window id: 0x%lx (context)",windows->context.id);
14662 context_values.background=pixel->background_color.pixel;
14663 context_values.font=font_info->fid;
14664 context_values.foreground=pixel->foreground_color.pixel;
14665 context_values.graphics_exposures=MagickFalse;
14666 context_mask=(MagickStatusType)
14667 (GCBackground | GCFont | GCForeground | GCGraphicsExposures);
14668 if (pixel->annotate_context != (GC) NULL)
14669 (void) XFreeGC(display,pixel->annotate_context);
14670 pixel->annotate_context=XCreateGC(display,windows->context.id,
14671 context_mask,&context_values);
14672 if (pixel->annotate_context == (GC) NULL)
14673 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14674 display_image->filename);
14675 context_values.background=pixel->depth_color.pixel;
14676 if (pixel->widget_context != (GC) NULL)
14677 (void) XFreeGC(display,pixel->widget_context);
14678 pixel->widget_context=XCreateGC(display,windows->context.id,context_mask,
14680 if (pixel->widget_context == (GC) NULL)
14681 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14682 display_image->filename);
14683 context_values.background=pixel->foreground_color.pixel;
14684 context_values.foreground=pixel->background_color.pixel;
14685 context_values.plane_mask=context_values.background ^
14686 context_values.foreground;
14687 if (pixel->highlight_context != (GC) NULL)
14688 (void) XFreeGC(display,pixel->highlight_context);
14689 pixel->highlight_context=XCreateGC(display,windows->context.id,
14690 (
size_t) (context_mask | GCPlaneMask),&context_values);
14691 if (pixel->highlight_context == (GC) NULL)
14692 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14693 display_image->filename);
14694 (void) XDestroyWindow(display,windows->context.id);
14698 XGetWindowInfo(display,icon_visual,icon_map,icon_pixel,(XFontStruct *) NULL,
14699 icon_resources,&windows->icon);
14700 windows->icon.geometry=resource_info->icon_geometry;
14701 XBestIconSize(display,&windows->icon,display_image);
14702 windows->icon.attributes.colormap=XDefaultColormap(display,
14703 icon_visual->screen);
14704 windows->icon.attributes.event_mask=ExposureMask | StructureNotifyMask;
14705 manager_hints->flags=InputHint | StateHint;
14706 manager_hints->input=MagickFalse;
14707 manager_hints->initial_state=IconicState;
14708 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14710 if (resource_info->debug != MagickFalse)
14711 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (icon)",
14716 if (icon_pixel->annotate_context != (GC) NULL)
14717 (void) XFreeGC(display,icon_pixel->annotate_context);
14718 context_values.background=icon_pixel->background_color.pixel;
14719 context_values.foreground=icon_pixel->foreground_color.pixel;
14720 icon_pixel->annotate_context=XCreateGC(display,windows->icon.id,
14721 (
size_t) (GCBackground | GCForeground),&context_values);
14722 if (icon_pixel->annotate_context == (GC) NULL)
14723 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14724 display_image->filename);
14725 windows->icon.annotate_context=icon_pixel->annotate_context;
14729 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,resource_info,
14731 windows->image.shape=MagickTrue;
14732 if (resource_info->use_shared_memory == MagickFalse)
14733 windows->image.shared_memory=MagickFalse;
14734 if ((resource_info->title != (
char *) NULL) && !(*state & MontageImageState))
14739 title=InterpretImageProperties(resource_info->image_info,display_image,
14740 resource_info->title,exception);
14741 (void) CloneString(&windows->image.name,title);
14742 (void) CloneString(&windows->image.icon_name,title);
14743 title=DestroyString(title);
14748 filename[MagickPathExtent],
14749 window_name[MagickPathExtent];
14754 GetPathComponent(display_image->magick_filename,TailPath,filename);
14755 if (display_image->scene == 0)
14756 (void) FormatLocaleString(window_name,MagickPathExtent,
"%s: %s",
14757 MagickPackageName,filename);
14759 (
void) FormatLocaleString(window_name,MagickPathExtent,
14760 "%s: %s[scene: %.20g frames: %.20g]",MagickPackageName,filename,
14761 (
double) display_image->scene,(
double) GetImageListLength(
14763 (void) CloneString(&windows->image.name,window_name);
14764 (void) CloneString(&windows->image.icon_name,filename);
14766 if (resource_info->immutable)
14767 windows->image.immutable=MagickTrue;
14768 windows->image.use_pixmap=resource_info->use_pixmap;
14769 windows->image.geometry=resource_info->image_geometry;
14770 (void) FormatLocaleString(geometry,MagickPathExtent,
"%ux%u+0+0>!",
14771 XDisplayWidth(display,visual_info->screen),
14772 XDisplayHeight(display,visual_info->screen));
14773 geometry_info.width=display_image->columns;
14774 geometry_info.height=display_image->rows;
14777 (void) ParseMetaGeometry(geometry,&geometry_info.x,&geometry_info.y,
14778 &geometry_info.width,&geometry_info.height);
14779 windows->image.width=(
unsigned int) geometry_info.width;
14780 windows->image.height=(
unsigned int) geometry_info.height;
14781 windows->image.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14782 ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
14783 KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask |
14784 PropertyChangeMask | StructureNotifyMask | SubstructureNotifyMask;
14785 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14786 resource_info,&windows->backdrop);
14787 if ((resource_info->backdrop) || (windows->backdrop.id != (Window) NULL))
14792 windows->backdrop.x=0;
14793 windows->backdrop.y=0;
14794 (void) CloneString(&windows->backdrop.name,
"Backdrop");
14795 windows->backdrop.flags=(size_t) (USSize | USPosition);
14796 windows->backdrop.width=(
unsigned int)
14797 XDisplayWidth(display,visual_info->screen);
14798 windows->backdrop.height=(
unsigned int)
14799 XDisplayHeight(display,visual_info->screen);
14800 windows->backdrop.border_width=0;
14801 windows->backdrop.immutable=MagickTrue;
14802 windows->backdrop.attributes.do_not_propagate_mask=ButtonPressMask |
14804 windows->backdrop.attributes.event_mask=ButtonPressMask | KeyPressMask |
14805 StructureNotifyMask;
14806 manager_hints->flags=IconWindowHint | InputHint | StateHint;
14807 manager_hints->icon_window=windows->icon.id;
14808 manager_hints->input=MagickTrue;
14809 manager_hints->initial_state=resource_info->iconic ? IconicState :
14811 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14812 &windows->backdrop);
14813 if (resource_info->debug != MagickFalse)
14814 (void) LogMagickEvent(X11Event,GetMagickModule(),
14815 "Window id: 0x%lx (backdrop)",windows->backdrop.id);
14816 (void) XMapWindow(display,windows->backdrop.id);
14817 (void) XClearWindow(display,windows->backdrop.id);
14818 if (windows->image.id != (Window) NULL)
14820 (void) XDestroyWindow(display,windows->image.id);
14821 windows->image.id=(Window) NULL;
14826 windows->image.flags|=USPosition;
14827 windows->image.x=(XDisplayWidth(display,visual_info->screen)/2)-
14828 ((
int) windows->image.width/2);
14829 windows->image.y=(XDisplayHeight(display,visual_info->screen)/2)-
14830 ((
int) windows->image.height/2);
14832 manager_hints->flags=IconWindowHint | InputHint | StateHint;
14833 manager_hints->icon_window=windows->icon.id;
14834 manager_hints->input=MagickTrue;
14835 manager_hints->initial_state=resource_info->iconic ? IconicState :
14837 if (windows->group_leader.id != (Window) NULL)
14842 manager_hints->flags|=WindowGroupHint;
14843 manager_hints->window_group=windows->group_leader.id;
14844 (void) XSelectInput(display,windows->group_leader.id,StructureNotifyMask);
14845 if (resource_info->debug != MagickFalse)
14846 (void) LogMagickEvent(X11Event,GetMagickModule(),
14847 "Window id: 0x%lx (group leader)",windows->group_leader.id);
14849 XMakeWindow(display,
14850 (Window) (resource_info->backdrop ? windows->backdrop.id : root_window),
14851 argv,argc,class_hints,manager_hints,&windows->image);
14852 (void) XChangeProperty(display,windows->image.id,windows->im_protocols,
14853 XA_STRING,8,PropModeReplace,(
unsigned char *) NULL,0);
14854 if (windows->group_leader.id != (Window) NULL)
14855 (void) XSetTransientForHint(display,windows->image.id,
14856 windows->group_leader.id);
14857 if (resource_info->debug != MagickFalse)
14858 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (image)",
14859 windows->image.id);
14863 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,resource_info,
14865 (void) CloneString(&windows->info.name,
"Info");
14866 (void) CloneString(&windows->info.icon_name,
"Info");
14867 windows->info.border_width=1;
14870 windows->info.flags|=PPosition;
14871 windows->info.attributes.win_gravity=UnmapGravity;
14872 windows->info.attributes.event_mask=ButtonPressMask | ExposureMask |
14873 StructureNotifyMask;
14874 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14875 manager_hints->input=MagickFalse;
14876 manager_hints->initial_state=NormalState;
14877 manager_hints->window_group=windows->image.id;
14878 XMakeWindow(display,windows->image.id,argv,argc,class_hints,manager_hints,
14880 windows->info.highlight_stipple=XCreateBitmapFromData(display,
14881 windows->info.id,(
char *) HighlightBitmap,HighlightWidth,HighlightHeight);
14882 windows->info.shadow_stipple=XCreateBitmapFromData(display,
14883 windows->info.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14884 (void) XSetTransientForHint(display,windows->info.id,windows->image.id);
14885 if (windows->image.mapped != MagickFalse)
14886 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
14887 if (resource_info->debug != MagickFalse)
14888 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (info)",
14893 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14894 resource_info,&windows->command);
14895 windows->command.data=MagickMenus;
14896 (void) XCommandWidget(display,windows,CommandMenu,(XEvent *) NULL);
14897 (void) FormatLocaleString(resource_name,MagickPathExtent,
"%s.command",
14898 resource_info->client_name);
14899 windows->command.geometry=XGetResourceClass(resource_info->resource_database,
14900 resource_name,
"geometry",(
char *) NULL);
14901 (void) CloneString(&windows->command.name,MagickTitle);
14902 windows->command.border_width=0;
14903 windows->command.flags|=PPosition;
14904 windows->command.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14905 ButtonReleaseMask | EnterWindowMask | ExposureMask | LeaveWindowMask |
14906 OwnerGrabButtonMask | StructureNotifyMask;
14907 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14908 manager_hints->input=MagickTrue;
14909 manager_hints->initial_state=NormalState;
14910 manager_hints->window_group=windows->image.id;
14911 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14912 &windows->command);
14913 windows->command.highlight_stipple=XCreateBitmapFromData(display,
14914 windows->command.id,(
char *) HighlightBitmap,HighlightWidth,
14916 windows->command.shadow_stipple=XCreateBitmapFromData(display,
14917 windows->command.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14918 (void) XSetTransientForHint(display,windows->command.id,windows->image.id);
14919 if (windows->command.mapped != MagickFalse)
14920 (void) XMapRaised(display,windows->command.id);
14921 if (resource_info->debug != MagickFalse)
14922 (void) LogMagickEvent(X11Event,GetMagickModule(),
14923 "Window id: 0x%lx (command)",windows->command.id);
14927 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14928 resource_info,&windows->widget);
14929 (void) FormatLocaleString(resource_name,MagickPathExtent,
"%s.widget",
14930 resource_info->client_name);
14931 windows->widget.geometry=XGetResourceClass(resource_info->resource_database,
14932 resource_name,
"geometry",(
char *) NULL);
14933 windows->widget.border_width=0;
14934 windows->widget.flags|=PPosition;
14935 windows->widget.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14936 ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
14937 KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask |
14938 StructureNotifyMask;
14939 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14940 manager_hints->input=MagickTrue;
14941 manager_hints->initial_state=NormalState;
14942 manager_hints->window_group=windows->image.id;
14943 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14945 windows->widget.highlight_stipple=XCreateBitmapFromData(display,
14946 windows->widget.id,(
char *) HighlightBitmap,HighlightWidth,HighlightHeight);
14947 windows->widget.shadow_stipple=XCreateBitmapFromData(display,
14948 windows->widget.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14949 (void) XSetTransientForHint(display,windows->widget.id,windows->image.id);
14950 if (resource_info->debug != MagickFalse)
14951 (void) LogMagickEvent(X11Event,GetMagickModule(),
14952 "Window id: 0x%lx (widget)",windows->widget.id);
14956 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14957 resource_info,&windows->popup);
14958 windows->popup.border_width=0;
14959 windows->popup.flags|=PPosition;
14960 windows->popup.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14961 ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
14962 KeyReleaseMask | LeaveWindowMask | StructureNotifyMask;
14963 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14964 manager_hints->input=MagickTrue;
14965 manager_hints->initial_state=NormalState;
14966 manager_hints->window_group=windows->image.id;
14967 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14969 windows->popup.highlight_stipple=XCreateBitmapFromData(display,
14970 windows->popup.id,(
char *) HighlightBitmap,HighlightWidth,HighlightHeight);
14971 windows->popup.shadow_stipple=XCreateBitmapFromData(display,
14972 windows->popup.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14973 (void) XSetTransientForHint(display,windows->popup.id,windows->image.id);
14974 if (resource_info->debug != MagickFalse)
14975 (void) LogMagickEvent(X11Event,GetMagickModule(),
14976 "Window id: 0x%lx (pop up)",windows->popup.id);
14980 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14981 resource_info,&windows->magnify);
14982 if (resource_info->use_shared_memory == MagickFalse)
14983 windows->magnify.shared_memory=MagickFalse;
14984 (void) FormatLocaleString(resource_name,MagickPathExtent,
"%s.magnify",
14985 resource_info->client_name);
14986 windows->magnify.geometry=XGetResourceClass(resource_info->resource_database,
14987 resource_name,
"geometry",(
char *) NULL);
14988 (void) FormatLocaleString(windows->magnify.name,MagickPathExtent,
14989 "Magnify %uX",resource_info->magnify);
14990 if (windows->magnify.cursor != (Cursor) NULL)
14991 (void) XFreeCursor(display,windows->magnify.cursor);
14992 windows->magnify.cursor=XMakeCursor(display,windows->image.id,
14993 map_info->colormap,resource_info->background_color,
14994 resource_info->foreground_color);
14995 if (windows->magnify.cursor == (Cursor) NULL)
14996 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateCursor",
14997 display_image->filename);
14998 windows->magnify.width=MagnifySize;
14999 windows->magnify.height=MagnifySize;
15000 windows->magnify.flags|=PPosition;
15001 windows->magnify.min_width=MagnifySize;
15002 windows->magnify.min_height=MagnifySize;
15003 windows->magnify.width_inc=MagnifySize;
15004 windows->magnify.height_inc=MagnifySize;
15005 windows->magnify.data=resource_info->magnify;
15006 windows->magnify.attributes.cursor=windows->magnify.cursor;
15007 windows->magnify.attributes.event_mask=ButtonPressMask | ButtonReleaseMask |
15008 ExposureMask | KeyPressMask | KeyReleaseMask | OwnerGrabButtonMask |
15009 StructureNotifyMask;
15010 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
15011 manager_hints->input=MagickTrue;
15012 manager_hints->initial_state=NormalState;
15013 manager_hints->window_group=windows->image.id;
15014 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
15015 &windows->magnify);
15016 if (resource_info->debug != MagickFalse)
15017 (void) LogMagickEvent(X11Event,GetMagickModule(),
15018 "Window id: 0x%lx (magnify)",windows->magnify.id);
15019 (void) XSetTransientForHint(display,windows->magnify.id,windows->image.id);
15023 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
15024 resource_info,&windows->pan);
15025 (void) CloneString(&windows->pan.name,
"Pan Icon");
15026 windows->pan.width=windows->icon.width;
15027 windows->pan.height=windows->icon.height;
15028 (void) FormatLocaleString(resource_name,MagickPathExtent,
"%s.pan",
15029 resource_info->client_name);
15030 windows->pan.geometry=XGetResourceClass(resource_info->resource_database,
15031 resource_name,
"geometry",(
char *) NULL);
15032 (void) XParseGeometry(windows->pan.geometry,&windows->pan.x,&windows->pan.y,
15033 &windows->pan.width,&windows->pan.height);
15034 windows->pan.flags|=PPosition;
15035 windows->pan.immutable=MagickTrue;
15036 windows->pan.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
15037 ButtonReleaseMask | ExposureMask | KeyPressMask | KeyReleaseMask |
15038 StructureNotifyMask;
15039 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
15040 manager_hints->input=MagickFalse;
15041 manager_hints->initial_state=NormalState;
15042 manager_hints->window_group=windows->image.id;
15043 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
15045 if (resource_info->debug != MagickFalse)
15046 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (pan)",
15048 (void) XSetTransientForHint(display,windows->pan.id,windows->image.id);
15049 if (windows->info.mapped != MagickFalse)
15050 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
15051 if ((windows->image.mapped == MagickFalse) ||
15052 (windows->backdrop.id != (Window) NULL))
15053 (void) XMapWindow(display,windows->image.id);
15057 if (warning_handler == (WarningHandler) NULL)
15059 warning_handler=resource_info->display_warnings ?
15060 SetErrorHandler(XWarning) : SetErrorHandler((ErrorHandler) NULL);
15061 warning_handler=resource_info->display_warnings ?
15062 SetWarningHandler(XWarning) : SetWarningHandler((WarningHandler) NULL);
15067 windows->image.x=0;
15068 windows->image.y=0;
15069 windows->magnify.shape=MagickFalse;
15070 width=(
unsigned int) display_image->columns;
15071 height=(
unsigned int) display_image->rows;
15072 if ((display_image->columns != width) || (display_image->rows != height))
15073 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
15074 display_image->filename);
15075 status=XMakeImage(display,resource_info,&windows->image,display_image,
15076 width,height,exception);
15077 if (status == MagickFalse)
15078 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
15079 display_image->filename);
15080 status=XMakeImage(display,resource_info,&windows->magnify,(Image *) NULL,
15081 windows->magnify.width,windows->magnify.height,exception);
15082 if (status == MagickFalse)
15083 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
15084 display_image->filename);
15085 if (windows->magnify.mapped != MagickFalse)
15086 (void) XMapRaised(display,windows->magnify.id);
15087 if (windows->pan.mapped != MagickFalse)
15088 (void) XMapRaised(display,windows->pan.id);
15089 windows->image.window_changes.width=(int) display_image->columns;
15090 windows->image.window_changes.height=(int) display_image->rows;
15091 (void) XConfigureImage(display,resource_info,windows,display_image,exception);
15092 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
15093 (void) XSync(display,MagickFalse);
15097 delay=display_image->delay/(size_t)
15098 MagickMax(display_image->ticks_per_second,1L);
15099 timer=GetMagickTime()+(time_t) (delay == 0 ? 1 : delay)+1;
15101 if (resource_info->update != MagickFalse)
15109 status=GetPathAttributes(display_image->filename,&attributes);
15110 if (status != MagickFalse)
15111 update_time=attributes.st_mtime;
15113 *state&=(
unsigned int) (~FormerImageState);
15114 *state&=(
unsigned int) (~MontageImageState);
15115 *state&=(
unsigned int) (~NextImageState);
15121 if (windows->image.mapped != MagickFalse)
15122 if ((display_image->delay != 0) || (resource_info->update != 0))
15124 if (timer < GetMagickTime())
15126 if (resource_info->update == MagickFalse)
15127 *state|=NextImageState | ExitState;
15136 status=GetPathAttributes(display_image->filename,&attributes);
15137 if (status != MagickFalse)
15138 if (update_time != attributes.st_mtime)
15143 (void) FormatLocaleString(
15144 resource_info->image_info->filename,MagickPathExtent,
15145 "%s:%s",display_image->magick,
15146 display_image->filename);
15147 nexus=ReadImage(resource_info->image_info,exception);
15148 if (nexus != (Image *) NULL)
15149 *state|=NextImageState | ExitState;
15151 delay=display_image->delay/(size_t) MagickMax(
15152 display_image->ticks_per_second,1L);
15153 timer=GetMagickTime()+(time_t) (delay == 0 ? 1 : delay)+1;
15156 if (XEventsQueued(display,QueuedAfterFlush) == 0)
15161 XDelay(display,SuspendTime << 2);
15165 timestamp=GetMagickTime();
15166 (void) XNextEvent(display,&event);
15167 if ((windows->image.stasis == MagickFalse) ||
15168 (windows->magnify.stasis == MagickFalse))
15170 if ((GetMagickTime()-timestamp) > 0)
15172 windows->image.stasis=MagickTrue;
15173 windows->magnify.stasis=MagickTrue;
15176 if (event.xany.window == windows->command.id)
15181 id=XCommandWidget(display,windows,CommandMenu,&event);
15184 (void) CopyMagickString(command,CommandMenu[
id],MagickPathExtent);
15185 display_command=CommandMenus[id];
15186 if (
id < MagickMenus)
15191 entry=XMenuWidget(display,windows,CommandMenu[
id],Menus[
id],
15195 (void) CopyMagickString(command,Menus[
id][entry],MagickPathExtent);
15196 display_command=Commands[id][entry];
15198 if (display_command != NullCommand)
15199 nexus=XMagickCommand(display,resource_info,windows,display_command,
15200 &display_image,exception);
15203 switch (event.type)
15207 if (resource_info->debug != MagickFalse)
15208 (void) LogMagickEvent(X11Event,GetMagickModule(),
15209 "Button Press: 0x%lx %u +%d+%d",event.xbutton.window,
15210 event.xbutton.button,event.xbutton.x,event.xbutton.y);
15211 if ((event.xbutton.button == Button3) &&
15212 (event.xbutton.state & Mod1Mask))
15217 event.xbutton.button=Button2;
15218 event.xbutton.state&=(
unsigned int) (~Mod1Mask);
15220 if (event.xbutton.window == windows->backdrop.id)
15222 (void) XSetInputFocus(display,event.xbutton.window,RevertToParent,
15223 event.xbutton.time);
15226 if (event.xbutton.window == windows->image.id)
15228 switch (event.xbutton.button)
15232 if (resource_info->immutable)
15237 entry=XMenuWidget(display,windows,
"Commands",VirtualMenu,
15240 nexus=XMagickCommand(display,resource_info,windows,
15241 VirtualCommands[entry],&display_image,exception);
15247 if (windows->command.mapped != MagickFalse)
15248 (void) XWithdrawWindow(display,windows->command.id,
15249 windows->command.screen);
15252 (void) XCommandWidget(display,windows,CommandMenu,
15254 (void) XMapRaised(display,windows->command.id);
15263 (void) XMagickCommand(display,resource_info,windows,ZoomCommand,
15264 &display_image,exception);
15265 XMagnifyImage(display,windows,&event,exception);
15270 if (resource_info->immutable)
15275 entry=XMenuWidget(display,windows,
"Commands",VirtualMenu,
15278 nexus=XMagickCommand(display,resource_info,windows,
15279 VirtualCommands[entry],&display_image,exception);
15282 if (display_image->montage != (
char *) NULL)
15287 nexus=XTileImage(display,resource_info,windows,
15288 display_image,&event,exception);
15289 if (nexus != (Image *) NULL)
15290 *state|=MontageImageState | NextImageState | ExitState;
15291 vid_info.x=(
short int) windows->image.x;
15292 vid_info.y=(
short int) windows->image.y;
15298 entry=XMenuWidget(display,windows,
"Short Cuts",ShortCutsMenu,
15301 nexus=XMagickCommand(display,resource_info,windows,
15302 ShortCutsCommands[entry],&display_image,exception);
15310 XTranslateImage(display,windows,*image,XK_Up);
15318 XTranslateImage(display,windows,*image,XK_Down);
15326 if (event.xbutton.window == windows->magnify.id)
15329 *
const MagnifyMenu[] =
15346 MagnifyCommands[] =
15361 factor=XMenuWidget(display,windows,
"Magnify",MagnifyMenu,command);
15363 XMagnifyWindowCommand(display,windows,0,MagnifyCommands[factor],
15367 if (event.xbutton.window == windows->pan.id)
15369 switch (event.xbutton.button)
15376 XTranslateImage(display,windows,*image,XK_Up);
15384 XTranslateImage(display,windows,*image,XK_Down);
15389 XPanImage(display,windows,&event,exception);
15395 delay=display_image->delay/(size_t)
15396 MagickMax(display_image->ticks_per_second,1L);
15397 timer=GetMagickTime()+(time_t) (delay == 0 ? 1 : delay)+1;
15400 case ButtonRelease:
15402 if (resource_info->debug != MagickFalse)
15403 (void) LogMagickEvent(X11Event,GetMagickModule(),
15404 "Button Release: 0x%lx %u +%d+%d",event.xbutton.window,
15405 event.xbutton.button,event.xbutton.x,event.xbutton.y);
15408 case ClientMessage:
15410 if (resource_info->debug != MagickFalse)
15411 (void) LogMagickEvent(X11Event,GetMagickModule(),
15412 "Client Message: 0x%lx 0x%lx %d 0x%lx",event.xclient.window,
15413 event.xclient.message_type,event.xclient.format,(
unsigned long)
15414 event.xclient.data.l[0]);
15415 if (event.xclient.message_type == windows->im_protocols)
15417 if (*event.xclient.data.l == (
long) windows->im_update_widget)
15419 (void) CloneString(&windows->command.name,MagickTitle);
15420 windows->command.data=MagickMenus;
15421 (void) XCommandWidget(display,windows,CommandMenu,
15425 if (*event.xclient.data.l == (
long) windows->im_update_colormap)
15430 for (i=0; i < (int) number_windows; i++)
15432 if (magick_windows[i]->
id == windows->icon.id)
15434 context_values.background=pixel->background_color.pixel;
15435 context_values.foreground=pixel->foreground_color.pixel;
15436 (void) XChangeGC(display,magick_windows[i]->annotate_context,
15437 context_mask,&context_values);
15438 (void) XChangeGC(display,magick_windows[i]->widget_context,
15439 context_mask,&context_values);
15440 context_values.background=pixel->foreground_color.pixel;
15441 context_values.foreground=pixel->background_color.pixel;
15442 context_values.plane_mask=context_values.background ^
15443 context_values.foreground;
15444 (void) XChangeGC(display,magick_windows[i]->highlight_context,
15445 (
size_t) (context_mask | GCPlaneMask),
15447 magick_windows[i]->attributes.background_pixel=
15448 pixel->background_color.pixel;
15449 magick_windows[i]->attributes.border_pixel=
15450 pixel->border_color.pixel;
15451 magick_windows[i]->attributes.colormap=map_info->colormap;
15452 (void) XChangeWindowAttributes(display,magick_windows[i]->
id,
15453 (
unsigned long) magick_windows[i]->mask,
15454 &magick_windows[i]->attributes);
15456 if (windows->pan.mapped != MagickFalse)
15458 (void) XSetWindowBackgroundPixmap(display,windows->pan.id,
15459 windows->pan.pixmap);
15460 (void) XClearWindow(display,windows->pan.id);
15461 XDrawPanRectangle(display,windows);
15463 if (windows->backdrop.id != (Window) NULL)
15464 (void) XInstallColormap(display,map_info->colormap);
15467 if (*event.xclient.data.l == (
long) windows->im_former_image)
15469 *state|=FormerImageState | ExitState;
15472 if (*event.xclient.data.l == (
long) windows->im_next_image)
15474 *state|=NextImageState | ExitState;
15477 if (*event.xclient.data.l == (
long) windows->im_retain_colors)
15479 *state|=RetainColorsState;
15482 if (*event.xclient.data.l == (
long) windows->im_exit)
15489 if (event.xclient.message_type == windows->dnd_protocols)
15509 if ((*event.xclient.data.l != 2) && (*event.xclient.data.l != 128))
15511 selection=XInternAtom(display,
"DndSelection",MagickFalse);
15512 status=XGetWindowProperty(display,root_window,selection,0L,(
long)
15513 MagickPathExtent,MagickFalse,(Atom) AnyPropertyType,&type,&format,
15514 &length,&after,&data);
15515 if ((status != Success) || (length == 0))
15517 if (*event.xclient.data.l == 2)
15522 (void) CopyMagickString(resource_info->image_info->filename,
15523 (
char *) data,MagickPathExtent);
15530 if (strncmp((
char *) data,
"file:", 5) != 0)
15532 (void) XFree((
void *) data);
15535 (void) CopyMagickString(resource_info->image_info->filename,
15536 ((
char *) data)+5,MagickPathExtent);
15538 nexus=ReadImage(resource_info->image_info,exception);
15539 CatchException(exception);
15540 if (nexus != (Image *) NULL)
15541 *state|=NextImageState | ExitState;
15542 (void) XFree((
void *) data);
15548 if (event.xclient.message_type != windows->wm_protocols)
15550 if (*event.xclient.data.l != (
long) windows->wm_delete_window)
15552 (void) XWithdrawWindow(display,event.xclient.window,
15553 visual_info->screen);
15554 if (event.xclient.window == windows->image.id)
15559 if (event.xclient.window == windows->pan.id)
15564 windows->image.window_changes.width=windows->image.ximage->width;
15565 windows->image.window_changes.height=windows->image.ximage->height;
15566 (void) XConfigureImage(display,resource_info,windows,
15567 display_image,exception);
15571 case ConfigureNotify:
15573 if (resource_info->debug != MagickFalse)
15574 (void) LogMagickEvent(X11Event,GetMagickModule(),
15575 "Configure Notify: 0x%lx %dx%d+%d+%d %d",event.xconfigure.window,
15576 event.xconfigure.width,event.xconfigure.height,event.xconfigure.x,
15577 event.xconfigure.y,event.xconfigure.send_event);
15578 if (event.xconfigure.window == windows->image.id)
15583 if (event.xconfigure.send_event != 0)
15591 if (windows->command.geometry == (
char *) NULL)
15592 if (windows->command.mapped == MagickFalse)
15594 windows->command.x=
event.xconfigure.x-(int)
15595 windows->command.width-25;
15596 windows->command.y=
event.xconfigure.y;
15597 XConstrainWindowPosition(display,&windows->command);
15598 window_changes.x=windows->command.x;
15599 window_changes.y=windows->command.y;
15600 (void) XReconfigureWMWindow(display,windows->command.id,
15601 windows->command.screen,(
unsigned int) (CWX | CWY),
15604 if (windows->widget.geometry == (
char *) NULL)
15605 if (windows->widget.mapped == MagickFalse)
15607 windows->widget.x=
event.xconfigure.x+
15608 event.xconfigure.width/10;
15609 windows->widget.y=
event.xconfigure.y+
15610 event.xconfigure.height/10;
15611 XConstrainWindowPosition(display,&windows->widget);
15612 window_changes.x=windows->widget.x;
15613 window_changes.y=windows->widget.y;
15614 (void) XReconfigureWMWindow(display,windows->widget.id,
15615 windows->widget.screen,(
unsigned int) (CWX | CWY),
15618 if (windows->magnify.geometry == (
char *) NULL)
15619 if (windows->magnify.mapped == MagickFalse)
15621 windows->magnify.x=
event.xconfigure.x+
15622 event.xconfigure.width+25;
15623 windows->magnify.y=
event.xconfigure.y;
15624 XConstrainWindowPosition(display,&windows->magnify);
15625 window_changes.x=windows->magnify.x;
15626 window_changes.y=windows->magnify.y;
15627 (void) XReconfigureWMWindow(display,windows->magnify.id,
15628 windows->magnify.screen,(
unsigned int) (CWX | CWY),
15631 if (windows->pan.geometry == (
char *) NULL)
15632 if (windows->pan.mapped == MagickFalse)
15634 windows->pan.x=
event.xconfigure.x+(int)
15635 event.xconfigure.width+25;
15636 windows->pan.y=
event.xconfigure.y+(int)
15637 windows->magnify.height+50;
15638 XConstrainWindowPosition(display,&windows->pan);
15639 window_changes.x=windows->pan.x;
15640 window_changes.y=windows->pan.y;
15641 (void) XReconfigureWMWindow(display,windows->pan.id,
15642 windows->pan.screen,(
unsigned int) (CWX | CWY),
15646 if ((event.xconfigure.width == (
int) windows->image.width) &&
15647 (event.xconfigure.height == (
int) windows->image.height))
15649 windows->image.width=(
unsigned int) event.xconfigure.width;
15650 windows->image.height=(
unsigned int) event.xconfigure.height;
15651 windows->image.x=0;
15652 windows->image.y=0;
15653 if (display_image->montage != (
char *) NULL)
15655 windows->image.x=vid_info.x;
15656 windows->image.y=vid_info.y;
15658 if (windows->image.mapped != MagickFalse &&
15659 windows->image.stasis != MagickFalse)
15664 windows->image.window_changes.width=
event.xconfigure.width;
15665 windows->image.window_changes.height=
event.xconfigure.height;
15666 (void) XConfigureImage(display,resource_info,windows,
15667 display_image,exception);
15672 if ((event.xconfigure.width < windows->image.ximage->width) ||
15673 (event.xconfigure.height < windows->image.ximage->height))
15675 (void) XMapRaised(display,windows->pan.id);
15676 XDrawPanRectangle(display,windows);
15679 if (windows->pan.mapped != MagickFalse)
15680 (void) XWithdrawWindow(display,windows->pan.id,
15681 windows->pan.screen);
15684 if (event.xconfigure.window == windows->magnify.id)
15692 windows->magnify.width=(
unsigned int) event.xconfigure.width;
15693 windows->magnify.height=(
unsigned int) event.xconfigure.height;
15694 if (windows->magnify.mapped == MagickFalse)
15697 while ((
int) magnify <= event.xconfigure.width)
15699 while ((
int) magnify <= event.xconfigure.height)
15702 if (((
int) magnify != event.xconfigure.width) ||
15703 ((
int) magnify != event.xconfigure.height))
15705 window_changes.width=(int) magnify;
15706 window_changes.height=(int) magnify;
15707 (void) XReconfigureWMWindow(display,windows->magnify.id,
15708 windows->magnify.screen,(
unsigned int) (CWWidth | CWHeight),
15712 if (windows->magnify.mapped != MagickFalse &&
15713 windows->magnify.stasis != MagickFalse)
15715 status=XMakeImage(display,resource_info,&windows->magnify,
15716 display_image,windows->magnify.width,windows->magnify.height,
15718 XMakeMagnifyImage(display,windows,exception);
15722 if (windows->magnify.mapped != MagickFalse &&
15723 (event.xconfigure.window == windows->pan.id))
15728 if (event.xconfigure.send_event != 0)
15730 windows->pan.x=
event.xconfigure.x;
15731 windows->pan.y=
event.xconfigure.y;
15733 windows->pan.width=(
unsigned int) event.xconfigure.width;
15734 windows->pan.height=(
unsigned int) event.xconfigure.height;
15737 if (event.xconfigure.window == windows->icon.id)
15742 windows->icon.width=(
unsigned int) event.xconfigure.width;
15743 windows->icon.height=(
unsigned int) event.xconfigure.height;
15748 case DestroyNotify:
15753 if (resource_info->debug != MagickFalse)
15754 (void) LogMagickEvent(X11Event,GetMagickModule(),
15755 "Destroy Notify: 0x%lx",event.xdestroywindow.window);
15756 if (event.xdestroywindow.window == windows->group_leader.id)
15768 if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
15769 if (event.xcrossing.mode != NotifyUngrab)
15770 XInstallColormap(display,map_info->colormap);
15775 if (resource_info->debug != MagickFalse)
15776 (void) LogMagickEvent(X11Event,GetMagickModule(),
15777 "Expose: 0x%lx %dx%d+%d+%d",event.xexpose.window,
15778 event.xexpose.width,event.xexpose.height,event.xexpose.x,
15783 if ((event.xexpose.window == windows->image.id) &&
15784 windows->image.mapped != MagickFalse)
15786 XRefreshWindow(display,&windows->image,&event);
15787 delay=display_image->delay/(size_t) MagickMax(
15788 display_image->ticks_per_second,1L);
15789 timer=GetMagickTime()+(time_t) (delay == 0 ? 1 : delay)+1;
15792 if ((event.xexpose.window == windows->magnify.id) &&
15793 windows->magnify.mapped != MagickFalse)
15795 XMakeMagnifyImage(display,windows,exception);
15798 if (event.xexpose.window == windows->pan.id)
15800 XDrawPanRectangle(display,windows);
15803 if (event.xexpose.window == windows->icon.id)
15805 XRefreshWindow(display,&windows->icon,&event);
15818 length=XLookupString((XKeyEvent *) &event.xkey,command,(
int)
15819 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
15820 *(command+length)=
'\0';
15821 if (resource_info->debug != MagickFalse)
15822 (void) LogMagickEvent(X11Event,GetMagickModule(),
15823 "Key press: %d 0x%lx (%s)",event.xkey.state,(
unsigned long)
15824 key_symbol,command);
15825 if (event.xkey.window == windows->image.id)
15827 display_command=XImageWindowCommand(display,resource_info,windows,
15828 event.xkey.state,key_symbol,&display_image,exception);
15829 if (display_command != NullCommand)
15830 nexus=XMagickCommand(display,resource_info,windows,
15831 display_command,&display_image,exception);
15833 if (event.xkey.window == windows->magnify.id)
15834 XMagnifyWindowCommand(display,windows,event.xkey.state,key_symbol,
15836 if (event.xkey.window == windows->pan.id)
15838 if ((key_symbol == XK_q) || (key_symbol == XK_Escape))
15839 (void) XWithdrawWindow(display,windows->pan.id,
15840 windows->pan.screen);
15842 if ((key_symbol == XK_F1) || (key_symbol == XK_Help))
15843 XTextViewHelp(display,resource_info,windows,MagickFalse,
15844 "Help Viewer - Image Pan",ImagePanHelp);
15846 XTranslateImage(display,windows,*image,key_symbol);
15848 delay=display_image->delay/(size_t) MagickMax(
15849 display_image->ticks_per_second,1L);
15850 timer=GetMagickTime()+(time_t) (delay == 0 ? 1 : delay)+1;
15858 (void) XLookupString((XKeyEvent *) &event.xkey,command,(
int)
15859 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
15860 if (resource_info->debug != MagickFalse)
15861 (void) LogMagickEvent(X11Event,GetMagickModule(),
15862 "Key release: 0x%lx (%c)",(
unsigned long) key_symbol,*command);
15870 if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
15871 if (event.xcrossing.mode != NotifyUngrab)
15872 XUninstallColormap(display,map_info->colormap);
15877 if (resource_info->debug != MagickFalse)
15878 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Map Notify: 0x%lx",
15879 event.xmap.window);
15880 if (event.xmap.window == windows->backdrop.id)
15882 (void) XSetInputFocus(display,event.xmap.window,RevertToParent,
15884 windows->backdrop.mapped=MagickTrue;
15887 if (event.xmap.window == windows->image.id)
15889 if (windows->backdrop.id != (Window) NULL)
15890 (void) XInstallColormap(display,map_info->colormap);
15891 if (LocaleCompare(display_image->magick,
"LOGO") == 0)
15893 if (LocaleCompare(display_image->filename,
"LOGO") == 0)
15894 nexus=XOpenImage(display,resource_info,windows,MagickFalse);
15896 if (((
int) windows->image.width < windows->image.ximage->width) ||
15897 ((
int) windows->image.height < windows->image.ximage->height))
15898 (void) XMapRaised(display,windows->pan.id);
15899 windows->image.mapped=MagickTrue;
15902 if (event.xmap.window == windows->magnify.id)
15904 XMakeMagnifyImage(display,windows,exception);
15905 windows->magnify.mapped=MagickTrue;
15906 (void) XWithdrawWindow(display,windows->info.id,
15907 windows->info.screen);
15910 if (event.xmap.window == windows->pan.id)
15912 XMakePanImage(display,resource_info,windows,display_image,
15914 windows->pan.mapped=MagickTrue;
15917 if (event.xmap.window == windows->info.id)
15919 windows->info.mapped=MagickTrue;
15922 if (event.xmap.window == windows->icon.id)
15930 taint=display_image->taint;
15931 XMakeStandardColormap(display,icon_visual,icon_resources,
15932 display_image,icon_map,icon_pixel,exception);
15933 (void) XMakeImage(display,icon_resources,&windows->icon,
15934 display_image,windows->icon.width,windows->icon.height,
15936 display_image->taint=taint;
15937 (void) XSetWindowBackgroundPixmap(display,windows->icon.id,
15938 windows->icon.pixmap);
15939 (void) XClearWindow(display,windows->icon.id);
15940 (void) XWithdrawWindow(display,windows->info.id,
15941 windows->info.screen);
15942 windows->icon.mapped=MagickTrue;
15945 if (event.xmap.window == windows->command.id)
15947 windows->command.mapped=MagickTrue;
15950 if (event.xmap.window == windows->popup.id)
15952 windows->popup.mapped=MagickTrue;
15955 if (event.xmap.window == windows->widget.id)
15957 windows->widget.mapped=MagickTrue;
15962 case MappingNotify:
15964 (void) XRefreshKeyboardMapping(&event.xmapping);
15969 case PropertyNotify:
15985 if (resource_info->debug != MagickFalse)
15986 (void) LogMagickEvent(X11Event,GetMagickModule(),
15987 "Property Notify: 0x%lx 0x%lx %d",event.xproperty.window,
15988 event.xproperty.atom,event.xproperty.state);
15989 if (event.xproperty.atom != windows->im_remote_command)
15994 status=XGetWindowProperty(display,event.xproperty.window,
15995 event.xproperty.atom,0L,(
long) MagickPathExtent,MagickFalse,(Atom)
15996 AnyPropertyType,&type,&format,&length,&after,&data);
15997 if ((status != Success) || (length == 0))
15999 if (LocaleCompare((
char *) data,
"-quit") == 0)
16001 XClientMessage(display,windows->image.id,windows->im_protocols,
16002 windows->im_exit,CurrentTime);
16003 (void) XFree((
void *) data);
16006 (void) CopyMagickString(resource_info->image_info->filename,
16007 (
char *) data,MagickPathExtent);
16008 (void) XFree((
void *) data);
16009 nexus=ReadImage(resource_info->image_info,exception);
16010 CatchException(exception);
16011 if (nexus != (Image *) NULL)
16012 *state|=NextImageState | ExitState;
16015 case ReparentNotify:
16017 if (resource_info->debug != MagickFalse)
16018 (void) LogMagickEvent(X11Event,GetMagickModule(),
16019 "Reparent Notify: 0x%lx=>0x%lx",event.xreparent.parent,
16020 event.xreparent.window);
16025 if (resource_info->debug != MagickFalse)
16026 (void) LogMagickEvent(X11Event,GetMagickModule(),
16027 "Unmap Notify: 0x%lx",event.xunmap.window);
16028 if (event.xunmap.window == windows->backdrop.id)
16030 windows->backdrop.mapped=MagickFalse;
16033 if (event.xunmap.window == windows->image.id)
16035 windows->image.mapped=MagickFalse;
16038 if (event.xunmap.window == windows->magnify.id)
16040 windows->magnify.mapped=MagickFalse;
16043 if (event.xunmap.window == windows->pan.id)
16045 windows->pan.mapped=MagickFalse;
16048 if (event.xunmap.window == windows->info.id)
16050 windows->info.mapped=MagickFalse;
16053 if (event.xunmap.window == windows->icon.id)
16055 if (map_info->colormap == icon_map->colormap)
16056 XConfigureImageColormap(display,resource_info,windows,
16057 display_image,exception);
16058 (void) XFreeStandardColormap(display,icon_visual,icon_map,
16060 windows->icon.mapped=MagickFalse;
16063 if (event.xunmap.window == windows->command.id)
16065 windows->command.mapped=MagickFalse;
16068 if (event.xunmap.window == windows->popup.id)
16070 if (windows->backdrop.id != (Window) NULL)
16071 (void) XSetInputFocus(display,windows->image.id,RevertToParent,
16073 windows->popup.mapped=MagickFalse;
16076 if (event.xunmap.window == windows->widget.id)
16078 if (windows->backdrop.id != (Window) NULL)
16079 (void) XSetInputFocus(display,windows->image.id,RevertToParent,
16081 windows->widget.mapped=MagickFalse;
16088 if (resource_info->debug != MagickFalse)
16089 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Event type: %d",
16094 }
while (!(*state & ExitState));
16095 if ((*state & ExitState) == 0)
16096 (void) XMagickCommand(display,resource_info,windows,FreeBuffersCommand,
16097 &display_image,exception);
16099 if (resource_info->confirm_edit != MagickFalse)
16104 if ((resource_info->immutable == MagickFalse) &&
16105 display_image->taint != MagickFalse)
16110 status=XConfirmWidget(display,windows,
"Your image changed.",
16111 "Do you want to save it");
16113 *state&=(
unsigned int) (~ExitState);
16116 (void) XMagickCommand(display,resource_info,windows,SaveCommand,
16117 &display_image,exception);
16120 if ((windows->visual_info->klass == GrayScale) ||
16121 (windows->visual_info->klass == PseudoColor) ||
16122 (windows->visual_info->klass == DirectColor))
16127 if (windows->info.mapped != MagickFalse)
16128 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
16129 if (windows->magnify.mapped != MagickFalse)
16130 (void) XWithdrawWindow(display,windows->magnify.id,
16131 windows->magnify.screen);
16132 if (windows->command.mapped != MagickFalse)
16133 (void) XWithdrawWindow(display,windows->command.id,
16134 windows->command.screen);
16136 if (windows->pan.mapped != MagickFalse)
16137 (void) XWithdrawWindow(display,windows->pan.id,windows->pan.screen);
16138 if (resource_info->backdrop == MagickFalse)
16139 if (windows->backdrop.mapped)
16141 (void) XWithdrawWindow(display,windows->backdrop.id,
16142 windows->backdrop.screen);
16143 (void) XDestroyWindow(display,windows->backdrop.id);
16144 windows->backdrop.id=(Window) NULL;
16145 (void) XWithdrawWindow(display,windows->image.id,
16146 windows->image.screen);
16147 (void) XDestroyWindow(display,windows->image.id);
16148 windows->image.id=(Window) NULL;
16150 XSetCursorState(display,windows,MagickTrue);
16151 XCheckRefreshWindows(display,windows);
16152 if (((*state & FormerImageState) != 0) || ((*state & NextImageState) != 0))
16153 *state&=(
unsigned int) (~ExitState);
16154 if (*state & ExitState)
16159 (void) XFreeStandardColormap(display,icon_visual,icon_map,icon_pixel);
16160 if (resource_info->map_type == (
char *) NULL)
16161 (void) XFreeStandardColormap(display,visual_info,map_info,pixel);
16165 if (resource_info->copy_image != (Image *) NULL)
16167 resource_info->copy_image=DestroyImage(resource_info->copy_image);
16168 resource_info->copy_image=NewImageList();
16170 DestroyXResources();
16172 (void) XSync(display,MagickFalse);
16176 (void) SetErrorHandler(warning_handler);
16177 (void) SetWarningHandler(warning_handler);
16181 directory=getcwd(working_directory,MagickPathExtent);
16187 if (*resource_info->home_directory ==
'\0')
16188 (void) CopyMagickString(resource_info->home_directory,
".",MagickPathExtent);
16189 status=chdir(resource_info->home_directory);
16191 (void) ThrowMagickException(exception,GetMagickModule(),FileOpenError,
16192 "UnableToOpenFile",
"%s",resource_info->home_directory);
16194 *image=display_image;
16228MagickExport MagickBooleanType DisplayImages(
const ImageInfo *image_info,
16229 Image *image,ExceptionInfo *exception)
16231 assert(image_info != (
const ImageInfo *) NULL);
16232 assert(image_info->signature == MagickCoreSignature);
16233 assert(image != (Image *) NULL);
16234 assert(image->signature == MagickCoreSignature);
16236 if (IsEventLogging() != MagickFalse)
16237 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
16238 (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError,
16239 "DelegateLibrarySupportNotBuiltIn",
"'%s' (X11)",image->filename);
16240 return(MagickFalse);
16273MagickExport MagickBooleanType RemoteDisplayCommand(
const ImageInfo *image_info,
16274 const char *window,
const char *filename,ExceptionInfo *exception)
16276 assert(image_info != (
const ImageInfo *) NULL);
16277 assert(image_info->signature == MagickCoreSignature);
16278 assert(filename != (
char *) NULL);
16279 if (IsEventLogging() != MagickFalse)
16280 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",filename);
16282 (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError,
16283 "DelegateLibrarySupportNotBuiltIn",
"'%s' (X11)",image_info->filename);
16284 return(MagickFalse);