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+=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+=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+=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+=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+=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);
6446 cache_image=undo_image;
6447 undo_image=GetPreviousImageInList(undo_image);
6448 windows->image.window_changes.width=(int) cache_image->columns;
6449 windows->image.window_changes.height=(int) cache_image->rows;
6450 (void) FormatLocaleString(image_geometry,MagickPathExtent,
"%dx%d!",
6451 windows->image.ximage->width,windows->image.ximage->height);
6452 (void) TransformImage(image,windows->image.crop_geometry,image_geometry,
6454 if (windows->image.crop_geometry != (
char *) NULL)
6455 windows->image.crop_geometry=(
char *) RelinquishMagickMemory(
6456 windows->image.crop_geometry);
6457 windows->image.crop_geometry=cache_image->geometry;
6458 if (redo_image != (
Image *) NULL)
6459 redo_image=DestroyImage(redo_image);
6460 redo_image=(*image);
6461 *image=cache_image->list;
6462 cache_image=DestroyImage(cache_image);
6463 if (windows->image.orphan != MagickFalse)
6465 XConfigureImageColormap(display,resource_info,windows,*image,exception);
6466 (void) XConfigureImage(display,resource_info,windows,*image,exception);
6472 case HalfSizeCommand:
6473 case OriginalSizeCommand:
6474 case DoubleSizeCommand:
6481 case RotateRightCommand:
6482 case RotateLeftCommand:
6487 case ContrastStretchCommand:
6488 case SigmoidalContrastCommand:
6489 case NormalizeCommand:
6490 case EqualizeCommand:
6492 case SaturationCommand:
6493 case BrightnessCommand:
6497 case GrayscaleCommand:
6499 case QuantizeCommand:
6500 case DespeckleCommand:
6502 case ReduceNoiseCommand:
6503 case AddNoiseCommand:
6504 case SharpenCommand:
6506 case ThresholdCommand:
6507 case EdgeDetectCommand:
6511 case SegmentCommand:
6512 case SolarizeCommand:
6513 case SepiaToneCommand:
6515 case ImplodeCommand:
6516 case VignetteCommand:
6518 case OilPaintCommand:
6519 case CharcoalDrawCommand:
6520 case AnnotateCommand:
6521 case AddBorderCommand:
6522 case AddFrameCommand:
6523 case CompositeCommand:
6524 case CommentCommand:
6526 case RegionOfInterestCommand:
6527 case SaveToUndoBufferCommand:
6536 bytes=(*image)->columns*(*image)->rows*
sizeof(
PixelInfo);
6537 if (undo_image != (
Image *) NULL)
6542 previous_image=undo_image;
6543 while (previous_image != (
Image *) NULL)
6545 bytes+=previous_image->list->columns*previous_image->list->rows*
6547 if (bytes <= (resource_info->undo_cache << 20))
6549 previous_image=GetPreviousImageInList(previous_image);
6552 bytes-=previous_image->list->columns*previous_image->list->rows*
6554 if (previous_image == undo_image)
6555 undo_image=NewImageList();
6557 previous_image->next->previous=NewImageList();
6560 while (previous_image != (
Image *) NULL)
6565 cache_image=previous_image;
6566 previous_image=GetPreviousImageInList(previous_image);
6567 cache_image->list=DestroyImage(cache_image->list);
6568 cache_image=DestroyImage(cache_image);
6571 if (bytes > (resource_info->undo_cache << 20))
6576 cache_image=AcquireImage((
ImageInfo *) NULL,exception);
6577 if (cache_image == (
Image *) NULL)
6579 XSetCursorState(display,windows,MagickTrue);
6580 XCheckRefreshWindows(display,windows);
6581 cache_image->list=CloneImage(*image,0,0,MagickTrue,exception);
6582 XSetCursorState(display,windows,MagickFalse);
6583 if (cache_image->list == (
Image *) NULL)
6585 cache_image=DestroyImage(cache_image);
6588 cache_image->columns=(size_t) windows->image.ximage->width;
6589 cache_image->rows=(size_t) windows->image.ximage->height;
6590 cache_image->geometry=windows->image.crop_geometry;
6591 if (windows->image.crop_geometry != (
char *) NULL)
6593 cache_image->geometry=AcquireString((
char *) NULL);
6594 (void) CopyMagickString(cache_image->geometry,
6595 windows->image.crop_geometry,MagickPathExtent);
6597 if (undo_image == (
Image *) NULL)
6599 undo_image=cache_image;
6602 undo_image->next=cache_image;
6603 undo_image->next->previous=undo_image;
6604 undo_image=undo_image->next;
6610 if (command == RedoCommand)
6615 if (redo_image == (
Image *) NULL)
6617 (void) XBell(display,0);
6620 windows->image.window_changes.width=(int) redo_image->columns;
6621 windows->image.window_changes.height=(int) redo_image->rows;
6622 if (windows->image.crop_geometry != (
char *) NULL)
6623 windows->image.crop_geometry=(
char *)
6624 RelinquishMagickMemory(windows->image.crop_geometry);
6625 windows->image.crop_geometry=redo_image->geometry;
6626 *image=DestroyImage(*image);
6628 redo_image=NewImageList();
6629 if (windows->image.orphan != MagickFalse)
6631 XConfigureImageColormap(display,resource_info,windows,*image,exception);
6632 (void) XConfigureImage(display,resource_info,windows,*image,exception);
6635 if (command != InfoCommand)
6640 XSetCursorState(display,windows,MagickTrue);
6641 XCheckRefreshWindows(display,windows);
6642 XDisplayImageInfo(display,resource_info,windows,undo_image,*image,exception);
6643 XSetCursorState(display,windows,MagickFalse);
6690static DisplayCommand XImageWindowCommand(Display *display,
6691 XResourceInfo *resource_info,XWindows *windows,
const MagickStatusType state,
6695 delta[MagickPathExtent] =
"";
6698 Digits[] =
"01234567890";
6703 if ((key_symbol >= XK_0) && (key_symbol <= XK_9))
6705 if (((last_symbol < XK_0) || (last_symbol > XK_9)))
6708 resource_info->quantum=1;
6710 last_symbol=key_symbol;
6711 delta[strlen(delta)+1]=
'\0';
6712 delta[strlen(delta)]=Digits[key_symbol-XK_0];
6713 resource_info->quantum=StringToLong(delta);
6714 return(NullCommand);
6716 last_symbol=key_symbol;
6717 if (resource_info->immutable)
6725 return(InfoCommand);
6728 return(PrintCommand);
6730 return(NextCommand);
6733 return(QuitCommand);
6737 return(NullCommand);
6739 switch ((
int) key_symbol)
6743 if ((state & ControlMask) == 0)
6745 return(OpenCommand);
6748 return(NextCommand);
6750 return(FormerCommand);
6753 if ((state & Mod1Mask) != 0)
6754 return(SwirlCommand);
6755 if ((state & ControlMask) == 0)
6756 return(ShearCommand);
6757 return(SaveCommand);
6762 if ((state & Mod1Mask) != 0)
6763 return(OilPaintCommand);
6764 if ((state & Mod4Mask) != 0)
6765 return(ColorCommand);
6766 if ((state & ControlMask) == 0)
6767 return(NullCommand);
6768 return(PrintCommand);
6772 if ((state & Mod4Mask) != 0)
6773 return(DrawCommand);
6774 if ((state & ControlMask) == 0)
6775 return(NullCommand);
6776 return(DeleteCommand);
6780 if ((state & ControlMask) == 0)
6781 return(NullCommand);
6782 return(SelectCommand);
6786 if ((state & ControlMask) == 0)
6787 return(NullCommand);
6792 return(QuitCommand);
6796 if ((state & ControlMask) == 0)
6797 return(NullCommand);
6798 return(UndoCommand);
6803 if ((state & ControlMask) == 0)
6804 return(RollCommand);
6805 return(RedoCommand);
6809 if ((state & ControlMask) == 0)
6810 return(NullCommand);
6815 if ((state & Mod1Mask) != 0)
6816 return(CharcoalDrawCommand);
6817 if ((state & ControlMask) == 0)
6818 return(CropCommand);
6819 return(CopyCommand);
6824 if ((state & Mod4Mask) != 0)
6825 return(CompositeCommand);
6826 if ((state & ControlMask) == 0)
6827 return(FlipCommand);
6828 return(PasteCommand);
6831 return(HalfSizeCommand);
6833 return(OriginalSizeCommand);
6835 return(DoubleSizeCommand);
6837 return(ResizeCommand);
6839 return(RefreshCommand);
6840 case XK_bracketleft:
6841 return(ChopCommand);
6843 return(FlopCommand);
6845 return(RotateRightCommand);
6847 return(RotateLeftCommand);
6849 return(RotateCommand);
6851 return(TrimCommand);
6855 return(SaturationCommand);
6857 return(BrightnessCommand);
6859 return(GammaCommand);
6861 return(SpiffCommand);
6863 return(DullCommand);
6865 return(NormalizeCommand);
6867 return(EqualizeCommand);
6869 return(NegateCommand);
6871 return(GrayscaleCommand);
6873 return(QuantizeCommand);
6875 return(DespeckleCommand);
6877 return(EmbossCommand);
6879 return(ReduceNoiseCommand);
6881 return(AddNoiseCommand);
6883 return(SharpenCommand);
6885 return(BlurCommand);
6887 return(ThresholdCommand);
6889 return(EdgeDetectCommand);
6891 return(SpreadCommand);
6893 return(ShadeCommand);
6895 return(RaiseCommand);
6897 return(SegmentCommand);
6900 if ((state & Mod1Mask) == 0)
6901 return(NullCommand);
6902 return(ImplodeCommand);
6906 if ((state & Mod1Mask) == 0)
6907 return(NullCommand);
6908 return(WaveCommand);
6912 if ((state & Mod4Mask) == 0)
6913 return(NullCommand);
6914 return(MatteCommand);
6918 if ((state & Mod4Mask) == 0)
6919 return(NullCommand);
6920 return(AddBorderCommand);
6924 if ((state & Mod4Mask) == 0)
6925 return(NullCommand);
6926 return(AddFrameCommand);
6930 if ((state & Mod4Mask) == 0)
6931 return(NullCommand);
6932 return(CommentCommand);
6936 if ((state & Mod1Mask) != 0)
6937 return(ApplyCommand);
6938 if ((state & Mod4Mask) != 0)
6939 return(AnnotateCommand);
6940 if ((state & ControlMask) == 0)
6941 return(NullCommand);
6942 return(RegionOfInterestCommand);
6945 return(InfoCommand);
6947 return(ZoomCommand);
6950 if ((state & ShiftMask) == 0)
6951 return(NullCommand);
6952 return(ShowPreviewCommand);
6955 return(LaunchCommand);
6957 return(HelpCommand);
6959 return(BrowseDocumentationCommand);
6962 (void) XMapRaised(display,windows->command.id);
6963 return(NullCommand);
6970 XTranslateImage(display,windows,*image,key_symbol);
6971 return(NullCommand);
6982 if ((state & Mod1Mask) != 0)
6992 crop_info.width=(size_t) windows->image.ximage->width;
6993 crop_info.height=(size_t) windows->image.ximage->height;
6994 if ((key_symbol == XK_Up) || (key_symbol == XK_KP_Up))
6996 if (resource_info->quantum >= (
int) crop_info.height)
6997 resource_info->quantum=(int) crop_info.height-1;
6998 crop_info.height-=(size_t) resource_info->quantum;
7000 if ((key_symbol == XK_Down) || (key_symbol == XK_KP_Down))
7002 if (resource_info->quantum >= ((
int) crop_info.height-crop_info.y))
7003 resource_info->quantum=(int) crop_info.height-crop_info.y-1;
7004 crop_info.y+=resource_info->quantum;
7005 crop_info.height-=(size_t) resource_info->quantum;
7007 if ((key_symbol == XK_Left) || (key_symbol == XK_KP_Left))
7009 if (resource_info->quantum >= (
int) crop_info.width)
7010 resource_info->quantum=(int) crop_info.width-1;
7011 crop_info.width-=(size_t) resource_info->quantum;
7013 if ((key_symbol == XK_Right) || (key_symbol == XK_KP_Right))
7015 if (resource_info->quantum >= ((
int) crop_info.width-crop_info.x))
7016 resource_info->quantum=(int) crop_info.width-crop_info.x-1;
7017 crop_info.x+=resource_info->quantum;
7018 crop_info.width-=(size_t) resource_info->quantum;
7020 if ((windows->image.x+(
int) windows->image.width) > (
int) crop_info.width)
7021 windows->image.x=(int) (crop_info.width-windows->image.width);
7022 if ((windows->image.y+(
int) windows->image.height) > (int) crop_info.height)
7023 windows->image.y=(int) (crop_info.height-windows->image.height);
7024 XSetCropGeometry(display,windows,&crop_info,*image);
7025 windows->image.window_changes.width=(int) crop_info.width;
7026 windows->image.window_changes.height=(int) crop_info.height;
7027 (void) XSetWindowBackgroundPixmap(display,windows->image.id,None);
7028 (void) XConfigureImage(display,resource_info,windows,*image,
7030 return(NullCommand);
7032 XTranslateImage(display,windows,*image,key_symbol);
7033 return(NullCommand);
7036 return(NullCommand);
7038 return(NullCommand);
7078static Image *XMagickCommand(Display *display,XResourceInfo *resource_info,
7079 XWindows *windows,
const DisplayCommand command,
Image **image,
7083 filename[MagickPathExtent],
7084 geometry[MagickPathExtent],
7085 modulate_factors[MagickPathExtent];
7114 color[MagickPathExtent] =
"gray";
7123 XCheckRefreshWindows(display,windows);
7124 XImageCache(display,resource_info,windows,command,image,exception);
7125 nexus=NewImageList();
7126 windows->image.window_changes.width=windows->image.ximage->width;
7127 windows->image.window_changes.height=windows->image.ximage->height;
7128 image_info=CloneImageInfo(resource_info->image_info);
7129 SetGeometryInfo(&geometry_info);
7130 GetQuantizeInfo(&quantize_info);
7138 nexus=XOpenImage(display,resource_info,windows,MagickFalse);
7146 for (i=0; i < resource_info->quantum; i++)
7147 XClientMessage(display,windows->image.id,windows->im_protocols,
7148 windows->im_next_image,CurrentTime);
7156 for (i=0; i < resource_info->quantum; i++)
7157 XClientMessage(display,windows->image.id,windows->im_protocols,
7158 windows->im_former_image,CurrentTime);
7169 if (*resource_info->home_directory ==
'\0')
7170 (void) CopyMagickString(resource_info->home_directory,
".",
7172 status=chdir(resource_info->home_directory);
7174 (void) ThrowMagickException(exception,GetMagickModule(),FileOpenError,
7175 "UnableToOpenFile",
"%s",resource_info->home_directory);
7176 nexus=XOpenImage(display,resource_info,windows,MagickTrue);
7184 status=XSaveImage(display,resource_info,windows,*image,exception);
7185 if (status == MagickFalse)
7188 message[MagickPathExtent];
7190 (void) FormatLocaleString(message,MagickPathExtent,
"%s:%s",
7191 exception->reason != (
char *) NULL ? exception->reason :
"",
7192 exception->description != (
char *) NULL ? exception->description :
7194 XNoticeWidget(display,windows,
"Unable to save file:",message);
7204 status=XPrintImage(display,resource_info,windows,*image,exception);
7205 if (status == MagickFalse)
7208 message[MagickPathExtent];
7210 (void) FormatLocaleString(message,MagickPathExtent,
"%s:%s",
7211 exception->reason != (
char *) NULL ? exception->reason :
"",
7212 exception->description != (
char *) NULL ? exception->description :
7214 XNoticeWidget(display,windows,
"Unable to print file:",message);
7222 filename[MagickPathExtent] =
"\0";
7227 XFileBrowserWidget(display,windows,
"Delete",filename);
7228 if (*filename ==
'\0')
7230 status=ShredFile(filename);
7231 if (remove_utf8(filename) < 0)
7233 if (status != MagickFalse)
7234 XNoticeWidget(display,windows,
"Unable to delete image file:",filename);
7243 color[MagickPathExtent] =
"gray",
7244 geometry[MagickPathExtent] =
"640x480";
7247 *format =
"gradient";
7252 status=XDialogWidget(display,windows,
"New",
"Enter image geometry:",
7254 if (*geometry ==
'\0')
7258 XColorBrowserWidget(display,windows,
"Select",color);
7264 (void) FormatLocaleString(image_info->filename,MagickPathExtent,
7265 "%s:%s",format,color);
7266 (void) CloneString(&image_info->size,geometry);
7267 nexus=ReadImage(image_info,exception);
7268 CatchException(exception);
7269 XClientMessage(display,windows->image.id,windows->im_protocols,
7270 windows->im_next_image,CurrentTime);
7273 case VisualDirectoryCommand:
7278 nexus=XVisualDirectoryImage(display,resource_info,windows,exception);
7286 if (resource_info->confirm_exit == MagickFalse)
7287 XClientMessage(display,windows->image.id,windows->im_protocols,
7288 windows->im_exit,CurrentTime);
7297 status=XConfirmWidget(display,windows,
"Do you really want to exit",
7298 resource_info->client_name);
7300 XClientMessage(display,windows->image.id,windows->im_protocols,
7301 windows->im_exit,CurrentTime);
7310 (void) XCropImage(display,resource_info,windows,*image,CutMode,exception);
7318 (void) XCropImage(display,resource_info,windows,*image,CopyMode,
7327 status=XPasteImage(display,resource_info,windows,*image,exception);
7328 if (status == MagickFalse)
7330 XNoticeWidget(display,windows,
"Unable to paste X image",
7331 (*image)->filename);
7336 case HalfSizeCommand:
7341 windows->image.window_changes.width=windows->image.ximage->width/2;
7342 windows->image.window_changes.height=windows->image.ximage->height/2;
7343 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7346 case OriginalSizeCommand:
7351 windows->image.window_changes.width=(int) (*image)->columns;
7352 windows->image.window_changes.height=(int) (*image)->rows;
7353 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7356 case DoubleSizeCommand:
7361 windows->image.window_changes.width=windows->image.ximage->width << 1;
7362 windows->image.window_changes.height=windows->image.ximage->height << 1;
7363 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7382 width=(size_t) windows->image.ximage->width;
7383 height=(size_t) windows->image.ximage->height;
7386 (void) FormatLocaleString(geometry,MagickPathExtent,
"%.20gx%.20g+0+0",
7387 (
double) width,(double) height);
7388 status=XDialogWidget(display,windows,
"Resize",
7389 "Enter resize geometry (e.g. 640x480, 200%):",geometry);
7390 if (*geometry ==
'\0')
7393 (void) ConcatenateMagickString(geometry,
"!",MagickPathExtent);
7394 (void) ParseMetaGeometry(geometry,&x,&y,&width,&height);
7395 windows->image.window_changes.width=(int) width;
7396 windows->image.window_changes.height=(int) height;
7397 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7403 image_geometry[MagickPathExtent];
7405 if ((windows->image.crop_geometry == (
char *) NULL) &&
7406 ((
int) (*image)->columns == windows->image.ximage->width) &&
7407 ((
int) (*image)->rows == windows->image.ximage->height))
7412 XSetCursorState(display,windows,MagickTrue);
7413 XCheckRefreshWindows(display,windows);
7417 (void) FormatLocaleString(image_geometry,MagickPathExtent,
"%dx%d!",
7418 windows->image.ximage->width,windows->image.ximage->height);
7419 (void) TransformImage(image,windows->image.crop_geometry,image_geometry,
7421 if (windows->image.crop_geometry != (
char *) NULL)
7422 windows->image.crop_geometry=(
char *) RelinquishMagickMemory(
7423 windows->image.crop_geometry);
7426 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7427 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7430 case RefreshCommand:
7432 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7435 case RestoreCommand:
7440 if ((windows->image.width == (
unsigned int) (*image)->columns) &&
7441 (windows->image.height == (
unsigned int) (*image)->rows) &&
7442 (windows->image.crop_geometry == (
char *) NULL))
7444 (void) XBell(display,0);
7447 windows->image.window_changes.width=(int) (*image)->columns;
7448 windows->image.window_changes.height=(int) (*image)->rows;
7449 if (windows->image.crop_geometry != (
char *) NULL)
7451 windows->image.crop_geometry=(
char *)
7452 RelinquishMagickMemory(windows->image.crop_geometry);
7453 windows->image.crop_geometry=(
char *) NULL;
7457 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7458 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7466 (void) XCropImage(display,resource_info,windows,*image,CropMode,
7475 status=XChopImage(display,resource_info,windows,image,exception);
7476 if (status == MagickFalse)
7478 XNoticeWidget(display,windows,
"Unable to cut X image",
7479 (*image)->filename);
7492 XSetCursorState(display,windows,MagickTrue);
7493 XCheckRefreshWindows(display,windows);
7494 flop_image=FlopImage(*image,exception);
7495 if (flop_image != (
Image *) NULL)
7497 *image=DestroyImage(*image);
7500 CatchException(exception);
7501 XSetCursorState(display,windows,MagickFalse);
7502 if (windows->image.crop_geometry != (
char *) NULL)
7507 width=(
unsigned int) (*image)->columns;
7508 height=(
unsigned int) (*image)->rows;
7509 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
7511 (void) FormatLocaleString(windows->image.crop_geometry,
7512 MagickPathExtent,
"%ux%u%+d%+d",width,height,(
int) (*image)->columns-
7515 if (windows->image.orphan != MagickFalse)
7517 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7528 XSetCursorState(display,windows,MagickTrue);
7529 XCheckRefreshWindows(display,windows);
7530 flip_image=FlipImage(*image,exception);
7531 if (flip_image != (
Image *) NULL)
7533 *image=DestroyImage(*image);
7536 CatchException(exception);
7537 XSetCursorState(display,windows,MagickFalse);
7538 if (windows->image.crop_geometry != (
char *) NULL)
7543 width=(
unsigned int) (*image)->columns;
7544 height=(
unsigned int) (*image)->rows;
7545 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
7547 (void) FormatLocaleString(windows->image.crop_geometry,
7548 MagickPathExtent,
"%ux%u%+d%+d",width,height,x,(
int) (*image)->rows-
7551 if (windows->image.orphan != MagickFalse)
7553 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7556 case RotateRightCommand:
7561 status=XRotateImage(display,resource_info,windows,90.0,image,exception);
7562 if (status == MagickFalse)
7564 XNoticeWidget(display,windows,
"Unable to rotate X image",
7565 (*image)->filename);
7570 case RotateLeftCommand:
7575 status=XRotateImage(display,resource_info,windows,-90.0,image,exception);
7576 if (status == MagickFalse)
7578 XNoticeWidget(display,windows,
"Unable to rotate X image",
7579 (*image)->filename);
7589 status=XRotateImage(display,resource_info,windows,0.0,image,exception);
7590 if (status == MagickFalse)
7592 XNoticeWidget(display,windows,
"Unable to rotate X image",
7593 (*image)->filename);
7604 geometry[MagickPathExtent] =
"45.0x45.0";
7609 XColorBrowserWidget(display,windows,
"Select",color);
7612 (void) XDialogWidget(display,windows,
"Shear",
"Enter shear geometry:",
7614 if (*geometry ==
'\0')
7619 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
7621 XSetCursorState(display,windows,MagickTrue);
7622 XCheckRefreshWindows(display,windows);
7623 (void) QueryColorCompliance(color,AllCompliance,
7624 &(*image)->background_color,exception);
7625 flags=ParseGeometry(geometry,&geometry_info);
7626 if ((flags & SigmaValue) == 0)
7627 geometry_info.sigma=geometry_info.rho;
7628 shear_image=ShearImage(*image,geometry_info.rho,geometry_info.sigma,
7630 if (shear_image != (
Image *) NULL)
7632 *image=DestroyImage(*image);
7635 CatchException(exception);
7636 XSetCursorState(display,windows,MagickFalse);
7637 if (windows->image.orphan != MagickFalse)
7639 windows->image.window_changes.width=(int) (*image)->columns;
7640 windows->image.window_changes.height=(int) (*image)->rows;
7641 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7642 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7651 geometry[MagickPathExtent] =
"+2+2";
7656 (void) XDialogWidget(display,windows,
"Roll",
"Enter roll geometry:",
7658 if (*geometry ==
'\0')
7663 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
7665 XSetCursorState(display,windows,MagickTrue);
7666 XCheckRefreshWindows(display,windows);
7667 (void) ParsePageGeometry(*image,geometry,&page_geometry,
7669 roll_image=RollImage(*image,page_geometry.x,page_geometry.y,
7671 if (roll_image != (
Image *) NULL)
7673 *image=DestroyImage(*image);
7676 CatchException(exception);
7677 XSetCursorState(display,windows,MagickFalse);
7678 if (windows->image.orphan != MagickFalse)
7680 windows->image.window_changes.width=(int) (*image)->columns;
7681 windows->image.window_changes.height=(int) (*image)->rows;
7682 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7683 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7689 fuzz[MagickPathExtent];
7694 (void) FormatLocaleString(fuzz,MagickPathExtent,
"%g%%",100.0*
7695 (*image)->fuzz/((
double) QuantumRange+1.0));
7696 (void) XDialogWidget(display,windows,
"Trim",
"Enter fuzz factor:",fuzz);
7699 (*image)->fuzz=StringToDoubleInterval(fuzz,(
double) QuantumRange+1.0);
7703 status=XTrimImage(display,resource_info,windows,*image,exception);
7704 if (status == MagickFalse)
7706 XNoticeWidget(display,windows,
"Unable to trim X image",
7707 (*image)->filename);
7715 hue_percent[MagickPathExtent] =
"110";
7720 (void) XDialogWidget(display,windows,
"Apply",
7721 "Enter percent change in image hue (0-200):",hue_percent);
7722 if (*hue_percent ==
'\0')
7727 XSetCursorState(display,windows,MagickTrue);
7728 XCheckRefreshWindows(display,windows);
7729 (void) CopyMagickString(modulate_factors,
"100.0/100.0/",MagickPathExtent);
7730 (void) ConcatenateMagickString(modulate_factors,hue_percent,
7732 (void) ModulateImage(*image,modulate_factors,exception);
7733 XSetCursorState(display,windows,MagickFalse);
7734 if (windows->image.orphan != MagickFalse)
7736 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7737 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7740 case SaturationCommand:
7743 saturation_percent[MagickPathExtent] =
"110";
7748 (void) XDialogWidget(display,windows,
"Apply",
7749 "Enter percent change in color saturation (0-200):",saturation_percent);
7750 if (*saturation_percent ==
'\0')
7755 XSetCursorState(display,windows,MagickTrue);
7756 XCheckRefreshWindows(display,windows);
7757 (void) CopyMagickString(modulate_factors,
"100.0/",MagickPathExtent);
7758 (void) ConcatenateMagickString(modulate_factors,saturation_percent,
7760 (void) ModulateImage(*image,modulate_factors,exception);
7761 XSetCursorState(display,windows,MagickFalse);
7762 if (windows->image.orphan != MagickFalse)
7764 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7765 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7768 case BrightnessCommand:
7771 brightness_percent[MagickPathExtent] =
"110";
7776 (void) XDialogWidget(display,windows,
"Apply",
7777 "Enter percent change in color brightness (0-200):",brightness_percent);
7778 if (*brightness_percent ==
'\0')
7783 XSetCursorState(display,windows,MagickTrue);
7784 XCheckRefreshWindows(display,windows);
7785 (void) CopyMagickString(modulate_factors,brightness_percent,
7787 (void) ModulateImage(*image,modulate_factors,exception);
7788 XSetCursorState(display,windows,MagickFalse);
7789 if (windows->image.orphan != MagickFalse)
7791 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7792 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7798 factor[MagickPathExtent] =
"1.6";
7803 (void) XDialogWidget(display,windows,
"Gamma",
7804 "Enter gamma value (e.g. 1.2):",factor);
7805 if (*factor ==
'\0')
7810 XSetCursorState(display,windows,MagickTrue);
7811 XCheckRefreshWindows(display,windows);
7812 (void) GammaImage(*image,strtod(factor,(
char **) NULL),exception);
7813 XSetCursorState(display,windows,MagickFalse);
7814 if (windows->image.orphan != MagickFalse)
7816 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7817 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7825 XSetCursorState(display,windows,MagickTrue);
7826 XCheckRefreshWindows(display,windows);
7827 (void) ContrastImage(*image,MagickTrue,exception);
7828 XSetCursorState(display,windows,MagickFalse);
7829 if (windows->image.orphan != MagickFalse)
7831 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7832 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7840 XSetCursorState(display,windows,MagickTrue);
7841 XCheckRefreshWindows(display,windows);
7842 (void) ContrastImage(*image,MagickFalse,exception);
7843 XSetCursorState(display,windows,MagickFalse);
7844 if (windows->image.orphan != MagickFalse)
7846 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7847 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7850 case ContrastStretchCommand:
7857 levels[MagickPathExtent] =
"1%";
7862 (void) XDialogWidget(display,windows,
"Contrast Stretch",
7863 "Enter black and white points:",levels);
7864 if (*levels ==
'\0')
7869 XSetCursorState(display,windows,MagickTrue);
7870 XCheckRefreshWindows(display,windows);
7871 flags=ParseGeometry(levels,&geometry_info);
7872 black_point=geometry_info.rho;
7873 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma : black_point;
7874 if ((flags & PercentValue) != 0)
7876 black_point*=(double) (*image)->columns*(*image)->rows/100.0;
7877 white_point*=(double) (*image)->columns*(*image)->rows/100.0;
7879 white_point=(double) (*image)->columns*(*image)->rows-white_point;
7880 (void) ContrastStretchImage(*image,black_point,white_point,
7882 XSetCursorState(display,windows,MagickFalse);
7883 if (windows->image.orphan != MagickFalse)
7885 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7886 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7889 case SigmoidalContrastCommand:
7898 levels[MagickPathExtent] =
"3x50%";
7903 (void) XDialogWidget(display,windows,
"Sigmoidal Contrast",
7904 "Enter contrast and midpoint:",levels);
7905 if (*levels ==
'\0')
7910 XSetCursorState(display,windows,MagickTrue);
7911 XCheckRefreshWindows(display,windows);
7912 flags=ParseGeometry(levels,&geometry_info);
7913 if ((flags & SigmaValue) == 0)
7914 geometry_info.sigma=1.0*(double) QuantumRange/2.0;
7915 if ((flags & PercentValue) != 0)
7916 geometry_info.sigma=1.0*(
double) QuantumRange*geometry_info.sigma/100.0;
7917 (void) SigmoidalContrastImage(*image,MagickTrue,geometry_info.rho,
7918 geometry_info.sigma,exception);
7919 XSetCursorState(display,windows,MagickFalse);
7920 if (windows->image.orphan != MagickFalse)
7922 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7923 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7926 case NormalizeCommand:
7931 XSetCursorState(display,windows,MagickTrue);
7932 XCheckRefreshWindows(display,windows);
7933 (void) NormalizeImage(*image,exception);
7934 XSetCursorState(display,windows,MagickFalse);
7935 if (windows->image.orphan != MagickFalse)
7937 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7938 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7941 case EqualizeCommand:
7946 XSetCursorState(display,windows,MagickTrue);
7947 XCheckRefreshWindows(display,windows);
7948 (void) EqualizeImage(*image,exception);
7949 XSetCursorState(display,windows,MagickFalse);
7950 if (windows->image.orphan != MagickFalse)
7952 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7953 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7961 XSetCursorState(display,windows,MagickTrue);
7962 XCheckRefreshWindows(display,windows);
7963 (void) NegateImage(*image,MagickFalse,exception);
7964 XSetCursorState(display,windows,MagickFalse);
7965 if (windows->image.orphan != MagickFalse)
7967 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7968 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7971 case GrayscaleCommand:
7976 XSetCursorState(display,windows,MagickTrue);
7977 XCheckRefreshWindows(display,windows);
7978 (void) SetImageType(*image,(*image)->alpha_trait == UndefinedPixelTrait ?
7979 GrayscaleType : GrayscaleAlphaType,exception);
7980 XSetCursorState(display,windows,MagickFalse);
7981 if (windows->image.orphan != MagickFalse)
7983 XConfigureImageColormap(display,resource_info,windows,*image,exception);
7984 (void) XConfigureImage(display,resource_info,windows,*image,exception);
7993 filename[MagickPathExtent] =
"\0";
7998 XFileBrowserWidget(display,windows,
"Map",filename);
7999 if (*filename ==
'\0')
8004 XSetCursorState(display,windows,MagickTrue);
8005 XCheckRefreshWindows(display,windows);
8006 (void) CopyMagickString(image_info->filename,filename,MagickPathExtent);
8007 affinity_image=ReadImage(image_info,exception);
8008 if (affinity_image != (
Image *) NULL)
8010 (void) RemapImage(&quantize_info,*image,affinity_image,exception);
8011 affinity_image=DestroyImage(affinity_image);
8013 CatchException(exception);
8014 XSetCursorState(display,windows,MagickFalse);
8015 if (windows->image.orphan != MagickFalse)
8017 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8018 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8021 case QuantizeCommand:
8027 colors[MagickPathExtent] =
"256";
8032 status=XDialogWidget(display,windows,
"Quantize",
8033 "Maximum number of colors:",colors);
8034 if (*colors ==
'\0')
8039 XSetCursorState(display,windows,MagickTrue);
8040 XCheckRefreshWindows(display,windows);
8041 quantize_info.number_colors=StringToUnsignedLong(colors);
8042 quantize_info.dither_method=status != 0 ? RiemersmaDitherMethod :
8044 (void) QuantizeImage(&quantize_info,*image,exception);
8045 XSetCursorState(display,windows,MagickFalse);
8046 if (windows->image.orphan != MagickFalse)
8048 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8049 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8052 case DespeckleCommand:
8060 XSetCursorState(display,windows,MagickTrue);
8061 XCheckRefreshWindows(display,windows);
8062 despeckle_image=DespeckleImage(*image,exception);
8063 if (despeckle_image != (
Image *) NULL)
8065 *image=DestroyImage(*image);
8066 *image=despeckle_image;
8068 CatchException(exception);
8069 XSetCursorState(display,windows,MagickFalse);
8070 if (windows->image.orphan != MagickFalse)
8072 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8073 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8082 radius[MagickPathExtent] =
"0.0x1.0";
8087 (void) XDialogWidget(display,windows,
"Emboss",
8088 "Enter the emboss radius and standard deviation:",radius);
8089 if (*radius ==
'\0')
8094 XSetCursorState(display,windows,MagickTrue);
8095 XCheckRefreshWindows(display,windows);
8096 flags=ParseGeometry(radius,&geometry_info);
8097 if ((flags & SigmaValue) == 0)
8098 geometry_info.sigma=1.0;
8099 emboss_image=EmbossImage(*image,geometry_info.rho,geometry_info.sigma,
8101 if (emboss_image != (
Image *) NULL)
8103 *image=DestroyImage(*image);
8104 *image=emboss_image;
8106 CatchException(exception);
8107 XSetCursorState(display,windows,MagickFalse);
8108 if (windows->image.orphan != MagickFalse)
8110 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8111 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8114 case ReduceNoiseCommand:
8120 radius[MagickPathExtent] =
"0";
8125 (void) XDialogWidget(display,windows,
"Reduce Noise",
8126 "Enter the noise radius:",radius);
8127 if (*radius ==
'\0')
8132 XSetCursorState(display,windows,MagickTrue);
8133 XCheckRefreshWindows(display,windows);
8134 flags=ParseGeometry(radius,&geometry_info);
8135 noise_image=StatisticImage(*image,NonpeakStatistic,(
size_t)
8136 geometry_info.rho,(
size_t) geometry_info.rho,exception);
8137 if (noise_image != (
Image *) NULL)
8139 *image=DestroyImage(*image);
8142 CatchException(exception);
8143 XSetCursorState(display,windows,MagickFalse);
8144 if (windows->image.orphan != MagickFalse)
8146 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8147 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8150 case AddNoiseCommand:
8159 noise_type[MagickPathExtent] =
"Gaussian";
8164 noises=GetCommandOptions(MagickNoiseOptions);
8165 if (noises == (
char **) NULL)
8167 XListBrowserWidget(display,windows,&windows->widget,
8168 (
const char **) noises,
"Add Noise",
8169 "Select a type of noise to add to your image:",noise_type);
8170 noises=DestroyStringList(noises);
8171 if (*noise_type ==
'\0')
8173 XSetCursorState(display,windows,MagickTrue);
8174 XCheckRefreshWindows(display,windows);
8175 noise_image=AddNoiseImage(*image,(NoiseType) ParseCommandOption(
8176 MagickNoiseOptions,MagickFalse,noise_type),1.0,exception);
8177 if (noise_image != (
Image *) NULL)
8179 *image=DestroyImage(*image);
8182 CatchException(exception);
8183 XSetCursorState(display,windows,MagickFalse);
8184 if (windows->image.orphan != MagickFalse)
8186 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8187 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8190 case SharpenCommand:
8196 radius[MagickPathExtent] =
"0.0x1.0";
8201 (void) XDialogWidget(display,windows,
"Sharpen",
8202 "Enter the sharpen radius and standard deviation:",radius);
8203 if (*radius ==
'\0')
8208 XSetCursorState(display,windows,MagickTrue);
8209 XCheckRefreshWindows(display,windows);
8210 flags=ParseGeometry(radius,&geometry_info);
8211 sharp_image=SharpenImage(*image,geometry_info.rho,geometry_info.sigma,
8213 if (sharp_image != (
Image *) NULL)
8215 *image=DestroyImage(*image);
8218 CatchException(exception);
8219 XSetCursorState(display,windows,MagickFalse);
8220 if (windows->image.orphan != MagickFalse)
8222 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8223 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8232 radius[MagickPathExtent] =
"0.0x1.0";
8237 (void) XDialogWidget(display,windows,
"Blur",
8238 "Enter the blur radius and standard deviation:",radius);
8239 if (*radius ==
'\0')
8244 XSetCursorState(display,windows,MagickTrue);
8245 XCheckRefreshWindows(display,windows);
8246 flags=ParseGeometry(radius,&geometry_info);
8247 blur_image=BlurImage(*image,geometry_info.rho,geometry_info.sigma,
8249 if (blur_image != (
Image *) NULL)
8251 *image=DestroyImage(*image);
8254 CatchException(exception);
8255 XSetCursorState(display,windows,MagickFalse);
8256 if (windows->image.orphan != MagickFalse)
8258 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8259 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8262 case ThresholdCommand:
8268 factor[MagickPathExtent] =
"128";
8273 (void) XDialogWidget(display,windows,
"Threshold",
8274 "Enter threshold value:",factor);
8275 if (*factor ==
'\0')
8280 XSetCursorState(display,windows,MagickTrue);
8281 XCheckRefreshWindows(display,windows);
8282 threshold=StringToDoubleInterval(factor,(
double) QuantumRange+1.0);
8283 (void) BilevelImage(*image,threshold,exception);
8284 XSetCursorState(display,windows,MagickFalse);
8285 if (windows->image.orphan != MagickFalse)
8287 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8288 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8291 case EdgeDetectCommand:
8297 radius[MagickPathExtent] =
"0";
8302 (void) XDialogWidget(display,windows,
"Detect Edges",
8303 "Enter the edge detect radius:",radius);
8304 if (*radius ==
'\0')
8309 XSetCursorState(display,windows,MagickTrue);
8310 XCheckRefreshWindows(display,windows);
8311 flags=ParseGeometry(radius,&geometry_info);
8312 edge_image=EdgeImage(*image,geometry_info.rho,exception);
8313 if (edge_image != (
Image *) NULL)
8315 *image=DestroyImage(*image);
8318 CatchException(exception);
8319 XSetCursorState(display,windows,MagickFalse);
8320 if (windows->image.orphan != MagickFalse)
8322 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8323 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8332 amount[MagickPathExtent] =
"2";
8337 (void) XDialogWidget(display,windows,
"Spread",
8338 "Enter the displacement amount:",amount);
8339 if (*amount ==
'\0')
8344 XSetCursorState(display,windows,MagickTrue);
8345 XCheckRefreshWindows(display,windows);
8346 flags=ParseGeometry(amount,&geometry_info);
8347 spread_image=EdgeImage(*image,geometry_info.rho,exception);
8348 if (spread_image != (
Image *) NULL)
8350 *image=DestroyImage(*image);
8351 *image=spread_image;
8353 CatchException(exception);
8354 XSetCursorState(display,windows,MagickFalse);
8355 if (windows->image.orphan != MagickFalse)
8357 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8358 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8370 geometry[MagickPathExtent] =
"30x30";
8375 status=XDialogWidget(display,windows,
"Shade",
8376 "Enter the azimuth and elevation of the light source:",geometry);
8377 if (*geometry ==
'\0')
8382 XSetCursorState(display,windows,MagickTrue);
8383 XCheckRefreshWindows(display,windows);
8384 flags=ParseGeometry(geometry,&geometry_info);
8385 if ((flags & SigmaValue) == 0)
8386 geometry_info.sigma=1.0;
8387 shade_image=ShadeImage(*image,status != 0 ? MagickTrue : MagickFalse,
8388 geometry_info.rho,geometry_info.sigma,exception);
8389 if (shade_image != (
Image *) NULL)
8391 *image=DestroyImage(*image);
8394 CatchException(exception);
8395 XSetCursorState(display,windows,MagickFalse);
8396 if (windows->image.orphan != MagickFalse)
8398 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8399 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8405 bevel_width[MagickPathExtent] =
"10";
8410 (void) XDialogWidget(display,windows,
"Raise",
"Bevel width:",bevel_width);
8411 if (*bevel_width ==
'\0')
8416 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
8418 XSetCursorState(display,windows,MagickTrue);
8419 XCheckRefreshWindows(display,windows);
8420 (void) ParsePageGeometry(*image,bevel_width,&page_geometry,
8422 (void) RaiseImage(*image,&page_geometry,MagickTrue,exception);
8423 XSetCursorState(display,windows,MagickFalse);
8424 if (windows->image.orphan != MagickFalse)
8426 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8427 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8430 case SegmentCommand:
8433 threshold[MagickPathExtent] =
"1.0x1.5";
8438 (void) XDialogWidget(display,windows,
"Segment",
"Smooth threshold:",
8440 if (*threshold ==
'\0')
8445 XSetCursorState(display,windows,MagickTrue);
8446 XCheckRefreshWindows(display,windows);
8447 flags=ParseGeometry(threshold,&geometry_info);
8448 if ((flags & SigmaValue) == 0)
8449 geometry_info.sigma=1.0;
8450 (void) SegmentImage(*image,sRGBColorspace,MagickFalse,geometry_info.rho,
8451 geometry_info.sigma,exception);
8452 XSetCursorState(display,windows,MagickFalse);
8453 if (windows->image.orphan != MagickFalse)
8455 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8456 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8459 case SepiaToneCommand:
8468 factor[MagickPathExtent] =
"80%";
8473 (void) XDialogWidget(display,windows,
"Sepia Tone",
8474 "Enter the sepia tone factor (0 - 99.9%):",factor);
8475 if (*factor ==
'\0')
8480 XSetCursorState(display,windows,MagickTrue);
8481 XCheckRefreshWindows(display,windows);
8482 threshold=StringToDoubleInterval(factor,(
double) QuantumRange+1.0);
8483 sepia_image=SepiaToneImage(*image,threshold,exception);
8484 if (sepia_image != (
Image *) NULL)
8486 *image=DestroyImage(*image);
8489 CatchException(exception);
8490 XSetCursorState(display,windows,MagickFalse);
8491 if (windows->image.orphan != MagickFalse)
8493 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8494 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8497 case SolarizeCommand:
8503 factor[MagickPathExtent] =
"60%";
8508 (void) XDialogWidget(display,windows,
"Solarize",
8509 "Enter the solarize factor (0 - 99.9%):",factor);
8510 if (*factor ==
'\0')
8515 XSetCursorState(display,windows,MagickTrue);
8516 XCheckRefreshWindows(display,windows);
8517 threshold=StringToDoubleInterval(factor,(
double) QuantumRange+1.0);
8518 (void) SolarizeImage(*image,threshold,exception);
8519 XSetCursorState(display,windows,MagickFalse);
8520 if (windows->image.orphan != MagickFalse)
8522 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8523 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8532 degrees[MagickPathExtent] =
"60";
8537 (void) XDialogWidget(display,windows,
"Swirl",
"Enter the swirl angle:",
8539 if (*degrees ==
'\0')
8544 XSetCursorState(display,windows,MagickTrue);
8545 XCheckRefreshWindows(display,windows);
8546 flags=ParseGeometry(degrees,&geometry_info);
8547 swirl_image=SwirlImage(*image,geometry_info.rho,(*image)->interpolate,
8549 if (swirl_image != (
Image *) NULL)
8551 *image=DestroyImage(*image);
8554 CatchException(exception);
8555 XSetCursorState(display,windows,MagickFalse);
8556 if (windows->image.orphan != MagickFalse)
8558 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8559 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8562 case ImplodeCommand:
8568 factor[MagickPathExtent] =
"0.3";
8573 (void) XDialogWidget(display,windows,
"Implode",
8574 "Enter the implosion/explosion factor (-1.0 - 1.0):",factor);
8575 if (*factor ==
'\0')
8580 XSetCursorState(display,windows,MagickTrue);
8581 XCheckRefreshWindows(display,windows);
8582 flags=ParseGeometry(factor,&geometry_info);
8583 implode_image=ImplodeImage(*image,geometry_info.rho,(*image)->interpolate,
8585 if (implode_image != (
Image *) NULL)
8587 *image=DestroyImage(*image);
8588 *image=implode_image;
8590 CatchException(exception);
8591 XSetCursorState(display,windows,MagickFalse);
8592 if (windows->image.orphan != MagickFalse)
8594 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8595 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8598 case VignetteCommand:
8604 geometry[MagickPathExtent] =
"0x20";
8609 (void) XDialogWidget(display,windows,
"Vignette",
8610 "Enter the radius, sigma, and x and y offsets:",geometry);
8611 if (*geometry ==
'\0')
8616 XSetCursorState(display,windows,MagickTrue);
8617 XCheckRefreshWindows(display,windows);
8618 flags=ParseGeometry(geometry,&geometry_info);
8619 if ((flags & SigmaValue) == 0)
8620 geometry_info.sigma=1.0;
8621 if ((flags & XiValue) == 0)
8622 geometry_info.xi=0.1*(*image)->columns;
8623 if ((flags & PsiValue) == 0)
8624 geometry_info.psi=0.1*(*image)->rows;
8625 vignette_image=VignetteImage(*image,geometry_info.rho,0.0,(ssize_t)
8626 ceil(geometry_info.xi-0.5),(ssize_t) ceil(geometry_info.psi-0.5),
8628 if (vignette_image != (
Image *) NULL)
8630 *image=DestroyImage(*image);
8631 *image=vignette_image;
8633 CatchException(exception);
8634 XSetCursorState(display,windows,MagickFalse);
8635 if (windows->image.orphan != MagickFalse)
8637 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8638 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8647 geometry[MagickPathExtent] =
"25x150";
8652 (void) XDialogWidget(display,windows,
"Wave",
8653 "Enter the amplitude and length of the wave:",geometry);
8654 if (*geometry ==
'\0')
8659 XSetCursorState(display,windows,MagickTrue);
8660 XCheckRefreshWindows(display,windows);
8661 flags=ParseGeometry(geometry,&geometry_info);
8662 if ((flags & SigmaValue) == 0)
8663 geometry_info.sigma=1.0;
8664 wave_image=WaveImage(*image,geometry_info.rho,geometry_info.sigma,
8665 (*image)->interpolate,exception);
8666 if (wave_image != (
Image *) NULL)
8668 *image=DestroyImage(*image);
8671 CatchException(exception);
8672 XSetCursorState(display,windows,MagickFalse);
8673 if (windows->image.orphan != MagickFalse)
8675 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8676 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8679 case OilPaintCommand:
8685 radius[MagickPathExtent] =
"0";
8690 (void) XDialogWidget(display,windows,
"Oil Paint",
8691 "Enter the mask radius:",radius);
8692 if (*radius ==
'\0')
8697 XSetCursorState(display,windows,MagickTrue);
8698 XCheckRefreshWindows(display,windows);
8699 flags=ParseGeometry(radius,&geometry_info);
8700 paint_image=OilPaintImage(*image,geometry_info.rho,geometry_info.sigma,
8702 if (paint_image != (
Image *) NULL)
8704 *image=DestroyImage(*image);
8707 CatchException(exception);
8708 XSetCursorState(display,windows,MagickFalse);
8709 if (windows->image.orphan != MagickFalse)
8711 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8712 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8715 case CharcoalDrawCommand:
8721 radius[MagickPathExtent] =
"0x1";
8726 (void) XDialogWidget(display,windows,
"Charcoal Draw",
8727 "Enter the charcoal radius and sigma:",radius);
8728 if (*radius ==
'\0')
8733 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
8735 XSetCursorState(display,windows,MagickTrue);
8736 XCheckRefreshWindows(display,windows);
8737 flags=ParseGeometry(radius,&geometry_info);
8738 if ((flags & SigmaValue) == 0)
8739 geometry_info.sigma=geometry_info.rho;
8740 charcoal_image=CharcoalImage(*image,geometry_info.rho,geometry_info.sigma,
8742 if (charcoal_image != (
Image *) NULL)
8744 *image=DestroyImage(*image);
8745 *image=charcoal_image;
8747 CatchException(exception);
8748 XSetCursorState(display,windows,MagickFalse);
8749 if (windows->image.orphan != MagickFalse)
8751 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8752 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8755 case AnnotateCommand:
8760 status=XAnnotateEditImage(display,resource_info,windows,*image,exception);
8761 if (status == MagickFalse)
8763 XNoticeWidget(display,windows,
"Unable to annotate X image",
8764 (*image)->filename);
8774 status=XDrawEditImage(display,resource_info,windows,image,exception);
8775 if (status == MagickFalse)
8777 XNoticeWidget(display,windows,
"Unable to draw on the X image",
8778 (*image)->filename);
8788 status=XColorEditImage(display,resource_info,windows,image,exception);
8789 if (status == MagickFalse)
8791 XNoticeWidget(display,windows,
"Unable to pixel edit X image",
8792 (*image)->filename);
8802 status=XMatteEditImage(display,resource_info,windows,image,exception);
8803 if (status == MagickFalse)
8805 XNoticeWidget(display,windows,
"Unable to matte edit X image",
8806 (*image)->filename);
8811 case CompositeCommand:
8816 status=XCompositeImage(display,resource_info,windows,*image,
8818 if (status == MagickFalse)
8820 XNoticeWidget(display,windows,
"Unable to composite X image",
8821 (*image)->filename);
8826 case AddBorderCommand:
8832 geometry[MagickPathExtent] =
"6x6";
8837 XColorBrowserWidget(display,windows,
"Select",color);
8840 (void) XDialogWidget(display,windows,
"Add Border",
8841 "Enter border geometry:",geometry);
8842 if (*geometry ==
'\0')
8847 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
8849 XSetCursorState(display,windows,MagickTrue);
8850 XCheckRefreshWindows(display,windows);
8851 (void) QueryColorCompliance(color,AllCompliance,&(*image)->border_color,
8853 (void) ParsePageGeometry(*image,geometry,&page_geometry,
8855 border_image=BorderImage(*image,&page_geometry,(*image)->compose,
8857 if (border_image != (
Image *) NULL)
8859 *image=DestroyImage(*image);
8860 *image=border_image;
8862 CatchException(exception);
8863 XSetCursorState(display,windows,MagickFalse);
8864 if (windows->image.orphan != MagickFalse)
8866 windows->image.window_changes.width=(int) (*image)->columns;
8867 windows->image.window_changes.height=(int) (*image)->rows;
8868 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8869 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8872 case AddFrameCommand:
8881 geometry[MagickPathExtent] =
"6x6";
8886 XColorBrowserWidget(display,windows,
"Select",color);
8889 (void) XDialogWidget(display,windows,
"Add Frame",
"Enter frame geometry:",
8891 if (*geometry ==
'\0')
8896 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
8898 XSetCursorState(display,windows,MagickTrue);
8899 XCheckRefreshWindows(display,windows);
8900 (void) QueryColorCompliance(color,AllCompliance,&(*image)->matte_color,
8902 (void) ParsePageGeometry(*image,geometry,&page_geometry,
8904 frame_info.width=page_geometry.width;
8905 frame_info.height=page_geometry.height;
8906 frame_info.outer_bevel=page_geometry.x;
8907 frame_info.inner_bevel=page_geometry.y;
8908 frame_info.x=(ssize_t) frame_info.width;
8909 frame_info.y=(ssize_t) frame_info.height;
8910 frame_info.width=(*image)->columns+2*frame_info.width;
8911 frame_info.height=(*image)->rows+2*frame_info.height;
8912 frame_image=FrameImage(*image,&frame_info,(*image)->compose,exception);
8913 if (frame_image != (
Image *) NULL)
8915 *image=DestroyImage(*image);
8918 CatchException(exception);
8919 XSetCursorState(display,windows,MagickFalse);
8920 if (windows->image.orphan != MagickFalse)
8922 windows->image.window_changes.width=(int) (*image)->columns;
8923 windows->image.window_changes.height=(int) (*image)->rows;
8924 XConfigureImageColormap(display,resource_info,windows,*image,exception);
8925 (void) XConfigureImage(display,resource_info,windows,*image,exception);
8928 case CommentCommand:
8942 unique_file=AcquireUniqueFileResource(image_info->filename);
8943 if (unique_file == -1)
8945 XNoticeWidget(display,windows,
"Unable to edit image comment",
8946 image_info->filename);
8949 value=GetImageProperty(*image,
"comment",exception);
8950 if (value == (
char *) NULL)
8951 unique_file=close(unique_file)-1;
8957 file=fdopen(unique_file,
"w");
8958 if (file == (FILE *) NULL)
8960 XNoticeWidget(display,windows,
"Unable to edit image comment",
8961 image_info->filename);
8964 for (p=value; *p !=
'\0'; p++)
8965 (
void) fputc((
int) *p,file);
8966 (void) fputc(
'\n',file);
8967 (void) fclose(file);
8969 XSetCursorState(display,windows,MagickTrue);
8970 XCheckRefreshWindows(display,windows);
8971 status=InvokeDelegate(image_info,*image,
"edit",(
char *) NULL,
8973 if (status == MagickFalse)
8974 XNoticeWidget(display,windows,
"Unable to edit image comment",
8981 comment=FileToString(image_info->filename,~0UL,exception);
8982 if (comment != (
char *) NULL)
8984 (void) SetImageProperty(*image,
"comment",comment,exception);
8985 (*image)->taint=MagickTrue;
8988 (void) RelinquishUniqueFileResource(image_info->filename);
8989 XSetCursorState(display,windows,MagickFalse);
8997 XSetCursorState(display,windows,MagickTrue);
8998 XCheckRefreshWindows(display,windows);
8999 (void) AcquireUniqueFilename(filename);
9000 (void) FormatLocaleString((*image)->filename,MagickPathExtent,
"launch:%s",
9002 status=WriteImage(image_info,*image,exception);
9003 if (status == MagickFalse)
9004 XNoticeWidget(display,windows,
"Unable to launch image editor",
9008 nexus=ReadImage(resource_info->image_info,exception);
9009 CatchException(exception);
9010 XClientMessage(display,windows->image.id,windows->im_protocols,
9011 windows->im_next_image,CurrentTime);
9013 (void) RelinquishUniqueFileResource(filename);
9014 XSetCursorState(display,windows,MagickFalse);
9017 case RegionOfInterestCommand:
9022 (void) XROIImage(display,resource_info,windows,image,exception);
9032 if (windows->magnify.mapped != MagickFalse)
9033 (void) XRaiseWindow(display,windows->magnify.id);
9039 XSetCursorState(display,windows,MagickTrue);
9040 (void) XMapRaised(display,windows->magnify.id);
9041 XSetCursorState(display,windows,MagickFalse);
9045 case ShowPreviewCommand:
9057 preview_type[MagickPathExtent] =
"Gamma";
9062 previews=GetCommandOptions(MagickPreviewOptions);
9063 if (previews == (
char **) NULL)
9065 XListBrowserWidget(display,windows,&windows->widget,
9066 (
const char **) previews,
"Preview",
9067 "Select an enhancement, effect, or F/X:",preview_type);
9068 previews=DestroyStringList(previews);
9069 if (*preview_type ==
'\0')
9074 XSetCursorState(display,windows,MagickTrue);
9075 XCheckRefreshWindows(display,windows);
9076 preview=(PreviewType) ParseCommandOption(MagickPreviewOptions,
9077 MagickFalse,preview_type);
9078 (void) FormatImageProperty(*image,
"group",
"%.20g",(
double)
9080 (void) DeleteImageProperty(*image,
"label");
9081 (void) SetImageProperty(*image,
"label",
"Preview",exception);
9082 preview_image=PreviewImage(*image,preview,exception);
9083 if (preview_image == (
Image *) NULL)
9085 (void) AcquireUniqueFilename(filename);
9086 (void) FormatLocaleString(preview_image->filename,MagickPathExtent,
9087 "show:%s",filename);
9088 status=WriteImage(image_info,preview_image,exception);
9089 (void) RelinquishUniqueFileResource(filename);
9090 preview_image=DestroyImage(preview_image);
9091 if (status == MagickFalse)
9092 XNoticeWidget(display,windows,
"Unable to show image preview",
9093 (*image)->filename);
9094 XDelay(display,1500);
9095 XSetCursorState(display,windows,MagickFalse);
9098 case ShowHistogramCommand:
9106 XSetCursorState(display,windows,MagickTrue);
9107 XCheckRefreshWindows(display,windows);
9108 (void) DeleteImageProperty(*image,
"label");
9109 (void) FormatImageProperty(*image,
"group",
"%.20g",(
double)
9111 (void) SetImageProperty(*image,
"label",
"Histogram",exception);
9112 (void) AcquireUniqueFilename(filename);
9113 (void) FormatLocaleString((*image)->filename,MagickPathExtent,
9114 "histogram:%s",filename);
9115 status=WriteImage(image_info,*image,exception);
9116 (void) CopyMagickString(image_info->filename,filename,MagickPathExtent);
9117 histogram_image=ReadImage(image_info,exception);
9118 (void) RelinquishUniqueFileResource(filename);
9119 if (histogram_image == (
Image *) NULL)
9121 (void) FormatLocaleString(histogram_image->filename,MagickPathExtent,
9122 "show:%s",filename);
9123 status=WriteImage(image_info,histogram_image,exception);
9124 histogram_image=DestroyImage(histogram_image);
9125 if (status == MagickFalse)
9126 XNoticeWidget(display,windows,
"Unable to show histogram",
9127 (*image)->filename);
9128 XDelay(display,1500);
9129 XSetCursorState(display,windows,MagickFalse);
9132 case ShowMatteCommand:
9137 if ((*image)->alpha_trait == UndefinedPixelTrait)
9139 XNoticeWidget(display,windows,
9140 "Image does not have any matte information",(*image)->filename);
9146 XSetCursorState(display,windows,MagickTrue);
9147 XCheckRefreshWindows(display,windows);
9148 (void) FormatImageProperty(*image,
"group",
"%.20g",(
double)
9150 (void) DeleteImageProperty(*image,
"label");
9151 (void) SetImageProperty(*image,
"label",
"Matte",exception);
9152 (void) AcquireUniqueFilename(filename);
9153 (void) FormatLocaleString((*image)->filename,MagickPathExtent,
"matte:%s",
9155 status=WriteImage(image_info,*image,exception);
9156 (void) CopyMagickString(image_info->filename,filename,MagickPathExtent);
9157 matte_image=ReadImage(image_info,exception);
9158 (void) RelinquishUniqueFileResource(filename);
9159 if (matte_image == (
Image *) NULL)
9161 (void) FormatLocaleString(matte_image->filename,MagickPathExtent,
9162 "show:%s",filename);
9163 status=WriteImage(image_info,matte_image,exception);
9164 matte_image=DestroyImage(matte_image);
9165 if (status == MagickFalse)
9166 XNoticeWidget(display,windows,
"Unable to show matte",
9167 (*image)->filename);
9168 XDelay(display,1500);
9169 XSetCursorState(display,windows,MagickFalse);
9172 case BackgroundCommand:
9177 status=XBackgroundImage(display,resource_info,windows,image,exception);
9178 if (status == MagickFalse)
9180 nexus=CloneImage(*image,0,0,MagickTrue,exception);
9181 if (nexus != (
Image *) NULL)
9182 XClientMessage(display,windows->image.id,windows->im_protocols,
9183 windows->im_next_image,CurrentTime);
9186 case SlideShowCommand:
9189 delay[MagickPathExtent] =
"5";
9194 (void) XDialogWidget(display,windows,
"Slide Show",
9195 "Pause how many 1/100ths of a second between images:",delay);
9198 resource_info->delay=StringToUnsignedLong(delay);
9199 XClientMessage(display,windows->image.id,windows->im_protocols,
9200 windows->im_next_image,CurrentTime);
9203 case PreferencesCommand:
9208 status=XPreferencesWidget(display,resource_info,windows);
9209 if (status == MagickFalse)
9211 nexus=CloneImage(*image,0,0,MagickTrue,exception);
9212 if (nexus != (
Image *) NULL)
9213 XClientMessage(display,windows->image.id,windows->im_protocols,
9214 windows->im_next_image,CurrentTime);
9222 XTextViewHelp(display,resource_info,windows,MagickFalse,
9223 "Help Viewer - Display",DisplayHelp);
9226 case BrowseDocumentationCommand:
9238 root_window=XRootWindow(display,XDefaultScreen(display));
9239 mozilla_atom=XInternAtom(display,
"_MOZILLA_VERSION",MagickFalse);
9240 mozilla_window=XWindowByProperty(display,root_window,mozilla_atom);
9241 if (mozilla_window != (Window) NULL)
9244 command[MagickPathExtent];
9249 (void) FormatLocaleString(command,MagickPathExtent,
9250 "openurl(%s,new-tab)",MagickAuthoritativeURL);
9251 mozilla_atom=XInternAtom(display,
"_MOZILLA_COMMAND",MagickFalse);
9252 (void) XChangeProperty(display,mozilla_window,mozilla_atom,XA_STRING,
9253 8,PropModeReplace,(
unsigned char *) command,(int) strlen(command));
9254 XSetCursorState(display,windows,MagickFalse);
9257 XSetCursorState(display,windows,MagickTrue);
9258 XCheckRefreshWindows(display,windows);
9259 status=InvokeDelegate(image_info,*image,
"browse",(
char *) NULL,
9261 if (status == MagickFalse)
9262 XNoticeWidget(display,windows,
"Unable to browse documentation",
9264 XDelay(display,1500);
9265 XSetCursorState(display,windows,MagickFalse);
9268 case VersionCommand:
9270 XNoticeWidget(display,windows,GetMagickVersion((
size_t *) NULL),
9271 GetMagickCopyright());
9274 case SaveToUndoBufferCommand:
9278 (void) XBell(display,0);
9282 image_info=DestroyImageInfo(image_info);
9318static void XMagnifyImage(Display *display,XWindows *windows,XEvent *event,
9322 text[MagickPathExtent];
9334 (void) XCheckDefineCursor(display,windows->image.id,windows->magnify.cursor);
9338 windows->magnify.x=(int) windows->image.x+x;
9339 windows->magnify.y=(int) windows->image.y+y;
9345 if (windows->info.mapped != MagickFalse)
9347 if ((x < (windows->info.x+(
int) windows->info.width)) &&
9348 (y < (windows->info.y+(
int) windows->info.height)))
9349 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
9352 if ((x > (windows->info.x+(
int) windows->info.width)) ||
9353 (y > (windows->info.y+(int) windows->info.height)))
9354 (void) XMapWindow(display,windows->info.id);
9355 if (windows->info.mapped != MagickFalse)
9360 (void) FormatLocaleString(text,MagickPathExtent,
" %+d%+d ",
9361 windows->magnify.x,windows->magnify.y);
9362 XInfoWidget(display,windows,text);
9367 XScreenEvent(display,windows,event,exception);
9368 switch (event->type)
9399 if (x >= (
int) windows->image.width)
9400 x=(int) windows->image.width-1;
9404 if (y >= (
int) windows->image.height)
9405 y=(int) windows->image.height-1;
9406 }
while ((state & ExitState) == 0);
9410 XSetCursorState(display,windows,MagickFalse);
9448static void XMagnifyWindowCommand(Display *display,XWindows *windows,
9449 const MagickStatusType state,
const KeySym key_symbol,
ExceptionInfo *exception)
9458 if ((state & Mod1Mask) != 0)
9460 switch ((
int) key_symbol)
9464 (void) XWithdrawWindow(display,windows->magnify.id,
9465 windows->magnify.screen);
9471 windows->magnify.x=(int) windows->image.width/2;
9472 windows->magnify.y=(int) windows->image.height/2;
9478 if (windows->magnify.x > 0)
9479 windows->magnify.x-=(int) quantum;
9485 if (windows->magnify.y > 0)
9486 windows->magnify.y-=(int) quantum;
9492 if (windows->magnify.x < (
int) (windows->image.ximage->width-1))
9493 windows->magnify.x+=(int) quantum;
9499 if (windows->magnify.y < (
int) (windows->image.ximage->height-1))
9500 windows->magnify.y+=(int) quantum;
9514 windows->magnify.data=(key_symbol-XK_0);
9528 windows->magnify.data=(key_symbol-XK_KP_0);
9534 XMakeMagnifyImage(display,windows,exception);
9570static void XMakePanImage(Display *display,XResourceInfo *resource_info,
9579 XSetCursorState(display,windows,MagickTrue);
9580 XCheckRefreshWindows(display,windows);
9581 windows->pan.x=(int) windows->image.x;
9582 windows->pan.y=(int) windows->image.y;
9583 status=XMakeImage(display,resource_info,&windows->pan,image,
9584 windows->pan.width,windows->pan.height,exception);
9585 if (status == MagickFalse)
9586 ThrowXWindowException(ResourceLimitError,
9587 "MemoryAllocationFailed",image->filename);
9588 (void) XSetWindowBackgroundPixmap(display,windows->pan.id,
9589 windows->pan.pixmap);
9590 (void) XClearWindow(display,windows->pan.id);
9591 XDrawPanRectangle(display,windows);
9592 XSetCursorState(display,windows,MagickFalse);
9630static MagickBooleanType XMatteEditImage(Display *display,
9631 XResourceInfo *resource_info,XWindows *windows,
Image **image,
9635 *
const MatteEditMenu[] =
9648 matte[MagickPathExtent] =
"0";
9650 static const ModeType
9651 MatteEditCommands[] =
9654 MatteEditBorderCommand,
9655 MatteEditFuzzCommand,
9656 MatteEditValueCommand,
9657 MatteEditUndoCommand,
9658 MatteEditHelpCommand,
9659 MatteEditDismissCommand
9663 method = PointMethod;
9666 border_color = { 0, 0, 0, 0, 0, 0 };
9669 command[MagickPathExtent],
9670 text[MagickPathExtent];
9702 (void) CloneString(&windows->command.name,
"Matte Edit");
9703 windows->command.data=4;
9704 (void) XCommandWidget(display,windows,MatteEditMenu,(XEvent *) NULL);
9705 (void) XMapRaised(display,windows->command.id);
9706 XClientMessage(display,windows->image.id,windows->im_protocols,
9707 windows->im_update_widget,CurrentTime);
9711 cursor=XMakeCursor(display,windows->image.id,windows->map_info->colormap,
9712 resource_info->background_color,resource_info->foreground_color);
9713 (void) XCheckDefineCursor(display,windows->image.id,cursor);
9717 XQueryPosition(display,windows->image.id,&x,&y);
9718 (void) XSelectInput(display,windows->image.id,
9719 windows->image.attributes.event_mask | PointerMotionMask);
9723 if (windows->info.mapped != MagickFalse)
9728 (void) FormatLocaleString(text,MagickPathExtent,
" %+d%+d ",
9729 x+windows->image.x,y+windows->image.y);
9730 XInfoWidget(display,windows,text);
9735 XScreenEvent(display,windows,&event,exception);
9736 if (event.xany.window == windows->command.id)
9741 id=XCommandWidget(display,windows,MatteEditMenu,&event);
9744 (void) XCheckDefineCursor(display,windows->image.id,cursor);
9747 switch (MatteEditCommands[
id])
9749 case MatteEditMethod:
9757 methods=GetCommandOptions(MagickMethodOptions);
9758 if (methods == (
char **) NULL)
9760 entry=XMenuWidget(display,windows,MatteEditMenu[
id],
9761 (
const char **) methods,command);
9763 method=(PaintMethod) ParseCommandOption(MagickMethodOptions,
9764 MagickFalse,methods[entry]);
9765 methods=DestroyStringList(methods);
9768 case MatteEditBorderCommand:
9771 *ColorMenu[MaxNumberPens];
9779 for (i=0; i < (int) (MaxNumberPens-2); i++)
9780 ColorMenu[i]=resource_info->pen_colors[i];
9781 ColorMenu[MaxNumberPens-2]=
"Browser...";
9782 ColorMenu[MaxNumberPens-1]=(
const char *) NULL;
9786 pen_number=XMenuWidget(display,windows,MatteEditMenu[
id],
9787 (
const char **) ColorMenu,command);
9790 if (pen_number == (MaxNumberPens-2))
9793 color_name[MagickPathExtent] =
"gray";
9798 resource_info->pen_colors[pen_number]=color_name;
9799 XColorBrowserWidget(display,windows,
"Select",color_name);
9800 if (*color_name ==
'\0')
9806 (void) XParseColor(display,windows->map_info->colormap,
9807 resource_info->pen_colors[pen_number],&border_color);
9810 case MatteEditFuzzCommand:
9825 fuzz[MagickPathExtent];
9830 entry=XMenuWidget(display,windows,MatteEditMenu[
id],FuzzMenu,
9836 (*image)->fuzz=StringToDoubleInterval(FuzzMenu[entry],(
double)
9840 (void) CopyMagickString(fuzz,
"20%",MagickPathExtent);
9841 (void) XDialogWidget(display,windows,
"Ok",
9842 "Enter fuzz factor (0.0 - 99.9%):",fuzz);
9845 (void) ConcatenateMagickString(fuzz,
"%",MagickPathExtent);
9846 (*image)->fuzz=StringToDoubleInterval(fuzz,(
double) QuantumRange+
9850 case MatteEditValueCommand:
9853 *
const MatteMenu[] =
9862 message[MagickPathExtent];
9867 entry=XMenuWidget(display,windows,MatteEditMenu[
id],MatteMenu,
9873 (void) FormatLocaleString(matte,MagickPathExtent,
"%g",
9874 (
double) OpaqueAlpha);
9875 if (LocaleCompare(MatteMenu[entry],
"Transparent") == 0)
9876 (
void) FormatLocaleString(matte,MagickPathExtent,
"%g",
9877 (
double) TransparentAlpha);
9880 (void) FormatLocaleString(message,MagickPathExtent,
9881 "Enter matte value (0 - " "%g" "):",(
double) QuantumRange);
9882 (void) XDialogWidget(display,windows,
"Matte",message,matte);
9887 case MatteEditUndoCommand:
9889 (void) XMagickCommand(display,resource_info,windows,UndoCommand,
9893 case MatteEditHelpCommand:
9895 XTextViewHelp(display,resource_info,windows,MagickFalse,
9896 "Help Viewer - Matte Edit",ImageMatteEditHelp);
9899 case MatteEditDismissCommand:
9911 (void) XCheckDefineCursor(display,windows->image.id,cursor);
9918 if (event.xbutton.button != Button1)
9920 if ((event.xbutton.window != windows->image.id) &&
9921 (
event.xbutton.window != windows->magnify.id))
9928 (void) XMagickCommand(display,resource_info,windows,
9929 SaveToUndoBufferCommand,image,exception);
9930 state|=UpdateConfigurationState;
9935 if (event.xbutton.button != Button1)
9937 if ((event.xbutton.window != windows->image.id) &&
9938 (
event.xbutton.window != windows->magnify.id))
9945 XConfigureImageColormap(display,resource_info,windows,*image,exception);
9946 (void) XConfigureImage(display,resource_info,windows,*image,exception);
9947 XInfoWidget(display,windows,text);
9948 (void) XCheckDefineCursor(display,windows->image.id,cursor);
9949 state&=(
unsigned int) (~UpdateConfigurationState);
9957 command[MagickPathExtent];
9962 if (event.xkey.window == windows->magnify.id)
9967 window=windows->magnify.id;
9968 while (XCheckWindowEvent(display,window,KeyPressMask,&event)) ;
9970 if (event.xkey.window != windows->image.id)
9975 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
9976 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
9977 switch ((
int) key_symbol)
9991 XTextViewHelp(display,resource_info,windows,MagickFalse,
9992 "Help Viewer - Matte Edit",ImageMatteEditHelp);
9997 (void) XBell(display,0);
10010 if (windows->info.mapped != MagickFalse)
10012 if ((x < (windows->info.x+(
int) windows->info.width)) &&
10013 (y < (windows->info.y+(int) windows->info.height)))
10014 (void) XWithdrawWindow(display,windows->info.id,
10015 windows->info.screen);
10018 if ((x > (windows->info.x+(
int) windows->info.width)) ||
10019 (y > (windows->info.y+(int) windows->info.height)))
10020 (void) XMapWindow(display,windows->info.id);
10026 if (event.xany.window == windows->magnify.id)
10028 x=windows->magnify.x-windows->image.x;
10029 y=windows->magnify.y-windows->image.y;
10033 if ((state & UpdateConfigurationState) != 0)
10045 (void) XClearArea(display,windows->image.id,x_offset,y_offset,1,1,
10047 XPutPixel(windows->image.ximage,x_offset,y_offset,
10048 windows->pixel_info->background_color.pixel);
10049 width=(
unsigned int) (*image)->columns;
10050 height=(
unsigned int) (*image)->rows;
10053 if (windows->image.crop_geometry != (
char *) NULL)
10054 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,
10056 x_offset=((int) width*(windows->image.x+x_offset)/
10057 windows->image.ximage->width+x);
10058 y_offset=((int) height*(windows->image.y+y_offset)/
10059 windows->image.ximage->height+y);
10060 if ((x_offset < 0) || (y_offset < 0))
10062 if ((x_offset >= (
int) (*image)->columns) ||
10063 (y_offset >= (
int) (*image)->rows))
10065 if (SetImageStorageClass(*image,DirectClass,exception) == MagickFalse)
10066 return(MagickFalse);
10067 if ((*image)->alpha_trait == UndefinedPixelTrait)
10068 (void) SetImageAlphaChannel(*image,OpaqueAlphaChannel,exception);
10069 image_view=AcquireAuthenticCacheView(*image,exception);
10078 q=GetCacheViewAuthenticPixels(image_view,(ssize_t) x_offset,
10079 (ssize_t) y_offset,1,1,exception);
10080 if (q == (Quantum *) NULL)
10082 SetPixelAlpha(*image,(Quantum) StringToLong(matte),q);
10083 (void) SyncCacheViewAuthenticPixels(image_view,exception);
10086 case ReplaceMethod:
10095 (void) GetOneCacheViewVirtualPixelInfo(image_view,(ssize_t)
10096 x_offset,(ssize_t) y_offset,&target,exception);
10097 for (y=0; y < (int) (*image)->rows; y++)
10099 q=GetCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
10100 (*image)->columns,1,exception);
10101 if (q == (Quantum *) NULL)
10103 for (x=0; x < (int) (*image)->columns; x++)
10105 GetPixelInfoPixel(*image,q,&pixel);
10106 if (IsFuzzyEquivalencePixelInfo(&pixel,&target))
10107 SetPixelAlpha(*image,(Quantum) StringToLong(matte),q);
10108 q+=GetPixelChannels(*image);
10110 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
10115 case FloodfillMethod:
10116 case FillToBorderMethod:
10130 (void) GetOneVirtualPixelInfo(*image,
10131 GetPixelCacheVirtualMethod(*image),(ssize_t) x_offset,(ssize_t)
10132 y_offset,&target,exception);
10133 if (method == FillToBorderMethod)
10135 target.red=(double) ScaleShortToQuantum(
10137 target.green=(double) ScaleShortToQuantum(
10138 border_color.green);
10139 target.blue=(double) ScaleShortToQuantum(
10140 border_color.blue);
10142 draw_info=CloneDrawInfo(resource_info->image_info,
10144 draw_info->fill.alpha=(double) ClampToQuantum(
10145 StringToDouble(matte,(
char **) NULL));
10146 channel_mask=SetImageChannelMask(*image,AlphaChannel);
10147 (void) FloodfillPaintImage(*image,draw_info,&target,(ssize_t)
10148 x_offset,(ssize_t) y_offset,
10149 method != FloodfillMethod ? MagickTrue : MagickFalse,exception);
10150 (void) SetPixelChannelMask(*image,channel_mask);
10151 draw_info=DestroyDrawInfo(draw_info);
10159 if (SetImageStorageClass(*image,DirectClass,exception) == MagickFalse)
10160 return(MagickFalse);
10161 for (y=0; y < (int) (*image)->rows; y++)
10163 q=QueueCacheViewAuthenticPixels(image_view,0,(ssize_t) y,
10164 (*image)->columns,1,exception);
10165 if (q == (Quantum *) NULL)
10167 for (x=0; x < (int) (*image)->columns; x++)
10169 SetPixelAlpha(*image,(Quantum) StringToLong(matte),q);
10170 q+=GetPixelChannels(*image);
10172 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
10175 if (StringToLong(matte) == (
long) OpaqueAlpha)
10176 (*image)->alpha_trait=UndefinedPixelTrait;
10180 image_view=DestroyCacheView(image_view);
10181 state&=(
unsigned int) (~UpdateConfigurationState);
10183 }
while ((state & ExitState) == 0);
10184 (void) XSelectInput(display,windows->image.id,
10185 windows->image.attributes.event_mask);
10186 XSetCursorState(display,windows,MagickFalse);
10187 (void) XFreeCursor(display,cursor);
10188 return(MagickTrue);
10222static Image *XOpenImage(Display *display,XResourceInfo *resource_info,
10223 XWindows *windows,
const MagickBooleanType command)
10238 filename[MagickPathExtent] =
"\0";
10243 if (command == MagickFalse)
10244 XFileBrowserWidget(display,windows,
"Open",filename);
10262 status=XGetCommand(display,windows->image.id,&files,&count);
10265 ThrowXWindowException(XServerError,
"UnableToGetProperty",
"...");
10266 return((
Image *) NULL);
10268 filelist=(
char **) AcquireQuantumMemory((
size_t) count,
sizeof(*filelist));
10269 if (filelist == (
char **) NULL)
10271 ThrowXWindowException(ResourceLimitError,
10272 "MemoryAllocationFailed",
"...");
10273 (void) XFreeStringList(files);
10274 return((
Image *) NULL);
10277 for (i=1; i < count; i++)
10278 if (*files[i] !=
'-')
10279 filelist[j++]=files[i];
10280 filelist[j]=(
char *) NULL;
10281 XListBrowserWidget(display,windows,&windows->widget,
10282 (
const char **) filelist,
"Load",
"Select Image to Load:",filename);
10283 filelist=(
char **) RelinquishMagickMemory(filelist);
10284 (void) XFreeStringList(files);
10286 if (*filename ==
'\0')
10287 return((
Image *) NULL);
10288 image_info=CloneImageInfo(resource_info->image_info);
10289 (void) SetImageInfoProgressMonitor(image_info,(MagickProgressMonitor) NULL,
10291 (void) CopyMagickString(image_info->filename,filename,MagickPathExtent);
10292 exception=AcquireExceptionInfo();
10293 (void) SetImageInfo(image_info,0,exception);
10294 if (LocaleCompare(image_info->magick,
"X") == 0)
10297 seconds[MagickPathExtent];
10302 (void) CopyMagickString(seconds,
"0",MagickPathExtent);
10303 (void) XDialogWidget(display,windows,
"Grab",
"Enter any delay in seconds:",
10305 if (*seconds ==
'\0')
10306 return((
Image *) NULL);
10307 XDelay(display,(
size_t) (1000*StringToLong(seconds)));
10309 magick_info=GetMagickInfo(image_info->magick,exception);
10310 if ((magick_info != (
const MagickInfo *) NULL) &&
10311 GetMagickRawSupport(magick_info) == MagickTrue)
10314 geometry[MagickPathExtent];
10319 (void) CopyMagickString(geometry,
"512x512",MagickPathExtent);
10320 if (image_info->size != (
char *) NULL)
10321 (
void) CopyMagickString(geometry,image_info->size,MagickPathExtent);
10322 (void) XDialogWidget(display,windows,
"Load",
"Enter the image geometry:",
10324 (void) CloneString(&image_info->size,geometry);
10329 XSetCursorState(display,windows,MagickTrue);
10330 XCheckRefreshWindows(display,windows);
10331 (void) CopyMagickString(image_info->filename,filename,MagickPathExtent);
10332 nexus=ReadImage(image_info,exception);
10333 CatchException(exception);
10334 XSetCursorState(display,windows,MagickFalse);
10335 if (nexus != (
Image *) NULL)
10336 XClientMessage(display,windows->image.id,windows->im_protocols,
10337 windows->im_next_image,CurrentTime);
10347 text=FileToString(filename,~0UL,exception);
10348 if (text == (
char *) NULL)
10349 return((
Image *) NULL);
10350 textlist=StringToList(text);
10351 if (textlist != (
char **) NULL)
10354 title[MagickPathExtent];
10359 (void) FormatLocaleString(title,MagickPathExtent,
10360 "Unknown format: %s",filename);
10361 XTextViewWidget(display,resource_info,windows,MagickTrue,title,
10362 (
const char **) textlist);
10363 for (i=0; textlist[i] != (
char *) NULL; i++)
10364 textlist[i]=DestroyString(textlist[i]);
10365 textlist=(
char **) RelinquishMagickMemory(textlist);
10367 text=DestroyString(text);
10369 exception=DestroyExceptionInfo(exception);
10370 image_info=DestroyImageInfo(image_info);
10405static void XPanImage(Display *display,XWindows *windows,XEvent *event,
10409 text[MagickPathExtent];
10427 if ((windows->image.ximage->width > (
int) windows->image.width) &&
10428 (windows->image.ximage->height > (
int) windows->image.height))
10429 cursor=XCreateFontCursor(display,XC_fleur);
10431 if (windows->image.ximage->width > (
int) windows->image.width)
10432 cursor=XCreateFontCursor(display,XC_sb_h_double_arrow);
10434 if (windows->image.ximage->height > (
int) windows->image.height)
10435 cursor=XCreateFontCursor(display,XC_sb_v_double_arrow);
10437 cursor=XCreateFontCursor(display,XC_arrow);
10438 (void) XCheckDefineCursor(display,windows->pan.id,cursor);
10442 x_factor=(double) windows->image.ximage->width/windows->pan.width;
10443 y_factor=(double) windows->image.ximage->height/windows->pan.height;
10444 pan_info.width=windows->pan.width*windows->image.width/
10445 (
unsigned int) windows->image.ximage->width;
10446 pan_info.height=windows->pan.height*windows->image.height/
10447 (
unsigned int) windows->image.ximage->height;
10450 state=UpdateConfigurationState;
10453 switch (event->type)
10460 pan_info.x=(ssize_t) event->xbutton.x;
10461 pan_info.y=(ssize_t) event->xbutton.y;
10462 state|=UpdateConfigurationState;
10465 case ButtonRelease:
10470 pan_info.x=(ssize_t) event->xbutton.x;
10471 pan_info.y=(ssize_t) event->xbutton.y;
10472 state|=UpdateConfigurationState | ExitState;
10477 pan_info.x=(ssize_t) event->xmotion.x;
10478 pan_info.y=(ssize_t) event->xmotion.y;
10479 state|=UpdateConfigurationState;
10484 if ((state & UpdateConfigurationState) != 0)
10489 if (pan_info.x < (ssize_t) (pan_info.width/2))
10492 pan_info.x=(x_factor*(pan_info.x-((int) pan_info.width/2)));
10493 if (pan_info.x < 0)
10496 if ((
int) (pan_info.x+windows->image.width) >
10497 windows->image.ximage->width)
10498 pan_info.x=windows->image.ximage->width-(int) windows->image.width;
10499 if (pan_info.y < (ssize_t) (pan_info.height/2))
10502 pan_info.y=(y_factor*(pan_info.y-((int) pan_info.height/2)));
10503 if (pan_info.y < 0)
10506 if ((
int) (pan_info.y+windows->image.height) >
10507 windows->image.ximage->height)
10508 pan_info.y=windows->image.ximage->height-(int)
10509 windows->image.height;
10510 if ((windows->image.x != (
int) pan_info.x) ||
10511 (windows->image.y != (
int) pan_info.y))
10516 windows->image.x=(int) pan_info.x;
10517 windows->image.y=(int) pan_info.y;
10518 (void) FormatLocaleString(text,MagickPathExtent,
" %ux%u%+d%+d ",
10519 windows->image.width,windows->image.height,windows->image.x,
10521 XInfoWidget(display,windows,text);
10525 XDrawPanRectangle(display,windows);
10526 XRefreshWindow(display,&windows->image,(XEvent *) NULL);
10528 state&=(
unsigned int) (~UpdateConfigurationState);
10533 if ((state & ExitState) == 0)
10534 XScreenEvent(display,windows,event,exception);
10535 }
while ((state & ExitState) == 0);
10539 (void) XCheckDefineCursor(display,windows->pan.id,windows->pan.cursor);
10540 (void) XFreeCursor(display,cursor);
10541 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
10578static MagickBooleanType XPasteImage(Display *display,
10579 XResourceInfo *resource_info,XWindows *windows,
Image *image,
10583 *
const PasteMenu[] =
10591 static const ModeType
10594 PasteOperatorsCommand,
10596 PasteDismissCommand
10599 static CompositeOperator
10600 compose = CopyCompositeOp;
10603 text[MagickPathExtent];
10637 if (resource_info->copy_image == (
Image *) NULL)
10638 return(MagickFalse);
10639 paste_image=CloneImage(resource_info->copy_image,0,0,MagickTrue,exception);
10640 if (paste_image == (
Image *) NULL)
10641 return(MagickFalse);
10645 (void) CloneString(&windows->command.name,
"Paste");
10646 windows->command.data=1;
10647 (void) XCommandWidget(display,windows,PasteMenu,(XEvent *) NULL);
10648 (void) XMapRaised(display,windows->command.id);
10649 XClientMessage(display,windows->image.id,windows->im_protocols,
10650 windows->im_update_widget,CurrentTime);
10654 XSetCursorState(display,windows,MagickFalse);
10655 XQueryPosition(display,windows->image.id,&x,&y);
10656 (void) XSelectInput(display,windows->image.id,
10657 windows->image.attributes.event_mask | PointerMotionMask);
10658 paste_info.x=(ssize_t) windows->image.x+x;
10659 paste_info.y=(ssize_t) windows->image.y+y;
10660 paste_info.width=0;
10661 paste_info.height=0;
10662 cursor=XCreateFontCursor(display,XC_ul_angle);
10663 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
10664 state=DefaultState;
10667 if (windows->info.mapped != MagickFalse)
10672 (void) FormatLocaleString(text,MagickPathExtent,
" %+ld%+ld ",
10673 (
long) paste_info.x,(long) paste_info.y);
10674 XInfoWidget(display,windows,text);
10676 highlight_info=paste_info;
10677 highlight_info.x=paste_info.x-windows->image.x;
10678 highlight_info.y=paste_info.y-windows->image.y;
10679 XHighlightRectangle(display,windows->image.id,
10680 windows->image.highlight_context,&highlight_info);
10684 XScreenEvent(display,windows,&event,exception);
10685 XHighlightRectangle(display,windows->image.id,
10686 windows->image.highlight_context,&highlight_info);
10687 if (event.xany.window == windows->command.id)
10692 id=XCommandWidget(display,windows,PasteMenu,&event);
10695 switch (PasteCommands[
id])
10697 case PasteOperatorsCommand:
10700 command[MagickPathExtent],
10706 operators=GetCommandOptions(MagickComposeOptions);
10707 if (operators == (
char **) NULL)
10709 entry=XMenuWidget(display,windows,PasteMenu[
id],
10710 (
const char **) operators,command);
10712 compose=(CompositeOperator) ParseCommandOption(
10713 MagickComposeOptions,MagickFalse,operators[entry]);
10714 operators=DestroyStringList(operators);
10717 case PasteHelpCommand:
10719 XTextViewHelp(display,resource_info,windows,MagickFalse,
10720 "Help Viewer - Image Composite",ImagePasteHelp);
10723 case PasteDismissCommand:
10728 state|=EscapeState;
10737 switch (event.type)
10741 if (resource_info->debug != MagickFalse)
10742 (void) LogMagickEvent(X11Event,GetMagickModule(),
10743 "Button Press: 0x%lx %u +%d+%d",
event.xbutton.window,
10744 event.xbutton.button,
event.xbutton.x,
event.xbutton.y);
10745 if (event.xbutton.button != Button1)
10747 if (event.xbutton.window != windows->image.id)
10752 width=(
unsigned int) image->columns;
10753 height=(
unsigned int) image->rows;
10756 if (windows->image.crop_geometry != (
char *) NULL)
10757 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
10759 scale_factor=(double) windows->image.ximage->width/width;
10760 paste_info.width=(
unsigned int) (scale_factor*paste_image->columns+0.5);
10761 scale_factor=(double) windows->image.ximage->height/height;
10762 paste_info.height=(
unsigned int) (scale_factor*paste_image->rows+0.5);
10763 (void) XCheckDefineCursor(display,windows->image.id,cursor);
10764 paste_info.x=(ssize_t) windows->image.x+event.xbutton.x;
10765 paste_info.y=(ssize_t) windows->image.y+event.xbutton.y;
10768 case ButtonRelease:
10770 if (resource_info->debug != MagickFalse)
10771 (void) LogMagickEvent(X11Event,GetMagickModule(),
10772 "Button Release: 0x%lx %u +%d+%d",
event.xbutton.window,
10773 event.xbutton.button,
event.xbutton.x,
event.xbutton.y);
10774 if (event.xbutton.button != Button1)
10776 if (event.xbutton.window != windows->image.id)
10778 if ((paste_info.width != 0) && (paste_info.height != 0))
10783 paste_info.x=(ssize_t) windows->image.x+event.xbutton.x;
10784 paste_info.y=(ssize_t) windows->image.y+event.xbutton.y;
10794 command[MagickPathExtent];
10802 if (event.xkey.window != windows->image.id)
10807 length=XLookupString((XKeyEvent *) &event.xkey,command,(
int)
10808 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
10809 *(command+length)=
'\0';
10810 if (resource_info->debug != MagickFalse)
10811 (void) LogMagickEvent(X11Event,GetMagickModule(),
10812 "Key press: 0x%lx (%s)",(long) key_symbol,command);
10813 switch ((
int) key_symbol)
10821 paste_image=DestroyImage(paste_image);
10822 state|=EscapeState;
10829 (void) XSetFunction(display,windows->image.highlight_context,
10831 XTextViewHelp(display,resource_info,windows,MagickFalse,
10832 "Help Viewer - Image Composite",ImagePasteHelp);
10833 (void) XSetFunction(display,windows->image.highlight_context,
10839 (void) XBell(display,0);
10852 if (windows->info.mapped != MagickFalse)
10854 if ((x < (windows->info.x+(
int) windows->info.width)) &&
10855 (y < (windows->info.y+(
int) windows->info.height)))
10856 (void) XWithdrawWindow(display,windows->info.id,
10857 windows->info.screen);
10860 if ((x > (windows->info.x+(
int) windows->info.width)) ||
10861 (y > (windows->info.y+(int) windows->info.height)))
10862 (void) XMapWindow(display,windows->info.id);
10863 paste_info.x=(ssize_t) windows->image.x+x;
10864 paste_info.y=(ssize_t) windows->image.y+y;
10869 if (resource_info->debug != MagickFalse)
10870 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Event type: %d",
10875 }
while ((state & ExitState) == 0);
10876 (void) XSelectInput(display,windows->image.id,
10877 windows->image.attributes.event_mask);
10878 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
10879 XSetCursorState(display,windows,MagickFalse);
10880 (void) XFreeCursor(display,cursor);
10881 if ((state & EscapeState) != 0)
10882 return(MagickTrue);
10886 XSetCursorState(display,windows,MagickTrue);
10887 XCheckRefreshWindows(display,windows);
10888 width=(
unsigned int) image->columns;
10889 height=(
unsigned int) image->rows;
10892 if (windows->image.crop_geometry != (
char *) NULL)
10893 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
10894 scale_factor=(double) width/windows->image.ximage->width;
10896 paste_info.x=(ssize_t) (scale_factor*paste_info.x+0.5);
10897 paste_info.width=(
unsigned int) (scale_factor*paste_info.width+0.5);
10898 scale_factor=(double) height/windows->image.ximage->height;
10900 paste_info.y=(ssize_t) (scale_factor*paste_info.y*scale_factor+0.5);
10901 paste_info.height=(
unsigned int) (scale_factor*paste_info.height+0.5);
10905 (void) CompositeImage(image,paste_image,compose,MagickTrue,paste_info.x,
10906 paste_info.y,exception);
10907 paste_image=DestroyImage(paste_image);
10908 XSetCursorState(display,windows,MagickFalse);
10912 XConfigureImageColormap(display,resource_info,windows,image,exception);
10913 (void) XConfigureImage(display,resource_info,windows,image,exception);
10914 return(MagickTrue);
10950static MagickBooleanType XPrintImage(Display *display,
10951 XResourceInfo *resource_info,XWindows *windows,
Image *image,
10955 filename[MagickPathExtent],
10956 geometry[MagickPathExtent];
10959 *
const PageSizes[] =
10990 image_info=CloneImageInfo(resource_info->image_info);
10991 (void) FormatLocaleString(geometry,MagickPathExtent,
"Letter");
10992 if (image_info->page != (
char *) NULL)
10993 (
void) CopyMagickString(geometry,image_info->page,MagickPathExtent);
10994 XListBrowserWidget(display,windows,&windows->widget,PageSizes,
"Select",
10995 "Select Postscript Page Geometry:",geometry);
10996 if (*geometry ==
'\0')
10997 return(MagickTrue);
10998 image_info->page=GetPageGeometry(geometry);
11002 XSetCursorState(display,windows,MagickTrue);
11003 XCheckRefreshWindows(display,windows);
11004 print_image=CloneImage(image,0,0,MagickTrue,exception);
11005 if (print_image == (
Image *) NULL)
11006 return(MagickFalse);
11007 (void) FormatLocaleString(geometry,MagickPathExtent,
"%dx%d!",
11008 windows->image.ximage->width,windows->image.ximage->height);
11009 (void) TransformImage(&print_image,windows->image.crop_geometry,geometry,
11014 (void) AcquireUniqueFilename(filename);
11015 (void) FormatLocaleString(print_image->filename,MagickPathExtent,
"print:%s",
11017 status=WriteImage(image_info,print_image,exception);
11018 (void) RelinquishUniqueFileResource(filename);
11019 print_image=DestroyImage(print_image);
11020 image_info=DestroyImageInfo(image_info);
11021 XSetCursorState(display,windows,MagickFalse);
11022 return(status != 0 ? MagickTrue : MagickFalse);
11058static MagickBooleanType XROIImage(Display *display,
11059 XResourceInfo *resource_info,XWindows *windows,
Image **image,
11062#define ApplyMenus 7
11071 *
const ApplyMenu[] =
11084 *
const FileMenu[] =
11090 *
const EditMenu[] =
11096 *
const TransformMenu[] =
11104 *
const EnhanceMenu[] =
11112 "Contrast Stretch...",
11113 "Sigmoidal Contrast...",
11122 *
const EffectsMenu[] =
11147 "Charcoal Draw...",
11150 *
const MiscellanyMenu[] =
11161 *
const *Menus[ApplyMenus] =
11172 static const DisplayCommand
11195 TransformCommands[] =
11199 RotateRightCommand,
11202 EnhanceCommands[] =
11210 ContrastStretchCommand,
11211 SigmoidalContrastCommand,
11219 EffectsCommands[] =
11223 ReduceNoiseCommand,
11242 CharcoalDrawCommand
11244 MiscellanyCommands[] =
11248 ShowPreviewCommand,
11249 ShowHistogramCommand,
11258 static const DisplayCommand
11259 *Commands[ApplyMenus] =
11271 command[MagickPathExtent],
11272 text[MagickPathExtent];
11292 MagickProgressMonitor
11313 (void) CloneString(&windows->command.name,
"ROI");
11314 windows->command.data=0;
11315 (void) XCommandWidget(display,windows,ROIMenu,(XEvent *) NULL);
11316 (void) XMapRaised(display,windows->command.id);
11317 XClientMessage(display,windows->image.id,windows->im_protocols,
11318 windows->im_update_widget,CurrentTime);
11322 XQueryPosition(display,windows->image.id,&x,&y);
11323 (void) XSelectInput(display,windows->image.id,
11324 windows->image.attributes.event_mask | PointerMotionMask);
11325 roi_info.x=(ssize_t) windows->image.x+x;
11326 roi_info.y=(ssize_t) windows->image.y+y;
11329 cursor=XCreateFontCursor(display,XC_fleur);
11330 state=DefaultState;
11333 if (windows->info.mapped != MagickFalse)
11338 (void) FormatLocaleString(text,MagickPathExtent,
" %+ld%+ld ",
11339 (
long) roi_info.x,(long) roi_info.y);
11340 XInfoWidget(display,windows,text);
11345 XScreenEvent(display,windows,&event,exception);
11346 if (event.xany.window == windows->command.id)
11351 id=XCommandWidget(display,windows,ROIMenu,&event);
11354 switch (ROICommands[
id])
11356 case ROIHelpCommand:
11358 XTextViewHelp(display,resource_info,windows,MagickFalse,
11359 "Help Viewer - Region of Interest",ImageROIHelp);
11362 case ROIDismissCommand:
11367 state|=EscapeState;
11376 switch (event.type)
11380 if (event.xbutton.button != Button1)
11382 if (event.xbutton.window != windows->image.id)
11387 (void) XCheckDefineCursor(display,windows->image.id,cursor);
11388 roi_info.x=(ssize_t) windows->image.x+event.xbutton.x;
11389 roi_info.y=(ssize_t) windows->image.y+event.xbutton.y;
11393 case ButtonRelease:
11402 if (event.xkey.window != windows->image.id)
11407 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
11408 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
11409 switch ((
int) key_symbol)
11417 state|=EscapeState;
11424 XTextViewHelp(display,resource_info,windows,MagickFalse,
11425 "Help Viewer - Region of Interest",ImageROIHelp);
11430 (void) XBell(display,0);
11443 if (windows->info.mapped != MagickFalse)
11445 if ((x < (windows->info.x+(
int) windows->info.width)) &&
11446 (y < (windows->info.y+(int) windows->info.height)))
11447 (void) XWithdrawWindow(display,windows->info.id,
11448 windows->info.screen);
11451 if ((x > (windows->info.x+(
int) windows->info.width)) ||
11452 (y > (windows->info.y+(int) windows->info.height)))
11453 (void) XMapWindow(display,windows->info.id);
11454 roi_info.x=(ssize_t) windows->image.x+x;
11455 roi_info.y=(ssize_t) windows->image.y+y;
11461 }
while ((state & ExitState) == 0);
11462 (void) XSelectInput(display,windows->image.id,
11463 windows->image.attributes.event_mask);
11464 if ((state & EscapeState) != 0)
11469 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
11470 (void) XFreeCursor(display,cursor);
11471 return(MagickTrue);
11473 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
11479 x=(int) roi_info.x;
11480 y=(int) roi_info.y;
11483 state=DefaultState;
11486 highlight_info=roi_info;
11487 highlight_info.x=roi_info.x-windows->image.x;
11488 highlight_info.y=roi_info.y-windows->image.y;
11489 if ((highlight_info.width > 3) && (highlight_info.height > 3))
11494 if (windows->info.mapped == MagickFalse)
11495 (void) XMapWindow(display,windows->info.id);
11496 (void) FormatLocaleString(text,MagickPathExtent,
11497 " %.20gx%.20g%+.20g%+.20g",(
double) roi_info.width,(double)
11498 roi_info.height,(
double) roi_info.x,(double) roi_info.y);
11499 XInfoWidget(display,windows,text);
11500 XHighlightRectangle(display,windows->image.id,
11501 windows->image.highlight_context,&highlight_info);
11504 if (windows->info.mapped != MagickFalse)
11505 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
11509 XScreenEvent(display,windows,&event,exception);
11510 if ((highlight_info.width > 3) && (highlight_info.height > 3))
11511 XHighlightRectangle(display,windows->image.id,
11512 windows->image.highlight_context,&highlight_info);
11513 switch (event.type)
11517 roi_info.x=(ssize_t) windows->image.x+event.xbutton.x;
11518 roi_info.y=(ssize_t) windows->image.y+event.xbutton.y;
11521 case ButtonRelease:
11526 roi_info.x=(ssize_t) windows->image.x+event.xbutton.x;
11527 roi_info.y=(ssize_t) windows->image.y+event.xbutton.y;
11528 XSetCursorState(display,windows,MagickFalse);
11530 if (LocaleCompare(windows->command.name,
"Apply") == 0)
11532 (void) CloneString(&windows->command.name,
"Apply");
11533 windows->command.data=ApplyMenus;
11534 (void) XCommandWidget(display,windows,ApplyMenu,(XEvent *) NULL);
11541 roi_info.x=(ssize_t) windows->image.x+event.xmotion.x;
11542 roi_info.y=(ssize_t) windows->image.y+event.xmotion.y;
11547 if ((((
int) roi_info.x != x) && ((
int) roi_info.y != y)) ||
11548 ((state & ExitState) != 0))
11553 if (roi_info.x < 0)
11556 if (roi_info.x > (ssize_t) windows->image.ximage->width)
11557 roi_info.x=(ssize_t) windows->image.ximage->width;
11558 if ((
int) roi_info.x < x)
11559 roi_info.width=(
unsigned int) (x-roi_info.x);
11562 roi_info.width=(
unsigned int) (roi_info.x-x);
11563 roi_info.x=(ssize_t) x;
11565 if (roi_info.y < 0)
11568 if (roi_info.y > (ssize_t) windows->image.ximage->height)
11569 roi_info.y=(ssize_t) windows->image.ximage->height;
11570 if ((
int) roi_info.y < y)
11571 roi_info.height=(
unsigned int) (y-roi_info.y);
11574 roi_info.height=(
unsigned int) (roi_info.y-y);
11575 roi_info.y=(ssize_t) y;
11578 }
while ((state & ExitState) == 0);
11582 state=DefaultState;
11583 display_command=NullCommand;
11586 (void) XMapWindow(display,windows->info.id);
11589 if (windows->info.mapped != MagickFalse)
11594 (void) FormatLocaleString(text,MagickPathExtent,
11595 " %.20gx%.20g%+.20g%+.20g",(
double) roi_info.width,(double)
11596 roi_info.height,(
double) roi_info.x,(double) roi_info.y);
11597 XInfoWidget(display,windows,text);
11599 highlight_info=roi_info;
11600 highlight_info.x=roi_info.x-windows->image.x;
11601 highlight_info.y=roi_info.y-windows->image.y;
11602 if ((highlight_info.width <= 3) || (highlight_info.height <= 3))
11604 state|=EscapeState;
11608 if ((state & UpdateRegionState) != 0)
11610 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
11611 switch (display_command)
11616 (void) XMagickCommand(display,resource_info,windows,
11617 display_command,image,exception);
11625 progress_monitor=SetImageProgressMonitor(*image,
11626 (MagickProgressMonitor) NULL,(*image)->client_data);
11627 crop_info=roi_info;
11628 width=(
unsigned int) (*image)->columns;
11629 height=(
unsigned int) (*image)->rows;
11632 if (windows->image.crop_geometry != (
char *) NULL)
11633 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
11635 scale_factor=(double) width/windows->image.ximage->width;
11637 crop_info.x=(ssize_t) (scale_factor*crop_info.x+0.5);
11638 crop_info.width=(
unsigned int) (scale_factor*crop_info.width+0.5);
11639 scale_factor=(double)
11640 height/windows->image.ximage->height;
11642 crop_info.y=(ssize_t) (scale_factor*crop_info.y+0.5);
11643 crop_info.height=(
unsigned int)
11644 (scale_factor*crop_info.height+0.5);
11645 roi_image=CropImage(*image,&crop_info,exception);
11646 (void) SetImageProgressMonitor(*image,progress_monitor,
11647 (*image)->client_data);
11648 if (roi_image == (
Image *) NULL)
11653 windows->image.orphan=MagickTrue;
11654 (void) XMagickCommand(display,resource_info,windows,
11655 display_command,&roi_image,exception);
11656 progress_monitor=SetImageProgressMonitor(*image,
11657 (MagickProgressMonitor) NULL,(*image)->client_data);
11658 (void) XMagickCommand(display,resource_info,windows,
11659 SaveToUndoBufferCommand,image,exception);
11660 windows->image.orphan=MagickFalse;
11661 (void) CompositeImage(*image,roi_image,CopyCompositeOp,
11662 MagickTrue,crop_info.x,crop_info.y,exception);
11663 roi_image=DestroyImage(roi_image);
11664 (void) SetImageProgressMonitor(*image,progress_monitor,
11665 (*image)->client_data);
11669 if (display_command != InfoCommand)
11671 XConfigureImageColormap(display,resource_info,windows,*image,
11673 (void) XConfigureImage(display,resource_info,windows,*image,
11676 XCheckRefreshWindows(display,windows);
11677 XInfoWidget(display,windows,text);
11678 (void) XSetFunction(display,windows->image.highlight_context,
11680 state&=(
unsigned int) (~UpdateRegionState);
11682 XHighlightRectangle(display,windows->image.id,
11683 windows->image.highlight_context,&highlight_info);
11684 XScreenEvent(display,windows,&event,exception);
11685 if (event.xany.window == windows->command.id)
11690 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
11691 display_command=NullCommand;
11692 id=XCommandWidget(display,windows,ApplyMenu,&event);
11695 (void) CopyMagickString(command,ApplyMenu[
id],MagickPathExtent);
11696 display_command=ApplyCommands[id];
11697 if (
id < ApplyMenus)
11702 entry=XMenuWidget(display,windows,ApplyMenu[
id],
11703 (
const char **) Menus[
id],command);
11706 (void) CopyMagickString(command,Menus[
id][entry],
11708 display_command=Commands[id][entry];
11712 (void) XSetFunction(display,windows->image.highlight_context,
11714 XHighlightRectangle(display,windows->image.id,
11715 windows->image.highlight_context,&highlight_info);
11716 if (display_command == HelpCommand)
11718 (void) XSetFunction(display,windows->image.highlight_context,
11720 XTextViewHelp(display,resource_info,windows,MagickFalse,
11721 "Help Viewer - Region of Interest",ImageROIHelp);
11722 (void) XSetFunction(display,windows->image.highlight_context,
11726 if (display_command == QuitCommand)
11731 state|=EscapeState;
11735 if (display_command != NullCommand)
11736 state|=UpdateRegionState;
11739 XHighlightRectangle(display,windows->image.id,
11740 windows->image.highlight_context,&highlight_info);
11741 switch (event.type)
11745 x=windows->image.x;
11746 y=windows->image.y;
11747 if (event.xbutton.button != Button1)
11749 if (event.xbutton.window != windows->image.id)
11751 x=windows->image.x+
event.xbutton.x;
11752 y=windows->image.y+
event.xbutton.y;
11753 if ((x < (
int) (roi_info.x+RoiDelta)) &&
11754 (x > (
int) (roi_info.x-RoiDelta)) &&
11755 (y < (
int) (roi_info.y+RoiDelta)) &&
11756 (y > (
int) (roi_info.y-RoiDelta)))
11758 roi_info.x=roi_info.x+(int) roi_info.width;
11759 roi_info.y=roi_info.y+(int) roi_info.height;
11760 state|=UpdateConfigurationState;
11763 if ((x < (
int) (roi_info.x+RoiDelta)) &&
11764 (x > (
int) (roi_info.x-RoiDelta)) &&
11765 (y < (roi_info.y+(
int) roi_info.height+RoiDelta)) &&
11766 (y > (roi_info.y+(
int) roi_info.height-RoiDelta)))
11768 roi_info.x=roi_info.x+(int) roi_info.width;
11769 state|=UpdateConfigurationState;
11772 if ((x < (roi_info.x+(
int) roi_info.width+RoiDelta)) &&
11773 (x > (roi_info.x+(
int) roi_info.width-RoiDelta)) &&
11774 (y < (
int) (roi_info.y+RoiDelta)) &&
11775 (y > (
int) (roi_info.y-RoiDelta)))
11777 roi_info.y=roi_info.y+(int) roi_info.height;
11778 state|=UpdateConfigurationState;
11781 if ((x < (roi_info.x+(
int) roi_info.width+RoiDelta)) &&
11782 (x > (roi_info.x+(
int) roi_info.width-RoiDelta)) &&
11783 (y < (roi_info.y+(
int) roi_info.height+RoiDelta)) &&
11784 (y > (roi_info.y+(
int) roi_info.height-RoiDelta)))
11786 state|=UpdateConfigurationState;
11789 magick_fallthrough;
11791 case ButtonRelease:
11793 if (event.xbutton.window == windows->pan.id)
11794 if ((highlight_info.x != crop_info.x-windows->image.x) ||
11795 (highlight_info.y != crop_info.y-windows->image.y))
11796 XHighlightRectangle(display,windows->image.id,
11797 windows->image.highlight_context,&highlight_info);
11798 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id,
11799 event.xbutton.time);
11804 if (event.xexpose.window == windows->image.id)
11805 if (event.xexpose.count == 0)
11807 event.xexpose.x=(int) highlight_info.x;
11808 event.xexpose.y=(int) highlight_info.y;
11809 event.xexpose.width=(int) highlight_info.width;
11810 event.xexpose.height=(int) highlight_info.height;
11811 XRefreshWindow(display,&windows->image,&event);
11813 if (event.xexpose.window == windows->info.id)
11814 if (event.xexpose.count == 0)
11815 XInfoWidget(display,windows,text);
11823 if (event.xkey.window != windows->image.id)
11828 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
11829 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
11830 switch ((
int) key_symbol)
11838 state|=EscapeState;
11839 magick_fallthrough;
11849 roi_info.x=(ssize_t) (windows->image.width/2L-roi_info.width/2L);
11850 roi_info.y=(ssize_t) (windows->image.height/2L-
11851 roi_info.height/2L);
11883 (void) XSetFunction(display,windows->image.highlight_context,
11885 XTextViewHelp(display,resource_info,windows,MagickFalse,
11886 "Help Viewer - Region of Interest",ImageROIHelp);
11887 (void) XSetFunction(display,windows->image.highlight_context,
11893 display_command=XImageWindowCommand(display,resource_info,windows,
11894 event.xkey.state,key_symbol,image,exception);
11895 if (display_command != NullCommand)
11896 state|=UpdateRegionState;
11900 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id,
11908 if (event.xbutton.window != windows->image.id)
11915 if (windows->info.mapped != MagickFalse)
11917 if ((x < (windows->info.x+(
int) windows->info.width)) &&
11918 (y < (windows->info.y+(int) windows->info.height)))
11919 (void) XWithdrawWindow(display,windows->info.id,
11920 windows->info.screen);
11923 if ((x > (windows->info.x+(
int) windows->info.width)) ||
11924 (y > (windows->info.y+(int) windows->info.height)))
11925 (void) XMapWindow(display,windows->info.id);
11926 roi_info.x=(ssize_t) windows->image.x+event.xmotion.x;
11927 roi_info.y=(ssize_t) windows->image.y+event.xmotion.y;
11930 case SelectionRequest:
11935 XSelectionRequestEvent
11941 (void) FormatLocaleString(text,MagickPathExtent,
11942 "%.20gx%.20g%+.20g%+.20g",(
double) roi_info.width,(double)
11943 roi_info.height,(
double) roi_info.x,(double) roi_info.y);
11944 request=(&(
event.xselectionrequest));
11945 (void) XChangeProperty(request->display,request->requestor,
11946 request->property,request->target,8,PropModeReplace,
11947 (
unsigned char *) text,(int) strlen(text));
11948 notify.type=SelectionNotify;
11949 notify.display=request->display;
11950 notify.requestor=request->requestor;
11951 notify.selection=request->selection;
11952 notify.target=request->target;
11953 notify.time=request->time;
11954 if (request->property == None)
11955 notify.property=request->target;
11957 notify.property=request->property;
11958 (void) XSendEvent(request->display,request->requestor,False,0,
11959 (XEvent *) ¬ify);
11964 if ((state & UpdateConfigurationState) != 0)
11966 (void) XPutBackEvent(display,&event);
11967 (void) XCheckDefineCursor(display,windows->image.id,cursor);
11970 }
while ((state & ExitState) == 0);
11971 }
while ((state & ExitState) == 0);
11972 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
11973 XSetCursorState(display,windows,MagickFalse);
11974 if ((state & EscapeState) != 0)
11975 return(MagickTrue);
11976 return(MagickTrue);
12015static MagickBooleanType XRotateImage(Display *display,
12016 XResourceInfo *resource_info,XWindows *windows,
double degrees,
Image **image,
12020 *
const RotateMenu[] =
12030 direction = HorizontalRotateCommand;
12032 static const ModeType
12033 DirectionCommands[] =
12035 HorizontalRotateCommand,
12036 VerticalRotateCommand
12040 RotateColorCommand,
12041 RotateDirectionCommand,
12043 RotateDismissCommand
12046 static unsigned int
12050 command[MagickPathExtent],
12051 text[MagickPathExtent];
12062 normalized_degrees;
12072 if (degrees == 0.0)
12089 (void) CloneString(&windows->command.name,
"Rotate");
12090 windows->command.data=2;
12091 (void) XCommandWidget(display,windows,RotateMenu,(XEvent *) NULL);
12092 (void) XMapRaised(display,windows->command.id);
12093 XClientMessage(display,windows->image.id,windows->im_protocols,
12094 windows->im_update_widget,CurrentTime);
12098 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
12099 XQueryPosition(display,windows->image.id,&x,&y);
12104 state=DefaultState;
12107 XHighlightLine(display,windows->image.id,
12108 windows->image.highlight_context,&rotate_info);
12112 XScreenEvent(display,windows,&event,exception);
12113 XHighlightLine(display,windows->image.id,
12114 windows->image.highlight_context,&rotate_info);
12115 if (event.xany.window == windows->command.id)
12120 id=XCommandWidget(display,windows,RotateMenu,&event);
12123 (void) XSetFunction(display,windows->image.highlight_context,
12125 switch (RotateCommands[
id])
12127 case RotateColorCommand:
12130 *ColorMenu[MaxNumberPens];
12141 for (i=0; i < (int) (MaxNumberPens-2); i++)
12142 ColorMenu[i]=resource_info->pen_colors[i];
12143 ColorMenu[MaxNumberPens-2]=
"Browser...";
12144 ColorMenu[MaxNumberPens-1]=(
const char *) NULL;
12148 pen_number=XMenuWidget(display,windows,RotateMenu[
id],
12149 (
const char **) ColorMenu,command);
12150 if (pen_number < 0)
12152 if (pen_number == (MaxNumberPens-2))
12155 color_name[MagickPathExtent] =
"gray";
12160 resource_info->pen_colors[pen_number]=color_name;
12161 XColorBrowserWidget(display,windows,
"Select",color_name);
12162 if (*color_name ==
'\0')
12168 (void) XParseColor(display,windows->map_info->colormap,
12169 resource_info->pen_colors[pen_number],&color);
12170 XBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
12171 (
unsigned int) MaxColors,&color);
12172 windows->pixel_info->pen_colors[pen_number]=color;
12173 pen_id=(
unsigned int) pen_number;
12176 case RotateDirectionCommand:
12189 id=XMenuWidget(display,windows,RotateMenu[
id],
12190 Directions,command);
12192 direction=DirectionCommands[id];
12195 case RotateHelpCommand:
12197 XTextViewHelp(display,resource_info,windows,MagickFalse,
12198 "Help Viewer - Image Rotation",ImageRotateHelp);
12201 case RotateDismissCommand:
12206 state|=EscapeState;
12213 (void) XSetFunction(display,windows->image.highlight_context,
12217 switch (event.type)
12221 if (event.xbutton.button != Button1)
12223 if (event.xbutton.window != windows->image.id)
12228 (void) XSetFunction(display,windows->image.highlight_context,
12230 rotate_info.x1=
event.xbutton.x;
12231 rotate_info.y1=
event.xbutton.y;
12235 case ButtonRelease:
12242 command[MagickPathExtent];
12247 if (event.xkey.window != windows->image.id)
12252 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
12253 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
12254 switch ((
int) key_symbol)
12262 state|=EscapeState;
12269 (void) XSetFunction(display,windows->image.highlight_context,
12271 XTextViewHelp(display,resource_info,windows,MagickFalse,
12272 "Help Viewer - Image Rotation",ImageRotateHelp);
12273 (void) XSetFunction(display,windows->image.highlight_context,
12279 (void) XBell(display,0);
12287 rotate_info.x1=
event.xmotion.x;
12288 rotate_info.y1=
event.xmotion.y;
12291 rotate_info.x2=rotate_info.x1;
12292 rotate_info.y2=rotate_info.y1;
12293 if (direction == HorizontalRotateCommand)
12294 rotate_info.x2+=32;
12296 rotate_info.y2-=32;
12297 }
while ((state & ExitState) == 0);
12298 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
12299 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
12300 if ((state & EscapeState) != 0)
12301 return(MagickTrue);
12306 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
12307 state=DefaultState;
12315 if (windows->info.mapped == MagickFalse)
12316 (void) XMapWindow(display,windows->info.id);
12317 (void) FormatLocaleString(text,MagickPathExtent,
" %g",
12318 direction == VerticalRotateCommand ? degrees-90.0 : degrees);
12319 XInfoWidget(display,windows,text);
12320 XHighlightLine(display,windows->image.id,
12321 windows->image.highlight_context,&rotate_info);
12324 if (windows->info.mapped != MagickFalse)
12325 (void) XWithdrawWindow(display,windows->info.id,
12326 windows->info.screen);
12330 XScreenEvent(display,windows,&event,exception);
12332 XHighlightLine(display,windows->image.id,
12333 windows->image.highlight_context,&rotate_info);
12334 switch (event.type)
12338 case ButtonRelease:
12343 rotate_info.x2=
event.xbutton.x;
12344 rotate_info.y2=
event.xbutton.y;
12352 rotate_info.x2=
event.xmotion.x;
12353 rotate_info.y2=
event.xmotion.y;
12361 if (rotate_info.x2 < 0)
12364 if (rotate_info.x2 > (
int) windows->image.width)
12365 rotate_info.x2=(short) windows->image.width;
12366 if (rotate_info.y2 < 0)
12369 if (rotate_info.y2 > (
int) windows->image.height)
12370 rotate_info.y2=(short) windows->image.height;
12375 distance=(
unsigned int)
12376 (((rotate_info.x2-rotate_info.x1+1)*(rotate_info.x2-rotate_info.x1+1))+
12377 ((rotate_info.y2-rotate_info.y1+1)*(rotate_info.y2-rotate_info.y1+1)));
12379 degrees=RadiansToDegrees(-atan2((
double) (rotate_info.y2-
12380 rotate_info.y1),(
double) (rotate_info.x2-rotate_info.x1)));
12381 }
while ((state & ExitState) == 0);
12382 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
12383 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
12385 return(MagickTrue);
12387 if (direction == VerticalRotateCommand)
12389 if (degrees == 0.0)
12390 return(MagickTrue);
12394 normalized_degrees=degrees;
12395 while (normalized_degrees < -45.0)
12396 normalized_degrees+=360.0;
12397 for (rotations=0; normalized_degrees > 45.0; rotations++)
12398 normalized_degrees-=90.0;
12399 if (normalized_degrees != 0.0)
12400 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
12402 XSetCursorState(display,windows,MagickTrue);
12403 XCheckRefreshWindows(display,windows);
12404 (*image)->background_color.red=(double) ScaleShortToQuantum(
12405 windows->pixel_info->pen_colors[pen_id].red);
12406 (*image)->background_color.green=(double) ScaleShortToQuantum(
12407 windows->pixel_info->pen_colors[pen_id].green);
12408 (*image)->background_color.blue=(double) ScaleShortToQuantum(
12409 windows->pixel_info->pen_colors[pen_id].blue);
12410 rotate_image=RotateImage(*image,degrees,exception);
12411 XSetCursorState(display,windows,MagickFalse);
12412 if (rotate_image == (
Image *) NULL)
12413 return(MagickFalse);
12414 *image=DestroyImage(*image);
12415 *image=rotate_image;
12416 if (windows->image.crop_geometry != (
char *) NULL)
12421 width=(
unsigned int) (*image)->columns;
12422 height=(
unsigned int) (*image)->rows;
12423 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
12424 switch (rotations % 4)
12434 (void) FormatLocaleString(windows->image.crop_geometry,
12435 MagickPathExtent,
"%ux%u%+d%+d",height,width,(
int) (*image)->columns-
12444 (void) FormatLocaleString(windows->image.crop_geometry,
12445 MagickPathExtent,
"%ux%u%+d%+d",width,height,(
int) width-x,(int)
12454 (void) FormatLocaleString(windows->image.crop_geometry,
12455 MagickPathExtent,
"%ux%u%+d%+d",height,width,y,(
int) (*image)->rows-
12461 if (windows->image.orphan != MagickFalse)
12462 return(MagickTrue);
12463 if (normalized_degrees != 0.0)
12468 windows->image.window_changes.width=(int) (*image)->columns;
12469 windows->image.window_changes.height=(int) (*image)->rows;
12470 if (windows->image.crop_geometry != (
char *) NULL)
12475 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
12477 windows->image.window_changes.width=(int) width;
12478 windows->image.window_changes.height=(int) height;
12480 XConfigureImageColormap(display,resource_info,windows,*image,exception);
12483 if (((rotations % 4) == 1) || ((rotations % 4) == 3))
12485 windows->image.window_changes.width=windows->image.ximage->height;
12486 windows->image.window_changes.height=windows->image.ximage->width;
12491 (void) XConfigureImage(display,resource_info,windows,*image,exception);
12492 return(MagickTrue);
12528static MagickBooleanType XSaveImage(Display *display,
12529 XResourceInfo *resource_info,XWindows *windows,
Image *image,
12533 filename[MagickPathExtent],
12534 geometry[MagickPathExtent];
12548 if (resource_info->write_filename != (
char *) NULL)
12549 (void) CopyMagickString(filename,resource_info->write_filename,
12554 path[MagickPathExtent];
12559 GetPathComponent(image->filename,HeadPath,path);
12560 GetPathComponent(image->filename,TailPath,filename);
12563 status=chdir(path);
12565 (void) ThrowMagickException(exception,GetMagickModule(),
12566 FileOpenError,
"UnableToOpenFile",
"%s",path);
12569 XFileBrowserWidget(display,windows,
"Save",filename);
12570 if (*filename ==
'\0')
12571 return(MagickTrue);
12572 if (IsPathAccessible(filename) != MagickFalse)
12580 status=XConfirmWidget(display,windows,
"Overwrite",filename);
12582 return(MagickTrue);
12584 image_info=CloneImageInfo(resource_info->image_info);
12585 (void) CopyMagickString(image_info->filename,filename,MagickPathExtent);
12586 (void) SetImageInfo(image_info,1,exception);
12587 if ((LocaleCompare(image_info->magick,
"JPEG") == 0) ||
12588 (LocaleCompare(image_info->magick,
"JPG") == 0))
12591 quality[MagickPathExtent];
12599 (void) FormatLocaleString(quality,MagickPathExtent,
"%.20g",(
double)
12601 status=XDialogWidget(display,windows,
"Save",
"Enter JPEG quality:",
12603 if (*quality ==
'\0')
12604 return(MagickTrue);
12605 image->quality=StringToUnsignedLong(quality);
12606 image_info->interlace=status != 0 ? NoInterlace : PlaneInterlace;
12608 if ((LocaleCompare(image_info->magick,
"EPS") == 0) ||
12609 (LocaleCompare(image_info->magick,
"PDF") == 0) ||
12610 (LocaleCompare(image_info->magick,
"PS") == 0) ||
12611 (LocaleCompare(image_info->magick,
"PS2") == 0))
12614 geometry[MagickPathExtent];
12617 *
const PageSizes[] =
12639 (void) CopyMagickString(geometry,PSPageGeometry,MagickPathExtent);
12640 if (LocaleCompare(image_info->magick,
"PDF") == 0)
12641 (
void) CopyMagickString(geometry,PSPageGeometry,MagickPathExtent);
12642 if (image_info->page != (
char *) NULL)
12643 (void) CopyMagickString(geometry,image_info->page,MagickPathExtent);
12644 XListBrowserWidget(display,windows,&windows->widget,PageSizes,
"Select",
12645 "Select page geometry:",geometry);
12646 if (*geometry !=
'\0')
12647 image_info->page=GetPageGeometry(geometry);
12652 XSetCursorState(display,windows,MagickTrue);
12653 XCheckRefreshWindows(display,windows);
12654 save_image=CloneImage(image,0,0,MagickTrue,exception);
12655 if (save_image == (
Image *) NULL)
12656 return(MagickFalse);
12657 (void) FormatLocaleString(geometry,MagickPathExtent,
"%dx%d!",
12658 windows->image.ximage->width,windows->image.ximage->height);
12659 (void) TransformImage(&save_image,windows->image.crop_geometry,geometry,
12664 (void) CopyMagickString(save_image->filename,filename,MagickPathExtent);
12665 status=WriteImage(image_info,save_image,exception);
12666 if (status != MagickFalse)
12667 image->taint=MagickFalse;
12668 save_image=DestroyImage(save_image);
12669 image_info=DestroyImageInfo(image_info);
12670 XSetCursorState(display,windows,MagickFalse);
12671 return(status != 0 ? MagickTrue : MagickFalse);
12706#if defined(__cplusplus) || defined(c_plusplus)
12710static int XPredicate(Display *magick_unused(display),XEvent *event,
char *data)
12715 windows=(XWindows *) data;
12716 if ((event->type == ClientMessage) &&
12717 (
event->xclient.window == windows->image.id))
12718 return(MagickFalse);
12719 return(MagickTrue);
12722#if defined(__cplusplus) || defined(c_plusplus)
12726static void XScreenEvent(Display *display,XWindows *windows,XEvent *event,
12733 (void) XIfEvent(display,event,XPredicate,(
char *) windows);
12734 if (event->xany.window == windows->command.id)
12736 switch (event->type)
12739 case ButtonRelease:
12741 if ((event->xbutton.button == Button3) &&
12742 (
event->xbutton.state & Mod1Mask))
12747 event->xbutton.button=Button2;
12748 event->xbutton.state&=(
unsigned int) (~Mod1Mask);
12750 if (event->xbutton.window == windows->backdrop.id)
12752 (void) XSetInputFocus(display,event->xbutton.window,RevertToParent,
12753 event->xbutton.time);
12756 if (event->xbutton.window == windows->pan.id)
12758 XPanImage(display,windows,event,exception);
12761 if (event->xbutton.window == windows->image.id)
12762 if (event->xbutton.button == Button2)
12767 x=
event->xbutton.x;
12768 y=
event->xbutton.y;
12772 if (x >= (
int) windows->image.width)
12773 x=(int) (windows->image.width-1);
12774 windows->magnify.x=(int) windows->image.x+x;
12778 if (y >= (
int) windows->image.height)
12779 y=(int) (windows->image.height-1);
12780 windows->magnify.y=windows->image.y+y;
12781 if (windows->magnify.mapped == MagickFalse)
12782 (void) XMapRaised(display,windows->magnify.id);
12783 XMakeMagnifyImage(display,windows,exception);
12784 if (event->type == ButtonRelease)
12785 (void) XWithdrawWindow(display,windows->info.id,
12786 windows->info.screen);
12791 case ClientMessage:
12796 if (event->xclient.message_type != windows->wm_protocols)
12798 if (*event->xclient.data.l != (
long) windows->wm_delete_window)
12800 if (event->xclient.window == windows->magnify.id)
12802 (void) XWithdrawWindow(display,windows->magnify.id,
12803 windows->magnify.screen);
12808 case ConfigureNotify:
12810 if (event->xconfigure.window == windows->magnify.id)
12818 windows->magnify.width=(
unsigned int) event->xconfigure.width;
12819 windows->magnify.height=(
unsigned int) event->xconfigure.height;
12820 if (windows->magnify.mapped == MagickFalse)
12823 while ((
int) magnify <= event->xconfigure.width)
12825 while ((
int) magnify <= event->xconfigure.height)
12828 if (((
int) magnify != event->xconfigure.width) ||
12829 ((
int) magnify != event->xconfigure.height))
12834 window_changes.width=(int) magnify;
12835 window_changes.height=(int) magnify;
12836 (void) XReconfigureWMWindow(display,windows->magnify.id,
12837 windows->magnify.screen,(
unsigned int) (CWWidth | CWHeight),
12841 XMakeMagnifyImage(display,windows,exception);
12848 if (event->xexpose.window == windows->image.id)
12850 XRefreshWindow(display,&windows->image,event);
12853 if (event->xexpose.window == windows->pan.id)
12854 if (event->xexpose.count == 0)
12856 XDrawPanRectangle(display,windows);
12859 if (event->xexpose.window == windows->magnify.id)
12860 if (event->xexpose.count == 0)
12862 XMakeMagnifyImage(display,windows,exception);
12870 command[MagickPathExtent];
12875 if (event->xkey.window != windows->magnify.id)
12880 (void) XLookupString((XKeyEvent *) &
event->xkey,command,(int)
12881 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
12882 XMagnifyWindowCommand(display,windows,event->xkey.state,key_symbol,
12888 if (event->xmap.window == windows->magnify.id)
12890 windows->magnify.mapped=MagickTrue;
12891 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
12894 if (event->xmap.window == windows->info.id)
12896 windows->info.mapped=MagickTrue;
12903 while (XCheckMaskEvent(display,ButtonMotionMask,event)) ;
12904 if (event->xmotion.window == windows->image.id)
12905 if (windows->magnify.mapped != MagickFalse)
12910 x=
event->xmotion.x;
12911 y=
event->xmotion.y;
12915 if (x >= (
int) windows->image.width)
12916 x=(
int) (windows->image.width-1);
12917 windows->magnify.x=(int) windows->image.x+x;
12921 if (y >= (
int) windows->image.height)
12922 y=(int) (windows->image.height-1);
12923 windows->magnify.y=windows->image.y+y;
12924 XMakeMagnifyImage(display,windows,exception);
12930 if (event->xunmap.window == windows->magnify.id)
12932 windows->magnify.mapped=MagickFalse;
12935 if (event->xunmap.window == windows->info.id)
12937 windows->info.mapped=MagickFalse;
12979static void XSetCropGeometry(Display *display,XWindows *windows,
12983 text[MagickPathExtent];
12996 if (windows->info.mapped != MagickFalse)
13001 (void) FormatLocaleString(text,MagickPathExtent,
" %.20gx%.20g%+.20g%+.20g",
13002 (
double) crop_info->width,(double) crop_info->height,(
double)
13003 crop_info->x,(double) crop_info->y);
13004 XInfoWidget(display,windows,text);
13011 width=(
unsigned int) image->columns;
13012 height=(
unsigned int) image->rows;
13013 if (windows->image.crop_geometry != (
char *) NULL)
13014 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
13016 windows->image.crop_geometry=AcquireString((
char *) NULL);
13020 scale_factor=(double) width/windows->image.ximage->width;
13021 if (crop_info->x > 0)
13022 x+=(int) (scale_factor*crop_info->x+0.5);
13023 width=(
unsigned int) (scale_factor*crop_info->width+0.5);
13026 scale_factor=(double) height/windows->image.ximage->height;
13027 if (crop_info->y > 0)
13028 y+=(int) (scale_factor*crop_info->y+0.5);
13029 height=(
unsigned int) (scale_factor*crop_info->height+0.5);
13032 (void) FormatLocaleString(windows->image.crop_geometry,MagickPathExtent,
13033 "%ux%u%+d%+d",width,height,x,y);
13075static Image *XTileImage(Display *display,XResourceInfo *resource_info,
13079 *
const VerbMenu[] =
13089 static const ModeType
13100 command[MagickPathExtent],
13101 filename[MagickPathExtent];
13132 width=(
unsigned int) image->columns;
13133 height=(
unsigned int) image->rows;
13134 if (windows->image.crop_geometry != (
char *) NULL)
13135 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
13136 scale_factor=(double) width/windows->image.ximage->width;
13137 event->xbutton.x+=windows->image.x;
13138 event->xbutton.x=(int) (scale_factor*event->xbutton.x+x+0.5);
13139 scale_factor=(double) height/windows->image.ximage->height;
13140 event->xbutton.y+=windows->image.y;
13141 event->xbutton.y=(int) (scale_factor*event->xbutton.y+y+0.5);
13145 width=(
unsigned int) image->columns;
13146 height=(
unsigned int) image->rows;
13149 (void) XParseGeometry(image->montage,&x,&y,&width,&height);
13150 tile=((
event->xbutton.y-y)/(
int) height)*(((
int) image->columns-x)/(
int)
13151 width)+(event->xbutton.x-x)/(int) width;
13157 (void) XBell(display,0);
13158 return((
Image *) NULL);
13163 p=image->directory;
13164 for (i=tile; (i != 0) && (*p !=
'\0'); )
13175 (void) XBell(display,0);
13176 return((
Image *) NULL);
13181 id=XMenuWidget(display,windows,
"Tile Verb",VerbMenu,command);
13183 return((
Image *) NULL);
13185 while ((*q !=
'\xff') && (*q !=
'\0'))
13187 (void) CopyMagickString(filename,p,(
size_t) (q-p+1));
13191 XSetCursorState(display,windows,MagickTrue);
13192 XCheckRefreshWindows(display,windows);
13193 tile_image=NewImageList();
13194 switch (TileCommands[
id])
13196 case TileLoadCommand:
13201 XCheckRefreshWindows(display,windows);
13202 (void) CopyMagickString(resource_info->image_info->magick,
"MIFF",
13204 (void) CopyMagickString(resource_info->image_info->filename,filename,
13206 tile_image=ReadImage(resource_info->image_info,exception);
13207 CatchException(exception);
13208 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
13211 case TileNextCommand:
13216 XClientMessage(display,windows->image.id,windows->im_protocols,
13217 windows->im_next_image,CurrentTime);
13220 case TileFormerCommand:
13225 XClientMessage(display,windows->image.id,windows->im_protocols,
13226 windows->im_former_image,CurrentTime);
13229 case TileDeleteCommand:
13234 if (IsPathAccessible(filename) == MagickFalse)
13236 XNoticeWidget(display,windows,
"Image file does not exist:",filename);
13239 status=XConfirmWidget(display,windows,
"Really delete tile",filename);
13242 status=ShredFile(filename) == MagickFalse ? 0 : 1;
13243 status|=remove_utf8(filename);
13244 if (status != MagickFalse)
13246 XNoticeWidget(display,windows,
"Unable to delete image file:",
13250 magick_fallthrough;
13252 case TileUpdateCommand:
13271 GetPixelInfo(image,&pixel);
13272 for (p=image->directory; *p !=
'\0'; p++)
13278 while ((*q !=
'\xff') && (*q !=
'\0'))
13280 (void) CopyMagickString(filename,p,(
size_t) (q-p+1));
13282 if (IsPathAccessible(filename) != MagickFalse)
13290 x_offset=((int) width*(tile % (((
int) image->columns-x)/(
int) width))+
13292 y_offset=((int) height*(tile/(((
int) image->columns-x)/(
int) width))+
13294 image_view=AcquireAuthenticCacheView(image,exception);
13295 (void) GetOneCacheViewVirtualPixelInfo(image_view,0,0,&pixel,exception);
13296 for (i=0; i < (int) height; i++)
13298 s=GetCacheViewAuthenticPixels(image_view,(ssize_t) x_offset,(ssize_t)
13299 y_offset+i,width,1,exception);
13300 if (s == (Quantum *) NULL)
13302 for (j=0; j < (int) width; j++)
13304 SetPixelViaPixelInfo(image,&pixel,s);
13305 s+=GetPixelChannels(image);
13307 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
13310 image_view=DestroyCacheView(image_view);
13313 windows->image.window_changes.width=(int) image->columns;
13314 windows->image.window_changes.height=(int) image->rows;
13315 XConfigureImageColormap(display,resource_info,windows,image,exception);
13316 (void) XConfigureImage(display,resource_info,windows,image,exception);
13322 XSetCursorState(display,windows,MagickFalse);
13323 return(tile_image);
13359static void XTranslateImage(Display *display,XWindows *windows,
13360 Image *image,
const KeySym key_symbol)
13363 text[MagickPathExtent];
13376 x_offset=windows->image.width;
13377 y_offset=windows->image.height;
13378 if (image->montage != (
char *) NULL)
13379 (void) XParseGeometry(image->montage,&x,&y,&x_offset,&y_offset);
13380 switch ((
int) key_symbol)
13385 windows->image.x=(int) windows->image.width/2;
13386 windows->image.y=(int) windows->image.height/2;
13392 windows->image.x-=(int) x_offset;
13399 windows->image.y-=(int) y_offset;
13405 windows->image.x+=(int) x_offset;
13412 windows->image.y+=(int) y_offset;
13421 if (windows->image.x < 0)
13422 windows->image.x=0;
13424 if ((windows->image.x+(
int) windows->image.width) > windows->image.ximage->width)
13425 windows->image.x=windows->image.ximage->width-(int) windows->image.width;
13426 if (windows->image.y < 0)
13427 windows->image.y=0;
13429 if ((windows->image.y+(
int) windows->image.height) > windows->image.ximage->height)
13430 windows->image.y=windows->image.ximage->height-(int)
13431 windows->image.height;
13435 (void) FormatLocaleString(text,MagickPathExtent,
" %ux%u%+d%+d ",
13436 windows->image.width,windows->image.height,windows->image.x,
13438 XInfoWidget(display,windows,text);
13439 XCheckRefreshWindows(display,windows);
13440 XDrawPanRectangle(display,windows);
13441 XRefreshWindow(display,&windows->image,(XEvent *) NULL);
13442 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
13478static MagickBooleanType XTrimImage(Display *display,
13479 XResourceInfo *resource_info,XWindows *windows,
Image *image,
13496 XSetCursorState(display,windows,MagickTrue);
13497 XCheckRefreshWindows(display,windows);
13501 background=XGetPixel(windows->image.ximage,0,0);
13502 trim_info.width=(size_t) windows->image.ximage->width;
13503 for (x=0; x < windows->image.ximage->width; x++)
13505 for (y=0; y < windows->image.ximage->height; y++)
13507 pixel=XGetPixel(windows->image.ximage,x,y);
13508 if (pixel != background)
13511 if (y < windows->image.ximage->height)
13514 trim_info.x=(ssize_t) x;
13515 if (trim_info.x == (ssize_t) windows->image.ximage->width)
13517 XSetCursorState(display,windows,MagickFalse);
13518 return(MagickFalse);
13523 background=XGetPixel(windows->image.ximage,windows->image.ximage->width-1,0);
13524 for (x=windows->image.ximage->width-1; x != 0; x--)
13526 for (y=0; y < windows->image.ximage->height; y++)
13528 pixel=XGetPixel(windows->image.ximage,x,y);
13529 if (pixel != background)
13532 if (y < windows->image.ximage->height)
13535 trim_info.width=(size_t) (x-trim_info.x+1);
13539 background=XGetPixel(windows->image.ximage,0,0);
13540 trim_info.height=(size_t) windows->image.ximage->height;
13541 for (y=0; y < windows->image.ximage->height; y++)
13543 for (x=0; x < windows->image.ximage->width; x++)
13545 pixel=XGetPixel(windows->image.ximage,x,y);
13546 if (pixel != background)
13549 if (x < windows->image.ximage->width)
13552 trim_info.y=(ssize_t) y;
13556 background=XGetPixel(windows->image.ximage,0,windows->image.ximage->height-1);
13557 for (y=windows->image.ximage->height-1; y != 0; y--)
13559 for (x=0; x < windows->image.ximage->width; x++)
13561 pixel=XGetPixel(windows->image.ximage,x,y);
13562 if (pixel != background)
13565 if (x < windows->image.ximage->width)
13568 trim_info.height=(size_t) (y-trim_info.y+1);
13569 if (((
unsigned int) trim_info.width != windows->image.width) ||
13570 ((
unsigned int) trim_info.height != windows->image.height))
13575 XSetCropGeometry(display,windows,&trim_info,image);
13576 windows->image.window_changes.width=(int) trim_info.width;
13577 windows->image.window_changes.height=(int) trim_info.height;
13578 (void) XConfigureImage(display,resource_info,windows,image,exception);
13580 XSetCursorState(display,windows,MagickFalse);
13581 return(MagickTrue);
13615static Image *XVisualDirectoryImage(Display *display,
13616 XResourceInfo *resource_info,XWindows *windows,
ExceptionInfo *exception)
13618#define TileImageTag "Scale/Image"
13619#define XClientName "montage"
13652 filename[MagickPathExtent] =
"\0",
13653 filenames[MagickPathExtent] =
"*";
13656 background_resources;
13661 XFileBrowserWidget(display,windows,
"Directory",filenames);
13662 if (*filenames ==
'\0')
13663 return((
Image *) NULL);
13667 filelist=(
char **) AcquireMagickMemory(
sizeof(*filelist));
13668 if (filelist == (
char **) NULL)
13670 ThrowXWindowException(ResourceLimitError,
"MemoryAllocationFailed",
13672 return((
Image *) NULL);
13675 filelist[0]=filenames;
13676 status=ExpandFilenames(&number_files,&filelist);
13677 if ((status == MagickFalse) || (number_files == 0))
13679 if (number_files == 0)
13680 ThrowXWindowException(ImageError,
"NoImagesWereFound",filenames)
13682 ThrowXWindowException(ResourceLimitError,
"MemoryAllocationFailed",
13684 return((
Image *) NULL);
13689 background_resources=(*resource_info);
13690 background_resources.window_id=AcquireString(
"");
13691 (void) FormatLocaleString(background_resources.window_id,MagickPathExtent,
13692 "0x%lx",windows->image.id);
13693 background_resources.backdrop=MagickTrue;
13697 backdrop=((windows->visual_info->klass == TrueColor) ||
13698 (windows->visual_info->klass == DirectColor)) ? MagickTrue : MagickFalse;
13699 read_info=CloneImageInfo(resource_info->image_info);
13700 (void) SetImageOption(read_info,
"jpeg:size",
"120x120");
13701 (void) CloneString(&read_info->size,DefaultTileGeometry);
13702 (void) SetImageInfoProgressMonitor(read_info,(MagickProgressMonitor) NULL,
13704 images=NewImageList();
13705 XSetCursorState(display,windows,MagickTrue);
13706 XCheckRefreshWindows(display,windows);
13707 for (i=0; i < (int) number_files; i++)
13709 (void) CopyMagickString(read_info->filename,filelist[i],MagickPathExtent);
13710 filelist[i]=DestroyString(filelist[i]);
13711 *read_info->magick=
'\0';
13712 next_image=ReadImage(read_info,exception);
13713 CatchException(exception);
13714 if (next_image != (
Image *) NULL)
13716 (void) DeleteImageProperty(next_image,
"label");
13717 (void) SetImageProperty(next_image,
"label",InterpretImageProperties(
13718 read_info,next_image,DefaultTileLabel,exception),exception);
13719 (void) ParseRegionGeometry(next_image,read_info->size,&geometry,
13721 thumbnail_image=ThumbnailImage(next_image,geometry.width,
13722 geometry.height,exception);
13723 if (thumbnail_image != (
Image *) NULL)
13725 next_image=DestroyImage(next_image);
13726 next_image=thumbnail_image;
13730 (void) XDisplayBackgroundImage(display,&background_resources,
13731 next_image,exception);
13732 XSetCursorState(display,windows,MagickTrue);
13734 AppendImageToList(&images,next_image);
13735 if (images->progress_monitor != (MagickProgressMonitor) NULL)
13740 proceed=SetImageProgress(images,LoadImageTag,(MagickOffsetType) i,
13741 (MagickSizeType) number_files);
13742 if (proceed == MagickFalse)
13747 filelist=(
char **) RelinquishMagickMemory(filelist);
13748 if (images == (
Image *) NULL)
13750 read_info=DestroyImageInfo(read_info);
13751 XSetCursorState(display,windows,MagickFalse);
13752 ThrowXWindowException(ImageError,
"NoImagesWereLoaded",filenames);
13753 return((
Image *) NULL);
13758 montage_info=CloneMontageInfo(read_info,(
MontageInfo *) NULL);
13759 montage_info->pointsize=10;
13760 if (resource_info->font != (
char *) NULL)
13761 (void) CloneString(&montage_info->font,resource_info->font);
13762 (void) CopyMagickString(montage_info->filename,filename,MagickPathExtent);
13763 montage_image=MontageImageList(read_info,montage_info,GetFirstImageInList(
13764 images),exception);
13765 images=DestroyImageList(images);
13766 montage_info=DestroyMontageInfo(montage_info);
13767 read_info=DestroyImageInfo(read_info);
13768 XSetCursorState(display,windows,MagickFalse);
13769 if (montage_image == (
Image *) NULL)
13770 return(montage_image);
13771 XClientMessage(display,windows->image.id,windows->im_protocols,
13772 windows->im_next_image,CurrentTime);
13773 return(montage_image);
13806MagickExport MagickBooleanType XDisplayBackgroundImage(Display *display,
13810 geometry[MagickPathExtent],
13811 visual_type[MagickPathExtent];
13824 static XStandardColormap
13828 *visual_info = (XVisualInfo *) NULL;
13851 assert(image != (
Image *) NULL);
13852 assert(image->signature == MagickCoreSignature);
13853 if (IsEventLogging() != MagickFalse)
13854 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
13855 resources=(*resource_info);
13856 window_info.id=(Window) NULL;
13857 root_window=XRootWindow(display,XDefaultScreen(display));
13858 if (LocaleCompare(resources.window_id,
"root") == 0)
13859 window_info.id=root_window;
13862 if (isdigit((
int) ((
unsigned char) *resources.window_id)) != 0)
13863 window_info.id=XWindowByID(display,root_window,
13864 (Window) strtol((
char *) resources.window_id,(
char **) NULL,0));
13865 if (window_info.id == (Window) NULL)
13866 window_info.id=XWindowByName(display,root_window,resources.window_id);
13868 if (window_info.id == (Window) NULL)
13870 ThrowXWindowException(XServerError,
"NoWindowWithSpecifiedIDExists",
13871 resources.window_id);
13872 return(MagickFalse);
13877 window_attributes.width=XDisplayWidth(display,XDefaultScreen(display));
13878 window_attributes.height=XDisplayHeight(display,XDefaultScreen(display));
13879 (void) CopyMagickString(visual_type,
"default",MagickPathExtent);
13880 status=XGetWindowAttributes(display,window_info.id,&window_attributes);
13882 (void) FormatLocaleString(visual_type,MagickPathExtent,
"0x%lx",
13883 XVisualIDFromVisual(window_attributes.visual));
13884 if (visual_info == (XVisualInfo *) NULL)
13889 map_info=XAllocStandardColormap();
13890 if (map_info == (XStandardColormap *) NULL)
13891 ThrowXWindowFatalException(XServerFatalError,
"MemoryAllocationFailed",
13893 map_info->colormap=(Colormap) NULL;
13894 pixel.pixels=(
unsigned long *) NULL;
13898 resources.map_type=(
char *) NULL;
13899 resources.visual_type=visual_type;
13900 visual_info=XBestVisualInfo(display,map_info,&resources);
13901 if (visual_info == (XVisualInfo *) NULL)
13902 ThrowXWindowFatalException(XServerFatalError,
"UnableToGetVisual",
13903 resources.visual_type);
13907 window_info.ximage=(XImage *) NULL;
13908 window_info.matte_image=(XImage *) NULL;
13909 window_info.pixmap=(Pixmap) NULL;
13910 window_info.matte_pixmap=(Pixmap) NULL;
13915 if (window_info.id == root_window)
13916 (void) XDestroyWindowColors(display,root_window);
13920 resources.colormap=SharedColormap;
13921 XMakeStandardColormap(display,visual_info,&resources,image,map_info,&pixel,
13926 context_values.background=pixel.foreground_color.pixel;
13927 context_values.foreground=pixel.background_color.pixel;
13928 pixel.annotate_context=XCreateGC(display,window_info.id,
13929 (
size_t) (GCBackground | GCForeground),&context_values);
13930 if (pixel.annotate_context == (GC) NULL)
13931 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
13936 window_info.name=AcquireString(
"\0");
13937 window_info.icon_name=AcquireString(
"\0");
13938 XGetWindowInfo(display,visual_info,map_info,&pixel,(XFontStruct *) NULL,
13939 &resources,&window_info);
13943 window_info.width=(
unsigned int) image->columns;
13944 window_info.height=(
unsigned int) image->rows;
13945 if ((image->columns != window_info.width) ||
13946 (image->rows != window_info.height))
13947 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
13949 (void) FormatLocaleString(geometry,MagickPathExtent,
"%ux%u+0+0>",
13950 window_attributes.width,window_attributes.height);
13951 geometry_info.width=window_info.width;
13952 geometry_info.height=window_info.height;
13953 geometry_info.x=(ssize_t) window_info.x;
13954 geometry_info.y=(ssize_t) window_info.y;
13955 (void) ParseMetaGeometry(geometry,&geometry_info.x,&geometry_info.y,
13956 &geometry_info.width,&geometry_info.height);
13957 window_info.width=(
unsigned int) geometry_info.width;
13958 window_info.height=(
unsigned int) geometry_info.height;
13959 window_info.x=(int) geometry_info.x;
13960 window_info.y=(int) geometry_info.y;
13961 status=XMakeImage(display,&resources,&window_info,image,window_info.width,
13962 window_info.height,exception) == MagickFalse ? 0 : 1;
13963 if (status == MagickFalse)
13964 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
13968 if (resource_info->debug != MagickFalse)
13970 (void) LogMagickEvent(X11Event,GetMagickModule(),
13971 "Image: %s[%.20g] %.20gx%.20g ",image->filename,(double) image->scene,
13972 (
double) image->columns,(double) image->rows);
13973 if (image->colors != 0)
13974 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%.20gc ",(double)
13976 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%s",image->magick);
13981 width=(int) window_info.width;
13982 height=(int) window_info.height;
13983 if (resources.backdrop != MagickFalse)
13988 window_info.x=(window_attributes.width/2)-(window_info.ximage->width/2);
13989 window_info.y=(window_attributes.height/2)-(window_info.ximage->height/2);
13990 width=window_attributes.width;
13991 height=window_attributes.height;
13993 if ((resources.image_geometry != (
char *) NULL) &&
13994 (*resources.image_geometry !=
'\0'))
13997 default_geometry[MagickPathExtent];
14009 size_hints=XAllocSizeHints();
14010 if (size_hints == (XSizeHints *) NULL)
14011 ThrowXWindowFatalException(ResourceLimitFatalError,
14012 "MemoryAllocationFailed",image->filename);
14013 size_hints->flags=0L;
14014 (void) FormatLocaleString(default_geometry,MagickPathExtent,
"%dx%d",
14016 flags=XWMGeometry(display,visual_info->screen,resources.image_geometry,
14017 default_geometry,window_info.border_width,size_hints,&window_info.x,
14018 &window_info.y,&width,&height,&gravity);
14019 if (flags & (XValue | YValue))
14021 width=window_attributes.width;
14022 height=window_attributes.height;
14024 (void) XFree((
void *) size_hints);
14029 window_info.pixmap=XCreatePixmap(display,window_info.id,(
unsigned int) width,
14030 (
unsigned int) height,window_info.depth);
14031 if (window_info.pixmap == (Pixmap) NULL)
14032 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXPixmap",
14037 if (((
unsigned int) width > window_info.width) ||
14038 ((
unsigned int) height > window_info.height))
14039 (void) XFillRectangle(display,window_info.pixmap,
14040 window_info.annotate_context,0,0,(
unsigned int) width,
14041 (
unsigned int) height);
14042 (void) XPutImage(display,window_info.pixmap,window_info.annotate_context,
14043 window_info.ximage,0,0,window_info.x,window_info.y,(
unsigned int)
14044 window_info.width,(
unsigned int) window_info.height);
14045 (void) XSetWindowBackgroundPixmap(display,window_info.id,window_info.pixmap);
14046 (void) XClearWindow(display,window_info.id);
14047 delay=1000*image->delay/(size_t) MagickMax(image->ticks_per_second,1L);
14048 XDelay(display,delay == 0UL ? 10UL : delay);
14049 (void) XSync(display,MagickFalse);
14050 return(window_info.id == root_window ? MagickTrue : MagickFalse);
14093MagickExport
Image *XDisplayImage(Display *display,XResourceInfo *resource_info,
14096#define MagnifySize 256
14097#define MagickMenus 10
14098#define MagickTitle "Commands"
14101 *
const CommandMenu[] =
14115 *
const FileMenu[] =
14125 "Visual Directory...",
14129 *
const EditMenu[] =
14138 *
const ViewMenu[] =
14149 *
const TransformMenu[] =
14163 *
const EnhanceMenu[] =
14171 "Contrast Stretch...",
14172 "Sigmoidal Contrast...",
14181 *
const EffectsMenu[] =
14206 "Charcoal Draw...",
14209 *
const ImageEditMenu[] =
14220 "Region of Interest...",
14223 *
const MiscellanyMenu[] =
14235 *
const HelpMenu[] =
14238 "Browse Documentation",
14242 *
const ShortCutsMenu[] =
14255 *
const VirtualMenu[] =
14265 *
const *Menus[MagickMenus] =
14279 static DisplayCommand
14303 VisualDirectoryCommand,
14317 OriginalSizeCommand,
14324 TransformCommands[] =
14330 RotateRightCommand,
14337 EnhanceCommands[] =
14345 ContrastStretchCommand,
14346 SigmoidalContrastCommand,
14354 EffectsCommands[] =
14358 ReduceNoiseCommand,
14378 CharcoalDrawCommand
14380 ImageEditCommands[] =
14391 RegionOfInterestCommand
14393 MiscellanyCommands[] =
14397 ShowPreviewCommand,
14398 ShowHistogramCommand,
14407 BrowseDocumentationCommand,
14410 ShortCutsCommands[] =
14422 VirtualCommands[] =
14430 static DisplayCommand
14431 *Commands[MagickMenus] =
14441 MiscellanyCommands,
14446 command[MagickPathExtent],
14448 geometry[MagickPathExtent],
14449 resource_name[MagickPathExtent];
14476 working_directory[MagickPathExtent];
14482 *magick_windows[MaxXWindows];
14484 static unsigned int
14544 assert(image != (
Image **) NULL);
14545 assert((*image)->signature == MagickCoreSignature);
14546 if (IsEventLogging() != MagickFalse)
14547 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",(*image)->filename);
14548 display_image=(*image);
14549 warning_handler=(WarningHandler) NULL;
14550 windows=XSetWindows((XWindows *) ~0);
14551 if (windows != (XWindows *) NULL)
14556 if (*working_directory ==
'\0')
14557 (void) CopyMagickString(working_directory,
".",MagickPathExtent);
14558 status=chdir(working_directory);
14560 (void) ThrowMagickException(exception,GetMagickModule(),FileOpenError,
14561 "UnableToOpenFile",
"%s",working_directory);
14562 warning_handler=resource_info->display_warnings ?
14563 SetErrorHandler(XWarning) : SetErrorHandler((ErrorHandler) NULL);
14564 warning_handler=resource_info->display_warnings ?
14565 SetWarningHandler(XWarning) : SetWarningHandler((WarningHandler) NULL);
14572 resource_info->colors=display_image->colors;
14573 windows=XSetWindows(XInitializeWindows(display,resource_info));
14574 if (windows == (XWindows *) NULL)
14575 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateWindow",
14576 (*image)->filename);
14581 magick_windows[number_windows++]=(&windows->icon);
14582 magick_windows[number_windows++]=(&windows->backdrop);
14583 magick_windows[number_windows++]=(&windows->image);
14584 magick_windows[number_windows++]=(&windows->info);
14585 magick_windows[number_windows++]=(&windows->command);
14586 magick_windows[number_windows++]=(&windows->widget);
14587 magick_windows[number_windows++]=(&windows->popup);
14588 magick_windows[number_windows++]=(&windows->magnify);
14589 magick_windows[number_windows++]=(&windows->pan);
14590 for (i=0; i < (int) number_windows; i++)
14591 magick_windows[i]->
id=(Window) NULL;
14598 if (windows->font_info != (XFontStruct *) NULL)
14599 (
void) XFreeFont(display,windows->font_info);
14600 windows->font_info=XBestFont(display,resource_info,MagickFalse);
14601 if (windows->font_info == (XFontStruct *) NULL)
14602 ThrowXWindowFatalException(XServerFatalError,
"UnableToLoadFont",
14603 resource_info->font);
14607 map_info=windows->map_info;
14608 icon_map=windows->icon_map;
14609 visual_info=windows->visual_info;
14610 icon_visual=windows->icon_visual;
14611 pixel=windows->pixel_info;
14612 icon_pixel=windows->icon_pixel;
14613 font_info=windows->font_info;
14614 icon_resources=windows->icon_resources;
14615 class_hints=windows->class_hints;
14616 manager_hints=windows->manager_hints;
14617 root_window=XRootWindow(display,visual_info->screen);
14618 nexus=NewImageList();
14619 if (resource_info->debug != MagickFalse)
14621 (void) LogMagickEvent(X11Event,GetMagickModule(),
14622 "Image: %s[%.20g] %.20gx%.20g ",display_image->filename,
14623 (double) display_image->scene,(
double) display_image->columns,
14624 (double) display_image->rows);
14625 if (display_image->colors != 0)
14626 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%.20gc ",(double)
14627 display_image->colors);
14628 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%s",
14629 display_image->magick);
14631 XMakeStandardColormap(display,visual_info,resource_info,display_image,
14632 map_info,pixel,exception);
14633 display_image->taint=MagickFalse;
14637 windows->context.id=(Window) NULL;
14638 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14639 resource_info,&windows->context);
14640 (void) CloneString(&class_hints->res_name,resource_info->client_name);
14641 (void) CloneString(&class_hints->res_class,resource_info->client_name);
14642 class_hints->res_class[0]=(char) LocaleToUppercase((
int)
14643 class_hints->res_class[0]);
14644 manager_hints->flags=InputHint | StateHint;
14645 manager_hints->input=MagickFalse;
14646 manager_hints->initial_state=WithdrawnState;
14647 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14648 &windows->context);
14649 if (resource_info->debug != MagickFalse)
14650 (void) LogMagickEvent(X11Event,GetMagickModule(),
14651 "Window id: 0x%lx (context)",windows->context.id);
14652 context_values.background=pixel->background_color.pixel;
14653 context_values.font=font_info->fid;
14654 context_values.foreground=pixel->foreground_color.pixel;
14655 context_values.graphics_exposures=MagickFalse;
14656 context_mask=(MagickStatusType)
14657 (GCBackground | GCFont | GCForeground | GCGraphicsExposures);
14658 if (pixel->annotate_context != (GC) NULL)
14659 (
void) XFreeGC(display,pixel->annotate_context);
14660 pixel->annotate_context=XCreateGC(display,windows->context.id,
14661 context_mask,&context_values);
14662 if (pixel->annotate_context == (GC) NULL)
14663 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14664 display_image->filename);
14665 context_values.background=pixel->depth_color.pixel;
14666 if (pixel->widget_context != (GC) NULL)
14667 (void) XFreeGC(display,pixel->widget_context);
14668 pixel->widget_context=XCreateGC(display,windows->context.id,context_mask,
14670 if (pixel->widget_context == (GC) NULL)
14671 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14672 display_image->filename);
14673 context_values.background=pixel->foreground_color.pixel;
14674 context_values.foreground=pixel->background_color.pixel;
14675 context_values.plane_mask=context_values.background ^
14676 context_values.foreground;
14677 if (pixel->highlight_context != (GC) NULL)
14678 (void) XFreeGC(display,pixel->highlight_context);
14679 pixel->highlight_context=XCreateGC(display,windows->context.id,
14680 (
size_t) (context_mask | GCPlaneMask),&context_values);
14681 if (pixel->highlight_context == (GC) NULL)
14682 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14683 display_image->filename);
14684 (void) XDestroyWindow(display,windows->context.id);
14688 XGetWindowInfo(display,icon_visual,icon_map,icon_pixel,(XFontStruct *) NULL,
14689 icon_resources,&windows->icon);
14690 windows->icon.geometry=resource_info->icon_geometry;
14691 XBestIconSize(display,&windows->icon,display_image);
14692 windows->icon.attributes.colormap=XDefaultColormap(display,
14693 icon_visual->screen);
14694 windows->icon.attributes.event_mask=ExposureMask | StructureNotifyMask;
14695 manager_hints->flags=InputHint | StateHint;
14696 manager_hints->input=MagickFalse;
14697 manager_hints->initial_state=IconicState;
14698 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14700 if (resource_info->debug != MagickFalse)
14701 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (icon)",
14706 if (icon_pixel->annotate_context != (GC) NULL)
14707 (
void) XFreeGC(display,icon_pixel->annotate_context);
14708 context_values.background=icon_pixel->background_color.pixel;
14709 context_values.foreground=icon_pixel->foreground_color.pixel;
14710 icon_pixel->annotate_context=XCreateGC(display,windows->icon.id,
14711 (
size_t) (GCBackground | GCForeground),&context_values);
14712 if (icon_pixel->annotate_context == (GC) NULL)
14713 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14714 display_image->filename);
14715 windows->icon.annotate_context=icon_pixel->annotate_context;
14719 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,resource_info,
14721 windows->image.shape=MagickTrue;
14722 if (resource_info->use_shared_memory == MagickFalse)
14723 windows->image.shared_memory=MagickFalse;
14724 if ((resource_info->title != (
char *) NULL) && !(*state & MontageImageState))
14729 title=InterpretImageProperties(resource_info->image_info,display_image,
14730 resource_info->title,exception);
14731 (void) CloneString(&windows->image.name,title);
14732 (void) CloneString(&windows->image.icon_name,title);
14733 title=DestroyString(title);
14738 filename[MagickPathExtent],
14739 window_name[MagickPathExtent];
14744 GetPathComponent(display_image->magick_filename,TailPath,filename);
14745 if (display_image->scene == 0)
14746 (void) FormatLocaleString(window_name,MagickPathExtent,
"%s: %s",
14747 MagickPackageName,filename);
14749 (
void) FormatLocaleString(window_name,MagickPathExtent,
14750 "%s: %s[scene: %.20g frames: %.20g]",MagickPackageName,filename,
14751 (
double) display_image->scene,(
double) GetImageListLength(
14753 (void) CloneString(&windows->image.name,window_name);
14754 (void) CloneString(&windows->image.icon_name,filename);
14756 if (resource_info->immutable)
14757 windows->image.immutable=MagickTrue;
14758 windows->image.use_pixmap=resource_info->use_pixmap;
14759 windows->image.geometry=resource_info->image_geometry;
14760 (void) FormatLocaleString(geometry,MagickPathExtent,
"%ux%u+0+0>!",
14761 XDisplayWidth(display,visual_info->screen),
14762 XDisplayHeight(display,visual_info->screen));
14763 geometry_info.width=display_image->columns;
14764 geometry_info.height=display_image->rows;
14767 (void) ParseMetaGeometry(geometry,&geometry_info.x,&geometry_info.y,
14768 &geometry_info.width,&geometry_info.height);
14769 windows->image.width=(
unsigned int) geometry_info.width;
14770 windows->image.height=(
unsigned int) geometry_info.height;
14771 windows->image.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14772 ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
14773 KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask |
14774 PropertyChangeMask | StructureNotifyMask | SubstructureNotifyMask;
14775 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14776 resource_info,&windows->backdrop);
14777 if ((resource_info->backdrop) || (windows->backdrop.id != (Window) NULL))
14782 windows->backdrop.x=0;
14783 windows->backdrop.y=0;
14784 (void) CloneString(&windows->backdrop.name,
"Backdrop");
14785 windows->backdrop.flags=(size_t) (USSize | USPosition);
14786 windows->backdrop.width=(
unsigned int)
14787 XDisplayWidth(display,visual_info->screen);
14788 windows->backdrop.height=(
unsigned int)
14789 XDisplayHeight(display,visual_info->screen);
14790 windows->backdrop.border_width=0;
14791 windows->backdrop.immutable=MagickTrue;
14792 windows->backdrop.attributes.do_not_propagate_mask=ButtonPressMask |
14794 windows->backdrop.attributes.event_mask=ButtonPressMask | KeyPressMask |
14795 StructureNotifyMask;
14796 manager_hints->flags=IconWindowHint | InputHint | StateHint;
14797 manager_hints->icon_window=windows->icon.id;
14798 manager_hints->input=MagickTrue;
14799 manager_hints->initial_state=resource_info->iconic ? IconicState :
14801 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14802 &windows->backdrop);
14803 if (resource_info->debug != MagickFalse)
14804 (void) LogMagickEvent(X11Event,GetMagickModule(),
14805 "Window id: 0x%lx (backdrop)",windows->backdrop.id);
14806 (void) XMapWindow(display,windows->backdrop.id);
14807 (void) XClearWindow(display,windows->backdrop.id);
14808 if (windows->image.id != (Window) NULL)
14810 (void) XDestroyWindow(display,windows->image.id);
14811 windows->image.id=(Window) NULL;
14816 windows->image.flags|=USPosition;
14817 windows->image.x=(XDisplayWidth(display,visual_info->screen)/2)-
14818 ((
int) windows->image.width/2);
14819 windows->image.y=(XDisplayHeight(display,visual_info->screen)/2)-
14820 ((
int) windows->image.height/2);
14822 manager_hints->flags=IconWindowHint | InputHint | StateHint;
14823 manager_hints->icon_window=windows->icon.id;
14824 manager_hints->input=MagickTrue;
14825 manager_hints->initial_state=resource_info->iconic ? IconicState :
14827 if (windows->group_leader.id != (Window) NULL)
14832 manager_hints->flags|=WindowGroupHint;
14833 manager_hints->window_group=windows->group_leader.id;
14834 (void) XSelectInput(display,windows->group_leader.id,StructureNotifyMask);
14835 if (resource_info->debug != MagickFalse)
14836 (void) LogMagickEvent(X11Event,GetMagickModule(),
14837 "Window id: 0x%lx (group leader)",windows->group_leader.id);
14839 XMakeWindow(display,
14840 (Window) (resource_info->backdrop ? windows->backdrop.id : root_window),
14841 argv,argc,class_hints,manager_hints,&windows->image);
14842 (void) XChangeProperty(display,windows->image.id,windows->im_protocols,
14843 XA_STRING,8,PropModeReplace,(
unsigned char *) NULL,0);
14844 if (windows->group_leader.id != (Window) NULL)
14845 (
void) XSetTransientForHint(display,windows->image.id,
14846 windows->group_leader.id);
14847 if (resource_info->debug != MagickFalse)
14848 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (image)",
14849 windows->image.id);
14853 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,resource_info,
14855 (void) CloneString(&windows->info.name,
"Info");
14856 (void) CloneString(&windows->info.icon_name,
"Info");
14857 windows->info.border_width=1;
14860 windows->info.flags|=PPosition;
14861 windows->info.attributes.win_gravity=UnmapGravity;
14862 windows->info.attributes.event_mask=ButtonPressMask | ExposureMask |
14863 StructureNotifyMask;
14864 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14865 manager_hints->input=MagickFalse;
14866 manager_hints->initial_state=NormalState;
14867 manager_hints->window_group=windows->image.id;
14868 XMakeWindow(display,windows->image.id,argv,argc,class_hints,manager_hints,
14870 windows->info.highlight_stipple=XCreateBitmapFromData(display,
14871 windows->info.id,(
char *) HighlightBitmap,HighlightWidth,HighlightHeight);
14872 windows->info.shadow_stipple=XCreateBitmapFromData(display,
14873 windows->info.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14874 (void) XSetTransientForHint(display,windows->info.id,windows->image.id);
14875 if (windows->image.mapped != MagickFalse)
14876 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
14877 if (resource_info->debug != MagickFalse)
14878 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (info)",
14883 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14884 resource_info,&windows->command);
14885 windows->command.data=MagickMenus;
14886 (void) XCommandWidget(display,windows,CommandMenu,(XEvent *) NULL);
14887 (void) FormatLocaleString(resource_name,MagickPathExtent,
"%s.command",
14888 resource_info->client_name);
14889 windows->command.geometry=XGetResourceClass(resource_info->resource_database,
14890 resource_name,
"geometry",(
char *) NULL);
14891 (void) CloneString(&windows->command.name,MagickTitle);
14892 windows->command.border_width=0;
14893 windows->command.flags|=PPosition;
14894 windows->command.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14895 ButtonReleaseMask | EnterWindowMask | ExposureMask | LeaveWindowMask |
14896 OwnerGrabButtonMask | StructureNotifyMask;
14897 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14898 manager_hints->input=MagickTrue;
14899 manager_hints->initial_state=NormalState;
14900 manager_hints->window_group=windows->image.id;
14901 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14902 &windows->command);
14903 windows->command.highlight_stipple=XCreateBitmapFromData(display,
14904 windows->command.id,(
char *) HighlightBitmap,HighlightWidth,
14906 windows->command.shadow_stipple=XCreateBitmapFromData(display,
14907 windows->command.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14908 (void) XSetTransientForHint(display,windows->command.id,windows->image.id);
14909 if (windows->command.mapped != MagickFalse)
14910 (void) XMapRaised(display,windows->command.id);
14911 if (resource_info->debug != MagickFalse)
14912 (void) LogMagickEvent(X11Event,GetMagickModule(),
14913 "Window id: 0x%lx (command)",windows->command.id);
14917 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14918 resource_info,&windows->widget);
14919 (void) FormatLocaleString(resource_name,MagickPathExtent,
"%s.widget",
14920 resource_info->client_name);
14921 windows->widget.geometry=XGetResourceClass(resource_info->resource_database,
14922 resource_name,
"geometry",(
char *) NULL);
14923 windows->widget.border_width=0;
14924 windows->widget.flags|=PPosition;
14925 windows->widget.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14926 ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
14927 KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask |
14928 StructureNotifyMask;
14929 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14930 manager_hints->input=MagickTrue;
14931 manager_hints->initial_state=NormalState;
14932 manager_hints->window_group=windows->image.id;
14933 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14935 windows->widget.highlight_stipple=XCreateBitmapFromData(display,
14936 windows->widget.id,(
char *) HighlightBitmap,HighlightWidth,HighlightHeight);
14937 windows->widget.shadow_stipple=XCreateBitmapFromData(display,
14938 windows->widget.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14939 (void) XSetTransientForHint(display,windows->widget.id,windows->image.id);
14940 if (resource_info->debug != MagickFalse)
14941 (void) LogMagickEvent(X11Event,GetMagickModule(),
14942 "Window id: 0x%lx (widget)",windows->widget.id);
14946 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14947 resource_info,&windows->popup);
14948 windows->popup.border_width=0;
14949 windows->popup.flags|=PPosition;
14950 windows->popup.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14951 ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
14952 KeyReleaseMask | LeaveWindowMask | StructureNotifyMask;
14953 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14954 manager_hints->input=MagickTrue;
14955 manager_hints->initial_state=NormalState;
14956 manager_hints->window_group=windows->image.id;
14957 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14959 windows->popup.highlight_stipple=XCreateBitmapFromData(display,
14960 windows->popup.id,(
char *) HighlightBitmap,HighlightWidth,HighlightHeight);
14961 windows->popup.shadow_stipple=XCreateBitmapFromData(display,
14962 windows->popup.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14963 (void) XSetTransientForHint(display,windows->popup.id,windows->image.id);
14964 if (resource_info->debug != MagickFalse)
14965 (void) LogMagickEvent(X11Event,GetMagickModule(),
14966 "Window id: 0x%lx (pop up)",windows->popup.id);
14970 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14971 resource_info,&windows->magnify);
14972 if (resource_info->use_shared_memory == MagickFalse)
14973 windows->magnify.shared_memory=MagickFalse;
14974 (void) FormatLocaleString(resource_name,MagickPathExtent,
"%s.magnify",
14975 resource_info->client_name);
14976 windows->magnify.geometry=XGetResourceClass(resource_info->resource_database,
14977 resource_name,
"geometry",(
char *) NULL);
14978 (void) FormatLocaleString(windows->magnify.name,MagickPathExtent,
14979 "Magnify %uX",resource_info->magnify);
14980 if (windows->magnify.cursor != (Cursor) NULL)
14981 (
void) XFreeCursor(display,windows->magnify.cursor);
14982 windows->magnify.cursor=XMakeCursor(display,windows->image.id,
14983 map_info->colormap,resource_info->background_color,
14984 resource_info->foreground_color);
14985 if (windows->magnify.cursor == (Cursor) NULL)
14986 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateCursor",
14987 display_image->filename);
14988 windows->magnify.width=MagnifySize;
14989 windows->magnify.height=MagnifySize;
14990 windows->magnify.flags|=PPosition;
14991 windows->magnify.min_width=MagnifySize;
14992 windows->magnify.min_height=MagnifySize;
14993 windows->magnify.width_inc=MagnifySize;
14994 windows->magnify.height_inc=MagnifySize;
14995 windows->magnify.data=resource_info->magnify;
14996 windows->magnify.attributes.cursor=windows->magnify.cursor;
14997 windows->magnify.attributes.event_mask=ButtonPressMask | ButtonReleaseMask |
14998 ExposureMask | KeyPressMask | KeyReleaseMask | OwnerGrabButtonMask |
14999 StructureNotifyMask;
15000 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
15001 manager_hints->input=MagickTrue;
15002 manager_hints->initial_state=NormalState;
15003 manager_hints->window_group=windows->image.id;
15004 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
15005 &windows->magnify);
15006 if (resource_info->debug != MagickFalse)
15007 (void) LogMagickEvent(X11Event,GetMagickModule(),
15008 "Window id: 0x%lx (magnify)",windows->magnify.id);
15009 (void) XSetTransientForHint(display,windows->magnify.id,windows->image.id);
15013 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
15014 resource_info,&windows->pan);
15015 (void) CloneString(&windows->pan.name,
"Pan Icon");
15016 windows->pan.width=windows->icon.width;
15017 windows->pan.height=windows->icon.height;
15018 (void) FormatLocaleString(resource_name,MagickPathExtent,
"%s.pan",
15019 resource_info->client_name);
15020 windows->pan.geometry=XGetResourceClass(resource_info->resource_database,
15021 resource_name,
"geometry",(
char *) NULL);
15022 (void) XParseGeometry(windows->pan.geometry,&windows->pan.x,&windows->pan.y,
15023 &windows->pan.width,&windows->pan.height);
15024 windows->pan.flags|=PPosition;
15025 windows->pan.immutable=MagickTrue;
15026 windows->pan.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
15027 ButtonReleaseMask | ExposureMask | KeyPressMask | KeyReleaseMask |
15028 StructureNotifyMask;
15029 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
15030 manager_hints->input=MagickFalse;
15031 manager_hints->initial_state=NormalState;
15032 manager_hints->window_group=windows->image.id;
15033 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
15035 if (resource_info->debug != MagickFalse)
15036 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (pan)",
15038 (void) XSetTransientForHint(display,windows->pan.id,windows->image.id);
15039 if (windows->info.mapped != MagickFalse)
15040 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
15041 if ((windows->image.mapped == MagickFalse) ||
15042 (windows->backdrop.id != (Window) NULL))
15043 (
void) XMapWindow(display,windows->image.id);
15047 if (warning_handler == (WarningHandler) NULL)
15049 warning_handler=resource_info->display_warnings ?
15050 SetErrorHandler(XWarning) : SetErrorHandler((ErrorHandler) NULL);
15051 warning_handler=resource_info->display_warnings ?
15052 SetWarningHandler(XWarning) : SetWarningHandler((WarningHandler) NULL);
15057 windows->image.x=0;
15058 windows->image.y=0;
15059 windows->magnify.shape=MagickFalse;
15060 width=(
unsigned int) display_image->columns;
15061 height=(
unsigned int) display_image->rows;
15062 if ((display_image->columns != width) || (display_image->rows != height))
15063 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
15064 display_image->filename);
15065 status=XMakeImage(display,resource_info,&windows->image,display_image,
15066 width,height,exception);
15067 if (status == MagickFalse)
15068 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
15069 display_image->filename);
15070 status=XMakeImage(display,resource_info,&windows->magnify,(
Image *) NULL,
15071 windows->magnify.width,windows->magnify.height,exception);
15072 if (status == MagickFalse)
15073 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
15074 display_image->filename);
15075 if (windows->magnify.mapped != MagickFalse)
15076 (void) XMapRaised(display,windows->magnify.id);
15077 if (windows->pan.mapped != MagickFalse)
15078 (void) XMapRaised(display,windows->pan.id);
15079 windows->image.window_changes.width=(int) display_image->columns;
15080 windows->image.window_changes.height=(int) display_image->rows;
15081 (void) XConfigureImage(display,resource_info,windows,display_image,exception);
15082 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
15083 (void) XSync(display,MagickFalse);
15087 delay=display_image->delay/(size_t)
15088 MagickMax(display_image->ticks_per_second,1L);
15089 timer=GetMagickTime()+(time_t) (delay == 0 ? 1 : delay)+1;
15091 if (resource_info->update != MagickFalse)
15099 status=GetPathAttributes(display_image->filename,&attributes);
15100 if (status != MagickFalse)
15101 update_time=attributes.st_mtime;
15103 *state&=(
unsigned int) (~FormerImageState);
15104 *state&=(
unsigned int) (~MontageImageState);
15105 *state&=(
unsigned int) (~NextImageState);
15111 if (windows->image.mapped != MagickFalse)
15112 if ((display_image->delay != 0) || (resource_info->update != 0))
15114 if (timer < GetMagickTime())
15116 if (resource_info->update == MagickFalse)
15117 *state|=NextImageState | ExitState;
15126 status=GetPathAttributes(display_image->filename,&attributes);
15127 if (status != MagickFalse)
15128 if (update_time != attributes.st_mtime)
15133 (void) FormatLocaleString(
15134 resource_info->image_info->filename,MagickPathExtent,
15135 "%s:%s",display_image->magick,
15136 display_image->filename);
15137 nexus=ReadImage(resource_info->image_info,exception);
15138 if (nexus != (
Image *) NULL)
15139 *state|=NextImageState | ExitState;
15141 delay=display_image->delay/(size_t) MagickMax(
15142 display_image->ticks_per_second,1L);
15143 timer=GetMagickTime()+(time_t) (delay == 0 ? 1 : delay)+1;
15146 if (XEventsQueued(display,QueuedAfterFlush) == 0)
15151 XDelay(display,SuspendTime << 2);
15155 timestamp=GetMagickTime();
15156 (void) XNextEvent(display,&event);
15157 if ((windows->image.stasis == MagickFalse) ||
15158 (windows->magnify.stasis == MagickFalse))
15160 if ((GetMagickTime()-timestamp) > 0)
15162 windows->image.stasis=MagickTrue;
15163 windows->magnify.stasis=MagickTrue;
15166 if (event.xany.window == windows->command.id)
15171 id=XCommandWidget(display,windows,CommandMenu,&event);
15174 (void) CopyMagickString(command,CommandMenu[
id],MagickPathExtent);
15175 display_command=CommandMenus[id];
15176 if (
id < MagickMenus)
15181 entry=XMenuWidget(display,windows,CommandMenu[
id],Menus[
id],
15185 (void) CopyMagickString(command,Menus[
id][entry],MagickPathExtent);
15186 display_command=Commands[id][entry];
15188 if (display_command != NullCommand)
15189 nexus=XMagickCommand(display,resource_info,windows,display_command,
15190 &display_image,exception);
15193 switch (event.type)
15197 if (resource_info->debug != MagickFalse)
15198 (void) LogMagickEvent(X11Event,GetMagickModule(),
15199 "Button Press: 0x%lx %u +%d+%d",
event.xbutton.window,
15200 event.xbutton.button,
event.xbutton.x,
event.xbutton.y);
15201 if ((event.xbutton.button == Button3) &&
15202 (
event.xbutton.state & Mod1Mask))
15207 event.xbutton.button=Button2;
15208 event.xbutton.state&=(
unsigned int) (~Mod1Mask);
15210 if (event.xbutton.window == windows->backdrop.id)
15212 (void) XSetInputFocus(display,event.xbutton.window,RevertToParent,
15213 event.xbutton.time);
15216 if (event.xbutton.window == windows->image.id)
15218 switch (event.xbutton.button)
15222 if (resource_info->immutable)
15227 entry=XMenuWidget(display,windows,
"Commands",VirtualMenu,
15230 nexus=XMagickCommand(display,resource_info,windows,
15231 VirtualCommands[entry],&display_image,exception);
15237 if (windows->command.mapped != MagickFalse)
15238 (void) XWithdrawWindow(display,windows->command.id,
15239 windows->command.screen);
15242 (void) XCommandWidget(display,windows,CommandMenu,
15244 (void) XMapRaised(display,windows->command.id);
15253 (void) XMagickCommand(display,resource_info,windows,ZoomCommand,
15254 &display_image,exception);
15255 XMagnifyImage(display,windows,&event,exception);
15260 if (resource_info->immutable)
15265 entry=XMenuWidget(display,windows,
"Commands",VirtualMenu,
15268 nexus=XMagickCommand(display,resource_info,windows,
15269 VirtualCommands[entry],&display_image,exception);
15272 if (display_image->montage != (
char *) NULL)
15277 nexus=XTileImage(display,resource_info,windows,
15278 display_image,&event,exception);
15279 if (nexus != (
Image *) NULL)
15280 *state|=MontageImageState | NextImageState | ExitState;
15281 vid_info.x=(
short int) windows->image.x;
15282 vid_info.y=(
short int) windows->image.y;
15288 entry=XMenuWidget(display,windows,
"Short Cuts",ShortCutsMenu,
15291 nexus=XMagickCommand(display,resource_info,windows,
15292 ShortCutsCommands[entry],&display_image,exception);
15300 XTranslateImage(display,windows,*image,XK_Up);
15308 XTranslateImage(display,windows,*image,XK_Down);
15316 if (event.xbutton.window == windows->magnify.id)
15319 *
const MagnifyMenu[] =
15336 MagnifyCommands[] =
15351 factor=XMenuWidget(display,windows,
"Magnify",MagnifyMenu,command);
15353 XMagnifyWindowCommand(display,windows,0,MagnifyCommands[factor],
15357 if (event.xbutton.window == windows->pan.id)
15359 switch (event.xbutton.button)
15366 XTranslateImage(display,windows,*image,XK_Up);
15374 XTranslateImage(display,windows,*image,XK_Down);
15379 XPanImage(display,windows,&event,exception);
15385 delay=display_image->delay/(size_t)
15386 MagickMax(display_image->ticks_per_second,1L);
15387 timer=GetMagickTime()+(time_t) (delay == 0 ? 1 : delay)+1;
15390 case ButtonRelease:
15392 if (resource_info->debug != MagickFalse)
15393 (void) LogMagickEvent(X11Event,GetMagickModule(),
15394 "Button Release: 0x%lx %u +%d+%d",
event.xbutton.window,
15395 event.xbutton.button,
event.xbutton.x,
event.xbutton.y);
15398 case ClientMessage:
15400 if (resource_info->debug != MagickFalse)
15401 (void) LogMagickEvent(X11Event,GetMagickModule(),
15402 "Client Message: 0x%lx 0x%lx %d 0x%lx",
event.xclient.window,
15403 event.xclient.message_type,
event.xclient.format,(
unsigned long)
15404 event.xclient.data.l[0]);
15405 if (event.xclient.message_type == windows->im_protocols)
15407 if (*event.xclient.data.l == (
long) windows->im_update_widget)
15409 (void) CloneString(&windows->command.name,MagickTitle);
15410 windows->command.data=MagickMenus;
15411 (void) XCommandWidget(display,windows,CommandMenu,
15415 if (*event.xclient.data.l == (
long) windows->im_update_colormap)
15420 for (i=0; i < (int) number_windows; i++)
15422 if (magick_windows[i]->
id == windows->icon.id)
15424 context_values.background=pixel->background_color.pixel;
15425 context_values.foreground=pixel->foreground_color.pixel;
15426 (void) XChangeGC(display,magick_windows[i]->annotate_context,
15427 context_mask,&context_values);
15428 (void) XChangeGC(display,magick_windows[i]->widget_context,
15429 context_mask,&context_values);
15430 context_values.background=pixel->foreground_color.pixel;
15431 context_values.foreground=pixel->background_color.pixel;
15432 context_values.plane_mask=context_values.background ^
15433 context_values.foreground;
15434 (void) XChangeGC(display,magick_windows[i]->highlight_context,
15435 (
size_t) (context_mask | GCPlaneMask),
15437 magick_windows[i]->attributes.background_pixel=
15438 pixel->background_color.pixel;
15439 magick_windows[i]->attributes.border_pixel=
15440 pixel->border_color.pixel;
15441 magick_windows[i]->attributes.colormap=map_info->colormap;
15442 (void) XChangeWindowAttributes(display,magick_windows[i]->
id,
15443 (
unsigned long) magick_windows[i]->mask,
15444 &magick_windows[i]->attributes);
15446 if (windows->pan.mapped != MagickFalse)
15448 (void) XSetWindowBackgroundPixmap(display,windows->pan.id,
15449 windows->pan.pixmap);
15450 (void) XClearWindow(display,windows->pan.id);
15451 XDrawPanRectangle(display,windows);
15453 if (windows->backdrop.id != (Window) NULL)
15454 (void) XInstallColormap(display,map_info->colormap);
15457 if (*event.xclient.data.l == (
long) windows->im_former_image)
15459 *state|=FormerImageState | ExitState;
15462 if (*event.xclient.data.l == (
long) windows->im_next_image)
15464 *state|=NextImageState | ExitState;
15467 if (*event.xclient.data.l == (
long) windows->im_retain_colors)
15469 *state|=RetainColorsState;
15472 if (*event.xclient.data.l == (
long) windows->im_exit)
15479 if (event.xclient.message_type == windows->dnd_protocols)
15499 if ((*event.xclient.data.l != 2) && (*
event.xclient.data.l != 128))
15501 selection=XInternAtom(display,
"DndSelection",MagickFalse);
15502 status=XGetWindowProperty(display,root_window,selection,0L,(
long)
15503 MagickPathExtent,MagickFalse,(Atom) AnyPropertyType,&type,&format,
15504 &length,&after,&data);
15505 if ((status != Success) || (length == 0))
15507 if (*event.xclient.data.l == 2)
15512 (void) CopyMagickString(resource_info->image_info->filename,
15513 (
char *) data,MagickPathExtent);
15520 if (strncmp((
char *) data,
"file:", 5) != 0)
15522 (void) XFree((
void *) data);
15525 (void) CopyMagickString(resource_info->image_info->filename,
15526 ((
char *) data)+5,MagickPathExtent);
15528 nexus=ReadImage(resource_info->image_info,exception);
15529 CatchException(exception);
15530 if (nexus != (
Image *) NULL)
15531 *state|=NextImageState | ExitState;
15532 (void) XFree((
void *) data);
15538 if (event.xclient.message_type != windows->wm_protocols)
15540 if (*event.xclient.data.l != (
long) windows->wm_delete_window)
15542 (void) XWithdrawWindow(display,event.xclient.window,
15543 visual_info->screen);
15544 if (event.xclient.window == windows->image.id)
15549 if (event.xclient.window == windows->pan.id)
15554 windows->image.window_changes.width=windows->image.ximage->width;
15555 windows->image.window_changes.height=windows->image.ximage->height;
15556 (void) XConfigureImage(display,resource_info,windows,
15557 display_image,exception);
15561 case ConfigureNotify:
15563 if (resource_info->debug != MagickFalse)
15564 (void) LogMagickEvent(X11Event,GetMagickModule(),
15565 "Configure Notify: 0x%lx %dx%d+%d+%d %d",
event.xconfigure.window,
15566 event.xconfigure.width,
event.xconfigure.height,
event.xconfigure.x,
15567 event.xconfigure.y,
event.xconfigure.send_event);
15568 if (event.xconfigure.window == windows->image.id)
15573 if (event.xconfigure.send_event != 0)
15581 if (windows->command.geometry == (
char *) NULL)
15582 if (windows->command.mapped == MagickFalse)
15584 windows->command.x=
event.xconfigure.x-(int)
15585 windows->command.width-25;
15586 windows->command.y=
event.xconfigure.y;
15587 XConstrainWindowPosition(display,&windows->command);
15588 window_changes.x=windows->command.x;
15589 window_changes.y=windows->command.y;
15590 (void) XReconfigureWMWindow(display,windows->command.id,
15591 windows->command.screen,(
unsigned int) (CWX | CWY),
15594 if (windows->widget.geometry == (
char *) NULL)
15595 if (windows->widget.mapped == MagickFalse)
15597 windows->widget.x=
event.xconfigure.x+
15598 event.xconfigure.width/10;
15599 windows->widget.y=
event.xconfigure.y+
15600 event.xconfigure.height/10;
15601 XConstrainWindowPosition(display,&windows->widget);
15602 window_changes.x=windows->widget.x;
15603 window_changes.y=windows->widget.y;
15604 (void) XReconfigureWMWindow(display,windows->widget.id,
15605 windows->widget.screen,(
unsigned int) (CWX | CWY),
15608 if (windows->magnify.geometry == (
char *) NULL)
15609 if (windows->magnify.mapped == MagickFalse)
15611 windows->magnify.x=
event.xconfigure.x+
15612 event.xconfigure.width+25;
15613 windows->magnify.y=
event.xconfigure.y;
15614 XConstrainWindowPosition(display,&windows->magnify);
15615 window_changes.x=windows->magnify.x;
15616 window_changes.y=windows->magnify.y;
15617 (void) XReconfigureWMWindow(display,windows->magnify.id,
15618 windows->magnify.screen,(
unsigned int) (CWX | CWY),
15621 if (windows->pan.geometry == (
char *) NULL)
15622 if (windows->pan.mapped == MagickFalse)
15624 windows->pan.x=
event.xconfigure.x+(int)
15625 event.xconfigure.width+25;
15626 windows->pan.y=
event.xconfigure.y+(int)
15627 windows->magnify.height+50;
15628 XConstrainWindowPosition(display,&windows->pan);
15629 window_changes.x=windows->pan.x;
15630 window_changes.y=windows->pan.y;
15631 (void) XReconfigureWMWindow(display,windows->pan.id,
15632 windows->pan.screen,(
unsigned int) (CWX | CWY),
15636 if ((event.xconfigure.width == (
int) windows->image.width) &&
15637 (event.xconfigure.height == (
int) windows->image.height))
15639 windows->image.width=(
unsigned int) event.xconfigure.width;
15640 windows->image.height=(
unsigned int) event.xconfigure.height;
15641 windows->image.x=0;
15642 windows->image.y=0;
15643 if (display_image->montage != (
char *) NULL)
15645 windows->image.x=vid_info.x;
15646 windows->image.y=vid_info.y;
15648 if (windows->image.mapped != MagickFalse &&
15649 windows->image.stasis != MagickFalse)
15654 windows->image.window_changes.width=
event.xconfigure.width;
15655 windows->image.window_changes.height=
event.xconfigure.height;
15656 (void) XConfigureImage(display,resource_info,windows,
15657 display_image,exception);
15662 if ((event.xconfigure.width < windows->image.ximage->width) ||
15663 (
event.xconfigure.height < windows->image.ximage->height))
15665 (void) XMapRaised(display,windows->pan.id);
15666 XDrawPanRectangle(display,windows);
15669 if (windows->pan.mapped != MagickFalse)
15670 (void) XWithdrawWindow(display,windows->pan.id,
15671 windows->pan.screen);
15674 if (event.xconfigure.window == windows->magnify.id)
15682 windows->magnify.width=(
unsigned int) event.xconfigure.width;
15683 windows->magnify.height=(
unsigned int) event.xconfigure.height;
15684 if (windows->magnify.mapped == MagickFalse)
15687 while ((
int) magnify <= event.xconfigure.width)
15689 while ((
int) magnify <= event.xconfigure.height)
15692 if (((
int) magnify != event.xconfigure.width) ||
15693 ((
int) magnify != event.xconfigure.height))
15695 window_changes.width=(int) magnify;
15696 window_changes.height=(int) magnify;
15697 (void) XReconfigureWMWindow(display,windows->magnify.id,
15698 windows->magnify.screen,(
unsigned int) (CWWidth | CWHeight),
15702 if (windows->magnify.mapped != MagickFalse &&
15703 windows->magnify.stasis != MagickFalse)
15705 status=XMakeImage(display,resource_info,&windows->magnify,
15706 display_image,windows->magnify.width,windows->magnify.height,
15708 XMakeMagnifyImage(display,windows,exception);
15712 if (windows->magnify.mapped != MagickFalse &&
15713 (event.xconfigure.window == windows->pan.id))
15718 if (event.xconfigure.send_event != 0)
15720 windows->pan.x=
event.xconfigure.x;
15721 windows->pan.y=
event.xconfigure.y;
15723 windows->pan.width=(
unsigned int) event.xconfigure.width;
15724 windows->pan.height=(
unsigned int) event.xconfigure.height;
15727 if (event.xconfigure.window == windows->icon.id)
15732 windows->icon.width=(
unsigned int) event.xconfigure.width;
15733 windows->icon.height=(
unsigned int) event.xconfigure.height;
15738 case DestroyNotify:
15743 if (resource_info->debug != MagickFalse)
15744 (void) LogMagickEvent(X11Event,GetMagickModule(),
15745 "Destroy Notify: 0x%lx",
event.xdestroywindow.window);
15746 if (event.xdestroywindow.window == windows->group_leader.id)
15758 if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
15759 if (event.xcrossing.mode != NotifyUngrab)
15760 XInstallColormap(display,map_info->colormap);
15765 if (resource_info->debug != MagickFalse)
15766 (void) LogMagickEvent(X11Event,GetMagickModule(),
15767 "Expose: 0x%lx %dx%d+%d+%d",
event.xexpose.window,
15768 event.xexpose.width,
event.xexpose.height,
event.xexpose.x,
15773 if ((event.xexpose.window == windows->image.id) &&
15774 windows->image.mapped != MagickFalse)
15776 XRefreshWindow(display,&windows->image,&event);
15777 delay=display_image->delay/(size_t) MagickMax(
15778 display_image->ticks_per_second,1L);
15779 timer=GetMagickTime()+(time_t) (delay == 0 ? 1 : delay)+1;
15782 if ((event.xexpose.window == windows->magnify.id) &&
15783 windows->magnify.mapped != MagickFalse)
15785 XMakeMagnifyImage(display,windows,exception);
15788 if (event.xexpose.window == windows->pan.id)
15790 XDrawPanRectangle(display,windows);
15793 if (event.xexpose.window == windows->icon.id)
15795 XRefreshWindow(display,&windows->icon,&event);
15808 length=XLookupString((XKeyEvent *) &event.xkey,command,(
int)
15809 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
15810 *(command+length)=
'\0';
15811 if (resource_info->debug != MagickFalse)
15812 (void) LogMagickEvent(X11Event,GetMagickModule(),
15813 "Key press: %d 0x%lx (%s)",
event.xkey.state,(
unsigned long)
15814 key_symbol,command);
15815 if (event.xkey.window == windows->image.id)
15817 display_command=XImageWindowCommand(display,resource_info,windows,
15818 event.xkey.state,key_symbol,&display_image,exception);
15819 if (display_command != NullCommand)
15820 nexus=XMagickCommand(display,resource_info,windows,
15821 display_command,&display_image,exception);
15823 if (event.xkey.window == windows->magnify.id)
15824 XMagnifyWindowCommand(display,windows,event.xkey.state,key_symbol,
15826 if (event.xkey.window == windows->pan.id)
15828 if ((key_symbol == XK_q) || (key_symbol == XK_Escape))
15829 (void) XWithdrawWindow(display,windows->pan.id,
15830 windows->pan.screen);
15832 if ((key_symbol == XK_F1) || (key_symbol == XK_Help))
15833 XTextViewHelp(display,resource_info,windows,MagickFalse,
15834 "Help Viewer - Image Pan",ImagePanHelp);
15836 XTranslateImage(display,windows,*image,key_symbol);
15838 delay=display_image->delay/(size_t) MagickMax(
15839 display_image->ticks_per_second,1L);
15840 timer=GetMagickTime()+(time_t) (delay == 0 ? 1 : delay)+1;
15848 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
15849 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
15850 if (resource_info->debug != MagickFalse)
15851 (void) LogMagickEvent(X11Event,GetMagickModule(),
15852 "Key release: 0x%lx (%c)",(
unsigned long) key_symbol,*command);
15860 if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
15861 if (event.xcrossing.mode != NotifyUngrab)
15862 XUninstallColormap(display,map_info->colormap);
15867 if (resource_info->debug != MagickFalse)
15868 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Map Notify: 0x%lx",
15869 event.xmap.window);
15870 if (event.xmap.window == windows->backdrop.id)
15872 (void) XSetInputFocus(display,event.xmap.window,RevertToParent,
15874 windows->backdrop.mapped=MagickTrue;
15877 if (event.xmap.window == windows->image.id)
15879 if (windows->backdrop.id != (Window) NULL)
15880 (
void) XInstallColormap(display,map_info->colormap);
15881 if (LocaleCompare(display_image->magick,
"LOGO") == 0)
15883 if (LocaleCompare(display_image->filename,
"LOGO") == 0)
15884 nexus=XOpenImage(display,resource_info,windows,MagickFalse);
15886 if (((
int) windows->image.width < windows->image.ximage->width) ||
15887 ((
int) windows->image.height < windows->image.ximage->height))
15888 (void) XMapRaised(display,windows->pan.id);
15889 windows->image.mapped=MagickTrue;
15892 if (event.xmap.window == windows->magnify.id)
15894 XMakeMagnifyImage(display,windows,exception);
15895 windows->magnify.mapped=MagickTrue;
15896 (void) XWithdrawWindow(display,windows->info.id,
15897 windows->info.screen);
15900 if (event.xmap.window == windows->pan.id)
15902 XMakePanImage(display,resource_info,windows,display_image,
15904 windows->pan.mapped=MagickTrue;
15907 if (event.xmap.window == windows->info.id)
15909 windows->info.mapped=MagickTrue;
15912 if (event.xmap.window == windows->icon.id)
15920 taint=display_image->taint;
15921 XMakeStandardColormap(display,icon_visual,icon_resources,
15922 display_image,icon_map,icon_pixel,exception);
15923 (void) XMakeImage(display,icon_resources,&windows->icon,
15924 display_image,windows->icon.width,windows->icon.height,
15926 display_image->taint=taint;
15927 (void) XSetWindowBackgroundPixmap(display,windows->icon.id,
15928 windows->icon.pixmap);
15929 (void) XClearWindow(display,windows->icon.id);
15930 (void) XWithdrawWindow(display,windows->info.id,
15931 windows->info.screen);
15932 windows->icon.mapped=MagickTrue;
15935 if (event.xmap.window == windows->command.id)
15937 windows->command.mapped=MagickTrue;
15940 if (event.xmap.window == windows->popup.id)
15942 windows->popup.mapped=MagickTrue;
15945 if (event.xmap.window == windows->widget.id)
15947 windows->widget.mapped=MagickTrue;
15952 case MappingNotify:
15954 (void) XRefreshKeyboardMapping(&event.xmapping);
15959 case PropertyNotify:
15975 if (resource_info->debug != MagickFalse)
15976 (void) LogMagickEvent(X11Event,GetMagickModule(),
15977 "Property Notify: 0x%lx 0x%lx %d",
event.xproperty.window,
15978 event.xproperty.atom,
event.xproperty.state);
15979 if (event.xproperty.atom != windows->im_remote_command)
15984 status=XGetWindowProperty(display,event.xproperty.window,
15985 event.xproperty.atom,0L,(
long) MagickPathExtent,MagickFalse,(Atom)
15986 AnyPropertyType,&type,&format,&length,&after,&data);
15987 if ((status != Success) || (length == 0))
15989 if (LocaleCompare((
char *) data,
"-quit") == 0)
15991 XClientMessage(display,windows->image.id,windows->im_protocols,
15992 windows->im_exit,CurrentTime);
15993 (void) XFree((
void *) data);
15996 (void) CopyMagickString(resource_info->image_info->filename,
15997 (
char *) data,MagickPathExtent);
15998 (void) XFree((
void *) data);
15999 nexus=ReadImage(resource_info->image_info,exception);
16000 CatchException(exception);
16001 if (nexus != (
Image *) NULL)
16002 *state|=NextImageState | ExitState;
16005 case ReparentNotify:
16007 if (resource_info->debug != MagickFalse)
16008 (void) LogMagickEvent(X11Event,GetMagickModule(),
16009 "Reparent Notify: 0x%lx=>0x%lx",
event.xreparent.parent,
16010 event.xreparent.window);
16015 if (resource_info->debug != MagickFalse)
16016 (void) LogMagickEvent(X11Event,GetMagickModule(),
16017 "Unmap Notify: 0x%lx",
event.xunmap.window);
16018 if (event.xunmap.window == windows->backdrop.id)
16020 windows->backdrop.mapped=MagickFalse;
16023 if (event.xunmap.window == windows->image.id)
16025 windows->image.mapped=MagickFalse;
16028 if (event.xunmap.window == windows->magnify.id)
16030 windows->magnify.mapped=MagickFalse;
16033 if (event.xunmap.window == windows->pan.id)
16035 windows->pan.mapped=MagickFalse;
16038 if (event.xunmap.window == windows->info.id)
16040 windows->info.mapped=MagickFalse;
16043 if (event.xunmap.window == windows->icon.id)
16045 if (map_info->colormap == icon_map->colormap)
16046 XConfigureImageColormap(display,resource_info,windows,
16047 display_image,exception);
16048 (void) XFreeStandardColormap(display,icon_visual,icon_map,
16050 windows->icon.mapped=MagickFalse;
16053 if (event.xunmap.window == windows->command.id)
16055 windows->command.mapped=MagickFalse;
16058 if (event.xunmap.window == windows->popup.id)
16060 if (windows->backdrop.id != (Window) NULL)
16061 (
void) XSetInputFocus(display,windows->image.id,RevertToParent,
16063 windows->popup.mapped=MagickFalse;
16066 if (event.xunmap.window == windows->widget.id)
16068 if (windows->backdrop.id != (Window) NULL)
16069 (void) XSetInputFocus(display,windows->image.id,RevertToParent,
16071 windows->widget.mapped=MagickFalse;
16078 if (resource_info->debug != MagickFalse)
16079 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Event type: %d",
16084 }
while (!(*state & ExitState));
16085 if ((*state & ExitState) == 0)
16086 (
void) XMagickCommand(display,resource_info,windows,FreeBuffersCommand,
16087 &display_image,exception);
16089 if (resource_info->confirm_edit != MagickFalse)
16094 if ((resource_info->immutable == MagickFalse) &&
16095 display_image->taint != MagickFalse)
16100 status=XConfirmWidget(display,windows,
"Your image changed.",
16101 "Do you want to save it");
16103 *state&=(
unsigned int) (~ExitState);
16106 (void) XMagickCommand(display,resource_info,windows,SaveCommand,
16107 &display_image,exception);
16110 if ((windows->visual_info->klass == GrayScale) ||
16111 (windows->visual_info->klass == PseudoColor) ||
16112 (windows->visual_info->klass == DirectColor))
16117 if (windows->info.mapped != MagickFalse)
16118 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
16119 if (windows->magnify.mapped != MagickFalse)
16120 (void) XWithdrawWindow(display,windows->magnify.id,
16121 windows->magnify.screen);
16122 if (windows->command.mapped != MagickFalse)
16123 (void) XWithdrawWindow(display,windows->command.id,
16124 windows->command.screen);
16126 if (windows->pan.mapped != MagickFalse)
16127 (void) XWithdrawWindow(display,windows->pan.id,windows->pan.screen);
16128 if (resource_info->backdrop == MagickFalse)
16129 if (windows->backdrop.mapped)
16131 (void) XWithdrawWindow(display,windows->backdrop.id,
16132 windows->backdrop.screen);
16133 (void) XDestroyWindow(display,windows->backdrop.id);
16134 windows->backdrop.id=(Window) NULL;
16135 (void) XWithdrawWindow(display,windows->image.id,
16136 windows->image.screen);
16137 (void) XDestroyWindow(display,windows->image.id);
16138 windows->image.id=(Window) NULL;
16140 XSetCursorState(display,windows,MagickTrue);
16141 XCheckRefreshWindows(display,windows);
16142 if (((*state & FormerImageState) != 0) || ((*state & NextImageState) != 0))
16143 *state&=(
unsigned int) (~ExitState);
16144 if (*state & ExitState)
16149 (void) XFreeStandardColormap(display,icon_visual,icon_map,icon_pixel);
16150 if (resource_info->map_type == (
char *) NULL)
16151 (
void) XFreeStandardColormap(display,visual_info,map_info,pixel);
16155 if (resource_info->copy_image != (
Image *) NULL)
16157 resource_info->copy_image=DestroyImage(resource_info->copy_image);
16158 resource_info->copy_image=NewImageList();
16160 DestroyXResources();
16162 (void) XSync(display,MagickFalse);
16166 (void) SetErrorHandler(warning_handler);
16167 (void) SetWarningHandler(warning_handler);
16171 directory=getcwd(working_directory,MagickPathExtent);
16177 if (*resource_info->home_directory ==
'\0')
16178 (void) CopyMagickString(resource_info->home_directory,
".",MagickPathExtent);
16179 status=chdir(resource_info->home_directory);
16181 (void) ThrowMagickException(exception,GetMagickModule(),FileOpenError,
16182 "UnableToOpenFile",
"%s",resource_info->home_directory);
16184 *image=display_image;
16218MagickExport MagickBooleanType DisplayImages(
const ImageInfo *image_info,
16221 assert(image_info != (
const ImageInfo *) NULL);
16222 assert(image_info->signature == MagickCoreSignature);
16223 assert(image != (
Image *) NULL);
16224 assert(image->signature == MagickCoreSignature);
16226 if (IsEventLogging() != MagickFalse)
16227 (
void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
16228 (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError,
16229 "DelegateLibrarySupportNotBuiltIn",
"'%s' (X11)",image->filename);
16230 return(MagickFalse);
16263MagickExport MagickBooleanType RemoteDisplayCommand(
const ImageInfo *image_info,
16264 const char *window,
const char *filename,
ExceptionInfo *exception)
16266 assert(image_info != (
const ImageInfo *) NULL);
16267 assert(image_info->signature == MagickCoreSignature);
16268 assert(filename != (
char *) NULL);
16269 if (IsEventLogging() != MagickFalse)
16270 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",filename);
16272 (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError,
16273 "DelegateLibrarySupportNotBuiltIn",
"'%s' (X11)",image_info->filename);
16274 return(MagickFalse);