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,
11243 CharcoalDrawCommand
11245 MiscellanyCommands[] =
11249 ShowPreviewCommand,
11250 ShowHistogramCommand,
11259 static const DisplayCommand
11260 *Commands[ApplyMenus] =
11272 command[MagickPathExtent],
11273 text[MagickPathExtent];
11293 MagickProgressMonitor
11314 (void) CloneString(&windows->command.name,
"ROI");
11315 windows->command.data=0;
11316 (void) XCommandWidget(display,windows,ROIMenu,(XEvent *) NULL);
11317 (void) XMapRaised(display,windows->command.id);
11318 XClientMessage(display,windows->image.id,windows->im_protocols,
11319 windows->im_update_widget,CurrentTime);
11323 XQueryPosition(display,windows->image.id,&x,&y);
11324 (void) XSelectInput(display,windows->image.id,
11325 windows->image.attributes.event_mask | PointerMotionMask);
11326 roi_info.x=(ssize_t) windows->image.x+x;
11327 roi_info.y=(ssize_t) windows->image.y+y;
11330 cursor=XCreateFontCursor(display,XC_fleur);
11331 state=DefaultState;
11334 if (windows->info.mapped != MagickFalse)
11339 (void) FormatLocaleString(text,MagickPathExtent,
" %+ld%+ld ",
11340 (
long) roi_info.x,(long) roi_info.y);
11341 XInfoWidget(display,windows,text);
11346 XScreenEvent(display,windows,&event,exception);
11347 if (event.xany.window == windows->command.id)
11352 id=XCommandWidget(display,windows,ROIMenu,&event);
11355 switch (ROICommands[
id])
11357 case ROIHelpCommand:
11359 XTextViewHelp(display,resource_info,windows,MagickFalse,
11360 "Help Viewer - Region of Interest",ImageROIHelp);
11363 case ROIDismissCommand:
11368 state|=EscapeState;
11377 switch (event.type)
11381 if (event.xbutton.button != Button1)
11383 if (event.xbutton.window != windows->image.id)
11388 (void) XCheckDefineCursor(display,windows->image.id,cursor);
11389 roi_info.x=(ssize_t) windows->image.x+event.xbutton.x;
11390 roi_info.y=(ssize_t) windows->image.y+event.xbutton.y;
11394 case ButtonRelease:
11403 if (event.xkey.window != windows->image.id)
11408 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
11409 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
11410 switch ((
int) key_symbol)
11418 state|=EscapeState;
11425 XTextViewHelp(display,resource_info,windows,MagickFalse,
11426 "Help Viewer - Region of Interest",ImageROIHelp);
11431 (void) XBell(display,0);
11444 if (windows->info.mapped != MagickFalse)
11446 if ((x < (windows->info.x+(
int) windows->info.width)) &&
11447 (y < (windows->info.y+(int) windows->info.height)))
11448 (void) XWithdrawWindow(display,windows->info.id,
11449 windows->info.screen);
11452 if ((x > (windows->info.x+(
int) windows->info.width)) ||
11453 (y > (windows->info.y+(int) windows->info.height)))
11454 (void) XMapWindow(display,windows->info.id);
11455 roi_info.x=(ssize_t) windows->image.x+x;
11456 roi_info.y=(ssize_t) windows->image.y+y;
11462 }
while ((state & ExitState) == 0);
11463 (void) XSelectInput(display,windows->image.id,
11464 windows->image.attributes.event_mask);
11465 if ((state & EscapeState) != 0)
11470 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
11471 (void) XFreeCursor(display,cursor);
11472 return(MagickTrue);
11474 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
11480 x=(int) roi_info.x;
11481 y=(int) roi_info.y;
11484 state=DefaultState;
11487 highlight_info=roi_info;
11488 highlight_info.x=roi_info.x-windows->image.x;
11489 highlight_info.y=roi_info.y-windows->image.y;
11490 if ((highlight_info.width > 3) && (highlight_info.height > 3))
11495 if (windows->info.mapped == MagickFalse)
11496 (void) XMapWindow(display,windows->info.id);
11497 (void) FormatLocaleString(text,MagickPathExtent,
11498 " %.20gx%.20g%+.20g%+.20g",(
double) roi_info.width,(double)
11499 roi_info.height,(
double) roi_info.x,(double) roi_info.y);
11500 XInfoWidget(display,windows,text);
11501 XHighlightRectangle(display,windows->image.id,
11502 windows->image.highlight_context,&highlight_info);
11505 if (windows->info.mapped != MagickFalse)
11506 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
11510 XScreenEvent(display,windows,&event,exception);
11511 if ((highlight_info.width > 3) && (highlight_info.height > 3))
11512 XHighlightRectangle(display,windows->image.id,
11513 windows->image.highlight_context,&highlight_info);
11514 switch (event.type)
11518 roi_info.x=(ssize_t) windows->image.x+event.xbutton.x;
11519 roi_info.y=(ssize_t) windows->image.y+event.xbutton.y;
11522 case ButtonRelease:
11527 roi_info.x=(ssize_t) windows->image.x+event.xbutton.x;
11528 roi_info.y=(ssize_t) windows->image.y+event.xbutton.y;
11529 XSetCursorState(display,windows,MagickFalse);
11531 if (LocaleCompare(windows->command.name,
"Apply") == 0)
11533 (void) CloneString(&windows->command.name,
"Apply");
11534 windows->command.data=ApplyMenus;
11535 (void) XCommandWidget(display,windows,ApplyMenu,(XEvent *) NULL);
11542 roi_info.x=(ssize_t) windows->image.x+event.xmotion.x;
11543 roi_info.y=(ssize_t) windows->image.y+event.xmotion.y;
11548 if ((((
int) roi_info.x != x) && ((
int) roi_info.y != y)) ||
11549 ((state & ExitState) != 0))
11554 if (roi_info.x < 0)
11557 if (roi_info.x > (ssize_t) windows->image.ximage->width)
11558 roi_info.x=(ssize_t) windows->image.ximage->width;
11559 if ((
int) roi_info.x < x)
11560 roi_info.width=(
unsigned int) (x-roi_info.x);
11563 roi_info.width=(
unsigned int) (roi_info.x-x);
11564 roi_info.x=(ssize_t) x;
11566 if (roi_info.y < 0)
11569 if (roi_info.y > (ssize_t) windows->image.ximage->height)
11570 roi_info.y=(ssize_t) windows->image.ximage->height;
11571 if ((
int) roi_info.y < y)
11572 roi_info.height=(
unsigned int) (y-roi_info.y);
11575 roi_info.height=(
unsigned int) (roi_info.y-y);
11576 roi_info.y=(ssize_t) y;
11579 }
while ((state & ExitState) == 0);
11583 state=DefaultState;
11584 display_command=NullCommand;
11587 (void) XMapWindow(display,windows->info.id);
11590 if (windows->info.mapped != MagickFalse)
11595 (void) FormatLocaleString(text,MagickPathExtent,
11596 " %.20gx%.20g%+.20g%+.20g",(
double) roi_info.width,(double)
11597 roi_info.height,(
double) roi_info.x,(double) roi_info.y);
11598 XInfoWidget(display,windows,text);
11600 highlight_info=roi_info;
11601 highlight_info.x=roi_info.x-windows->image.x;
11602 highlight_info.y=roi_info.y-windows->image.y;
11603 if ((highlight_info.width <= 3) || (highlight_info.height <= 3))
11605 state|=EscapeState;
11609 if ((state & UpdateRegionState) != 0)
11611 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
11612 switch (display_command)
11617 (void) XMagickCommand(display,resource_info,windows,
11618 display_command,image,exception);
11626 progress_monitor=SetImageProgressMonitor(*image,
11627 (MagickProgressMonitor) NULL,(*image)->client_data);
11628 crop_info=roi_info;
11629 width=(
unsigned int) (*image)->columns;
11630 height=(
unsigned int) (*image)->rows;
11633 if (windows->image.crop_geometry != (
char *) NULL)
11634 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
11636 scale_factor=(double) width/windows->image.ximage->width;
11638 crop_info.x=(ssize_t) (scale_factor*crop_info.x+0.5);
11639 crop_info.width=(
unsigned int) (scale_factor*crop_info.width+0.5);
11640 scale_factor=(double)
11641 height/windows->image.ximage->height;
11643 crop_info.y=(ssize_t) (scale_factor*crop_info.y+0.5);
11644 crop_info.height=(
unsigned int)
11645 (scale_factor*crop_info.height+0.5);
11646 roi_image=CropImage(*image,&crop_info,exception);
11647 (void) SetImageProgressMonitor(*image,progress_monitor,
11648 (*image)->client_data);
11649 if (roi_image == (
Image *) NULL)
11654 windows->image.orphan=MagickTrue;
11655 (void) XMagickCommand(display,resource_info,windows,
11656 display_command,&roi_image,exception);
11657 progress_monitor=SetImageProgressMonitor(*image,
11658 (MagickProgressMonitor) NULL,(*image)->client_data);
11659 (void) XMagickCommand(display,resource_info,windows,
11660 SaveToUndoBufferCommand,image,exception);
11661 windows->image.orphan=MagickFalse;
11662 (void) CompositeImage(*image,roi_image,CopyCompositeOp,
11663 MagickTrue,crop_info.x,crop_info.y,exception);
11664 roi_image=DestroyImage(roi_image);
11665 (void) SetImageProgressMonitor(*image,progress_monitor,
11666 (*image)->client_data);
11670 if (display_command != InfoCommand)
11672 XConfigureImageColormap(display,resource_info,windows,*image,
11674 (void) XConfigureImage(display,resource_info,windows,*image,
11677 XCheckRefreshWindows(display,windows);
11678 XInfoWidget(display,windows,text);
11679 (void) XSetFunction(display,windows->image.highlight_context,
11681 state&=(
unsigned int) (~UpdateRegionState);
11683 XHighlightRectangle(display,windows->image.id,
11684 windows->image.highlight_context,&highlight_info);
11685 XScreenEvent(display,windows,&event,exception);
11686 if (event.xany.window == windows->command.id)
11691 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
11692 display_command=NullCommand;
11693 id=XCommandWidget(display,windows,ApplyMenu,&event);
11696 (void) CopyMagickString(command,ApplyMenu[
id],MagickPathExtent);
11697 display_command=ApplyCommands[id];
11698 if (
id < ApplyMenus)
11703 entry=XMenuWidget(display,windows,ApplyMenu[
id],
11704 (
const char **) Menus[
id],command);
11707 (void) CopyMagickString(command,Menus[
id][entry],
11709 display_command=Commands[id][entry];
11713 (void) XSetFunction(display,windows->image.highlight_context,
11715 XHighlightRectangle(display,windows->image.id,
11716 windows->image.highlight_context,&highlight_info);
11717 if (display_command == HelpCommand)
11719 (void) XSetFunction(display,windows->image.highlight_context,
11721 XTextViewHelp(display,resource_info,windows,MagickFalse,
11722 "Help Viewer - Region of Interest",ImageROIHelp);
11723 (void) XSetFunction(display,windows->image.highlight_context,
11727 if (display_command == QuitCommand)
11732 state|=EscapeState;
11736 if (display_command != NullCommand)
11737 state|=UpdateRegionState;
11740 XHighlightRectangle(display,windows->image.id,
11741 windows->image.highlight_context,&highlight_info);
11742 switch (event.type)
11746 x=windows->image.x;
11747 y=windows->image.y;
11748 if (event.xbutton.button != Button1)
11750 if (event.xbutton.window != windows->image.id)
11752 x=windows->image.x+
event.xbutton.x;
11753 y=windows->image.y+
event.xbutton.y;
11754 if ((x < (
int) (roi_info.x+RoiDelta)) &&
11755 (x > (
int) (roi_info.x-RoiDelta)) &&
11756 (y < (
int) (roi_info.y+RoiDelta)) &&
11757 (y > (
int) (roi_info.y-RoiDelta)))
11759 roi_info.x=roi_info.x+(int) roi_info.width;
11760 roi_info.y=roi_info.y+(int) roi_info.height;
11761 state|=UpdateConfigurationState;
11764 if ((x < (
int) (roi_info.x+RoiDelta)) &&
11765 (x > (
int) (roi_info.x-RoiDelta)) &&
11766 (y < (roi_info.y+(
int) roi_info.height+RoiDelta)) &&
11767 (y > (roi_info.y+(
int) roi_info.height-RoiDelta)))
11769 roi_info.x=roi_info.x+(int) roi_info.width;
11770 state|=UpdateConfigurationState;
11773 if ((x < (roi_info.x+(
int) roi_info.width+RoiDelta)) &&
11774 (x > (roi_info.x+(
int) roi_info.width-RoiDelta)) &&
11775 (y < (
int) (roi_info.y+RoiDelta)) &&
11776 (y > (
int) (roi_info.y-RoiDelta)))
11778 roi_info.y=roi_info.y+(int) roi_info.height;
11779 state|=UpdateConfigurationState;
11782 if ((x < (roi_info.x+(
int) roi_info.width+RoiDelta)) &&
11783 (x > (roi_info.x+(
int) roi_info.width-RoiDelta)) &&
11784 (y < (roi_info.y+(
int) roi_info.height+RoiDelta)) &&
11785 (y > (roi_info.y+(
int) roi_info.height-RoiDelta)))
11787 state|=UpdateConfigurationState;
11790 magick_fallthrough;
11792 case ButtonRelease:
11794 if (event.xbutton.window == windows->pan.id)
11795 if ((highlight_info.x != crop_info.x-windows->image.x) ||
11796 (highlight_info.y != crop_info.y-windows->image.y))
11797 XHighlightRectangle(display,windows->image.id,
11798 windows->image.highlight_context,&highlight_info);
11799 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id,
11800 event.xbutton.time);
11805 if (event.xexpose.window == windows->image.id)
11806 if (event.xexpose.count == 0)
11808 event.xexpose.x=(int) highlight_info.x;
11809 event.xexpose.y=(int) highlight_info.y;
11810 event.xexpose.width=(int) highlight_info.width;
11811 event.xexpose.height=(int) highlight_info.height;
11812 XRefreshWindow(display,&windows->image,&event);
11814 if (event.xexpose.window == windows->info.id)
11815 if (event.xexpose.count == 0)
11816 XInfoWidget(display,windows,text);
11824 if (event.xkey.window != windows->image.id)
11829 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
11830 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
11831 switch ((
int) key_symbol)
11839 state|=EscapeState;
11840 magick_fallthrough;
11850 roi_info.x=(ssize_t) (windows->image.width/2L-roi_info.width/2L);
11851 roi_info.y=(ssize_t) (windows->image.height/2L-
11852 roi_info.height/2L);
11884 (void) XSetFunction(display,windows->image.highlight_context,
11886 XTextViewHelp(display,resource_info,windows,MagickFalse,
11887 "Help Viewer - Region of Interest",ImageROIHelp);
11888 (void) XSetFunction(display,windows->image.highlight_context,
11894 display_command=XImageWindowCommand(display,resource_info,windows,
11895 event.xkey.state,key_symbol,image,exception);
11896 if (display_command != NullCommand)
11897 state|=UpdateRegionState;
11901 (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id,
11909 if (event.xbutton.window != windows->image.id)
11916 if (windows->info.mapped != MagickFalse)
11918 if ((x < (windows->info.x+(
int) windows->info.width)) &&
11919 (y < (windows->info.y+(int) windows->info.height)))
11920 (void) XWithdrawWindow(display,windows->info.id,
11921 windows->info.screen);
11924 if ((x > (windows->info.x+(
int) windows->info.width)) ||
11925 (y > (windows->info.y+(int) windows->info.height)))
11926 (void) XMapWindow(display,windows->info.id);
11927 roi_info.x=(ssize_t) windows->image.x+event.xmotion.x;
11928 roi_info.y=(ssize_t) windows->image.y+event.xmotion.y;
11931 case SelectionRequest:
11936 XSelectionRequestEvent
11942 (void) FormatLocaleString(text,MagickPathExtent,
11943 "%.20gx%.20g%+.20g%+.20g",(
double) roi_info.width,(double)
11944 roi_info.height,(
double) roi_info.x,(double) roi_info.y);
11945 request=(&(
event.xselectionrequest));
11946 (void) XChangeProperty(request->display,request->requestor,
11947 request->property,request->target,8,PropModeReplace,
11948 (
unsigned char *) text,(int) strlen(text));
11949 notify.type=SelectionNotify;
11950 notify.display=request->display;
11951 notify.requestor=request->requestor;
11952 notify.selection=request->selection;
11953 notify.target=request->target;
11954 notify.time=request->time;
11955 if (request->property == None)
11956 notify.property=request->target;
11958 notify.property=request->property;
11959 (void) XSendEvent(request->display,request->requestor,False,0,
11960 (XEvent *) ¬ify);
11965 if ((state & UpdateConfigurationState) != 0)
11967 (void) XPutBackEvent(display,&event);
11968 (void) XCheckDefineCursor(display,windows->image.id,cursor);
11971 }
while ((state & ExitState) == 0);
11972 }
while ((state & ExitState) == 0);
11973 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
11974 XSetCursorState(display,windows,MagickFalse);
11975 if ((state & EscapeState) != 0)
11976 return(MagickTrue);
11977 return(MagickTrue);
12016static MagickBooleanType XRotateImage(Display *display,
12017 XResourceInfo *resource_info,XWindows *windows,
double degrees,
Image **image,
12021 *
const RotateMenu[] =
12031 direction = HorizontalRotateCommand;
12033 static const ModeType
12034 DirectionCommands[] =
12036 HorizontalRotateCommand,
12037 VerticalRotateCommand
12041 RotateColorCommand,
12042 RotateDirectionCommand,
12044 RotateDismissCommand
12047 static unsigned int
12051 command[MagickPathExtent],
12052 text[MagickPathExtent];
12063 normalized_degrees;
12073 if (degrees == 0.0)
12090 (void) CloneString(&windows->command.name,
"Rotate");
12091 windows->command.data=2;
12092 (void) XCommandWidget(display,windows,RotateMenu,(XEvent *) NULL);
12093 (void) XMapRaised(display,windows->command.id);
12094 XClientMessage(display,windows->image.id,windows->im_protocols,
12095 windows->im_update_widget,CurrentTime);
12099 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
12100 XQueryPosition(display,windows->image.id,&x,&y);
12105 state=DefaultState;
12108 XHighlightLine(display,windows->image.id,
12109 windows->image.highlight_context,&rotate_info);
12113 XScreenEvent(display,windows,&event,exception);
12114 XHighlightLine(display,windows->image.id,
12115 windows->image.highlight_context,&rotate_info);
12116 if (event.xany.window == windows->command.id)
12121 id=XCommandWidget(display,windows,RotateMenu,&event);
12124 (void) XSetFunction(display,windows->image.highlight_context,
12126 switch (RotateCommands[
id])
12128 case RotateColorCommand:
12131 *ColorMenu[MaxNumberPens];
12142 for (i=0; i < (int) (MaxNumberPens-2); i++)
12143 ColorMenu[i]=resource_info->pen_colors[i];
12144 ColorMenu[MaxNumberPens-2]=
"Browser...";
12145 ColorMenu[MaxNumberPens-1]=(
const char *) NULL;
12149 pen_number=XMenuWidget(display,windows,RotateMenu[
id],
12150 (
const char **) ColorMenu,command);
12151 if (pen_number < 0)
12153 if (pen_number == (MaxNumberPens-2))
12156 color_name[MagickPathExtent] =
"gray";
12161 resource_info->pen_colors[pen_number]=color_name;
12162 XColorBrowserWidget(display,windows,
"Select",color_name);
12163 if (*color_name ==
'\0')
12169 (void) XParseColor(display,windows->map_info->colormap,
12170 resource_info->pen_colors[pen_number],&color);
12171 XBestPixel(display,windows->map_info->colormap,(XColor *) NULL,
12172 (
unsigned int) MaxColors,&color);
12173 windows->pixel_info->pen_colors[pen_number]=color;
12174 pen_id=(
unsigned int) pen_number;
12177 case RotateDirectionCommand:
12190 id=XMenuWidget(display,windows,RotateMenu[
id],
12191 Directions,command);
12193 direction=DirectionCommands[id];
12196 case RotateHelpCommand:
12198 XTextViewHelp(display,resource_info,windows,MagickFalse,
12199 "Help Viewer - Image Rotation",ImageRotateHelp);
12202 case RotateDismissCommand:
12207 state|=EscapeState;
12214 (void) XSetFunction(display,windows->image.highlight_context,
12218 switch (event.type)
12222 if (event.xbutton.button != Button1)
12224 if (event.xbutton.window != windows->image.id)
12229 (void) XSetFunction(display,windows->image.highlight_context,
12231 rotate_info.x1=
event.xbutton.x;
12232 rotate_info.y1=
event.xbutton.y;
12236 case ButtonRelease:
12243 command[MagickPathExtent];
12248 if (event.xkey.window != windows->image.id)
12253 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
12254 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
12255 switch ((
int) key_symbol)
12263 state|=EscapeState;
12270 (void) XSetFunction(display,windows->image.highlight_context,
12272 XTextViewHelp(display,resource_info,windows,MagickFalse,
12273 "Help Viewer - Image Rotation",ImageRotateHelp);
12274 (void) XSetFunction(display,windows->image.highlight_context,
12280 (void) XBell(display,0);
12288 rotate_info.x1=
event.xmotion.x;
12289 rotate_info.y1=
event.xmotion.y;
12292 rotate_info.x2=rotate_info.x1;
12293 rotate_info.y2=rotate_info.y1;
12294 if (direction == HorizontalRotateCommand)
12295 rotate_info.x2+=32;
12297 rotate_info.y2-=32;
12298 }
while ((state & ExitState) == 0);
12299 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
12300 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
12301 if ((state & EscapeState) != 0)
12302 return(MagickTrue);
12307 (void) XSetFunction(display,windows->image.highlight_context,GXinvert);
12308 state=DefaultState;
12316 if (windows->info.mapped == MagickFalse)
12317 (void) XMapWindow(display,windows->info.id);
12318 (void) FormatLocaleString(text,MagickPathExtent,
" %g",
12319 direction == VerticalRotateCommand ? degrees-90.0 : degrees);
12320 XInfoWidget(display,windows,text);
12321 XHighlightLine(display,windows->image.id,
12322 windows->image.highlight_context,&rotate_info);
12325 if (windows->info.mapped != MagickFalse)
12326 (void) XWithdrawWindow(display,windows->info.id,
12327 windows->info.screen);
12331 XScreenEvent(display,windows,&event,exception);
12333 XHighlightLine(display,windows->image.id,
12334 windows->image.highlight_context,&rotate_info);
12335 switch (event.type)
12339 case ButtonRelease:
12344 rotate_info.x2=
event.xbutton.x;
12345 rotate_info.y2=
event.xbutton.y;
12353 rotate_info.x2=
event.xmotion.x;
12354 rotate_info.y2=
event.xmotion.y;
12362 if (rotate_info.x2 < 0)
12365 if (rotate_info.x2 > (
int) windows->image.width)
12366 rotate_info.x2=(short) windows->image.width;
12367 if (rotate_info.y2 < 0)
12370 if (rotate_info.y2 > (
int) windows->image.height)
12371 rotate_info.y2=(short) windows->image.height;
12376 distance=(
unsigned int)
12377 (((rotate_info.x2-rotate_info.x1+1)*(rotate_info.x2-rotate_info.x1+1))+
12378 ((rotate_info.y2-rotate_info.y1+1)*(rotate_info.y2-rotate_info.y1+1)));
12380 degrees=RadiansToDegrees(-atan2((
double) (rotate_info.y2-
12381 rotate_info.y1),(
double) (rotate_info.x2-rotate_info.x1)));
12382 }
while ((state & ExitState) == 0);
12383 (void) XSetFunction(display,windows->image.highlight_context,GXcopy);
12384 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
12386 return(MagickTrue);
12388 if (direction == VerticalRotateCommand)
12390 if (degrees == 0.0)
12391 return(MagickTrue);
12395 normalized_degrees=degrees;
12396 while (normalized_degrees < -45.0)
12397 normalized_degrees+=360.0;
12398 for (rotations=0; normalized_degrees > 45.0; rotations++)
12399 normalized_degrees-=90.0;
12400 if (normalized_degrees != 0.0)
12401 (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image,
12403 XSetCursorState(display,windows,MagickTrue);
12404 XCheckRefreshWindows(display,windows);
12405 (*image)->background_color.red=(double) ScaleShortToQuantum(
12406 windows->pixel_info->pen_colors[pen_id].red);
12407 (*image)->background_color.green=(double) ScaleShortToQuantum(
12408 windows->pixel_info->pen_colors[pen_id].green);
12409 (*image)->background_color.blue=(double) ScaleShortToQuantum(
12410 windows->pixel_info->pen_colors[pen_id].blue);
12411 rotate_image=RotateImage(*image,degrees,exception);
12412 XSetCursorState(display,windows,MagickFalse);
12413 if (rotate_image == (
Image *) NULL)
12414 return(MagickFalse);
12415 *image=DestroyImage(*image);
12416 *image=rotate_image;
12417 if (windows->image.crop_geometry != (
char *) NULL)
12422 width=(
unsigned int) (*image)->columns;
12423 height=(
unsigned int) (*image)->rows;
12424 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
12425 switch (rotations % 4)
12435 (void) FormatLocaleString(windows->image.crop_geometry,
12436 MagickPathExtent,
"%ux%u%+d%+d",height,width,(
int) (*image)->columns-
12445 (void) FormatLocaleString(windows->image.crop_geometry,
12446 MagickPathExtent,
"%ux%u%+d%+d",width,height,(
int) width-x,(int)
12455 (void) FormatLocaleString(windows->image.crop_geometry,
12456 MagickPathExtent,
"%ux%u%+d%+d",height,width,y,(
int) (*image)->rows-
12462 if (windows->image.orphan != MagickFalse)
12463 return(MagickTrue);
12464 if (normalized_degrees != 0.0)
12469 windows->image.window_changes.width=(int) (*image)->columns;
12470 windows->image.window_changes.height=(int) (*image)->rows;
12471 if (windows->image.crop_geometry != (
char *) NULL)
12476 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,
12478 windows->image.window_changes.width=(int) width;
12479 windows->image.window_changes.height=(int) height;
12481 XConfigureImageColormap(display,resource_info,windows,*image,exception);
12484 if (((rotations % 4) == 1) || ((rotations % 4) == 3))
12486 windows->image.window_changes.width=windows->image.ximage->height;
12487 windows->image.window_changes.height=windows->image.ximage->width;
12492 (void) XConfigureImage(display,resource_info,windows,*image,exception);
12493 return(MagickTrue);
12529static MagickBooleanType XSaveImage(Display *display,
12530 XResourceInfo *resource_info,XWindows *windows,
Image *image,
12534 filename[MagickPathExtent],
12535 geometry[MagickPathExtent];
12549 if (resource_info->write_filename != (
char *) NULL)
12550 (void) CopyMagickString(filename,resource_info->write_filename,
12555 path[MagickPathExtent];
12560 GetPathComponent(image->filename,HeadPath,path);
12561 GetPathComponent(image->filename,TailPath,filename);
12564 status=chdir(path);
12566 (void) ThrowMagickException(exception,GetMagickModule(),
12567 FileOpenError,
"UnableToOpenFile",
"%s",path);
12570 XFileBrowserWidget(display,windows,
"Save",filename);
12571 if (*filename ==
'\0')
12572 return(MagickTrue);
12573 if (IsPathAccessible(filename) != MagickFalse)
12581 status=XConfirmWidget(display,windows,
"Overwrite",filename);
12583 return(MagickTrue);
12585 image_info=CloneImageInfo(resource_info->image_info);
12586 (void) CopyMagickString(image_info->filename,filename,MagickPathExtent);
12587 (void) SetImageInfo(image_info,1,exception);
12588 if ((LocaleCompare(image_info->magick,
"JPEG") == 0) ||
12589 (LocaleCompare(image_info->magick,
"JPG") == 0))
12592 quality[MagickPathExtent];
12600 (void) FormatLocaleString(quality,MagickPathExtent,
"%.20g",(
double)
12602 status=XDialogWidget(display,windows,
"Save",
"Enter JPEG quality:",
12604 if (*quality ==
'\0')
12605 return(MagickTrue);
12606 image->quality=StringToUnsignedLong(quality);
12607 image_info->interlace=status != 0 ? NoInterlace : PlaneInterlace;
12609 if ((LocaleCompare(image_info->magick,
"EPS") == 0) ||
12610 (LocaleCompare(image_info->magick,
"PDF") == 0) ||
12611 (LocaleCompare(image_info->magick,
"PS") == 0) ||
12612 (LocaleCompare(image_info->magick,
"PS2") == 0))
12615 geometry[MagickPathExtent];
12618 *
const PageSizes[] =
12640 (void) CopyMagickString(geometry,PSPageGeometry,MagickPathExtent);
12641 if (LocaleCompare(image_info->magick,
"PDF") == 0)
12642 (
void) CopyMagickString(geometry,PSPageGeometry,MagickPathExtent);
12643 if (image_info->page != (
char *) NULL)
12644 (void) CopyMagickString(geometry,image_info->page,MagickPathExtent);
12645 XListBrowserWidget(display,windows,&windows->widget,PageSizes,
"Select",
12646 "Select page geometry:",geometry);
12647 if (*geometry !=
'\0')
12648 image_info->page=GetPageGeometry(geometry);
12653 XSetCursorState(display,windows,MagickTrue);
12654 XCheckRefreshWindows(display,windows);
12655 save_image=CloneImage(image,0,0,MagickTrue,exception);
12656 if (save_image == (
Image *) NULL)
12657 return(MagickFalse);
12658 (void) FormatLocaleString(geometry,MagickPathExtent,
"%dx%d!",
12659 windows->image.ximage->width,windows->image.ximage->height);
12660 (void) TransformImage(&save_image,windows->image.crop_geometry,geometry,
12665 (void) CopyMagickString(save_image->filename,filename,MagickPathExtent);
12666 status=WriteImage(image_info,save_image,exception);
12667 if (status != MagickFalse)
12668 image->taint=MagickFalse;
12669 save_image=DestroyImage(save_image);
12670 image_info=DestroyImageInfo(image_info);
12671 XSetCursorState(display,windows,MagickFalse);
12672 return(status != 0 ? MagickTrue : MagickFalse);
12707#if defined(__cplusplus) || defined(c_plusplus)
12711static int XPredicate(Display *magick_unused(display),XEvent *event,
char *data)
12716 windows=(XWindows *) data;
12717 if ((event->type == ClientMessage) &&
12718 (
event->xclient.window == windows->image.id))
12719 return(MagickFalse);
12720 return(MagickTrue);
12723#if defined(__cplusplus) || defined(c_plusplus)
12727static void XScreenEvent(Display *display,XWindows *windows,XEvent *event,
12734 (void) XIfEvent(display,event,XPredicate,(
char *) windows);
12735 if (event->xany.window == windows->command.id)
12737 switch (event->type)
12740 case ButtonRelease:
12742 if ((event->xbutton.button == Button3) &&
12743 (
event->xbutton.state & Mod1Mask))
12748 event->xbutton.button=Button2;
12749 event->xbutton.state&=(
unsigned int) (~Mod1Mask);
12751 if (event->xbutton.window == windows->backdrop.id)
12753 (void) XSetInputFocus(display,event->xbutton.window,RevertToParent,
12754 event->xbutton.time);
12757 if (event->xbutton.window == windows->pan.id)
12759 XPanImage(display,windows,event,exception);
12762 if (event->xbutton.window == windows->image.id)
12763 if (event->xbutton.button == Button2)
12768 x=
event->xbutton.x;
12769 y=
event->xbutton.y;
12773 if (x >= (
int) windows->image.width)
12774 x=(int) (windows->image.width-1);
12775 windows->magnify.x=(int) windows->image.x+x;
12779 if (y >= (
int) windows->image.height)
12780 y=(int) (windows->image.height-1);
12781 windows->magnify.y=windows->image.y+y;
12782 if (windows->magnify.mapped == MagickFalse)
12783 (void) XMapRaised(display,windows->magnify.id);
12784 XMakeMagnifyImage(display,windows,exception);
12785 if (event->type == ButtonRelease)
12786 (void) XWithdrawWindow(display,windows->info.id,
12787 windows->info.screen);
12792 case ClientMessage:
12797 if (event->xclient.message_type != windows->wm_protocols)
12799 if (*event->xclient.data.l != (
long) windows->wm_delete_window)
12801 if (event->xclient.window == windows->magnify.id)
12803 (void) XWithdrawWindow(display,windows->magnify.id,
12804 windows->magnify.screen);
12809 case ConfigureNotify:
12811 if (event->xconfigure.window == windows->magnify.id)
12819 windows->magnify.width=(
unsigned int) event->xconfigure.width;
12820 windows->magnify.height=(
unsigned int) event->xconfigure.height;
12821 if (windows->magnify.mapped == MagickFalse)
12824 while ((
int) magnify <= event->xconfigure.width)
12826 while ((
int) magnify <= event->xconfigure.height)
12829 if (((
int) magnify != event->xconfigure.width) ||
12830 ((
int) magnify != event->xconfigure.height))
12835 window_changes.width=(int) magnify;
12836 window_changes.height=(int) magnify;
12837 (void) XReconfigureWMWindow(display,windows->magnify.id,
12838 windows->magnify.screen,(
unsigned int) (CWWidth | CWHeight),
12842 XMakeMagnifyImage(display,windows,exception);
12849 if (event->xexpose.window == windows->image.id)
12851 XRefreshWindow(display,&windows->image,event);
12854 if (event->xexpose.window == windows->pan.id)
12855 if (event->xexpose.count == 0)
12857 XDrawPanRectangle(display,windows);
12860 if (event->xexpose.window == windows->magnify.id)
12861 if (event->xexpose.count == 0)
12863 XMakeMagnifyImage(display,windows,exception);
12871 command[MagickPathExtent];
12876 if (event->xkey.window != windows->magnify.id)
12881 (void) XLookupString((XKeyEvent *) &
event->xkey,command,(int)
12882 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
12883 XMagnifyWindowCommand(display,windows,event->xkey.state,key_symbol,
12889 if (event->xmap.window == windows->magnify.id)
12891 windows->magnify.mapped=MagickTrue;
12892 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
12895 if (event->xmap.window == windows->info.id)
12897 windows->info.mapped=MagickTrue;
12904 while (XCheckMaskEvent(display,ButtonMotionMask,event)) ;
12905 if (event->xmotion.window == windows->image.id)
12906 if (windows->magnify.mapped != MagickFalse)
12911 x=
event->xmotion.x;
12912 y=
event->xmotion.y;
12916 if (x >= (
int) windows->image.width)
12917 x=(
int) (windows->image.width-1);
12918 windows->magnify.x=(int) windows->image.x+x;
12922 if (y >= (
int) windows->image.height)
12923 y=(int) (windows->image.height-1);
12924 windows->magnify.y=windows->image.y+y;
12925 XMakeMagnifyImage(display,windows,exception);
12931 if (event->xunmap.window == windows->magnify.id)
12933 windows->magnify.mapped=MagickFalse;
12936 if (event->xunmap.window == windows->info.id)
12938 windows->info.mapped=MagickFalse;
12980static void XSetCropGeometry(Display *display,XWindows *windows,
12984 text[MagickPathExtent];
12997 if (windows->info.mapped != MagickFalse)
13002 (void) FormatLocaleString(text,MagickPathExtent,
" %.20gx%.20g%+.20g%+.20g",
13003 (
double) crop_info->width,(double) crop_info->height,(
double)
13004 crop_info->x,(double) crop_info->y);
13005 XInfoWidget(display,windows,text);
13012 width=(
unsigned int) image->columns;
13013 height=(
unsigned int) image->rows;
13014 if (windows->image.crop_geometry != (
char *) NULL)
13015 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
13017 windows->image.crop_geometry=AcquireString((
char *) NULL);
13021 scale_factor=(double) width/windows->image.ximage->width;
13022 if (crop_info->x > 0)
13023 x+=(int) (scale_factor*crop_info->x+0.5);
13024 width=(
unsigned int) (scale_factor*crop_info->width+0.5);
13027 scale_factor=(double) height/windows->image.ximage->height;
13028 if (crop_info->y > 0)
13029 y+=(int) (scale_factor*crop_info->y+0.5);
13030 height=(
unsigned int) (scale_factor*crop_info->height+0.5);
13033 (void) FormatLocaleString(windows->image.crop_geometry,MagickPathExtent,
13034 "%ux%u%+d%+d",width,height,x,y);
13076static Image *XTileImage(Display *display,XResourceInfo *resource_info,
13080 *
const VerbMenu[] =
13090 static const ModeType
13101 command[MagickPathExtent],
13102 filename[MagickPathExtent];
13133 width=(
unsigned int) image->columns;
13134 height=(
unsigned int) image->rows;
13135 if (windows->image.crop_geometry != (
char *) NULL)
13136 (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height);
13137 scale_factor=(double) width/windows->image.ximage->width;
13138 event->xbutton.x+=windows->image.x;
13139 event->xbutton.x=(int) (scale_factor*event->xbutton.x+x+0.5);
13140 scale_factor=(double) height/windows->image.ximage->height;
13141 event->xbutton.y+=windows->image.y;
13142 event->xbutton.y=(int) (scale_factor*event->xbutton.y+y+0.5);
13146 width=(
unsigned int) image->columns;
13147 height=(
unsigned int) image->rows;
13150 (void) XParseGeometry(image->montage,&x,&y,&width,&height);
13151 tile=((
event->xbutton.y-y)/(
int) height)*(((
int) image->columns-x)/(
int)
13152 width)+(event->xbutton.x-x)/(int) width;
13158 (void) XBell(display,0);
13159 return((
Image *) NULL);
13164 p=image->directory;
13165 for (i=tile; (i != 0) && (*p !=
'\0'); )
13176 (void) XBell(display,0);
13177 return((
Image *) NULL);
13182 id=XMenuWidget(display,windows,
"Tile Verb",VerbMenu,command);
13184 return((
Image *) NULL);
13186 while ((*q !=
'\xff') && (*q !=
'\0'))
13188 (void) CopyMagickString(filename,p,(
size_t) (q-p+1));
13192 XSetCursorState(display,windows,MagickTrue);
13193 XCheckRefreshWindows(display,windows);
13194 tile_image=NewImageList();
13195 switch (TileCommands[
id])
13197 case TileLoadCommand:
13202 XCheckRefreshWindows(display,windows);
13203 (void) CopyMagickString(resource_info->image_info->magick,
"MIFF",
13205 (void) CopyMagickString(resource_info->image_info->filename,filename,
13207 tile_image=ReadImage(resource_info->image_info,exception);
13208 CatchException(exception);
13209 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
13212 case TileNextCommand:
13217 XClientMessage(display,windows->image.id,windows->im_protocols,
13218 windows->im_next_image,CurrentTime);
13221 case TileFormerCommand:
13226 XClientMessage(display,windows->image.id,windows->im_protocols,
13227 windows->im_former_image,CurrentTime);
13230 case TileDeleteCommand:
13235 if (IsPathAccessible(filename) == MagickFalse)
13237 XNoticeWidget(display,windows,
"Image file does not exist:",filename);
13240 status=XConfirmWidget(display,windows,
"Really delete tile",filename);
13243 status=ShredFile(filename) == MagickFalse ? 0 : 1;
13244 status|=remove_utf8(filename);
13245 if (status != MagickFalse)
13247 XNoticeWidget(display,windows,
"Unable to delete image file:",
13251 magick_fallthrough;
13253 case TileUpdateCommand:
13272 GetPixelInfo(image,&pixel);
13273 for (p=image->directory; *p !=
'\0'; p++)
13279 while ((*q !=
'\xff') && (*q !=
'\0'))
13281 (void) CopyMagickString(filename,p,(
size_t) (q-p+1));
13283 if (IsPathAccessible(filename) != MagickFalse)
13291 x_offset=((int) width*(tile % (((
int) image->columns-x)/(
int) width))+
13293 y_offset=((int) height*(tile/(((
int) image->columns-x)/(
int) width))+
13295 image_view=AcquireAuthenticCacheView(image,exception);
13296 (void) GetOneCacheViewVirtualPixelInfo(image_view,0,0,&pixel,exception);
13297 for (i=0; i < (int) height; i++)
13299 s=GetCacheViewAuthenticPixels(image_view,(ssize_t) x_offset,(ssize_t)
13300 y_offset+i,width,1,exception);
13301 if (s == (Quantum *) NULL)
13303 for (j=0; j < (int) width; j++)
13305 SetPixelViaPixelInfo(image,&pixel,s);
13306 s+=GetPixelChannels(image);
13308 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
13311 image_view=DestroyCacheView(image_view);
13314 windows->image.window_changes.width=(int) image->columns;
13315 windows->image.window_changes.height=(int) image->rows;
13316 XConfigureImageColormap(display,resource_info,windows,image,exception);
13317 (void) XConfigureImage(display,resource_info,windows,image,exception);
13323 XSetCursorState(display,windows,MagickFalse);
13324 return(tile_image);
13360static void XTranslateImage(Display *display,XWindows *windows,
13361 Image *image,
const KeySym key_symbol)
13364 text[MagickPathExtent];
13377 x_offset=windows->image.width;
13378 y_offset=windows->image.height;
13379 if (image->montage != (
char *) NULL)
13380 (void) XParseGeometry(image->montage,&x,&y,&x_offset,&y_offset);
13381 switch ((
int) key_symbol)
13386 windows->image.x=(int) windows->image.width/2;
13387 windows->image.y=(int) windows->image.height/2;
13393 windows->image.x-=(int) x_offset;
13400 windows->image.y-=(int) y_offset;
13406 windows->image.x+=(int) x_offset;
13413 windows->image.y+=(int) y_offset;
13422 if (windows->image.x < 0)
13423 windows->image.x=0;
13425 if ((windows->image.x+(
int) windows->image.width) > windows->image.ximage->width)
13426 windows->image.x=windows->image.ximage->width-(int) windows->image.width;
13427 if (windows->image.y < 0)
13428 windows->image.y=0;
13430 if ((windows->image.y+(
int) windows->image.height) > windows->image.ximage->height)
13431 windows->image.y=windows->image.ximage->height-(int)
13432 windows->image.height;
13436 (void) FormatLocaleString(text,MagickPathExtent,
" %ux%u%+d%+d ",
13437 windows->image.width,windows->image.height,windows->image.x,
13439 XInfoWidget(display,windows,text);
13440 XCheckRefreshWindows(display,windows);
13441 XDrawPanRectangle(display,windows);
13442 XRefreshWindow(display,&windows->image,(XEvent *) NULL);
13443 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
13479static MagickBooleanType XTrimImage(Display *display,
13480 XResourceInfo *resource_info,XWindows *windows,
Image *image,
13497 XSetCursorState(display,windows,MagickTrue);
13498 XCheckRefreshWindows(display,windows);
13502 background=XGetPixel(windows->image.ximage,0,0);
13503 trim_info.width=(size_t) windows->image.ximage->width;
13504 for (x=0; x < windows->image.ximage->width; x++)
13506 for (y=0; y < windows->image.ximage->height; y++)
13508 pixel=XGetPixel(windows->image.ximage,x,y);
13509 if (pixel != background)
13512 if (y < windows->image.ximage->height)
13515 trim_info.x=(ssize_t) x;
13516 if (trim_info.x == (ssize_t) windows->image.ximage->width)
13518 XSetCursorState(display,windows,MagickFalse);
13519 return(MagickFalse);
13524 background=XGetPixel(windows->image.ximage,windows->image.ximage->width-1,0);
13525 for (x=windows->image.ximage->width-1; x != 0; x--)
13527 for (y=0; y < windows->image.ximage->height; y++)
13529 pixel=XGetPixel(windows->image.ximage,x,y);
13530 if (pixel != background)
13533 if (y < windows->image.ximage->height)
13536 trim_info.width=(size_t) (x-trim_info.x+1);
13540 background=XGetPixel(windows->image.ximage,0,0);
13541 trim_info.height=(size_t) windows->image.ximage->height;
13542 for (y=0; y < windows->image.ximage->height; y++)
13544 for (x=0; x < windows->image.ximage->width; x++)
13546 pixel=XGetPixel(windows->image.ximage,x,y);
13547 if (pixel != background)
13550 if (x < windows->image.ximage->width)
13553 trim_info.y=(ssize_t) y;
13557 background=XGetPixel(windows->image.ximage,0,windows->image.ximage->height-1);
13558 for (y=windows->image.ximage->height-1; y != 0; y--)
13560 for (x=0; x < windows->image.ximage->width; x++)
13562 pixel=XGetPixel(windows->image.ximage,x,y);
13563 if (pixel != background)
13566 if (x < windows->image.ximage->width)
13569 trim_info.height=(size_t) (y-trim_info.y+1);
13570 if (((
unsigned int) trim_info.width != windows->image.width) ||
13571 ((
unsigned int) trim_info.height != windows->image.height))
13576 XSetCropGeometry(display,windows,&trim_info,image);
13577 windows->image.window_changes.width=(int) trim_info.width;
13578 windows->image.window_changes.height=(int) trim_info.height;
13579 (void) XConfigureImage(display,resource_info,windows,image,exception);
13581 XSetCursorState(display,windows,MagickFalse);
13582 return(MagickTrue);
13616static Image *XVisualDirectoryImage(Display *display,
13617 XResourceInfo *resource_info,XWindows *windows,
ExceptionInfo *exception)
13619#define TileImageTag "Scale/Image"
13620#define XClientName "montage"
13653 filename[MagickPathExtent] =
"\0",
13654 filenames[MagickPathExtent] =
"*";
13657 background_resources;
13662 XFileBrowserWidget(display,windows,
"Directory",filenames);
13663 if (*filenames ==
'\0')
13664 return((
Image *) NULL);
13668 filelist=(
char **) AcquireMagickMemory(
sizeof(*filelist));
13669 if (filelist == (
char **) NULL)
13671 ThrowXWindowException(ResourceLimitError,
"MemoryAllocationFailed",
13673 return((
Image *) NULL);
13676 filelist[0]=filenames;
13677 status=ExpandFilenames(&number_files,&filelist);
13678 if ((status == MagickFalse) || (number_files == 0))
13680 if (number_files == 0)
13681 ThrowXWindowException(ImageError,
"NoImagesWereFound",filenames)
13683 ThrowXWindowException(ResourceLimitError,
"MemoryAllocationFailed",
13685 return((
Image *) NULL);
13690 background_resources=(*resource_info);
13691 background_resources.window_id=AcquireString(
"");
13692 (void) FormatLocaleString(background_resources.window_id,MagickPathExtent,
13693 "0x%lx",windows->image.id);
13694 background_resources.backdrop=MagickTrue;
13698 backdrop=((windows->visual_info->klass == TrueColor) ||
13699 (windows->visual_info->klass == DirectColor)) ? MagickTrue : MagickFalse;
13700 read_info=CloneImageInfo(resource_info->image_info);
13701 (void) SetImageOption(read_info,
"jpeg:size",
"120x120");
13702 (void) CloneString(&read_info->size,DefaultTileGeometry);
13703 (void) SetImageInfoProgressMonitor(read_info,(MagickProgressMonitor) NULL,
13705 images=NewImageList();
13706 XSetCursorState(display,windows,MagickTrue);
13707 XCheckRefreshWindows(display,windows);
13708 for (i=0; i < (int) number_files; i++)
13710 (void) CopyMagickString(read_info->filename,filelist[i],MagickPathExtent);
13711 filelist[i]=DestroyString(filelist[i]);
13712 *read_info->magick=
'\0';
13713 next_image=ReadImage(read_info,exception);
13714 CatchException(exception);
13715 if (next_image != (
Image *) NULL)
13717 (void) DeleteImageProperty(next_image,
"label");
13718 (void) SetImageProperty(next_image,
"label",InterpretImageProperties(
13719 read_info,next_image,DefaultTileLabel,exception),exception);
13720 (void) ParseRegionGeometry(next_image,read_info->size,&geometry,
13722 thumbnail_image=ThumbnailImage(next_image,geometry.width,
13723 geometry.height,exception);
13724 if (thumbnail_image != (
Image *) NULL)
13726 next_image=DestroyImage(next_image);
13727 next_image=thumbnail_image;
13731 (void) XDisplayBackgroundImage(display,&background_resources,
13732 next_image,exception);
13733 XSetCursorState(display,windows,MagickTrue);
13735 AppendImageToList(&images,next_image);
13736 if (images->progress_monitor != (MagickProgressMonitor) NULL)
13741 proceed=SetImageProgress(images,LoadImageTag,(MagickOffsetType) i,
13742 (MagickSizeType) number_files);
13743 if (proceed == MagickFalse)
13748 filelist=(
char **) RelinquishMagickMemory(filelist);
13749 if (images == (
Image *) NULL)
13751 read_info=DestroyImageInfo(read_info);
13752 XSetCursorState(display,windows,MagickFalse);
13753 ThrowXWindowException(ImageError,
"NoImagesWereLoaded",filenames);
13754 return((
Image *) NULL);
13759 montage_info=CloneMontageInfo(read_info,(
MontageInfo *) NULL);
13760 montage_info->pointsize=10;
13761 if (resource_info->font != (
char *) NULL)
13762 (void) CloneString(&montage_info->font,resource_info->font);
13763 (void) CopyMagickString(montage_info->filename,filename,MagickPathExtent);
13764 montage_image=MontageImageList(read_info,montage_info,GetFirstImageInList(
13765 images),exception);
13766 images=DestroyImageList(images);
13767 montage_info=DestroyMontageInfo(montage_info);
13768 read_info=DestroyImageInfo(read_info);
13769 XSetCursorState(display,windows,MagickFalse);
13770 if (montage_image == (
Image *) NULL)
13771 return(montage_image);
13772 XClientMessage(display,windows->image.id,windows->im_protocols,
13773 windows->im_next_image,CurrentTime);
13774 return(montage_image);
13807MagickExport MagickBooleanType XDisplayBackgroundImage(Display *display,
13811 geometry[MagickPathExtent],
13812 visual_type[MagickPathExtent];
13825 static XStandardColormap
13829 *visual_info = (XVisualInfo *) NULL;
13852 assert(image != (
Image *) NULL);
13853 assert(image->signature == MagickCoreSignature);
13854 if (IsEventLogging() != MagickFalse)
13855 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
13856 resources=(*resource_info);
13857 window_info.id=(Window) NULL;
13858 root_window=XRootWindow(display,XDefaultScreen(display));
13859 if (LocaleCompare(resources.window_id,
"root") == 0)
13860 window_info.id=root_window;
13863 if (isdigit((
int) ((
unsigned char) *resources.window_id)) != 0)
13864 window_info.id=XWindowByID(display,root_window,
13865 (Window) strtol((
char *) resources.window_id,(
char **) NULL,0));
13866 if (window_info.id == (Window) NULL)
13867 window_info.id=XWindowByName(display,root_window,resources.window_id);
13869 if (window_info.id == (Window) NULL)
13871 ThrowXWindowException(XServerError,
"NoWindowWithSpecifiedIDExists",
13872 resources.window_id);
13873 return(MagickFalse);
13878 window_attributes.width=XDisplayWidth(display,XDefaultScreen(display));
13879 window_attributes.height=XDisplayHeight(display,XDefaultScreen(display));
13880 (void) CopyMagickString(visual_type,
"default",MagickPathExtent);
13881 status=XGetWindowAttributes(display,window_info.id,&window_attributes);
13883 (void) FormatLocaleString(visual_type,MagickPathExtent,
"0x%lx",
13884 XVisualIDFromVisual(window_attributes.visual));
13885 if (visual_info == (XVisualInfo *) NULL)
13890 map_info=XAllocStandardColormap();
13891 if (map_info == (XStandardColormap *) NULL)
13892 ThrowXWindowFatalException(XServerFatalError,
"MemoryAllocationFailed",
13894 map_info->colormap=(Colormap) NULL;
13895 pixel.pixels=(
unsigned long *) NULL;
13899 resources.map_type=(
char *) NULL;
13900 resources.visual_type=visual_type;
13901 visual_info=XBestVisualInfo(display,map_info,&resources);
13902 if (visual_info == (XVisualInfo *) NULL)
13903 ThrowXWindowFatalException(XServerFatalError,
"UnableToGetVisual",
13904 resources.visual_type);
13908 window_info.ximage=(XImage *) NULL;
13909 window_info.matte_image=(XImage *) NULL;
13910 window_info.pixmap=(Pixmap) NULL;
13911 window_info.matte_pixmap=(Pixmap) NULL;
13916 if (window_info.id == root_window)
13917 (void) XDestroyWindowColors(display,root_window);
13921 resources.colormap=SharedColormap;
13922 XMakeStandardColormap(display,visual_info,&resources,image,map_info,&pixel,
13927 context_values.background=pixel.foreground_color.pixel;
13928 context_values.foreground=pixel.background_color.pixel;
13929 pixel.annotate_context=XCreateGC(display,window_info.id,
13930 (
size_t) (GCBackground | GCForeground),&context_values);
13931 if (pixel.annotate_context == (GC) NULL)
13932 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
13937 window_info.name=AcquireString(
"\0");
13938 window_info.icon_name=AcquireString(
"\0");
13939 XGetWindowInfo(display,visual_info,map_info,&pixel,(XFontStruct *) NULL,
13940 &resources,&window_info);
13944 window_info.width=(
unsigned int) image->columns;
13945 window_info.height=(
unsigned int) image->rows;
13946 if ((image->columns != window_info.width) ||
13947 (image->rows != window_info.height))
13948 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
13950 (void) FormatLocaleString(geometry,MagickPathExtent,
"%ux%u+0+0>",
13951 window_attributes.width,window_attributes.height);
13952 geometry_info.width=window_info.width;
13953 geometry_info.height=window_info.height;
13954 geometry_info.x=(ssize_t) window_info.x;
13955 geometry_info.y=(ssize_t) window_info.y;
13956 (void) ParseMetaGeometry(geometry,&geometry_info.x,&geometry_info.y,
13957 &geometry_info.width,&geometry_info.height);
13958 window_info.width=(
unsigned int) geometry_info.width;
13959 window_info.height=(
unsigned int) geometry_info.height;
13960 window_info.x=(int) geometry_info.x;
13961 window_info.y=(int) geometry_info.y;
13962 status=XMakeImage(display,&resources,&window_info,image,window_info.width,
13963 window_info.height,exception) == MagickFalse ? 0 : 1;
13964 if (status == MagickFalse)
13965 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
13969 if (resource_info->debug != MagickFalse)
13971 (void) LogMagickEvent(X11Event,GetMagickModule(),
13972 "Image: %s[%.20g] %.20gx%.20g ",image->filename,(double) image->scene,
13973 (
double) image->columns,(double) image->rows);
13974 if (image->colors != 0)
13975 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%.20gc ",(double)
13977 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%s",image->magick);
13982 width=(int) window_info.width;
13983 height=(int) window_info.height;
13984 if (resources.backdrop != MagickFalse)
13989 window_info.x=(window_attributes.width/2)-(window_info.ximage->width/2);
13990 window_info.y=(window_attributes.height/2)-(window_info.ximage->height/2);
13991 width=window_attributes.width;
13992 height=window_attributes.height;
13994 if ((resources.image_geometry != (
char *) NULL) &&
13995 (*resources.image_geometry !=
'\0'))
13998 default_geometry[MagickPathExtent];
14010 size_hints=XAllocSizeHints();
14011 if (size_hints == (XSizeHints *) NULL)
14012 ThrowXWindowFatalException(ResourceLimitFatalError,
14013 "MemoryAllocationFailed",image->filename);
14014 size_hints->flags=0L;
14015 (void) FormatLocaleString(default_geometry,MagickPathExtent,
"%dx%d",
14017 flags=XWMGeometry(display,visual_info->screen,resources.image_geometry,
14018 default_geometry,window_info.border_width,size_hints,&window_info.x,
14019 &window_info.y,&width,&height,&gravity);
14020 if (flags & (XValue | YValue))
14022 width=window_attributes.width;
14023 height=window_attributes.height;
14025 (void) XFree((
void *) size_hints);
14030 window_info.pixmap=XCreatePixmap(display,window_info.id,(
unsigned int) width,
14031 (
unsigned int) height,window_info.depth);
14032 if (window_info.pixmap == (Pixmap) NULL)
14033 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXPixmap",
14038 if (((
unsigned int) width > window_info.width) ||
14039 ((
unsigned int) height > window_info.height))
14040 (void) XFillRectangle(display,window_info.pixmap,
14041 window_info.annotate_context,0,0,(
unsigned int) width,
14042 (
unsigned int) height);
14043 (void) XPutImage(display,window_info.pixmap,window_info.annotate_context,
14044 window_info.ximage,0,0,window_info.x,window_info.y,(
unsigned int)
14045 window_info.width,(
unsigned int) window_info.height);
14046 (void) XSetWindowBackgroundPixmap(display,window_info.id,window_info.pixmap);
14047 (void) XClearWindow(display,window_info.id);
14048 delay=1000*image->delay/(size_t) MagickMax(image->ticks_per_second,1L);
14049 XDelay(display,delay == 0UL ? 10UL : delay);
14050 (void) XSync(display,MagickFalse);
14051 return(window_info.id == root_window ? MagickTrue : MagickFalse);
14094MagickExport
Image *XDisplayImage(Display *display,XResourceInfo *resource_info,
14097#define MagnifySize 256
14098#define MagickMenus 10
14099#define MagickTitle "Commands"
14102 *
const CommandMenu[] =
14116 *
const FileMenu[] =
14126 "Visual Directory...",
14130 *
const EditMenu[] =
14139 *
const ViewMenu[] =
14150 *
const TransformMenu[] =
14164 *
const EnhanceMenu[] =
14172 "Contrast Stretch...",
14173 "Sigmoidal Contrast...",
14182 *
const EffectsMenu[] =
14207 "Charcoal Draw...",
14210 *
const ImageEditMenu[] =
14221 "Region of Interest...",
14224 *
const MiscellanyMenu[] =
14236 *
const HelpMenu[] =
14239 "Browse Documentation",
14243 *
const ShortCutsMenu[] =
14256 *
const VirtualMenu[] =
14266 *
const *Menus[MagickMenus] =
14280 static DisplayCommand
14304 VisualDirectoryCommand,
14318 OriginalSizeCommand,
14325 TransformCommands[] =
14331 RotateRightCommand,
14338 EnhanceCommands[] =
14346 ContrastStretchCommand,
14347 SigmoidalContrastCommand,
14355 EffectsCommands[] =
14359 ReduceNoiseCommand,
14379 CharcoalDrawCommand
14381 ImageEditCommands[] =
14392 RegionOfInterestCommand
14394 MiscellanyCommands[] =
14398 ShowPreviewCommand,
14399 ShowHistogramCommand,
14408 BrowseDocumentationCommand,
14411 ShortCutsCommands[] =
14423 VirtualCommands[] =
14431 static DisplayCommand
14432 *Commands[MagickMenus] =
14442 MiscellanyCommands,
14447 command[MagickPathExtent],
14449 geometry[MagickPathExtent],
14450 resource_name[MagickPathExtent];
14477 working_directory[MagickPathExtent];
14483 *magick_windows[MaxXWindows];
14485 static unsigned int
14545 assert(image != (
Image **) NULL);
14546 assert((*image)->signature == MagickCoreSignature);
14547 if (IsEventLogging() != MagickFalse)
14548 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",(*image)->filename);
14549 display_image=(*image);
14550 warning_handler=(WarningHandler) NULL;
14551 windows=XSetWindows((XWindows *) ~0);
14552 if (windows != (XWindows *) NULL)
14557 if (*working_directory ==
'\0')
14558 (void) CopyMagickString(working_directory,
".",MagickPathExtent);
14559 status=chdir(working_directory);
14561 (void) ThrowMagickException(exception,GetMagickModule(),FileOpenError,
14562 "UnableToOpenFile",
"%s",working_directory);
14563 warning_handler=resource_info->display_warnings ?
14564 SetErrorHandler(XWarning) : SetErrorHandler((ErrorHandler) NULL);
14565 warning_handler=resource_info->display_warnings ?
14566 SetWarningHandler(XWarning) : SetWarningHandler((WarningHandler) NULL);
14573 resource_info->colors=display_image->colors;
14574 windows=XSetWindows(XInitializeWindows(display,resource_info));
14575 if (windows == (XWindows *) NULL)
14576 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateWindow",
14577 (*image)->filename);
14582 magick_windows[number_windows++]=(&windows->icon);
14583 magick_windows[number_windows++]=(&windows->backdrop);
14584 magick_windows[number_windows++]=(&windows->image);
14585 magick_windows[number_windows++]=(&windows->info);
14586 magick_windows[number_windows++]=(&windows->command);
14587 magick_windows[number_windows++]=(&windows->widget);
14588 magick_windows[number_windows++]=(&windows->popup);
14589 magick_windows[number_windows++]=(&windows->magnify);
14590 magick_windows[number_windows++]=(&windows->pan);
14591 for (i=0; i < (int) number_windows; i++)
14592 magick_windows[i]->
id=(Window) NULL;
14599 if (windows->font_info != (XFontStruct *) NULL)
14600 (
void) XFreeFont(display,windows->font_info);
14601 windows->font_info=XBestFont(display,resource_info,MagickFalse);
14602 if (windows->font_info == (XFontStruct *) NULL)
14603 ThrowXWindowFatalException(XServerFatalError,
"UnableToLoadFont",
14604 resource_info->font);
14608 map_info=windows->map_info;
14609 icon_map=windows->icon_map;
14610 visual_info=windows->visual_info;
14611 icon_visual=windows->icon_visual;
14612 pixel=windows->pixel_info;
14613 icon_pixel=windows->icon_pixel;
14614 font_info=windows->font_info;
14615 icon_resources=windows->icon_resources;
14616 class_hints=windows->class_hints;
14617 manager_hints=windows->manager_hints;
14618 root_window=XRootWindow(display,visual_info->screen);
14619 nexus=NewImageList();
14620 if (resource_info->debug != MagickFalse)
14622 (void) LogMagickEvent(X11Event,GetMagickModule(),
14623 "Image: %s[%.20g] %.20gx%.20g ",display_image->filename,
14624 (double) display_image->scene,(
double) display_image->columns,
14625 (double) display_image->rows);
14626 if (display_image->colors != 0)
14627 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%.20gc ",(double)
14628 display_image->colors);
14629 (void) LogMagickEvent(X11Event,GetMagickModule(),
"%s",
14630 display_image->magick);
14632 XMakeStandardColormap(display,visual_info,resource_info,display_image,
14633 map_info,pixel,exception);
14634 display_image->taint=MagickFalse;
14638 windows->context.id=(Window) NULL;
14639 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14640 resource_info,&windows->context);
14641 (void) CloneString(&class_hints->res_name,resource_info->client_name);
14642 (void) CloneString(&class_hints->res_class,resource_info->client_name);
14643 class_hints->res_class[0]=(char) LocaleToUppercase((
int)
14644 class_hints->res_class[0]);
14645 manager_hints->flags=InputHint | StateHint;
14646 manager_hints->input=MagickFalse;
14647 manager_hints->initial_state=WithdrawnState;
14648 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14649 &windows->context);
14650 if (resource_info->debug != MagickFalse)
14651 (void) LogMagickEvent(X11Event,GetMagickModule(),
14652 "Window id: 0x%lx (context)",windows->context.id);
14653 context_values.background=pixel->background_color.pixel;
14654 context_values.font=font_info->fid;
14655 context_values.foreground=pixel->foreground_color.pixel;
14656 context_values.graphics_exposures=MagickFalse;
14657 context_mask=(MagickStatusType)
14658 (GCBackground | GCFont | GCForeground | GCGraphicsExposures);
14659 if (pixel->annotate_context != (GC) NULL)
14660 (
void) XFreeGC(display,pixel->annotate_context);
14661 pixel->annotate_context=XCreateGC(display,windows->context.id,
14662 context_mask,&context_values);
14663 if (pixel->annotate_context == (GC) NULL)
14664 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14665 display_image->filename);
14666 context_values.background=pixel->depth_color.pixel;
14667 if (pixel->widget_context != (GC) NULL)
14668 (void) XFreeGC(display,pixel->widget_context);
14669 pixel->widget_context=XCreateGC(display,windows->context.id,context_mask,
14671 if (pixel->widget_context == (GC) NULL)
14672 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14673 display_image->filename);
14674 context_values.background=pixel->foreground_color.pixel;
14675 context_values.foreground=pixel->background_color.pixel;
14676 context_values.plane_mask=context_values.background ^
14677 context_values.foreground;
14678 if (pixel->highlight_context != (GC) NULL)
14679 (void) XFreeGC(display,pixel->highlight_context);
14680 pixel->highlight_context=XCreateGC(display,windows->context.id,
14681 (
size_t) (context_mask | GCPlaneMask),&context_values);
14682 if (pixel->highlight_context == (GC) NULL)
14683 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14684 display_image->filename);
14685 (void) XDestroyWindow(display,windows->context.id);
14689 XGetWindowInfo(display,icon_visual,icon_map,icon_pixel,(XFontStruct *) NULL,
14690 icon_resources,&windows->icon);
14691 windows->icon.geometry=resource_info->icon_geometry;
14692 XBestIconSize(display,&windows->icon,display_image);
14693 windows->icon.attributes.colormap=XDefaultColormap(display,
14694 icon_visual->screen);
14695 windows->icon.attributes.event_mask=ExposureMask | StructureNotifyMask;
14696 manager_hints->flags=InputHint | StateHint;
14697 manager_hints->input=MagickFalse;
14698 manager_hints->initial_state=IconicState;
14699 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14701 if (resource_info->debug != MagickFalse)
14702 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (icon)",
14707 if (icon_pixel->annotate_context != (GC) NULL)
14708 (
void) XFreeGC(display,icon_pixel->annotate_context);
14709 context_values.background=icon_pixel->background_color.pixel;
14710 context_values.foreground=icon_pixel->foreground_color.pixel;
14711 icon_pixel->annotate_context=XCreateGC(display,windows->icon.id,
14712 (
size_t) (GCBackground | GCForeground),&context_values);
14713 if (icon_pixel->annotate_context == (GC) NULL)
14714 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateGraphicContext",
14715 display_image->filename);
14716 windows->icon.annotate_context=icon_pixel->annotate_context;
14720 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,resource_info,
14722 windows->image.shape=MagickTrue;
14723 if (resource_info->use_shared_memory == MagickFalse)
14724 windows->image.shared_memory=MagickFalse;
14725 if ((resource_info->title != (
char *) NULL) && !(*state & MontageImageState))
14730 title=InterpretImageProperties(resource_info->image_info,display_image,
14731 resource_info->title,exception);
14732 (void) CloneString(&windows->image.name,title);
14733 (void) CloneString(&windows->image.icon_name,title);
14734 title=DestroyString(title);
14739 filename[MagickPathExtent],
14740 window_name[MagickPathExtent];
14745 GetPathComponent(display_image->magick_filename,TailPath,filename);
14746 if (display_image->scene == 0)
14747 (void) FormatLocaleString(window_name,MagickPathExtent,
"%s: %s",
14748 MagickPackageName,filename);
14750 (
void) FormatLocaleString(window_name,MagickPathExtent,
14751 "%s: %s[scene: %.20g frames: %.20g]",MagickPackageName,filename,
14752 (
double) display_image->scene,(
double) GetImageListLength(
14754 (void) CloneString(&windows->image.name,window_name);
14755 (void) CloneString(&windows->image.icon_name,filename);
14757 if (resource_info->immutable)
14758 windows->image.immutable=MagickTrue;
14759 windows->image.use_pixmap=resource_info->use_pixmap;
14760 windows->image.geometry=resource_info->image_geometry;
14761 (void) FormatLocaleString(geometry,MagickPathExtent,
"%ux%u+0+0>!",
14762 XDisplayWidth(display,visual_info->screen),
14763 XDisplayHeight(display,visual_info->screen));
14764 geometry_info.width=display_image->columns;
14765 geometry_info.height=display_image->rows;
14768 (void) ParseMetaGeometry(geometry,&geometry_info.x,&geometry_info.y,
14769 &geometry_info.width,&geometry_info.height);
14770 windows->image.width=(
unsigned int) geometry_info.width;
14771 windows->image.height=(
unsigned int) geometry_info.height;
14772 windows->image.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14773 ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
14774 KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask |
14775 PropertyChangeMask | StructureNotifyMask | SubstructureNotifyMask;
14776 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14777 resource_info,&windows->backdrop);
14778 if ((resource_info->backdrop) || (windows->backdrop.id != (Window) NULL))
14783 windows->backdrop.x=0;
14784 windows->backdrop.y=0;
14785 (void) CloneString(&windows->backdrop.name,
"Backdrop");
14786 windows->backdrop.flags=(size_t) (USSize | USPosition);
14787 windows->backdrop.width=(
unsigned int)
14788 XDisplayWidth(display,visual_info->screen);
14789 windows->backdrop.height=(
unsigned int)
14790 XDisplayHeight(display,visual_info->screen);
14791 windows->backdrop.border_width=0;
14792 windows->backdrop.immutable=MagickTrue;
14793 windows->backdrop.attributes.do_not_propagate_mask=ButtonPressMask |
14795 windows->backdrop.attributes.event_mask=ButtonPressMask | KeyPressMask |
14796 StructureNotifyMask;
14797 manager_hints->flags=IconWindowHint | InputHint | StateHint;
14798 manager_hints->icon_window=windows->icon.id;
14799 manager_hints->input=MagickTrue;
14800 manager_hints->initial_state=resource_info->iconic ? IconicState :
14802 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14803 &windows->backdrop);
14804 if (resource_info->debug != MagickFalse)
14805 (void) LogMagickEvent(X11Event,GetMagickModule(),
14806 "Window id: 0x%lx (backdrop)",windows->backdrop.id);
14807 (void) XMapWindow(display,windows->backdrop.id);
14808 (void) XClearWindow(display,windows->backdrop.id);
14809 if (windows->image.id != (Window) NULL)
14811 (void) XDestroyWindow(display,windows->image.id);
14812 windows->image.id=(Window) NULL;
14817 windows->image.flags|=USPosition;
14818 windows->image.x=(XDisplayWidth(display,visual_info->screen)/2)-
14819 ((
int) windows->image.width/2);
14820 windows->image.y=(XDisplayHeight(display,visual_info->screen)/2)-
14821 ((
int) windows->image.height/2);
14823 manager_hints->flags=IconWindowHint | InputHint | StateHint;
14824 manager_hints->icon_window=windows->icon.id;
14825 manager_hints->input=MagickTrue;
14826 manager_hints->initial_state=resource_info->iconic ? IconicState :
14828 if (windows->group_leader.id != (Window) NULL)
14833 manager_hints->flags|=WindowGroupHint;
14834 manager_hints->window_group=windows->group_leader.id;
14835 (void) XSelectInput(display,windows->group_leader.id,StructureNotifyMask);
14836 if (resource_info->debug != MagickFalse)
14837 (void) LogMagickEvent(X11Event,GetMagickModule(),
14838 "Window id: 0x%lx (group leader)",windows->group_leader.id);
14840 XMakeWindow(display,
14841 (Window) (resource_info->backdrop ? windows->backdrop.id : root_window),
14842 argv,argc,class_hints,manager_hints,&windows->image);
14843 (void) XChangeProperty(display,windows->image.id,windows->im_protocols,
14844 XA_STRING,8,PropModeReplace,(
unsigned char *) NULL,0);
14845 if (windows->group_leader.id != (Window) NULL)
14846 (
void) XSetTransientForHint(display,windows->image.id,
14847 windows->group_leader.id);
14848 if (resource_info->debug != MagickFalse)
14849 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (image)",
14850 windows->image.id);
14854 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,resource_info,
14856 (void) CloneString(&windows->info.name,
"Info");
14857 (void) CloneString(&windows->info.icon_name,
"Info");
14858 windows->info.border_width=1;
14861 windows->info.flags|=PPosition;
14862 windows->info.attributes.win_gravity=UnmapGravity;
14863 windows->info.attributes.event_mask=ButtonPressMask | ExposureMask |
14864 StructureNotifyMask;
14865 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14866 manager_hints->input=MagickFalse;
14867 manager_hints->initial_state=NormalState;
14868 manager_hints->window_group=windows->image.id;
14869 XMakeWindow(display,windows->image.id,argv,argc,class_hints,manager_hints,
14871 windows->info.highlight_stipple=XCreateBitmapFromData(display,
14872 windows->info.id,(
char *) HighlightBitmap,HighlightWidth,HighlightHeight);
14873 windows->info.shadow_stipple=XCreateBitmapFromData(display,
14874 windows->info.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14875 (void) XSetTransientForHint(display,windows->info.id,windows->image.id);
14876 if (windows->image.mapped != MagickFalse)
14877 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
14878 if (resource_info->debug != MagickFalse)
14879 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (info)",
14884 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14885 resource_info,&windows->command);
14886 windows->command.data=MagickMenus;
14887 (void) XCommandWidget(display,windows,CommandMenu,(XEvent *) NULL);
14888 (void) FormatLocaleString(resource_name,MagickPathExtent,
"%s.command",
14889 resource_info->client_name);
14890 windows->command.geometry=XGetResourceClass(resource_info->resource_database,
14891 resource_name,
"geometry",(
char *) NULL);
14892 (void) CloneString(&windows->command.name,MagickTitle);
14893 windows->command.border_width=0;
14894 windows->command.flags|=PPosition;
14895 windows->command.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14896 ButtonReleaseMask | EnterWindowMask | ExposureMask | LeaveWindowMask |
14897 OwnerGrabButtonMask | StructureNotifyMask;
14898 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14899 manager_hints->input=MagickTrue;
14900 manager_hints->initial_state=NormalState;
14901 manager_hints->window_group=windows->image.id;
14902 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14903 &windows->command);
14904 windows->command.highlight_stipple=XCreateBitmapFromData(display,
14905 windows->command.id,(
char *) HighlightBitmap,HighlightWidth,
14907 windows->command.shadow_stipple=XCreateBitmapFromData(display,
14908 windows->command.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14909 (void) XSetTransientForHint(display,windows->command.id,windows->image.id);
14910 if (windows->command.mapped != MagickFalse)
14911 (void) XMapRaised(display,windows->command.id);
14912 if (resource_info->debug != MagickFalse)
14913 (void) LogMagickEvent(X11Event,GetMagickModule(),
14914 "Window id: 0x%lx (command)",windows->command.id);
14918 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14919 resource_info,&windows->widget);
14920 (void) FormatLocaleString(resource_name,MagickPathExtent,
"%s.widget",
14921 resource_info->client_name);
14922 windows->widget.geometry=XGetResourceClass(resource_info->resource_database,
14923 resource_name,
"geometry",(
char *) NULL);
14924 windows->widget.border_width=0;
14925 windows->widget.flags|=PPosition;
14926 windows->widget.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14927 ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
14928 KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask |
14929 StructureNotifyMask;
14930 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14931 manager_hints->input=MagickTrue;
14932 manager_hints->initial_state=NormalState;
14933 manager_hints->window_group=windows->image.id;
14934 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14936 windows->widget.highlight_stipple=XCreateBitmapFromData(display,
14937 windows->widget.id,(
char *) HighlightBitmap,HighlightWidth,HighlightHeight);
14938 windows->widget.shadow_stipple=XCreateBitmapFromData(display,
14939 windows->widget.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14940 (void) XSetTransientForHint(display,windows->widget.id,windows->image.id);
14941 if (resource_info->debug != MagickFalse)
14942 (void) LogMagickEvent(X11Event,GetMagickModule(),
14943 "Window id: 0x%lx (widget)",windows->widget.id);
14947 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14948 resource_info,&windows->popup);
14949 windows->popup.border_width=0;
14950 windows->popup.flags|=PPosition;
14951 windows->popup.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
14952 ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask |
14953 KeyReleaseMask | LeaveWindowMask | StructureNotifyMask;
14954 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
14955 manager_hints->input=MagickTrue;
14956 manager_hints->initial_state=NormalState;
14957 manager_hints->window_group=windows->image.id;
14958 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
14960 windows->popup.highlight_stipple=XCreateBitmapFromData(display,
14961 windows->popup.id,(
char *) HighlightBitmap,HighlightWidth,HighlightHeight);
14962 windows->popup.shadow_stipple=XCreateBitmapFromData(display,
14963 windows->popup.id,(
char *) ShadowBitmap,ShadowWidth,ShadowHeight);
14964 (void) XSetTransientForHint(display,windows->popup.id,windows->image.id);
14965 if (resource_info->debug != MagickFalse)
14966 (void) LogMagickEvent(X11Event,GetMagickModule(),
14967 "Window id: 0x%lx (pop up)",windows->popup.id);
14971 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
14972 resource_info,&windows->magnify);
14973 if (resource_info->use_shared_memory == MagickFalse)
14974 windows->magnify.shared_memory=MagickFalse;
14975 (void) FormatLocaleString(resource_name,MagickPathExtent,
"%s.magnify",
14976 resource_info->client_name);
14977 windows->magnify.geometry=XGetResourceClass(resource_info->resource_database,
14978 resource_name,
"geometry",(
char *) NULL);
14979 (void) FormatLocaleString(windows->magnify.name,MagickPathExtent,
14980 "Magnify %uX",resource_info->magnify);
14981 if (windows->magnify.cursor != (Cursor) NULL)
14982 (
void) XFreeCursor(display,windows->magnify.cursor);
14983 windows->magnify.cursor=XMakeCursor(display,windows->image.id,
14984 map_info->colormap,resource_info->background_color,
14985 resource_info->foreground_color);
14986 if (windows->magnify.cursor == (Cursor) NULL)
14987 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateCursor",
14988 display_image->filename);
14989 windows->magnify.width=MagnifySize;
14990 windows->magnify.height=MagnifySize;
14991 windows->magnify.flags|=PPosition;
14992 windows->magnify.min_width=MagnifySize;
14993 windows->magnify.min_height=MagnifySize;
14994 windows->magnify.width_inc=MagnifySize;
14995 windows->magnify.height_inc=MagnifySize;
14996 windows->magnify.data=resource_info->magnify;
14997 windows->magnify.attributes.cursor=windows->magnify.cursor;
14998 windows->magnify.attributes.event_mask=ButtonPressMask | ButtonReleaseMask |
14999 ExposureMask | KeyPressMask | KeyReleaseMask | OwnerGrabButtonMask |
15000 StructureNotifyMask;
15001 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
15002 manager_hints->input=MagickTrue;
15003 manager_hints->initial_state=NormalState;
15004 manager_hints->window_group=windows->image.id;
15005 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
15006 &windows->magnify);
15007 if (resource_info->debug != MagickFalse)
15008 (void) LogMagickEvent(X11Event,GetMagickModule(),
15009 "Window id: 0x%lx (magnify)",windows->magnify.id);
15010 (void) XSetTransientForHint(display,windows->magnify.id,windows->image.id);
15014 XGetWindowInfo(display,visual_info,map_info,pixel,font_info,
15015 resource_info,&windows->pan);
15016 (void) CloneString(&windows->pan.name,
"Pan Icon");
15017 windows->pan.width=windows->icon.width;
15018 windows->pan.height=windows->icon.height;
15019 (void) FormatLocaleString(resource_name,MagickPathExtent,
"%s.pan",
15020 resource_info->client_name);
15021 windows->pan.geometry=XGetResourceClass(resource_info->resource_database,
15022 resource_name,
"geometry",(
char *) NULL);
15023 (void) XParseGeometry(windows->pan.geometry,&windows->pan.x,&windows->pan.y,
15024 &windows->pan.width,&windows->pan.height);
15025 windows->pan.flags|=PPosition;
15026 windows->pan.immutable=MagickTrue;
15027 windows->pan.attributes.event_mask=ButtonMotionMask | ButtonPressMask |
15028 ButtonReleaseMask | ExposureMask | KeyPressMask | KeyReleaseMask |
15029 StructureNotifyMask;
15030 manager_hints->flags=InputHint | StateHint | WindowGroupHint;
15031 manager_hints->input=MagickFalse;
15032 manager_hints->initial_state=NormalState;
15033 manager_hints->window_group=windows->image.id;
15034 XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints,
15036 if (resource_info->debug != MagickFalse)
15037 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Window id: 0x%lx (pan)",
15039 (void) XSetTransientForHint(display,windows->pan.id,windows->image.id);
15040 if (windows->info.mapped != MagickFalse)
15041 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
15042 if ((windows->image.mapped == MagickFalse) ||
15043 (windows->backdrop.id != (Window) NULL))
15044 (
void) XMapWindow(display,windows->image.id);
15048 if (warning_handler == (WarningHandler) NULL)
15050 warning_handler=resource_info->display_warnings ?
15051 SetErrorHandler(XWarning) : SetErrorHandler((ErrorHandler) NULL);
15052 warning_handler=resource_info->display_warnings ?
15053 SetWarningHandler(XWarning) : SetWarningHandler((WarningHandler) NULL);
15058 windows->image.x=0;
15059 windows->image.y=0;
15060 windows->magnify.shape=MagickFalse;
15061 width=(
unsigned int) display_image->columns;
15062 height=(
unsigned int) display_image->rows;
15063 if ((display_image->columns != width) || (display_image->rows != height))
15064 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
15065 display_image->filename);
15066 status=XMakeImage(display,resource_info,&windows->image,display_image,
15067 width,height,exception);
15068 if (status == MagickFalse)
15069 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
15070 display_image->filename);
15071 status=XMakeImage(display,resource_info,&windows->magnify,(
Image *) NULL,
15072 windows->magnify.width,windows->magnify.height,exception);
15073 if (status == MagickFalse)
15074 ThrowXWindowFatalException(XServerFatalError,
"UnableToCreateXImage",
15075 display_image->filename);
15076 if (windows->magnify.mapped != MagickFalse)
15077 (void) XMapRaised(display,windows->magnify.id);
15078 if (windows->pan.mapped != MagickFalse)
15079 (void) XMapRaised(display,windows->pan.id);
15080 windows->image.window_changes.width=(int) display_image->columns;
15081 windows->image.window_changes.height=(int) display_image->rows;
15082 (void) XConfigureImage(display,resource_info,windows,display_image,exception);
15083 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
15084 (void) XSync(display,MagickFalse);
15088 delay=display_image->delay/(size_t)
15089 MagickMax(display_image->ticks_per_second,1L);
15090 timer=GetMagickTime()+(time_t) (delay == 0 ? 1 : delay)+1;
15092 if (resource_info->update != MagickFalse)
15100 status=GetPathAttributes(display_image->filename,&attributes);
15101 if (status != MagickFalse)
15102 update_time=attributes.st_mtime;
15104 *state&=(
unsigned int) (~FormerImageState);
15105 *state&=(
unsigned int) (~MontageImageState);
15106 *state&=(
unsigned int) (~NextImageState);
15112 if (windows->image.mapped != MagickFalse)
15113 if ((display_image->delay != 0) || (resource_info->update != 0))
15115 if (timer < GetMagickTime())
15117 if (resource_info->update == MagickFalse)
15118 *state|=NextImageState | ExitState;
15127 status=GetPathAttributes(display_image->filename,&attributes);
15128 if (status != MagickFalse)
15129 if (update_time != attributes.st_mtime)
15134 (void) FormatLocaleString(
15135 resource_info->image_info->filename,MagickPathExtent,
15136 "%s:%s",display_image->magick,
15137 display_image->filename);
15138 nexus=ReadImage(resource_info->image_info,exception);
15139 if (nexus != (
Image *) NULL)
15140 *state|=NextImageState | ExitState;
15142 delay=display_image->delay/(size_t) MagickMax(
15143 display_image->ticks_per_second,1L);
15144 timer=GetMagickTime()+(time_t) (delay == 0 ? 1 : delay)+1;
15147 if (XEventsQueued(display,QueuedAfterFlush) == 0)
15152 XDelay(display,SuspendTime << 2);
15156 timestamp=GetMagickTime();
15157 (void) XNextEvent(display,&event);
15158 if ((windows->image.stasis == MagickFalse) ||
15159 (windows->magnify.stasis == MagickFalse))
15161 if ((GetMagickTime()-timestamp) > 0)
15163 windows->image.stasis=MagickTrue;
15164 windows->magnify.stasis=MagickTrue;
15167 if (event.xany.window == windows->command.id)
15172 id=XCommandWidget(display,windows,CommandMenu,&event);
15175 (void) CopyMagickString(command,CommandMenu[
id],MagickPathExtent);
15176 display_command=CommandMenus[id];
15177 if (
id < MagickMenus)
15182 entry=XMenuWidget(display,windows,CommandMenu[
id],Menus[
id],
15186 (void) CopyMagickString(command,Menus[
id][entry],MagickPathExtent);
15187 display_command=Commands[id][entry];
15189 if (display_command != NullCommand)
15190 nexus=XMagickCommand(display,resource_info,windows,display_command,
15191 &display_image,exception);
15194 switch (event.type)
15198 if (resource_info->debug != MagickFalse)
15199 (void) LogMagickEvent(X11Event,GetMagickModule(),
15200 "Button Press: 0x%lx %u +%d+%d",
event.xbutton.window,
15201 event.xbutton.button,
event.xbutton.x,
event.xbutton.y);
15202 if ((event.xbutton.button == Button3) &&
15203 (
event.xbutton.state & Mod1Mask))
15208 event.xbutton.button=Button2;
15209 event.xbutton.state&=(
unsigned int) (~Mod1Mask);
15211 if (event.xbutton.window == windows->backdrop.id)
15213 (void) XSetInputFocus(display,event.xbutton.window,RevertToParent,
15214 event.xbutton.time);
15217 if (event.xbutton.window == windows->image.id)
15219 switch (event.xbutton.button)
15223 if (resource_info->immutable)
15228 entry=XMenuWidget(display,windows,
"Commands",VirtualMenu,
15231 nexus=XMagickCommand(display,resource_info,windows,
15232 VirtualCommands[entry],&display_image,exception);
15238 if (windows->command.mapped != MagickFalse)
15239 (void) XWithdrawWindow(display,windows->command.id,
15240 windows->command.screen);
15243 (void) XCommandWidget(display,windows,CommandMenu,
15245 (void) XMapRaised(display,windows->command.id);
15254 (void) XMagickCommand(display,resource_info,windows,ZoomCommand,
15255 &display_image,exception);
15256 XMagnifyImage(display,windows,&event,exception);
15261 if (resource_info->immutable)
15266 entry=XMenuWidget(display,windows,
"Commands",VirtualMenu,
15269 nexus=XMagickCommand(display,resource_info,windows,
15270 VirtualCommands[entry],&display_image,exception);
15273 if (display_image->montage != (
char *) NULL)
15278 nexus=XTileImage(display,resource_info,windows,
15279 display_image,&event,exception);
15280 if (nexus != (
Image *) NULL)
15281 *state|=MontageImageState | NextImageState | ExitState;
15282 vid_info.x=(
short int) windows->image.x;
15283 vid_info.y=(
short int) windows->image.y;
15289 entry=XMenuWidget(display,windows,
"Short Cuts",ShortCutsMenu,
15292 nexus=XMagickCommand(display,resource_info,windows,
15293 ShortCutsCommands[entry],&display_image,exception);
15301 XTranslateImage(display,windows,*image,XK_Up);
15309 XTranslateImage(display,windows,*image,XK_Down);
15317 if (event.xbutton.window == windows->magnify.id)
15320 *
const MagnifyMenu[] =
15337 MagnifyCommands[] =
15352 factor=XMenuWidget(display,windows,
"Magnify",MagnifyMenu,command);
15354 XMagnifyWindowCommand(display,windows,0,MagnifyCommands[factor],
15358 if (event.xbutton.window == windows->pan.id)
15360 switch (event.xbutton.button)
15367 XTranslateImage(display,windows,*image,XK_Up);
15375 XTranslateImage(display,windows,*image,XK_Down);
15380 XPanImage(display,windows,&event,exception);
15386 delay=display_image->delay/(size_t)
15387 MagickMax(display_image->ticks_per_second,1L);
15388 timer=GetMagickTime()+(time_t) (delay == 0 ? 1 : delay)+1;
15391 case ButtonRelease:
15393 if (resource_info->debug != MagickFalse)
15394 (void) LogMagickEvent(X11Event,GetMagickModule(),
15395 "Button Release: 0x%lx %u +%d+%d",
event.xbutton.window,
15396 event.xbutton.button,
event.xbutton.x,
event.xbutton.y);
15399 case ClientMessage:
15401 if (resource_info->debug != MagickFalse)
15402 (void) LogMagickEvent(X11Event,GetMagickModule(),
15403 "Client Message: 0x%lx 0x%lx %d 0x%lx",
event.xclient.window,
15404 event.xclient.message_type,
event.xclient.format,(
unsigned long)
15405 event.xclient.data.l[0]);
15406 if (event.xclient.message_type == windows->im_protocols)
15408 if (*event.xclient.data.l == (
long) windows->im_update_widget)
15410 (void) CloneString(&windows->command.name,MagickTitle);
15411 windows->command.data=MagickMenus;
15412 (void) XCommandWidget(display,windows,CommandMenu,
15416 if (*event.xclient.data.l == (
long) windows->im_update_colormap)
15421 for (i=0; i < (int) number_windows; i++)
15423 if (magick_windows[i]->
id == windows->icon.id)
15425 context_values.background=pixel->background_color.pixel;
15426 context_values.foreground=pixel->foreground_color.pixel;
15427 (void) XChangeGC(display,magick_windows[i]->annotate_context,
15428 context_mask,&context_values);
15429 (void) XChangeGC(display,magick_windows[i]->widget_context,
15430 context_mask,&context_values);
15431 context_values.background=pixel->foreground_color.pixel;
15432 context_values.foreground=pixel->background_color.pixel;
15433 context_values.plane_mask=context_values.background ^
15434 context_values.foreground;
15435 (void) XChangeGC(display,magick_windows[i]->highlight_context,
15436 (
size_t) (context_mask | GCPlaneMask),
15438 magick_windows[i]->attributes.background_pixel=
15439 pixel->background_color.pixel;
15440 magick_windows[i]->attributes.border_pixel=
15441 pixel->border_color.pixel;
15442 magick_windows[i]->attributes.colormap=map_info->colormap;
15443 (void) XChangeWindowAttributes(display,magick_windows[i]->
id,
15444 (
unsigned long) magick_windows[i]->mask,
15445 &magick_windows[i]->attributes);
15447 if (windows->pan.mapped != MagickFalse)
15449 (void) XSetWindowBackgroundPixmap(display,windows->pan.id,
15450 windows->pan.pixmap);
15451 (void) XClearWindow(display,windows->pan.id);
15452 XDrawPanRectangle(display,windows);
15454 if (windows->backdrop.id != (Window) NULL)
15455 (void) XInstallColormap(display,map_info->colormap);
15458 if (*event.xclient.data.l == (
long) windows->im_former_image)
15460 *state|=FormerImageState | ExitState;
15463 if (*event.xclient.data.l == (
long) windows->im_next_image)
15465 *state|=NextImageState | ExitState;
15468 if (*event.xclient.data.l == (
long) windows->im_retain_colors)
15470 *state|=RetainColorsState;
15473 if (*event.xclient.data.l == (
long) windows->im_exit)
15480 if (event.xclient.message_type == windows->dnd_protocols)
15500 if ((*event.xclient.data.l != 2) && (*
event.xclient.data.l != 128))
15502 selection=XInternAtom(display,
"DndSelection",MagickFalse);
15503 status=XGetWindowProperty(display,root_window,selection,0L,(
long)
15504 MagickPathExtent,MagickFalse,(Atom) AnyPropertyType,&type,&format,
15505 &length,&after,&data);
15506 if ((status != Success) || (length == 0))
15508 if (*event.xclient.data.l == 2)
15513 (void) CopyMagickString(resource_info->image_info->filename,
15514 (
char *) data,MagickPathExtent);
15521 if (strncmp((
char *) data,
"file:", 5) != 0)
15523 (void) XFree((
void *) data);
15526 (void) CopyMagickString(resource_info->image_info->filename,
15527 ((
char *) data)+5,MagickPathExtent);
15529 nexus=ReadImage(resource_info->image_info,exception);
15530 CatchException(exception);
15531 if (nexus != (
Image *) NULL)
15532 *state|=NextImageState | ExitState;
15533 (void) XFree((
void *) data);
15539 if (event.xclient.message_type != windows->wm_protocols)
15541 if (*event.xclient.data.l != (
long) windows->wm_delete_window)
15543 (void) XWithdrawWindow(display,event.xclient.window,
15544 visual_info->screen);
15545 if (event.xclient.window == windows->image.id)
15550 if (event.xclient.window == windows->pan.id)
15555 windows->image.window_changes.width=windows->image.ximage->width;
15556 windows->image.window_changes.height=windows->image.ximage->height;
15557 (void) XConfigureImage(display,resource_info,windows,
15558 display_image,exception);
15562 case ConfigureNotify:
15564 if (resource_info->debug != MagickFalse)
15565 (void) LogMagickEvent(X11Event,GetMagickModule(),
15566 "Configure Notify: 0x%lx %dx%d+%d+%d %d",
event.xconfigure.window,
15567 event.xconfigure.width,
event.xconfigure.height,
event.xconfigure.x,
15568 event.xconfigure.y,
event.xconfigure.send_event);
15569 if (event.xconfigure.window == windows->image.id)
15574 if (event.xconfigure.send_event != 0)
15582 if (windows->command.geometry == (
char *) NULL)
15583 if (windows->command.mapped == MagickFalse)
15585 windows->command.x=
event.xconfigure.x-(int)
15586 windows->command.width-25;
15587 windows->command.y=
event.xconfigure.y;
15588 XConstrainWindowPosition(display,&windows->command);
15589 window_changes.x=windows->command.x;
15590 window_changes.y=windows->command.y;
15591 (void) XReconfigureWMWindow(display,windows->command.id,
15592 windows->command.screen,(
unsigned int) (CWX | CWY),
15595 if (windows->widget.geometry == (
char *) NULL)
15596 if (windows->widget.mapped == MagickFalse)
15598 windows->widget.x=
event.xconfigure.x+
15599 event.xconfigure.width/10;
15600 windows->widget.y=
event.xconfigure.y+
15601 event.xconfigure.height/10;
15602 XConstrainWindowPosition(display,&windows->widget);
15603 window_changes.x=windows->widget.x;
15604 window_changes.y=windows->widget.y;
15605 (void) XReconfigureWMWindow(display,windows->widget.id,
15606 windows->widget.screen,(
unsigned int) (CWX | CWY),
15609 if (windows->magnify.geometry == (
char *) NULL)
15610 if (windows->magnify.mapped == MagickFalse)
15612 windows->magnify.x=
event.xconfigure.x+
15613 event.xconfigure.width+25;
15614 windows->magnify.y=
event.xconfigure.y;
15615 XConstrainWindowPosition(display,&windows->magnify);
15616 window_changes.x=windows->magnify.x;
15617 window_changes.y=windows->magnify.y;
15618 (void) XReconfigureWMWindow(display,windows->magnify.id,
15619 windows->magnify.screen,(
unsigned int) (CWX | CWY),
15622 if (windows->pan.geometry == (
char *) NULL)
15623 if (windows->pan.mapped == MagickFalse)
15625 windows->pan.x=
event.xconfigure.x+(int)
15626 event.xconfigure.width+25;
15627 windows->pan.y=
event.xconfigure.y+(int)
15628 windows->magnify.height+50;
15629 XConstrainWindowPosition(display,&windows->pan);
15630 window_changes.x=windows->pan.x;
15631 window_changes.y=windows->pan.y;
15632 (void) XReconfigureWMWindow(display,windows->pan.id,
15633 windows->pan.screen,(
unsigned int) (CWX | CWY),
15637 if ((event.xconfigure.width == (
int) windows->image.width) &&
15638 (event.xconfigure.height == (
int) windows->image.height))
15640 windows->image.width=(
unsigned int) event.xconfigure.width;
15641 windows->image.height=(
unsigned int) event.xconfigure.height;
15642 windows->image.x=0;
15643 windows->image.y=0;
15644 if (display_image->montage != (
char *) NULL)
15646 windows->image.x=vid_info.x;
15647 windows->image.y=vid_info.y;
15649 if (windows->image.mapped != MagickFalse &&
15650 windows->image.stasis != MagickFalse)
15655 windows->image.window_changes.width=
event.xconfigure.width;
15656 windows->image.window_changes.height=
event.xconfigure.height;
15657 (void) XConfigureImage(display,resource_info,windows,
15658 display_image,exception);
15663 if ((event.xconfigure.width < windows->image.ximage->width) ||
15664 (
event.xconfigure.height < windows->image.ximage->height))
15666 (void) XMapRaised(display,windows->pan.id);
15667 XDrawPanRectangle(display,windows);
15670 if (windows->pan.mapped != MagickFalse)
15671 (void) XWithdrawWindow(display,windows->pan.id,
15672 windows->pan.screen);
15675 if (event.xconfigure.window == windows->magnify.id)
15683 windows->magnify.width=(
unsigned int) event.xconfigure.width;
15684 windows->magnify.height=(
unsigned int) event.xconfigure.height;
15685 if (windows->magnify.mapped == MagickFalse)
15688 while ((
int) magnify <= event.xconfigure.width)
15690 while ((
int) magnify <= event.xconfigure.height)
15693 if (((
int) magnify != event.xconfigure.width) ||
15694 ((
int) magnify != event.xconfigure.height))
15696 window_changes.width=(int) magnify;
15697 window_changes.height=(int) magnify;
15698 (void) XReconfigureWMWindow(display,windows->magnify.id,
15699 windows->magnify.screen,(
unsigned int) (CWWidth | CWHeight),
15703 if (windows->magnify.mapped != MagickFalse &&
15704 windows->magnify.stasis != MagickFalse)
15706 status=XMakeImage(display,resource_info,&windows->magnify,
15707 display_image,windows->magnify.width,windows->magnify.height,
15709 XMakeMagnifyImage(display,windows,exception);
15713 if (windows->magnify.mapped != MagickFalse &&
15714 (event.xconfigure.window == windows->pan.id))
15719 if (event.xconfigure.send_event != 0)
15721 windows->pan.x=
event.xconfigure.x;
15722 windows->pan.y=
event.xconfigure.y;
15724 windows->pan.width=(
unsigned int) event.xconfigure.width;
15725 windows->pan.height=(
unsigned int) event.xconfigure.height;
15728 if (event.xconfigure.window == windows->icon.id)
15733 windows->icon.width=(
unsigned int) event.xconfigure.width;
15734 windows->icon.height=(
unsigned int) event.xconfigure.height;
15739 case DestroyNotify:
15744 if (resource_info->debug != MagickFalse)
15745 (void) LogMagickEvent(X11Event,GetMagickModule(),
15746 "Destroy Notify: 0x%lx",
event.xdestroywindow.window);
15747 if (event.xdestroywindow.window == windows->group_leader.id)
15759 if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
15760 if (event.xcrossing.mode != NotifyUngrab)
15761 XInstallColormap(display,map_info->colormap);
15766 if (resource_info->debug != MagickFalse)
15767 (void) LogMagickEvent(X11Event,GetMagickModule(),
15768 "Expose: 0x%lx %dx%d+%d+%d",
event.xexpose.window,
15769 event.xexpose.width,
event.xexpose.height,
event.xexpose.x,
15774 if ((event.xexpose.window == windows->image.id) &&
15775 windows->image.mapped != MagickFalse)
15777 XRefreshWindow(display,&windows->image,&event);
15778 delay=display_image->delay/(size_t) MagickMax(
15779 display_image->ticks_per_second,1L);
15780 timer=GetMagickTime()+(time_t) (delay == 0 ? 1 : delay)+1;
15783 if ((event.xexpose.window == windows->magnify.id) &&
15784 windows->magnify.mapped != MagickFalse)
15786 XMakeMagnifyImage(display,windows,exception);
15789 if (event.xexpose.window == windows->pan.id)
15791 XDrawPanRectangle(display,windows);
15794 if (event.xexpose.window == windows->icon.id)
15796 XRefreshWindow(display,&windows->icon,&event);
15809 length=XLookupString((XKeyEvent *) &event.xkey,command,(
int)
15810 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
15811 *(command+length)=
'\0';
15812 if (resource_info->debug != MagickFalse)
15813 (void) LogMagickEvent(X11Event,GetMagickModule(),
15814 "Key press: %d 0x%lx (%s)",
event.xkey.state,(
unsigned long)
15815 key_symbol,command);
15816 if (event.xkey.window == windows->image.id)
15818 display_command=XImageWindowCommand(display,resource_info,windows,
15819 event.xkey.state,key_symbol,&display_image,exception);
15820 if (display_command != NullCommand)
15821 nexus=XMagickCommand(display,resource_info,windows,
15822 display_command,&display_image,exception);
15824 if (event.xkey.window == windows->magnify.id)
15825 XMagnifyWindowCommand(display,windows,event.xkey.state,key_symbol,
15827 if (event.xkey.window == windows->pan.id)
15829 if ((key_symbol == XK_q) || (key_symbol == XK_Escape))
15830 (void) XWithdrawWindow(display,windows->pan.id,
15831 windows->pan.screen);
15833 if ((key_symbol == XK_F1) || (key_symbol == XK_Help))
15834 XTextViewHelp(display,resource_info,windows,MagickFalse,
15835 "Help Viewer - Image Pan",ImagePanHelp);
15837 XTranslateImage(display,windows,*image,key_symbol);
15839 delay=display_image->delay/(size_t) MagickMax(
15840 display_image->ticks_per_second,1L);
15841 timer=GetMagickTime()+(time_t) (delay == 0 ? 1 : delay)+1;
15849 (void) XLookupString((XKeyEvent *) &
event.xkey,command,(int)
15850 sizeof(command),&key_symbol,(XComposeStatus *) NULL);
15851 if (resource_info->debug != MagickFalse)
15852 (void) LogMagickEvent(X11Event,GetMagickModule(),
15853 "Key release: 0x%lx (%c)",(
unsigned long) key_symbol,*command);
15861 if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
15862 if (event.xcrossing.mode != NotifyUngrab)
15863 XUninstallColormap(display,map_info->colormap);
15868 if (resource_info->debug != MagickFalse)
15869 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Map Notify: 0x%lx",
15870 event.xmap.window);
15871 if (event.xmap.window == windows->backdrop.id)
15873 (void) XSetInputFocus(display,event.xmap.window,RevertToParent,
15875 windows->backdrop.mapped=MagickTrue;
15878 if (event.xmap.window == windows->image.id)
15880 if (windows->backdrop.id != (Window) NULL)
15881 (
void) XInstallColormap(display,map_info->colormap);
15882 if (LocaleCompare(display_image->magick,
"LOGO") == 0)
15884 if (LocaleCompare(display_image->filename,
"LOGO") == 0)
15885 nexus=XOpenImage(display,resource_info,windows,MagickFalse);
15887 if (((
int) windows->image.width < windows->image.ximage->width) ||
15888 ((
int) windows->image.height < windows->image.ximage->height))
15889 (void) XMapRaised(display,windows->pan.id);
15890 windows->image.mapped=MagickTrue;
15893 if (event.xmap.window == windows->magnify.id)
15895 XMakeMagnifyImage(display,windows,exception);
15896 windows->magnify.mapped=MagickTrue;
15897 (void) XWithdrawWindow(display,windows->info.id,
15898 windows->info.screen);
15901 if (event.xmap.window == windows->pan.id)
15903 XMakePanImage(display,resource_info,windows,display_image,
15905 windows->pan.mapped=MagickTrue;
15908 if (event.xmap.window == windows->info.id)
15910 windows->info.mapped=MagickTrue;
15913 if (event.xmap.window == windows->icon.id)
15921 taint=display_image->taint;
15922 XMakeStandardColormap(display,icon_visual,icon_resources,
15923 display_image,icon_map,icon_pixel,exception);
15924 (void) XMakeImage(display,icon_resources,&windows->icon,
15925 display_image,windows->icon.width,windows->icon.height,
15927 display_image->taint=taint;
15928 (void) XSetWindowBackgroundPixmap(display,windows->icon.id,
15929 windows->icon.pixmap);
15930 (void) XClearWindow(display,windows->icon.id);
15931 (void) XWithdrawWindow(display,windows->info.id,
15932 windows->info.screen);
15933 windows->icon.mapped=MagickTrue;
15936 if (event.xmap.window == windows->command.id)
15938 windows->command.mapped=MagickTrue;
15941 if (event.xmap.window == windows->popup.id)
15943 windows->popup.mapped=MagickTrue;
15946 if (event.xmap.window == windows->widget.id)
15948 windows->widget.mapped=MagickTrue;
15953 case MappingNotify:
15955 (void) XRefreshKeyboardMapping(&event.xmapping);
15960 case PropertyNotify:
15976 if (resource_info->debug != MagickFalse)
15977 (void) LogMagickEvent(X11Event,GetMagickModule(),
15978 "Property Notify: 0x%lx 0x%lx %d",
event.xproperty.window,
15979 event.xproperty.atom,
event.xproperty.state);
15980 if (event.xproperty.atom != windows->im_remote_command)
15985 status=XGetWindowProperty(display,event.xproperty.window,
15986 event.xproperty.atom,0L,(
long) MagickPathExtent,MagickFalse,(Atom)
15987 AnyPropertyType,&type,&format,&length,&after,&data);
15988 if ((status != Success) || (length == 0))
15990 if (LocaleCompare((
char *) data,
"-quit") == 0)
15992 XClientMessage(display,windows->image.id,windows->im_protocols,
15993 windows->im_exit,CurrentTime);
15994 (void) XFree((
void *) data);
15997 (void) CopyMagickString(resource_info->image_info->filename,
15998 (
char *) data,MagickPathExtent);
15999 (void) XFree((
void *) data);
16000 nexus=ReadImage(resource_info->image_info,exception);
16001 CatchException(exception);
16002 if (nexus != (
Image *) NULL)
16003 *state|=NextImageState | ExitState;
16006 case ReparentNotify:
16008 if (resource_info->debug != MagickFalse)
16009 (void) LogMagickEvent(X11Event,GetMagickModule(),
16010 "Reparent Notify: 0x%lx=>0x%lx",
event.xreparent.parent,
16011 event.xreparent.window);
16016 if (resource_info->debug != MagickFalse)
16017 (void) LogMagickEvent(X11Event,GetMagickModule(),
16018 "Unmap Notify: 0x%lx",
event.xunmap.window);
16019 if (event.xunmap.window == windows->backdrop.id)
16021 windows->backdrop.mapped=MagickFalse;
16024 if (event.xunmap.window == windows->image.id)
16026 windows->image.mapped=MagickFalse;
16029 if (event.xunmap.window == windows->magnify.id)
16031 windows->magnify.mapped=MagickFalse;
16034 if (event.xunmap.window == windows->pan.id)
16036 windows->pan.mapped=MagickFalse;
16039 if (event.xunmap.window == windows->info.id)
16041 windows->info.mapped=MagickFalse;
16044 if (event.xunmap.window == windows->icon.id)
16046 if (map_info->colormap == icon_map->colormap)
16047 XConfigureImageColormap(display,resource_info,windows,
16048 display_image,exception);
16049 (void) XFreeStandardColormap(display,icon_visual,icon_map,
16051 windows->icon.mapped=MagickFalse;
16054 if (event.xunmap.window == windows->command.id)
16056 windows->command.mapped=MagickFalse;
16059 if (event.xunmap.window == windows->popup.id)
16061 if (windows->backdrop.id != (Window) NULL)
16062 (
void) XSetInputFocus(display,windows->image.id,RevertToParent,
16064 windows->popup.mapped=MagickFalse;
16067 if (event.xunmap.window == windows->widget.id)
16069 if (windows->backdrop.id != (Window) NULL)
16070 (void) XSetInputFocus(display,windows->image.id,RevertToParent,
16072 windows->widget.mapped=MagickFalse;
16079 if (resource_info->debug != MagickFalse)
16080 (void) LogMagickEvent(X11Event,GetMagickModule(),
"Event type: %d",
16085 }
while (!(*state & ExitState));
16086 if ((*state & ExitState) == 0)
16087 (
void) XMagickCommand(display,resource_info,windows,FreeBuffersCommand,
16088 &display_image,exception);
16090 if (resource_info->confirm_edit != MagickFalse)
16095 if ((resource_info->immutable == MagickFalse) &&
16096 display_image->taint != MagickFalse)
16101 status=XConfirmWidget(display,windows,
"Your image changed.",
16102 "Do you want to save it");
16104 *state&=(
unsigned int) (~ExitState);
16107 (void) XMagickCommand(display,resource_info,windows,SaveCommand,
16108 &display_image,exception);
16111 if ((windows->visual_info->klass == GrayScale) ||
16112 (windows->visual_info->klass == PseudoColor) ||
16113 (windows->visual_info->klass == DirectColor))
16118 if (windows->info.mapped != MagickFalse)
16119 (void) XWithdrawWindow(display,windows->info.id,windows->info.screen);
16120 if (windows->magnify.mapped != MagickFalse)
16121 (void) XWithdrawWindow(display,windows->magnify.id,
16122 windows->magnify.screen);
16123 if (windows->command.mapped != MagickFalse)
16124 (void) XWithdrawWindow(display,windows->command.id,
16125 windows->command.screen);
16127 if (windows->pan.mapped != MagickFalse)
16128 (void) XWithdrawWindow(display,windows->pan.id,windows->pan.screen);
16129 if (resource_info->backdrop == MagickFalse)
16130 if (windows->backdrop.mapped)
16132 (void) XWithdrawWindow(display,windows->backdrop.id,
16133 windows->backdrop.screen);
16134 (void) XDestroyWindow(display,windows->backdrop.id);
16135 windows->backdrop.id=(Window) NULL;
16136 (void) XWithdrawWindow(display,windows->image.id,
16137 windows->image.screen);
16138 (void) XDestroyWindow(display,windows->image.id);
16139 windows->image.id=(Window) NULL;
16141 XSetCursorState(display,windows,MagickTrue);
16142 XCheckRefreshWindows(display,windows);
16143 if (((*state & FormerImageState) != 0) || ((*state & NextImageState) != 0))
16144 *state&=(
unsigned int) (~ExitState);
16145 if (*state & ExitState)
16150 (void) XFreeStandardColormap(display,icon_visual,icon_map,icon_pixel);
16151 if (resource_info->map_type == (
char *) NULL)
16152 (
void) XFreeStandardColormap(display,visual_info,map_info,pixel);
16156 if (resource_info->copy_image != (
Image *) NULL)
16158 resource_info->copy_image=DestroyImage(resource_info->copy_image);
16159 resource_info->copy_image=NewImageList();
16161 DestroyXResources();
16163 (void) XSync(display,MagickFalse);
16167 (void) SetErrorHandler(warning_handler);
16168 (void) SetWarningHandler(warning_handler);
16172 directory=getcwd(working_directory,MagickPathExtent);
16178 if (*resource_info->home_directory ==
'\0')
16179 (void) CopyMagickString(resource_info->home_directory,
".",MagickPathExtent);
16180 status=chdir(resource_info->home_directory);
16182 (void) ThrowMagickException(exception,GetMagickModule(),FileOpenError,
16183 "UnableToOpenFile",
"%s",resource_info->home_directory);
16185 *image=display_image;
16219MagickExport MagickBooleanType DisplayImages(
const ImageInfo *image_info,
16222 assert(image_info != (
const ImageInfo *) NULL);
16223 assert(image_info->signature == MagickCoreSignature);
16224 assert(image != (
Image *) NULL);
16225 assert(image->signature == MagickCoreSignature);
16227 if (IsEventLogging() != MagickFalse)
16228 (
void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
16229 (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError,
16230 "DelegateLibrarySupportNotBuiltIn",
"'%s' (X11)",image->filename);
16231 return(MagickFalse);
16264MagickExport MagickBooleanType RemoteDisplayCommand(
const ImageInfo *image_info,
16265 const char *window,
const char *filename,
ExceptionInfo *exception)
16267 assert(image_info != (
const ImageInfo *) NULL);
16268 assert(image_info->signature == MagickCoreSignature);
16269 assert(filename != (
char *) NULL);
16270 if (IsEventLogging() != MagickFalse)
16271 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",filename);
16273 (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError,
16274 "DelegateLibrarySupportNotBuiltIn",
"'%s' (X11)",image_info->filename);
16275 return(MagickFalse);