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 *,
1545 *XMagickCommand(Display *,XResourceInfo *,XWindows *,
const DisplayCommand,
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 *,
1567 XDrawEditImage(Display *,XResourceInfo *,XWindows *,
Image **,
1569 XMatteEditImage(Display *,XResourceInfo *,XWindows *,
Image **,
1573 XRotateImage(Display *,XResourceInfo *,XWindows *,
double,
Image **,
1580 XDrawPanRectangle(Display *,XWindows *),
1581 XImageCache(Display *,XResourceInfo *,XWindows *,
const DisplayCommand,
Image **,
1583 XMagnifyImage(Display *,XWindows *,XEvent *,
ExceptionInfo *),
1586 XMagnifyWindowCommand(Display *,XWindows *,
const MagickStatusType,
1589 XScreenEvent(Display *,XWindows *,XEvent *,
ExceptionInfo *),
1590 XTranslateImage(Display *,XWindows *,
Image *,
const KeySym);
1621MagickExport MagickBooleanType DisplayImages(
const ImageInfo *image_info,
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,
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,
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,
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,
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,
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,
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,
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 < (crop_info.y+(
int) crop_info.height+RoiDelta)) &&
5052 (y > (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 < (crop_info.x+(
int) crop_info.width+RoiDelta)) &&
5059 (x > (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 < (crop_info.x+(
int) crop_info.width+RoiDelta)) &&
5068 (x > (crop_info.x+(
int) crop_info.width-RoiDelta)) &&
5069 (y < (crop_info.y+(
int) crop_info.height+RoiDelta)) &&
5070 (y > (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,
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,
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,
6697 delta[MagickPathExtent] =
"";
6700 Digits[] =
"01234567890";
6705 if ((key_symbol >= XK_0) && (key_symbol <= XK_9))
6707 if (((last_symbol < XK_0) || (last_symbol > XK_9)))
6710 resource_info->quantum=1;
6712 last_symbol=key_symbol;
6713 delta[strlen(delta)+1]=
'\0';
6714 delta[strlen(delta)]=Digits[key_symbol-XK_0];
6715 resource_info->quantum=StringToLong(delta);
6716 return(NullCommand);
6718 last_symbol=key_symbol;
6719 if (resource_info->immutable)
6727 return(InfoCommand);
6730 return(PrintCommand);
6732 return(NextCommand);
6735 return(QuitCommand);
6739 return(NullCommand);
6741 switch ((
int) key_symbol)
6745 if ((state & ControlMask) == 0)
6747 return(OpenCommand);
6750 return(NextCommand);
6752 return(FormerCommand);
6755 if ((state & Mod1Mask) != 0)
6756 return(SwirlCommand);
6757 if ((state & ControlMask) == 0)
6758 return(ShearCommand);
6759 return(SaveCommand);
6764 if ((state & Mod1Mask) != 0)
6765 return(OilPaintCommand);
6766 if ((state & Mod4Mask) != 0)
6767 return(ColorCommand);
6768 if ((state & ControlMask) == 0)
6769 return(NullCommand);
6770 return(PrintCommand);
6774 if ((state & Mod4Mask) != 0)
6775 return(DrawCommand);
6776 if ((state & ControlMask) == 0)
6777 return(NullCommand);
6778 return(DeleteCommand);
6782 if ((state & ControlMask) == 0)
6783 return(NullCommand);
6784 return(SelectCommand);
6788 if ((state & ControlMask) == 0)
6789 return(NullCommand);
6794 return(QuitCommand);
6798 if ((state & ControlMask) == 0)
6799 return(NullCommand);
6800 return(UndoCommand);
6805 if ((state & ControlMask) == 0)
6806 return(RollCommand);
6807 return(RedoCommand);
6811 if ((state & ControlMask) == 0)
6812 return(NullCommand);
6817 if ((state & Mod1Mask) != 0)
6818 return(CharcoalDrawCommand);
6819 if ((state & ControlMask) == 0)
6820 return(CropCommand);
6821 return(CopyCommand);
6826 if ((state & Mod4Mask) != 0)
6827 return(CompositeCommand);
6828 if ((state & ControlMask) == 0)
6829 return(FlipCommand);
6830 return(PasteCommand);
6833 return(HalfSizeCommand);
6835 return(OriginalSizeCommand);
6837 return(DoubleSizeCommand);
6839 return(ResizeCommand);
6841 return(RefreshCommand);
6842 case XK_bracketleft:
6843 return(ChopCommand);
6845 return(FlopCommand);
6847 return(RotateRightCommand);
6849 return(RotateLeftCommand);
6851 return(RotateCommand);
6853 return(TrimCommand);
6857 return(SaturationCommand);
6859 return(BrightnessCommand);
6861 return(GammaCommand);
6863 return(SpiffCommand);
6865 return(DullCommand);
6867 return(NormalizeCommand);
6869 return(EqualizeCommand);
6871 return(NegateCommand);
6873 return(GrayscaleCommand);
6875 return(QuantizeCommand);
6877 return(DespeckleCommand);
6879 return(EmbossCommand);
6881 return(ReduceNoiseCommand);
6883 return(AddNoiseCommand);
6885 return(SharpenCommand);
6887 return(BlurCommand);
6889 return(ThresholdCommand);
6891 return(EdgeDetectCommand);
6893 return(SpreadCommand);
6895 return(ShadeCommand);
6897 return(RaiseCommand);
6899 return(SegmentCommand);
6902 if ((state & Mod1Mask) == 0)
6903 return(NullCommand);
6904 return(ImplodeCommand);
6908 if ((state & Mod1Mask) == 0)
6909 return(NullCommand);
6910 return(WaveCommand);
6914 if ((state & Mod4Mask) == 0)
6915 return(NullCommand);
6916 return(MatteCommand);
6920 if ((state & Mod4Mask) == 0)
6921 return(NullCommand);
6922 return(AddBorderCommand);
6926 if ((state & Mod4Mask) == 0)
6927 return(NullCommand);
6928 return(AddFrameCommand);
6932 if ((state & Mod4Mask) == 0)
6933 return(NullCommand);
6934 return(CommentCommand);
6938 if ((state & Mod1Mask) != 0)
6939 return(ApplyCommand);
6940 if ((state & Mod4Mask) != 0)
6941 return(AnnotateCommand);
6942 if ((state & ControlMask) == 0)
6943 return(NullCommand);
6944 return(RegionOfInterestCommand);
6947 return(InfoCommand);
6949 return(ZoomCommand);
6952 if ((state & ShiftMask) == 0)
6953 return(NullCommand);
6954 return(ShowPreviewCommand);
6957 return(LaunchCommand);
6959 return(HelpCommand);
6961 return(BrowseDocumentationCommand);
6964 (void) XMapRaised(display,windows->command.id);
6965 return(NullCommand);
6972 XTranslateImage(display,windows,*image,key_symbol);
6973 return(NullCommand);
6984 if ((state & Mod1Mask) != 0)
6994 crop_info.width=(size_t) windows->image.ximage->width;
6995 crop_info.height=(size_t) windows->image.ximage->height;
6996 if ((key_symbol == XK_Up) || (key_symbol == XK_KP_Up))
6998 if (resource_info->quantum >= (
int) crop_info.height)
6999 resource_info->quantum=(int) crop_info.height-1;
7000 crop_info.height-=(size_t) resource_info->quantum;
7002 if ((key_symbol == XK_Down) || (key_symbol == XK_KP_Down))
7004 if (resource_info->quantum >= ((
int) crop_info.height-crop_info.y))
7005 resource_info->quantum=(int) crop_info.height-crop_info.y-1;
7006 crop_info.y+=resource_info->quantum;
7007 crop_info.height-=(size_t) resource_info->quantum;
7009 if ((key_symbol == XK_Left) || (key_symbol == XK_KP_Left))
7011 if (resource_info->quantum >= (
int) crop_info.width)
7012 resource_info->quantum=(int) crop_info.width-1;
7013 crop_info.width-=(size_t) resource_info->quantum;
7015 if ((key_symbol == XK_Right) || (key_symbol == XK_KP_Right))
7017 if (resource_info->quantum >= ((
int) crop_info.width-crop_info.x))
7018 resource_info->quantum=(int) crop_info.width-crop_info.x-1;
7019 crop_info.x+=resource_info->quantum;
7020 crop_info.width-=(size_t) resource_info->quantum;
7022 if ((windows->image.x+(
int) windows->image.width) > (
int) crop_info.width)
7023 windows->image.x=(int) (crop_info.width-windows->image.width);
7024 if ((windows->image.y+(
int) windows->image.height) > (
int) crop_info.height)
7025 windows->image.y=(int) (crop_info.height-windows->image.height);
7026 XSetCropGeometry(display,windows,&crop_info,*image);
7027 windows->image.window_changes.width=(int) crop_info.width;
7028 windows->image.window_changes.height=(int) crop_info.height;
7029 (void) XSetWindowBackgroundPixmap(display,windows->image.id,None);
7030 (void) XConfigureImage(display,resource_info,windows,*image,
7032 return(NullCommand);
7034 XTranslateImage(display,windows,*image,key_symbol);
7035 return(NullCommand);
7038 return(NullCommand);
7040 return(NullCommand);
7080static Image *XMagickCommand(Display *display,XResourceInfo *resource_info,
7081 XWindows *windows,
const DisplayCommand command,
Image **image,
7085 filename[MagickPathExtent],
7086 geometry[MagickPathExtent],
7087 modulate_factors[MagickPathExtent];
7116 color[MagickPathExtent] =
"gray";
7125 XCheckRefreshWindows(display,windows);
7126 XImageCache(display,resource_info,windows,command,image,exception);
7127 nexus=NewImageList();
7128 windows->image.window_changes.width=windows->image.ximage->width;
7129 windows->image.window_changes.height=windows->image.ximage->height;
7130 image_info=CloneImageInfo(resource_info->image_info);
7131 SetGeometryInfo(&geometry_info);
7132 GetQuantizeInfo(&quantize_info);
7140 nexus=XOpenImage(display,resource_info,windows,MagickFalse);
7148 for (i=0; i < resource_info->quantum; i++)
7149 XClientMessage(display,windows->image.id,windows->im_protocols,
7150 windows->im_next_image,CurrentTime);
7158 for (i=0; i < resource_info->quantum; i++)
7159 XClientMessage(display,windows->image.id,windows->im_protocols,
7160 windows->im_former_image,CurrentTime);
7171 if (*resource_info->home_directory ==
'\0')
7172 (void) CopyMagickString(resource_info->home_directory,
".",
7174 status=chdir(resource_info->home_directory);
7176 (void) ThrowMagickException(exception,GetMagickModule(),FileOpenError,
7177 "UnableToOpenFile",
"%s",resource_info->home_directory);
7178 nexus=XOpenImage(display,resource_info,windows,MagickTrue);
7186 status=XSaveImage(display,resource_info,windows,*image,exception);
7187 if (status == MagickFalse)
7190 message[MagickPathExtent];
7192 (void) FormatLocaleString(message,MagickPathExtent,
"%s:%s",
7193 exception->reason != (
char *) NULL ? exception->reason :
"",
7194 exception->description != (
char *) NULL ? exception->description :
7196 XNoticeWidget(display,windows,
"Unable to save file:",message);
7206 status=XPrintImage(display,resource_info,windows,*image,exception);
7207 if (status == MagickFalse)
7210 message[MagickPathExtent];
7212 (void) FormatLocaleString(message,MagickPathExtent,
"%s:%s",
7213 exception->reason != (
char *) NULL ? exception->reason :
"",
7214 exception->description != (
char *) NULL ? exception->description :
7216 XNoticeWidget(display,windows,
"Unable to print file:",message);
7224 filename[MagickPathExtent] =
"\0";
7229 XFileBrowserWidget(display,windows,
"Delete",filename);
7230 if (*filename ==
'\0')
7232 status=ShredFile(filename);
7233 if (remove_utf8(filename) < 0)
7235 if (status != MagickFalse)
7236 XNoticeWidget(display,windows,
"Unable to delete image file:",filename);
7245 color[MagickPathExtent] =
"gray",
7246 geometry[MagickPathExtent] =
"640x480";
7249 *format =
"gradient";
7254 status=XDialogWidget(display,windows,
"New",
"Enter image geometry:",
7256 if (*geometry ==
'\0')
7260 XColorBrowserWidget(display,windows,
"Select",color);
7266 (void) FormatLocaleString(image_info->filename,MagickPathExtent,
7267 "%s:%s",format,color);
7268 (void) CloneString(&image_info->size,geometry);
7269 nexus=ReadImage(image_info,exception);
7270 CatchException(exception);
7271 XClientMessage(display,windows->image.id,windows->im_protocols,
7272 windows->im_next_image,CurrentTime);
7275 case VisualDirectoryCommand:
7280 nexus=XVisualDirectoryImage(display,resource_info,windows,exception);
7288 if (resource_info->confirm_exit == MagickFalse)
7289 XClientMessage(display,windows->image.id,windows->im_protocols,
7290 windows->im_exit,CurrentTime);
7299 status=XConfirmWidget(display,windows,
"Do you really want to exit",
7300 resource_info->client_name);
7302 XClientMessage(display,windows->image.id,windows->im_protocols,
7303 windows->im_exit,CurrentTime);
7312 (void) XCropImage(display,resource_info,windows,*image,CutMode,exception);
7320 (void) XCropImage(display,resource_info,windows,*image,CopyMode,
7329 status=XPasteImage(display,resource_info,windows,*image,exception);
7330 if (status == MagickFalse)
7332 XNoticeWidget(display,windows,
"Unable to paste X image",
7333 (*image)->filename);
7338 case HalfSizeCommand:
7343 windows->image.window_changes.width=windows->image.ximage->width/2;
7344 windows->image.window_changes.height=windows->image.ximage->height/2;
7345 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7348 case OriginalSizeCommand:
7353 windows->image.window_changes.width=(int) (*image)->columns;
7354 windows->image.window_changes.height=(int) (*image)->rows;
7355 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7358 case DoubleSizeCommand:
7363 windows->image.window_changes.width=windows->image.ximage->width << 1;
7364 windows->image.window_changes.height=windows->image.ximage->height << 1;
7365 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7384 width=(size_t) windows->image.ximage->width;
7385 height=(size_t) windows->image.ximage->height;
7388 (void) FormatLocaleString(geometry,MagickPathExtent,
"%.20gx%.20g+0+0",
7389 (
double) width,(
double) height);
7390 status=XDialogWidget(display,windows,
"Resize",
7391 "Enter resize geometry (e.g. 640x480, 200%):",geometry);
7392 if (*geometry ==
'\0')
7395 (void) ConcatenateMagickString(geometry,
"!",MagickPathExtent);
7396 (void) ParseMetaGeometry(geometry,&x,&y,&width,&height);
7397 windows->image.window_changes.width=(int) width;
7398 windows->image.window_changes.height=(int) height;
7399 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7405 image_geometry[MagickPathExtent];
7407 if ((windows->image.crop_geometry == (
char *) NULL) &&
7408 ((
int) (*image)->columns == windows->image.ximage->width) &&
7409 ((
int) (*image)->rows == windows->image.ximage->height))
7414 XSetCursorState(display,windows,MagickTrue);
7415 XCheckRefreshWindows(display,windows);
7419 (void) FormatLocaleString(image_geometry,MagickPathExtent,
"%dx%d!",
7420 windows->image.ximage->width,windows->image.ximage->height);
7421 (void) TransformImage(image,windows->image.crop_geometry,image_geometry,
7423 if (windows->image.crop_geometry != (
char *) NULL)
7424 windows->image.crop_geometry=(
char *) RelinquishMagickMemory(
7425 windows->image.crop_geometry);
7428 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7429 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7432 case RefreshCommand:
7434 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7437 case RestoreCommand:
7442 if ((windows->image.width == (
unsigned int) (*image)->columns) &&
7443 (windows->image.height == (
unsigned int) (*image)->rows) &&
7444 (windows->image.crop_geometry == (
char *) NULL))
7446 (void) XBell(display,0);
7449 windows->image.window_changes.width=(int) (*image)->columns;
7450 windows->image.window_changes.height=(int) (*image)->rows;
7451 if (windows->image.crop_geometry != (
char *) NULL)
7453 windows->image.crop_geometry=(
char *)
7454 RelinquishMagickMemory(windows->image.crop_geometry);
7455 windows->image.crop_geometry=(
char *) NULL;
7459 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7460 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7468 (void) XCropImage(display,resource_info,windows,*image,CropMode,
7477 status=XChopImage(display,resource_info,windows,image,exception);
7478 if (status == MagickFalse)
7480 XNoticeWidget(display,windows,
"Unable to cut X image",
7481 (*image)->filename);
7494 XSetCursorState(display,windows,MagickTrue);
7495 XCheckRefreshWindows(display,windows);
7496 flop_image=FlopImage(*image,exception);
7497 if (flop_image != (
Image *) NULL)
7499 *image=DestroyImage(*image);
7502 CatchException(exception);
7503 XSetCursorState(display,windows,MagickFalse);
7504 if (windows->image.crop_geometry != (
char *) NULL)
7509 width=(
unsigned int) (*image)->columns;
7510 height=(
unsigned int) (*image)->rows;
7511 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
7513 (void) FormatLocaleString(windows->image.crop_geometry,
7514 MagickPathExtent,
"%ux%u%+d%+d",width,height,(
int) (*image)->columns-
7517 if (windows->image.orphan != MagickFalse)
7519 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7530 XSetCursorState(display,windows,MagickTrue);
7531 XCheckRefreshWindows(display,windows);
7532 flip_image=FlipImage(*image,exception);
7533 if (flip_image != (
Image *) NULL)
7535 *image=DestroyImage(*image);
7538 CatchException(exception);
7539 XSetCursorState(display,windows,MagickFalse);
7540 if (windows->image.crop_geometry != (
char *) NULL)
7545 width=(
unsigned int) (*image)->columns;
7546 height=(
unsigned int) (*image)->rows;
7547 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
7549 (void) FormatLocaleString(windows->image.crop_geometry,
7550 MagickPathExtent,
"%ux%u%+d%+d",width,height,x,(
int) (*image)->rows-
7553 if (windows->image.orphan != MagickFalse)
7555 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7558 case RotateRightCommand:
7563 status=XRotateImage(display,resource_info,windows,90.0,image,exception);
7564 if (status == MagickFalse)
7566 XNoticeWidget(display,windows,
"Unable to rotate X image",
7567 (*image)->filename);
7572 case RotateLeftCommand:
7577 status=XRotateImage(display,resource_info,windows,-90.0,image,exception);
7578 if (status == MagickFalse)
7580 XNoticeWidget(display,windows,
"Unable to rotate X image",
7581 (*image)->filename);
7591 status=XRotateImage(display,resource_info,windows,0.0,image,exception);
7592 if (status == MagickFalse)
7594 XNoticeWidget(display,windows,
"Unable to rotate X image",
7595 (*image)->filename);
7606 geometry[MagickPathExtent] =
"45.0x45.0";
7611 XColorBrowserWidget(display,windows,
"Select",color);
7614 (void) XDialogWidget(display,windows,
"Shear",
"Enter shear geometry:",
7616 if (*geometry ==
'\0')
7621 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
7623 XSetCursorState(display,windows,MagickTrue);
7624 XCheckRefreshWindows(display,windows);
7625 (void) QueryColorCompliance(color,AllCompliance,
7626 &(*image)->background_color,exception);
7627 flags=ParseGeometry(geometry,&geometry_info);
7628 if ((flags & SigmaValue) == 0)
7629 geometry_info.sigma=geometry_info.rho;
7630 shear_image=ShearImage(*image,geometry_info.rho,geometry_info.sigma,
7632 if (shear_image != (
Image *) NULL)
7634 *image=DestroyImage(*image);
7637 CatchException(exception);
7638 XSetCursorState(display,windows,MagickFalse);
7639 if (windows->image.orphan != MagickFalse)
7641 windows->image.window_changes.width=(int) (*image)->columns;
7642 windows->image.window_changes.height=(int) (*image)->rows;
7643 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7644 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7653 geometry[MagickPathExtent] =
"+2+2";
7658 (void) XDialogWidget(display,windows,
"Roll",
"Enter roll geometry:",
7660 if (*geometry ==
'\0')
7665 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
7667 XSetCursorState(display,windows,MagickTrue);
7668 XCheckRefreshWindows(display,windows);
7669 (void) ParsePageGeometry(*image,geometry,&page_geometry,
7671 roll_image=RollImage(*image,page_geometry.x,page_geometry.y,
7673 if (roll_image != (
Image *) NULL)
7675 *image=DestroyImage(*image);
7678 CatchException(exception);
7679 XSetCursorState(display,windows,MagickFalse);
7680 if (windows->image.orphan != MagickFalse)
7682 windows->image.window_changes.width=(int) (*image)->columns;
7683 windows->image.window_changes.height=(int) (*image)->rows;
7684 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7685 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7691 fuzz[MagickPathExtent];
7696 (void) FormatLocaleString(fuzz,MagickPathExtent,
"%g%%",100.0*
7697 (*image)->fuzz/((
double) QuantumRange+1.0));
7698 (void) XDialogWidget(display,windows,
"Trim",
"Enter fuzz factor:",fuzz);
7701 (*image)->fuzz=StringToDoubleInterval(fuzz,(
double) QuantumRange+1.0);
7705 status=XTrimImage(display,resource_info,windows,*image,exception);
7706 if (status == MagickFalse)
7708 XNoticeWidget(display,windows,
"Unable to trim X image",
7709 (*image)->filename);
7717 hue_percent[MagickPathExtent] =
"110";
7722 (void) XDialogWidget(display,windows,
"Apply",
7723 "Enter percent change in image hue (0-200):",hue_percent);
7724 if (*hue_percent ==
'\0')
7729 XSetCursorState(display,windows,MagickTrue);
7730 XCheckRefreshWindows(display,windows);
7731 (void) CopyMagickString(modulate_factors,
"100.0/100.0/",MagickPathExtent);
7732 (void) ConcatenateMagickString(modulate_factors,hue_percent,
7734 (void) ModulateImage(*image,modulate_factors,exception);
7735 XSetCursorState(display,windows,MagickFalse);
7736 if (windows->image.orphan != MagickFalse)
7738 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7739 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7742 case SaturationCommand:
7745 saturation_percent[MagickPathExtent] =
"110";
7750 (void) XDialogWidget(display,windows,
"Apply",
7751 "Enter percent change in color saturation (0-200):",saturation_percent);
7752 if (*saturation_percent ==
'\0')
7757 XSetCursorState(display,windows,MagickTrue);
7758 XCheckRefreshWindows(display,windows);
7759 (void) CopyMagickString(modulate_factors,
"100.0/",MagickPathExtent);
7760 (void) ConcatenateMagickString(modulate_factors,saturation_percent,
7762 (void) ModulateImage(*image,modulate_factors,exception);
7763 XSetCursorState(display,windows,MagickFalse);
7764 if (windows->image.orphan != MagickFalse)
7766 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7767 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7770 case BrightnessCommand:
7773 brightness_percent[MagickPathExtent] =
"110";
7778 (void) XDialogWidget(display,windows,
"Apply",
7779 "Enter percent change in color brightness (0-200):",brightness_percent);
7780 if (*brightness_percent ==
'\0')
7785 XSetCursorState(display,windows,MagickTrue);
7786 XCheckRefreshWindows(display,windows);
7787 (void) CopyMagickString(modulate_factors,brightness_percent,
7789 (void) ModulateImage(*image,modulate_factors,exception);
7790 XSetCursorState(display,windows,MagickFalse);
7791 if (windows->image.orphan != MagickFalse)
7793 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7794 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7800 factor[MagickPathExtent] =
"1.6";
7805 (void) XDialogWidget(display,windows,
"Gamma",
7806 "Enter gamma value (e.g. 1.2):",factor);
7807 if (*factor ==
'\0')
7812 XSetCursorState(display,windows,MagickTrue);
7813 XCheckRefreshWindows(display,windows);
7814 (void) GammaImage(*image,strtod(factor,(
char **) NULL),exception);
7815 XSetCursorState(display,windows,MagickFalse);
7816 if (windows->image.orphan != MagickFalse)
7818 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7819 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7827 XSetCursorState(display,windows,MagickTrue);
7828 XCheckRefreshWindows(display,windows);
7829 (void) ContrastImage(*image,MagickTrue,exception);
7830 XSetCursorState(display,windows,MagickFalse);
7831 if (windows->image.orphan != MagickFalse)
7833 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7834 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7842 XSetCursorState(display,windows,MagickTrue);
7843 XCheckRefreshWindows(display,windows);
7844 (void) ContrastImage(*image,MagickFalse,exception);
7845 XSetCursorState(display,windows,MagickFalse);
7846 if (windows->image.orphan != MagickFalse)
7848 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7849 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7852 case ContrastStretchCommand:
7859 levels[MagickPathExtent] =
"1%";
7864 (void) XDialogWidget(display,windows,
"Contrast Stretch",
7865 "Enter black and white points:",levels);
7866 if (*levels ==
'\0')
7871 XSetCursorState(display,windows,MagickTrue);
7872 XCheckRefreshWindows(display,windows);
7873 flags=ParseGeometry(levels,&geometry_info);
7874 black_point=geometry_info.rho;
7875 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma : black_point;
7876 if ((flags & PercentValue) != 0)
7878 black_point*=(double) (*image)->columns*(*image)->rows/100.0;
7879 white_point*=(double) (*image)->columns*(*image)->rows/100.0;
7881 white_point=(double) (*image)->columns*(*image)->rows-white_point;
7882 (void) ContrastStretchImage(*image,black_point,white_point,
7884 XSetCursorState(display,windows,MagickFalse);
7885 if (windows->image.orphan != MagickFalse)
7887 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7888 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7891 case SigmoidalContrastCommand:
7900 levels[MagickPathExtent] =
"3x50%";
7905 (void) XDialogWidget(display,windows,
"Sigmoidal Contrast",
7906 "Enter contrast and midpoint:",levels);
7907 if (*levels ==
'\0')
7912 XSetCursorState(display,windows,MagickTrue);
7913 XCheckRefreshWindows(display,windows);
7914 flags=ParseGeometry(levels,&geometry_info);
7915 if ((flags & SigmaValue) == 0)
7916 geometry_info.sigma=1.0*(double) QuantumRange/2.0;
7917 if ((flags & PercentValue) != 0)
7918 geometry_info.sigma=1.0*(double) QuantumRange*geometry_info.sigma/100.0;
7919 (void) SigmoidalContrastImage(*image,MagickTrue,geometry_info.rho,
7920 geometry_info.sigma,exception);
7921 XSetCursorState(display,windows,MagickFalse);
7922 if (windows->image.orphan != MagickFalse)
7924 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7925 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7928 case NormalizeCommand:
7933 XSetCursorState(display,windows,MagickTrue);
7934 XCheckRefreshWindows(display,windows);
7935 (void) NormalizeImage(*image,exception);
7936 XSetCursorState(display,windows,MagickFalse);
7937 if (windows->image.orphan != MagickFalse)
7939 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7940 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7943 case EqualizeCommand:
7948 XSetCursorState(display,windows,MagickTrue);
7949 XCheckRefreshWindows(display,windows);
7950 (void) EqualizeImage(*image,exception);
7951 XSetCursorState(display,windows,MagickFalse);
7952 if (windows->image.orphan != MagickFalse)
7954 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7955 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7963 XSetCursorState(display,windows,MagickTrue);
7964 XCheckRefreshWindows(display,windows);
7965 (void) NegateImage(*image,MagickFalse,exception);
7966 XSetCursorState(display,windows,MagickFalse);
7967 if (windows->image.orphan != MagickFalse)
7969 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7970 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7973 case GrayscaleCommand:
7978 XSetCursorState(display,windows,MagickTrue);
7979 XCheckRefreshWindows(display,windows);
7980 (void) SetImageType(*image,(*image)->alpha_trait == UndefinedPixelTrait ?
7981 GrayscaleType : GrayscaleAlphaType,exception);
7982 XSetCursorState(display,windows,MagickFalse);
7983 if (windows->image.orphan != MagickFalse)
7985 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7986 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7995 filename[MagickPathExtent] =
"\0";
8000 XFileBrowserWidget(display,windows,
"Map",filename);
8001 if (*filename ==
'\0')
8006 XSetCursorState(display,windows,MagickTrue);
8007 XCheckRefreshWindows(display,windows);
8008 (void) CopyMagickString(image_info->filename,filename,MagickPathExtent);
8009 affinity_image=ReadImage(image_info,exception);
8010 if (affinity_image != (
Image *) NULL)
8012 (void) RemapImage(&quantize_info,*image,affinity_image,exception);
8013 affinity_image=DestroyImage(affinity_image);
8015 CatchException(exception);
8016 XSetCursorState(display,windows,MagickFalse);
8017 if (windows->image.orphan != MagickFalse)
8019 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8020 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8023 case QuantizeCommand:
8029 colors[MagickPathExtent] =
"256";
8034 status=XDialogWidget(display,windows,
"Quantize",
8035 "Maximum number of colors:",colors);
8036 if (*colors ==
'\0')
8041 XSetCursorState(display,windows,MagickTrue);
8042 XCheckRefreshWindows(display,windows);
8043 quantize_info.number_colors=StringToUnsignedLong(colors);
8044 quantize_info.dither_method=status != 0 ? RiemersmaDitherMethod :
8046 (void) QuantizeImage(&quantize_info,*image,exception);
8047 XSetCursorState(display,windows,MagickFalse);
8048 if (windows->image.orphan != MagickFalse)
8050 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8051 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8054 case DespeckleCommand:
8062 XSetCursorState(display,windows,MagickTrue);
8063 XCheckRefreshWindows(display,windows);
8064 despeckle_image=DespeckleImage(*image,exception);
8065 if (despeckle_image != (
Image *) NULL)
8067 *image=DestroyImage(*image);
8068 *image=despeckle_image;
8070 CatchException(exception);
8071 XSetCursorState(display,windows,MagickFalse);
8072 if (windows->image.orphan != MagickFalse)
8074 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8075 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8084 radius[MagickPathExtent] =
"0.0x1.0";
8089 (void) XDialogWidget(display,windows,
"Emboss",
8090 "Enter the emboss radius and standard deviation:",radius);
8091 if (*radius ==
'\0')
8096 XSetCursorState(display,windows,MagickTrue);
8097 XCheckRefreshWindows(display,windows);
8098 flags=ParseGeometry(radius,&geometry_info);
8099 if ((flags & SigmaValue) == 0)
8100 geometry_info.sigma=1.0;
8101 emboss_image=EmbossImage(*image,geometry_info.rho,geometry_info.sigma,
8103 if (emboss_image != (
Image *) NULL)
8105 *image=DestroyImage(*image);
8106 *image=emboss_image;
8108 CatchException(exception);
8109 XSetCursorState(display,windows,MagickFalse);
8110 if (windows->image.orphan != MagickFalse)
8112 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8113 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8116 case ReduceNoiseCommand:
8122 radius[MagickPathExtent] =
"0";
8127 (void) XDialogWidget(display,windows,
"Reduce Noise",
8128 "Enter the noise radius:",radius);
8129 if (*radius ==
'\0')
8134 XSetCursorState(display,windows,MagickTrue);
8135 XCheckRefreshWindows(display,windows);
8136 flags=ParseGeometry(radius,&geometry_info);
8137 noise_image=StatisticImage(*image,NonpeakStatistic,(
size_t)
8138 geometry_info.rho,(
size_t) geometry_info.rho,exception);
8139 if (noise_image != (
Image *) NULL)
8141 *image=DestroyImage(*image);
8144 CatchException(exception);
8145 XSetCursorState(display,windows,MagickFalse);
8146 if (windows->image.orphan != MagickFalse)
8148 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8149 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8152 case AddNoiseCommand:
8161 noise_type[MagickPathExtent] =
"Gaussian";
8166 noises=GetCommandOptions(MagickNoiseOptions);
8167 if (noises == (
char **) NULL)
8169 XListBrowserWidget(display,windows,&windows->widget,
8170 (
const char **) noises,
"Add Noise",
8171 "Select a type of noise to add to your image:",noise_type);
8172 noises=DestroyStringList(noises);
8173 if (*noise_type ==
'\0')
8175 XSetCursorState(display,windows,MagickTrue);
8176 XCheckRefreshWindows(display,windows);
8177 noise_image=AddNoiseImage(*image,(NoiseType) ParseCommandOption(
8178 MagickNoiseOptions,MagickFalse,noise_type),1.0,exception);
8179 if (noise_image != (
Image *) NULL)
8181 *image=DestroyImage(*image);
8184 CatchException(exception);
8185 XSetCursorState(display,windows,MagickFalse);
8186 if (windows->image.orphan != MagickFalse)
8188 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8189 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8192 case SharpenCommand:
8198 radius[MagickPathExtent] =
"0.0x1.0";
8203 (void) XDialogWidget(display,windows,
"Sharpen",
8204 "Enter the sharpen radius and standard deviation:",radius);
8205 if (*radius ==
'\0')
8210 XSetCursorState(display,windows,MagickTrue);
8211 XCheckRefreshWindows(display,windows);
8212 flags=ParseGeometry(radius,&geometry_info);
8213 sharp_image=SharpenImage(*image,geometry_info.rho,geometry_info.sigma,
8215 if (sharp_image != (
Image *) NULL)
8217 *image=DestroyImage(*image);
8220 CatchException(exception);
8221 XSetCursorState(display,windows,MagickFalse);
8222 if (windows->image.orphan != MagickFalse)
8224 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8225 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8234 radius[MagickPathExtent] =
"0.0x1.0";
8239 (void) XDialogWidget(display,windows,
"Blur",
8240 "Enter the blur radius and standard deviation:",radius);
8241 if (*radius ==
'\0')
8246 XSetCursorState(display,windows,MagickTrue);
8247 XCheckRefreshWindows(display,windows);
8248 flags=ParseGeometry(radius,&geometry_info);
8249 blur_image=BlurImage(*image,geometry_info.rho,geometry_info.sigma,
8251 if (blur_image != (
Image *) NULL)
8253 *image=DestroyImage(*image);
8256 CatchException(exception);
8257 XSetCursorState(display,windows,MagickFalse);
8258 if (windows->image.orphan != MagickFalse)
8260 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8261 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8264 case ThresholdCommand:
8270 factor[MagickPathExtent] =
"128";
8275 (void) XDialogWidget(display,windows,
"Threshold",
8276 "Enter threshold value:",factor);
8277 if (*factor ==
'\0')
8282 XSetCursorState(display,windows,MagickTrue);
8283 XCheckRefreshWindows(display,windows);
8284 threshold=StringToDoubleInterval(factor,(
double) QuantumRange+1.0);
8285 (void) BilevelImage(*image,threshold,exception);
8286 XSetCursorState(display,windows,MagickFalse);
8287 if (windows->image.orphan != MagickFalse)
8289 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8290 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8293 case EdgeDetectCommand:
8299 radius[MagickPathExtent] =
"0";
8304 (void) XDialogWidget(display,windows,
"Detect Edges",
8305 "Enter the edge detect radius:",radius);
8306 if (*radius ==
'\0')
8311 XSetCursorState(display,windows,MagickTrue);
8312 XCheckRefreshWindows(display,windows);
8313 flags=ParseGeometry(radius,&geometry_info);
8314 edge_image=EdgeImage(*image,geometry_info.rho,exception);
8315 if (edge_image != (
Image *) NULL)
8317 *image=DestroyImage(*image);
8320 CatchException(exception);
8321 XSetCursorState(display,windows,MagickFalse);
8322 if (windows->image.orphan != MagickFalse)
8324 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8325 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8334 amount[MagickPathExtent] =
"2";
8339 (void) XDialogWidget(display,windows,
"Spread",
8340 "Enter the displacement amount:",amount);
8341 if (*amount ==
'\0')
8346 XSetCursorState(display,windows,MagickTrue);
8347 XCheckRefreshWindows(display,windows);
8348 flags=ParseGeometry(amount,&geometry_info);
8349 spread_image=EdgeImage(*image,geometry_info.rho,exception);
8350 if (spread_image != (
Image *) NULL)
8352 *image=DestroyImage(*image);
8353 *image=spread_image;
8355 CatchException(exception);
8356 XSetCursorState(display,windows,MagickFalse);
8357 if (windows->image.orphan != MagickFalse)
8359 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8360 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8372 geometry[MagickPathExtent] =
"30x30";
8377 status=XDialogWidget(display,windows,
"Shade",
8378 "Enter the azimuth and elevation of the light source:",geometry);
8379 if (*geometry ==
'\0')
8384 XSetCursorState(display,windows,MagickTrue);
8385 XCheckRefreshWindows(display,windows);
8386 flags=ParseGeometry(geometry,&geometry_info);
8387 if ((flags & SigmaValue) == 0)
8388 geometry_info.sigma=1.0;
8389 shade_image=ShadeImage(*image,status != 0 ? MagickTrue : MagickFalse,
8390 geometry_info.rho,geometry_info.sigma,exception);
8391 if (shade_image != (
Image *) NULL)
8393 *image=DestroyImage(*image);
8396 CatchException(exception);
8397 XSetCursorState(display,windows,MagickFalse);
8398 if (windows->image.orphan != MagickFalse)
8400 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8401 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8407 bevel_width[MagickPathExtent] =
"10";
8412 (void) XDialogWidget(display,windows,
"Raise",
"Bevel width:",bevel_width);
8413 if (*bevel_width ==
'\0')
8418 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
8420 XSetCursorState(display,windows,MagickTrue);
8421 XCheckRefreshWindows(display,windows);
8422 (void) ParsePageGeometry(*image,bevel_width,&page_geometry,
8424 (void) RaiseImage(*image,&page_geometry,MagickTrue,exception);
8425 XSetCursorState(display,windows,MagickFalse);
8426 if (windows->image.orphan != MagickFalse)
8428 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8429 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8432 case SegmentCommand:
8435 threshold[MagickPathExtent] =
"1.0x1.5";
8440 (void) XDialogWidget(display,windows,
"Segment",
"Smooth threshold:",
8442 if (*threshold ==
'\0')
8447 XSetCursorState(display,windows,MagickTrue);
8448 XCheckRefreshWindows(display,windows);
8449 flags=ParseGeometry(threshold,&geometry_info);
8450 if ((flags & SigmaValue) == 0)
8451 geometry_info.sigma=1.0;
8452 (void) SegmentImage(*image,sRGBColorspace,MagickFalse,geometry_info.rho,
8453 geometry_info.sigma,exception);
8454 XSetCursorState(display,windows,MagickFalse);
8455 if (windows->image.orphan != MagickFalse)
8457 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8458 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8461 case SepiaToneCommand:
8470 factor[MagickPathExtent] =
"80%";
8475 (void) XDialogWidget(display,windows,
"Sepia Tone",
8476 "Enter the sepia tone factor (0 - 99.9%):",factor);
8477 if (*factor ==
'\0')
8482 XSetCursorState(display,windows,MagickTrue);
8483 XCheckRefreshWindows(display,windows);
8484 threshold=StringToDoubleInterval(factor,(
double) QuantumRange+1.0);
8485 sepia_image=SepiaToneImage(*image,threshold,exception);
8486 if (sepia_image != (
Image *) NULL)
8488 *image=DestroyImage(*image);
8491 CatchException(exception);
8492 XSetCursorState(display,windows,MagickFalse);
8493 if (windows->image.orphan != MagickFalse)
8495 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8496 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8499 case SolarizeCommand:
8505 factor[MagickPathExtent] =
"60%";
8510 (void) XDialogWidget(display,windows,
"Solarize",
8511 "Enter the solarize factor (0 - 99.9%):",factor);
8512 if (*factor ==
'\0')
8517 XSetCursorState(display,windows,MagickTrue);
8518 XCheckRefreshWindows(display,windows);
8519 threshold=StringToDoubleInterval(factor,(
double) QuantumRange+1.0);
8520 (void) SolarizeImage(*image,threshold,exception);
8521 XSetCursorState(display,windows,MagickFalse);
8522 if (windows->image.orphan != MagickFalse)
8524 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8525 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8534 degrees[MagickPathExtent] =
"60";
8539 (void) XDialogWidget(display,windows,
"Swirl",
"Enter the swirl angle:",
8541 if (*degrees ==
'\0')
8546 XSetCursorState(display,windows,MagickTrue);
8547 XCheckRefreshWindows(display,windows);
8548 flags=ParseGeometry(degrees,&geometry_info);
8549 swirl_image=SwirlImage(*image,geometry_info.rho,(*image)->interpolate,
8551 if (swirl_image != (
Image *) NULL)
8553 *image=DestroyImage(*image);
8556 CatchException(exception);
8557 XSetCursorState(display,windows,MagickFalse);
8558 if (windows->image.orphan != MagickFalse)
8560 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8561 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8564 case ImplodeCommand:
8570 factor[MagickPathExtent] =
"0.3";
8575 (void) XDialogWidget(display,windows,
"Implode",
8576 "Enter the implosion/explosion factor (-1.0 - 1.0):",factor);
8577 if (*factor ==
'\0')
8582 XSetCursorState(display,windows,MagickTrue);
8583 XCheckRefreshWindows(display,windows);
8584 flags=ParseGeometry(factor,&geometry_info);
8585 implode_image=ImplodeImage(*image,geometry_info.rho,(*image)->interpolate,
8587 if (implode_image != (
Image *) NULL)
8589 *image=DestroyImage(*image);
8590 *image=implode_image;
8592 CatchException(exception);
8593 XSetCursorState(display,windows,MagickFalse);
8594 if (windows->image.orphan != MagickFalse)
8596 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8597 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8600 case VignetteCommand:
8606 geometry[MagickPathExtent] =
"0x20";
8611 (void) XDialogWidget(display,windows,
"Vignette",
8612 "Enter the radius, sigma, and x and y offsets:",geometry);
8613 if (*geometry ==
'\0')
8618 XSetCursorState(display,windows,MagickTrue);
8619 XCheckRefreshWindows(display,windows);
8620 flags=ParseGeometry(geometry,&geometry_info);
8621 if ((flags & SigmaValue) == 0)
8622 geometry_info.sigma=1.0;
8623 if ((flags & XiValue) == 0)
8624 geometry_info.xi=0.1*(*image)->columns;
8625 if ((flags & PsiValue) == 0)
8626 geometry_info.psi=0.1*(*image)->rows;
8627 vignette_image=VignetteImage(*image,geometry_info.rho,0.0,(ssize_t)
8628 ceil(geometry_info.xi-0.5),(ssize_t) ceil(geometry_info.psi-0.5),
8630 if (vignette_image != (
Image *) NULL)
8632 *image=DestroyImage(*image);
8633 *image=vignette_image;
8635 CatchException(exception);
8636 XSetCursorState(display,windows,MagickFalse);
8637 if (windows->image.orphan != MagickFalse)
8639 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8640 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8649 geometry[MagickPathExtent] =
"25x150";
8654 (void) XDialogWidget(display,windows,
"Wave",
8655 "Enter the amplitude and length of the wave:",geometry);
8656 if (*geometry ==
'\0')
8661 XSetCursorState(display,windows,MagickTrue);
8662 XCheckRefreshWindows(display,windows);
8663 flags=ParseGeometry(geometry,&geometry_info);
8664 if ((flags & SigmaValue) == 0)
8665 geometry_info.sigma=1.0;
8666 wave_image=WaveImage(*image,geometry_info.rho,geometry_info.sigma,
8667 (*image)->interpolate,exception);
8668 if (wave_image != (
Image *) NULL)
8670 *image=DestroyImage(*image);
8673 CatchException(exception);
8674 XSetCursorState(display,windows,MagickFalse);
8675 if (windows->image.orphan != MagickFalse)
8677 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8678 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8681 case OilPaintCommand:
8687 radius[MagickPathExtent] =
"0";
8692 (void) XDialogWidget(display,windows,
"Oil Paint",
8693 "Enter the mask radius:",radius);
8694 if (*radius ==
'\0')
8699 XSetCursorState(display,windows,MagickTrue);
8700 XCheckRefreshWindows(display,windows);
8701 flags=ParseGeometry(radius,&geometry_info);
8702 paint_image=OilPaintImage(*image,geometry_info.rho,geometry_info.sigma,
8704 if (paint_image != (
Image *) NULL)
8706 *image=DestroyImage(*image);
8709 CatchException(exception);
8710 XSetCursorState(display,windows,MagickFalse);
8711 if (windows->image.orphan != MagickFalse)
8713 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8714 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8717 case CharcoalDrawCommand:
8723 radius[MagickPathExtent] =
"0x1";
8728 (void) XDialogWidget(display,windows,
"Charcoal Draw",
8729 "Enter the charcoal radius and sigma:",radius);
8730 if (*radius ==
'\0')
8735 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
8737 XSetCursorState(display,windows,MagickTrue);
8738 XCheckRefreshWindows(display,windows);
8739 flags=ParseGeometry(radius,&geometry_info);
8740 if ((flags & SigmaValue) == 0)
8741 geometry_info.sigma=geometry_info.rho;
8742 charcoal_image=CharcoalImage(*image,geometry_info.rho,geometry_info.sigma,
8744 if (charcoal_image != (
Image *) NULL)
8746 *image=DestroyImage(*image);
8747 *image=charcoal_image;
8749 CatchException(exception);
8750 XSetCursorState(display,windows,MagickFalse);
8751 if (windows->image.orphan != MagickFalse)
8753 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8754 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8757 case AnnotateCommand:
8762 status=XAnnotateEditImage(display,resource_info,windows,*image,exception);
8763 if (status == MagickFalse)
8765 XNoticeWidget(display,windows,
"Unable to annotate X image",
8766 (*image)->filename);
8776 status=XDrawEditImage(display,resource_info,windows,image,exception);
8777 if (status == MagickFalse)
8779 XNoticeWidget(display,windows,
"Unable to draw on the X image",
8780 (*image)->filename);
8790 status=XColorEditImage(display,resource_info,windows,image,exception);
8791 if (status == MagickFalse)
8793 XNoticeWidget(display,windows,
"Unable to pixel edit X image",
8794 (*image)->filename);
8804 status=XMatteEditImage(display,resource_info,windows,image,exception);
8805 if (status == MagickFalse)
8807 XNoticeWidget(display,windows,
"Unable to matte edit X image",
8808 (*image)->filename);
8813 case CompositeCommand:
8818 status=XCompositeImage(display,resource_info,windows,*image,
8820 if (status == MagickFalse)
8822 XNoticeWidget(display,windows,
"Unable to composite X image",
8823 (*image)->filename);
8828 case AddBorderCommand:
8834 geometry[MagickPathExtent] =
"6x6";
8839 XColorBrowserWidget(display,windows,
"Select",color);
8842 (void) XDialogWidget(display,windows,
"Add Border",
8843 "Enter border geometry:",geometry);
8844 if (*geometry ==
'\0')
8849 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
8851 XSetCursorState(display,windows,MagickTrue);
8852 XCheckRefreshWindows(display,windows);
8853 (void) QueryColorCompliance(color,AllCompliance,&(*image)->border_color,
8855 (void) ParsePageGeometry(*image,geometry,&page_geometry,
8857 border_image=BorderImage(*image,&page_geometry,(*image)->compose,
8859 if (border_image != (
Image *) NULL)
8861 *image=DestroyImage(*image);
8862 *image=border_image;
8864 CatchException(exception);
8865 XSetCursorState(display,windows,MagickFalse);
8866 if (windows->image.orphan != MagickFalse)
8868 windows->image.window_changes.width=(int) (*image)->columns;
8869 windows->image.window_changes.height=(int) (*image)->rows;
8870 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8871 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8874 case AddFrameCommand:
8883 geometry[MagickPathExtent] =
"6x6";
8888 XColorBrowserWidget(display,windows,
"Select",color);
8891 (void) XDialogWidget(display,windows,
"Add Frame",
"Enter frame geometry:",
8893 if (*geometry ==
'\0')
8898 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
8900 XSetCursorState(display,windows,MagickTrue);
8901 XCheckRefreshWindows(display,windows);
8902 (void) QueryColorCompliance(color,AllCompliance,&(*image)->matte_color,
8904 (void) ParsePageGeometry(*image,geometry,&page_geometry,
8906 frame_info.width=page_geometry.width;
8907 frame_info.height=page_geometry.height;
8908 frame_info.outer_bevel=page_geometry.x;
8909 frame_info.inner_bevel=page_geometry.y;
8910 frame_info.x=(ssize_t) frame_info.width;
8911 frame_info.y=(ssize_t) frame_info.height;
8912 frame_info.width=(*image)->columns+2*frame_info.width;
8913 frame_info.height=(*image)->rows+2*frame_info.height;
8914 frame_image=FrameImage(*image,&frame_info,(*image)->compose,exception);
8915 if (frame_image != (
Image *) NULL)
8917 *image=DestroyImage(*image);
8920 CatchException(exception);
8921 XSetCursorState(display,windows,MagickFalse);
8922 if (windows->image.orphan != MagickFalse)
8924 windows->image.window_changes.width=(int) (*image)->columns;
8925 windows->image.window_changes.height=(int) (*image)->rows;
8926 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8927 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8930 case CommentCommand:
8944 unique_file=AcquireUniqueFileResource(image_info->filename);
8945 if (unique_file == -1)
8947 XNoticeWidget(display,windows,
"Unable to edit image comment",
8948 image_info->filename);
8951 value=GetImageProperty(*image,
"comment",exception);
8952 if (value == (
char *) NULL)
8953 unique_file=close(unique_file)-1;
8959 file=fdopen(unique_file,
"w");
8960 if (file == (FILE *) NULL)
8962 XNoticeWidget(display,windows,
"Unable to edit image comment",
8963 image_info->filename);
8966 for (p=value; *p !=
'\0'; p++)
8967 (
void) fputc((
int) *p,file);
8968 (void) fputc(
'\n',file);
8969 (void) fclose(file);
8971 XSetCursorState(display,windows,MagickTrue);
8972 XCheckRefreshWindows(display,windows);
8973 status=InvokeDelegate(image_info,*image,
"edit",(
char *) NULL,
8975 if (status == MagickFalse)
8976 XNoticeWidget(display,windows,
"Unable to edit image comment",
8983 comment=FileToString(image_info->filename,~0UL,exception);
8984 if (comment != (
char *) NULL)
8986 (void) SetImageProperty(*image,
"comment",comment,exception);
8987 (*image)->taint=MagickTrue;
8990 (void) RelinquishUniqueFileResource(image_info->filename);
8991 XSetCursorState(display,windows,MagickFalse);
8999 XSetCursorState(display,windows,MagickTrue);
9000 XCheckRefreshWindows(display,windows);
9001 (void) AcquireUniqueFilename(filename);
9002 (void) FormatLocaleString((*image)->filename,MagickPathExtent,
"launch:%s",
9004 status=WriteImage(image_info,*image,exception);
9005 if (status == MagickFalse)
9006 XNoticeWidget(display,windows,
"Unable to launch image editor",
9010 nexus=ReadImage(resource_info->image_info,exception);
9011 CatchException(exception);
9012 XClientMessage(display,windows->image.id,windows->im_protocols,
9013 windows->im_next_image,CurrentTime);
9015 (void) RelinquishUniqueFileResource(filename);
9016 XSetCursorState(display,windows,MagickFalse);
9019 case RegionOfInterestCommand:
9024 (void) XROIImage(display,resource_info,windows,image,exception);
9034 if (windows->magnify.mapped != MagickFalse)
9035 (void) XRaiseWindow(display,windows->magnify.id);
9041 XSetCursorState(display,windows,MagickTrue);
9042 (void) XMapRaised(display,windows->magnify.id);
9043 XSetCursorState(display,windows,MagickFalse);
9047 case ShowPreviewCommand:
9059 preview_type[MagickPathExtent] =
"Gamma";
9064 previews=GetCommandOptions(MagickPreviewOptions);
9065 if (previews == (
char **) NULL)
9067 XListBrowserWidget(display,windows,&windows->widget,
9068 (
const char **) previews,
"Preview",
9069 "Select an enhancement, effect, or F/X:",preview_type);
9070 previews=DestroyStringList(previews);
9071 if (*preview_type ==
'\0')
9076 XSetCursorState(display,windows,MagickTrue);
9077 XCheckRefreshWindows(display,windows);
9078 preview=(PreviewType) ParseCommandOption(MagickPreviewOptions,
9079 MagickFalse,preview_type);
9080 (void) FormatImageProperty(*image,
"group",
"%.20g",(
double)
9082 (void) DeleteImageProperty(*image,
"label");
9083 (void) SetImageProperty(*image,
"label",
"Preview",exception);
9084 preview_image=PreviewImage(*image,preview,exception);
9085 if (preview_image == (
Image *) NULL)
9087 (void) AcquireUniqueFilename(filename);
9088 (void) FormatLocaleString(preview_image->filename,MagickPathExtent,
9089 "show:%s",filename);
9090 status=WriteImage(image_info,preview_image,exception);
9091 (void) RelinquishUniqueFileResource(filename);
9092 preview_image=DestroyImage(preview_image);
9093 if (status == MagickFalse)
9094 XNoticeWidget(display,windows,
"Unable to show image preview",
9095 (*image)->filename);
9096 XDelay(display,1500);
9097 XSetCursorState(display,windows,MagickFalse);
9100 case ShowHistogramCommand:
9108 XSetCursorState(display,windows,MagickTrue);
9109 XCheckRefreshWindows(display,windows);
9110 (void) DeleteImageProperty(*image,
"label");
9111 (void) FormatImageProperty(*image,
"group",
"%.20g",(
double)
9113 (void) SetImageProperty(*image,
"label",
"Histogram",exception);
9114 (void) AcquireUniqueFilename(filename);
9115 (void) FormatLocaleString((*image)->filename,MagickPathExtent,
9116 "histogram:%s",filename);
9117 status=WriteImage(image_info,*image,exception);
9118 (void) CopyMagickString(image_info->filename,filename,MagickPathExtent);
9119 histogram_image=ReadImage(image_info,exception);
9120 (void) RelinquishUniqueFileResource(filename);
9121 if (histogram_image == (
Image *) NULL)
9123 (void) FormatLocaleString(histogram_image->filename,MagickPathExtent,
9124 "show:%s",filename);
9125 status=WriteImage(image_info,histogram_image,exception);
9126 histogram_image=DestroyImage(histogram_image);
9127 if (status == MagickFalse)
9128 XNoticeWidget(display,windows,
"Unable to show histogram",
9129 (*image)->filename);
9130 XDelay(display,1500);
9131 XSetCursorState(display,windows,MagickFalse);
9134 case ShowMatteCommand:
9139 if ((*image)->alpha_trait == UndefinedPixelTrait)
9141 XNoticeWidget(display,windows,
9142 "Image does not have any matte information",(*image)->filename);
9148 XSetCursorState(display,windows,MagickTrue);
9149 XCheckRefreshWindows(display,windows);
9150 (void) FormatImageProperty(*image,
"group",
"%.20g",(
double)
9152 (void) DeleteImageProperty(*image,
"label");
9153 (void) SetImageProperty(*image,
"label",
"Matte",exception);
9154 (void) AcquireUniqueFilename(filename);
9155 (void) FormatLocaleString((*image)->filename,MagickPathExtent,
"matte:%s",
9157 status=WriteImage(image_info,*image,exception);
9158 (void) CopyMagickString(image_info->filename,filename,MagickPathExtent);
9159 matte_image=ReadImage(image_info,exception);
9160 (void) RelinquishUniqueFileResource(filename);
9161 if (matte_image == (
Image *) NULL)
9163 (void) FormatLocaleString(matte_image->filename,MagickPathExtent,
9164 "show:%s",filename);
9165 status=WriteImage(image_info,matte_image,exception);
9166 matte_image=DestroyImage(matte_image);
9167 if (status == MagickFalse)
9168 XNoticeWidget(display,windows,
"Unable to show matte",
9169 (*image)->filename);
9170 XDelay(display,1500);
9171 XSetCursorState(display,windows,MagickFalse);
9174 case BackgroundCommand:
9179 status=XBackgroundImage(display,resource_info,windows,image,exception);
9180 if (status == MagickFalse)
9182 nexus=CloneImage(*image,0,0,MagickTrue,exception);
9183 if (nexus != (
Image *) NULL)
9184 XClientMessage(display,windows->image.id,windows->im_protocols,
9185 windows->im_next_image,CurrentTime);
9188 case SlideShowCommand:
9191 delay[MagickPathExtent] =
"5";
9196 (void) XDialogWidget(display,windows,
"Slide Show",
9197 "Pause how many 1/100ths of a second between images:",delay);
9200 resource_info->delay=StringToUnsignedLong(delay);
9201 XClientMessage(display,windows->image.id,windows->im_protocols,
9202 windows->im_next_image,CurrentTime);
9205 case PreferencesCommand:
9210 status=XPreferencesWidget(display,resource_info,windows);
9211 if (status == MagickFalse)
9213 nexus=CloneImage(*image,0,0,MagickTrue,exception);
9214 if (nexus != (
Image *) NULL)
9215 XClientMessage(display,windows->image.id,windows->im_protocols,
9216 windows->im_next_image,CurrentTime);
9224 XTextViewHelp(display,resource_info,windows,MagickFalse,
9225 "Help Viewer - Display",DisplayHelp);
9228 case BrowseDocumentationCommand:
9240 root_window=XRootWindow(display,XDefaultScreen(display));
9241 mozilla_atom=XInternAtom(display,
"_MOZILLA_VERSION",MagickFalse);
9242 mozilla_window=XWindowByProperty(display,root_window,mozilla_atom);
9243 if (mozilla_window != (Window) NULL)
9246 command[MagickPathExtent];
9251 (void) FormatLocaleString(command,MagickPathExtent,
9252 "openurl(%s,new-tab)",MagickAuthoritativeURL);
9253 mozilla_atom=XInternAtom(display,
"_MOZILLA_COMMAND",MagickFalse);
9254 (void) XChangeProperty(display,mozilla_window,mozilla_atom,XA_STRING,
9255 8,PropModeReplace,(
unsigned char *) command,(
int) strlen(command));
9256 XSetCursorState(display,windows,MagickFalse);
9259 XSetCursorState(display,windows,MagickTrue);
9260 XCheckRefreshWindows(display,windows);
9261 status=InvokeDelegate(image_info,*image,
"browse",(
char *) NULL,
9263 if (status == MagickFalse)
9264 XNoticeWidget(display,windows,
"Unable to browse documentation",
9266 XDelay(display,1500);
9267 XSetCursorState(display,windows,MagickFalse);
9270 case VersionCommand:
9272 XNoticeWidget(display,windows,GetMagickVersion((
size_t *) NULL),
9273 GetMagickCopyright());
9276 case SaveToUndoBufferCommand:
9280 (void) XBell(display,0);
9284 image_info=DestroyImageInfo(image_info);
9320static void XMagnifyImage(Display *display,XWindows *windows,XEvent *event,
9324 text[MagickPathExtent];
9336 (void) XCheckDefineCursor(display,windows->image.id,windows->magnify.cursor);
9340 windows->magnify.x=(int) windows->image.x+x;
9341 windows->magnify.y=(int) windows->image.y+y;
9347 if (windows->info.mapped != MagickFalse)
9349 if ((x < (windows->info.x+(
int) windows->info.width)) &&
9350 (y < (windows->info.y+(
int) windows->info.height)))
9351 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
9354 if ((x > (windows->info.x+(
int) windows->info.width)) ||
9355 (y > (windows->info.y+(
int) windows->info.height)))
9356 (void) XMapWindow(display,windows->info.id);
9357 if (windows->info.mapped != MagickFalse)
9362 (void) FormatLocaleString(text,MagickPathExtent,
" %+d%+d ",
9363 windows->magnify.x,windows->magnify.y);
9364 XInfoWidget(display,windows,text);
9369 XScreenEvent(display,windows,event,exception);
9370 switch (event->type)
9401 if (x >= (
int) windows->image.width)
9402 x=(int) windows->image.width-1;
9406 if (y >= (
int) windows->image.height)
9407 y=(int) windows->image.height-1;
9408 }
while ((state & ExitState) == 0);
9412 XSetCursorState(display,windows,MagickFalse);
9450static void XMagnifyWindowCommand(Display *display,XWindows *windows,
9451 const MagickStatusType state,
const KeySym key_symbol,
ExceptionInfo *exception)
9460 if ((state & Mod1Mask) != 0)
9462 switch ((
int) key_symbol)
9466 (void) XWithdrawWindow(display,windows->magnify.id,
9467 windows->magnify.screen);
9473 windows->magnify.x=(int) windows->image.width/2;
9474 windows->magnify.y=(int) windows->image.height/2;
9480 if (windows->magnify.x > 0)
9481 windows->magnify.x-=(int) quantum;
9487 if (windows->magnify.y > 0)
9488 windows->magnify.y-=(int) quantum;
9494 if (windows->magnify.x < (
int) (windows->image.ximage->width-1))
9495 windows->magnify.x+=(int) quantum;
9501 if (windows->magnify.y < (
int) (windows->image.ximage->height-1))
9502 windows->magnify.y+=(int) quantum;
9516 windows->magnify.data=(key_symbol-XK_0);
9530 windows->magnify.data=(key_symbol-XK_KP_0);
9536 XMakeMagnifyImage(display,windows,exception);
9572static void XMakePanImage(Display *display,XResourceInfo *resource_info,
9581 XSetCursorState(display,windows,MagickTrue);
9582 XCheckRefreshWindows(display,windows);
9583 windows->pan.x=(int) windows->image.x;
9584 windows->pan.y=(int) windows->image.y;
9585 status=XMakeImage(display,resource_info,&windows->pan,image,
9586 windows->pan.width,windows->pan.height,exception);
9587 if (status == MagickFalse)
9588 ThrowXWindowException(ResourceLimitError,
"MemoryAllocationFailed",
9590 (void) XSetWindowBackgroundPixmap(display,windows->pan.id,
9591 windows->pan.pixmap);
9592 (void) XClearWindow(display,windows->pan.id);
9593 XDrawPanRectangle(display,windows);
9594 XSetCursorState(display,windows,MagickFalse);
9632static MagickBooleanType XMatteEditImage(Display *display,
9633 XResourceInfo *resource_info,XWindows *windows,
Image **image,
9637 *
const MatteEditMenu[] =
9650 matte[MagickPathExtent] =
"0";
9652 static const ModeType
9653 MatteEditCommands[] =
9656 MatteEditBorderCommand,
9657 MatteEditFuzzCommand,
9658 MatteEditValueCommand,
9659 MatteEditUndoCommand,
9660 MatteEditHelpCommand,
9661 MatteEditDismissCommand
9665 method = PointMethod;
9668 border_color = { 0, 0, 0, 0, 0, 0 };
9671 command[MagickPathExtent],
9672 text[MagickPathExtent];
9704 (void) CloneString(&windows->command.name,
"Matte Edit");
9705 windows->command.data=4;
9706 (void) XCommandWidget(display,windows,MatteEditMenu,(XEvent *) NULL);
9707 (void) XMapRaised(display,windows->command.id);
9708 XClientMessage(display,windows->image.id,windows->im_protocols,
9709 windows->im_update_widget,CurrentTime);
9713 cursor=XMakeCursor(display,windows->image.id,windows->map_info->colormap,
9714 resource_info->background_color,resource_info->foreground_color);
9715 (void) XCheckDefineCursor(display,windows->image.id,cursor);
9719 XQueryPosition(display,windows->image.id,&x,&y);
9720 (void) XSelectInput(display,windows->image.id,
9721 windows->image.attributes.event_mask | PointerMotionMask);
9725 if (windows->info.mapped != MagickFalse)
9730 (void) FormatLocaleString(text,MagickPathExtent,
" %+d%+d ",
9731 x+windows->image.x,y+windows->image.y);
9732 XInfoWidget(display,windows,text);
9737 XScreenEvent(display,windows,&event,exception);
9738 if (event.xany.window == windows->command.id)
9743 id=XCommandWidget(display,windows,MatteEditMenu,&event);
9746 (void) XCheckDefineCursor(display,windows->image.id,cursor);
9749 switch (MatteEditCommands[
id])
9751 case MatteEditMethod:
9759 methods=GetCommandOptions(MagickMethodOptions);
9760 if (methods == (
char **) NULL)
9762 entry=XMenuWidget(display,windows,MatteEditMenu[
id],
9763 (
const char **) methods,command);
9765 method=(PaintMethod) ParseCommandOption(MagickMethodOptions,
9766 MagickFalse,methods[entry]);
9767 methods=DestroyStringList(methods);
9770 case MatteEditBorderCommand:
9773 *ColorMenu[MaxNumberPens];
9781 for (i=0; i < (int) (MaxNumberPens-2); i++)
9782 ColorMenu[i]=resource_info->pen_colors[i];
9783 ColorMenu[MaxNumberPens-2]=
"Browser...";
9784 ColorMenu[MaxNumberPens-1]=(
const char *) NULL;
9788 pen_number=XMenuWidget(display,windows,MatteEditMenu[
id],
9789 (
const char **) ColorMenu,command);
9792 if (pen_number == (MaxNumberPens-2))
9795 color_name[MagickPathExtent] =
"gray";
9800 resource_info->pen_colors[pen_number]=color_name;
9801 XColorBrowserWidget(display,windows,
"Select",color_name);
9802 if (*color_name ==
'\0')
9808 (void) XParseColor(display,windows->map_info->colormap,
9809 resource_info->pen_colors[pen_number],&border_color);
9812 case MatteEditFuzzCommand:
9827 fuzz[MagickPathExtent];
9832 entry=XMenuWidget(display,windows,MatteEditMenu[
id],FuzzMenu,
9838 (*image)->fuzz=StringToDoubleInterval(FuzzMenu[entry],(
double)
9842 (void) CopyMagickString(fuzz,
"20%",MagickPathExtent);
9843 (void) XDialogWidget(display,windows,
"Ok",
9844 "Enter fuzz factor (0.0 - 99.9%):",fuzz);
9847 (void) ConcatenateMagickString(fuzz,
"%",MagickPathExtent);
9848 (*image)->fuzz=StringToDoubleInterval(fuzz,(
double) QuantumRange+
9852 case MatteEditValueCommand:
9855 *
const MatteMenu[] =
9864 message[MagickPathExtent];
9869 entry=XMenuWidget(display,windows,MatteEditMenu[
id],MatteMenu,
9875 (void) FormatLocaleString(matte,MagickPathExtent,
"%g",
9876 (
double) OpaqueAlpha);
9877 if (LocaleCompare(MatteMenu[entry],
"Transparent") == 0)
9878 (void) FormatLocaleString(matte,MagickPathExtent,
"%g",
9879 (
double) TransparentAlpha);
9882 (void) FormatLocaleString(message,MagickPathExtent,
9883 "Enter matte value (0 - " "%g" "):",(
double) QuantumRange);
9884 (void) XDialogWidget(display,windows,
"Matte",message,matte);
9889 case MatteEditUndoCommand:
9891 (void) XMagickCommand(display,resource_info,windows,UndoCommand,
9895 case MatteEditHelpCommand:
9897 XTextViewHelp(display,resource_info,windows,MagickFalse,
9898 "Help Viewer - Matte Edit",ImageMatteEditHelp);
9901 case MatteEditDismissCommand:
9913 (void) XCheckDefineCursor(display,windows->image.id,cursor);
9920 if (event.xbutton.button != Button1)
9922 if ((event.xbutton.window != windows->image.id) &&
9923 (event.xbutton.window != windows->magnify.id))
9930 (void) XMagickCommand(display,resource_info,windows,
9931 SaveToUndoBufferCommand,image,exception);
9932 state|=UpdateConfigurationState;
9937 if (event.xbutton.button != Button1)
9939 if ((event.xbutton.window != windows->image.id) &&
9940 (event.xbutton.window != windows->magnify.id))
9947 XConfigureImageColormap(display,resource_info,windows,*image,exception);
9948 (void) XConfigureImage(display,resource_info,windows,*image,exception);
9949 XInfoWidget(display,windows,text);
9950 (void) XCheckDefineCursor(display,windows->image.id,cursor);
9951 state&=(
unsigned int) (~UpdateConfigurationState);
9959 command[MagickPathExtent];
9964 if (event.xkey.window == windows->magnify.id)
9969 window=windows->magnify.id;
9970 while (XCheckWindowEvent(display,window,KeyPressMask,&event)) ;
9972 if (event.xkey.window != windows->image.id)
9977 (void) XLookupString((XKeyEvent *) &event.xkey,command,(
int)
9978 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
9979 switch ((
int) key_symbol)
9993 XTextViewHelp(display,resource_info,windows,MagickFalse,
9994 "Help Viewer - Matte Edit",ImageMatteEditHelp);
9999 (void) XBell(display,0);
10012 if (windows->info.mapped != MagickFalse)
10014 if ((x < (windows->info.x+(
int) windows->info.width)) &&
10015 (y < (windows->info.y+(
int) windows->info.height)))
10016 (void) XWithdrawWindow(display,windows->info.id,
10017 windows->info.screen);
10020 if ((x > (windows->info.x+(
int) windows->info.width)) ||
10021 (y > (windows->info.y+(
int) windows->info.height)))
10022 (void) XMapWindow(display,windows->info.id);
10028 if (event.xany.window == windows->magnify.id)
10030 x=windows->magnify.x-windows->image.x;
10031 y=windows->magnify.y-windows->image.y;
10035 if ((state & UpdateConfigurationState) != 0)
10047 (void) XClearArea(display,windows->image.id,x_offset,y_offset,1,1,
10049 XPutPixel(windows->image.ximage,x_offset,y_offset,
10050 windows->pixel_info->background_color.pixel);
10051 width=(
unsigned int) (*image)->columns;
10052 height=(
unsigned int) (*image)->rows;
10055 if (windows->image.crop_geometry != (
char *) NULL)
10056 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,
10058 x_offset=((int) width*(windows->image.x+x_offset)/
10059 windows->image.ximage->width+x);
10060 y_offset=((int) height*(windows->image.y+y_offset)/
10061 windows->image.ximage->height+y);
10062 if ((x_offset < 0) || (y_offset < 0))
10064 if ((x_offset >= (
int) (*image)->columns) ||
10065 (y_offset >= (
int) (*image)->rows))
10067 if (SetImageStorageClass(*image,DirectClass,exception) == MagickFalse)
10068 return(MagickFalse);
10069 if ((*image)->alpha_trait == UndefinedPixelTrait)
10070 (void) SetImageAlphaChannel(*image,OpaqueAlphaChannel,exception);
10071 image_view=AcquireAuthenticCacheView(*image,exception);
10080 q=GetCacheViewAuthenticPixels(image_view,(ssize_t) x_offset,
10081 (ssize_t) y_offset,1,1,exception);
10082 if (q == (Quantum *) NULL)
10084 SetPixelAlpha(*image,(Quantum) StringToLong(matte),q);
10085 (void) SyncCacheViewAuthenticPixels(image_view,exception);
10088 case ReplaceMethod:
10097 (void) GetOneCacheViewVirtualPixelInfo(image_view,(ssize_t)
10098 x_offset,(ssize_t) y_offset,&target,exception);
10099 for (y=0; y < (int) (*image)->rows; y++)
10101 q=GetCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
10102 (*image)->columns,1,exception);
10103 if (q == (Quantum *) NULL)
10105 for (x=0; x < (int) (*image)->columns; x++)
10107 GetPixelInfoPixel(*image,q,&pixel);
10108 if (IsFuzzyEquivalencePixelInfo(&pixel,&target))
10109 SetPixelAlpha(*image,(Quantum) StringToLong(matte),q);
10110 q+=(ptrdiff_t) GetPixelChannels(*image);
10112 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
10117 case FloodfillMethod:
10118 case FillToBorderMethod:
10132 (void) GetOneVirtualPixelInfo(*image,
10133 GetPixelCacheVirtualMethod(*image),(ssize_t) x_offset,(ssize_t)
10134 y_offset,&target,exception);
10135 if (method == FillToBorderMethod)
10137 target.red=(double) ScaleShortToQuantum(
10139 target.green=(double) ScaleShortToQuantum(
10140 border_color.green);
10141 target.blue=(double) ScaleShortToQuantum(
10142 border_color.blue);
10144 draw_info=CloneDrawInfo(resource_info->image_info,
10146 draw_info->fill.alpha=(double) ClampToQuantum(
10147 StringToDouble(matte,(
char **) NULL));
10148 channel_mask=SetImageChannelMask(*image,AlphaChannel);
10149 (void) FloodfillPaintImage(*image,draw_info,&target,(ssize_t)
10150 x_offset,(ssize_t) y_offset,
10151 method != FloodfillMethod ? MagickTrue : MagickFalse,exception);
10152 (void) SetPixelChannelMask(*image,channel_mask);
10153 draw_info=DestroyDrawInfo(draw_info);
10161 if (SetImageStorageClass(*image,DirectClass,exception) == MagickFalse)
10162 return(MagickFalse);
10163 for (y=0; y < (int) (*image)->rows; y++)
10165 q=QueueCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
10166 (*image)->columns,1,exception);
10167 if (q == (Quantum *) NULL)
10169 for (x=0; x < (int) (*image)->columns; x++)
10171 SetPixelAlpha(*image,(Quantum) StringToLong(matte),q);
10172 q+=(ptrdiff_t) GetPixelChannels(*image);
10174 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
10177 if (StringToLong(matte) == (
long) OpaqueAlpha)
10178 (*image)->alpha_trait=UndefinedPixelTrait;
10182 image_view=DestroyCacheView(image_view);
10183 state&=(
unsigned int) (~UpdateConfigurationState);
10185 }
while ((state & ExitState) == 0);
10186 (void) XSelectInput(display,windows->image.id,
10187 windows->image.attributes.event_mask);
10188 XSetCursorState(display,windows,MagickFalse);
10189 (void) XFreeCursor(display,cursor);
10190 return(MagickTrue);
10224static Image *XOpenImage(Display *display,XResourceInfo *resource_info,
10225 XWindows *windows,
const MagickBooleanType command)
10240 filename[MagickPathExtent] =
"\0";
10245 if (command == MagickFalse)
10246 XFileBrowserWidget(display,windows,
"Open",filename);
10264 status=XGetCommand(display,windows->image.id,&files,&count);
10267 ThrowXWindowException(XServerError,
"UnableToGetProperty",
"...");
10268 return((
Image *) NULL);
10270 filelist=(
char **) AcquireQuantumMemory((
size_t) count,
sizeof(*filelist));
10271 if (filelist == (
char **) NULL)
10273 ThrowXWindowException(ResourceLimitError,
"MemoryAllocationFailed",
10275 (void) XFreeStringList(files);
10276 return((
Image *) NULL);
10279 for (i=1; i < count; i++)
10280 if (*files[i] !=
'-')
10281 filelist[j++]=files[i];
10282 filelist[j]=(
char *) NULL;
10283 XListBrowserWidget(display,windows,&windows->widget,
10284 (
const char **) filelist,
"Load",
"Select Image to Load:",filename);
10285 filelist=(
char **) RelinquishMagickMemory(filelist);
10286 (void) XFreeStringList(files);
10288 if (*filename ==
'\0')
10289 return((
Image *) NULL);
10290 image_info=CloneImageInfo(resource_info->image_info);
10291 (void) SetImageInfoProgressMonitor(image_info,(MagickProgressMonitor) NULL,
10293 (void) CopyMagickString(image_info->filename,filename,MagickPathExtent);
10294 exception=AcquireExceptionInfo();
10295 (void) SetImageInfo(image_info,0,exception);
10296 if (LocaleCompare(image_info->magick,
"X") == 0)
10299 seconds[MagickPathExtent];
10304 (void) CopyMagickString(seconds,
"0",MagickPathExtent);
10305 (void) XDialogWidget(display,windows,
"Grab",
"Enter any delay in seconds:",
10307 if (*seconds ==
'\0')
10308 return((
Image *) NULL);
10309 XDelay(display,(
size_t) (1000*StringToLong(seconds)));
10311 magick_info=GetMagickInfo(image_info->magick,exception);
10312 if ((magick_info != (
const MagickInfo *) NULL) &&
10313 GetMagickRawSupport(magick_info) == MagickTrue)
10316 geometry[MagickPathExtent];
10321 (void) CopyMagickString(geometry,
"512x512",MagickPathExtent);
10322 if (image_info->size != (
char *) NULL)
10323 (void) CopyMagickString(geometry,image_info->size,MagickPathExtent);
10324 (void) XDialogWidget(display,windows,
"Load",
"Enter the image geometry:",
10326 (void) CloneString(&image_info->size,geometry);
10331 XSetCursorState(display,windows,MagickTrue);
10332 XCheckRefreshWindows(display,windows);
10333 (void) CopyMagickString(image_info->filename,filename,MagickPathExtent);
10334 nexus=ReadImage(image_info,exception);
10335 CatchException(exception);
10336 XSetCursorState(display,windows,MagickFalse);
10337 if (nexus != (
Image *) NULL)
10338 XClientMessage(display,windows->image.id,windows->im_protocols,
10339 windows->im_next_image,CurrentTime);
10349 text=FileToString(filename,~0UL,exception);
10350 if (text == (
char *) NULL)
10351 return((
Image *) NULL);
10352 textlist=StringToList(text);
10353 if (textlist != (
char **) NULL)
10356 title[MagickPathExtent];
10361 (void) FormatLocaleString(title,MagickPathExtent,
10362 "Unknown format: %s",filename);
10363 XTextViewWidget(display,resource_info,windows,MagickTrue,title,
10364 (
const char **) textlist);
10365 for (i=0; textlist[i] != (
char *) NULL; i++)
10366 textlist[i]=DestroyString(textlist[i]);
10367 textlist=(
char **) RelinquishMagickMemory(textlist);
10369 text=DestroyString(text);
10371 exception=DestroyExceptionInfo(exception);
10372 image_info=DestroyImageInfo(image_info);
10407static void XPanImage(Display *display,XWindows *windows,XEvent *event,
10411 text[MagickPathExtent];
10429 if ((windows->image.ximage->width > (
int) windows->image.width) &&
10430 (windows->image.ximage->height > (
int) windows->image.height))
10431 cursor=XCreateFontCursor(display,XC_fleur);
10433 if (windows->image.ximage->width > (
int) windows->image.width)
10434 cursor=XCreateFontCursor(display,XC_sb_h_double_arrow);
10436 if (windows->image.ximage->height > (
int) windows->image.height)
10437 cursor=XCreateFontCursor(display,XC_sb_v_double_arrow);
10439 cursor=XCreateFontCursor(display,XC_arrow);
10440 (void) XCheckDefineCursor(display,windows->pan.id,cursor);
10444 x_factor=(double) windows->image.ximage->width/windows->pan.width;
10445 y_factor=(double) windows->image.ximage->height/windows->pan.height;
10446 pan_info.width=windows->pan.width*windows->image.width/
10447 (
unsigned int) windows->image.ximage->width;
10448 pan_info.height=windows->pan.height*windows->image.height/
10449 (
unsigned int) windows->image.ximage->height;
10452 state=UpdateConfigurationState;
10455 switch (event->type)
10462 pan_info.x=(ssize_t) event->xbutton.x;
10463 pan_info.y=(ssize_t) event->xbutton.y;
10464 state|=UpdateConfigurationState;
10467 case ButtonRelease:
10472 pan_info.x=(ssize_t) event->xbutton.x;
10473 pan_info.y=(ssize_t) event->xbutton.y;
10474 state|=UpdateConfigurationState | ExitState;
10479 pan_info.x=(ssize_t) event->xmotion.x;
10480 pan_info.y=(ssize_t) event->xmotion.y;
10481 state|=UpdateConfigurationState;
10486 if ((state & UpdateConfigurationState) != 0)
10491 if (pan_info.x < (ssize_t) (pan_info.width/2))
10494 pan_info.x=(x_factor*(pan_info.x-((int) pan_info.width/2)));
10495 if (pan_info.x < 0)
10498 if ((
int) (pan_info.x+windows->image.width) >
10499 windows->image.ximage->width)
10500 pan_info.x=windows->image.ximage->width-(int) windows->image.width;
10501 if (pan_info.y < (ssize_t) (pan_info.height/2))
10504 pan_info.y=(y_factor*(pan_info.y-((int) pan_info.height/2)));
10505 if (pan_info.y < 0)
10508 if ((
int) (pan_info.y+windows->image.height) >
10509 windows->image.ximage->height)
10510 pan_info.y=windows->image.ximage->height-(int)
10511 windows->image.height;
10512 if ((windows->image.x != (
int) pan_info.x) ||
10513 (windows->image.y != (
int) pan_info.y))
10518 windows->image.x=(int) pan_info.x;
10519 windows->image.y=(int) pan_info.y;
10520 (void) FormatLocaleString(text,MagickPathExtent,
" %ux%u%+d%+d ",
10521 windows->image.width,windows->image.height,windows->image.x,
10523 XInfoWidget(display,windows,text);
10527 XDrawPanRectangle(display,windows);
10528 XRefreshWindow(display,&windows->image,(XEvent *) NULL);
10530 state&=(
unsigned int) (~UpdateConfigurationState);
10535 if ((state & ExitState) == 0)
10536 XScreenEvent(display,windows,event,exception);
10537 }
while ((state & ExitState) == 0);
10541 (void) XCheckDefineCursor(display,windows->pan.id,windows->pan.cursor);
10542 (void) XFreeCursor(display,cursor);
10543 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
10580static MagickBooleanType XPasteImage(Display *display,
10581 XResourceInfo *resource_info,XWindows *windows,
Image *image,
10585 *
const PasteMenu[] =
10593 static const ModeType
10596 PasteOperatorsCommand,
10598 PasteDismissCommand
10601 static CompositeOperator
10602 compose = CopyCompositeOp;
10605 text[MagickPathExtent];
10639 if (resource_info->copy_image == (
Image *) NULL)
10640 return(MagickFalse);
10641 paste_image=CloneImage(resource_info->copy_image,0,0,MagickTrue,exception);
10642 if (paste_image == (
Image *) NULL)
10643 return(MagickFalse);
10647 (void) CloneString(&windows->command.name,
"Paste");
10648 windows->command.data=1;
10649 (void) XCommandWidget(display,windows,PasteMenu,(XEvent *) NULL);
10650 (void) XMapRaised(display,windows->command.id);
10651 XClientMessage(display,windows->image.id,windows->im_protocols,
10652 windows->im_update_widget,CurrentTime);
10656 XSetCursorState(display,windows,MagickFalse);
10657 XQueryPosition(display,windows->image.id,&x,&y);
10658 (void) XSelectInput(display,windows->image.id,
10659 windows->image.attributes.event_mask | PointerMotionMask);
10660 paste_info.x=(ssize_t) windows->image.x+x;
10661 paste_info.y=(ssize_t) windows->image.y+y;
10662 paste_info.width=0;
10663 paste_info.height=0;
10664 cursor=XCreateFontCursor(display,XC_ul_angle);
10665 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
10666 state=DefaultState;
10669 if (windows->info.mapped != MagickFalse)
10674 (void) FormatLocaleString(text,MagickPathExtent,
" %+ld%+ld ",
10675 (
long) paste_info.x,(
long) paste_info.y);
10676 XInfoWidget(display,windows,text);
10678 highlight_info=paste_info;
10679 highlight_info.x=paste_info.x-windows->image.x;
10680 highlight_info.y=paste_info.y-windows->image.y;
10681 XHighlightRectangle(display,windows->image.id,
10682 windows->image.highlight_context,&highlight_info);
10686 XScreenEvent(display,windows,&event,exception);
10687 XHighlightRectangle(display,windows->image.id,
10688 windows->image.highlight_context,&highlight_info);
10689 if (event.xany.window == windows->command.id)
10694 id=XCommandWidget(display,windows,PasteMenu,&event);
10697 switch (PasteCommands[
id])
10699 case PasteOperatorsCommand:
10702 command[MagickPathExtent],
10708 operators=GetCommandOptions(MagickComposeOptions);
10709 if (operators == (
char **) NULL)
10711 entry=XMenuWidget(display,windows,PasteMenu[
id],
10712 (
const char **) operators,command);
10714 compose=(CompositeOperator) ParseCommandOption(
10715 MagickComposeOptions,MagickFalse,operators[entry]);
10716 operators=DestroyStringList(operators);
10719 case PasteHelpCommand:
10721 XTextViewHelp(display,resource_info,windows,MagickFalse,
10722 "Help Viewer - Image Composite",ImagePasteHelp);
10725 case PasteDismissCommand:
10730 state|=EscapeState;
10739 switch (event.type)
10743 if (resource_info->debug != MagickFalse)
10744 (void) LogMagickEvent(X11Event,GetMagickModule(),
10745 "Button Press: 0x%lx %u +%d+%d",event.xbutton.window,
10746 event.xbutton.button,event.xbutton.x,event.xbutton.y);
10747 if (event.xbutton.button != Button1)
10749 if (event.xbutton.window != windows->image.id)
10754 width=(
unsigned int) image->columns;
10755 height=(
unsigned int) image->rows;
10758 if (windows->image.crop_geometry != (
char *) NULL)
10759 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
10761 scale_factor=(double) windows->image.ximage->width/width;
10762 paste_info.width=(
unsigned int) (scale_factor*paste_image->columns+0.5);
10763 scale_factor=(double) windows->image.ximage->height/height;
10764 paste_info.height=(
unsigned int) (scale_factor*paste_image->rows+0.5);
10765 (void) XCheckDefineCursor(display,windows->image.id,cursor);
10766 paste_info.x=(ssize_t) windows->image.x+event.xbutton.x;
10767 paste_info.y=(ssize_t) windows->image.y+event.xbutton.y;
10770 case ButtonRelease:
10772 if (resource_info->debug != MagickFalse)
10773 (void) LogMagickEvent(X11Event,GetMagickModule(),
10774 "Button Release: 0x%lx %u +%d+%d",event.xbutton.window,
10775 event.xbutton.button,event.xbutton.x,event.xbutton.y);
10776 if (event.xbutton.button != Button1)
10778 if (event.xbutton.window != windows->image.id)
10780 if ((paste_info.width != 0) && (paste_info.height != 0))
10785 paste_info.x=(ssize_t) windows->image.x+event.xbutton.x;
10786 paste_info.y=(ssize_t) windows->image.y+event.xbutton.y;
10796 command[MagickPathExtent];
10804 if (event.xkey.window != windows->image.id)
10809 length=XLookupString((XKeyEvent *) &event.xkey,command,(
int)
10810 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
10811 *(command+length)=
'\0';
10812 if (resource_info->debug != MagickFalse)
10813 (void) LogMagickEvent(X11Event,GetMagickModule(),
10814 "Key press: 0x%lx (%s)",(
long) key_symbol,command);
10815 switch ((
int) key_symbol)
10823 paste_image=DestroyImage(paste_image);
10824 state|=EscapeState;
10831 (void) XSetFunction(display,windows->image.highlight_context,
10833 XTextViewHelp(display,resource_info,windows,MagickFalse,
10834 "Help Viewer - Image Composite",ImagePasteHelp);
10835 (void) XSetFunction(display,windows->image.highlight_context,
10841 (void) XBell(display,0);
10854 if (windows->info.mapped != MagickFalse)
10856 if ((x < (windows->info.x+(
int) windows->info.width)) &&
10857 (y < (windows->info.y+(
int) windows->info.height)))
10858 (void) XWithdrawWindow(display,windows->info.id,
10859 windows->info.screen);
10862 if ((x > (windows->info.x+(
int) windows->info.width)) ||
10863 (y > (windows->info.y+(
int) windows->info.height)))
10864 (void) XMapWindow(display,windows->info.id);
10865 paste_info.x=(ssize_t) windows->image.x+x;
10866 paste_info.y=(ssize_t) windows->image.y+y;
10871 if (resource_info->debug != MagickFalse)
10872 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Event type: %d",
10877 }
while ((state & ExitState) == 0);
10878 (void) XSelectInput(display,windows->image.id,
10879 windows->image.attributes.event_mask);
10880 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
10881 XSetCursorState(display,windows,MagickFalse);
10882 (void) XFreeCursor(display,cursor);
10883 if ((state & EscapeState) != 0)
10884 return(MagickTrue);
10888 XSetCursorState(display,windows,MagickTrue);
10889 XCheckRefreshWindows(display,windows);
10890 width=(
unsigned int) image->columns;
10891 height=(
unsigned int) image->rows;
10894 if (windows->image.crop_geometry != (
char *) NULL)
10895 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
10896 scale_factor=(double) width/windows->image.ximage->width;
10898 paste_info.x=(ssize_t) (scale_factor*paste_info.x+0.5);
10899 paste_info.width=(
unsigned int) (scale_factor*paste_info.width+0.5);
10900 scale_factor=(double) height/windows->image.ximage->height;
10902 paste_info.y=(ssize_t) (scale_factor*paste_info.y*scale_factor+0.5);
10903 paste_info.height=(
unsigned int) (scale_factor*paste_info.height+0.5);
10907 (void) CompositeImage(image,paste_image,compose,MagickTrue,paste_info.x,
10908 paste_info.y,exception);
10909 paste_image=DestroyImage(paste_image);
10910 XSetCursorState(display,windows,MagickFalse);
10914 XConfigureImageColormap(display,resource_info,windows,image,exception);
10915 (void) XConfigureImage(display,resource_info,windows,image,exception);
10916 return(MagickTrue);
10952static MagickBooleanType XPrintImage(Display *display,
10953 XResourceInfo *resource_info,XWindows *windows,
Image *image,
10957 filename[MagickPathExtent],
10958 geometry[MagickPathExtent];
10961 *
const PageSizes[] =
10992 image_info=CloneImageInfo(resource_info->image_info);
10993 (void) FormatLocaleString(geometry,MagickPathExtent,
"Letter");
10994 if (image_info->page != (
char *) NULL)
10995 (void) CopyMagickString(geometry,image_info->page,MagickPathExtent);
10996 XListBrowserWidget(display,windows,&windows->widget,PageSizes,
"Select",
10997 "Select Postscript Page Geometry:",geometry);
10998 if (*geometry ==
'\0')
10999 return(MagickTrue);
11000 image_info->page=GetPageGeometry(geometry);
11004 XSetCursorState(display,windows,MagickTrue);
11005 XCheckRefreshWindows(display,windows);
11006 print_image=CloneImage(image,0,0,MagickTrue,exception);
11007 if (print_image == (
Image *) NULL)
11008 return(MagickFalse);
11009 (void) FormatLocaleString(geometry,MagickPathExtent,
"%dx%d!",
11010 windows->image.ximage->width,windows->image.ximage->height);
11011 (void) TransformImage(&print_image,windows->image.crop_geometry,geometry,
11016 (void) AcquireUniqueFilename(filename);
11017 (void) FormatLocaleString(print_image->filename,MagickPathExtent,
"print:%s",
11019 status=WriteImage(image_info,print_image,exception);
11020 (void) RelinquishUniqueFileResource(filename);
11021 print_image=DestroyImage(print_image);
11022 image_info=DestroyImageInfo(image_info);
11023 XSetCursorState(display,windows,MagickFalse);
11024 return(status != 0 ? MagickTrue : MagickFalse);
11060static MagickBooleanType XROIImage(Display *display,
11061 XResourceInfo *resource_info,XWindows *windows,
Image **image,
11064#define ApplyMenus 7
11073 *
const ApplyMenu[] =
11086 *
const FileMenu[] =
11092 *
const EditMenu[] =
11098 *
const TransformMenu[] =
11106 *
const EnhanceMenu[] =
11114 "Contrast Stretch...",
11115 "Sigmoidal Contrast...",
11124 *
const EffectsMenu[] =
11149 "Charcoal Draw...",
11152 *
const MiscellanyMenu[] =
11163 *
const *Menus[ApplyMenus] =
11174 static const DisplayCommand
11197 TransformCommands[] =
11201 RotateRightCommand,
11204 EnhanceCommands[] =
11212 ContrastStretchCommand,
11213 SigmoidalContrastCommand,
11221 EffectsCommands[] =
11225 ReduceNoiseCommand,
11245 CharcoalDrawCommand
11247 MiscellanyCommands[] =
11251 ShowPreviewCommand,
11252 ShowHistogramCommand,
11261 static const DisplayCommand
11262 *Commands[ApplyMenus] =
11274 command[MagickPathExtent],
11275 text[MagickPathExtent];
11295 MagickProgressMonitor
11316 (void) CloneString(&windows->command.name,
"ROI");
11317 windows->command.data=0;
11318 (void) XCommandWidget(display,windows,ROIMenu,(XEvent *) NULL);
11319 (void) XMapRaised(display,windows->command.id);
11320 XClientMessage(display,windows->image.id,windows->im_protocols,
11321 windows->im_update_widget,CurrentTime);
11325 XQueryPosition(display,windows->image.id,&x,&y);
11326 (void) XSelectInput(display,windows->image.id,
11327 windows->image.attributes.event_mask | PointerMotionMask);
11328 roi_info.x=(ssize_t) windows->image.x+x;
11329 roi_info.y=(ssize_t) windows->image.y+y;
11332 cursor=XCreateFontCursor(display,XC_fleur);
11333 state=DefaultState;
11336 if (windows->info.mapped != MagickFalse)
11341 (void) FormatLocaleString(text,MagickPathExtent,
" %+ld%+ld ",
11342 (
long) roi_info.x,(
long) roi_info.y);
11343 XInfoWidget(display,windows,text);
11348 XScreenEvent(display,windows,&event,exception);
11349 if (event.xany.window == windows->command.id)
11354 id=XCommandWidget(display,windows,ROIMenu,&event);
11357 switch (ROICommands[
id])
11359 case ROIHelpCommand:
11361 XTextViewHelp(display,resource_info,windows,MagickFalse,
11362 "Help Viewer - Region of Interest",ImageROIHelp);
11365 case ROIDismissCommand:
11370 state|=EscapeState;
11379 switch (event.type)
11383 if (event.xbutton.button != Button1)
11385 if (event.xbutton.window != windows->image.id)
11390 (void) XCheckDefineCursor(display,windows->image.id,cursor);
11391 roi_info.x=(ssize_t) windows->image.x+event.xbutton.x;
11392 roi_info.y=(ssize_t) windows->image.y+event.xbutton.y;
11396 case ButtonRelease:
11405 if (event.xkey.window != windows->image.id)
11410 (void) XLookupString((XKeyEvent *) &event.xkey,command,(
int)
11411 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
11412 switch ((
int) key_symbol)
11420 state|=EscapeState;
11427 XTextViewHelp(display,resource_info,windows,MagickFalse,
11428 "Help Viewer - Region of Interest",ImageROIHelp);
11433 (void) XBell(display,0);
11446 if (windows->info.mapped != MagickFalse)
11448 if ((x < (windows->info.x+(
int) windows->info.width)) &&
11449 (y < (windows->info.y+(
int) windows->info.height)))
11450 (void) XWithdrawWindow(display,windows->info.id,
11451 windows->info.screen);
11454 if ((x > (windows->info.x+(
int) windows->info.width)) ||
11455 (y > (windows->info.y+(
int) windows->info.height)))
11456 (void) XMapWindow(display,windows->info.id);
11457 roi_info.x=(ssize_t) windows->image.x+x;
11458 roi_info.y=(ssize_t) windows->image.y+y;
11464 }
while ((state & ExitState) == 0);
11465 (void) XSelectInput(display,windows->image.id,
11466 windows->image.attributes.event_mask);
11467 if ((state & EscapeState) != 0)
11472 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
11473 (void) XFreeCursor(display,cursor);
11474 return(MagickTrue);
11476 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
11482 x=(int) roi_info.x;
11483 y=(int) roi_info.y;
11486 state=DefaultState;
11489 highlight_info=roi_info;
11490 highlight_info.x=roi_info.x-windows->image.x;
11491 highlight_info.y=roi_info.y-windows->image.y;
11492 if ((highlight_info.width > 3) && (highlight_info.height > 3))
11497 if (windows->info.mapped == MagickFalse)
11498 (void) XMapWindow(display,windows->info.id);
11499 (void) FormatLocaleString(text,MagickPathExtent,
11500 " %.20gx%.20g%+.20g%+.20g",(
double) roi_info.width,(
double)
11501 roi_info.height,(
double) roi_info.x,(
double) roi_info.y);
11502 XInfoWidget(display,windows,text);
11503 XHighlightRectangle(display,windows->image.id,
11504 windows->image.highlight_context,&highlight_info);
11507 if (windows->info.mapped != MagickFalse)
11508 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
11512 XScreenEvent(display,windows,&event,exception);
11513 if ((highlight_info.width > 3) && (highlight_info.height > 3))
11514 XHighlightRectangle(display,windows->image.id,
11515 windows->image.highlight_context,&highlight_info);
11516 switch (event.type)
11520 roi_info.x=(ssize_t) windows->image.x+event.xbutton.x;
11521 roi_info.y=(ssize_t) windows->image.y+event.xbutton.y;
11524 case ButtonRelease:
11529 roi_info.x=(ssize_t) windows->image.x+event.xbutton.x;
11530 roi_info.y=(ssize_t) windows->image.y+event.xbutton.y;
11531 XSetCursorState(display,windows,MagickFalse);
11533 if (LocaleCompare(windows->command.name,
"Apply") == 0)
11535 (void) CloneString(&windows->command.name,
"Apply");
11536 windows->command.data=ApplyMenus;
11537 (void) XCommandWidget(display,windows,ApplyMenu,(XEvent *) NULL);
11544 roi_info.x=(ssize_t) windows->image.x+event.xmotion.x;
11545 roi_info.y=(ssize_t) windows->image.y+event.xmotion.y;
11550 if ((((
int) roi_info.x != x) && ((
int) roi_info.y != y)) ||
11551 ((state & ExitState) != 0))
11556 if (roi_info.x < 0)
11559 if (roi_info.x > (ssize_t) windows->image.ximage->width)
11560 roi_info.x=(ssize_t) windows->image.ximage->width;
11561 if ((
int) roi_info.x < x)
11562 roi_info.width=(
unsigned int) (x-roi_info.x);
11565 roi_info.width=(
unsigned int) (roi_info.x-x);
11566 roi_info.x=(ssize_t) x;
11568 if (roi_info.y < 0)
11571 if (roi_info.y > (ssize_t) windows->image.ximage->height)
11572 roi_info.y=(ssize_t) windows->image.ximage->height;
11573 if ((
int) roi_info.y < y)
11574 roi_info.height=(
unsigned int) (y-roi_info.y);
11577 roi_info.height=(
unsigned int) (roi_info.y-y);
11578 roi_info.y=(ssize_t) y;
11581 }
while ((state & ExitState) == 0);
11585 state=DefaultState;
11586 display_command=NullCommand;
11589 (void) XMapWindow(display,windows->info.id);
11592 if (windows->info.mapped != MagickFalse)
11597 (void) FormatLocaleString(text,MagickPathExtent,
11598 " %.20gx%.20g%+.20g%+.20g",(
double) roi_info.width,(
double)
11599 roi_info.height,(
double) roi_info.x,(
double) roi_info.y);
11600 XInfoWidget(display,windows,text);
11602 highlight_info=roi_info;
11603 highlight_info.x=roi_info.x-windows->image.x;
11604 highlight_info.y=roi_info.y-windows->image.y;
11605 if ((highlight_info.width <= 3) || (highlight_info.height <= 3))
11607 state|=EscapeState;
11611 if ((state & UpdateRegionState) != 0)
11613 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
11614 switch (display_command)
11619 (void) XMagickCommand(display,resource_info,windows,
11620 display_command,image,exception);
11628 progress_monitor=SetImageProgressMonitor(*image,
11629 (MagickProgressMonitor) NULL,(*image)->client_data);
11630 crop_info=roi_info;
11631 width=(
unsigned int) (*image)->columns;
11632 height=(
unsigned int) (*image)->rows;
11635 if (windows->image.crop_geometry != (
char *) NULL)
11636 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
11638 scale_factor=(double) width/windows->image.ximage->width;
11640 crop_info.x=(ssize_t) (scale_factor*crop_info.x+0.5);
11641 crop_info.width=(
unsigned int) (scale_factor*crop_info.width+0.5);
11642 scale_factor=(double)
11643 height/windows->image.ximage->height;
11645 crop_info.y=(ssize_t) (scale_factor*crop_info.y+0.5);
11646 crop_info.height=(
unsigned int)
11647 (scale_factor*crop_info.height+0.5);
11648 roi_image=CropImage(*image,&crop_info,exception);
11649 (void) SetImageProgressMonitor(*image,progress_monitor,
11650 (*image)->client_data);
11651 if (roi_image == (
Image *) NULL)
11656 windows->image.orphan=MagickTrue;
11657 (void) XMagickCommand(display,resource_info,windows,
11658 display_command,&roi_image,exception);
11659 progress_monitor=SetImageProgressMonitor(*image,
11660 (MagickProgressMonitor) NULL,(*image)->client_data);
11661 (void) XMagickCommand(display,resource_info,windows,
11662 SaveToUndoBufferCommand,image,exception);
11663 windows->image.orphan=MagickFalse;
11664 (void) CompositeImage(*image,roi_image,CopyCompositeOp,
11665 MagickTrue,crop_info.x,crop_info.y,exception);
11666 roi_image=DestroyImage(roi_image);
11667 (void) SetImageProgressMonitor(*image,progress_monitor,
11668 (*image)->client_data);
11672 if (display_command != InfoCommand)
11674 XConfigureImageColormap(display,resource_info,windows,*image,
11676 (void) XConfigureImage(display,resource_info,windows,*image,
11679 XCheckRefreshWindows(display,windows);
11680 XInfoWidget(display,windows,text);
11681 (void) XSetFunction(display,windows->image.highlight_context,
11683 state&=(
unsigned int) (~UpdateRegionState);
11685 XHighlightRectangle(display,windows->image.id,
11686 windows->image.highlight_context,&highlight_info);
11687 XScreenEvent(display,windows,&event,exception);
11688 if (event.xany.window == windows->command.id)
11693 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
11694 display_command=NullCommand;
11695 id=XCommandWidget(display,windows,ApplyMenu,&event);
11698 (void) CopyMagickString(command,ApplyMenu[
id],MagickPathExtent);
11699 display_command=ApplyCommands[id];
11700 if (
id < ApplyMenus)
11705 entry=XMenuWidget(display,windows,ApplyMenu[
id],
11706 (
const char **) Menus[
id],command);
11709 (void) CopyMagickString(command,Menus[
id][entry],
11711 display_command=Commands[id][entry];
11715 (void) XSetFunction(display,windows->image.highlight_context,
11717 XHighlightRectangle(display,windows->image.id,
11718 windows->image.highlight_context,&highlight_info);
11719 if (display_command == HelpCommand)
11721 (void) XSetFunction(display,windows->image.highlight_context,
11723 XTextViewHelp(display,resource_info,windows,MagickFalse,
11724 "Help Viewer - Region of Interest",ImageROIHelp);
11725 (void) XSetFunction(display,windows->image.highlight_context,
11729 if (display_command == QuitCommand)
11734 state|=EscapeState;
11738 if (display_command != NullCommand)
11739 state|=UpdateRegionState;
11742 XHighlightRectangle(display,windows->image.id,
11743 windows->image.highlight_context,&highlight_info);
11744 switch (event.type)
11748 x=windows->image.x;
11749 y=windows->image.y;
11750 if (event.xbutton.button != Button1)
11752 if (event.xbutton.window != windows->image.id)
11754 x=windows->image.x+
event.xbutton.x;
11755 y=windows->image.y+
event.xbutton.y;
11756 if ((x < (
int) (roi_info.x+RoiDelta)) &&
11757 (x > (
int) (roi_info.x-RoiDelta)) &&
11758 (y < (
int) (roi_info.y+RoiDelta)) &&
11759 (y > (
int) (roi_info.y-RoiDelta)))
11761 roi_info.x=roi_info.x+(int) roi_info.width;
11762 roi_info.y=roi_info.y+(int) roi_info.height;
11763 state|=UpdateConfigurationState;
11766 if ((x < (
int) (roi_info.x+RoiDelta)) &&
11767 (x > (
int) (roi_info.x-RoiDelta)) &&
11768 (y < (roi_info.y+(
int) roi_info.height+RoiDelta)) &&
11769 (y > (roi_info.y+(
int) roi_info.height-RoiDelta)))
11771 roi_info.x=roi_info.x+(int) roi_info.width;
11772 state|=UpdateConfigurationState;
11775 if ((x < (roi_info.x+(
int) roi_info.width+RoiDelta)) &&
11776 (x > (roi_info.x+(
int) roi_info.width-RoiDelta)) &&
11777 (y < (
int) (roi_info.y+RoiDelta)) &&
11778 (y > (
int) (roi_info.y-RoiDelta)))
11780 roi_info.y=roi_info.y+(int) roi_info.height;
11781 state|=UpdateConfigurationState;
11784 if ((x < (roi_info.x+(
int) roi_info.width+RoiDelta)) &&
11785 (x > (roi_info.x+(
int) roi_info.width-RoiDelta)) &&
11786 (y < (roi_info.y+(
int) roi_info.height+RoiDelta)) &&
11787 (y > (roi_info.y+(
int) roi_info.height-RoiDelta)))
11789 state|=UpdateConfigurationState;
11792 magick_fallthrough;
11794 case ButtonRelease:
11796 if (event.xbutton.window == windows->pan.id)
11797 if ((highlight_info.x != crop_info.x-windows->image.x) ||
11798 (highlight_info.y != crop_info.y-windows->image.y))
11799 XHighlightRectangle(display,windows->image.id,
11800 windows->image.highlight_context,&highlight_info);
11801 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id,
11802 event.xbutton.time);
11807 if (event.xexpose.window == windows->image.id)
11808 if (event.xexpose.count == 0)
11810 event.xexpose.x=(int) highlight_info.x;
11811 event.xexpose.y=(int) highlight_info.y;
11812 event.xexpose.width=(int) highlight_info.width;
11813 event.xexpose.height=(int) highlight_info.height;
11814 XRefreshWindow(display,&windows->image,&event);
11816 if (event.xexpose.window == windows->info.id)
11817 if (event.xexpose.count == 0)
11818 XInfoWidget(display,windows,text);
11826 if (event.xkey.window != windows->image.id)
11831 (void) XLookupString((XKeyEvent *) &event.xkey,command,(
int)
11832 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
11833 switch ((
int) key_symbol)
11841 state|=EscapeState;
11842 magick_fallthrough;
11852 roi_info.x=(ssize_t) (windows->image.width/2L-roi_info.width/2L);
11853 roi_info.y=(ssize_t) (windows->image.height/2L-
11854 roi_info.height/2L);
11886 (void) XSetFunction(display,windows->image.highlight_context,
11888 XTextViewHelp(display,resource_info,windows,MagickFalse,
11889 "Help Viewer - Region of Interest",ImageROIHelp);
11890 (void) XSetFunction(display,windows->image.highlight_context,
11896 display_command=XImageWindowCommand(display,resource_info,windows,
11897 event.xkey.state,key_symbol,image,exception);
11898 if (display_command != NullCommand)
11899 state|=UpdateRegionState;
11903 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id,
11911 if (event.xbutton.window != windows->image.id)
11918 if (windows->info.mapped != MagickFalse)
11920 if ((x < (windows->info.x+(
int) windows->info.width)) &&
11921 (y < (windows->info.y+(
int) windows->info.height)))
11922 (void) XWithdrawWindow(display,windows->info.id,
11923 windows->info.screen);
11926 if ((x > (windows->info.x+(
int) windows->info.width)) ||
11927 (y > (windows->info.y+(
int) windows->info.height)))
11928 (void) XMapWindow(display,windows->info.id);
11929 roi_info.x=(ssize_t) windows->image.x+event.xmotion.x;
11930 roi_info.y=(ssize_t) windows->image.y+event.xmotion.y;
11933 case SelectionRequest:
11938 XSelectionRequestEvent
11944 (void) FormatLocaleString(text,MagickPathExtent,
11945 "%.20gx%.20g%+.20g%+.20g",(
double) roi_info.width,(
double)
11946 roi_info.height,(
double) roi_info.x,(
double) roi_info.y);
11947 request=(&(
event.xselectionrequest));
11948 (void) XChangeProperty(request->display,request->requestor,
11949 request->property,request->target,8,PropModeReplace,
11950 (
unsigned char *) text,(
int) strlen(text));
11951 notify.type=SelectionNotify;
11952 notify.display=request->display;
11953 notify.requestor=request->requestor;
11954 notify.selection=request->selection;
11955 notify.target=request->target;
11956 notify.time=request->time;
11957 if (request->property == None)
11958 notify.property=request->target;
11960 notify.property=request->property;
11961 (void) XSendEvent(request->display,request->requestor,False,0,
11962 (XEvent *) ¬ify);
11967 if ((state & UpdateConfigurationState) != 0)
11969 (void) XPutBackEvent(display,&event);
11970 (void) XCheckDefineCursor(display,windows->image.id,cursor);
11973 }
while ((state & ExitState) == 0);
11974 }
while ((state & ExitState) == 0);
11975 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
11976 XSetCursorState(display,windows,MagickFalse);
11977 if ((state & EscapeState) != 0)
11978 return(MagickTrue);
11979 return(MagickTrue);
12018static MagickBooleanType XRotateImage(Display *display,
12019 XResourceInfo *resource_info,XWindows *windows,
double degrees,
Image **image,
12023 *
const RotateMenu[] =
12033 direction = HorizontalRotateCommand;
12035 static const ModeType
12036 DirectionCommands[] =
12038 HorizontalRotateCommand,
12039 VerticalRotateCommand
12043 RotateColorCommand,
12044 RotateDirectionCommand,
12046 RotateDismissCommand
12049 static unsigned int
12053 command[MagickPathExtent],
12054 text[MagickPathExtent];
12065 normalized_degrees;
12075 if (degrees == 0.0)
12092 (void) CloneString(&windows->command.name,
"Rotate");
12093 windows->command.data=2;
12094 (void) XCommandWidget(display,windows,RotateMenu,(XEvent *) NULL);
12095 (void) XMapRaised(display,windows->command.id);
12096 XClientMessage(display,windows->image.id,windows->im_protocols,
12097 windows->im_update_widget,CurrentTime);
12101 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
12102 XQueryPosition(display,windows->image.id,&x,&y);
12107 state=DefaultState;
12110 XHighlightLine(display,windows->image.id,
12111 windows->image.highlight_context,&rotate_info);
12115 XScreenEvent(display,windows,&event,exception);
12116 XHighlightLine(display,windows->image.id,
12117 windows->image.highlight_context,&rotate_info);
12118 if (event.xany.window == windows->command.id)
12123 id=XCommandWidget(display,windows,RotateMenu,&event);
12126 (void) XSetFunction(display,windows->image.highlight_context,
12128 switch (RotateCommands[
id])
12130 case RotateColorCommand:
12133 *ColorMenu[MaxNumberPens];
12144 for (i=0; i < (int) (MaxNumberPens-2); i++)
12145 ColorMenu[i]=resource_info->pen_colors[i];
12146 ColorMenu[MaxNumberPens-2]=
"Browser...";
12147 ColorMenu[MaxNumberPens-1]=(
const char *) NULL;
12151 pen_number=XMenuWidget(display,windows,RotateMenu[
id],
12152 (
const char **) ColorMenu,command);
12153 if (pen_number < 0)
12155 if (pen_number == (MaxNumberPens-2))
12158 color_name[MagickPathExtent] =
"gray";
12163 resource_info->pen_colors[pen_number]=color_name;
12164 XColorBrowserWidget(display,windows,
"Select",color_name);
12165 if (*color_name ==
'\0')
12171 (void) XParseColor(display,windows->map_info->colormap,
12172 resource_info->pen_colors[pen_number],&color);
12173 XBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
12174 (
unsigned int) MaxColors,&color);
12175 windows->pixel_info->pen_colors[pen_number]=color;
12176 pen_id=(
unsigned int) pen_number;
12179 case RotateDirectionCommand:
12192 id=XMenuWidget(display,windows,RotateMenu[
id],
12193 Directions,command);
12195 direction=DirectionCommands[id];
12198 case RotateHelpCommand:
12200 XTextViewHelp(display,resource_info,windows,MagickFalse,
12201 "Help Viewer - Image Rotation",ImageRotateHelp);
12204 case RotateDismissCommand:
12209 state|=EscapeState;
12216 (void) XSetFunction(display,windows->image.highlight_context,
12220 switch (event.type)
12224 if (event.xbutton.button != Button1)
12226 if (event.xbutton.window != windows->image.id)
12231 (void) XSetFunction(display,windows->image.highlight_context,
12233 rotate_info.x1=
event.xbutton.x;
12234 rotate_info.y1=
event.xbutton.y;
12238 case ButtonRelease:
12245 command[MagickPathExtent];
12250 if (event.xkey.window != windows->image.id)
12255 (void) XLookupString((XKeyEvent *) &event.xkey,command,(
int)
12256 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
12257 switch ((
int) key_symbol)
12265 state|=EscapeState;
12272 (void) XSetFunction(display,windows->image.highlight_context,
12274 XTextViewHelp(display,resource_info,windows,MagickFalse,
12275 "Help Viewer - Image Rotation",ImageRotateHelp);
12276 (void) XSetFunction(display,windows->image.highlight_context,
12282 (void) XBell(display,0);
12290 rotate_info.x1=
event.xmotion.x;
12291 rotate_info.y1=
event.xmotion.y;
12294 rotate_info.x2=rotate_info.x1;
12295 rotate_info.y2=rotate_info.y1;
12296 if (direction == HorizontalRotateCommand)
12297 rotate_info.x2+=32;
12299 rotate_info.y2-=32;
12300 }
while ((state & ExitState) == 0);
12301 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
12302 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
12303 if ((state & EscapeState) != 0)
12304 return(MagickTrue);
12309 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
12310 state=DefaultState;
12318 if (windows->info.mapped == MagickFalse)
12319 (void) XMapWindow(display,windows->info.id);
12320 (void) FormatLocaleString(text,MagickPathExtent,
" %g",
12321 direction == VerticalRotateCommand ? degrees-90.0 : degrees);
12322 XInfoWidget(display,windows,text);
12323 XHighlightLine(display,windows->image.id,
12324 windows->image.highlight_context,&rotate_info);
12327 if (windows->info.mapped != MagickFalse)
12328 (void) XWithdrawWindow(display,windows->info.id,
12329 windows->info.screen);
12333 XScreenEvent(display,windows,&event,exception);
12335 XHighlightLine(display,windows->image.id,
12336 windows->image.highlight_context,&rotate_info);
12337 switch (event.type)
12341 case ButtonRelease:
12346 rotate_info.x2=
event.xbutton.x;
12347 rotate_info.y2=
event.xbutton.y;
12355 rotate_info.x2=
event.xmotion.x;
12356 rotate_info.y2=
event.xmotion.y;
12364 if (rotate_info.x2 < 0)
12367 if (rotate_info.x2 > (
int) windows->image.width)
12368 rotate_info.x2=(short) windows->image.width;
12369 if (rotate_info.y2 < 0)
12372 if (rotate_info.y2 > (
int) windows->image.height)
12373 rotate_info.y2=(short) windows->image.height;
12378 distance=(
unsigned int)
12379 (((rotate_info.x2-rotate_info.x1+1)*(rotate_info.x2-rotate_info.x1+1))+
12380 ((rotate_info.y2-rotate_info.y1+1)*(rotate_info.y2-rotate_info.y1+1)));
12382 degrees=RadiansToDegrees(-atan2((
double) (rotate_info.y2-
12383 rotate_info.y1),(
double) (rotate_info.x2-rotate_info.x1)));
12384 }
while ((state & ExitState) == 0);
12385 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
12386 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
12388 return(MagickTrue);
12390 if (direction == VerticalRotateCommand)
12392 if (degrees == 0.0)
12393 return(MagickTrue);
12397 normalized_degrees=degrees;
12398 while (normalized_degrees < -45.0)
12399 normalized_degrees+=360.0;
12400 for (rotations=0; normalized_degrees > 45.0; rotations++)
12401 normalized_degrees-=90.0;
12402 if (normalized_degrees != 0.0)
12403 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
12405 XSetCursorState(display,windows,MagickTrue);
12406 XCheckRefreshWindows(display,windows);
12407 (*image)->background_color.red=(double) ScaleShortToQuantum(
12408 windows->pixel_info->pen_colors[pen_id].red);
12409 (*image)->background_color.green=(double) ScaleShortToQuantum(
12410 windows->pixel_info->pen_colors[pen_id].green);
12411 (*image)->background_color.blue=(double) ScaleShortToQuantum(
12412 windows->pixel_info->pen_colors[pen_id].blue);
12413 rotate_image=RotateImage(*image,degrees,exception);
12414 XSetCursorState(display,windows,MagickFalse);
12415 if (rotate_image == (
Image *) NULL)
12416 return(MagickFalse);
12417 *image=DestroyImage(*image);
12418 *image=rotate_image;
12419 if (windows->image.crop_geometry != (
char *) NULL)
12424 width=(
unsigned int) (*image)->columns;
12425 height=(
unsigned int) (*image)->rows;
12426 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
12427 switch (rotations % 4)
12437 (void) FormatLocaleString(windows->image.crop_geometry,
12438 MagickPathExtent,
"%ux%u%+d%+d",height,width,(
int) (*image)->columns-
12447 (void) FormatLocaleString(windows->image.crop_geometry,
12448 MagickPathExtent,
"%ux%u%+d%+d",width,height,(
int) width-x,(
int)
12457 (void) FormatLocaleString(windows->image.crop_geometry,
12458 MagickPathExtent,
"%ux%u%+d%+d",height,width,y,(
int) (*image)->rows-
12464 if (windows->image.orphan != MagickFalse)
12465 return(MagickTrue);
12466 if (normalized_degrees != 0.0)
12471 windows->image.window_changes.width=(int) (*image)->columns;
12472 windows->image.window_changes.height=(int) (*image)->rows;
12473 if (windows->image.crop_geometry != (
char *) NULL)
12478 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
12480 windows->image.window_changes.width=(int) width;
12481 windows->image.window_changes.height=(int) height;
12483 XConfigureImageColormap(display,resource_info,windows,*image,exception);
12486 if (((rotations % 4) == 1) || ((rotations % 4) == 3))
12488 windows->image.window_changes.width=windows->image.ximage->height;
12489 windows->image.window_changes.height=windows->image.ximage->width;
12494 (void) XConfigureImage(display,resource_info,windows,*image,exception);
12495 return(MagickTrue);
12531static MagickBooleanType XSaveImage(Display *display,
12532 XResourceInfo *resource_info,XWindows *windows,
Image *image,
12536 filename[MagickPathExtent],
12537 geometry[MagickPathExtent];
12551 if (resource_info->write_filename != (
char *) NULL)
12552 (void) CopyMagickString(filename,resource_info->write_filename,
12557 path[MagickPathExtent];
12562 GetPathComponent(image->filename,HeadPath,path);
12563 GetPathComponent(image->filename,TailPath,filename);
12566 status=chdir(path);
12568 (void) ThrowMagickException(exception,GetMagickModule(),
12569 FileOpenError,
"UnableToOpenFile",
"%s",path);
12572 XFileBrowserWidget(display,windows,
"Save",filename);
12573 if (*filename ==
'\0')
12574 return(MagickTrue);
12575 if (IsPathAccessible(filename) != MagickFalse)
12583 status=XConfirmWidget(display,windows,
"Overwrite",filename);
12585 return(MagickTrue);
12587 image_info=CloneImageInfo(resource_info->image_info);
12588 (void) CopyMagickString(image_info->filename,filename,MagickPathExtent);
12589 (void) SetImageInfo(image_info,1,exception);
12590 if ((LocaleCompare(image_info->magick,
"JPEG") == 0) ||
12591 (LocaleCompare(image_info->magick,
"JPG") == 0))
12594 quality[MagickPathExtent];
12602 (void) FormatLocaleString(quality,MagickPathExtent,
"%.20g",(
double)
12604 status=XDialogWidget(display,windows,
"Save",
"Enter JPEG quality:",
12606 if (*quality ==
'\0')
12607 return(MagickTrue);
12608 image->quality=StringToUnsignedLong(quality);
12609 image_info->interlace=status != 0 ? NoInterlace : PlaneInterlace;
12611 if ((LocaleCompare(image_info->magick,
"EPS") == 0) ||
12612 (LocaleCompare(image_info->magick,
"PDF") == 0) ||
12613 (LocaleCompare(image_info->magick,
"PS") == 0) ||
12614 (LocaleCompare(image_info->magick,
"PS2") == 0))
12617 geometry[MagickPathExtent];
12620 *
const PageSizes[] =
12642 (void) CopyMagickString(geometry,PSPageGeometry,MagickPathExtent);
12643 if (LocaleCompare(image_info->magick,
"PDF") == 0)
12644 (void) CopyMagickString(geometry,PSPageGeometry,MagickPathExtent);
12645 if (image_info->page != (
char *) NULL)
12646 (void) CopyMagickString(geometry,image_info->page,MagickPathExtent);
12647 XListBrowserWidget(display,windows,&windows->widget,PageSizes,
"Select",
12648 "Select page geometry:",geometry);
12649 if (*geometry !=
'\0')
12650 image_info->page=GetPageGeometry(geometry);
12655 XSetCursorState(display,windows,MagickTrue);
12656 XCheckRefreshWindows(display,windows);
12657 save_image=CloneImage(image,0,0,MagickTrue,exception);
12658 if (save_image == (
Image *) NULL)
12659 return(MagickFalse);
12660 (void) FormatLocaleString(geometry,MagickPathExtent,
"%dx%d!",
12661 windows->image.ximage->width,windows->image.ximage->height);
12662 (void) TransformImage(&save_image,windows->image.crop_geometry,geometry,
12667 (void) CopyMagickString(save_image->filename,filename,MagickPathExtent);
12668 status=WriteImage(image_info,save_image,exception);
12669 if (status != MagickFalse)
12670 image->taint=MagickFalse;
12671 save_image=DestroyImage(save_image);
12672 image_info=DestroyImageInfo(image_info);
12673 XSetCursorState(display,windows,MagickFalse);
12674 return(status != 0 ? MagickTrue : MagickFalse);
12709#if defined(__cplusplus) || defined(c_plusplus)
12713static int XPredicate(Display *magick_unused(display),XEvent *event,
char *data)
12718 windows=(XWindows *) data;
12719 if ((event->type == ClientMessage) &&
12720 (event->xclient.window == windows->image.id))
12721 return(MagickFalse);
12722 return(MagickTrue);
12725#if defined(__cplusplus) || defined(c_plusplus)
12729static void XScreenEvent(Display *display,XWindows *windows,XEvent *event,
12736 (void) XIfEvent(display,event,XPredicate,(
char *) windows);
12737 if (event->xany.window == windows->command.id)
12739 switch (event->type)
12742 case ButtonRelease:
12744 if ((event->xbutton.button == Button3) &&
12745 (event->xbutton.state & Mod1Mask))
12750 event->xbutton.button=Button2;
12751 event->xbutton.state&=(
unsigned int) (~Mod1Mask);
12753 if (event->xbutton.window == windows->backdrop.id)
12755 (void) XSetInputFocus(display,event->xbutton.window,RevertToParent,
12756 event->xbutton.time);
12759 if (event->xbutton.window == windows->pan.id)
12761 XPanImage(display,windows,event,exception);
12764 if (event->xbutton.window == windows->image.id)
12765 if (event->xbutton.button == Button2)
12770 x=
event->xbutton.x;
12771 y=
event->xbutton.y;
12775 if (x >= (
int) windows->image.width)
12776 x=(int) (windows->image.width-1);
12777 windows->magnify.x=(int) windows->image.x+x;
12781 if (y >= (
int) windows->image.height)
12782 y=(int) (windows->image.height-1);
12783 windows->magnify.y=windows->image.y+y;
12784 if (windows->magnify.mapped == MagickFalse)
12785 (void) XMapRaised(display,windows->magnify.id);
12786 XMakeMagnifyImage(display,windows,exception);
12787 if (event->type == ButtonRelease)
12788 (void) XWithdrawWindow(display,windows->info.id,
12789 windows->info.screen);
12794 case ClientMessage:
12799 if (event->xclient.message_type != windows->wm_protocols)
12801 if (*event->xclient.data.l != (
long) windows->wm_delete_window)
12803 if (event->xclient.window == windows->magnify.id)
12805 (void) XWithdrawWindow(display,windows->magnify.id,
12806 windows->magnify.screen);
12811 case ConfigureNotify:
12813 if (event->xconfigure.window == windows->magnify.id)
12821 windows->magnify.width=(
unsigned int) event->xconfigure.width;
12822 windows->magnify.height=(
unsigned int) event->xconfigure.height;
12823 if (windows->magnify.mapped == MagickFalse)
12826 while ((
int) magnify <= event->xconfigure.width)
12828 while ((
int) magnify <= event->xconfigure.height)
12831 if (((
int) magnify != event->xconfigure.width) ||
12832 ((
int) magnify != event->xconfigure.height))
12837 window_changes.width=(int) magnify;
12838 window_changes.height=(int) magnify;
12839 (void) XReconfigureWMWindow(display,windows->magnify.id,
12840 windows->magnify.screen,(
unsigned int) (CWWidth | CWHeight),
12844 XMakeMagnifyImage(display,windows,exception);
12851 if (event->xexpose.window == windows->image.id)
12853 XRefreshWindow(display,&windows->image,event);
12856 if (event->xexpose.window == windows->pan.id)
12857 if (event->xexpose.count == 0)
12859 XDrawPanRectangle(display,windows);
12862 if (event->xexpose.window == windows->magnify.id)
12863 if (event->xexpose.count == 0)
12865 XMakeMagnifyImage(display,windows,exception);
12873 command[MagickPathExtent];
12878 if (event->xkey.window != windows->magnify.id)
12883 (void) XLookupString((XKeyEvent *) &event->xkey,command,(
int)
12884 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
12885 XMagnifyWindowCommand(display,windows,event->xkey.state,key_symbol,
12891 if (event->xmap.window == windows->magnify.id)
12893 windows->magnify.mapped=MagickTrue;
12894 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
12897 if (event->xmap.window == windows->info.id)
12899 windows->info.mapped=MagickTrue;
12906 while (XCheckMaskEvent(display,ButtonMotionMask,event)) ;
12907 if (event->xmotion.window == windows->image.id)
12908 if (windows->magnify.mapped != MagickFalse)
12913 x=
event->xmotion.x;
12914 y=
event->xmotion.y;
12918 if (x >= (
int) windows->image.width)
12919 x=(int) (windows->image.width-1);
12920 windows->magnify.x=(int) windows->image.x+x;
12924 if (y >= (
int) windows->image.height)
12925 y=(int) (windows->image.height-1);
12926 windows->magnify.y=windows->image.y+y;
12927 XMakeMagnifyImage(display,windows,exception);
12933 if (event->xunmap.window == windows->magnify.id)
12935 windows->magnify.mapped=MagickFalse;
12938 if (event->xunmap.window == windows->info.id)
12940 windows->info.mapped=MagickFalse;
12982static void XSetCropGeometry(Display *display,XWindows *windows,
12986 text[MagickPathExtent];
12999 if (windows->info.mapped != MagickFalse)
13004 (void) FormatLocaleString(text,MagickPathExtent,
" %.20gx%.20g%+.20g%+.20g",
13005 (
double) crop_info->width,(
double) crop_info->height,(
double)
13006 crop_info->x,(
double) crop_info->y);
13007 XInfoWidget(display,windows,text);
13014 width=(
unsigned int) image->columns;
13015 height=(
unsigned int) image->rows;
13016 if (windows->image.crop_geometry != (
char *) NULL)
13017 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
13019 windows->image.crop_geometry=AcquireString((
char *) NULL);
13023 scale_factor=(double) width/windows->image.ximage->width;
13024 if (crop_info->x > 0)
13025 x+=(int) (scale_factor*crop_info->x+0.5);
13026 width=(
unsigned int) (scale_factor*crop_info->width+0.5);
13029 scale_factor=(double) height/windows->image.ximage->height;
13030 if (crop_info->y > 0)
13031 y+=(int) (scale_factor*crop_info->y+0.5);
13032 height=(
unsigned int) (scale_factor*crop_info->height+0.5);
13035 (void) FormatLocaleString(windows->image.crop_geometry,MagickPathExtent,
13036 "%ux%u%+d%+d",width,height,x,y);
13078static Image *XTileImage(Display *display,XResourceInfo *resource_info,
13082 *
const VerbMenu[] =
13092 static const ModeType
13103 command[MagickPathExtent],
13104 filename[MagickPathExtent];
13135 width=(
unsigned int) image->columns;
13136 height=(
unsigned int) image->rows;
13137 if (windows->image.crop_geometry != (
char *) NULL)
13138 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
13139 scale_factor=(double) width/windows->image.ximage->width;
13140 event->xbutton.x+=windows->image.x;
13141 event->xbutton.x=(int) (scale_factor*event->xbutton.x+x+0.5);
13142 scale_factor=(double) height/windows->image.ximage->height;
13143 event->xbutton.y+=windows->image.y;
13144 event->xbutton.y=(int) (scale_factor*event->xbutton.y+y+0.5);
13148 width=(
unsigned int) image->columns;
13149 height=(
unsigned int) image->rows;
13152 (void) XParseGeometry(image->montage,&x,&y,&width,&height);
13153 tile=((
event->xbutton.y-y)/(int) height)*(((
int) image->columns-x)/(
int)
13154 width)+(
event->xbutton.x-x)/(
int) width;
13160 (void) XBell(display,0);
13161 return((
Image *) NULL);
13166 p=image->directory;
13167 for (i=tile; (i != 0) && (*p !=
'\0'); )
13178 (void) XBell(display,0);
13179 return((
Image *) NULL);
13184 id=XMenuWidget(display,windows,
"Tile Verb",VerbMenu,command);
13186 return((
Image *) NULL);
13188 while ((*q !=
'\xff') && (*q !=
'\0'))
13190 (void) CopyMagickString(filename,p,(
size_t) (q-p+1));
13194 XSetCursorState(display,windows,MagickTrue);
13195 XCheckRefreshWindows(display,windows);
13196 tile_image=NewImageList();
13197 switch (TileCommands[
id])
13199 case TileLoadCommand:
13204 XCheckRefreshWindows(display,windows);
13205 (void) CopyMagickString(resource_info->image_info->magick,
"MIFF",
13207 (void) CopyMagickString(resource_info->image_info->filename,filename,
13209 tile_image=ReadImage(resource_info->image_info,exception);
13210 CatchException(exception);
13211 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
13214 case TileNextCommand:
13219 XClientMessage(display,windows->image.id,windows->im_protocols,
13220 windows->im_next_image,CurrentTime);
13223 case TileFormerCommand:
13228 XClientMessage(display,windows->image.id,windows->im_protocols,
13229 windows->im_former_image,CurrentTime);
13232 case TileDeleteCommand:
13237 if (IsPathAccessible(filename) == MagickFalse)
13239 XNoticeWidget(display,windows,
"Image file does not exist:",filename);
13242 status=XConfirmWidget(display,windows,
"Really delete tile",filename);
13245 status=ShredFile(filename) == MagickFalse ? 0 : 1;
13246 status|=remove_utf8(filename);
13247 if (status != MagickFalse)
13249 XNoticeWidget(display,windows,
"Unable to delete image file:",
13253 magick_fallthrough;
13255 case TileUpdateCommand:
13274 GetPixelInfo(image,&pixel);
13275 for (p=image->directory; *p !=
'\0'; p++)
13281 while ((*q !=
'\xff') && (*q !=
'\0'))
13283 (void) CopyMagickString(filename,p,(
size_t) (q-p+1));
13285 if (IsPathAccessible(filename) != MagickFalse)
13293 x_offset=((int) width*(tile % (((int) image->columns-x)/(int) width))+
13295 y_offset=((int) height*(tile/(((int) image->columns-x)/(int) width))+
13297 image_view=AcquireAuthenticCacheView(image,exception);
13298 (void) GetOneCacheViewVirtualPixelInfo(image_view,0,0,&pixel,exception);
13299 for (i=0; i < (int) height; i++)
13301 s=GetCacheViewAuthenticPixels(image_view,(ssize_t) x_offset,(ssize_t)
13302 y_offset+i,width,1,exception);
13303 if (s == (Quantum *) NULL)
13305 for (j=0; j < (int) width; j++)
13307 SetPixelViaPixelInfo(image,&pixel,s);
13308 s+=(ptrdiff_t) GetPixelChannels(image);
13310 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
13313 image_view=DestroyCacheView(image_view);
13316 windows->image.window_changes.width=(int) image->columns;
13317 windows->image.window_changes.height=(int) image->rows;
13318 XConfigureImageColormap(display,resource_info,windows,image,exception);
13319 (void) XConfigureImage(display,resource_info,windows,image,exception);
13325 XSetCursorState(display,windows,MagickFalse);
13326 return(tile_image);
13362static void XTranslateImage(Display *display,XWindows *windows,
13363 Image *image,
const KeySym key_symbol)
13366 text[MagickPathExtent];
13379 x_offset=windows->image.width;
13380 y_offset=windows->image.height;
13381 if (image->montage != (
char *) NULL)
13382 (void) XParseGeometry(image->montage,&x,&y,&x_offset,&y_offset);
13383 switch ((
int) key_symbol)
13388 windows->image.x=(int) windows->image.width/2;
13389 windows->image.y=(int) windows->image.height/2;
13395 windows->image.x-=(int) x_offset;
13402 windows->image.y-=(int) y_offset;
13408 windows->image.x+=(int) x_offset;
13415 windows->image.y+=(int) y_offset;
13424 if (windows->image.x < 0)
13425 windows->image.x=0;
13427 if ((windows->image.x+(
int) windows->image.width) > windows->image.ximage->width)
13428 windows->image.x=windows->image.ximage->width-(int) windows->image.width;
13429 if (windows->image.y < 0)
13430 windows->image.y=0;
13432 if ((windows->image.y+(
int) windows->image.height) > windows->image.ximage->height)
13433 windows->image.y=windows->image.ximage->height-(int)
13434 windows->image.height;
13438 (void) FormatLocaleString(text,MagickPathExtent,
" %ux%u%+d%+d ",
13439 windows->image.width,windows->image.height,windows->image.x,
13441 XInfoWidget(display,windows,text);
13442 XCheckRefreshWindows(display,windows);
13443 XDrawPanRectangle(display,windows);
13444 XRefreshWindow(display,&windows->image,(XEvent *) NULL);
13445 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
13481static MagickBooleanType XTrimImage(Display *display,
13482 XResourceInfo *resource_info,XWindows *windows,
Image *image,
13499 XSetCursorState(display,windows,MagickTrue);
13500 XCheckRefreshWindows(display,windows);
13504 background=XGetPixel(windows->image.ximage,0,0);
13505 trim_info.width=(size_t) windows->image.ximage->width;
13506 for (x=0; x < windows->image.ximage->width; x++)
13508 for (y=0; y < windows->image.ximage->height; y++)
13510 pixel=XGetPixel(windows->image.ximage,x,y);
13511 if (pixel != background)
13514 if (y < windows->image.ximage->height)
13517 trim_info.x=(ssize_t) x;
13518 if (trim_info.x == (ssize_t) windows->image.ximage->width)
13520 XSetCursorState(display,windows,MagickFalse);
13521 return(MagickFalse);
13526 background=XGetPixel(windows->image.ximage,windows->image.ximage->width-1,0);
13527 for (x=windows->image.ximage->width-1; x != 0; x--)
13529 for (y=0; y < windows->image.ximage->height; y++)
13531 pixel=XGetPixel(windows->image.ximage,x,y);
13532 if (pixel != background)
13535 if (y < windows->image.ximage->height)
13538 trim_info.width=(size_t) (x-trim_info.x+1);
13542 background=XGetPixel(windows->image.ximage,0,0);
13543 trim_info.height=(size_t) windows->image.ximage->height;
13544 for (y=0; y < windows->image.ximage->height; y++)
13546 for (x=0; x < windows->image.ximage->width; x++)
13548 pixel=XGetPixel(windows->image.ximage,x,y);
13549 if (pixel != background)
13552 if (x < windows->image.ximage->width)
13555 trim_info.y=(ssize_t) y;
13559 background=XGetPixel(windows->image.ximage,0,windows->image.ximage->height-1);
13560 for (y=windows->image.ximage->height-1; y != 0; y--)
13562 for (x=0; x < windows->image.ximage->width; x++)
13564 pixel=XGetPixel(windows->image.ximage,x,y);
13565 if (pixel != background)
13568 if (x < windows->image.ximage->width)
13571 trim_info.height=(size_t) (y-trim_info.y+1);
13572 if (((
unsigned int) trim_info.width != windows->image.width) ||
13573 ((
unsigned int) trim_info.height != windows->image.height))
13578 XSetCropGeometry(display,windows,&trim_info,image);
13579 windows->image.window_changes.width=(int) trim_info.width;
13580 windows->image.window_changes.height=(int) trim_info.height;
13581 (void) XConfigureImage(display,resource_info,windows,image,exception);
13583 XSetCursorState(display,windows,MagickFalse);
13584 return(MagickTrue);
13618static Image *XVisualDirectoryImage(Display *display,
13619 XResourceInfo *resource_info,XWindows *windows,
ExceptionInfo *exception)
13621#define TileImageTag "Scale/Image"
13622#define XClientName "montage"
13655 filename[MagickPathExtent] =
"\0",
13656 filenames[MagickPathExtent] =
"*";
13659 background_resources;
13664 XFileBrowserWidget(display,windows,
"Directory",filenames);
13665 if (*filenames ==
'\0')
13666 return((
Image *) NULL);
13670 filelist=(
char **) AcquireMagickMemory(
sizeof(*filelist));
13671 if (filelist == (
char **) NULL)
13673 ThrowXWindowException(ResourceLimitError,
"MemoryAllocationFailed",
13675 return((
Image *) NULL);
13678 filelist[0]=filenames;
13679 status=ExpandFilenames(&number_files,&filelist);
13680 if ((status == MagickFalse) || (number_files == 0))
13682 if (number_files == 0)
13683 ThrowXWindowException(ImageError,
"NoImagesWereFound",filenames)
13685 ThrowXWindowException(ResourceLimitError,
"MemoryAllocationFailed",
13687 return((
Image *) NULL);
13692 background_resources=(*resource_info);
13693 background_resources.window_id=AcquireString(
"");
13694 (void) FormatLocaleString(background_resources.window_id,MagickPathExtent,
13695 "0x%lx",windows->image.id);
13696 background_resources.backdrop=MagickTrue;
13700 backdrop=((windows->visual_info->klass == TrueColor) ||
13701 (windows->visual_info->klass == DirectColor)) ? MagickTrue : MagickFalse;
13702 read_info=CloneImageInfo(resource_info->image_info);
13703 (void) SetImageOption(read_info,
"jpeg:size",
"120x120");
13704 (void) CloneString(&read_info->size,DefaultTileGeometry);
13705 (void) SetImageInfoProgressMonitor(read_info,(MagickProgressMonitor) NULL,
13707 images=NewImageList();
13708 XSetCursorState(display,windows,MagickTrue);
13709 XCheckRefreshWindows(display,windows);
13710 for (i=0; i < (int) number_files; i++)
13712 (void) CopyMagickString(read_info->filename,filelist[i],MagickPathExtent);
13713 filelist[i]=DestroyString(filelist[i]);
13714 *read_info->magick=
'\0';
13715 next_image=ReadImage(read_info,exception);
13716 CatchException(exception);
13717 if (next_image != (
Image *) NULL)
13719 (void) DeleteImageProperty(next_image,
"label");
13720 (void) SetImageProperty(next_image,
"label",InterpretImageProperties(
13721 read_info,next_image,DefaultTileLabel,exception),exception);
13722 (void) ParseRegionGeometry(next_image,read_info->size,&geometry,
13724 thumbnail_image=ThumbnailImage(next_image,geometry.width,
13725 geometry.height,exception);
13726 if (thumbnail_image != (
Image *) NULL)
13728 next_image=DestroyImage(next_image);
13729 next_image=thumbnail_image;
13733 (void) XDisplayBackgroundImage(display,&background_resources,
13734 next_image,exception);
13735 XSetCursorState(display,windows,MagickTrue);
13737 AppendImageToList(&images,next_image);
13738 if (images->progress_monitor != (MagickProgressMonitor) NULL)
13743 proceed=SetImageProgress(images,LoadImageTag,(MagickOffsetType) i,
13744 (MagickSizeType) number_files);
13745 if (proceed == MagickFalse)
13750 filelist=(
char **) RelinquishMagickMemory(filelist);
13751 if (images == (
Image *) NULL)
13753 read_info=DestroyImageInfo(read_info);
13754 XSetCursorState(display,windows,MagickFalse);
13755 ThrowXWindowException(ImageError,
"NoImagesWereLoaded",filenames);
13756 return((
Image *) NULL);
13761 montage_info=CloneMontageInfo(read_info,(
MontageInfo *) NULL);
13762 montage_info->pointsize=10;
13763 if (resource_info->font != (
char *) NULL)
13764 (void) CloneString(&montage_info->font,resource_info->font);
13765 (void) CopyMagickString(montage_info->filename,filename,MagickPathExtent);
13766 montage_image=MontageImageList(read_info,montage_info,GetFirstImageInList(
13767 images),exception);
13768 images=DestroyImageList(images);
13769 montage_info=DestroyMontageInfo(montage_info);
13770 read_info=DestroyImageInfo(read_info);
13771 XSetCursorState(display,windows,MagickFalse);
13772 if (montage_image == (
Image *) NULL)
13773 return(montage_image);
13774 XClientMessage(display,windows->image.id,windows->im_protocols,
13775 windows->im_next_image,CurrentTime);
13776 return(montage_image);
13809MagickExport MagickBooleanType XDisplayBackgroundImage(Display *display,
13813 geometry[MagickPathExtent],
13814 visual_type[MagickPathExtent];
13827 static XStandardColormap
13831 *visual_info = (XVisualInfo *) NULL;
13854 assert(image != (
Image *) NULL);
13855 assert(image->signature == MagickCoreSignature);
13856 if (IsEventLogging() != MagickFalse)
13857 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
13858 resources=(*resource_info);
13859 window_info.id=(Window) NULL;
13860 root_window=XRootWindow(display,XDefaultScreen(display));
13861 if (LocaleCompare(resources.window_id,
"root") == 0)
13862 window_info.id=root_window;
13865 if (isdigit((
int) ((
unsigned char) *resources.window_id)) != 0)
13866 window_info.id=XWindowByID(display,root_window,
13867 (Window) strtol((
char *) resources.window_id,(
char **) NULL,0));
13868 if (window_info.id == (Window) NULL)
13869 window_info.id=XWindowByName(display,root_window,resources.window_id);
13871 if (window_info.id == (Window) NULL)
13873 ThrowXWindowException(XServerError,
"NoWindowWithSpecifiedIDExists",
13874 resources.window_id);
13875 return(MagickFalse);
13880 window_attributes.width=XDisplayWidth(display,XDefaultScreen(display));
13881 window_attributes.height=XDisplayHeight(display,XDefaultScreen(display));
13882 (void) CopyMagickString(visual_type,
"default",MagickPathExtent);
13883 status=XGetWindowAttributes(display,window_info.id,&window_attributes);
13885 (void) FormatLocaleString(visual_type,MagickPathExtent,
"0x%lx",
13886 XVisualIDFromVisual(window_attributes.visual));
13887 if (visual_info == (XVisualInfo *) NULL)
13892 map_info=XAllocStandardColormap();
13893 if (map_info == (XStandardColormap *) NULL)
13894 ThrowXWindowFatalException(XServerFatalError,
"MemoryAllocationFailed",
13896 map_info->colormap=(Colormap) NULL;
13897 pixel.pixels=(
unsigned long *) NULL;
13901 resources.map_type=(
char *) NULL;
13902 resources.visual_type=visual_type;
13903 visual_info=XBestVisualInfo(display,map_info,&resources);
13904 if (visual_info == (XVisualInfo *) NULL)
13905 ThrowXWindowFatalException(XServerFatalError,
"UnableToGetVisual",
13906 resources.visual_type);
13910 window_info.ximage=(XImage *) NULL;
13911 window_info.matte_image=(XImage *) NULL;
13912 window_info.pixmap=(Pixmap) NULL;
13913 window_info.matte_pixmap=(Pixmap) NULL;
13918 if (window_info.id == root_window)
13919 (void) XDestroyWindowColors(display,root_window);
13923 resources.colormap=SharedColormap;
13924 XMakeStandardColormap(display,visual_info,&resources,image,map_info,&pixel,
13929 context_values.background=pixel.foreground_color.pixel;
13930 context_values.foreground=pixel.background_color.pixel;
13931 pixel.annotate_context=XCreateGC(display,window_info.id,
13932 (
size_t) (GCBackground | GCForeground),&context_values);
13933 if (pixel.annotate_context == (GC) NULL)
13934 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
13939 window_info.name=AcquireString(
"\0");
13940 window_info.icon_name=AcquireString(
"\0");
13941 XGetWindowInfo(display,visual_info,map_info,&pixel,(XFontStruct *) NULL,
13942 &resources,&window_info);
13946 window_info.width=(
unsigned int) image->columns;
13947 window_info.height=(
unsigned int) image->rows;
13948 if ((image->columns != window_info.width) ||
13949 (image->rows != window_info.height))
13950 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
13952 (void) FormatLocaleString(geometry,MagickPathExtent,
"%ux%u+0+0>",
13953 window_attributes.width,window_attributes.height);
13954 geometry_info.width=window_info.width;
13955 geometry_info.height=window_info.height;
13956 geometry_info.x=(ssize_t) window_info.x;
13957 geometry_info.y=(ssize_t) window_info.y;
13958 (void) ParseMetaGeometry(geometry,&geometry_info.x,&geometry_info.y,
13959 &geometry_info.width,&geometry_info.height);
13960 window_info.width=(
unsigned int) geometry_info.width;
13961 window_info.height=(
unsigned int) geometry_info.height;
13962 window_info.x=(int) geometry_info.x;
13963 window_info.y=(int) geometry_info.y;
13964 status=XMakeImage(display,&resources,&window_info,image,window_info.width,
13965 window_info.height,exception) == MagickFalse ? 0 : 1;
13966 if (status == MagickFalse)
13967 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
13971 if (resource_info->debug != MagickFalse)
13973 (void) LogMagickEvent(X11Event,GetMagickModule(),
13974 "Image: %s[%.20g] %.20gx%.20g ",image->filename,(
double) image->scene,
13975 (
double) image->columns,(
double) image->rows);
13976 if (image->colors != 0)
13977 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%.20gc ",(
double)
13979 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%s",image->magick);
13984 width=(int) window_info.width;
13985 height=(int) window_info.height;
13986 if (resources.backdrop != MagickFalse)
13991 window_info.x=(window_attributes.width/2)-(window_info.ximage->width/2);
13992 window_info.y=(window_attributes.height/2)-(window_info.ximage->height/2);
13993 width=window_attributes.width;
13994 height=window_attributes.height;
13996 if ((resources.image_geometry != (
char *) NULL) &&
13997 (*resources.image_geometry !=
'\0'))
14000 default_geometry[MagickPathExtent];
14012 size_hints=XAllocSizeHints();
14013 if (size_hints == (XSizeHints *) NULL)
14014 ThrowXWindowFatalException(ResourceLimitFatalError,
14015 "MemoryAllocationFailed",image->filename);
14016 size_hints->flags=0L;
14017 (void) FormatLocaleString(default_geometry,MagickPathExtent,
"%dx%d",
14019 flags=XWMGeometry(display,visual_info->screen,resources.image_geometry,
14020 default_geometry,window_info.border_width,size_hints,&window_info.x,
14021 &window_info.y,&width,&height,&gravity);
14022 if (flags & (XValue | YValue))
14024 width=window_attributes.width;
14025 height=window_attributes.height;
14027 (void) XFree((
void *) size_hints);
14032 window_info.pixmap=XCreatePixmap(display,window_info.id,(
unsigned int) width,
14033 (
unsigned int) height,window_info.depth);
14034 if (window_info.pixmap == (Pixmap) NULL)
14035 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXPixmap",
14040 if (((
unsigned int) width > window_info.width) ||
14041 ((
unsigned int) height > window_info.height))
14042 (void) XFillRectangle(display,window_info.pixmap,
14043 window_info.annotate_context,0,0,(
unsigned int) width,
14044 (
unsigned int) height);
14045 (void) XPutImage(display,window_info.pixmap,window_info.annotate_context,
14046 window_info.ximage,0,0,window_info.x,window_info.y,(
unsigned int)
14047 window_info.width,(
unsigned int) window_info.height);
14048 (void) XSetWindowBackgroundPixmap(display,window_info.id,window_info.pixmap);
14049 (void) XClearWindow(display,window_info.id);
14050 delay=1000*image->delay/(size_t) MagickMax(image->ticks_per_second,1L);
14051 XDelay(display,delay == 0UL ? 10UL : delay);
14052 (void) XSync(display,MagickFalse);
14053 return(window_info.id == root_window ? MagickTrue : MagickFalse);
14096MagickExport
Image *XDisplayImage(Display *display,XResourceInfo *resource_info,
14099#define MagnifySize 256
14100#define MagickMenus 10
14101#define MagickTitle "Commands"
14104 *
const CommandMenu[] =
14118 *
const FileMenu[] =
14128 "Visual Directory...",
14132 *
const EditMenu[] =
14141 *
const ViewMenu[] =
14152 *
const TransformMenu[] =
14166 *
const EnhanceMenu[] =
14174 "Contrast Stretch...",
14175 "Sigmoidal Contrast...",
14184 *
const EffectsMenu[] =
14209 "Charcoal Draw...",
14212 *
const ImageEditMenu[] =
14223 "Region of Interest...",
14226 *
const MiscellanyMenu[] =
14238 *
const HelpMenu[] =
14241 "Browse Documentation",
14245 *
const ShortCutsMenu[] =
14258 *
const VirtualMenu[] =
14268 *
const *Menus[MagickMenus] =
14282 static DisplayCommand
14306 VisualDirectoryCommand,
14320 OriginalSizeCommand,
14327 TransformCommands[] =
14333 RotateRightCommand,
14340 EnhanceCommands[] =
14348 ContrastStretchCommand,
14349 SigmoidalContrastCommand,
14357 EffectsCommands[] =
14361 ReduceNoiseCommand,
14381 CharcoalDrawCommand
14383 ImageEditCommands[] =
14394 RegionOfInterestCommand
14396 MiscellanyCommands[] =
14400 ShowPreviewCommand,
14401 ShowHistogramCommand,
14410 BrowseDocumentationCommand,
14413 ShortCutsCommands[] =
14425 VirtualCommands[] =
14433 static DisplayCommand
14434 *Commands[MagickMenus] =
14444 MiscellanyCommands,
14449 command[MagickPathExtent],
14451 geometry[MagickPathExtent],
14452 resource_name[MagickPathExtent];
14479 working_directory[MagickPathExtent];
14485 *magick_windows[MaxXWindows];
14487 static unsigned int
14547 assert(image != (
Image **) NULL);
14548 assert((*image)->signature == MagickCoreSignature);
14549 if (IsEventLogging() != MagickFalse)
14550 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",(*image)->filename);
14551 display_image=(*image);
14552 warning_handler=(WarningHandler) NULL;
14553 windows=XSetWindows((XWindows *) ~0);
14554 if (windows != (XWindows *) NULL)
14559 if (*working_directory ==
'\0')
14560 (void) CopyMagickString(working_directory,
".",MagickPathExtent);
14561 status=chdir(working_directory);
14563 (void) ThrowMagickException(exception,GetMagickModule(),FileOpenError,
14564 "UnableToOpenFile",
"%s",working_directory);
14565 warning_handler=resource_info->display_warnings ?
14566 SetErrorHandler(XWarning) : SetErrorHandler((ErrorHandler) NULL);
14567 warning_handler=resource_info->display_warnings ?
14568 SetWarningHandler(XWarning) : SetWarningHandler((WarningHandler) NULL);
14575 resource_info->colors=display_image->colors;
14576 windows=XSetWindows(XInitializeWindows(display,resource_info));
14577 if (windows == (XWindows *) NULL)
14578 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateWindow",
14579 (*image)->filename);
14584 magick_windows[number_windows++]=(&windows->icon);
14585 magick_windows[number_windows++]=(&windows->backdrop);
14586 magick_windows[number_windows++]=(&windows->image);
14587 magick_windows[number_windows++]=(&windows->info);
14588 magick_windows[number_windows++]=(&windows->command);
14589 magick_windows[number_windows++]=(&windows->widget);
14590 magick_windows[number_windows++]=(&windows->popup);
14591 magick_windows[number_windows++]=(&windows->magnify);
14592 magick_windows[number_windows++]=(&windows->pan);
14593 for (i=0; i < (int) number_windows; i++)
14594 magick_windows[i]->
id=(Window) NULL;
14601 if (windows->font_info != (XFontStruct *) NULL)
14602 (void) XFreeFont(display,windows->font_info);
14603 windows->font_info=XBestFont(display,resource_info,MagickFalse);
14604 if (windows->font_info == (XFontStruct *) NULL)
14605 ThrowXWindowFatalException(XServerFatalError,
"UnableToLoadFont",
14606 resource_info->font);
14610 map_info=windows->map_info;
14611 icon_map=windows->icon_map;
14612 visual_info=windows->visual_info;
14613 icon_visual=windows->icon_visual;
14614 pixel=windows->pixel_info;
14615 icon_pixel=windows->icon_pixel;
14616 font_info=windows->font_info;
14617 icon_resources=windows->icon_resources;
14618 class_hints=windows->class_hints;
14619 manager_hints=windows->manager_hints;
14620 root_window=XRootWindow(display,visual_info->screen);
14621 nexus=NewImageList();
14622 if (resource_info->debug != MagickFalse)
14624 (void) LogMagickEvent(X11Event,GetMagickModule(),
14625 "Image: %s[%.20g] %.20gx%.20g ",display_image->filename,
14626 (
double) display_image->scene,(
double) display_image->columns,
14627 (
double) display_image->rows);
14628 if (display_image->colors != 0)
14629 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%.20gc ",(
double)
14630 display_image->colors);
14631 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%s",
14632 display_image->magick);
14634 XMakeStandardColormap(display,visual_info,resource_info,display_image,
14635 map_info,pixel,exception);
14636 display_image->taint=MagickFalse;
14640 windows->context.id=(Window) NULL;
14641 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14642 resource_info,&windows->context);
14643 (void) CloneString(&class_hints->res_name,resource_info->client_name);
14644 (void) CloneString(&class_hints->res_class,resource_info->client_name);
14645 class_hints->res_class[0]=(char) LocaleToUppercase((
int)
14646 class_hints->res_class[0]);
14647 manager_hints->flags=InputHint | StateHint;
14648 manager_hints->input=MagickFalse;
14649 manager_hints->initial_state=WithdrawnState;
14650 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14651 &windows->context);
14652 if (resource_info->debug != MagickFalse)
14653 (void) LogMagickEvent(X11Event,GetMagickModule(),
14654 "Window id: 0x%lx (context)",windows->context.id);
14655 context_values.background=pixel->background_color.pixel;
14656 context_values.font=font_info->fid;
14657 context_values.foreground=pixel->foreground_color.pixel;
14658 context_values.graphics_exposures=MagickFalse;
14659 context_mask=(MagickStatusType)
14660 (GCBackground | GCFont | GCForeground | GCGraphicsExposures);
14661 if (pixel->annotate_context != (GC) NULL)
14662 (void) XFreeGC(display,pixel->annotate_context);
14663 pixel->annotate_context=XCreateGC(display,windows->context.id,
14664 context_mask,&context_values);
14665 if (pixel->annotate_context == (GC) NULL)
14666 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14667 display_image->filename);
14668 context_values.background=pixel->depth_color.pixel;
14669 if (pixel->widget_context != (GC) NULL)
14670 (void) XFreeGC(display,pixel->widget_context);
14671 pixel->widget_context=XCreateGC(display,windows->context.id,context_mask,
14673 if (pixel->widget_context == (GC) NULL)
14674 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14675 display_image->filename);
14676 context_values.background=pixel->foreground_color.pixel;
14677 context_values.foreground=pixel->background_color.pixel;
14678 context_values.plane_mask=context_values.background ^
14679 context_values.foreground;
14680 if (pixel->highlight_context != (GC) NULL)
14681 (void) XFreeGC(display,pixel->highlight_context);
14682 pixel->highlight_context=XCreateGC(display,windows->context.id,
14683 (
size_t) (context_mask | GCPlaneMask),&context_values);
14684 if (pixel->highlight_context == (GC) NULL)
14685 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14686 display_image->filename);
14687 (void) XDestroyWindow(display,windows->context.id);
14691 XGetWindowInfo(display,icon_visual,icon_map,icon_pixel,(XFontStruct *) NULL,
14692 icon_resources,&windows->icon);
14693 windows->icon.geometry=resource_info->icon_geometry;
14694 XBestIconSize(display,&windows->icon,display_image);
14695 windows->icon.attributes.colormap=XDefaultColormap(display,
14696 icon_visual->screen);
14697 windows->icon.attributes.event_mask=ExposureMask | StructureNotifyMask;
14698 manager_hints->flags=InputHint | StateHint;
14699 manager_hints->input=MagickFalse;
14700 manager_hints->initial_state=IconicState;
14701 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14703 if (resource_info->debug != MagickFalse)
14704 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (icon)",
14709 if (icon_pixel->annotate_context != (GC) NULL)
14710 (void) XFreeGC(display,icon_pixel->annotate_context);
14711 context_values.background=icon_pixel->background_color.pixel;
14712 context_values.foreground=icon_pixel->foreground_color.pixel;
14713 icon_pixel->annotate_context=XCreateGC(display,windows->icon.id,
14714 (
size_t) (GCBackground | GCForeground),&context_values);
14715 if (icon_pixel->annotate_context == (GC) NULL)
14716 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14717 display_image->filename);
14718 windows->icon.annotate_context=icon_pixel->annotate_context;
14722 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,resource_info,
14724 windows->image.shape=MagickTrue;
14725 if (resource_info->use_shared_memory == MagickFalse)
14726 windows->image.shared_memory=MagickFalse;
14727 if ((resource_info->title != (
char *) NULL) && !(*state & MontageImageState))
14732 title=InterpretImageProperties(resource_info->image_info,display_image,
14733 resource_info->title,exception);
14734 (void) CloneString(&windows->image.name,title);
14735 (void) CloneString(&windows->image.icon_name,title);
14736 title=DestroyString(title);
14741 filename[MagickPathExtent],
14742 window_name[MagickPathExtent];
14747 GetPathComponent(display_image->magick_filename,TailPath,filename);
14748 if (display_image->scene == 0)
14749 (void) FormatLocaleString(window_name,MagickPathExtent,
"%s: %s",
14750 MagickPackageName,filename);
14752 (
void) FormatLocaleString(window_name,MagickPathExtent,
14753 "%s: %s[scene: %.20g frames: %.20g]",MagickPackageName,filename,
14754 (
double) display_image->scene,(
double) GetImageListLength(
14756 (void) CloneString(&windows->image.name,window_name);
14757 (void) CloneString(&windows->image.icon_name,filename);
14759 if (resource_info->immutable)
14760 windows->image.immutable=MagickTrue;
14761 windows->image.use_pixmap=resource_info->use_pixmap;
14762 windows->image.geometry=resource_info->image_geometry;
14763 (void) FormatLocaleString(geometry,MagickPathExtent,
"%ux%u+0+0>!",
14764 XDisplayWidth(display,visual_info->screen),
14765 XDisplayHeight(display,visual_info->screen));
14766 geometry_info.width=display_image->columns;
14767 geometry_info.height=display_image->rows;
14770 (void) ParseMetaGeometry(geometry,&geometry_info.x,&geometry_info.y,
14771 &geometry_info.width,&geometry_info.height);
14772 windows->image.width=(
unsigned int) geometry_info.width;
14773 windows->image.height=(
unsigned int) geometry_info.height;
14774 windows->image.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14775 ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
14776 KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask |
14777 PropertyChangeMask | StructureNotifyMask | SubstructureNotifyMask;
14778 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14779 resource_info,&windows->backdrop);
14780 if ((resource_info->backdrop) || (windows->backdrop.id != (Window) NULL))
14785 windows->backdrop.x=0;
14786 windows->backdrop.y=0;
14787 (void) CloneString(&windows->backdrop.name,
"Backdrop");
14788 windows->backdrop.flags=(size_t) (USSize | USPosition);
14789 windows->backdrop.width=(
unsigned int)
14790 XDisplayWidth(display,visual_info->screen);
14791 windows->backdrop.height=(
unsigned int)
14792 XDisplayHeight(display,visual_info->screen);
14793 windows->backdrop.border_width=0;
14794 windows->backdrop.immutable=MagickTrue;
14795 windows->backdrop.attributes.do_not_propagate_mask=ButtonPressMask |
14797 windows->backdrop.attributes.event_mask=ButtonPressMask | KeyPressMask |
14798 StructureNotifyMask;
14799 manager_hints->flags=IconWindowHint | InputHint | StateHint;
14800 manager_hints->icon_window=windows->icon.id;
14801 manager_hints->input=MagickTrue;
14802 manager_hints->initial_state=resource_info->iconic ? IconicState :
14804 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14805 &windows->backdrop);
14806 if (resource_info->debug != MagickFalse)
14807 (void) LogMagickEvent(X11Event,GetMagickModule(),
14808 "Window id: 0x%lx (backdrop)",windows->backdrop.id);
14809 (void) XMapWindow(display,windows->backdrop.id);
14810 (void) XClearWindow(display,windows->backdrop.id);
14811 if (windows->image.id != (Window) NULL)
14813 (void) XDestroyWindow(display,windows->image.id);
14814 windows->image.id=(Window) NULL;
14819 windows->image.flags|=USPosition;
14820 windows->image.x=(XDisplayWidth(display,visual_info->screen)/2)-
14821 ((
int) windows->image.width/2);
14822 windows->image.y=(XDisplayHeight(display,visual_info->screen)/2)-
14823 ((
int) windows->image.height/2);
14825 manager_hints->flags=IconWindowHint | InputHint | StateHint;
14826 manager_hints->icon_window=windows->icon.id;
14827 manager_hints->input=MagickTrue;
14828 manager_hints->initial_state=resource_info->iconic ? IconicState :
14830 if (windows->group_leader.id != (Window) NULL)
14835 manager_hints->flags|=WindowGroupHint;
14836 manager_hints->window_group=windows->group_leader.id;
14837 (void) XSelectInput(display,windows->group_leader.id,StructureNotifyMask);
14838 if (resource_info->debug != MagickFalse)
14839 (void) LogMagickEvent(X11Event,GetMagickModule(),
14840 "Window id: 0x%lx (group leader)",windows->group_leader.id);
14842 XMakeWindow(display,
14843 (Window) (resource_info->backdrop ? windows->backdrop.id : root_window),
14844 argv,argc,class_hints,manager_hints,&windows->image);
14845 (void) XChangeProperty(display,windows->image.id,windows->im_protocols,
14846 XA_STRING,8,PropModeReplace,(
unsigned char *) NULL,0);
14847 if (windows->group_leader.id != (Window) NULL)
14848 (void) XSetTransientForHint(display,windows->image.id,
14849 windows->group_leader.id);
14850 if (resource_info->debug != MagickFalse)
14851 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (image)",
14852 windows->image.id);
14856 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,resource_info,
14858 (void) CloneString(&windows->info.name,
"Info");
14859 (void) CloneString(&windows->info.icon_name,
"Info");
14860 windows->info.border_width=1;
14863 windows->info.flags|=PPosition;
14864 windows->info.attributes.win_gravity=UnmapGravity;
14865 windows->info.attributes.event_mask=ButtonPressMask | ExposureMask |
14866 StructureNotifyMask;
14867 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14868 manager_hints->input=MagickFalse;
14869 manager_hints->initial_state=NormalState;
14870 manager_hints->window_group=windows->image.id;
14871 XMakeWindow(display,windows->image.id,argv,argc,class_hints,manager_hints,
14873 windows->info.highlight_stipple=XCreateBitmapFromData(display,
14874 windows->info.id,(
char *) HighlightBitmap,HighlightWidth,HighlightHeight);
14875 windows->info.shadow_stipple=XCreateBitmapFromData(display,
14876 windows->info.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14877 (void) XSetTransientForHint(display,windows->info.id,windows->image.id);
14878 if (windows->image.mapped != MagickFalse)
14879 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
14880 if (resource_info->debug != MagickFalse)
14881 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (info)",
14886 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14887 resource_info,&windows->command);
14888 windows->command.data=MagickMenus;
14889 (void) XCommandWidget(display,windows,CommandMenu,(XEvent *) NULL);
14890 (void) FormatLocaleString(resource_name,MagickPathExtent,
"%s.command",
14891 resource_info->client_name);
14892 windows->command.geometry=XGetResourceClass(resource_info->resource_database,
14893 resource_name,
"geometry",(
char *) NULL);
14894 (void) CloneString(&windows->command.name,MagickTitle);
14895 windows->command.border_width=0;
14896 windows->command.flags|=PPosition;
14897 windows->command.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14898 ButtonReleaseMask | EnterWindowMask | ExposureMask | LeaveWindowMask |
14899 OwnerGrabButtonMask | StructureNotifyMask;
14900 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14901 manager_hints->input=MagickTrue;
14902 manager_hints->initial_state=NormalState;
14903 manager_hints->window_group=windows->image.id;
14904 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14905 &windows->command);
14906 windows->command.highlight_stipple=XCreateBitmapFromData(display,
14907 windows->command.id,(
char *) HighlightBitmap,HighlightWidth,
14909 windows->command.shadow_stipple=XCreateBitmapFromData(display,
14910 windows->command.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14911 (void) XSetTransientForHint(display,windows->command.id,windows->image.id);
14912 if (windows->command.mapped != MagickFalse)
14913 (void) XMapRaised(display,windows->command.id);
14914 if (resource_info->debug != MagickFalse)
14915 (void) LogMagickEvent(X11Event,GetMagickModule(),
14916 "Window id: 0x%lx (command)",windows->command.id);
14920 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14921 resource_info,&windows->widget);
14922 (void) FormatLocaleString(resource_name,MagickPathExtent,
"%s.widget",
14923 resource_info->client_name);
14924 windows->widget.geometry=XGetResourceClass(resource_info->resource_database,
14925 resource_name,
"geometry",(
char *) NULL);
14926 windows->widget.border_width=0;
14927 windows->widget.flags|=PPosition;
14928 windows->widget.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14929 ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
14930 KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask |
14931 StructureNotifyMask;
14932 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14933 manager_hints->input=MagickTrue;
14934 manager_hints->initial_state=NormalState;
14935 manager_hints->window_group=windows->image.id;
14936 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14938 windows->widget.highlight_stipple=XCreateBitmapFromData(display,
14939 windows->widget.id,(
char *) HighlightBitmap,HighlightWidth,HighlightHeight);
14940 windows->widget.shadow_stipple=XCreateBitmapFromData(display,
14941 windows->widget.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14942 (void) XSetTransientForHint(display,windows->widget.id,windows->image.id);
14943 if (resource_info->debug != MagickFalse)
14944 (void) LogMagickEvent(X11Event,GetMagickModule(),
14945 "Window id: 0x%lx (widget)",windows->widget.id);
14949 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14950 resource_info,&windows->popup);
14951 windows->popup.border_width=0;
14952 windows->popup.flags|=PPosition;
14953 windows->popup.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14954 ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
14955 KeyReleaseMask | LeaveWindowMask | StructureNotifyMask;
14956 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14957 manager_hints->input=MagickTrue;
14958 manager_hints->initial_state=NormalState;
14959 manager_hints->window_group=windows->image.id;
14960 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14962 windows->popup.highlight_stipple=XCreateBitmapFromData(display,
14963 windows->popup.id,(
char *) HighlightBitmap,HighlightWidth,HighlightHeight);
14964 windows->popup.shadow_stipple=XCreateBitmapFromData(display,
14965 windows->popup.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14966 (void) XSetTransientForHint(display,windows->popup.id,windows->image.id);
14967 if (resource_info->debug != MagickFalse)
14968 (void) LogMagickEvent(X11Event,GetMagickModule(),
14969 "Window id: 0x%lx (pop up)",windows->popup.id);
14973 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14974 resource_info,&windows->magnify);
14975 if (resource_info->use_shared_memory == MagickFalse)
14976 windows->magnify.shared_memory=MagickFalse;
14977 (void) FormatLocaleString(resource_name,MagickPathExtent,
"%s.magnify",
14978 resource_info->client_name);
14979 windows->magnify.geometry=XGetResourceClass(resource_info->resource_database,
14980 resource_name,
"geometry",(
char *) NULL);
14981 (void) FormatLocaleString(windows->magnify.name,MagickPathExtent,
14982 "Magnify %uX",resource_info->magnify);
14983 if (windows->magnify.cursor != (Cursor) NULL)
14984 (void) XFreeCursor(display,windows->magnify.cursor);
14985 windows->magnify.cursor=XMakeCursor(display,windows->image.id,
14986 map_info->colormap,resource_info->background_color,
14987 resource_info->foreground_color);
14988 if (windows->magnify.cursor == (Cursor) NULL)
14989 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateCursor",
14990 display_image->filename);
14991 windows->magnify.width=MagnifySize;
14992 windows->magnify.height=MagnifySize;
14993 windows->magnify.flags|=PPosition;
14994 windows->magnify.min_width=MagnifySize;
14995 windows->magnify.min_height=MagnifySize;
14996 windows->magnify.width_inc=MagnifySize;
14997 windows->magnify.height_inc=MagnifySize;
14998 windows->magnify.data=resource_info->magnify;
14999 windows->magnify.attributes.cursor=windows->magnify.cursor;
15000 windows->magnify.attributes.event_mask=ButtonPressMask | ButtonReleaseMask |
15001 ExposureMask | KeyPressMask | KeyReleaseMask | OwnerGrabButtonMask |
15002 StructureNotifyMask;
15003 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
15004 manager_hints->input=MagickTrue;
15005 manager_hints->initial_state=NormalState;
15006 manager_hints->window_group=windows->image.id;
15007 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
15008 &windows->magnify);
15009 if (resource_info->debug != MagickFalse)
15010 (void) LogMagickEvent(X11Event,GetMagickModule(),
15011 "Window id: 0x%lx (magnify)",windows->magnify.id);
15012 (void) XSetTransientForHint(display,windows->magnify.id,windows->image.id);
15016 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
15017 resource_info,&windows->pan);
15018 (void) CloneString(&windows->pan.name,
"Pan Icon");
15019 windows->pan.width=windows->icon.width;
15020 windows->pan.height=windows->icon.height;
15021 (void) FormatLocaleString(resource_name,MagickPathExtent,
"%s.pan",
15022 resource_info->client_name);
15023 windows->pan.geometry=XGetResourceClass(resource_info->resource_database,
15024 resource_name,
"geometry",(
char *) NULL);
15025 (void) XParseGeometry(windows->pan.geometry,&windows->pan.x,&windows->pan.y,
15026 &windows->pan.width,&windows->pan.height);
15027 windows->pan.flags|=PPosition;
15028 windows->pan.immutable=MagickTrue;
15029 windows->pan.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
15030 ButtonReleaseMask | ExposureMask | KeyPressMask | KeyReleaseMask |
15031 StructureNotifyMask;
15032 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
15033 manager_hints->input=MagickFalse;
15034 manager_hints->initial_state=NormalState;
15035 manager_hints->window_group=windows->image.id;
15036 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
15038 if (resource_info->debug != MagickFalse)
15039 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (pan)",
15041 (void) XSetTransientForHint(display,windows->pan.id,windows->image.id);
15042 if (windows->info.mapped != MagickFalse)
15043 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
15044 if ((windows->image.mapped == MagickFalse) ||
15045 (windows->backdrop.id != (Window) NULL))
15046 (void) XMapWindow(display,windows->image.id);
15050 if (warning_handler == (WarningHandler) NULL)
15052 warning_handler=resource_info->display_warnings ?
15053 SetErrorHandler(XWarning) : SetErrorHandler((ErrorHandler) NULL);
15054 warning_handler=resource_info->display_warnings ?
15055 SetWarningHandler(XWarning) : SetWarningHandler((WarningHandler) NULL);
15060 windows->image.x=0;
15061 windows->image.y=0;
15062 windows->magnify.shape=MagickFalse;
15063 width=(
unsigned int) display_image->columns;
15064 height=(
unsigned int) display_image->rows;
15065 if ((display_image->columns != width) || (display_image->rows != height))
15066 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
15067 display_image->filename);
15068 status=XMakeImage(display,resource_info,&windows->image,display_image,
15069 width,height,exception);
15070 if (status == MagickFalse)
15071 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
15072 display_image->filename);
15073 status=XMakeImage(display,resource_info,&windows->magnify,(
Image *) NULL,
15074 windows->magnify.width,windows->magnify.height,exception);
15075 if (status == MagickFalse)
15076 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
15077 display_image->filename);
15078 if (windows->magnify.mapped != MagickFalse)
15079 (void) XMapRaised(display,windows->magnify.id);
15080 if (windows->pan.mapped != MagickFalse)
15081 (void) XMapRaised(display,windows->pan.id);
15082 windows->image.window_changes.width=(int) display_image->columns;
15083 windows->image.window_changes.height=(int) display_image->rows;
15084 (void) XConfigureImage(display,resource_info,windows,display_image,exception);
15085 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
15086 (void) XSync(display,MagickFalse);
15090 delay=display_image->delay/(size_t)
15091 MagickMax(display_image->ticks_per_second,1L);
15092 timer=GetMagickTime()+(time_t) (delay == 0 ? 1 : delay)+1;
15094 if (resource_info->update != MagickFalse)
15102 status=GetPathAttributes(display_image->filename,&attributes);
15103 if (status != MagickFalse)
15104 update_time=attributes.st_mtime;
15106 *state&=(
unsigned int) (~FormerImageState);
15107 *state&=(
unsigned int) (~MontageImageState);
15108 *state&=(
unsigned int) (~NextImageState);
15114 if (windows->image.mapped != MagickFalse)
15115 if ((display_image->delay != 0) || (resource_info->update != 0))
15117 if (timer < GetMagickTime())
15119 if (resource_info->update == MagickFalse)
15120 *state|=NextImageState | ExitState;
15129 status=GetPathAttributes(display_image->filename,&attributes);
15130 if (status != MagickFalse)
15131 if (update_time != attributes.st_mtime)
15136 (void) FormatLocaleString(
15137 resource_info->image_info->filename,MagickPathExtent,
15138 "%s:%s",display_image->magick,
15139 display_image->filename);
15140 nexus=ReadImage(resource_info->image_info,exception);
15141 if (nexus != (
Image *) NULL)
15142 *state|=NextImageState | ExitState;
15144 delay=display_image->delay/(size_t) MagickMax(
15145 display_image->ticks_per_second,1L);
15146 timer=GetMagickTime()+(time_t) (delay == 0 ? 1 : delay)+1;
15149 if (XEventsQueued(display,QueuedAfterFlush) == 0)
15154 XDelay(display,SuspendTime << 2);
15158 timestamp=GetMagickTime();
15159 (void) XNextEvent(display,&event);
15160 if ((windows->image.stasis == MagickFalse) ||
15161 (windows->magnify.stasis == MagickFalse))
15163 if ((GetMagickTime()-timestamp) > 0)
15165 windows->image.stasis=MagickTrue;
15166 windows->magnify.stasis=MagickTrue;
15169 if (event.xany.window == windows->command.id)
15174 id=XCommandWidget(display,windows,CommandMenu,&event);
15177 (void) CopyMagickString(command,CommandMenu[
id],MagickPathExtent);
15178 display_command=CommandMenus[id];
15179 if (
id < MagickMenus)
15184 entry=XMenuWidget(display,windows,CommandMenu[
id],Menus[
id],
15188 (void) CopyMagickString(command,Menus[
id][entry],MagickPathExtent);
15189 display_command=Commands[id][entry];
15191 if (display_command != NullCommand)
15192 nexus=XMagickCommand(display,resource_info,windows,display_command,
15193 &display_image,exception);
15196 switch (event.type)
15200 if (resource_info->debug != MagickFalse)
15201 (void) LogMagickEvent(X11Event,GetMagickModule(),
15202 "Button Press: 0x%lx %u +%d+%d",event.xbutton.window,
15203 event.xbutton.button,event.xbutton.x,event.xbutton.y);
15204 if ((event.xbutton.button == Button3) &&
15205 (event.xbutton.state & Mod1Mask))
15210 event.xbutton.button=Button2;
15211 event.xbutton.state&=(
unsigned int) (~Mod1Mask);
15213 if (event.xbutton.window == windows->backdrop.id)
15215 (void) XSetInputFocus(display,event.xbutton.window,RevertToParent,
15216 event.xbutton.time);
15219 if (event.xbutton.window == windows->image.id)
15221 switch (event.xbutton.button)
15225 if (resource_info->immutable)
15230 entry=XMenuWidget(display,windows,
"Commands",VirtualMenu,
15233 nexus=XMagickCommand(display,resource_info,windows,
15234 VirtualCommands[entry],&display_image,exception);
15240 if (windows->command.mapped != MagickFalse)
15241 (void) XWithdrawWindow(display,windows->command.id,
15242 windows->command.screen);
15245 (void) XCommandWidget(display,windows,CommandMenu,
15247 (void) XMapRaised(display,windows->command.id);
15256 (void) XMagickCommand(display,resource_info,windows,ZoomCommand,
15257 &display_image,exception);
15258 XMagnifyImage(display,windows,&event,exception);
15263 if (resource_info->immutable)
15268 entry=XMenuWidget(display,windows,
"Commands",VirtualMenu,
15271 nexus=XMagickCommand(display,resource_info,windows,
15272 VirtualCommands[entry],&display_image,exception);
15275 if (display_image->montage != (
char *) NULL)
15280 nexus=XTileImage(display,resource_info,windows,
15281 display_image,&event,exception);
15282 if (nexus != (
Image *) NULL)
15283 *state|=MontageImageState | NextImageState | ExitState;
15284 vid_info.x=(
short int) windows->image.x;
15285 vid_info.y=(
short int) windows->image.y;
15291 entry=XMenuWidget(display,windows,
"Short Cuts",ShortCutsMenu,
15294 nexus=XMagickCommand(display,resource_info,windows,
15295 ShortCutsCommands[entry],&display_image,exception);
15303 XTranslateImage(display,windows,*image,XK_Up);
15311 XTranslateImage(display,windows,*image,XK_Down);
15319 if (event.xbutton.window == windows->magnify.id)
15322 *
const MagnifyMenu[] =
15339 MagnifyCommands[] =
15354 factor=XMenuWidget(display,windows,
"Magnify",MagnifyMenu,command);
15356 XMagnifyWindowCommand(display,windows,0,MagnifyCommands[factor],
15360 if (event.xbutton.window == windows->pan.id)
15362 switch (event.xbutton.button)
15369 XTranslateImage(display,windows,*image,XK_Up);
15377 XTranslateImage(display,windows,*image,XK_Down);
15382 XPanImage(display,windows,&event,exception);
15388 delay=display_image->delay/(size_t)
15389 MagickMax(display_image->ticks_per_second,1L);
15390 timer=GetMagickTime()+(time_t) (delay == 0 ? 1 : delay)+1;
15393 case ButtonRelease:
15395 if (resource_info->debug != MagickFalse)
15396 (void) LogMagickEvent(X11Event,GetMagickModule(),
15397 "Button Release: 0x%lx %u +%d+%d",event.xbutton.window,
15398 event.xbutton.button,event.xbutton.x,event.xbutton.y);
15401 case ClientMessage:
15403 if (resource_info->debug != MagickFalse)
15404 (void) LogMagickEvent(X11Event,GetMagickModule(),
15405 "Client Message: 0x%lx 0x%lx %d 0x%lx",event.xclient.window,
15406 event.xclient.message_type,event.xclient.format,(
unsigned long)
15407 event.xclient.data.l[0]);
15408 if (event.xclient.message_type == windows->im_protocols)
15410 if (*event.xclient.data.l == (
long) windows->im_update_widget)
15412 (void) CloneString(&windows->command.name,MagickTitle);
15413 windows->command.data=MagickMenus;
15414 (void) XCommandWidget(display,windows,CommandMenu,
15418 if (*event.xclient.data.l == (
long) windows->im_update_colormap)
15423 for (i=0; i < (int) number_windows; i++)
15425 if (magick_windows[i]->
id == windows->icon.id)
15427 context_values.background=pixel->background_color.pixel;
15428 context_values.foreground=pixel->foreground_color.pixel;
15429 (void) XChangeGC(display,magick_windows[i]->annotate_context,
15430 context_mask,&context_values);
15431 (void) XChangeGC(display,magick_windows[i]->widget_context,
15432 context_mask,&context_values);
15433 context_values.background=pixel->foreground_color.pixel;
15434 context_values.foreground=pixel->background_color.pixel;
15435 context_values.plane_mask=context_values.background ^
15436 context_values.foreground;
15437 (void) XChangeGC(display,magick_windows[i]->highlight_context,
15438 (
size_t) (context_mask | GCPlaneMask),
15440 magick_windows[i]->attributes.background_pixel=
15441 pixel->background_color.pixel;
15442 magick_windows[i]->attributes.border_pixel=
15443 pixel->border_color.pixel;
15444 magick_windows[i]->attributes.colormap=map_info->colormap;
15445 (void) XChangeWindowAttributes(display,magick_windows[i]->
id,
15446 (
unsigned long) magick_windows[i]->mask,
15447 &magick_windows[i]->attributes);
15449 if (windows->pan.mapped != MagickFalse)
15451 (void) XSetWindowBackgroundPixmap(display,windows->pan.id,
15452 windows->pan.pixmap);
15453 (void) XClearWindow(display,windows->pan.id);
15454 XDrawPanRectangle(display,windows);
15456 if (windows->backdrop.id != (Window) NULL)
15457 (void) XInstallColormap(display,map_info->colormap);
15460 if (*event.xclient.data.l == (
long) windows->im_former_image)
15462 *state|=FormerImageState | ExitState;
15465 if (*event.xclient.data.l == (
long) windows->im_next_image)
15467 *state|=NextImageState | ExitState;
15470 if (*event.xclient.data.l == (
long) windows->im_retain_colors)
15472 *state|=RetainColorsState;
15475 if (*event.xclient.data.l == (
long) windows->im_exit)
15482 if (event.xclient.message_type == windows->dnd_protocols)
15502 if ((*event.xclient.data.l != 2) && (*event.xclient.data.l != 128))
15504 selection=XInternAtom(display,
"DndSelection",MagickFalse);
15505 status=XGetWindowProperty(display,root_window,selection,0L,(
long)
15506 MagickPathExtent,MagickFalse,(Atom) AnyPropertyType,&type,&format,
15507 &length,&after,&data);
15508 if ((status != Success) || (length == 0))
15510 if (*event.xclient.data.l == 2)
15515 (void) CopyMagickString(resource_info->image_info->filename,
15516 (
char *) data,MagickPathExtent);
15523 if (strncmp((
char *) data,
"file:", 5) != 0)
15525 (void) XFree((
void *) data);
15528 (void) CopyMagickString(resource_info->image_info->filename,
15529 ((
char *) data)+5,MagickPathExtent);
15531 nexus=ReadImage(resource_info->image_info,exception);
15532 CatchException(exception);
15533 if (nexus != (
Image *) NULL)
15534 *state|=NextImageState | ExitState;
15535 (void) XFree((
void *) data);
15541 if (event.xclient.message_type != windows->wm_protocols)
15543 if (*event.xclient.data.l != (
long) windows->wm_delete_window)
15545 (void) XWithdrawWindow(display,event.xclient.window,
15546 visual_info->screen);
15547 if (event.xclient.window == windows->image.id)
15552 if (event.xclient.window == windows->pan.id)
15557 windows->image.window_changes.width=windows->image.ximage->width;
15558 windows->image.window_changes.height=windows->image.ximage->height;
15559 (void) XConfigureImage(display,resource_info,windows,
15560 display_image,exception);
15564 case ConfigureNotify:
15566 if (resource_info->debug != MagickFalse)
15567 (void) LogMagickEvent(X11Event,GetMagickModule(),
15568 "Configure Notify: 0x%lx %dx%d+%d+%d %d",event.xconfigure.window,
15569 event.xconfigure.width,event.xconfigure.height,event.xconfigure.x,
15570 event.xconfigure.y,event.xconfigure.send_event);
15571 if (event.xconfigure.window == windows->image.id)
15576 if (event.xconfigure.send_event != 0)
15584 if (windows->command.geometry == (
char *) NULL)
15585 if (windows->command.mapped == MagickFalse)
15587 windows->command.x=
event.xconfigure.x-(int)
15588 windows->command.width-25;
15589 windows->command.y=
event.xconfigure.y;
15590 XConstrainWindowPosition(display,&windows->command);
15591 window_changes.x=windows->command.x;
15592 window_changes.y=windows->command.y;
15593 (void) XReconfigureWMWindow(display,windows->command.id,
15594 windows->command.screen,(
unsigned int) (CWX | CWY),
15597 if (windows->widget.geometry == (
char *) NULL)
15598 if (windows->widget.mapped == MagickFalse)
15600 windows->widget.x=
event.xconfigure.x+
15601 event.xconfigure.width/10;
15602 windows->widget.y=
event.xconfigure.y+
15603 event.xconfigure.height/10;
15604 XConstrainWindowPosition(display,&windows->widget);
15605 window_changes.x=windows->widget.x;
15606 window_changes.y=windows->widget.y;
15607 (void) XReconfigureWMWindow(display,windows->widget.id,
15608 windows->widget.screen,(
unsigned int) (CWX | CWY),
15611 if (windows->magnify.geometry == (
char *) NULL)
15612 if (windows->magnify.mapped == MagickFalse)
15614 windows->magnify.x=
event.xconfigure.x+
15615 event.xconfigure.width+25;
15616 windows->magnify.y=
event.xconfigure.y;
15617 XConstrainWindowPosition(display,&windows->magnify);
15618 window_changes.x=windows->magnify.x;
15619 window_changes.y=windows->magnify.y;
15620 (void) XReconfigureWMWindow(display,windows->magnify.id,
15621 windows->magnify.screen,(
unsigned int) (CWX | CWY),
15624 if (windows->pan.geometry == (
char *) NULL)
15625 if (windows->pan.mapped == MagickFalse)
15627 windows->pan.x=
event.xconfigure.x+(int)
15628 event.xconfigure.width+25;
15629 windows->pan.y=
event.xconfigure.y+(int)
15630 windows->magnify.height+50;
15631 XConstrainWindowPosition(display,&windows->pan);
15632 window_changes.x=windows->pan.x;
15633 window_changes.y=windows->pan.y;
15634 (void) XReconfigureWMWindow(display,windows->pan.id,
15635 windows->pan.screen,(
unsigned int) (CWX | CWY),
15639 if ((event.xconfigure.width == (
int) windows->image.width) &&
15640 (event.xconfigure.height == (
int) windows->image.height))
15642 windows->image.width=(
unsigned int) event.xconfigure.width;
15643 windows->image.height=(
unsigned int) event.xconfigure.height;
15644 windows->image.x=0;
15645 windows->image.y=0;
15646 if (display_image->montage != (
char *) NULL)
15648 windows->image.x=vid_info.x;
15649 windows->image.y=vid_info.y;
15651 if (windows->image.mapped != MagickFalse &&
15652 windows->image.stasis != MagickFalse)
15657 windows->image.window_changes.width=
event.xconfigure.width;
15658 windows->image.window_changes.height=
event.xconfigure.height;
15659 (void) XConfigureImage(display,resource_info,windows,
15660 display_image,exception);
15665 if ((event.xconfigure.width < windows->image.ximage->width) ||
15666 (event.xconfigure.height < windows->image.ximage->height))
15668 (void) XMapRaised(display,windows->pan.id);
15669 XDrawPanRectangle(display,windows);
15672 if (windows->pan.mapped != MagickFalse)
15673 (void) XWithdrawWindow(display,windows->pan.id,
15674 windows->pan.screen);
15677 if (event.xconfigure.window == windows->magnify.id)
15685 windows->magnify.width=(
unsigned int) event.xconfigure.width;
15686 windows->magnify.height=(
unsigned int) event.xconfigure.height;
15687 if (windows->magnify.mapped == MagickFalse)
15690 while ((
int) magnify <= event.xconfigure.width)
15692 while ((
int) magnify <= event.xconfigure.height)
15695 if (((
int) magnify != event.xconfigure.width) ||
15696 ((
int) magnify != event.xconfigure.height))
15698 window_changes.width=(int) magnify;
15699 window_changes.height=(int) magnify;
15700 (void) XReconfigureWMWindow(display,windows->magnify.id,
15701 windows->magnify.screen,(
unsigned int) (CWWidth | CWHeight),
15705 if (windows->magnify.mapped != MagickFalse &&
15706 windows->magnify.stasis != MagickFalse)
15708 status=XMakeImage(display,resource_info,&windows->magnify,
15709 display_image,windows->magnify.width,windows->magnify.height,
15711 XMakeMagnifyImage(display,windows,exception);
15715 if (windows->magnify.mapped != MagickFalse &&
15716 (event.xconfigure.window == windows->pan.id))
15721 if (event.xconfigure.send_event != 0)
15723 windows->pan.x=
event.xconfigure.x;
15724 windows->pan.y=
event.xconfigure.y;
15726 windows->pan.width=(
unsigned int) event.xconfigure.width;
15727 windows->pan.height=(
unsigned int) event.xconfigure.height;
15730 if (event.xconfigure.window == windows->icon.id)
15735 windows->icon.width=(
unsigned int) event.xconfigure.width;
15736 windows->icon.height=(
unsigned int) event.xconfigure.height;
15741 case DestroyNotify:
15746 if (resource_info->debug != MagickFalse)
15747 (void) LogMagickEvent(X11Event,GetMagickModule(),
15748 "Destroy Notify: 0x%lx",event.xdestroywindow.window);
15749 if (event.xdestroywindow.window == windows->group_leader.id)
15761 if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
15762 if (event.xcrossing.mode != NotifyUngrab)
15763 XInstallColormap(display,map_info->colormap);
15768 if (resource_info->debug != MagickFalse)
15769 (void) LogMagickEvent(X11Event,GetMagickModule(),
15770 "Expose: 0x%lx %dx%d+%d+%d",event.xexpose.window,
15771 event.xexpose.width,event.xexpose.height,event.xexpose.x,
15776 if ((event.xexpose.window == windows->image.id) &&
15777 windows->image.mapped != MagickFalse)
15779 XRefreshWindow(display,&windows->image,&event);
15780 delay=display_image->delay/(size_t) MagickMax(
15781 display_image->ticks_per_second,1L);
15782 timer=GetMagickTime()+(time_t) (delay == 0 ? 1 : delay)+1;
15785 if ((event.xexpose.window == windows->magnify.id) &&
15786 windows->magnify.mapped != MagickFalse)
15788 XMakeMagnifyImage(display,windows,exception);
15791 if (event.xexpose.window == windows->pan.id)
15793 XDrawPanRectangle(display,windows);
15796 if (event.xexpose.window == windows->icon.id)
15798 XRefreshWindow(display,&windows->icon,&event);
15811 length=XLookupString((XKeyEvent *) &event.xkey,command,(
int)
15812 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
15813 *(command+length)=
'\0';
15814 if (resource_info->debug != MagickFalse)
15815 (void) LogMagickEvent(X11Event,GetMagickModule(),
15816 "Key press: %d 0x%lx (%s)",event.xkey.state,(
unsigned long)
15817 key_symbol,command);
15818 if (event.xkey.window == windows->image.id)
15820 display_command=XImageWindowCommand(display,resource_info,windows,
15821 event.xkey.state,key_symbol,&display_image,exception);
15822 if (display_command != NullCommand)
15823 nexus=XMagickCommand(display,resource_info,windows,
15824 display_command,&display_image,exception);
15826 if (event.xkey.window == windows->magnify.id)
15827 XMagnifyWindowCommand(display,windows,event.xkey.state,key_symbol,
15829 if (event.xkey.window == windows->pan.id)
15831 if ((key_symbol == XK_q) || (key_symbol == XK_Escape))
15832 (void) XWithdrawWindow(display,windows->pan.id,
15833 windows->pan.screen);
15835 if ((key_symbol == XK_F1) || (key_symbol == XK_Help))
15836 XTextViewHelp(display,resource_info,windows,MagickFalse,
15837 "Help Viewer - Image Pan",ImagePanHelp);
15839 XTranslateImage(display,windows,*image,key_symbol);
15841 delay=display_image->delay/(size_t) MagickMax(
15842 display_image->ticks_per_second,1L);
15843 timer=GetMagickTime()+(time_t) (delay == 0 ? 1 : delay)+1;
15851 (void) XLookupString((XKeyEvent *) &event.xkey,command,(
int)
15852 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
15853 if (resource_info->debug != MagickFalse)
15854 (void) LogMagickEvent(X11Event,GetMagickModule(),
15855 "Key release: 0x%lx (%c)",(
unsigned long) key_symbol,*command);
15863 if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
15864 if (event.xcrossing.mode != NotifyUngrab)
15865 XUninstallColormap(display,map_info->colormap);
15870 if (resource_info->debug != MagickFalse)
15871 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Map Notify: 0x%lx",
15872 event.xmap.window);
15873 if (event.xmap.window == windows->backdrop.id)
15875 (void) XSetInputFocus(display,event.xmap.window,RevertToParent,
15877 windows->backdrop.mapped=MagickTrue;
15880 if (event.xmap.window == windows->image.id)
15882 if (windows->backdrop.id != (Window) NULL)
15883 (void) XInstallColormap(display,map_info->colormap);
15884 if (LocaleCompare(display_image->magick,
"LOGO") == 0)
15886 if (LocaleCompare(display_image->filename,
"LOGO") == 0)
15887 nexus=XOpenImage(display,resource_info,windows,MagickFalse);
15889 if (((
int) windows->image.width < windows->image.ximage->width) ||
15890 ((
int) windows->image.height < windows->image.ximage->height))
15891 (void) XMapRaised(display,windows->pan.id);
15892 windows->image.mapped=MagickTrue;
15895 if (event.xmap.window == windows->magnify.id)
15897 XMakeMagnifyImage(display,windows,exception);
15898 windows->magnify.mapped=MagickTrue;
15899 (void) XWithdrawWindow(display,windows->info.id,
15900 windows->info.screen);
15903 if (event.xmap.window == windows->pan.id)
15905 XMakePanImage(display,resource_info,windows,display_image,
15907 windows->pan.mapped=MagickTrue;
15910 if (event.xmap.window == windows->info.id)
15912 windows->info.mapped=MagickTrue;
15915 if (event.xmap.window == windows->icon.id)
15923 taint=display_image->taint;
15924 XMakeStandardColormap(display,icon_visual,icon_resources,
15925 display_image,icon_map,icon_pixel,exception);
15926 (void) XMakeImage(display,icon_resources,&windows->icon,
15927 display_image,windows->icon.width,windows->icon.height,
15929 display_image->taint=taint;
15930 (void) XSetWindowBackgroundPixmap(display,windows->icon.id,
15931 windows->icon.pixmap);
15932 (void) XClearWindow(display,windows->icon.id);
15933 (void) XWithdrawWindow(display,windows->info.id,
15934 windows->info.screen);
15935 windows->icon.mapped=MagickTrue;
15938 if (event.xmap.window == windows->command.id)
15940 windows->command.mapped=MagickTrue;
15943 if (event.xmap.window == windows->popup.id)
15945 windows->popup.mapped=MagickTrue;
15948 if (event.xmap.window == windows->widget.id)
15950 windows->widget.mapped=MagickTrue;
15955 case MappingNotify:
15957 (void) XRefreshKeyboardMapping(&event.xmapping);
15962 case PropertyNotify:
15978 if (resource_info->debug != MagickFalse)
15979 (void) LogMagickEvent(X11Event,GetMagickModule(),
15980 "Property Notify: 0x%lx 0x%lx %d",event.xproperty.window,
15981 event.xproperty.atom,event.xproperty.state);
15982 if (event.xproperty.atom != windows->im_remote_command)
15987 status=XGetWindowProperty(display,event.xproperty.window,
15988 event.xproperty.atom,0L,(
long) MagickPathExtent,MagickFalse,(Atom)
15989 AnyPropertyType,&type,&format,&length,&after,&data);
15990 if ((status != Success) || (length == 0))
15992 if (LocaleCompare((
char *) data,
"-quit") == 0)
15994 XClientMessage(display,windows->image.id,windows->im_protocols,
15995 windows->im_exit,CurrentTime);
15996 (void) XFree((
void *) data);
15999 (void) CopyMagickString(resource_info->image_info->filename,
16000 (
char *) data,MagickPathExtent);
16001 (void) XFree((
void *) data);
16002 nexus=ReadImage(resource_info->image_info,exception);
16003 CatchException(exception);
16004 if (nexus != (
Image *) NULL)
16005 *state|=NextImageState | ExitState;
16008 case ReparentNotify:
16010 if (resource_info->debug != MagickFalse)
16011 (void) LogMagickEvent(X11Event,GetMagickModule(),
16012 "Reparent Notify: 0x%lx=>0x%lx",event.xreparent.parent,
16013 event.xreparent.window);
16018 if (resource_info->debug != MagickFalse)
16019 (void) LogMagickEvent(X11Event,GetMagickModule(),
16020 "Unmap Notify: 0x%lx",event.xunmap.window);
16021 if (event.xunmap.window == windows->backdrop.id)
16023 windows->backdrop.mapped=MagickFalse;
16026 if (event.xunmap.window == windows->image.id)
16028 windows->image.mapped=MagickFalse;
16031 if (event.xunmap.window == windows->magnify.id)
16033 windows->magnify.mapped=MagickFalse;
16036 if (event.xunmap.window == windows->pan.id)
16038 windows->pan.mapped=MagickFalse;
16041 if (event.xunmap.window == windows->info.id)
16043 windows->info.mapped=MagickFalse;
16046 if (event.xunmap.window == windows->icon.id)
16048 if (map_info->colormap == icon_map->colormap)
16049 XConfigureImageColormap(display,resource_info,windows,
16050 display_image,exception);
16051 (void) XFreeStandardColormap(display,icon_visual,icon_map,
16053 windows->icon.mapped=MagickFalse;
16056 if (event.xunmap.window == windows->command.id)
16058 windows->command.mapped=MagickFalse;
16061 if (event.xunmap.window == windows->popup.id)
16063 if (windows->backdrop.id != (Window) NULL)
16064 (void) XSetInputFocus(display,windows->image.id,RevertToParent,
16066 windows->popup.mapped=MagickFalse;
16069 if (event.xunmap.window == windows->widget.id)
16071 if (windows->backdrop.id != (Window) NULL)
16072 (void) XSetInputFocus(display,windows->image.id,RevertToParent,
16074 windows->widget.mapped=MagickFalse;
16081 if (resource_info->debug != MagickFalse)
16082 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Event type: %d",
16087 }
while (!(*state & ExitState));
16088 if ((*state & ExitState) == 0)
16089 (void) XMagickCommand(display,resource_info,windows,FreeBuffersCommand,
16090 &display_image,exception);
16092 if (resource_info->confirm_edit != MagickFalse)
16097 if ((resource_info->immutable == MagickFalse) &&
16098 display_image->taint != MagickFalse)
16103 status=XConfirmWidget(display,windows,
"Your image changed.",
16104 "Do you want to save it");
16106 *state&=(
unsigned int) (~ExitState);
16109 (void) XMagickCommand(display,resource_info,windows,SaveCommand,
16110 &display_image,exception);
16113 if ((windows->visual_info->klass == GrayScale) ||
16114 (windows->visual_info->klass == PseudoColor) ||
16115 (windows->visual_info->klass == DirectColor))
16120 if (windows->info.mapped != MagickFalse)
16121 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
16122 if (windows->magnify.mapped != MagickFalse)
16123 (void) XWithdrawWindow(display,windows->magnify.id,
16124 windows->magnify.screen);
16125 if (windows->command.mapped != MagickFalse)
16126 (void) XWithdrawWindow(display,windows->command.id,
16127 windows->command.screen);
16129 if (windows->pan.mapped != MagickFalse)
16130 (void) XWithdrawWindow(display,windows->pan.id,windows->pan.screen);
16131 if (resource_info->backdrop == MagickFalse)
16132 if (windows->backdrop.mapped)
16134 (void) XWithdrawWindow(display,windows->backdrop.id,
16135 windows->backdrop.screen);
16136 (void) XDestroyWindow(display,windows->backdrop.id);
16137 windows->backdrop.id=(Window) NULL;
16138 (void) XWithdrawWindow(display,windows->image.id,
16139 windows->image.screen);
16140 (void) XDestroyWindow(display,windows->image.id);
16141 windows->image.id=(Window) NULL;
16143 XSetCursorState(display,windows,MagickTrue);
16144 XCheckRefreshWindows(display,windows);
16145 if (((*state & FormerImageState) != 0) || ((*state & NextImageState) != 0))
16146 *state&=(
unsigned int) (~ExitState);
16147 if (*state & ExitState)
16152 (void) XFreeStandardColormap(display,icon_visual,icon_map,icon_pixel);
16153 if (resource_info->map_type == (
char *) NULL)
16154 (void) XFreeStandardColormap(display,visual_info,map_info,pixel);
16158 if (resource_info->copy_image != (
Image *) NULL)
16160 resource_info->copy_image=DestroyImage(resource_info->copy_image);
16161 resource_info->copy_image=NewImageList();
16163 DestroyXResources();
16165 (void) XSync(display,MagickFalse);
16169 (void) SetErrorHandler(warning_handler);
16170 (void) SetWarningHandler(warning_handler);
16174 directory=getcwd(working_directory,MagickPathExtent);
16180 if (*resource_info->home_directory ==
'\0')
16181 (void) CopyMagickString(resource_info->home_directory,
".",MagickPathExtent);
16182 status=chdir(resource_info->home_directory);
16184 (void) ThrowMagickException(exception,GetMagickModule(),FileOpenError,
16185 "UnableToOpenFile",
"%s",resource_info->home_directory);
16187 *image=display_image;
16221MagickExport MagickBooleanType DisplayImages(
const ImageInfo *image_info,
16224 assert(image_info != (
const ImageInfo *) NULL);
16225 assert(image_info->signature == MagickCoreSignature);
16226 assert(image != (
Image *) NULL);
16227 assert(image->signature == MagickCoreSignature);
16229 if (IsEventLogging() != MagickFalse)
16230 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
16231 (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError,
16232 "DelegateLibrarySupportNotBuiltIn",
"'%s' (X11)",image->filename);
16233 return(MagickFalse);
16266MagickExport MagickBooleanType RemoteDisplayCommand(
const ImageInfo *image_info,
16267 const char *window,
const char *filename,
ExceptionInfo *exception)
16269 assert(image_info != (
const ImageInfo *) NULL);
16270 assert(image_info->signature == MagickCoreSignature);
16271 assert(filename != (
char *) NULL);
16272 if (IsEventLogging() != MagickFalse)
16273 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",filename);
16275 (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError,
16276 "DelegateLibrarySupportNotBuiltIn",
"'%s' (X11)",image_info->filename);
16277 return(MagickFalse);